Skip to content

Commit 943f8b9

Browse files
authored
feat: added GetFeatureVariableJSON. (#317)
1 parent 534c8a7 commit 943f8b9

File tree

10 files changed

+272
-11
lines changed

10 files changed

+272
-11
lines changed

Sources/Data Model/FeatureVariable.swift

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2019, Optimizely, Inc. and contributors *
2+
* Copyright 2019-2020, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -20,6 +20,40 @@ struct FeatureVariable: Codable, Equatable {
2020
var id: String
2121
var key: String
2222
var type: String
23-
// datafile schema rquires this, but test has "null" value case. keep optional for FSC
23+
var subType: String?
24+
// datafile schema requires this, but test has "null" value case. keep optional for FSC
2425
var defaultValue: String?
26+
27+
enum CodingKeys: String, CodingKey {
28+
case id
29+
case key
30+
case type
31+
case subType
32+
case defaultValue
33+
}
34+
35+
init(id: String, key: String, type: String, subType: String?, defaultValue: String?) {
36+
self.id = id
37+
self.key = key
38+
self.type = type
39+
self.subType = subType
40+
self.defaultValue = defaultValue
41+
overrideTypeIfJSON()
42+
}
43+
44+
init(from decoder: Decoder) throws {
45+
let container = try decoder.container(keyedBy: CodingKeys.self)
46+
id = try container.decode(String.self, forKey: .id)
47+
key = try container.decode(String.self, forKey: .key)
48+
type = try container.decode(String.self, forKey: .type)
49+
subType = try container.decodeIfPresent(String.self, forKey: .subType)
50+
defaultValue = try container.decodeIfPresent(String.self, forKey: .defaultValue)
51+
overrideTypeIfJSON()
52+
}
53+
54+
mutating func overrideTypeIfJSON() {
55+
if type == "string" && subType == "json" {
56+
type = "json"
57+
}
58+
}
2559
}

Sources/Optimizely/OptimizelyClient+ObjC.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,27 @@ extension OptimizelyClient {
295295
attributes: attributes)
296296
}
297297

298+
@available(swift, obsoleted: 1.0)
299+
@objc(getFeatureVariableJSONWithFeatureKey:variableKey:userId:attributes:error:)
300+
/// Gets json feature variable value.
301+
///
302+
/// - Parameters:
303+
/// - featureKey: The key for the feature flag.
304+
/// - variableKey: The key for the variable.
305+
/// - userId: The user ID to be used for bucketing.
306+
/// - attributes: The user's attributes.
307+
/// - Returns: feature variable value of type OptimizelyJSON.
308+
/// - Throws: `OptimizelyError` if feature parameter is not valid
309+
public func objcGetFeatureVariableJSON(featureKey: String,
310+
variableKey: String,
311+
userId: String,
312+
attributes: [String: Any]?) throws -> OptimizelyJSON {
313+
return try self.getFeatureVariableJSON(featureKey: featureKey,
314+
variableKey: variableKey,
315+
userId: userId,
316+
attributes: attributes)
317+
}
318+
298319
@available(swift, obsoleted: 1.0)
299320
@objc(getEnabledFeaturesWithUserId:attributes:)
300321
/// Get array of features that are enabled for the user.

Sources/Optimizely/OptimizelyClient.swift

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,26 @@ open class OptimizelyClient: NSObject {
490490
attributes: attributes)
491491
}
492492

