1+ using CSharpExtender . Attributes ;
2+ using System . ComponentModel . DataAnnotations ;
3+
4+ namespace Test . CSharpExtender . Attributes ;
5+
6+ public class UniqueItemsAttributeTests
7+ {
8+ private static ValidationContext GetValidationContext ( object instance ) => new ( instance ) ;
9+
10+ // Test class for complex object validation
11+ private class TestItem ( int id , string name )
12+ {
13+ public int Id { get ; set ; } = id ;
14+ public string Name { get ; set ; } = name ;
15+ }
16+
17+ [ Fact ]
18+ public void UniqueItemsAttribute_NullList_ReturnsSuccess ( )
19+ {
20+ var model = new { Items = null as List < string > } ;
21+ var attribute = new UniqueItemsAttribute ( ) ;
22+ var result = attribute . GetValidationResult ( model . Items , GetValidationContext ( model ) ) ;
23+
24+ Assert . Equal ( ValidationResult . Success , result ) ;
25+ }
26+
27+ [ Fact ]
28+ public void UniqueItemsAttribute_EmptyList_ReturnsSuccess ( )
29+ {
30+ var model = new { Items = new List < string > ( ) } ;
31+ var attribute = new UniqueItemsAttribute ( ) ;
32+ var result = attribute . GetValidationResult ( model . Items , GetValidationContext ( model ) ) ;
33+
34+ Assert . Equal ( ValidationResult . Success , result ) ;
35+ }
36+
37+ [ Fact ]
38+ public void UniqueItemsAttribute_UniqueStrings_ReturnsSuccess ( )
39+ {
40+ var model = new { Items = new List < string > { "apple" , "banana" , "cherry" } } ;
41+ var attribute = new UniqueItemsAttribute ( ) ;
42+ var result = attribute . GetValidationResult ( model . Items , GetValidationContext ( model ) ) ;
43+
44+ Assert . Equal ( ValidationResult . Success , result ) ;
45+ }
46+
47+ [ Fact ]
48+ public void UniqueItemsAttribute_DuplicateStrings_DefaultErrorMessage ( )
49+ {
50+ var model = new { Items = new List < string > { "apple" , "apple" , "cherry" } } ;
51+ var attribute = new UniqueItemsAttribute ( ) ;
52+ var result = attribute . GetValidationResult ( model . Items , GetValidationContext ( model ) ) ;
53+
54+ Assert . NotEqual ( ValidationResult . Success , result ) ;
55+ Assert . Contains ( "duplicate items" , result . ErrorMessage ) ;
56+ Assert . Contains ( "indices 0 and 1" , result . ErrorMessage ) ;
57+ }
58+
59+ [ Fact ]
60+ public void UniqueItemsAttribute_DuplicateStrings_CustomErrorMessage ( )
61+ {
62+ var model = new { Items = new List < string > { "apple" , "apple" , "cherry" } } ;
63+ var attribute = new UniqueItemsAttribute { ErrorMessage = "All items must be unique in the list." } ;
64+ var result = attribute . GetValidationResult ( model . Items , GetValidationContext ( model ) ) ;
65+
66+ Assert . NotEqual ( ValidationResult . Success , result ) ;
67+ Assert . Equal ( "All items must be unique in the list." , result . ErrorMessage ) ;
68+ }
69+
70+ [ Fact ]
71+ public void UniqueItemsAttribute_UniqueNumbers_ReturnsSuccess ( )
72+ {
73+ var model = new { Items = new List < int > { 1 , 2 , 3 } } ;
74+ var attribute = new UniqueItemsAttribute ( ) ;
75+ var result = attribute . GetValidationResult ( model . Items , GetValidationContext ( model ) ) ;
76+
77+ Assert . Equal ( ValidationResult . Success , result ) ;
78+ }
79+
80+ [ Fact ]
81+ public void UniqueItemsAttribute_DuplicateNumbers_DefaultErrorMessage ( )
82+ {
83+ var model = new { Items = new List < int > { 1 , 2 , 2 } } ;
84+ var attribute = new UniqueItemsAttribute ( ) ;
85+ var result = attribute . GetValidationResult ( model . Items , GetValidationContext ( model ) ) ;
86+
87+ Assert . NotEqual ( ValidationResult . Success , result ) ;
88+ Assert . Contains ( "duplicate items" , result . ErrorMessage ) ;
89+ Assert . Contains ( "indices 1 and 2" , result . ErrorMessage ) ;
90+ }
91+
92+ [ Fact ]
93+ public void UniqueItemsAttribute_DuplicateNumbers_CustomErrorMessage ( )
94+ {
95+ var model = new { Items = new List < int > { 1 , 2 , 2 } } ;
96+ var attribute = new UniqueItemsAttribute { ErrorMessage = "Numbers must be unique." } ;
97+ var result = attribute . GetValidationResult ( model . Items , GetValidationContext ( model ) ) ;
98+
99+ Assert . NotEqual ( ValidationResult . Success , result ) ;
100+ Assert . Equal ( "Numbers must be unique." , result . ErrorMessage ) ;
101+ }
102+
103+ [ Fact ]
104+ public void UniqueItemsAttribute_UniqueComplexObjects_ReturnsSuccess ( )
105+ {
106+ var model = new
107+ {
108+ Items = new List < TestItem >
109+ {
110+ new TestItem ( 1 , "apple" ) ,
111+ new TestItem ( 2 , "banana" )
112+ }
113+ } ;
114+
115+ var attribute = new UniqueItemsAttribute ( ) ;
116+ var result = attribute . GetValidationResult ( model . Items , GetValidationContext ( model ) ) ;
117+
118+ Assert . Equal ( ValidationResult . Success , result ) ;
119+ }
120+
121+ [ Fact ]
122+ public void UniqueItemsAttribute_DuplicateComplexObjects_DefaultErrorMessage ( )
123+ {
124+ var model = new
125+ {
126+ Items = new List < TestItem >
127+ {
128+ new TestItem ( 1 , "apple" ) ,
129+ new TestItem ( 1 , "apple" )
130+ }
131+ } ;
132+
133+ var attribute = new UniqueItemsAttribute ( ) ;
134+ var result = attribute . GetValidationResult ( model . Items , GetValidationContext ( model ) ) ;
135+
136+ Assert . NotEqual ( ValidationResult . Success , result ) ;
137+ Assert . Contains ( "duplicate items" , result . ErrorMessage ) ;
138+ Assert . Contains ( "indices 0 and 1" , result . ErrorMessage ) ;
139+ }
140+
141+ [ Fact ]
142+ public void UniqueItemsAttribute_DuplicateComplexObjects_CustomErrorMessage ( )
143+ {
144+ var model = new
145+ {
146+ Items = new List < TestItem >
147+ {
148+ new TestItem ( 1 , "apple" ) ,
149+ new TestItem ( 1 , "apple" )
150+ }
151+ } ;
152+
153+ var attribute = new UniqueItemsAttribute { ErrorMessage = "Objects in the list must have unique values." } ;
154+ var result = attribute . GetValidationResult ( model . Items , GetValidationContext ( model ) ) ;
155+
156+ Assert . NotEqual ( ValidationResult . Success , result ) ;
157+ Assert . Equal ( "Objects in the list must have unique values." , result . ErrorMessage ) ;
158+ }
159+
160+ [ Fact ]
161+ public void UniqueItemsAttribute_SingleString_ReturnsError ( )
162+ {
163+ var model = new { Items = "not a list" } ;
164+ var attribute = new UniqueItemsAttribute ( ) ;
165+ var result = attribute . GetValidationResult ( model . Items , GetValidationContext ( model ) ) ;
166+
167+ Assert . NotEqual ( ValidationResult . Success , result ) ;
168+ Assert . Contains ( "must be applied to a collection" , result . ErrorMessage ) ;
169+ }
170+
171+ [ Fact ]
172+ public void UniqueItemsAttribute_NonCollectionNonString_ReturnsError ( )
173+ {
174+ var model = new { Items = 42 } ; // An int, not a string or collection
175+ var attribute = new UniqueItemsAttribute ( ) ;
176+ var result = attribute . GetValidationResult ( model . Items , GetValidationContext ( model ) ) ;
177+
178+ Assert . NotEqual ( ValidationResult . Success , result ) ;
179+ Assert . Contains ( "must be applied to a collection" , result . ErrorMessage ) ;
180+ }
181+ }
0 commit comments