Skip to content

Commit 925e570

Browse files
fix for datafile download start when datafile has not changed or when… (#199)
* fix for datafile download start when datafile has not changed or when starting synchronously * to avoid multiple starts, stop any service that is running before starting. * added some unit tests to make sure that backgrounding is started when interval is set
1 parent 1026563 commit 925e570

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

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

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import android.support.test.runner.AndroidJUnit4;
3030

3131
import com.optimizely.ab.android.datafile_handler.DatafileHandler;
32+
import com.optimizely.ab.android.datafile_handler.DatafileLoadedListener;
3233
import com.optimizely.ab.android.datafile_handler.DatafileService;
3334
import com.optimizely.ab.android.datafile_handler.DefaultDatafileHandler;
3435
import com.optimizely.ab.android.event_handler.DefaultEventHandler;
@@ -44,6 +45,8 @@
4445
import org.junit.Test;
4546
import org.junit.runner.RunWith;
4647
import org.mockito.ArgumentCaptor;
48+
import org.mockito.invocation.InvocationOnMock;
49+
import org.mockito.stubbing.Answer;
4750
import org.slf4j.Logger;
4851

4952
import java.util.concurrent.TimeUnit;
@@ -56,6 +59,7 @@
5659
import static junit.framework.Assert.fail;
5760
import static org.mockito.Matchers.any;
5861
import static org.mockito.Matchers.eq;
62+
import static org.mockito.Mockito.doAnswer;
5963
import static org.mockito.Mockito.mock;
6064
import static org.mockito.Mockito.verify;
6165
import static org.mockito.Mockito.when;
@@ -112,6 +116,7 @@ public void initializeInt() {
112116

113117
assertEquals(optimizelyManager.getDatafileUrl("1"), "https://cdn.optimizely.com/json/1.json" );
114118

119+
verify(optimizelyManager.getDatafileHandler()).startBackgroundUpdates(eq(InstrumentationRegistry.getTargetContext()), eq(testProjectId), eq(3600L));
115120
assertNotNull(optimizelyManager.getOptimizely());
116121
assertNotNull(optimizelyManager.getDatafileHandler());
117122

@@ -174,14 +179,28 @@ public void initializeAsync() {
174179
* Scenario#1: when datafile is not Empty
175180
* Scenario#2: when datafile is Empty
176181
*/
177-
optimizelyManager.initialize(InstrumentationRegistry.getContext(), R.raw.datafile, new OptimizelyStartListener() {
182+
183+
doAnswer(
184+
new Answer<Object>() {
185+
public Object answer(InvocationOnMock invocation) {
186+
((DatafileLoadedListener) invocation.getArguments()[2]).onDatafileLoaded(null);
187+
return null;
188+
}
189+
}).when(optimizelyManager.getDatafileHandler()).downloadDatafile(any(Context.class), any(String.class),
190+
any(DatafileLoadedListener.class));
191+
192+
OptimizelyStartListener listener = new OptimizelyStartListener() {
178193
@Override
179194
public void onStart(OptimizelyClient optimizely) {
180195
assertNotNull(optimizelyManager.getOptimizely());
181196
assertNotNull(optimizelyManager.getDatafileHandler());
182197
assertNull(optimizelyManager.getOptimizelyStartListener());
183198
}
184-
});
199+
};
200+
optimizelyManager.initialize(InstrumentationRegistry.getContext(), R.raw.datafile, listener);
201+
202+
verify(optimizelyManager.getDatafileHandler()).startBackgroundUpdates(any(Context.class), eq(testProjectId), eq(3600L));
203+
185204

186205
assertEquals(optimizelyManager.isDatafileCached(InstrumentationRegistry.getTargetContext()), false);
187206

@@ -271,6 +290,28 @@ public void injectOptimizely() {
271290

272291
verify(logger).info("Sending Optimizely instance to listener");
273292
verify(startListener).onStart(any(OptimizelyClient.class));
293+
verify(optimizelyManager.getDatafileHandler()).startBackgroundUpdates(eq(context), eq(testProjectId), eq(3600L));
294+
295+
}
296+
297+
@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
298+
@Test
299+
public void injectOptimizelyWithDatafileLisener() {
300+
Context context = mock(Context.class);
301+
UserProfileService userProfileService = mock(UserProfileService.class);
302+
OptimizelyStartListener startListener = mock(OptimizelyStartListener.class);
303+
304+
optimizelyManager.setOptimizelyStartListener(startListener);
305+
optimizelyManager.injectOptimizely(context, userProfileService, minDatafile);
306+
try {
307+
executor.awaitTermination(5, TimeUnit.SECONDS);
308+
} catch (InterruptedException e) {
309+
fail("Timed out");
310+
}
311+
312+
verify(optimizelyManager.getDatafileHandler()).startBackgroundUpdates(eq(context), eq(testProjectId), eq(3600L));
313+
verify(logger).info("Sending Optimizely instance to listener");
314+
verify(startListener).onStart(any(OptimizelyClient.class));
274315
}
275316

276317
@Test

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public class OptimizelyManager {
6969
@Nullable private ErrorHandler errorHandler;
7070
@NonNull private Logger logger;
7171
@NonNull private final String projectId;
72+
7273
@NonNull private UserProfileService userProfileService;
7374

7475
@Nullable private OptimizelyStartListener optimizelyStartListener;
@@ -165,6 +166,11 @@ protected OptimizelyClient initialize(@NonNull Context context,@Nullable String
165166
defaultUserProfileService.start();
166167
}
167168
optimizelyClient = buildOptimizely(context, datafile);
169+
170+
if (datafileDownloadInterval > 0 && datafileHandler != null) {
171+
datafileHandler.startBackgroundUpdates(context, projectId, datafileDownloadInterval);
172+
}
173+
168174
}
169175
else {
170176
logger.error("Invalid datafile");
@@ -303,8 +309,7 @@ public void onDatafileLoaded(@Nullable String datafile) {
303309
} else {
304310
//if datafile is null than it should be able to take from cache and if not present
305311
//in Cache than should be able to get from raw data file
306-
optimizelyClient = initialize(context,getDatafile(context,datafileRes),false);
307-
notifyStartListener();
312+
injectOptimizely(context, userProfileService, getDatafile(context,datafileRes));
308313
}
309314
}
310315

@@ -384,7 +389,6 @@ public boolean isDatafileCached(Context context) {
384389
public @NonNull String getDatafileUrl(String projectId) {
385390
return DatafileService.getDatafileUrl(projectId);
386391
}
387-
388392
@NonNull
389393
public String getProjectId() {
390394
return projectId;
@@ -584,6 +588,7 @@ public static class Builder {
584588
@Nullable private EventHandler eventHandler = null;
585589
@Nullable private ErrorHandler errorHandler = null;
586590
@Nullable private UserProfileService userProfileService = null;
591+
587592
Builder(@NonNull String projectId) {
588593
this.projectId = projectId;
589594
}

datafile-handler/src/main/java/com/optimizely/ab/android/datafile_handler/DefaultDatafileHandler.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ public void onStop(Context context) {
103103
* @param updateInterval frequency of updates in seconds
104104
*/
105105
public void startBackgroundUpdates(Context context, String projectId, Long updateInterval) {
106+
107+
// if already running, stop it
108+
stopBackgroundUpdates(context, projectId);
109+
106110
enableBackgroundCache(context, projectId);
107111

108112
ServiceScheduler.PendingIntentFactory pendingIntentFactory = new ServiceScheduler

0 commit comments

Comments
 (0)