493+
/// Gets json feature variable value.
494+
///
495+
/// - Parameters:
496+
/// - featureKey: The key for the feature flag.
497+
/// - variableKey: The key for the variable.
498+
/// - userId: The user ID to be used for bucketing.
499+
/// - attributes: The user's attributes.
500+
/// - Returns: feature variable value of type OptimizelyJSON.
501+
/// - Throws: `OptimizelyError` if feature parameter is not valid
502+
public func getFeatureVariableJSON(featureKey: String,
503+
variableKey: String,
504+
userId: String,
505+
attributes: OptimizelyAttributes? = nil) throws -> OptimizelyJSON {
506+
507+
return try getFeatureVariable(featureKey: featureKey,
508+
variableKey: variableKey,
509+
userId: userId,
510+
attributes: attributes)
511+
}
512+
493513
func getFeatureVariable<T>(featureKey: String,
494514
variableKey: String,
495515
userId: String,
@@ -543,13 +563,18 @@ open class OptimizelyClient: NSObject {
543563
case is Bool.Type:
544564
typeName = "boolean"
545565
valueParsed = Bool(featureValue) as? T
566+
case is OptimizelyJSON.Type:
567+
typeName = "json"
568+
if let optimizelyJSON = OptimizelyJSON(payload: featureValue) {
569+
valueParsed = optimizelyJSON as? T
570+
}
546571
default:
547572
break
548573
}
549574

550575
guard let value = valueParsed,
551576
variable.type == typeName else {
552-
throw OptimizelyError.variableValueInvalid(variableKey)
577+
throw OptimizelyError.variableValueInvalid(variableKey)
553578
}
554579

555580
// Decision Notification
@@ -568,7 +593,7 @@ open class OptimizelyClient: NSObject {
568593
variableKey: variableKey,
569594
variableType: typeName,
570595
variableValue: value)
571-
596+
572597
return value
573598
}
574599

Tests/OptimizelyTests-APIs/OptimizelyClientTests_Invalid.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2019, Optimizely, Inc. and contributors *
2+
* Copyright 2019-2020, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -97,6 +97,13 @@ extension OptimizelyClientTests_Invalid {
9797
XCTAssertNil(result)
9898
}
9999

100+
func testGetFeatureVariableJSON_WhenManagerNonInitialized() {
101+
let result: OptimizelyJSON? = try? self.optimizely.getFeatureVariableJSON(featureKey: kFeatureKey,
102+
variableKey: kVariableKey,
103+
userId: kUserId)
104+
XCTAssertNil(result)
105+
}
106+
100107
func testGetEnabledFeatures_WhenManagerNonInitialized() {
101108
let result = self.optimizely.getEnabledFeatures(userId: kUserId)
102109
XCTAssert(result.count == 0)

Tests/OptimizelyTests-APIs/OptimizelyClientTests_ObjcAPIs.m

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2019, Optimizely, Inc. and contributors *
2+
* Copyright 2019-2020, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -31,11 +31,13 @@
3131
static NSString * const kVariableKeyInt = @"i_42";
3232
static NSString * const kVariableKeyDouble = @"d_4_2";
3333
static NSString * const kVariableKeyBool = @"b_true";
34+
static NSString * const kVariableKeyJSON = @"j_1";
3435

3536
static NSString * const kVariableValueString = @"foo";
3637
static const int kVariableValueInt = 42;
3738
static const double kVariableValueDouble = 4.2;
3839
static const BOOL kVariableValueBool = true;
40+
static NSString * const kVariableValueJSON = @"{\"value\":1}";
3941

4042
static NSString * const kEventKey = @"event1";
4143

@@ -191,6 +193,15 @@ - (void)testGetFeatureVariableString {
191193
error:nil];
192194
XCTAssertEqualObjects(result, kVariableValueString);
193195
}
196+
197+
- (void)testGetFeatureVariableJSON {
198+
OptimizelyJSON *result = [self.optimizely getFeatureVariableJSONWithFeatureKey:kFeatureKey
199+
variableKey:kVariableKeyJSON
200+
userId:kUserId
201+
attributes:self.attributes
202+
error:nil];
203+
XCTAssertEqualObjects([result toString], kVariableValueJSON);
204+
}
194205

