@@ -54,14 +54,27 @@ public class FirebaseABTestingTest {
54
54
private static final String TEST_EXPERIMENT_1_ID = "1" ;
55
55
private static final String TEST_EXPERIMENT_2_ID = "2" ;
56
56
57
+ private static final String TEST_VARIANT_ID_A = "VARIANT_A" ;
58
+ private static final String TEST_VARIANT_ID_B = "VARIANT_B" ;
59
+
57
60
private static final AbtExperimentInfo TEST_ABT_EXPERIMENT_1 =
58
61
createExperimentInfo (
59
62
TEST_EXPERIMENT_1_ID ,
63
+ TEST_VARIANT_ID_A ,
60
64
/*triggerEventName=*/ "" ,
61
65
/*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 =
63
73
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 );
65
78
66
79
private static final int MAX_ALLOWED_EXPERIMENTS_IN_ANALYTICS = 100 ;
67
80
@@ -91,7 +104,7 @@ public void replaceAllExperiments_noExperimentsInAnalytics_experimentsCorrectlyS
91
104
92
105
firebaseAbt .replaceAllExperiments (
93
106
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 ()));
95
108
96
109
ArgumentCaptor <ConditionalUserProperty > analyticsExperimentArgumentCaptor =
97
110
ArgumentCaptor .forClass (ConditionalUserProperty .class );
@@ -107,7 +120,8 @@ public void replaceAllExperiments_noExperimentsInAnalytics_experimentsCorrectlyS
107
120
108
121
// Validates that TEST_ABT_EXPERIMENT_1 and TEST_ABT_EXPERIMENT_2 have been set in Analytics.
109
122
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 ());
111
125
}
112
126
113
127
@ Test
@@ -117,10 +131,11 @@ public void replaceAllExperiments_existExperimentsInAnalytics_experimentsCorrect
117
131
.thenReturn (
118
132
Lists .newArrayList (
119
133
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 )));
121
135
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 );
124
139
125
140
// Simulates the case where experiment 1 is assigned (as before), experiment 2 is no longer
126
141
// assigned; experiment 3 and experiment 4 are newly assigned.
@@ -146,6 +161,47 @@ public void replaceAllExperiments_existExperimentsInAnalytics_experimentsCorrect
146
161
.isEqualTo (newExperiment4 .toStringMap ());
147
162
}
148
163
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
+
149
205
@ Test
150
206
public void replaceAllExperiments_totalExperimentsExceedsAnalyticsLimit_oldExperimentsDiscarded ()
151
207
throws Exception {
@@ -155,17 +211,18 @@ public void replaceAllExperiments_totalExperimentsExceedsAnalyticsLimit_oldExper
155
211
.thenReturn (
156
212
Lists .newArrayList (
157
213
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 )));
159
215
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 );
162
219
163
220
// Simulates the case where experiment 1 and 2 are assigned (as before), experiment 3 and
164
221
// experiment 4 are newly assigned.
165
222
firebaseAbt .replaceAllExperiments (
166
223
Lists .newArrayList (
167
224
TEST_ABT_EXPERIMENT_1 .toStringMap (),
168
- TEST_ABT_EXPERIMENT_2 .toStringMap (),
225
+ TEST_ABT_EXPERIMENT_2_VARIANT_A .toStringMap (),
169
226
newExperiment3 .toStringMap (),
170
227
newExperiment4 .toStringMap ()));
171
228
@@ -231,7 +288,7 @@ public void removeAllExperiments_existExperimentsInAnalytics_experimentsClearedF
231
288
.thenReturn (
232
289
Lists .newArrayList (
233
290
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 )));
235
292
236
293
firebaseAbt .removeAllExperiments ();
237
294
@@ -266,15 +323,15 @@ public void getAllExperiments_existExperimentsInAnalytics_returnAllExperiments()
266
323
.thenReturn (
267
324
Lists .newArrayList (
268
325
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 )));
270
327
271
328
List <AbtExperimentInfo > abtExperimentInfoList = firebaseAbt .getAllExperiments ();
272
329
273
330
assertThat (abtExperimentInfoList ).hasSize (2 );
274
331
assertThat (abtExperimentInfoList .get (0 ).toStringMap ())
275
332
.isEqualTo (TEST_ABT_EXPERIMENT_1 .toStringMap ());
276
333
assertThat (abtExperimentInfoList .get (1 ).toStringMap ())
277
- .isEqualTo (TEST_ABT_EXPERIMENT_2 .toStringMap ());
334
+ .isEqualTo (TEST_ABT_EXPERIMENT_2_VARIANT_A .toStringMap ());
278
335
}
279
336
280
337
@ Test
@@ -298,7 +355,7 @@ public void getAllExperiments_analyticsSdkUnavailable_throwsAbtException() {
298
355
.thenReturn (
299
356
Lists .newArrayList (
300
357
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 )));
302
359
303
360
// Update to just one experiment running
304
361
firebaseAbt .validateRunningExperiments (Lists .newArrayList (TEST_ABT_EXPERIMENT_1 ));
@@ -315,11 +372,11 @@ public void validateRunningExperiments_noinactiveExperimentsInAnalytics_cleansUp
315
372
.thenReturn (
316
373
Lists .newArrayList (
317
374
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 )));
319
376
320
377
// Update still says the same two experiments are running
321
378
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 ));
323
380
324
381
// Verify nothing cleared
325
382
verify (mockAnalyticsConnector , never ()).clearConditionalUserProperty (any (), any (), any ());
@@ -346,11 +403,14 @@ public void reportActiveExperiment_setsNullTriggerCondition() throws Exception {
346
403
}
347
404
348
405
private static AbtExperimentInfo createExperimentInfo (
349
- String experimentId , String triggerEventName , long experimentStartTimeInEpochMillis ) {
406
+ String experimentId ,
407
+ String variantId ,
408
+ String triggerEventName ,
409
+ long experimentStartTimeInEpochMillis ) {
350
410
351
411
return new AbtExperimentInfo (
352
412
experimentId ,
353
- VARIANT_ID_VALUE ,
413
+ variantId ,
354
414
triggerEventName ,
355
415
new Date (experimentStartTimeInEpochMillis ),
356
416
TRIGGER_TIMEOUT_IN_MILLIS_VALUE ,
0 commit comments