1
+ using System ;
2
+ using System . Collections . Generic ;
3
+ using System . ComponentModel . DataAnnotations ;
4
+ using System . Runtime . Serialization ;
5
+ using Microsoft . VisualStudio . TestTools . UnitTesting ;
6
+ using Newtonsoft . Json ;
7
+ using Newtonsoft . Json . Converters ;
8
+
9
+ namespace Adyen . Test
10
+ {
11
+ // Base class
12
+ public abstract class StringEnumBase : IEquatable < StringEnumBase > , IValidatableObject
13
+ {
14
+ private readonly string _value ;
15
+
16
+ protected StringEnumBase ( string value )
17
+ {
18
+ _value = value ;
19
+ }
20
+
21
+ public abstract StringEnumBase FromString ( string value ) ;
22
+
23
+ public override string ToString ( )
24
+ {
25
+ return _value ;
26
+ }
27
+
28
+ public override bool Equals ( object obj )
29
+ {
30
+ if ( obj is StringEnumBase otherEnum )
31
+ return _value . Equals ( otherEnum . _value ) ;
32
+ return false ;
33
+ }
34
+
35
+ public override int GetHashCode ( )
36
+ {
37
+ return _value . GetHashCode ( ) ;
38
+ }
39
+
40
+ public static bool operator == ( StringEnumBase a , StringEnumBase b )
41
+ {
42
+ if ( a is null )
43
+ return b is null ;
44
+ return a . Equals ( b ) ;
45
+ }
46
+
47
+ public static bool operator != ( StringEnumBase a , StringEnumBase b )
48
+ {
49
+ return ! ( a == b ) ;
50
+ }
51
+
52
+ public bool Equals ( StringEnumBase other )
53
+ {
54
+ if ( other is null )
55
+ return false ;
56
+ return _value == other . _value ;
57
+ }
58
+
59
+ public IEnumerable < ValidationResult > Validate ( ValidationContext validationContext )
60
+ {
61
+ yield break ;
62
+ }
63
+ }
64
+
65
+ // Converter that can take a json string and match it to the correct class
66
+ public class StringEnumBaseConverter < T > : JsonConverter where T : StringEnumBase , new ( )
67
+ {
68
+ public override bool CanConvert ( Type objectType )
69
+ {
70
+ return typeof ( T ) . IsAssignableFrom ( objectType ) ;
71
+ }
72
+
73
+ public override object ReadJson ( JsonReader reader , Type objectType , object existingValue , JsonSerializer serializer )
74
+ {
75
+ var value = reader . Value . ToString ( ) ;
76
+ return new T ( ) . FromString ( value ) ;
77
+ }
78
+
79
+ public override void WriteJson ( JsonWriter writer , object value , JsonSerializer serializer )
80
+ {
81
+ var stringEnum = ( StringEnumBase ) value ;
82
+ writer . WriteValue ( stringEnum . ToString ( ) ) ;
83
+ }
84
+ }
85
+
86
+ /// Example class to deserialize
87
+ [ DataContract ( Name = "AuthenticationInfo" ) ]
88
+ public class AuthenticationInfo : IEquatable < AuthenticationInfo > , IValidatableObject
89
+ {
90
+ [ JsonConverter ( typeof ( StringEnumBaseConverter < ChallengeIndicatorEnum > ) ) ]
91
+ public class ChallengeIndicatorEnum : StringEnumBase
92
+ {
93
+ public ChallengeIndicatorEnum ( ) : base ( null )
94
+ {
95
+ }
96
+
97
+ private ChallengeIndicatorEnum ( string value = null ) : base ( value )
98
+ {
99
+ }
100
+
101
+ public static ChallengeIndicatorEnum _01 = new ChallengeIndicatorEnum ( "01" ) ;
102
+ public static ChallengeIndicatorEnum _02 = new ChallengeIndicatorEnum ( "02" ) ;
103
+ public static ChallengeIndicatorEnum _03 = new ChallengeIndicatorEnum ( "03" ) ;
104
+ public static ChallengeIndicatorEnum _04 = new ChallengeIndicatorEnum ( "04" ) ;
105
+
106
+ public override StringEnumBase FromString ( string value )
107
+ {
108
+ switch ( value )
109
+ {
110
+ case null :
111
+ return null ;
112
+ case "01" :
113
+ return _01 ;
114
+ case "02" :
115
+ return _02 ;
116
+ case "03" :
117
+ return _03 ;
118
+ case "04" :
119
+ return _04 ;
120
+ default :
121
+ throw new ArgumentException ( $ "Unhandled value: { value } ") ;
122
+ } ;
123
+ }
124
+ }
125
+
126
+ [ DataMember ( Name = "challengeIndicator" , IsRequired = false , EmitDefaultValue = false ) ]
127
+ public ChallengeIndicatorEnum ChallengeIndicator { get ; set ; }
128
+
129
+ // This is the original
130
+ // [JsonConverter(typeof(StringEnumConverter))]
131
+ // public enum ChallengeIndicatorEnum
132
+ // {
133
+ // /// <summary>
134
+ // /// Enum _01 for value: 01
135
+ // /// </summary>
136
+ // [EnumMember(Value = "01")]
137
+ // _01 = 1,
138
+ //
139
+ // /// <summary>
140
+ // /// Enum _02 for value: 02
141
+ // /// </summary>
142
+ // [EnumMember(Value = "02")]
143
+ // _02 = 2,
144
+ //
145
+ // /// <summary>
146
+ // /// Enum _03 for value: 03
147
+ // /// </summary>
148
+ // [EnumMember(Value = "03")]
149
+ // _03 = 3,
150
+ //
151
+ // /// <summary>
152
+ // /// Enum _04 for value: 04
153
+ // /// </summary>
154
+ // [EnumMember(Value = "04")]
155
+ // _04 = 4,
156
+ //
157
+ // /// <summary>
158
+ // /// Enum _05 for value: 05
159
+ // /// </summary>
160
+ // [EnumMember(Value = "05")]
161
+ // _05 = 5,
162
+ //
163
+ // /// <summary>
164
+ // /// Enum _07 for value: 07
165
+ // /// </summary>
166
+ // [EnumMember(Value = "07")]
167
+ // _07 = 6,
168
+ //
169
+ // /// <summary>
170
+ // /// Enum _08 for value: 08
171
+ // /// </summary>
172
+ // [EnumMember(Value = "08")]
173
+ // _08 = 7,
174
+ //
175
+ // /// <summary>
176
+ // /// Enum _09 for value: 09
177
+ // /// </summary>
178
+ // [EnumMember(Value = "09")]
179
+ // _09 = 8,
180
+ //
181
+ // /// <summary>
182
+ // /// Enum _80 for value: 80
183
+ // /// </summary>
184
+ // [EnumMember(Value = "80")]
185
+ // _80 = 9,
186
+ //
187
+ // /// <summary>
188
+ // /// Enum _82 for value: 82
189
+ // /// </summary>
190
+ // [EnumMember(Value = "82")]
191
+ // _82 = 10
192
+ //
193
+ // }
194
+ //
195
+ // /// <summary>
196
+ // /// Specifies a preference for receiving a challenge. Possible values: * **01**: No preference * **02**: No challenge requested * **03**: Challenge requested (preference) * **04**: Challenge requested (mandate) * **05**: No challenge requested (transactional risk analysis is already performed) * **07**: No challenge requested (SCA is already performed) * **08**: No challenge requested (trusted beneficiaries exemption of no challenge required) * **09**: Challenge requested (trusted beneficiaries prompt requested if challenge required) * **80**: No challenge requested (secure corporate payment with Mastercard) * **82**: No challenge requested (secure corporate payment with Visa)
197
+ // /// </summary>
198
+ // /// <value>Specifies a preference for receiving a challenge. Possible values: * **01**: No preference * **02**: No challenge requested * **03**: Challenge requested (preference) * **04**: Challenge requested (mandate) * **05**: No challenge requested (transactional risk analysis is already performed) * **07**: No challenge requested (SCA is already performed) * **08**: No challenge requested (trusted beneficiaries exemption of no challenge required) * **09**: Challenge requested (trusted beneficiaries prompt requested if challenge required) * **80**: No challenge requested (secure corporate payment with Mastercard) * **82**: No challenge requested (secure corporate payment with Visa) </value>
199
+ // [DataMember(Name = "challengeIndicator", IsRequired = true, EmitDefaultValue = false)]
200
+ // public ChallengeIndicatorEnum ChallengeIndicator { get; set; }
201
+
202
+
203
+ /// <summary>
204
+ /// Returns true if AuthenticationInfo instances are equal
205
+ /// </summary>
206
+ /// <param name="input">Instance of AuthenticationInfo to be compared</param>
207
+ /// <returns>Boolean</returns>
208
+ public bool Equals ( AuthenticationInfo input )
209
+ {
210
+ if ( input == null )
211
+ {
212
+ return false ;
213
+ }
214
+
215
+ return
216
+ (
217
+ this . ChallengeIndicator == input . ChallengeIndicator ||
218
+ this . ChallengeIndicator . Equals ( input . ChallengeIndicator )
219
+ ) ;
220
+ }
221
+
222
+ /// <summary>
223
+ /// To validate all properties of the instance
224
+ /// </summary>
225
+ /// <param name="validationContext">Validation context</param>
226
+ /// <returns>Validation Result</returns>
227
+ public IEnumerable < System . ComponentModel . DataAnnotations . ValidationResult > Validate ( ValidationContext validationContext )
228
+ {
229
+ yield break ;
230
+ }
231
+
232
+ // Test -> random string
233
+ [ DataMember ( Name = "test" , IsRequired = false , EmitDefaultValue = false ) ]
234
+ public string Test { get ; set ; }
235
+ }
236
+
237
+ [ TestClass ]
238
+ public class BaseEnumTest : BaseTest
239
+ {
240
+ private readonly JsonSerializerSettings _jsonSettings ;
241
+
242
+ public BaseEnumTest ( )
243
+ {
244
+ _jsonSettings = new JsonSerializerSettings
245
+ {
246
+ NullValueHandling = NullValueHandling . Ignore ,
247
+ DefaultValueHandling = DefaultValueHandling . Include ,
248
+ } ;
249
+ _jsonSettings . Converters . Add ( new StringEnumConverter ( ) ) ;
250
+ }
251
+
252
+ [ DataTestMethod ]
253
+ [ DataRow ( @"{""Test"": ""Aaa""}" ) ]
254
+ [ DataRow ( @"{""challengeIndicator"": null, ""Test"": ""Aaa""}" ) ]
255
+ public void When_No_ChallengeIndicator_Is_Provided_ResultShouldBe_Null ( string json )
256
+ {
257
+ AuthenticationInfo info = JsonConvert . DeserializeObject < AuthenticationInfo > ( json , _jsonSettings ) ;
258
+ Assert . AreEqual ( null , info . ChallengeIndicator ) ;
259
+ }
260
+
261
+ [ DataTestMethod ]
262
+ [ DataRow ( @"{""challengeIndicator"": ""null"", ""Test"": ""Aaa""}" ) ]
263
+ [ DataRow ( @"{""challengeIndicator"": 0, ""Test"": ""Aaa""}" ) ]
264
+ [ DataRow ( @"{""challengeIndicator"": ""invalidEnum"", ""Test"": ""Aaa""}" ) ]
265
+ public void When_Value_Is_Not_In_List_ResultShouldThrow_ArugmentException ( string json )
266
+ {
267
+ Assert . ThrowsException < ArgumentException > ( ( ) => JsonConvert . DeserializeObject < AuthenticationInfo > ( json , _jsonSettings ) ) ;
268
+ }
269
+
270
+
271
+ [ DataTestMethod ]
272
+ [ DataRow ( @"{""challengeIndicator"": ""03"", ""Test"": ""Aaa""}" ) ]
273
+ [ DataRow ( @"{""ChallengeIndicator"": ""03"", ""Test"": ""Aaa""}" ) ]
274
+ public void When_Value_Is_In_List_ResultShouldBe__03 ( string json )
275
+ {
276
+ AuthenticationInfo info = JsonConvert . DeserializeObject < AuthenticationInfo > ( json , _jsonSettings ) ;
277
+ Assert . AreEqual ( AuthenticationInfo . ChallengeIndicatorEnum . _03 , info . ChallengeIndicator ) ;
278
+ }
279
+
280
+ [ TestMethod ]
281
+ public void WhenEqualOperatorOrEqualsFunction_Is_Called_ResultShouldBe_Expected ( )
282
+ {
283
+ var a = AuthenticationInfo . ChallengeIndicatorEnum . _01 ;
284
+ var aa = AuthenticationInfo . ChallengeIndicatorEnum . _01 ;
285
+
286
+ var b = AuthenticationInfo . ChallengeIndicatorEnum . _02 ;
287
+ var c = AuthenticationInfo . ChallengeIndicatorEnum . _03 ;
288
+ var d = AuthenticationInfo . ChallengeIndicatorEnum . _04 ;
289
+
290
+ Assert . AreEqual ( a , a ) ; Assert . IsTrue ( a == a ) ;
291
+ Assert . AreEqual ( a , aa ) ; Assert . IsTrue ( a == aa ) ;
292
+ Assert . AreNotEqual ( a , b ) ; Assert . IsTrue ( a != b ) ;
293
+ Assert . AreNotEqual ( a , c ) ; Assert . IsTrue ( a != c ) ;
294
+ Assert . AreNotEqual ( a , d ) ; Assert . IsTrue ( a != d ) ;
295
+ Assert . AreNotEqual ( a , null ) ; Assert . IsTrue ( a != null ) ;
296
+ }
297
+ }
298
+ }
0 commit comments