195206
- (void)testGetEnabledFeatures {
196207
NSArray *result = [self.optimizely getEnabledFeaturesWithUserId:kUserId

Tests/OptimizelyTests-APIs/OptimizelyClientTests_Others.swift

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2019, Optimizely, Inc. and contributors *
2+
* Copyright 2019-2020, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -28,6 +28,9 @@ class OptimizelyClientTests_Others: XCTestCase {
2828

2929
let kVariableKeyString = "s_foo"
3030
let kInvalidVariableKeyString = "invalid_key"
31+
32+
let kVariableKeyJSON = "j_1"
33+
let kInvalidVariableKeyJSON = "invalid_key"
3134

3235
let kUserId = "user"
3336
let kNotRealSdkKey = "notrealkey123"
@@ -74,6 +77,14 @@ class OptimizelyClientTests_Others: XCTestCase {
7477
value = try? optimizely.getFeatureVariableString(featureKey: kInvalidFeatureKey, variableKey: kVariableKeyString, userId: kUserId)
7578
XCTAssertNil(value)
7679
}
80+
81+
func testGetFeatureVariableJSON_InvalidFeatureKey() {
82+
var value = try? optimizely.getFeatureVariableJSON(featureKey: kFeatureKey, variableKey: kVariableKeyJSON, userId: kUserId)
83+
XCTAssertNotNil(value)
84+
85+
value = try? optimizely.getFeatureVariableJSON(featureKey: kInvalidFeatureKey, variableKey: kVariableKeyJSON, userId: kUserId)
86+
XCTAssertNil(value)
87+
}
7788

7889
func testGetFeatureVariableString_InvalidVariableKey() {
7990
var value = try? optimizely.getFeatureVariableString(featureKey: kFeatureKey, variableKey: kVariableKeyString, userId: kUserId)
@@ -83,6 +94,14 @@ class OptimizelyClientTests_Others: XCTestCase {
8394
XCTAssertNil(value)
8495
}
8596

97+
func testGetFeatureVariableJSON_InvalidVariableKey() {
98+
var value = try? optimizely.getFeatureVariableJSON(featureKey: kFeatureKey, variableKey: kVariableKeyJSON, userId: kUserId)
99+
XCTAssertNotNil(value)
100+
101+
value = try? optimizely.getFeatureVariableJSON(featureKey: kFeatureKey, variableKey: kInvalidVariableKeyJSON, userId: kUserId)
102+
XCTAssertNil(value)
103+
}
104+
86105
func testGetFeatureVariable_WrongType() {
87106
// read integer for string-type variable
88107
let value = try? optimizely.getFeatureVariableInteger(featureKey: kFeatureKey, variableKey: kVariableKeyString, userId: kUserId)

Tests/OptimizelyTests-APIs/OptimizelyClientTests_Valid.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2019, Optimizely, Inc. and contributors *
2+
* Copyright 2019-2020, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -32,11 +32,13 @@ class OptimizelyClientTests_Valid: XCTestCase {
3232
let kVariableKeyInt = "i_42"
3333
let kVariableKeyDouble = "d_4_2"
3434
let kVariableKeyBool = "b_true"
35+
let kVariableKeyJSON = "j_1"
3536

3637
let kVariableValueString = "foo"
3738
let kVariableValueInt = 42
3839
let kVariableValueDouble = 4.2
3940
let kVariableValueBool = true
41+
let kVariableValueJSON = "{\"value\":1}"
4042

4143
let kEventKey = "event1"
4244

@@ -134,6 +136,17 @@ class OptimizelyClientTests_Valid: XCTestCase {
134136
XCTAssert(result == kVariableValueString)
135137
}
136138

139+
func testGetFeatureVariableJSON() {
140+
let result: OptimizelyJSON? = try? self.optimizely.getFeatureVariableJSON(featureKey: kFeatureKey,
141+
variableKey: kVariableKeyJSON,
142+
userId: kUserId)
143+
XCTAssert(result?.toString() == kVariableValueJSON)
144+
XCTAssert((result?.toMap()["value"] as! Int) == 1)
145+
var intValue: Int = 0
146+
XCTAssertTrue(result!.getValue(jsonPath: "value", schema: &intValue))
147+
XCTAssert(intValue == 1)
148+
}
149+
137150
func testGetEnabledFeatures() {
138151
let result: [String] = self.optimizely.getEnabledFeatures(userId: kUserId)
139152
XCTAssert(result == [kFeatureKey])

0 commit comments

Comments
 (0)