@@ -154,7 +154,7 @@ def test_activate__feature(session_obj, feature_key, expected_response,
154154 assert resp .status_code == expected_status_code , resp .text
155155
156156
157- expected_activate_type_exper = """[
157+ expected_activate_type_exper_base = """[
158158 {
159159 "userId": "matjaz",
160160 "experimentKey": "feature_2_test",
@@ -173,7 +173,7 @@ def test_activate__feature(session_obj, feature_key, expected_response,
173173 }
174174]"""
175175
176- expected_activate_type_feat = """[
176+ expected_activate_type_feat_base = """[
177177 {
178178 "userId": "matjaz",
179179 "experimentKey": "feature_2_test",
@@ -232,8 +232,8 @@ def test_activate__feature(session_obj, feature_key, expected_response,
232232
233233
234234@pytest .mark .parametrize ("decision_type, expected_response, expected_status_code, bypass_validation_request" , [
235- ("experiment" , expected_activate_type_exper , 200 , False ),
236- ("feature" , expected_activate_type_feat , 200 , False ),
235+ ("experiment" , expected_activate_type_exper_base , 200 , False ),
236+ ("feature" , expected_activate_type_feat_base , 200 , False ),
237237 ("invalid decision type" , {'error' : 'type "invalid decision type" not supported' }, 400 , True ),
238238 ("" , {'error' : 'type "" not supported' }, 400 , True )
239239], ids = ["experiment decision type" , "feature decision type" , "invalid decision type" , "empty decision type" ])
@@ -255,10 +255,47 @@ def test_activate__type(session_obj, decision_type, expected_response,
255255 resp = create_and_validate_request_and_response (ENDPOINT_ACTIVATE , 'post' , session_obj , bypass_validation_request ,
256256 payload = payload , params = params )
257257
258- if decision_type in ['experiment' , 'feature' ]:
259- sorted_actual = sort_response (
260- resp .json (), 'experimentKey' , 'featureKey' )
261- sorted_expected = sort_response (json .loads (expected_response ), 'experimentKey' , 'featureKey' )
258+ if decision_type == 'experiment' :
259+ # For experiment type, verify base experiments plus CMAB experiment
260+ actual_results = resp .json ()
261+ expected_base = json .loads (expected_response )
262+
263+ # Check we have the expected count (2 base + 1 CMAB)
264+ assert len (actual_results ) == 3 , f"Expected 3 experiments, got { len (actual_results )} "
265+
266+ # Find and verify CMAB experiment
267+ cmab_result = next ((r for r in actual_results if r ['experimentKey' ] == 'cmab-rule_1' ), None )
268+ assert cmab_result is not None , "CMAB experiment not found"
269+ assert cmab_result ['userId' ] == 'matjaz'
270+ assert cmab_result ['featureKey' ] == ''
271+ assert cmab_result ['variationKey' ] in ['on' , 'off' ], f"Unexpected CMAB variation: { cmab_result ['variationKey' ]} "
272+ assert cmab_result ['type' ] == 'experiment'
273+
274+ # Verify base experiments (excluding CMAB)
275+ base_results = [r for r in actual_results if r ['experimentKey' ] != 'cmab-rule_1' ]
276+ sorted_actual = sort_response (base_results , 'experimentKey' , 'featureKey' )
277+ sorted_expected = sort_response (expected_base , 'experimentKey' , 'featureKey' )
278+ assert sorted_actual == sorted_expected
279+ elif decision_type == 'feature' :
280+ # For feature type, verify base features plus CMAB feature
281+ actual_results = resp .json ()
282+ expected_base = json .loads (expected_response )
283+
284+ # Check we have the expected count (6 base + 1 CMAB)
285+ assert len (actual_results ) == 7 , f"Expected 7 features, got { len (actual_results )} "
286+
287+ # Find and verify CMAB feature
288+ cmab_result = next ((r for r in actual_results if r ['featureKey' ] == 'cmab_flag' ), None )
289+ assert cmab_result is not None , "CMAB feature not found"
290+ assert cmab_result ['userId' ] == 'matjaz'
291+ assert cmab_result ['experimentKey' ] == 'cmab-rule_1'
292+ assert cmab_result ['variationKey' ] in ['on' , 'off' ], f"Unexpected CMAB variation: { cmab_result ['variationKey' ]} "
293+ assert cmab_result ['type' ] == 'feature'
294+
295+ # Verify base features (excluding CMAB)
296+ base_results = [r for r in actual_results if r ['featureKey' ] != 'cmab_flag' ]
297+ sorted_actual = sort_response (base_results , 'experimentKey' , 'featureKey' )
298+ sorted_expected = sort_response (expected_base , 'experimentKey' , 'featureKey' )
262299 assert sorted_actual == sorted_expected
263300 elif resp .json ()['error' ]:
264301 with pytest .raises (requests .exceptions .HTTPError ):
@@ -476,7 +513,7 @@ def test_activate__enabled(session_obj, enabled, experimentKey, featureKey,
476513# #######################################################
477514
478515
479- expected_activate_with_config = """[
516+ expected_activate_with_config_base = """[
480517 {
481518 "userId": "matjaz",
482519 "experimentKey": "ab_test1",
@@ -556,8 +593,8 @@ def test_activate_with_config(session_obj):
556593 validates against the whole response body.
557594
558595 In "activate"
559- Request payload defines the “ who” (user id and attributes)
560- while the query parameters define the “ what” (feature, experiment, etc)
596+ Request payload defines the " who" (user id and attributes)
597+ while the query parameters define the " what" (feature, experiment, etc)
561598
562599 Request parameter is a list of experiment keys or feature keys.
563600 If you want both add both and separate them with comma.
@@ -594,9 +631,29 @@ def test_activate_with_config(session_obj):
594631 resp_activate = create_and_validate_request_and_response (ENDPOINT_ACTIVATE , 'post' , session_obj , payload = payload ,
595632 params = params )
596633
597- sorted_actual = sort_response (resp_activate .json (), 'experimentKey' , 'featureKey' )
598- sorted_expected = sort_response (json .loads (expected_activate_with_config ),
599- 'experimentKey' ,
600- 'featureKey' )
634+ actual_results = resp_activate .json ()
635+ expected_base = json .loads (expected_activate_with_config_base )
636+
637+ # Find CMAB entries (experiment and feature versions)
638+ cmab_experiment = next ((r for r in actual_results if r .get ('experimentKey' ) == 'cmab-rule_1' and r .get ('featureKey' ) == '' ), None )
639+ cmab_feature = next ((r for r in actual_results if r .get ('featureKey' ) == 'cmab_flag' ), None )
640+
641+ # Verify CMAB experiment entry exists and is valid
642+ assert cmab_experiment is not None , "CMAB experiment not found"
643+ assert cmab_experiment ['variationKey' ] in ['on' , 'off' ]
644+ assert cmab_experiment ['type' ] == 'experiment'
645+
646+ # Verify CMAB feature entry exists and is valid
647+ assert cmab_feature is not None , "CMAB feature not found"
648+ assert cmab_feature ['experimentKey' ] == 'cmab-rule_1'
649+ assert cmab_feature ['variationKey' ] in ['on' , 'off' ]
650+ assert cmab_feature ['type' ] == 'feature'
651+
652+ # Verify base results (excluding CMAB entries)
653+ base_results = [r for r in actual_results if r .get ('experimentKey' ) != 'cmab-rule_1' or r .get ('featureKey' ) != '' ]
654+ base_results = [r for r in base_results if r .get ('featureKey' ) != 'cmab_flag' ]
655+
656+ sorted_actual = sort_response (base_results , 'experimentKey' , 'featureKey' )
657+ sorted_expected = sort_response (expected_base , 'experimentKey' , 'featureKey' )
601658
602659 assert sorted_actual == sorted_expected
0 commit comments