@@ -123,4 +123,228 @@ class UserConfigTests: XCTestCase {
123123 XCTAssertNotNil ( json)
124124 XCTAssertNotNil ( nestedJson)
125125 }
126+
127+
128+ func testSuccessfulConfigParsingWithNonStringValuesOnFeatures( ) throws {
129+ let data = getConfigData ( name: " test_config_eval_reason " )
130+ let dictionary = try JSONSerialization . jsonObject ( with: data, options: . fragmentsAllowed) as! [ String : Any ]
131+ let config = try UserConfig ( from: dictionary)
132+ let features = config. features
133+ XCTAssertNotNil ( config)
134+ XCTAssertNotNil ( features)
135+ }
136+
137+ func testSuccessfulConfigParsingWithManyUnusedProperties( ) throws {
138+ let data = """
139+ {
140+ " project " : {
141+ " _id " : " id1 " ,
142+ " key " : " default " ,
143+ " settings " : {
144+ " unused " : " data "
145+ }
146+ },
147+ " environment " : {
148+ " _id " : " id2 " ,
149+ " key " : " development " ,
150+ " metadata " : {
151+ " testing " : " unused data "
152+ }
153+ },
154+ " features " : {
155+ " new-feature " : {
156+ " _id " : " id3 " ,
157+ " key " : " new-feature " ,
158+ " type " : " release " ,
159+ " _variation " : " id4 " ,
160+ " variationKey " : " id4-key " ,
161+ " variationName " : " id4 name " ,
162+ " eval " : {
163+ " reason " : " TARGETING_MATCH " ,
164+ " details " : " Platform AND App Version "
165+ },
166+ " evalReason " : " we don't do this anymore "
167+ }
168+ },
169+ " featureVariationMap " : {
170+ " id3 " : " id4 "
171+ },
172+ " knownVariableKeys " : [],
173+ " variables " : {
174+ " bool-var " : {
175+ " _id " : " id5 " ,
176+ " key " : " bool-var " ,
177+ " type " : " Boolean " ,
178+ " value " : true,
179+ " eval " : {
180+ " reason " : " TARGETING_MATCH " ,
181+ " details " : " Platform AND App Version "
182+ }
183+ },
184+ " json-var " : {
185+ " _id " : " id6 " ,
186+ " key " : " json-var " ,
187+ " type " : " JSON " ,
188+ " value " : {
189+ " key1 " : " value1 " ,
190+ " key2 " : {
191+ " nestedKey1 " : " nestedValue1 "
192+ }
193+ },
194+ " eval " : {
195+ " reason " : " TARGETING_MATCH " ,
196+ " details " : " Platform AND App Version "
197+ }
198+ },
199+ " string-var " : {
200+ " _id " : " id7 " ,
201+ " key " : " string-var " ,
202+ " type " : " String " ,
203+ " value " : " string1 " ,
204+ " eval " : {
205+ " reason " : " TARGETING_MATCH " ,
206+ " details " : " Platform AND App Version "
207+ },
208+ " evalReason " : " we really don't do this anymore "
209+ },
210+ " num-var " : {
211+ " _id " : " id8 " ,
212+ " key " : " num-var " ,
213+ " type " : " Number " ,
214+ " value " : 4,
215+ " eval " : {
216+ " reason " : " TARGETING_MATCH " ,
217+ " details " : " Platform AND App Version "
218+ }
219+ }
220+ },
221+ " sse " : {
222+ " url " : " https://example.com " ,
223+ " inactivityDelay " : 5,
224+ " questionable " : {
225+ " unused " : [ " values " , " here " ]
226+ }
227+ },
228+ " welcome " : " to the future " ,
229+ " the_answer " : 42,
230+ " hitchhiker " : false
231+ }
232+ """ . data ( using: . utf8) !
233+ let dictionary =
234+ try JSONSerialization . jsonObject ( with: data, options: . fragmentsAllowed)
235+ as! [ String : Any ]
236+ let config = try UserConfig ( from: dictionary)
237+ XCTAssertNotNil ( config)
238+ XCTAssertNotNil ( config. project)
239+ XCTAssertNotNil ( config. environment)
240+ XCTAssertNotNil ( config. variables)
241+ XCTAssertNotNil ( config. featureVariationMap)
242+ XCTAssertNotNil ( config. features)
243+ XCTAssertNotNil ( config. sse)
244+ }
245+
246+ func testConfigWithFeatureKeyAsNumber( ) throws {
247+ // Feature feature-1 has a Number `key` instead of a String
248+ let data = """
249+ {
250+ " project " : {
251+ " _id " : " id1 " ,
252+ " key " : " default "
253+ },
254+ " environment " : {
255+ " _id " : " id2 " ,
256+ " key " : " development "
257+ },
258+ " features " : {
259+ " feature-1 " : {
260+ " _id " : " id3 " ,
261+ " key " : 1,
262+ " type " : " release " ,
263+ " _variation " : " id4 " ,
264+ " variationKey " : " id4-key " ,
265+ " variationName " : " id4 name " ,
266+ }
267+ },
268+ " featureVariationMap " : {},
269+ " knownVariableKeys " : [],
270+ " variables " : {
271+ " bool-var " : {
272+ " _id " : " id5 " ,
273+ " key " : " bool-var " ,
274+ " type " : " Boolean " ,
275+ " value " : true,
276+ " eval " : {
277+ " reason " : " TARGETING_MATCH " ,
278+ " details " : " Platform AND App Version "
279+ }
280+ }
281+ },
282+ " sse " : {
283+ " url " : " https://example.com " ,
284+ " inactivityDelay " : 5
285+ }
286+ }
287+ """ . data ( using: . utf8) !
288+ let dictionary =
289+ try JSONSerialization . jsonObject ( with: data, options: . fragmentsAllowed)
290+ as! [ String : Any ]
291+ do {
292+ _ = try UserConfig ( from: dictionary)
293+ } catch {
294+ let stringError = String ( describing: UserConfigError . MissingProperty ( " String: key in Feature object " ) )
295+ XCTAssertEqual ( String ( describing: error) , stringError)
296+ }
297+ }
298+
299+ func testConfigWithVariableIdMissing( ) throws {
300+ // Variable bool-var is missing the `_id` property
301+ let data = """
302+ {
303+ " project " : {
304+ " _id " : " id1 " ,
305+ " key " : " default "
306+ },
307+ " environment " : {
308+ " _id " : " id2 " ,
309+ " key " : " development "
310+ },
311+ " features " : {
312+ " feature-1 " : {
313+ " _id " : " id3 " ,
314+ " key " : " feature-1 " ,
315+ " type " : " release " ,
316+ " _variation " : " id4 " ,
317+ " variationKey " : " id4-key " ,
318+ " variationName " : " id4 name " ,
319+ }
320+ },
321+ " featureVariationMap " : {},
322+ " knownVariableKeys " : [],
323+ " variables " : {
324+ " bool-var " : {
325+ " key " : " bool-var " ,
326+ " type " : " Boolean " ,
327+ " value " : true,
328+ " eval " : {
329+ " reason " : " TARGETING_MATCH " ,
330+ " details " : " Platform AND App Version "
331+ }
332+ }
333+ },
334+ " sse " : {
335+ " url " : " https://example.com " ,
336+ " inactivityDelay " : 5
337+ }
338+ }
339+ """ . data ( using: . utf8) !
340+ let dictionary =
341+ try JSONSerialization . jsonObject ( with: data, options: . fragmentsAllowed)
342+ as! [ String : Any ]
343+ do {
344+ _ = try UserConfig ( from: dictionary)
345+ } catch {
346+ let stringError = String ( describing: UserConfigError . MissingProperty ( " _id in Variable object " ) )
347+ XCTAssertEqual ( String ( describing: error) , stringError)
348+ }
349+ }
126350}
0 commit comments