Skip to content

Commit fc23783

Browse files
author
Vignesh Raja
authored
Release version 0.5.0 (#81)
1 parent 41486e2 commit fc23783

File tree

10 files changed

+176
-170
lines changed

10 files changed

+176
-170
lines changed

CHANGELOG.md

+11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
# Optimizely Android X SDK Changelog
2+
### 0.5.0
3+
4+
*Bug Fixes*
5+
6+
- Persist experiment and variation IDs instead of keys in the `AndroidUserProfile`
7+
8+
*Breaking Changes*
9+
10+
- Change live variable getter signature from `getVariableFloat` to `getVariableDouble`
11+
212
### 0.4.1
313
December 28, 2016
414

@@ -28,6 +38,7 @@ December 8, 2016
2838

2939
### 0.2.2
3040
November 30, 2016
41+
3142
*Bug Fixes*
3243
- Update to java-core 1.0.3 which fixes crashes with Jackson annotations on ICS
3344
- Use the old SQLiteDatabse constructor for compatibility with ICS

README.md

+10-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# optimizely-ab-android-sdk
1+
# Optimizely Android SDK
22
Master<br/>
33
[![Master Status](https://travis-ci.org/optimizely/android-sdk.svg?branch=master)](https://travis-ci.org/optimizely/android-sdk)
44
<br/>
@@ -12,11 +12,9 @@ Devel<br/>
1212
[![Apache 2.0](https://img.shields.io/github/license/nebula-plugins/gradle-extra-configurations-plugin.svg)](http://www.apache.org/licenses/LICENSE-2.0)
1313
## Overview
1414

15-
Our Optimizely X Android solution allows you to easily run experiments anywhere in an Android application, even Services. The solution includes easy-to-use SDKs for experimenting in your code and tracking conversion events in Optimizely.
15+
This repository houses the Android SDK for Optimizely's Mobile product. To find out more check out the [documentation](https://developers.optimizely.com/x/solutions/sdks/introduction/index.html?language=android&platform=mobile).
1616

17-
To find out more check out the [documentation](https://developers.optimizely.com/x/solutions/sdks/introduction/index.html?language=android&platform=mobile).
18-
19-
This repo depends on [Optimizely X Java](https://github.com/optimizely/java-sdk).
17+
This repo depends on the [Optimizely Java SDK](https://github.com/optimizely/java-sdk).
2018

2119
## Architecture
2220

@@ -27,13 +25,13 @@ root declares modules. The `build.gradle` in the project root has build
2725
config common for all modules.
2826

2927
1. Android SDK
30-
- Users who want all modules should just declare a dependency on this module
28+
- Users who want all modules should declare a dependency on this module
3129
- This is the outer module that depends on all other modules
32-
- Handles downloading the Optimizely Data File and building Optimizely objects
30+
- Handles downloading the Optimizely datafile and building Optimizely objects
3331
- Delivers the built Optimizely object to listeners and caches it in memory
3432
2. Event Handler
35-
- Handles dispatching events to the Optimizely Backend
36-
- Uses a Service so events can be sent without the app being reopened
33+
- Handles dispatching events to the Optimizely backend
34+
- Uses a Service so events can be sent without the app being re-opened
3735
- Persists events in a SQLite3 database
3836
- Required to be implemented by the Optimizely Java core
3937
3. User Profile
@@ -51,10 +49,8 @@ config common for all modules.
5149
### Command Line
5250

5351
1. Clone the repo
54-
* `git clone [email protected]:optimizely/optimizely-ab-android-sdk.git`
55-
3. Create, or use an existing, Optimizely Custom Project
56-
* put a file in `test-app/src/main/res/values/git_ignored_strings.xml`
57-
* Give it this contents `<resources><string name="optly_project_id">{CUSTOM_PROJECT_ID}</string></resources>`
52+
* `git clone [email protected]:optimizely/android-sdk.git`
53+
3. Create, or use an existing, Optimizely Android project
5854
4. Build the project (from the project root)
5955
* `./gradlew assemble`
6056
5. Run tests for all modules
@@ -84,7 +80,7 @@ The default branch is devel. Feature branch PRs are automatically made against
8480

8581
Versions are managed via git tags. Tags can be created from the command line or from the Github UI.
8682

87-
Snapshot builds are made off of the beta branch. Travis will test all commits to this branch. When commit is tagged and pushed travis will build, test, *and*, ship the build bintray. The version name used
83+
Snapshot builds are made off of the beta branch. Travis will test all commits to this branch. When a commit is tagged and pushed, Travis will build, test, *and*, ship the build to Bintray. The version name used
8884
is the name of the tag. For snapshot builds the version should have `-SNAPSHOT` appended. For example `0.1.2-SNAPSHOT`. Multiple builds with the same version can be pushed to Bintray when using snapshot versions.
8985
This keeps the version number from increasing too quickly for beta builds. Grade and maven ensure that users are on the latest snapshot via timestamps.
9086
There can be only one git tag per version name so snapshot tags may need to be moved. For example `git tag -f -a 0.1.2` and `git push -f --tags`.

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

+15-14
Original file line numberDiff line numberDiff line change
@@ -276,33 +276,34 @@ public void track(@NonNull String eventName,
276276
}
277277

278278
/**
279-
* Get the value of a Float live variable
279+
* Get the value of a Double live variable
280280
* @param variableKey the String key for the variable
281281
* @param userId the user ID
282282
* @param activateExperiment the flag denoting whether to activate an experiment or not
283-
* @return Float value of the live variable
283+
* @return Double value of the live variable
284284
*/
285-
public @Nullable Float getVariableFloat(@NonNull String variableKey,
286-
@NonNull String userId,
287-
boolean activateExperiment) {
288-
return getVariableFloat(variableKey, userId, Collections.<String, String>emptyMap(),
289-
activateExperiment);
285+
public @Nullable Double getVariableDouble(@NonNull String variableKey,
286+
@NonNull String userId,
287+
boolean activateExperiment) {
288+
return getVariableDouble(variableKey, userId, Collections.<String, String>emptyMap(),
289+
activateExperiment);
290290
}
291291

292292
/**
293-
* Get the value of a Float live variable
293+
* Get the value of a Double live variable
294294
* @param variableKey the String key for the variable
295295
* @param userId the user ID
296296
* @param attributes a map of attributes about the user
297297
* @param activateExperiment the flag denoting whether to activate an experiment or not
298-
* @return Float value of the live variable
298+
* @return Double value of the live variable
299299
*/
300-
public @Nullable Float getVariableFloat(@NonNull String variableKey,
301-
@NonNull String userId,
302-
@NonNull Map<String, String> attributes,
303-
boolean activateExperiment) {
300+
public @Nullable Double getVariableDouble(@NonNull String variableKey,
301+
@NonNull String userId,
302+
@NonNull Map<String, String> attributes,
303+
boolean activateExperiment) {
304304
if (optimizely != null) {
305-
return optimizely.getVariableFloat(variableKey, userId, attributes, activateExperiment);
305+
return optimizely.getVariableDouble(variableKey, userId, attributes,
306+
activateExperiment);
306307
} else {
307308
logger.warn("Optimizely is not initialized, could not get live variable {} " +
308309
"for user {}", variableKey, userId);

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

+8-8
Original file line numberDiff line numberDiff line change
@@ -238,19 +238,19 @@ public void testBadGetVariableInteger() {
238238
}
239239

240240
@Test
241-
public void testGoodGetVariableFloat() {
241+
public void testGoodGetVariableDouble() {
242242
OptimizelyClient optimizelyClient = new OptimizelyClient(optimizely, logger);
243-
optimizelyClient.getVariableFloat("test_key", "userId",
244-
Collections.<String, String>emptyMap(), true);
245-
verify(optimizely).getVariableFloat("test_key", "userId",
246-
Collections.<String, String>emptyMap(), true);
243+
optimizelyClient.getVariableDouble("test_key", "userId",
244+
Collections.<String, String>emptyMap(), true);
245+
verify(optimizely).getVariableDouble("test_key", "userId",
246+
Collections.<String, String>emptyMap(), true);
247247
}
248248

249249
@Test
250-
public void testBadGetVariableFloat() {
250+
public void testBadGetVariableDouble() {
251251
OptimizelyClient optimizelyClient = new OptimizelyClient(null, logger);
252-
optimizelyClient.getVariableFloat("test_key", "userId",
253-
Collections.<String, String>emptyMap(), true);
252+
optimizelyClient.getVariableDouble("test_key", "userId",
253+
Collections.<String, String>emptyMap(), true);
254254
verify(logger).warn("Optimizely is not initialized, could not get live variable {} " +
255255
"for user {}", "test_key", "userId");
256256
}

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ ext {
5252
min_sdk_version = 10
5353
target_sdk_version = 24
5454

55-
java_core_ver = "1.2.0"
55+
java_core_ver = "1.3.0"
5656
android_logger_ver = "1.3.1"
5757
support_annotations_ver = "24.2.1"
5858
junit_ver = "4.12"

test-app/README.md

+4-6
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ is also used to run integration tests on using the Android Espresso framework.
55

66
## Experiments Run
77

8-
The experiments run in this demo app are part of the [email protected] account.
9-
108
We run the following experiment:
119
- Background change in second activity, which is loaded after the splash screen.
1210

@@ -15,12 +13,12 @@ We run the following experiment:
1513
The SDK is implemented in the following way:
1614
- The splash screen initializes the Optimizely manager asynchronously. This starts the datafile
1715
fetch.
18-
- Once the datafile is fetched and the Optimizely manager is started, we use grab the `optimizelyClient`
19-
from the manager and use it to activate the `background_experiment`. This buckets the user and sends
16+
- Once the datafile is fetched and the Optimizely manager is started, we grab the `optimizelyClient`
17+
from the manager and use it to activate the experiment named `background_experiment`. This buckets the user and sends
2018
an impression event.
2119
- We then use the bucketed variation to determine which activity to show. `VariationAActivity` for
22-
`variation_a` and `VariationBActivity` for `variation_b`.
23-
- Each of those activities include a `Test Conversion` button.
20+
`variation_a`, `VariationBActivity` for `variation_b`, or `ActivationErrorActivity` for the control.
21+
- Each of the variation activities includes a `Test Conversion` button.
2422
- Clicking on that button will call `optimizelyClient.track()` and send a conversion event for the
2523
event named `sample_conversion`.
2624
- Then the application will navigate to the conversion page to confirm that a conversion event has

test-app/build.gradle

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ android {
2929
dependencies {
3030
// Includes SST Java core, event handler, and user profile
3131
compile project(':android-sdk')
32-
// compile 'com.optimizely.ab:android-sdk:0.3.1'
32+
// compile 'com.optimizely.ab:android-sdk:0.5.0'
3333
compile 'com.android.support:appcompat-v7:24.2.1'
3434
compile 'com.android.support:design:24.2.1'
3535

3636
testCompile "junit:junit:$junit_ver"
3737
testCompile "org.mockito:mockito-core:$mockito_ver"
3838
testCompile "com.noveogroup.android:android-logger:$android_logger_ver"
39-
// testCompile 'com.optimizely.ab:android-sdk:0.3.1'
39+
// testCompile 'com.optimizely.ab:android-sdk:0.5.0'
4040
testCompile project(':android-sdk')
4141

4242
androidTestCompile("com.android.support.test:runner:$support_test_runner_ver")
@@ -48,6 +48,6 @@ dependencies {
4848
androidTestCompile "org.mockito:mockito-core:$mockito_ver"
4949
androidTestCompile "com.google.dexmaker:dexmaker:$dexmaker_ver"
5050
androidTestCompile "com.google.dexmaker:dexmaker-mockito:$dexmaker_ver"
51-
// androidTestCompile 'com.optimizely.ab:android-sdk:0.3.1'
51+
// androidTestCompile 'com.optimizely.ab:android-sdk:0.5.0'
5252
androidTestCompile project(':android-sdk')
5353
}

user-profile/src/androidTest/java/com/optimizely/ab/android/user_profile/AndroidUserProfileTest.java

+48-48
Original file line numberDiff line numberDiff line change
@@ -80,131 +80,131 @@ public void teardown() {
8080
@Test
8181
public void saveActivation() {
8282
String userId = "user1";
83-
String expKey = "exp1";
84-
String varKey = "var1";
85-
assertTrue(androidUserProfile.save(userId, expKey, varKey));
83+
String expId = "1";
84+
String varId = "2";
85+
assertTrue(androidUserProfile.save(userId, expId, varId));
8686
try {
8787
executor.awaitTermination(5, TimeUnit.SECONDS);
8888
} catch (InterruptedException e) {
8989
fail("Time out");
9090
}
91-
assertEquals(varKey, androidUserProfile.lookup(userId, expKey));
91+
assertEquals(varId, androidUserProfile.lookup(userId, expId));
9292
}
9393

9494
@Test
9595
public void saveActivationNullUserId() {
96-
assertFalse(androidUserProfile.save(null, "exp1", "var1"));
97-
verify(logger).error("Received null userId, unable to save activation");
96+
assertFalse(androidUserProfile.save(null, "1", "2"));
97+
verify(logger).error("Received null userId, unable to save activation.");
9898
}
9999

100100
@Test
101-
public void saveActivationNullExperimentKey() {
102-
assertFalse(androidUserProfile.save("foo", null, "var1"));
103-
verify(logger).error("Received null experiment key, unable to save activation");
101+
public void saveActivationNullExperimentId() {
102+
assertFalse(androidUserProfile.save("foo", null, "1"));
103+
verify(logger).error("Received null experiment ID, unable to save activation.");
104104
}
105105

106106
@Test
107-
public void saveActivationNullVariationKey() {
108-
assertFalse(androidUserProfile.save("foo", "exp1", null));
109-
verify(logger).error("Received null variation key, unable to save activation");
107+
public void saveActivationNullVariationId() {
108+
assertFalse(androidUserProfile.save("foo", "1", null));
109+
verify(logger).error("Received null variation ID, unable to save activation.");
110110
}
111111

112112
@Test
113113
public void saveActivationEmptyUserId() {
114-
assertFalse(androidUserProfile.save("", "exp1", "var1"));
115-
verify(logger).error("Received empty user id, unable to save activation");
114+
assertFalse(androidUserProfile.save("", "1", "2"));
115+
verify(logger).error("Received empty user ID, unable to save activation.");
116116
}
117117

118118
@Test
119-
public void saveActivationEmptyExperimentKey() {
120-
assertFalse(androidUserProfile.save("foo", "", "var1"));
121-
verify(logger).error("Received empty experiment key, unable to save activation");
119+
public void saveActivationEmptyExperimentId() {
120+
assertFalse(androidUserProfile.save("foo", "", "1"));
121+
verify(logger).error("Received empty experiment ID, unable to save activation.");
122122
}
123123

124124
@Test
125-
public void saveActivationEmptyVariationKey() {
126-
assertFalse(androidUserProfile.save("foo", "exp1", ""));
127-
verify(logger).error("Received empty variation key, unable to save activation");
125+
public void saveActivationEmptyVariationId() {
126+
assertFalse(androidUserProfile.save("foo", "1", ""));
127+
verify(logger).error("Received empty variation ID, unable to save activation.");
128128
}
129129

130130
@Test
131131
public void lookupActivationNullUserId() {
132-
assertNull(androidUserProfile.lookup(null, "exp1"));
133-
verify(logger).error("Received null user id, unable to lookup activation");
132+
assertNull(androidUserProfile.lookup(null, "1"));
133+
verify(logger).error("Received null user ID, unable to lookup activation.");
134134
}
135135

136136
@Test
137-
public void lookupActivationNullExperimentKey() {
138-
assertNull(androidUserProfile.lookup("foo", null));
139-
verify(logger).error("Received null experiment key, unable to lookup activation");
137+
public void lookupActivationNullExperimentId() {
138+
assertNull(androidUserProfile.lookup("1", null));
139+
verify(logger).error("Received null experiment ID, unable to lookup activation.");
140140
}
141141

142142
@Test
143143
public void lookupActivationEmptyUserId() {
144-
assertNull(androidUserProfile.lookup("", "exp1"));
145-
verify(logger).error("Received empty user id, unable to lookup activation");
144+
assertNull(androidUserProfile.lookup("", "1"));
145+
verify(logger).error("Received empty user ID, unable to lookup activation.");
146146
}
147147

148148
@Test
149-
public void lookupActivationEmptyExperimentKey() {
149+
public void lookupActivationEmptyExperimentId() {
150150
assertNull(androidUserProfile.lookup("foo", ""));
151-
verify(logger).error("Received empty experiment key, unable to lookup activation");
151+
verify(logger).error("Received empty experiment ID, unable to lookup activation.");
152152
}
153153

154154
@Test
155155
public void removeExistingActivation() {
156-
androidUserProfile.save("user1", "exp1", "var1");
157-
assertTrue(androidUserProfile.remove("user1", "exp1"));
158-
assertNull(androidUserProfile.lookup("user1", "exp1"));
156+
androidUserProfile.save("user1", "1", "2");
157+
assertTrue(androidUserProfile.remove("user1", "1"));
158+
assertNull(androidUserProfile.lookup("user1", "1"));
159159
}
160160

161161
@Test
162162
public void removeNonExistingActivation() {
163-
assertFalse(androidUserProfile.remove("user1", "exp1"));
163+
assertFalse(androidUserProfile.remove("user1", "1"));
164164
}
165165

166166
@Test
167167
public void removeActivationNullUserId() {
168-
assertFalse(androidUserProfile.remove(null, "exp1"));
169-
verify(logger).error("Received null user id, unable to remove activation");
168+
assertFalse(androidUserProfile.remove(null, "1"));
169+
verify(logger).error("Received null user ID, unable to remove activation.");
170170
}
171171

172172
@Test
173-
public void removeActivationNullExperimentKey() {
173+
public void removeActivationNullExperimentId() {
174174
assertFalse(androidUserProfile.remove("foo", null));
175-
verify(logger).error("Received null experiment key, unable to remove activation");
175+
verify(logger).error("Received null experiment ID, unable to remove activation.");
176176
}
177177

178178
@Test
179179
public void removeActivationEmptyUserId() {
180-
assertFalse(androidUserProfile.remove("", "exp1"));
181-
verify(logger).error("Received empty user id, unable to remove activation");
180+
assertFalse(androidUserProfile.remove("", "1"));
181+
verify(logger).error("Received empty user ID, unable to remove activation.");
182182
}
183183

184184
@Test
185-
public void removeActivationEmptyExperimentKey() {
185+
public void removeActivationEmptyExperimentId() {
186186
assertFalse(androidUserProfile.remove("foo", ""));
187-
verify(logger).error("Received empty experiment key, unable to remove activation");
187+
verify(logger).error("Received empty experiment ID, unable to remove activation.");
188188
}
189189

190190
@Test
191191
public void startHandlesJSONException() throws IOException {
192192
assertTrue(cache.save(diskUserProfileCache.getFileName(), "{"));
193193
androidUserProfile.start();
194-
verify(logger).error(eq("Unable to parse user profile cache"), any(JSONException.class));
194+
verify(logger).error(eq("Unable to parse user profile cache."), any(JSONException.class));
195195
}
196196

197197
@Test
198198
public void start() throws JSONException {
199199
androidUserProfile.start();
200-
androidUserProfile.save("user1", "exp1", "var1");
201-
androidUserProfile.save("user1", "exp2", "var2");
200+
androidUserProfile.save("user1", "1", "3");
201+
androidUserProfile.save("user1", "2", "4");
202202

203-
Map<String, String> expKeyToVarKeyMap = new HashMap<>();
204-
expKeyToVarKeyMap.put("exp1", "var1");
205-
expKeyToVarKeyMap.put("exp2", "var2");
203+
Map<String, String> expIdToVarIdMap = new HashMap<>();
204+
expIdToVarIdMap.put("1", "3");
205+
expIdToVarIdMap.put("2", "4");
206206
Map<String, Map<String, String>> profileMap = new HashMap<>();
207-
profileMap.put("user1", expKeyToVarKeyMap);
207+
profileMap.put("user1", expIdToVarIdMap);
208208

209209
assertEquals(profileMap, memoryUserProfileCache);
210210
}

0 commit comments

Comments
 (0)