Skip to content

Commit 67220bb

Browse files
update: enhance CMAB UUID handling in decide method and verify dispatched events
1 parent db1c991 commit 67220bb

File tree

1 file changed

+48
-48
lines changed

1 file changed

+48
-48
lines changed

tests/test_optimizely.py

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5752,39 +5752,50 @@ def test_decide_returns_error_decision_when_decision_service_fails(self):
57525752
self.assertIn('CMAB service failed to fetch decision', decision.reasons)
57535753

57545754
def test_decide_includes_cmab_uuid_in_dispatched_event(self):
5755-
"""Test that decide calls UserEventFactory.create_impression_event with correct CMAB UUID."""
5755+
"""Test that decide dispatches event with correct CMAB UUID."""
57565756
import copy
5757+
from typing import List
57575758
config_dict = copy.deepcopy(self.config_dict_with_features)
57585759
config_dict['experiments'][0]['cmab'] = {'attributeIds': ['808797688', '808797689'], 'trafficAllocation': 4000}
57595760
config_dict['experiments'][0]['trafficAllocation'] = []
5760-
opt_obj = optimizely.Optimizely(json.dumps(config_dict))
5761+
5762+
class TestEventDispatcher:
5763+
"""Custom event dispatcher for testing that captures dispatched events."""
5764+
5765+
def __init__(self):
5766+
self.dispatched_events: List[event_builder.Event] = []
5767+
5768+
def dispatch_event(self, event: event_builder.Event) -> None:
5769+
"""Capture the event instead of actually dispatching it."""
5770+
self.dispatched_events.append(event)
5771+
5772+
test_dispatcher = TestEventDispatcher()
5773+
5774+
opt_obj = optimizely.Optimizely(json.dumps(config_dict), event_dispatcher=test_dispatcher)
57615775
user_context = opt_obj.create_user_context('test_user')
57625776
project_config = opt_obj.config_manager.get_config()
57635777

57645778
# Mock decision service to return a CMAB result
57655779
expected_cmab_uuid = 'uuid-cmab'
57665780
mock_experiment = project_config.get_experiment_from_key('test_experiment')
57675781
mock_variation = project_config.get_variation_from_id('test_experiment', '111129')
5768-
decision_result = {
5769-
'decision': decision_service.Decision(
5770-
mock_experiment,
5771-
mock_variation,
5772-
enums.DecisionSources.FEATURE_TEST,
5773-
expected_cmab_uuid
5774-
),
5775-
'reasons': [],
5776-
'error': False
5777-
}
57785782

5783+
# Create decision with CMAB UUID
5784+
decision_with_cmab = decision_service.Decision(
5785+
mock_experiment,
5786+
mock_variation,
5787+
enums.DecisionSources.FEATURE_TEST,
5788+
expected_cmab_uuid
5789+
)
5790+
5791+
# Mock the decision service method that's actually called by decide
57795792
with mock.patch.object(
57805793
opt_obj.decision_service, 'get_variations_for_feature_list',
5781-
return_value=[decision_result]
5782-
), mock.patch(
5783-
'optimizely.event.user_event_factory.UserEventFactory.create_impression_event'
5784-
) as mock_create_impression, mock.patch(
5785-
'time.time', return_value=42
5786-
), mock.patch(
5787-
'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'
5794+
return_value=[{
5795+
'decision': decision_with_cmab,
5796+
'reasons': [],
5797+
'error': False
5798+
}]
57885799
):
57895800
# Call decide
57905801
decision = user_context.decide('test_feature_in_experiment')
@@ -5795,32 +5806,21 @@ def test_decide_includes_cmab_uuid_in_dispatched_event(self):
57955806
self.assertEqual(decision.rule_key, 'test_experiment')
57965807
self.assertEqual(decision.flag_key, 'test_feature_in_experiment')
57975808

5798-
# Verify that create_impression_event was called once
5799-
mock_create_impression.assert_called_once()
5800-
5801-
# Get the call arguments
5802-
call_args = mock_create_impression.call_args[0]
5803-
5804-
# Verify the correct parameters were passed
5805-
project_config_arg = call_args[0]
5806-
experiment_arg = call_args[1]
5807-
variation_id_arg = call_args[2]
5808-
flag_key_arg = call_args[3]
5809-
rule_key_arg = call_args[4]
5810-
rule_type_arg = call_args[5]
5811-
enabled_arg = call_args[6]
5812-
user_id_arg = call_args[7]
5813-
attributes_arg = call_args[8]
5814-
cmab_uuid_arg = call_args[9]
5815-
5816-
# Verify all parameters
5817-
self.assertEqual(project_config_arg, project_config)
5818-
self.assertEqual(experiment_arg, mock_experiment)
5819-
self.assertEqual(variation_id_arg, '111129') # variation.id
5820-
self.assertEqual(flag_key_arg, 'test_feature_in_experiment')
5821-
self.assertEqual(rule_key_arg, 'test_experiment')
5822-
self.assertEqual(rule_type_arg, str(enums.DecisionSources.FEATURE_TEST))
5823-
self.assertTrue(enabled_arg)
5824-
self.assertEqual(user_id_arg, 'test_user')
5825-
self.assertEqual(attributes_arg, {})
5826-
self.assertEqual(cmab_uuid_arg, expected_cmab_uuid)
5809+
# Verify an event was dispatched
5810+
time.sleep(0.1)
5811+
self.assertEqual(len(test_dispatcher.dispatched_events), 1)
5812+
5813+
dispatched_event = test_dispatcher.dispatched_events[0]
5814+
5815+
# Verify the structure exists before accessing
5816+
self.assertIn('visitors', dispatched_event.params)
5817+
self.assertTrue(len(dispatched_event.params['visitors']) > 0)
5818+
self.assertIn('snapshots', dispatched_event.params['visitors'][0])
5819+
self.assertTrue(len(dispatched_event.params['visitors'][0]['snapshots']) > 0)
5820+
self.assertIn('decisions', dispatched_event.params['visitors'][0]['snapshots'][0])
5821+
self.assertTrue(len(dispatched_event.params['visitors'][0]['snapshots'][0]['decisions']) > 0)
5822+
5823+
# Get the metadata and assert CMAB UUID
5824+
metadata = dispatched_event.params['visitors'][0]['snapshots'][0]['decisions'][0]['metadata']
5825+
self.assertIn('cmab_uuid', metadata)
5826+
self.assertEqual(metadata['cmab_uuid'], expected_cmab_uuid)

0 commit comments

Comments
 (0)