Skip to content

Commit 4adc0a0

Browse files
Test case updated
1 parent 283608e commit 4adc0a0

File tree

1 file changed

+142
-33
lines changed

1 file changed

+142
-33
lines changed

Tests/OptimizelyTests-Common/OptimizelyUserContextTests_Decide_Reasons.swift

Lines changed: 142 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -106,35 +106,53 @@ extension OptimizelyUserContextTests_Decide_Reasons {
106106
XCTAssert(decision.reasons.contains(OptimizelyError.conditionInvalidFormat("Empty condition array").reason))
107107
}
108108

109-
// func testDecideReasons_evaluateAttributeInvalidCondition() {
110-
// let featureKey = "feature_1"
111-
// let audienceId = "invalid_condition"
112-
// setAudienceForFeatureTest(featureKey: featureKey, audienceId: audienceId)
113-
//
114-
// let condition = "{\"match\":\"gt\",\"value\":\"US\",\"name\":\"age\",\"type\":\"custom_attribute\"}"
115-
// user.setAttribute(key: "age", value: 25)
116-
//
117-
// var decision = user.decide(key: featureKey)
118-
// XCTAssert(decision.reasons.isEmpty)
119-
// decision = user.decide(key: featureKey, options: [.includeReasons])
120-
// XCTAssert(decision.reasons.contains(OptimizelyError.evaluateAttributeInvalidCondition(condition).reason))
121-
// }
109+
func testDecideReasons_evaluateAttributeInvalidCondition() {
110+
let featureKey = "feature_1"
111+
let audienceId = "invalid_condition"
112+
setAudienceForFeatureTest(featureKey: featureKey, audienceId: audienceId)
113+
114+
let condition = "{\"match\":\"gt\",\"value\":\"US\",\"name\":\"age\",\"type\":\"custom_attribute\"}"
115+
user.setAttribute(key: "age", value: 25)
116+
117+
var decision = user.decide(key: featureKey)
118+
XCTAssert(decision.reasons.isEmpty)
119+
decision = user.decide(key: featureKey, options: [.includeReasons])
120+
121+
let expectedReason = OptimizelyError.evaluateAttributeInvalidCondition(condition).reason
122+
123+
// Look for a matching reason in the decision.reasons array
124+
let foundMatchingReason = matchReason(expectedReason: expectedReason, in: decision.reasons)
125+
126+
XCTAssert(foundMatchingReason, "Expected reason with matching condition not found in decision reasons")
127+
128+
//XCTAssert(decision.reasons.contains(OptimizelyError.evaluateAttributeInvalidCondition(condition).reason))
129+
}
122130

123-
// func testDecideReasons_evaluateAttributeInvalidType() {
124-
// let featureKey = "feature_1"
125-
// let audienceId = "13389130056"
126-
// setAudienceForFeatureTest(featureKey: featureKey, audienceId: audienceId)
127-
//
128-
// let condition = "{\"match\":\"exact\",\"value\":\"US\",\"name\":\"country\",\"type\":\"custom_attribute\"}"
129-
// let attributeKey = "country"
130-
// let attributeValue = 25
131-
// user.setAttribute(key: attributeKey, value: attributeValue)
132-
//
133-
// var decision = user.decide(key: featureKey)
134-
// XCTAssert(decision.reasons.isEmpty)
131+
func testDecideReasons_evaluateAttributeInvalidType() {
132+
let featureKey = "feature_1"
133+
let audienceId = "13389130056"
134+
setAudienceForFeatureTest(featureKey: featureKey, audienceId: audienceId)
135+
136+
let condition = "{\"match\":\"exact\",\"value\":\"US\",\"name\":\"country\",\"type\":\"custom_attribute\"}"
137+
let attributeKey = "country"
138+
let attributeValue = 25
139+
user.setAttribute(key: attributeKey, value: attributeValue)
140+
141+
var decision = user.decide(key: featureKey)
142+
XCTAssert(decision.reasons.isEmpty)
143+
144+
decision = user.decide(key: featureKey, options: [.includeReasons])
145+
146+
let expectedReason = OptimizelyError.evaluateAttributeInvalidType(condition, attributeValue, attributeKey).reason
147+
148+
// Look for a matching reason in the decision.reasons array
149+
let foundMatchingReason = matchReason(expectedReason: expectedReason, in: decision.reasons)
150+
151+
XCTAssert(foundMatchingReason, "Expected reason with matching condition not found in decision reasons")
152+
135153
// decision = user.decide(key: featureKey, options: [.includeReasons])
136154
// XCTAssert(decision.reasons.contains(OptimizelyError.evaluateAttributeInvalidType(condition, attributeValue, attributeKey).reason))
137-
// }
155+
}
138156

