@@ -2291,173 +2291,6 @@ public void testDecide_withDefaultDecideOptions() throws IOException {
22912291 assertTrue (decision .getReasons ().size () > 0 );
22922292 }
22932293
2294- // Holdout Tests
2295-
2296- private OptimizelyClient createOptimizelyClientWithHoldouts (Context context ) throws IOException {
2297- String holdoutDatafile = loadRawResource (context , R .raw .holdouts_project_config );
2298- OptimizelyManager optimizelyManager = OptimizelyManager .builder (testProjectId ).build (context );
2299- optimizelyManager .initialize (context , holdoutDatafile );
2300- return optimizelyManager .getOptimizely ();
2301- }
2302-
2303- @ Test
2304- public void testDecide_withHoldout () throws IOException {
2305- assumeTrue (datafileVersion == Integer .parseInt (ProjectConfig .Version .V4 .toString ()));
2306-
2307- Context context = InstrumentationRegistry .getInstrumentation ().getTargetContext ();
2308- OptimizelyClient optimizelyClient = createOptimizelyClientWithHoldouts (context );
2309-
2310- String flagKey = "boolean_feature" ;
2311- String userId = "user123" ;
2312- String variationKey = "ho_off_key" ;
2313- String ruleKey = "basic_holdout" ;
2314-
2315- Map <String , Object > attributes = new HashMap <>();
2316- attributes .put ("$opt_bucketing_id" , "ppid160000" ); // deterministic bucketing into basic_holdout
2317- attributes .put ("nationality" , "English" ); // non-reserved attribute
2318-
2319- OptimizelyUserContext userContext = optimizelyClient .createUserContext (userId , attributes );
2320- OptimizelyDecision decision = userContext .decide (flagKey , Collections .singletonList (OptimizelyDecideOption .INCLUDE_REASONS ));
2321-
2322- // Validate holdout decision
2323- assertEquals (flagKey , decision .getFlagKey ());
2324- assertEquals (variationKey , decision .getVariationKey ());
2325- assertEquals (ruleKey , decision .getRuleKey ());
2326- assertFalse (decision .getEnabled ());
2327- assertTrue (decision .getVariables ().toMap ().isEmpty ());
2328- assertTrue ("Expected holdout reason" , decision .getReasons ().stream ()
2329- .anyMatch (reason -> reason .contains ("holdout" )));
2330- }
2331-
2332- @ Test
2333- public void testDecideForKeys_withHoldout () throws IOException {
2334- assumeTrue (datafileVersion == Integer .parseInt (ProjectConfig .Version .V4 .toString ()));
2335-
2336- Context context = InstrumentationRegistry .getInstrumentation ().getTargetContext ();
2337- OptimizelyClient optimizelyClient = createOptimizelyClientWithHoldouts (context );
2338-
2339- String userId = "user123" ;
2340- String variationKey = "ho_off_key" ;
2341- String ruleKey = "basic_holdout" ;
2342-
2343- Map <String , Object > attributes = new HashMap <>();
2344- attributes .put ("$opt_bucketing_id" , "ppid160000" ); // deterministic bucketing into basic_holdout
2345-
2346- List <String > flagKeys = Arrays .asList (
2347- "boolean_feature" ,
2348- "double_single_variable_feature" ,
2349- "integer_single_variable_feature"
2350- );
2351-
2352- OptimizelyUserContext userContext = optimizelyClient .createUserContext (userId , attributes );
2353- Map <String , OptimizelyDecision > decisions = userContext .decideForKeys (flagKeys , Collections .singletonList (OptimizelyDecideOption .INCLUDE_REASONS ));
2354-
2355- assertEquals (3 , decisions .size ());
2356-
2357- for (String flagKey : flagKeys ) {
2358- OptimizelyDecision decision = decisions .get (flagKey );
2359- assertNotNull ("Missing decision for flag " + flagKey , decision );
2360- assertEquals (flagKey , decision .getFlagKey ());
2361- assertEquals (variationKey , decision .getVariationKey ());
2362- assertEquals (ruleKey , decision .getRuleKey ());
2363- assertFalse (decision .getEnabled ());
2364- assertTrue ("Expected holdout reason for flag " + flagKey , decision .getReasons ().stream ()
2365- .anyMatch (reason -> reason .contains ("holdout" )));
2366- }
2367- }
2368-
2369- @ Test
2370- public void testDecideAll_withHoldout () throws IOException {
2371- assumeTrue (datafileVersion == Integer .parseInt (ProjectConfig .Version .V4 .toString ()));
2372-
2373- Context context = InstrumentationRegistry .getInstrumentation ().getTargetContext ();
2374- OptimizelyClient optimizelyClient = createOptimizelyClientWithHoldouts (context );
2375-
2376- String userId = "user123" ;
2377- String variationKey = "ho_off_key" ;
2378-
2379- Map <String , Object > attributes = new HashMap <>();
2380- // ppid120000 buckets user into holdout_included_flags (selective holdout)
2381- attributes .put ("$opt_bucketing_id" , "ppid120000" );
2382-
2383- // Flags INCLUDED in holdout_included_flags (only these should be holdout decisions)
2384- List <String > includedInHoldout = Arrays .asList (
2385- "boolean_feature" ,
2386- "double_single_variable_feature" ,
2387- "integer_single_variable_feature"
2388- );
2389-
2390- OptimizelyUserContext userContext = optimizelyClient .createUserContext (userId , attributes );
2391- Map <String , OptimizelyDecision > decisions = userContext .decideAll (Arrays .asList (
2392- OptimizelyDecideOption .INCLUDE_REASONS ,
2393- OptimizelyDecideOption .DISABLE_DECISION_EVENT
2394- ));
2395-
2396- assertTrue ("Should have multiple decisions" , decisions .size () > 0 );
2397-
2398- String expectedReason = "User (" + userId + ") is in variation (" + variationKey + ") of holdout (holdout_included_flags)." ;
2399-
2400- int holdoutCount = 0 ;
2401- for (Map .Entry <String , OptimizelyDecision > entry : decisions .entrySet ()) {
2402- String flagKey = entry .getKey ();
2403- OptimizelyDecision decision = entry .getValue ();
2404- assertNotNull ("Missing decision for flag " + flagKey , decision );
2405-
2406- if (includedInHoldout .contains (flagKey )) {
2407- // Should be holdout decision
2408- assertEquals (variationKey , decision .getVariationKey ());
2409- assertFalse (decision .getEnabled ());
2410- assertTrue ("Expected holdout reason for flag " + flagKey , decision .getReasons ().contains (expectedReason ));
2411- holdoutCount ++;
2412- } else {
2413- // Should NOT be a holdout decision
2414- assertFalse ("Non-included flag should not have holdout reason: " + flagKey ,
2415- decision .getReasons ().contains (expectedReason ));
2416- }
2417- }
2418- assertEquals ("Expected exactly the included flags to be in holdout" , includedInHoldout .size (), holdoutCount );
2419- }
2420-
2421- @ Test
2422- public void testDecisionNotificationHandler_withHoldout () throws IOException {
2423- assumeTrue (datafileVersion == Integer .parseInt (ProjectConfig .Version .V4 .toString ()));
2424-
2425- Context context = InstrumentationRegistry .getInstrumentation ().getTargetContext ();
2426- OptimizelyClient optimizelyClient = createOptimizelyClientWithHoldouts (context );
2427-
2428- String flagKey = "boolean_feature" ;
2429- String userId = "user123" ;
2430- String variationKey = "ho_off_key" ;
2431- String ruleKey = "basic_holdout" ;
2432-
2433- Map <String , Object > attributes = new HashMap <>();
2434- attributes .put ("$opt_bucketing_id" , "ppid160000" ); // deterministic bucketing into basic_holdout
2435- attributes .put ("nationality" , "English" ); // non-reserved attribute
2436-
2437- final boolean [] listenerCalled = {false };
2438- optimizelyClient .addDecisionNotificationHandler (decisionNotification -> {
2439- assertEquals ("FLAG" , decisionNotification .getType ());
2440- assertEquals (userId , decisionNotification .getUserId ());
2441- assertEquals (attributes , decisionNotification .getAttributes ());
2442-
2443- Map <String , ?> info = decisionNotification .getDecisionInfo ();
2444- assertEquals (flagKey , info .get ("flagKey" ));
2445- assertEquals (variationKey , info .get ("variationKey" ));
2446- assertEquals (false , info .get ("enabled" ));
2447- assertEquals (ruleKey , info .get ("ruleKey" ));
2448- assertTrue (((Map <?, ?>) info .get ("variables" )).isEmpty ());
2449-
2450- listenerCalled [0 ] = true ;
2451- });
2452-
2453- OptimizelyUserContext userContext = optimizelyClient .createUserContext (userId , attributes );
2454- OptimizelyDecision decision = userContext .decide (flagKey , Collections .singletonList (OptimizelyDecideOption .INCLUDE_REASONS ));
2455-
2456- assertTrue ("Decision notification handler should have been called" , listenerCalled [0 ]);
2457- assertEquals (variationKey , decision .getVariationKey ());
2458- assertFalse (decision .getEnabled ());
2459- }
2460-
24612294 // Utils
24622295
24632296 private boolean compareJsonStrings (String str1 , String str2 ) {
0 commit comments