Skip to content

Commit 848bca3

Browse files
author
Josh Deffibaugh
committed
Simplifies datafile loader and makes tests integration tests
1 parent 4f8739a commit 848bca3

File tree

10 files changed

+308
-271
lines changed

10 files changed

+308
-271
lines changed

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

android-sdk/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ dependencies {
6060
testCompile "junit:junit:$junit_ver"
6161
testCompile "org.mockito:mockito-core:$mockito_ver"
6262
testCompile "com.noveogroup.android:android-logger:$android_logger_ver"
63+
testCompile "com.android.support.test.espresso:espresso-core:$espresso_ver"
6364

6465
androidTestCompile "com.android.support.test:runner:$support_test_runner_ver"
6566
// Set this dependency to use JUnit 4 rules

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public void setup() {
6262

6363
@Test
6464
public void request200() throws IOException {
65-
URL url = new URL(String.format(DataFileLoader.RequestDataFileFromClientTask.FORMAT_CDN_URL, "1"));
65+
URL url = new URL(String.format(DataFileLoader.FORMAT_CDN_URL, "1"));
6666
when(client.openConnection(url)).thenReturn(urlConnection);
6767
when(urlConnection.getResponseCode()).thenReturn(200);
6868
when(client.readStream(urlConnection)).thenReturn("{}");
@@ -87,7 +87,7 @@ public void request200() throws IOException {
8787

8888
@Test
8989
public void request201() throws IOException {
90-
URL url = new URL(String.format(DataFileLoader.RequestDataFileFromClientTask.FORMAT_CDN_URL, "1"));
90+
URL url = new URL(String.format(DataFileLoader.FORMAT_CDN_URL, "1"));
9191
when(client.openConnection(url)).thenReturn(urlConnection);
9292
when(urlConnection.getResponseCode()).thenReturn(201);
9393
when(client.readStream(urlConnection)).thenReturn("{}");
@@ -112,7 +112,7 @@ public void request201() throws IOException {
112112

113113
@Test
114114
public void request299() throws IOException {
115-
URL url = new URL(String.format(DataFileLoader.RequestDataFileFromClientTask.FORMAT_CDN_URL, "1"));
115+
URL url = new URL(String.format(DataFileLoader.FORMAT_CDN_URL, "1"));
116116
when(client.openConnection(url)).thenReturn(urlConnection);
117117
when(urlConnection.getResponseCode()).thenReturn(299);
118118
when(client.readStream(urlConnection)).thenReturn("{}");
@@ -137,7 +137,7 @@ public void request299() throws IOException {
137137

138138
@Test
139139
public void request300() throws IOException {
140-
URL url = new URL(String.format(DataFileLoader.RequestDataFileFromClientTask.FORMAT_CDN_URL, "1"));
140+
URL url = new URL(String.format(DataFileLoader.FORMAT_CDN_URL, "1"));
141141
when(client.openConnection(url)).thenReturn(urlConnection);
142142
when(urlConnection.getResponseCode()).thenReturn(300);
143143

@@ -157,7 +157,7 @@ public void request300() throws IOException {
157157

158158
@Test
159159
public void handlesIOException() throws IOException {
160-
URL url = new URL(String.format(DataFileLoader.RequestDataFileFromClientTask.FORMAT_CDN_URL, "1"));
160+
URL url = new URL(String.format(DataFileLoader.FORMAT_CDN_URL, "1"));
161161
when(client.openConnection(url)).thenReturn(urlConnection);
162162
when(urlConnection.getResponseCode()).thenReturn(200);
163163
doThrow(new IOException()).when(client).readStream(urlConnection);
@@ -179,14 +179,14 @@ public void handlesIOException() throws IOException {
179179

180180
@Test
181181
public void handlesNullResponse() throws MalformedURLException {
182-
URL url = new URL(String.format(DataFileLoader.RequestDataFileFromClientTask.FORMAT_CDN_URL, "1"));
182+
URL url = new URL(String.format(DataFileLoader.FORMAT_CDN_URL, "1"));
183183
when(client.execute(any(Client.Request.class), eq(2), eq(3))).thenReturn(null);
184184
assertNull(dataFileClient.request(url.toString()));
185185
}
186186

187187
@Test
188188
public void handlesEmptyStringResponse() throws MalformedURLException {
189-
URL url = new URL(String.format(DataFileLoader.RequestDataFileFromClientTask.FORMAT_CDN_URL, "1"));
189+
URL url = new URL(String.format(DataFileLoader.FORMAT_CDN_URL, "1"));
190190
when(client.execute(any(Client.Request.class), eq(2), eq(3))).thenReturn("");
191191
assertEquals("", dataFileClient.request(url.toString()));
192192
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
/*
2+
* Copyright 2016, Optimizely
3+
* <p/>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p/>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p/>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.optimizely.ab.android.sdk;
17+
18+
import android.content.Context;
19+
import android.os.Build;
20+
import android.support.annotation.RequiresApi;
21+
import android.support.test.InstrumentationRegistry;
22+
import android.support.test.espresso.core.deps.guava.util.concurrent.ListeningExecutorService;
23+
import android.support.test.espresso.core.deps.guava.util.concurrent.MoreExecutors;
24+
import android.support.test.runner.AndroidJUnit4;
25+
26+
import com.optimizely.ab.android.shared.Cache;
27+
import com.optimizely.ab.android.shared.Client;
28+
29+
import org.json.JSONException;
30+
import org.json.JSONObject;
31+
import org.junit.After;
32+
import org.junit.Before;
33+
import org.junit.Test;
34+
import org.junit.runner.RunWith;
35+
import org.slf4j.Logger;
36+
37+
import java.io.IOException;
38+
import java.net.MalformedURLException;
39+
import java.util.concurrent.TimeUnit;
40+
41+
import static junit.framework.Assert.assertEquals;
42+
import static junit.framework.Assert.assertNotNull;
43+
import static junit.framework.Assert.assertNull;
44+
import static junit.framework.Assert.fail;
45+
import static org.mockito.Matchers.any;
46+
import static org.mockito.Matchers.anyInt;
47+
import static org.mockito.Mockito.atMost;
48+
import static org.mockito.Mockito.mock;
49+
import static org.mockito.Mockito.verify;
50+
import static org.mockito.Mockito.when;
51+
52+
/**
53+
* Tests for {@link DataFileLoader}
54+
*/
55+
@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
56+
@RunWith(AndroidJUnit4.class)
57+
public class DataFileLoaderTest {
58+
59+
private DataFileService datafileService;
60+
private DataFileCache dataFileCache;
61+
private DataFileClient dataFileClient;
62+
private Client client;
63+
private Logger logger;
64+
private DataFileLoadedListener dataFileLoadedListener;
65+
66+
@Before
67+
public void setup() {
68+
datafileService = mock(DataFileService.class);
69+
logger = mock(Logger.class);
70+
final Context targetContext = InstrumentationRegistry.getTargetContext();
71+
dataFileCache = new DataFileCache("1", new Cache(targetContext, logger), logger);
72+
client = mock(Client.class);
73+
dataFileClient = new DataFileClient(client, logger);
74+
dataFileLoadedListener = mock(DataFileLoadedListener.class);
75+
when(datafileService.getApplicationContext()).thenReturn(targetContext);
76+
when(datafileService.isBound()).thenReturn(true);
77+
}
78+
79+
@After
80+
public void tearDown() {
81+
dataFileCache.delete();
82+
}
83+
84+
@Test
85+
public void loadFromCDNWhenNoCachedFile() throws MalformedURLException, JSONException {
86+
final ListeningExecutorService executor = MoreExecutors.newDirectExecutorService();
87+
DataFileLoader dataFileLoader =
88+
new DataFileLoader(datafileService, dataFileClient, dataFileCache, executor, logger);
89+
90+
when(client.execute(any(Client.Request.class), anyInt(), anyInt())).thenReturn("{}");
91+
92+
dataFileLoader.getDataFile("1", dataFileLoadedListener);
93+
try {
94+
executor.awaitTermination(5, TimeUnit.SECONDS);
95+
} catch (InterruptedException e) {
96+
fail();
97+
}
98+
99+
final JSONObject cachedDataFile = dataFileCache.load();
100+
assertNotNull(cachedDataFile);
101+
assertEquals("{}", cachedDataFile.toString());
102+
verify(dataFileLoadedListener, atMost(1)).onDataFileLoaded("{}");
103+
}
104+
105+
@Test
106+
public void loadWhenCacheFileExistsAndCDNNotModified() {
107+
final ListeningExecutorService executor = MoreExecutors.newDirectExecutorService();
108+
DataFileLoader dataFileLoader =
109+
new DataFileLoader(datafileService, dataFileClient, dataFileCache, executor, logger);
110+
dataFileCache.save("{}");
111+
112+
when(client.execute(any(Client.Request.class), anyInt(), anyInt())).thenReturn("");
113+
114+
dataFileLoader.getDataFile("1", dataFileLoadedListener);
115+
try {
116+
executor.awaitTermination(5, TimeUnit.SECONDS);
117+
} catch (InterruptedException e) {
118+
fail();
119+
}
120+
121+
final JSONObject cachedDataFile = dataFileCache.load();
122+
assertNotNull(cachedDataFile);
123+
assertEquals("{}", cachedDataFile.toString());
124+
verify(dataFileLoadedListener, atMost(1)).onDataFileLoaded("{}");
125+
}
126+
127+
@Test
128+
public void noCacheAndLoadFromCDNFails() {
129+
final ListeningExecutorService executor = MoreExecutors.newDirectExecutorService();
130+
DataFileLoader dataFileLoader =
131+
new DataFileLoader(datafileService, dataFileClient, dataFileCache, executor, logger);
132+
133+
when(client.execute(any(Client.Request.class), anyInt(), anyInt())).thenReturn(null);
134+
135+
dataFileLoader.getDataFile("1", dataFileLoadedListener);
136+
try {
137+
executor.awaitTermination(5, TimeUnit.SECONDS);
138+
} catch (InterruptedException e) {
139+
fail();
140+
}
141+
142+
final JSONObject cachedDataFile = dataFileCache.load();
143+
assertNull(cachedDataFile);
144+
verify(dataFileLoadedListener, atMost(1)).onDataFileLoaded(null);
145+
}
146+
147+
@Test
148+
public void warningsAreLogged() throws IOException {
149+
final ListeningExecutorService executor = MoreExecutors.newDirectExecutorService();
150+
Cache cache = mock(Cache.class);
151+
dataFileCache = new DataFileCache("1", cache, logger);
152+
DataFileLoader dataFileLoader =
153+
new DataFileLoader(datafileService, dataFileClient, dataFileCache, executor, logger);
154+
155+
when(client.execute(any(Client.Request.class), anyInt(), anyInt())).thenReturn("{}");
156+
when(cache.exists(dataFileCache.getFileName())).thenReturn(true);
157+
when(cache.delete(dataFileCache.getFileName())).thenReturn(false);
158+
when(cache.save(dataFileCache.getFileName(), "{}")).thenReturn(false);
159+
160+
dataFileLoader.getDataFile("1", dataFileLoadedListener);
161+
try {
162+
executor.awaitTermination(5, TimeUnit.SECONDS);
163+
} catch (InterruptedException e) {
164+
fail();
165+
}
166+
167+
verify(logger).warn("Unable to delete old datafile");
168+
verify(logger).warn("Unable to save new datafile");
169+
verify(dataFileLoadedListener, atMost(1)).onDataFileLoaded("{}");
170+
}
171+
172+
}

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@
2121
import android.os.IBinder;
2222
import android.support.annotation.RequiresApi;
2323
import android.support.test.InstrumentationRegistry;
24+
import android.support.test.espresso.core.deps.guava.util.concurrent.MoreExecutors;
2425
import android.support.test.rule.ServiceTestRule;
2526

27+
import com.optimizely.ab.android.shared.Cache;
28+
import com.optimizely.ab.android.shared.Client;
29+
2630
import org.junit.Ignore;
2731
import org.junit.Rule;
2832
import org.junit.Test;
@@ -33,6 +37,7 @@
3337
import static junit.framework.Assert.assertTrue;
3438
import static org.mockito.Mockito.mock;
3539
import static org.mockito.Mockito.verify;
40+
import static org.mockito.Mockito.when;
3641

3742
/**
3843
* Test for {@link DataFileService}
@@ -51,9 +56,16 @@ public void testBinding() throws TimeoutException {
5156
Context context = InstrumentationRegistry.getTargetContext();
5257
Intent intent = new Intent(context, DataFileService.class);
5358
IBinder binder = mServiceRule.bindService(intent);
54-
DataFileService dataFileService = ((DataFileService.LocalBinder) binder).getService();
55-
DataFileLoader dataFileLoader = new DataFileLoader(new DataFileLoader.TaskChain(dataFileService), mock(Logger.class));
59+
final Context targetContext = InstrumentationRegistry.getTargetContext();
60+
Logger logger = mock(Logger.class);
61+
DataFileCache dataFileCache = new DataFileCache("1", new Cache(targetContext, logger), logger);
62+
Client client = mock(Client.class);
63+
DataFileClient dataFileClient = new DataFileClient(client, logger);
5664
DataFileLoadedListener dataFileLoadedListener = mock(DataFileLoadedListener.class);
65+
66+
67+
DataFileService dataFileService = ((DataFileService.LocalBinder) binder).getService();
68+
DataFileLoader dataFileLoader = new DataFileLoader(dataFileService, dataFileClient, dataFileCache, MoreExecutors.newDirectExecutorService(), mock(Logger.class));
5769
dataFileService.getDataFile("1", dataFileLoader, dataFileLoadedListener);
5870

5971
assertTrue(dataFileService.isBound());

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,4 @@ public String execute() {
9393

9494
return client.execute(request, 2, 3);
9595
}
96-
97-
boolean isModifiedResponse(@Nullable String dataFile) {
98-
return dataFile != null && !dataFile.isEmpty();
99-
}
100-
101-
boolean isNotModifiedResponse(@Nullable String dataFile) {
102-
return dataFile == null || dataFile.isEmpty();
103-
}
10496
}

0 commit comments

Comments
 (0)