139157
func testDecideReasons_evaluateAttributeValueOutOfRange() {
140158
let featureKey = "feature_1"
@@ -146,8 +164,17 @@ extension OptimizelyUserContextTests_Decide_Reasons {
146164

147165
var decision = user.decide(key: featureKey)
148166
XCTAssert(decision.reasons.isEmpty)
167+
149168
decision = user.decide(key: featureKey, options: [.includeReasons])
150-
XCTAssert(decision.reasons.contains(OptimizelyError.evaluateAttributeValueOutOfRange(condition, "age").reason))
169+
170+
let expectedReason = OptimizelyError.evaluateAttributeValueOutOfRange(condition, "age").reason
171+
172+
// Look for a matching reason in the decision.reasons array
173+
let foundMatchingReason = matchReason(expectedReason: expectedReason, in: decision.reasons)
174+
175+
XCTAssert(foundMatchingReason, "Expected reason with matching condition not found in decision reasons")
176+
177+
//XCTAssert(decision.reasons.contains(OptimizelyError.evaluateAttributeValueOutOfRange(condition, "age").reason))
151178
}
152179

153180
func testDecideReasons_userAttributeInvalidType() {
@@ -161,7 +188,15 @@ extension OptimizelyUserContextTests_Decide_Reasons {
161188
var decision = user.decide(key: featureKey)
162189
XCTAssert(decision.reasons.isEmpty)
163190
decision = user.decide(key: featureKey, options: [.includeReasons])
164-
XCTAssert(decision.reasons.contains(OptimizelyError.userAttributeInvalidType(condition).reason))
191+
192+
let expectedReason = OptimizelyError.userAttributeInvalidType(condition).reason
193+
194+
// Look for a matching reason in the decision.reasons array
195+
let foundMatchingReason = matchReason(expectedReason: expectedReason, in: decision.reasons)
196+
197+
XCTAssert(foundMatchingReason, "Expected reason with matching condition not found in decision reasons")
198+
199+
//XCTAssert(decision.reasons.contains(OptimizelyError.userAttributeInvalidType(condition).reason))
165200
}
166201

167202
func testDecideReasons_userAttributeInvalidMatch() {
@@ -175,7 +210,15 @@ extension OptimizelyUserContextTests_Decide_Reasons {
175210
var decision = user.decide(key: featureKey)
176211
XCTAssert(decision.reasons.isEmpty)
177212
decision = user.decide(key: featureKey, options: [.includeReasons])
178-
XCTAssert(decision.reasons.contains(OptimizelyError.userAttributeInvalidMatch(condition).reason))
213+
214+
let expectedReason = OptimizelyError.userAttributeInvalidMatch(condition).reason
215+
216+
// Look for a matching reason in the decision.reasons array
217+
let foundMatchingReason = matchReason(expectedReason: expectedReason, in: decision.reasons)
218+
219+
XCTAssert(foundMatchingReason, "Expected reason with matching condition not found in decision reasons")
220+
221+
//XCTAssert(decision.reasons.contains(OptimizelyError.userAttributeInvalidMatch(condition).reason))
179222
}
180223

181224
func testDecideReasons_userAttributeNilValue() {
@@ -188,8 +231,17 @@ extension OptimizelyUserContextTests_Decide_Reasons {
188231

189232
var decision = user.decide(key: featureKey)
190233
XCTAssert(decision.reasons.isEmpty)
234+
191235
decision = user.decide(key: featureKey, options: [.includeReasons])
192-
XCTAssert(decision.reasons.contains(OptimizelyError.userAttributeNilValue(condition).reason))
236+
237+
let expectedReason = OptimizelyError.userAttributeNilValue(condition).reason
238+
239+
// Look for a matching reason in the decision.reasons array
240+
let foundMatchingReason = matchReason(expectedReason: expectedReason, in: decision.reasons)
241+
242+
XCTAssert(foundMatchingReason, "Expected reason with matching condition not found in decision reasons")
243+
244+
// XCTAssert(decision.reasons.contains(OptimizelyError.userAttributeNilValue(condition).reason))
193245
}
194246

195247
func testDecideReasons_userAttributeInvalidName() {
@@ -202,8 +254,17 @@ extension OptimizelyUserContextTests_Decide_Reasons {
202254

203255
var decision = user.decide(key: featureKey)
204256
XCTAssert(decision.reasons.isEmpty)
257+
205258
decision = user.decide(key: featureKey, options: [.includeReasons])
206-
XCTAssert(decision.reasons.contains(OptimizelyError.userAttributeInvalidName(condition).reason))
259+
260+
let expectedReason = OptimizelyError.userAttributeInvalidName(condition).reason
261+
262+
// Look for a matching reason in the decision.reasons array
263+
let foundMatchingReason = matchReason(expectedReason: expectedReason, in: decision.reasons)
264+
265+
XCTAssert(foundMatchingReason, "Expected reason with matching condition not found in decision reasons")
266+
267+
//XCTAssert(decision.reasons.contains(OptimizelyError.userAttributeInvalidName(condition).reason))
207268
}
208269

209270
func testDecideReasons_missingAttributeValue() {
@@ -215,8 +276,17 @@ extension OptimizelyUserContextTests_Decide_Reasons {
215276

216277
var decision = user.decide(key: featureKey)
217278
XCTAssert(decision.reasons.isEmpty)
279+
218280
decision = user.decide(key: featureKey, options: [.includeReasons])
219-
XCTAssert(decision.reasons.contains(OptimizelyError.missingAttributeValue(condition, "age").reason))
281+
282+
let expectedReason = OptimizelyError.missingAttributeValue(condition, "age").reason
283+
284+
// Look for a matching reason in the decision.reasons array
285+
let foundMatchingReason = matchReason(expectedReason: expectedReason, in: decision.reasons)
286+
287+
XCTAssert(foundMatchingReason, "Expected reason with matching condition not found in decision reasons")
288+
289+
//XCTAssert(decision.reasons.contains(OptimizelyError.missingAttributeValue(condition, "age").reason))
220290
}
221291

222292
}
@@ -462,7 +532,46 @@ extension OptimizelyUserContextTests_Decide_Reasons {
462532
// Utils
463533

464534
extension OptimizelyUserContextTests_Decide_Reasons {
465-
535+
func matchReason(expectedReason: String, in reasons: [String]) -> Bool {
536+
// Extract the condition JSON and remaining strings from expectedReason
537+
let (expectedPrefix, expectedJsonCondition, expectedSuffix) = extractComponents(from: expectedReason) ?? ("", [:], "")
538+
539+
// Look for a matching reason in the decision.reasons array
540+
let foundMatchingReason = reasons.contains { reason in
541+
guard let (actualPrefix, actualJsonCondition, actualSuffix) = extractComponents(from: reason) else {
542+
return false
543+
}
544+
545+
// Check if the prefix and suffix match exactly and the JSON conditions match ignoring key order
546+
return expectedPrefix == actualPrefix &&
547+
expectedSuffix == actualSuffix &&
548+
NSDictionary(dictionary: expectedJsonCondition) == NSDictionary(dictionary: actualJsonCondition)
549+
}
550+
return foundMatchingReason
551+
}
552+
553+
// Helper function to extract prefix, JSON condition, and suffix from the reason string
554+
func extractComponents(from reason: String) -> (String, [String: Any], String)? {
555+
// Use regular expression to extract the parts of the string before, inside, and after the parentheses
556+
let pattern = "^(.*?)\\((.*?)\\)(.*?)$"
557+
let regex = try? NSRegularExpression(pattern: pattern)
558+
let nsString = reason as NSString
559+
if let match = regex?.firstMatch(in: reason, range: NSRange(location: 0, length: nsString.length)) {
560+
let prefix = nsString.substring(with: match.range(at: 1)) // Part before the parentheses
561+
let jsonString = nsString.substring(with: match.range(at: 2)) // JSON inside parentheses
562+
let suffix = nsString.substring(with: match.range(at: 3)) // Part after the parentheses
563+
564+
// Convert the JSON string into a dictionary
565+
if let data = jsonString.data(using: .utf8),
566+
let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []),
567+
let jsonDict = jsonObject as? [String: Any] {
568+
return (prefix, jsonDict, suffix)
569+
}
570+
}
571+
572+
return nil
573+
}
574+
466575
func setAudienceForFeatureTest(featureKey: String, audienceId: String) {
467576
let experimentId = "10390977673" // "exp_with_audience"
468577
var experiment = optimizely.config!.getExperiment(id: experimentId)!

0 commit comments

Comments
 (0)