@@ -54,14 +54,27 @@ public class FirebaseABTestingTest {
5454 private static final String TEST_EXPERIMENT_1_ID = "1" ;
5555 private static final String TEST_EXPERIMENT_2_ID = "2" ;
5656
57+ private static final String TEST_VARIANT_ID_A = "VARIANT_A" ;
58+ private static final String TEST_VARIANT_ID_B = "VARIANT_B" ;
59+
5760 private static final AbtExperimentInfo TEST_ABT_EXPERIMENT_1 =
5861 createExperimentInfo (
5962 TEST_EXPERIMENT_1_ID ,
63+ TEST_VARIANT_ID_A ,
6064 /*triggerEventName=*/ "" ,
6165 /*experimentStartTimeInEpochMillis=*/ 1000L );
62- private static final AbtExperimentInfo TEST_ABT_EXPERIMENT_2 =
66+ private static final AbtExperimentInfo TEST_ABT_EXPERIMENT_2_VARIANT_A =
67+ createExperimentInfo (
68+ TEST_EXPERIMENT_2_ID ,
69+ TEST_VARIANT_ID_A ,
70+ "trigger_event_2" ,
71+ /*experimentStartTimeInEpochMillis=*/ 2000L );
72+ private static final AbtExperimentInfo TEST_ABT_EXPERIMENT_2_VARIANT_B =
6373 createExperimentInfo (
64- TEST_EXPERIMENT_2_ID , "trigger_event_2" , /*experimentStartTimeInEpochMillis=*/ 2000L );
74+ TEST_EXPERIMENT_2_ID ,
75+ TEST_VARIANT_ID_B ,
76+ "trigger_event_2" ,
77+ /*experimentStartTimeInEpochMillis=*/ 2000L );
6578
6679 private static final int MAX_ALLOWED_EXPERIMENTS_IN_ANALYTICS = 100 ;
6780
@@ -91,7 +104,7 @@ public void replaceAllExperiments_noExperimentsInAnalytics_experimentsCorrectlyS
91104
92105 firebaseAbt .replaceAllExperiments (
93106 Lists .newArrayList (
94- TEST_ABT_EXPERIMENT_1 .toStringMap (), TEST_ABT_EXPERIMENT_2 .toStringMap ()));
107+ TEST_ABT_EXPERIMENT_1 .toStringMap (), TEST_ABT_EXPERIMENT_2_VARIANT_A .toStringMap ()));
95108
96109 ArgumentCaptor <ConditionalUserProperty > analyticsExperimentArgumentCaptor =
97110 ArgumentCaptor .forClass (ConditionalUserProperty .class );
@@ -107,7 +120,8 @@ public void replaceAllExperiments_noExperimentsInAnalytics_experimentsCorrectlyS
107120
108121 // Validates that TEST_ABT_EXPERIMENT_1 and TEST_ABT_EXPERIMENT_2 have been set in Analytics.
109122 assertThat (analyticsExperiment1 .toStringMap ()).isEqualTo (TEST_ABT_EXPERIMENT_1 .toStringMap ());
110- assertThat (analyticsExperiment2 .toStringMap ()).isEqualTo (TEST_ABT_EXPERIMENT_2 .toStringMap ());
123+ assertThat (analyticsExperiment2 .toStringMap ())
124+ .isEqualTo (TEST_ABT_EXPERIMENT_2_VARIANT_A .toStringMap ());
111125 }
112126
113127 @ Test
@@ -117,10 +131,11 @@ public void replaceAllExperiments_existExperimentsInAnalytics_experimentsCorrect
117131 .thenReturn (
118132 Lists .newArrayList (
119133 TEST_ABT_EXPERIMENT_1 .toConditionalUserProperty (ORIGIN_SERVICE ),
120- TEST_ABT_EXPERIMENT_2 .toConditionalUserProperty (ORIGIN_SERVICE )));
134+ TEST_ABT_EXPERIMENT_2_VARIANT_A .toConditionalUserProperty (ORIGIN_SERVICE )));
121135
122- AbtExperimentInfo newExperiment3 = createExperimentInfo ("3" , "" , 1000L );
123- AbtExperimentInfo newExperiment4 = createExperimentInfo ("4" , "trigger_event_4" , 1000L );
136+ AbtExperimentInfo newExperiment3 = createExperimentInfo ("3" , TEST_VARIANT_ID_A , "" , 1000L );
137+ AbtExperimentInfo newExperiment4 =
138+ createExperimentInfo ("4" , TEST_VARIANT_ID_A , "trigger_event_4" , 1000L );
124139
125140 // Simulates the case where experiment 1 is assigned (as before), experiment 2 is no longer
126141 // assigned; experiment 3 and experiment 4 are newly assigned.
@@ -146,6 +161,47 @@ public void replaceAllExperiments_existExperimentsInAnalytics_experimentsCorrect
146161 .isEqualTo (newExperiment4 .toStringMap ());
147162 }
148163
164+ @ Test
165+ public void
166+ replaceAllExperiments_existExperimentsInAnalyticsWithDifferentVariants_experimentsCorrectlySetInAnalytics ()
167+ throws Exception {
168+ when (mockAnalyticsConnector .getConditionalUserProperties (ORIGIN_SERVICE , "" ))
169+ .thenReturn (
170+ Lists .newArrayList (
171+ TEST_ABT_EXPERIMENT_1 .toConditionalUserProperty (ORIGIN_SERVICE ),
172+ TEST_ABT_EXPERIMENT_2_VARIANT_A .toConditionalUserProperty (ORIGIN_SERVICE )));
173+
174+ AbtExperimentInfo newExperiment3 = createExperimentInfo ("3" , "b" , "" , 1000L );
175+ AbtExperimentInfo newExperiment4 = createExperimentInfo ("4" , "a" , "trigger_event_4" , 1000L );
176+
177+ // Simulates the case where experiments 1 and 2 are removed,
178+ // experiment 2 is re-set with a new variant, and experiments 3 and 4 are newly added.
179+ firebaseAbt .replaceAllExperiments (
180+ Lists .newArrayList (
181+ TEST_ABT_EXPERIMENT_2_VARIANT_B .toStringMap (),
182+ newExperiment3 .toStringMap (),
183+ newExperiment4 .toStringMap ()));
184+
185+ // Validates that experiment 1 is cleared, experiment 2 is updated,
186+ // and experiment 3 and experiment 4 are set in Analytics.
187+ ArgumentCaptor <ConditionalUserProperty > analyticsExperimentArgumentCaptor =
188+ ArgumentCaptor .forClass (ConditionalUserProperty .class );
189+ verify (mockAnalyticsConnector , times (1 ))
190+ .clearConditionalUserProperty (TEST_EXPERIMENT_1_ID , null , null );
191+ verify (mockAnalyticsConnector , times (1 ))
192+ .clearConditionalUserProperty (TEST_EXPERIMENT_2_ID , null , null );
193+ verify (mockAnalyticsConnector , times (3 ))
194+ .setConditionalUserProperty (analyticsExperimentArgumentCaptor .capture ());
195+
196+ List <ConditionalUserProperty > actualValues = analyticsExperimentArgumentCaptor .getAllValues ();
197+ assertThat (AbtExperimentInfo .fromConditionalUserProperty (actualValues .get (0 )).toStringMap ())
198+ .isEqualTo (TEST_ABT_EXPERIMENT_2_VARIANT_B .toStringMap ());
199+ assertThat (AbtExperimentInfo .fromConditionalUserProperty (actualValues .get (1 )).toStringMap ())
200+ .isEqualTo (newExperiment3 .toStringMap ());
201+ assertThat (AbtExperimentInfo .fromConditionalUserProperty (actualValues .get (2 )).toStringMap ())
202+ .isEqualTo (newExperiment4 .toStringMap ());
203+ }
204+
149205 @ Test
150206 public void replaceAllExperiments_totalExperimentsExceedsAnalyticsLimit_oldExperimentsDiscarded ()
151207 throws Exception {
@@ -155,17 +211,18 @@ public void replaceAllExperiments_totalExperimentsExceedsAnalyticsLimit_oldExper
155211 .thenReturn (
156212 Lists .newArrayList (
157213 TEST_ABT_EXPERIMENT_1 .toConditionalUserProperty (ORIGIN_SERVICE ),
158- TEST_ABT_EXPERIMENT_2 .toConditionalUserProperty (ORIGIN_SERVICE )));
214+ TEST_ABT_EXPERIMENT_2_VARIANT_A .toConditionalUserProperty (ORIGIN_SERVICE )));
159215
160- AbtExperimentInfo newExperiment3 = createExperimentInfo ("3" , "" , 1000L );
161- AbtExperimentInfo newExperiment4 = createExperimentInfo ("4" , "trigger_event_4" , 1000L );
216+ AbtExperimentInfo newExperiment3 = createExperimentInfo ("3" , TEST_VARIANT_ID_A , "" , 1000L );
217+ AbtExperimentInfo newExperiment4 =
218+ createExperimentInfo ("4" , TEST_VARIANT_ID_A , "trigger_event_4" , 1000L );
162219
163220 // Simulates the case where experiment 1 and 2 are assigned (as before), experiment 3 and
164221 // experiment 4 are newly assigned.
165222 firebaseAbt .replaceAllExperiments (
166223 Lists .newArrayList (
167224 TEST_ABT_EXPERIMENT_1 .toStringMap (),
168- TEST_ABT_EXPERIMENT_2 .toStringMap (),
225+ TEST_ABT_EXPERIMENT_2_VARIANT_A .toStringMap (),
169226 newExperiment3 .toStringMap (),
170227 newExperiment4 .toStringMap ()));
171228
@@ -231,7 +288,7 @@ public void removeAllExperiments_existExperimentsInAnalytics_experimentsClearedF
231288 .thenReturn (
232289 Lists .newArrayList (
233290 TEST_ABT_EXPERIMENT_1 .toConditionalUserProperty (ORIGIN_SERVICE ),
234- TEST_ABT_EXPERIMENT_2 .toConditionalUserProperty (ORIGIN_SERVICE )));
291+ TEST_ABT_EXPERIMENT_2_VARIANT_A .toConditionalUserProperty (ORIGIN_SERVICE )));
235292
236293 firebaseAbt .removeAllExperiments ();
237294
@@ -266,15 +323,15 @@ public void getAllExperiments_existExperimentsInAnalytics_returnAllExperiments()
266323 .thenReturn (
267324 Lists .newArrayList (
268325 TEST_ABT_EXPERIMENT_1 .toConditionalUserProperty (ORIGIN_SERVICE ),
269- TEST_ABT_EXPERIMENT_2 .toConditionalUserProperty (ORIGIN_SERVICE )));
326+ TEST_ABT_EXPERIMENT_2_VARIANT_A .toConditionalUserProperty (ORIGIN_SERVICE )));
270327
271328 List <AbtExperimentInfo > abtExperimentInfoList = firebaseAbt .getAllExperiments ();
272329
273330 assertThat (abtExperimentInfoList ).hasSize (2 );
274331 assertThat (abtExperimentInfoList .get (0 ).toStringMap ())
275332 .isEqualTo (TEST_ABT_EXPERIMENT_1 .toStringMap ());
276333 assertThat (abtExperimentInfoList .get (1 ).toStringMap ())
277- .isEqualTo (TEST_ABT_EXPERIMENT_2 .toStringMap ());
334+ .isEqualTo (TEST_ABT_EXPERIMENT_2_VARIANT_A .toStringMap ());
278335 }
279336
280337 @ Test
@@ -298,7 +355,7 @@ public void getAllExperiments_analyticsSdkUnavailable_throwsAbtException() {
298355 .thenReturn (
299356 Lists .newArrayList (
300357 TEST_ABT_EXPERIMENT_1 .toConditionalUserProperty (ORIGIN_SERVICE ),
301- TEST_ABT_EXPERIMENT_2 .toConditionalUserProperty (ORIGIN_SERVICE )));
358+ TEST_ABT_EXPERIMENT_2_VARIANT_A .toConditionalUserProperty (ORIGIN_SERVICE )));
302359
303360 // Update to just one experiment running
304361 firebaseAbt .validateRunningExperiments (Lists .newArrayList (TEST_ABT_EXPERIMENT_1 ));
@@ -315,11 +372,11 @@ public void validateRunningExperiments_noinactiveExperimentsInAnalytics_cleansUp
315372 .thenReturn (
316373 Lists .newArrayList (
317374 TEST_ABT_EXPERIMENT_1 .toConditionalUserProperty (ORIGIN_SERVICE ),
318- TEST_ABT_EXPERIMENT_2 .toConditionalUserProperty (ORIGIN_SERVICE )));
375+ TEST_ABT_EXPERIMENT_2_VARIANT_A .toConditionalUserProperty (ORIGIN_SERVICE )));
319376
320377 // Update still says the same two experiments are running
321378 firebaseAbt .validateRunningExperiments (
322- Lists .newArrayList (TEST_ABT_EXPERIMENT_1 , TEST_ABT_EXPERIMENT_2 ));
379+ Lists .newArrayList (TEST_ABT_EXPERIMENT_1 , TEST_ABT_EXPERIMENT_2_VARIANT_A ));
323380
324381 // Verify nothing cleared
325382 verify (mockAnalyticsConnector , never ()).clearConditionalUserProperty (any (), any (), any ());
@@ -346,11 +403,14 @@ public void reportActiveExperiment_setsNullTriggerCondition() throws Exception {
346403 }
347404
348405 private static AbtExperimentInfo createExperimentInfo (
349- String experimentId , String triggerEventName , long experimentStartTimeInEpochMillis ) {
406+ String experimentId ,
407+ String variantId ,
408+ String triggerEventName ,
409+ long experimentStartTimeInEpochMillis ) {
350410
351411 return new AbtExperimentInfo (
352412 experimentId ,
353- VARIANT_ID_VALUE ,
413+ variantId ,
354414 triggerEventName ,
355415 new Date (experimentStartTimeInEpochMillis ),
356416 TRIGGER_TIMEOUT_IN_MILLIS_VALUE ,
0 commit comments