@@ -2252,7 +2252,7 @@ describe('DecisionService', () => {
22522252 } ) ;
22532253 } ) ;
22542254
2255- it ( 'should return delivery variation when excludeTargetedDeliveries is true and delivery matches' , async ( ) => {
2255+ it ( 'should return delivery variation with holdout info when excludeTargetedDeliveries is true and delivery matches' , async ( ) => {
22562256 const { decisionService } = getDecisionService ( ) ;
22572257 const datafile = getExcludeTDDatafile ( true ) ;
22582258
@@ -2281,10 +2281,14 @@ describe('DecisionService', () => {
22812281 experiment : config . experimentKeyMap [ 'delivery_1' ] ,
22822282 variation : config . variationIdMap [ '5004' ] ,
22832283 decisionSource : DECISION_SOURCES . ROLLOUT ,
2284+ holdout : {
2285+ experiment : config . holdoutIdMap && config . holdoutIdMap [ 'holdout_running_id' ] ,
2286+ variation : config . variationIdMap [ 'holdout_variation_running_id' ] ,
2287+ } ,
22842288 } ) ;
22852289 } ) ;
22862290
2287- it ( 'should return holdout variation when excludeTargetedDeliveries is true but no delivery matches' , async ( ) => {
2291+ it ( 'should return null decision with holdout info when excludeTargetedDeliveries is true but no delivery matches' , async ( ) => {
22882292 const { decisionService } = getDecisionService ( ) ;
22892293 const datafile = getExcludeTDDatafile ( true ) ;
22902294
@@ -2307,9 +2311,13 @@ describe('DecisionService', () => {
23072311 const variation = ( await value ) [ 0 ] ;
23082312
23092313 expect ( variation . result ) . toEqual ( {
2310- experiment : config . holdoutIdMap && config . holdoutIdMap [ 'holdout_running_id' ] ,
2311- variation : config . variationIdMap [ 'holdout_variation_running_id' ] ,
2312- decisionSource : DECISION_SOURCES . HOLDOUT ,
2314+ experiment : null ,
2315+ variation : null ,
2316+ decisionSource : DECISION_SOURCES . ROLLOUT ,
2317+ holdout : {
2318+ experiment : config . holdoutIdMap && config . holdoutIdMap [ 'holdout_running_id' ] ,
2319+ variation : config . variationIdMap [ 'holdout_variation_running_id' ] ,
2320+ } ,
23132321 } ) ;
23142322 } ) ;
23152323
@@ -2338,12 +2346,14 @@ describe('DecisionService', () => {
23382346 const value = decisionService . resolveVariationsForFeatureList ( 'async' , config , [ feature ] , user , { } ) . get ( ) ;
23392347 const variation = ( await value ) [ 0 ] ;
23402348
2341- // Should NOT get exp_1 — holdout blocks experiments even with excludeTargetedDeliveries
2342- // Should get holdout since no delivery matched
23432349 expect ( variation . result ) . toEqual ( {
2344- experiment : config . holdoutIdMap && config . holdoutIdMap [ 'holdout_running_id' ] ,
2345- variation : config . variationIdMap [ 'holdout_variation_running_id' ] ,
2346- decisionSource : DECISION_SOURCES . HOLDOUT ,
2350+ experiment : null ,
2351+ variation : null ,
2352+ decisionSource : DECISION_SOURCES . ROLLOUT ,
2353+ holdout : {
2354+ experiment : config . holdoutIdMap && config . holdoutIdMap [ 'holdout_running_id' ] ,
2355+ variation : config . variationIdMap [ 'holdout_variation_running_id' ] ,
2356+ } ,
23472357 } ) ;
23482358 } ) ;
23492359 } ) ;
@@ -3252,6 +3262,34 @@ describe('DecisionService', () => {
32523262 expect ( value [ 0 ] . result . decisionSource ) . toBe ( DECISION_SOURCES . FEATURE_TEST ) ;
32533263 expect ( value [ 0 ] . result . variation ?. key ) . toBe ( 'variation_1' ) ;
32543264 } ) ;
3265+
3266+ it ( 'local holdout ignores excludeTargetedDeliveries and applies normally' , async ( ) => {
3267+ const datafile = makeLocalHoldoutDatafile ( '2001' ) ;
3268+ ( datafile as any ) . localHoldouts [ 0 ] . excludeTargetedDeliveries = true ;
3269+ const config = createProjectConfig ( JSON . stringify ( datafile ) ) ;
3270+ const { decisionService } = getDecisionService ( ) ;
3271+
3272+ mockBucket . mockImplementation ( ( params : BucketerParams ) => {
3273+ if ( params . experimentId === 'local_holdout_id' ) {
3274+ return { result : 'local_holdout_variation_id' , reasons : [ ] } ;
3275+ }
3276+ return { result : null , reasons : [ ] } ;
3277+ } ) ;
3278+
3279+ const user = new OptimizelyUserContext ( {
3280+ optimizely : { } as any ,
3281+ userId : 'user1' ,
3282+ attributes : { age : 15 } ,
3283+ } ) ;
3284+
3285+ const feature = config . featureKeyMap [ 'flag_1' ] ;
3286+ const value = await decisionService . resolveVariationsForFeatureList ( 'async' , config , [ feature ] , user , { } ) . get ( ) ;
3287+
3288+ // Local holdout applies normally even with excludeTargetedDeliveries set
3289+ expect ( value [ 0 ] . result . decisionSource ) . toBe ( DECISION_SOURCES . HOLDOUT ) ;
3290+ expect ( value [ 0 ] . result . experiment ?. id ) . toBe ( 'local_holdout_id' ) ;
3291+ expect ( value [ 0 ] . result . variation ?. id ) . toBe ( 'local_holdout_variation_id' ) ;
3292+ } ) ;
32553293 } ) ;
32563294} ) ;
32573295
0 commit comments