@@ -152,7 +152,7 @@ class OptimizelyUserContextTests_Decide_CMAB: XCTestCase {
152
152
wait ( for: [ expectation] , timeout: 5 ) // Increased timeout for reliability
153
153
}
154
154
155
- func testDecideAsync_cmabWithCaching ( ) {
155
+ func testDecideAsync_cmabWithUserProfileCahing ( ) {
156
156
let expectation1 = XCTestExpectation ( description: " First CMAB decision " )
157
157
let expectation2 = XCTestExpectation ( description: " Second CMAB decision " )
158
158
@@ -169,7 +169,7 @@ class OptimizelyUserContextTests_Decide_CMAB: XCTestCase {
169
169
attributes: [ " gender " : " f " , " age " : 25 ]
170
170
)
171
171
172
- // First decision
172
+ // First decision cache into user profile
173
173
user. decideAsync ( key: " feature_1 " ) { decision in
174
174
XCTAssertEqual ( decision. variationKey, " a " )
175
175
XCTAssertEqual ( self . mockCmabService. decisionCallCount, 1 )
@@ -186,38 +186,44 @@ class OptimizelyUserContextTests_Decide_CMAB: XCTestCase {
186
186
187
187
wait ( for: [ expectation1, expectation2] , timeout: 1 )
188
188
}
189
- // FixMe: Need to fix the test case
190
- // func testDecideAsync_cmabWithIgnoreCache() {
191
- // let expectation = XCTestExpectation(description: "CMAB ignore cache")
192
- // // Set up the CMAB experiment
193
- // let cmab: Cmab = try! OTUtils.model(from: ["trafficAllocation": 10000, "attributeIds": ["10389729780"]])
194
- // var experiments = optimizely.config!.project.experiments
195
- // experiments[0].cmab = cmab
196
- // optimizely.config?.project.experiments = experiments
197
- // mockCmabService.variationId = "10389729780" // corresponds to variation "a"
198
- //
199
- // // Create user with attributes that match CMAB experiment
200
- // let user = optimizely.createUserContext(
201
- // userId: kUserId,
202
- // attributes: ["gender": "f", "age": 25]
203
- // )
204
- //
205
- // // Make decision with ignoreCmabCache option
206
- // user.decideAsync(
207
- // key: "feature_1",
208
- // options: [.ignoreCmabCache, .ignoreUserProfileService]
209
- // ) { decision in
210
- // XCTAssertEqual(decision.variationKey, "a")
211
- // XCTAssertTrue(self.mockCmabService.decisionCalled)
212
- // XCTAssertTrue(self.mockCmabService.ignoreCacheUsed)
213
- // expectation.fulfill()
214
- // }
215
- //
216
- // wait(for: [expectation], timeout: 1)
217
- // }
218
-
219
-
220
189
190
+ func testDecideAsync_cmabCacheOptions( ) {
191
+ let exp1 = XCTestExpectation ( description: " First call " )
192
+ let exp2 = XCTestExpectation ( description: " Second call " )
193
+ let exp3 = XCTestExpectation ( description: " Third call " )
194
+
195
+
196
+ // Set up the CMAB experiment
197
+ let cmab : Cmab = try ! OTUtils . model ( from: [ " trafficAllocation " : 10000 , " attributeIds " : [ " 10389729780 " ] ] )
198
+ var experiments = optimizely. config!. project. experiments
199
+ experiments [ 0 ] . cmab = cmab
200
+ optimizely. config? . project. experiments = experiments
201
+ mockCmabService. variationId = " 10389729780 " // corresponds to variation "a"
202
+
203
+ // Create user with attributes that match CMAB experiment
204
+ let user = optimizely. createUserContext (
205
+ userId: kUserId,
206
+ attributes: [ " gender " : " f " , " age " : 25 ]
207
+ )
208
+ user. decideAsync ( key: " feature_1 " , options: [ . ignoreUserProfileService, . ignoreCmabCache] ) { decision in
209
+ XCTAssertEqual ( decision. variationKey, " a " )
210
+ XCTAssertTrue ( self . mockCmabService. ignoreCacheUsed)
211
+ exp1. fulfill ( )
212
+ }
213
+ user. decideAsync ( key: " feature_1 " , options: [ . ignoreUserProfileService, . resetCmabCache] ) { decision in
214
+ XCTAssertEqual ( decision. variationKey, " a " )
215
+ XCTAssertTrue ( self . mockCmabService. resetCacheCache)
216
+ exp2. fulfill ( )
217
+ }
218
+ user. decideAsync ( key: " feature_1 " , options: [ . ignoreUserProfileService, . invalidateUserCmabCache] ) { decision in
219
+ XCTAssertEqual ( decision. variationKey, " a " )
220
+ XCTAssertTrue ( self . mockCmabService. invalidateUserCmabCache)
221
+ exp3. fulfill ( )
222
+ }
223
+ wait ( for: [ exp1, exp2, exp3] , timeout: 1 )
224
+
225
+ }
226
+
221
227
func testDecideAsync_cmabError( ) {
222
228
let expectation = XCTestExpectation ( description: " CMAB error handling " )
223
229
// Set up the CMAB experiment
@@ -244,25 +250,27 @@ class OptimizelyUserContextTests_Decide_CMAB: XCTestCase {
244
250
245
251
}
246
252
247
-
248
253
fileprivate class MockCmabService : DefaultCmabService {
249
254
var variationId : String ?
250
255
var error : Error ?
251
256
var decisionCalled = false
252
257
var decisionCallCount = 0
253
258
var lastRuleId : String ?
254
259
var ignoreCacheUsed = false
260
+ var resetCacheCache = false
261
+ var invalidateUserCmabCache = false
255
262
256
263
init ( ) {
257
264
super. init ( cmabClient: DefaultCmabClient ( ) , cmabCache: LruCache ( size: 10 , timeoutInSecs: 10 ) )
258
265
}
259
266
260
267
override func getDecision( config: ProjectConfig , userContext: OptimizelyUserContext , ruleId: String , options: [ OptimizelyDecideOption ] ) -> Result < CmabDecision , any Error > {
261
268
decisionCalled = true
262
- decisionCallCount += 1
263
269
lastRuleId = ruleId
264
270
ignoreCacheUsed = options. contains ( . ignoreCmabCache)
265
-
271
+ resetCacheCache = options. contains ( . resetCmabCache)
272
+ invalidateUserCmabCache = options. contains ( . invalidateUserCmabCache)
273
+ decisionCallCount += 1
266
274
if let error = error {
267
275
return . failure( error)
268
276
}
0 commit comments