Skip to content

Commit 083d445

Browse files
authored
feat: add getFeatureVariableJSON and getAllFeatureVariables apis (#337)
* Added getFeatureVariable json and getAllFeatureVariables support * Added getAllFeatureVariables unit tests * nit fix * added getvalue test * getValue null test * - Add mavenLocal() to supported repositories for local development - Bump core SDK to 3.5.0-beta * updated java sdk release version
1 parent 0184417 commit 083d445

File tree

4 files changed

+361
-6
lines changed

4 files changed

+361
-6
lines changed

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

Lines changed: 252 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* Copyright 2017-2019, Optimizely, Inc. and contributors *
2+
* Copyright 2017-2020, 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. *
@@ -19,13 +19,17 @@
1919
import android.content.Context;
2020
import android.support.test.InstrumentationRegistry;
2121

22+
import com.google.gson.Gson;
23+
import com.google.gson.JsonElement;
24+
import com.google.gson.JsonParser;
2225
import com.optimizely.ab.Optimizely;
2326
import com.optimizely.ab.android.event_handler.DefaultEventHandler;
2427
import com.optimizely.ab.bucketing.Bucketer;
2528
import com.optimizely.ab.bucketing.DecisionService;
2629
import com.optimizely.ab.config.Experiment;
2730
import com.optimizely.ab.config.ProjectConfig;
2831
import com.optimizely.ab.config.Variation;
32+
import com.optimizely.ab.config.parser.JsonParseException;
2933
import com.optimizely.ab.event.EventHandler;
3034
import com.optimizely.ab.event.LogEvent;
3135
import com.optimizely.ab.internal.ReservedEventKey;
@@ -37,6 +41,7 @@
3741
import com.optimizely.ab.notification.TrackNotification;
3842
import com.optimizely.ab.notification.TrackNotificationListener;
3943
import com.optimizely.ab.optimizelyconfig.OptimizelyConfig;
44+
import com.optimizely.ab.optimizelyjson.OptimizelyJSON;
4045

4146
import org.junit.Assert;
4247
import org.junit.Test;
@@ -105,6 +110,7 @@ public static Collection<Object[]> data() throws IOException {
105110
private final static String INTEGER_VARIABLE_KEY = "integer_variable";
106111
private final static String STRING_FEATURE_KEY = "multi_variate_feature";
107112
private final static String STRING_VARIABLE_KEY = "first_letter";
113+
private final static String JSON_VARIABLE_KEY = "json_patched";
108114
private static final String GENERIC_USER_ID = "userId";
109115
private String testProjectId = "7595190003";
110116
private int datafileVersion;
@@ -1764,6 +1770,239 @@ public void testBadGetFeatureVariableString() {
17641770
);
17651771
}
17661772

1773+
/*
1774+
* FeatureVariableJSON
1775+
* Scenario#1 Without attributes in which user
1776+
* was not bucketed into any variation for feature flag will return default value which is
1777+
* '{"k1":"v1","k2":3.5,"k3":true,"k4":{"kk1":"vv1","kk2":false}}' in config
1778+
*/
1779+
@Test
1780+
public void testGetFeatureVariableJSONWithoutAttr() {
1781+
assumeTrue(datafileVersion == Integer.parseInt(ProjectConfig.Version.V4.toString()));
1782+
1783+
OptimizelyClient optimizelyClient = new OptimizelyClient(
1784+
optimizely,
1785+
logger
1786+
);
1787+
String defaultValueOfStringVar = "{\"k1\":\"v1\",\"k2\":3.5,\"k3\":true,\"k4\":{\"kk1\":\"vv1\",\"kk2\":false}}";
1788+
1789+
OptimizelyJSON json = optimizelyClient.getFeatureVariableJSON(
1790+
STRING_FEATURE_KEY,
1791+
JSON_VARIABLE_KEY,
1792+
GENERIC_USER_ID
1793+
);
1794+
1795+
assertTrue(compareJsonStrings(json.toString(), defaultValueOfStringVar));
1796+
}
1797+
1798+
//FeatureVariableJSON Scenario#2 with attributes
1799+
@Test
1800+
public void testGetFeatureVariableJsonWithAttr() {
1801+
assumeTrue(datafileVersion == Integer.parseInt(ProjectConfig.Version.V4.toString()));
1802+
1803+
OptimizelyClient optimizelyClient = new OptimizelyClient(
1804+
optimizely,
1805+
logger);
1806+
1807+
1808+
String defaultValueOfStringVar = "{\"k1\":\"s1\",\"k2\":103.5,\"k3\":false,\"k4\":{\"kk1\":\"ss1\",\"kk2\":true}}";
1809+
1810+
OptimizelyJSON json = optimizelyClient.getFeatureVariableJSON(
1811+
STRING_FEATURE_KEY,
1812+
JSON_VARIABLE_KEY,
1813+
GENERIC_USER_ID,
1814+
Collections.singletonMap("house", "Gryffindor")
1815+
);
1816+
1817+
assertTrue(compareJsonStrings(json.toString(), defaultValueOfStringVar));
1818+
verifyZeroInteractions(logger);
1819+
}
1820+
1821+
//FeatureVariableJSON Scenario#3 if feature not found
1822+
@Test
1823+
public void testGetFeatureVariableJsonInvalidFeatureKey() {
1824+
assumeTrue(datafileVersion == Integer.parseInt(ProjectConfig.Version.V4.toString()));
1825+
1826+
OptimizelyClient optimizelyClient = new OptimizelyClient(
1827+
optimizely,
1828+
logger);
1829+
1830+
assertNull(optimizelyClient.getFeatureVariableJSON(
1831+
"invalidFeatureKey",
1832+
"invalidVariableKey",
1833+
GENERIC_USER_ID
1834+
));
1835+
}
1836+
1837+
//FeatureVariableJSON Scenario#4 if variable not found
1838+
@Test
1839+
public void testGetFeatureVariableJsonInvalidVariableKey() {
1840+
assumeTrue(datafileVersion == Integer.parseInt(ProjectConfig.Version.V4.toString()));
1841+
1842+
OptimizelyClient optimizelyClient = new OptimizelyClient(
1843+
optimizely,
1844+
logger
1845+
);
1846+
1847+
//Scenario#4 if variable not found
1848+
assertNull(optimizelyClient.getFeatureVariableJSON(
1849+
STRING_FEATURE_KEY,
1850+
"invalidVariableKey",
1851+
GENERIC_USER_ID
1852+
));
1853+
}
1854+
1855+
@Test
1856+
public void testBadGetFeatureVariableJson() {
1857+
OptimizelyClient optimizelyClient = new OptimizelyClient(null, logger);
1858+
1859+
//Scenario#1 without attributes
1860+
assertNull(optimizelyClient.getFeatureVariableJSON(
1861+
STRING_FEATURE_KEY,
1862+
JSON_VARIABLE_KEY,
1863+
GENERIC_USER_ID
1864+
));
1865+
1866+
verify(logger).warn("Optimizely is not initialized, could not get feature {} variable {} JSON for user {}.",
1867+
STRING_FEATURE_KEY,
1868+
JSON_VARIABLE_KEY,
1869+
GENERIC_USER_ID
1870+
);
1871+
1872+
//Scenario#2 with attributes
1873+
assertNull(optimizelyClient.getFeatureVariableJSON(
1874+
STRING_FEATURE_KEY,
1875+
JSON_VARIABLE_KEY,
1876+
GENERIC_USER_ID,
1877+
Collections.EMPTY_MAP
1878+
));
1879+
1880+
verify(logger).warn("Optimizely is not initialized, could not get feature {} variable {} JSON for user {} with attributes.",
1881+
STRING_FEATURE_KEY,
1882+
JSON_VARIABLE_KEY,
1883+
GENERIC_USER_ID
1884+
);
1885+
}
1886+
1887+
/*
1888+
* getAllFeatureVariables
1889+
* Scenario#1 Without attributes in which user
1890+
* was not bucketed into any variation for feature flag will return default value which is
1891+
* '{"first_letter":"H","json_patched":{"k1":"v1","k2":3.5,"k3":true,"k4":{"kk1":"vv1","kk2":false}},"rest_of_name":"arry"}' in config
1892+
*/
1893+
@Test
1894+
public void testGetAllFeatureVariablesWithoutAttr() {
1895+
assumeTrue(datafileVersion == Integer.parseInt(ProjectConfig.Version.V4.toString()));
1896+
1897+
OptimizelyClient optimizelyClient = new OptimizelyClient(
1898+
optimizely,
1899+
logger
1900+
);
1901+
String defaultValueOfStringVar = "{\"first_letter\":\"H\",\"json_patched\":{\"k1\":\"v1\",\"k2\":3.5,\"k3\":true,\"k4\":{\"kk1\":\"vv1\",\"kk2\":false}},\"rest_of_name\":\"arry\"}";
1902+
1903+
OptimizelyJSON json = optimizelyClient.getAllFeatureVariables(
1904+
STRING_FEATURE_KEY,
1905+
GENERIC_USER_ID
1906+
);
1907+
1908+
assertTrue(compareJsonStrings(json.toString(), defaultValueOfStringVar));
1909+
}
1910+
1911+
//GetAllFeatureVariables Scenario#2 with attributes
1912+
@Test
1913+
public void testGetAllFeatureVariablesWithAttr() {
1914+
assumeTrue(datafileVersion == Integer.parseInt(ProjectConfig.Version.V4.toString()));
1915+
1916+
OptimizelyClient optimizelyClient = new OptimizelyClient(
1917+
optimizely,
1918+
logger);
1919+
1920+
1921+
String defaultValueOfStringVar = "{\"first_letter\":\"F\",\"json_patched\":{\"k1\":\"s1\",\"k2\":103.5,\"k3\":false,\"k4\":{\"kk1\":\"ss1\",\"kk2\":true}},\"rest_of_name\":\"eorge\"}";
1922+
1923+
OptimizelyJSON json = optimizelyClient.getAllFeatureVariables(
1924+
STRING_FEATURE_KEY,
1925+
GENERIC_USER_ID,
1926+
Collections.singletonMap("house", "Gryffindor")
1927+
);
1928+
1929+
assertTrue(compareJsonStrings(json.toString(), defaultValueOfStringVar));
1930+
verifyZeroInteractions(logger);
1931+
}
1932+
1933+
//GetAllFeatureVariables Scenario#3 if feature not found
1934+
@Test
1935+
public void testGetAllFeatureVariablesInvalidFeatureKey() {
1936+
assumeTrue(datafileVersion == Integer.parseInt(ProjectConfig.Version.V4.toString()));
1937+
1938+
OptimizelyClient optimizelyClient = new OptimizelyClient(
1939+
optimizely,
1940+
logger);
1941+
1942+
assertNull(optimizelyClient.getAllFeatureVariables(
1943+
"invalidFeatureKey",
1944+
GENERIC_USER_ID
1945+
));
1946+
}
1947+
1948+
@Test
1949+
public void testBadGetAllFeatureVariables() {
1950+
OptimizelyClient optimizelyClient = new OptimizelyClient(null, logger);
1951+
1952+
//Scenario#1 without attributes
1953+
assertNull(optimizelyClient.getAllFeatureVariables(
1954+
STRING_FEATURE_KEY,
1955+
GENERIC_USER_ID
1956+
));
1957+
1958+
verify(logger).warn("Optimizely is not initialized, could not get feature {} all feature variables for user {}.",
1959+
STRING_FEATURE_KEY,
1960+
GENERIC_USER_ID
1961+
);
1962+
1963+
//Scenario#2 with attributes
1964+
assertNull(optimizelyClient.getAllFeatureVariables(
1965+
STRING_FEATURE_KEY,
1966+
GENERIC_USER_ID,
1967+
Collections.EMPTY_MAP
1968+
));
1969+
1970+
verify(logger).warn("Optimizely is not initialized, could not get feature {} all feature variables for user {} with attributes.",
1971+
STRING_FEATURE_KEY,
1972+
GENERIC_USER_ID
1973+
);
1974+
}
1975+
1976+
// Accessibility testing of OptimizelyJSON.getValue
1977+
@Test
1978+
public void testGetValueOfOptimizelyJson() {
1979+
assumeTrue(datafileVersion == Integer.parseInt(ProjectConfig.Version.V4.toString()));
1980+
1981+
Map<String, Object> expectedMap = new HashMap<>();
1982+
expectedMap.put("kk1", "vv1");
1983+
expectedMap.put("kk2", false);
1984+
1985+
OptimizelyClient optimizelyClient = new OptimizelyClient(
1986+
optimizely,
1987+
logger
1988+
);
1989+
1990+
OptimizelyJSON optimizelyJSON = optimizelyClient.getAllFeatureVariables(
1991+
STRING_FEATURE_KEY,
1992+
GENERIC_USER_ID
1993+
);
1994+
1995+
try {
1996+
assertEquals(optimizelyJSON.getValue("first_letter", String.class), "H");
1997+
assertEquals(optimizelyJSON.getValue("json_patched.k4", Map.class), expectedMap);
1998+
1999+
// When given jsonKey does not exist
2000+
assertNull(optimizelyJSON.getValue("json_patched.k5", String.class));
2001+
} catch (JsonParseException e) {
2002+
e.printStackTrace();
2003+
}
2004+
}
2005+
17672006
@Test
17682007
public void testGetOptimizelyConfig() {
17692008
assumeTrue(datafileVersion == Integer.parseInt(ProjectConfig.Version.V4.toString()));
@@ -1860,4 +2099,16 @@ public void handle(DecisionNotification decisionNotification) {
18602099
assertTrue(optimizelyClient.getNotificationCenter().removeNotificationListener(notificationId));
18612100
assertFalse(optimizelyClient.getNotificationCenter().removeNotificationListener(notificationId2));
18622101
}
2102+
2103+
private boolean compareJsonStrings(String str1, String str2) {
2104+
JsonParser parser = new JsonParser();
2105+
2106+
JsonElement j1 = parser.parse(str1);
2107+
JsonElement j2 = parser.parse(str2);
2108+
return j1.equals(j2);
2109+
}
2110+
2111+
private Map parseJsonString(String str) {
2112+
return new Gson().fromJson(str, Map.class);
2113+
}
18632114
}

android-sdk/src/debug/res/raw/validprojectconfigv4

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,13 @@
169169
}, {
170170
"id": "4111654444",
171171
"value": "3.14"
172-
}, {
172+
}, {
173173
"id": "593964691",
174174
"value": "2"
175-
}]
175+
}, {
176+
"id": "4111661000",
177+
"value": "{\"k1\":\"s1\",\"k2\":103.5,\"k3\":false,\"k4\":{\"kk1\":\"ss1\",\"kk2\":true}}"
178+
}]
176179
}, {
177180
"id": "4204375027",
178181
"key": "Gred",
@@ -477,7 +480,13 @@
477480
"key": "rest_of_name",
478481
"type": "string",
479482
"defaultValue": "arry"
480-
}]
483+
}, {
484+
"id": "4111661000",
485+
"key": "json_patched",
486+
"type": "string",
487+
"subType": "json",
488+
"defaultValue": "{\"k1\":\"v1\",\"k2\":3.5,\"k3\":true,\"k4\":{\"kk1\":\"vv1\",\"kk2\":false}}"
489+
}]
481490
}, {
482491
"id": "3263342226",
483492
"key": "mutex_group_feature",

0 commit comments

Comments
 (0)