Skip to content

Commit 29d7e21

Browse files
mnoman09thomaszurkan-optimizely
authored andcommitted
Parameterized OptimizelyClientTest.java and Is feature enabled changes (#177)
* Parameterized OptimizelyClientTest.java and Is feature enabled changes * Updated Test unit tests * parameterized optimizelyClientTest.java * updated getdatafile url method and removed Static (because its only usage was in unit tests where we already had optimizelymanager object) * space removed * Added forced variation unitTest and some refactoring * Code refactoring * Updated copyrights
1 parent fabcdea commit 29d7e21

File tree

8 files changed

+349
-185
lines changed

8 files changed

+349
-185
lines changed

android-sdk/src/androidTest/java/com/optimizely/ab/android/sdk/OptimizelyClientTest.java

Lines changed: 288 additions & 172 deletions
Large diffs are not rendered by default.

android-sdk/src/androidTest/java/com/optimizely/ab/android/sdk/OptimizelyManagerTest.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2016, Optimizely, Inc. and contributors *
2+
* Copyright 2017-2018, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -32,6 +32,7 @@
3232
import com.optimizely.ab.android.datafile_handler.DatafileService;
3333
import com.optimizely.ab.android.datafile_handler.DefaultDatafileHandler;
3434
import com.optimizely.ab.android.event_handler.DefaultEventHandler;
35+
import com.optimizely.ab.android.sdk.test.R;
3536
import com.optimizely.ab.android.shared.ServiceScheduler;
3637
import com.optimizely.ab.android.user_profile.DefaultUserProfileService;
3738
import com.optimizely.ab.bucketing.UserProfileService;
@@ -59,8 +60,6 @@
5960
import static org.mockito.Mockito.verify;
6061
import static org.mockito.Mockito.when;
6162

62-
import com.optimizely.ab.android.sdk.test.R;
63-
6463
/**
6564
* Tests for {@link OptimizelyManager}
6665
*/
@@ -111,7 +110,7 @@ public void initializeInt() {
111110

112111
assertEquals(optimizelyManager.isDatafileCached(InstrumentationRegistry.getTargetContext()), false);
113112

114-
assertEquals(OptimizelyManager.getDatafileUrl("1"), "https://cdn.optimizely.com/public/1/datafile_v3.json" );
113+
assertEquals(optimizelyManager.getDatafileUrl("1"), "https://cdn.optimizely.com/public/1/datafile_v3.json" );
115114

116115
assertNotNull(optimizelyManager.getOptimizely());
117116
assertNotNull(optimizelyManager.getDatafileHandler());
@@ -127,7 +126,7 @@ public void initializeSync() {
127126

128127
assertEquals(optimizelyManager.isDatafileCached(InstrumentationRegistry.getTargetContext()), false);
129128

130-
assertEquals(OptimizelyManager.getDatafileUrl("1"), "https://cdn.optimizely.com/public/1/datafile_v3.json" );
129+
assertEquals(optimizelyManager.getDatafileUrl("1"), "https://cdn.optimizely.com/public/1/datafile_v3.json" );
131130

132131
assertNotNull(optimizelyManager.getOptimizely());
133132
assertNotNull(optimizelyManager.getDatafileHandler());
@@ -165,7 +164,7 @@ public void getDatafile() {
165164
*/
166165
assertEquals(optimizelyManager.isDatafileCached(InstrumentationRegistry.getTargetContext()), false);
167166
String datafile = optimizelyManager.getDatafile(InstrumentationRegistry.getTargetContext(), R.raw.datafile);
168-
assertEquals(OptimizelyManager.getDatafileUrl("1"), "https://cdn.optimizely.com/public/1/datafile_v3.json" );
167+
assertEquals(optimizelyManager.getDatafileUrl("1"), "https://cdn.optimizely.com/public/1/datafile_v3.json" );
169168
assertNotNull(datafile);
170169
assertNotNull(optimizelyManager.getDatafileHandler());
171170
}
@@ -186,7 +185,7 @@ public void onStart(OptimizelyClient optimizely) {
186185

187186
assertEquals(optimizelyManager.isDatafileCached(InstrumentationRegistry.getTargetContext()), false);
188187

189-
assertEquals(OptimizelyManager.getDatafileUrl("1"), "https://cdn.optimizely.com/public/1/datafile_v3.json" );
188+
assertEquals(optimizelyManager.getDatafileUrl("1"), "https://cdn.optimizely.com/public/1/datafile_v3.json" );
190189

191190

192191
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "groups": [], "projectId": "8504447126", "variables": [{ "defaultValue": "true", "type": "boolean", "id": "8516291943", "key": "test_variable" }], "version": "3", "experiments": [{ "status": "Running", "key": "android_experiment_key", "layerId": "8499056327", "trafficAllocation": [{ "entityId": "8509854340", "endOfRange": 5000 }, { "entityId": "8505434669", "endOfRange": 10000 }], "audienceIds": [], "variations": [{ "variables": [], "id": "8509854340", "key": "var_1" }, { "variables": [], "id": "8505434669", "key": "var_2" }], "forcedVariations": {}, "id": "8509139139" }], "audiences": [], "anonymizeIP": true, "attributes": [], "revision": "7", "events": [{ "experimentIds": ["8509139139"], "id": "8505434668", "key": "test_event" }], "accountId": "8362480420" }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "accountId": "2360254204", "anonymizeIP": true, "projectId": "3918735994", "revision": "1480511547", "version": "4", "audiences": [{ "id": "3468206642", "name": "Gryffindors", "conditions": "[\"and\", [\"or\", [\"or\", {\"name\": \"house\", \"type\": \"custom_dimension\", \"value\":\"Gryffindor\"}]]]" }, { "id": "3988293898", "name": "Slytherins", "conditions": "[\"and\", [\"or\", [\"or\", {\"name\": \"house\", \"type\": \"custom_dimension\", \"value\":\"Slytherin\"}]]]" }, { "id": "4194404272", "name": "english_citizens", "conditions": "[\"and\", [\"or\", [\"or\", {\"name\": \"nationality\", \"type\": \"custom_dimension\", \"value\":\"English\"}]]]" }, { "id": "2196265320", "name": "audience_with_missing_value", "conditions": "[\"and\", [\"or\", [\"or\", {\"name\": \"nationality\", \"type\": \"custom_dimension\", \"value\": \"English\"}, {\"name\": \"nationality\", \"type\": \"custom_dimension\"}]]]" }], "attributes": [{ "id": "553339214", "key": "house" }, { "id": "58339410", "key": "nationality" }], "events": [ { "experimentIds": ["8509139139"], "id": "8505434668", "key": "test_event" },{ "id": "3785620495", "key": "basic_event", "experimentIds": ["1323241596", "2738374745", "3042640549", "3262035800", "3072915611"] }, { "id": "3195631717", "key": "event_with_paused_experiment", "experimentIds": ["2667098701"] }, { "id": "1987018666", "key": "event_with_launched_experiments_only", "experimentIds": ["3072915611"] }], "experiments": [ { "status": "Running", "key": "android_experiment_key", "layerId": "8499056327", "trafficAllocation": [{ "entityId": "8509854340", "endOfRange": 5000 }, { "entityId": "8505434669", "endOfRange": 10000 }], "audienceIds": [], "variations": [{ "variables": [], "id": "8509854340", "key": "var_1" }, { "variables": [], "id": "8505434669", "key": "var_2" }], "forcedVariations": {}, "id": "8509139139" }, { "id": "1323241596", "key": "basic_experiment", "layerId": "1630555626", "status": "Running", "variations": [{ "id": "1423767502", "key": "A", "variables": [] }, { "id": "3433458314", "key": "B", "variables": [] }], "trafficAllocation": [{ "entityId": "1423767502", "endOfRange": 5000 }, { "entityId": "3433458314", "endOfRange": 10000 }], "audienceIds": [], "forcedVariations": { "Harry Potter": "A", "Tom Riddle": "B" } }, { "id": "3262035800", "key": "multivariate_experiment", "layerId": "3262035800", "status": "Running", "variations": [{ "id": "1880281238", "key": "Fred", "variables": [{ "id": "675244127", "value": "F" }, { "id": "4052219963", "value": "red" }] }, { "id": "3631049532", "key": "Feorge", "variables": [{ "id": "675244127", "value": "F" }, { "id": "4052219963", "value": "eorge" }] }, { "id": "4204375027", "key": "Gred", "variables": [{ "id": "675244127", "value": "G" }, { "id": "4052219963", "value": "red" }] }, { "id": "2099211198", "key": "George", "variables": [{ "id": "675244127", "value": "G" }, { "id": "4052219963", "value": "eorge" }] }], "trafficAllocation": [{ "entityId": "1880281238", "endOfRange": 2500 }, { "entityId": "3631049532", "endOfRange": 5000 }, { "entityId": "4204375027", "endOfRange": 7500 }, { "entityId": "2099211198", "endOfRange": 10000 }], "audienceIds": ["3468206642"], "forcedVariations": { "Fred": "Fred", "Feorge": "Feorge", "Gred": "Gred", "George": "George" } }, { "id": "2201520193", "key": "double_single_variable_feature_experiment", "layerId": "1278722008", "status": "Running", "variations": [{ "id": "1505457580", "key": "pi_variation", "variables": [{ "id": "4111654444", "value": "3.14" }] }, { "id": "119616179", "key": "euler_variation", "variables": [{ "id": "4111654444", "value": "2.718" }] }], "trafficAllocation": [{ "entityId": "1505457580", "endOfRange": 4000 }, { "entityId": "119616179", "endOfRange": 8000 }], "audienceIds": ["3988293898"], "forcedVariations": {} }, { "id": "2667098701", "key": "paused_experiment", "layerId": "3949273892", "status": "Paused", "variations": [{ "id": "391535909", "key": "Control", "variables": [] }], "trafficAllocation": [{ "entityId": "391535909", "endOfRange": 10000 }], "audienceIds": [], "forcedVariations": { "Harry Potter": "Control" } }, { "id": "3072915611", "key": "launched_experiment", "layerId": "3587821424", "status": "Launched", "variations": [{ "id": "1647582435", "key": "launch_control", "variables": [] }], "trafficAllocation": [{ "entityId": "1647582435", "endOfRange": 8000 }], "audienceIds": [], "forcedVariations": {} }, { "id": "748215081", "key": "experiment_with_malformed_audience", "layerId": "1238149537", "status": "Running", "variations": [{ "id": "535538389", "key": "var1", "variables": [] }], "trafficAllocation": [{ "entityId": "535538389", "endOfRange": 10000 }], "audienceIds": ["2196265320"], "forcedVariations": {} }, { "id": "3262035800", "key": "multivariate_experiment", "layerId": "3262035800", "status": "Running", "variations": [{ "id": "1880281238", "key": "Fred", "variables": [{ "id": "675244127", "value": "F" }, { "id": "4052219963", "value": "red" }] }, { "id": "3631049532", "key": "Feorge", "variables": [{ "id": "675244127", "value": "F" }, { "id": "4052219963", "value": "eorge" }] }, { "id": "4204375027", "key": "Gred", "variables": [{ "id": "675244127", "value": "G" }, { "id": "4052219963", "value": "red" }] }, { "id": "2099211198", "key": "George", "variables": [{ "id": "675244127", "value": "G" }, { "id": "4052219963", "value": "eorge" }] }], "trafficAllocation": [{ "entityId": "1880281238", "endOfRange": 2500 }, { "entityId": "3631049532", "endOfRange": 5000 }, { "entityId": "4204375027", "endOfRange": 7500 }, { "entityId": "2099211198", "endOfRange": 10000 }], "audienceIds": ["3468206642"], "forcedVariations": { "Fred": "Fred", "Feorge": "Feorge", "Gred": "Gred", "George": "George" } }], "groups": [{ "id": "1015968292", "policy": "random", "experiments": [{ "id": "2738374745", "key": "first_grouped_experiment", "layerId": "3301900159", "status": "Running", "variations": [{ "id": "2377378132", "key": "A", "variables": [] }, { "id": "1179171250", "key": "B", "variables": [] }], "trafficAllocation": [{ "entityId": "2377378132", "endOfRange": 5000 }, { "entityId": "1179171250", "endOfRange": 10000 }], "audienceIds": ["3468206642"], "forcedVariations": { "Harry Potter": "A", "Tom Riddle": "B" } }, { "id": "3042640549", "key": "second_grouped_experiment", "layerId": "2625300442", "status": "Running", "variations": [{ "id": "1558539439", "key": "A", "variables": [] }, { "id": "2142748370", "key": "B", "variables": [] }], "trafficAllocation": [{ "entityId": "1558539439", "endOfRange": 5000 }, { "entityId": "2142748370", "endOfRange": 10000 }], "audienceIds": ["3468206642"], "forcedVariations": { "Hermione Granger": "A", "Ronald Weasley": "B" } }], "trafficAllocation": [{ "entityId": "2738374745", "endOfRange": 4000 }, { "entityId": "3042640549", "endOfRange": 8000 }] }, { "id": "2606208781", "policy": "random", "experiments": [{ "id": "4138322202", "key": "mutex_group_2_experiment_1", "layerId": "3755588495", "status": "Running", "variations": [{ "id": "1394671166", "key": "mutex_group_2_experiment_1_variation_1", "variables": [{ "id": "2059187672", "value": "mutex_group_2_experiment_1_variation_1" }] }], "audienceIds": [], "forcedVariations": {}, "trafficAllocation": [{ "entityId": "1394671166", "endOfRange": 10000 }] }, { "id": "1786133852", "key": "mutex_group_2_experiment_2", "layerId": "3818002538", "status": "Running", "variations": [{ "id": "1619235542", "key": "mutex_group_2_experiment_2_variation_2", "variables": [{ "id": "2059187672", "value": "mutex_group_2_experiment_2_variation_2" }] }], "trafficAllocation": [{ "entityId": "1619235542", "endOfRange": 10000 }], "audienceIds": [], "forcedVariations": {} }], "trafficAllocation": [{ "entityId": "4138322202", "endOfRange": 5000 }, { "entityId": "1786133852", "endOfRange": 10000 }] }], "featureFlags": [{ "id": "4195505407", "key": "boolean_feature", "rolloutId": "", "experimentIds": [], "variables": [] }, { "id": "3926744821", "key": "double_single_variable_feature", "rolloutId": "", "experimentIds": ["2201520193"], "variables": [{ "id": "4111654444", "key": "double_variable", "type": "double", "defaultValue": "14.99" }] }, { "id": "3281420120", "key": "integer_single_variable_feature", "rolloutId": "2048875663", "experimentIds": [], "variables": [{ "id": "593964691", "key": "integer_variable", "type": "integer", "defaultValue": "7" }] }, { "id": "2591051011", "key": "boolean_single_variable_feature", "rolloutId": "", "experimentIds": [], "variables": [{ "id": "3974680341", "key": "boolean_variable", "type": "boolean", "defaultValue": "true" }] }, { "id": "2079378557", "key": "string_single_variable_feature", "rolloutId": "1058508303", "experimentIds": [], "variables": [{ "id": "2077511132", "key": "string_variable", "type": "string", "defaultValue": "wingardium leviosa" }] }, { "id": "3263342226", "key": "multi_variate_feature", "rolloutId": "813411034", "experimentIds": ["3262035800"], "variables": [{ "id": "675244127", "key": "first_letter", "type": "string", "defaultValue": "H" }, { "id": "4052219963", "key": "rest_of_name", "type": "string", "defaultValue": "arry" }] }, { "id": "3263342226", "key": "mutex_group_feature", "rolloutId": "", "experimentIds": ["4138322202", "1786133852"], "variables": [{ "id": "2059187672", "key": "correlating_variation_name", "type": "string", "defaultValue": "null" }] }], "rollouts": [{ "id": "1058508303", "experiments": [{ "id": "1785077004", "key": "1785077004", "status": "Running", "layerId": "1058508303", "audienceIds": [], "forcedVariations": {}, "variations": [{ "id": "1566407342", "key": "1566407342", "variables": [{ "id": "2077511132", "value": "lumos" }] }], "trafficAllocation": [{ "entityId": "1566407342", "endOfRange": 5000 }] }] }, { "id": "813411034", "experiments": [{ "id": "3421010877", "key": "3421010877", "status": "Running", "layerId": "813411034", "audienceIds": ["3468206642"], "forcedVariations": {}, "variations": [{ "id": "521740985", "key": "521740985", "variables": [{ "id": "675244127", "value": "G" }, { "id": "4052219963", "value": "odric" }] }], "trafficAllocation": [{ "entityId": "521740985", "endOfRange": 5000 }] }, { "id": "600050626", "key": "600050626", "status": "Running", "layerId": "813411034", "audienceIds": ["3988293898"], "forcedVariations": {}, "variations": [{ "id": "180042646", "key": "180042646", "variables": [{ "id": "675244127", "value": "S" }, { "id": "4052219963", "value": "alazar" }] }], "trafficAllocation": [{ "entityId": "180042646", "endOfRange": 5000 }] }, { "id": "2637642575", "key": "2637642575", "status": "Running", "layerId": "813411034", "audienceIds": ["4194404272"], "forcedVariations": {}, "variations": [{ "id": "2346257680", "key": "2346257680", "variables": [{ "id": "675244127", "value": "D" }, { "id": "4052219963", "value": "udley" }] }], "trafficAllocation": [{ "entityId": "2346257680", "endOfRange": 5000 }] }, { "id": "828245624", "key": "828245624", "status": "Running", "layerId": "813411034", "audienceIds": [], "forcedVariations": {}, "variations": [{ "id": "3137445031", "key": "3137445031", "variables": [{ "id": "675244127", "value": "M" }, { "id": "4052219963", "value": "uggle" }] }], "trafficAllocation": [{ "entityId": "3137445031", "endOfRange": 5000 }] }] }, { "id": "2048875663", "experiments": [{ "id": "3794675122", "key": "3794675122", "status": "Running", "layerId": "2048875663", "audienceIds": [], "forcedVariations": {}, "variations": [{ "id": "589640735", "key": "589640735", "variables": [] }], "trafficAllocation": [{ "entityId": "589640735", "endOfRange": 10000 }] }] }], "variables": [] }

android-sdk/src/main/java/com/optimizely/ab/android/sdk/OptimizelyClient.java

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2016-2017, Optimizely, Inc. and contributors *
2+
* Copyright 2017-2018, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -34,6 +34,8 @@
3434
import java.util.HashMap;
3535
import java.util.Map;
3636

37+
import javax.annotation.Nonnull;
38+
3739
/**
3840
* Wraps {@link Optimizely} instances
3941
*
@@ -377,4 +379,51 @@ public void clearNotificationListeners() {
377379
logger.warn("Optimizely is not initialized, could not clear notification listeners");
378380
}
379381
}
382+
383+
//======== FeatureFlag APIs ========//
384+
385+
/**
386+
* Determine whether a feature is enabled for a user.
387+
* Send an impression event if the user is bucketed into an experiment using the feature.
388+
*
389+
* @param featureKey The unique key of the feature.
390+
* @param userId The ID of the user.
391+
* @return True if the feature is enabled.
392+
* False if the feature is disabled.
393+
* False if the feature is not found.
394+
*/
395+
public @Nonnull
396+
Boolean isFeatureEnabled(@Nonnull String featureKey,
397+
@Nonnull String userId) {
398+
if (isValid()) {
399+
return optimizely.isFeatureEnabled(featureKey, userId);
400+
} else {
401+
logger.warn("Optimizely is not initialized, could not enable feature {} for user {}",
402+
featureKey, userId);
403+
return false;
404+
}
405+
}
406+
407+
/**
408+
* Determine whether a feature is enabled for a user.
409+
* Send an impression event if the user is bucketed into an experiment using the feature.
410+
*
411+
* @param featureKey The unique key of the feature.
412+
* @param userId The ID of the user.
413+
* @param attributes The user's attributes.
414+
* @return True if the feature is enabled.
415+
* False if the feature is disabled.
416+
* False if the feature is not found.
417+
*/
418+
public @Nonnull Boolean isFeatureEnabled(@Nonnull String featureKey,
419+
@Nonnull String userId,
420+
@Nonnull Map<String, String> attributes) {
421+
if (isValid()) {
422+
return optimizely.isFeatureEnabled(featureKey, userId, attributes);
423+
} else {
424+
logger.warn("Optimizely is not initialized, could not enable feature {} for user {} with attributes",
425+
featureKey, userId);
426+
return false;
427+
}
428+
}
380429
}

android-sdk/src/main/java/com/optimizely/ab/android/sdk/OptimizelyManager.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2016-2017, Optimizely, Inc. and contributors *
2+
* Copyright 2017-2018, Optimizely, Inc. and contributors *
33
* *
44
* Licensed under the Apache License, Version 2.0 (the "License"); *
55
* you may not use this file except in compliance with the License. *
@@ -308,7 +308,7 @@ public OptimizelyClient getOptimizely() {
308308
return optimizelyClient;
309309
}
310310

311-
private String loadRawResource(Context context, @RawRes int rawRes) throws IOException {
311+
public static String loadRawResource(Context context, @RawRes int rawRes) throws IOException {
312312
Resources res = context.getResources();
313313
InputStream in = res.openRawResource(rawRes);
314314
byte[] b = new byte[in.available()];
@@ -335,7 +335,7 @@ public boolean isDatafileCached(Context context) {
335335
* @param projectId The id of the project for which we are getting the datafile
336336
* @return the CDN location of the datafile
337337
*/
338-
public static @NonNull String getDatafileUrl(String projectId) {
338+
public @NonNull String getDatafileUrl(String projectId) {
339339
return DatafileService.getDatafileUrl(projectId);
340340
}
341341

build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ ext {
5151
build_tools_version = "26.0.1"
5252
min_sdk_version = 10
5353
target_sdk_version = 26
54-
5554
java_core_ver = "2.0.0-beta2"
5655
android_logger_ver = "1.3.6"
5756
support_annotations_ver = "24.2.1"

0 commit comments

Comments
 (0)