@@ -1818,6 +1818,55 @@ def test_legacy_api_skips_local_holdout_rule_without_holdout_event(self):
18181818 self .assertEqual ([(c .args [4 ], c .args [5 ]) for c in mock_send .call_args_list ],
18191819 [('211147' , str (enums .DecisionSources .ROLLOUT ))])
18201820
1821+ def test_disable_decision_event_suppresses_local_holdout_event (self ):
1822+ """DISABLE_DECISION_EVENT suppresses the holdout impression for a skipped rule."""
1823+ opt = self ._make_opt_exp_with_rollout ([_holdout ('lh_exp' , 'for_exp' , included_rules = ['111127' ])])
1824+
1825+ with mock .patch .object (opt , '_send_impression_event' , wraps = opt ._send_impression_event ) as mock_send :
1826+ decision = opt .create_user_context ('test_user' , {}).decide (
1827+ 'test_feature_in_experiment' , [OptimizelyDecideOption .DISABLE_DECISION_EVENT ]
1828+ )
1829+
1830+ self .assertEqual (decision .rule_key , '211147' )
1831+ mock_send .assert_not_called ()
1832+
1833+ def test_local_holdout_hit_on_first_experiment_then_second_experiment_serves (self ):
1834+ """Held out of the first experiment rule; the second experiment rule serves."""
1835+ cfg = copy .deepcopy (self .config_dict_with_features )
1836+ cfg ['experiments' ].append ({
1837+ 'key' : 'second_experiment' ,
1838+ 'status' : 'Running' ,
1839+ 'forcedVariations' : {},
1840+ 'layerId' : '111183' ,
1841+ 'audienceIds' : [],
1842+ 'trafficAllocation' : [{'entityId' : '111141' , 'endOfRange' : 10000 }],
1843+ 'id' : '111140' ,
1844+ 'variations' : [{'key' : 'second_variation' , 'id' : '111141' , 'featureEnabled' : True , 'variables' : []}],
1845+ })
1846+ for flag in cfg ['featureFlags' ]:
1847+ if flag ['key' ] == 'test_feature_in_experiment' :
1848+ flag ['experimentIds' ] = ['111127' , '111140' ]
1849+ cfg ['holdouts' ] = []
1850+ cfg ['localHoldouts' ] = [_holdout ('lh_exp' , 'for_exp' , included_rules = ['111127' ])]
1851+ self .opt_obj = opt = optimizely_module .Optimizely (json .dumps (cfg ))
1852+ config = opt .config_manager .get_config ()
1853+
1854+ result = self ._decision_svc ().get_decision_for_flag (
1855+ config .get_feature_from_key ('test_feature_in_experiment' ), opt .create_user_context ('test_user' , {}), config
1856+ )
1857+ self .assertEqual (result ['decision' ].source , enums .DecisionSources .FEATURE_TEST )
1858+ self .assertEqual (result ['decision' ].experiment .id , '111140' )
1859+ self .assertEqual ([d .experiment .key for d in result ['holdout_decisions' ]], ['for_exp' ])
1860+
1861+ with mock .patch .object (opt , '_send_impression_event' , wraps = opt ._send_impression_event ) as mock_send :
1862+ decision = opt .create_user_context ('test_user' , {}).decide ('test_feature_in_experiment' )
1863+
1864+ self .assertEqual (decision .rule_key , 'second_experiment' )
1865+ self .assertEqual (decision .variation_key , 'second_variation' )
1866+ self .assertEqual (self ._holdout_impressions (mock_send ), ['for_exp' ])
1867+ self .assertEqual (mock_send .call_count , 2 )
1868+ self .assertEqual (mock_send .call_args_list [1 ].args [5 ], str (enums .DecisionSources .FEATURE_TEST ))
1869+
18211870
18221871# ---------------------------------------------------------------------------
18231872# Exclude Targeted Deliveries Tests
0 commit comments