Skip to content

Commit b381889

Browse files
committed
Add the state machine of updating custom installation id in the local
cache and update to Firebase Segmentation backend. CL also contains unit tests. (The http client is not implemented yet.)
1 parent bb8bf45 commit b381889

File tree

10 files changed

+588
-80
lines changed

10 files changed

+588
-80
lines changed

firebase-segmentation/firebase-segmentation.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,18 @@ android {
8383

8484
dependencies {
8585
implementation project(':firebase-common')
86+
implementation project(':protolite-well-known-types')
8687

8788
implementation('com.google.firebase:firebase-iid:17.0.3') {
8889
exclude group: "com.google.firebase", module: "firebase-common"
8990
}
91+
implementation 'io.grpc:grpc-stub:1.21.0'
92+
implementation 'io.grpc:grpc-protobuf-lite:1.21.0'
93+
implementation 'io.grpc:grpc-okhttp:1.21.0'
9094
implementation 'androidx.appcompat:appcompat:1.0.2'
9195
implementation 'androidx.multidex:multidex:2.0.0'
9296
implementation 'com.google.android.gms:play-services-tasks:16.0.1'
97+
implementation 'com.squareup.okhttp:okhttp:2.7.5'
9398

9499
compileOnly "com.google.auto.value:auto-value-annotations:1.6.5"
95100
annotationProcessor "com.google.auto.value:auto-value:1.6.2"
@@ -104,4 +109,6 @@ dependencies {
104109
androidTestImplementation 'androidx.test:runner:1.2.0'
105110
androidTestImplementation "com.google.truth:truth:$googleTruthVersion"
106111
androidTestImplementation 'junit:junit:4.12'
112+
androidTestImplementation 'org.mockito:mockito-core:2.25.0'
113+
androidTestImplementation 'org.mockito:mockito-android:2.25.0'
107114
}

firebase-segmentation/src/androidTest/java/com/google/firebase/segmentation/FirebaseSegmentationInstrumentedTest.java

Lines changed: 186 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,37 +14,220 @@
1414

1515
package com.google.firebase.segmentation;
1616

17+
import static com.google.common.truth.Truth.assertThat;
1718
import static org.junit.Assert.assertNull;
19+
import static org.junit.Assert.fail;
20+
import static org.mockito.ArgumentMatchers.anyLong;
21+
import static org.mockito.ArgumentMatchers.anyString;
22+
import static org.mockito.Mockito.any;
23+
import static org.mockito.Mockito.when;
1824

25+
import androidx.annotation.NonNull;
1926
import androidx.test.core.app.ApplicationProvider;
2027
import androidx.test.ext.junit.runners.AndroidJUnit4;
28+
import com.google.android.gms.tasks.Tasks;
2129
import com.google.firebase.FirebaseApp;
2230
import com.google.firebase.FirebaseOptions;
31+
import com.google.firebase.iid.FirebaseInstanceId;
32+
import com.google.firebase.iid.InstanceIdResult;
33+
import com.google.firebase.segmentation.local.CustomInstallationIdCache;
34+
import com.google.firebase.segmentation.local.CustomInstallationIdCacheEntryValue;
35+
import com.google.firebase.segmentation.remote.SegmentationServiceClient;
36+
import java.util.concurrent.ExecutionException;
37+
import org.junit.After;
2338
import org.junit.Before;
39+
import org.junit.FixMethodOrder;
2440
import org.junit.Test;
2541
import org.junit.runner.RunWith;
42+
import org.junit.runners.MethodSorters;
43+
import org.mockito.Mock;
44+
import org.mockito.MockitoAnnotations;
2645

2746
/**
2847
* Instrumented test, which will execute on an Android device.
2948
*
3049
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
3150
*/
3251
@RunWith(AndroidJUnit4.class)
52+
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
3353
public class FirebaseSegmentationInstrumentedTest {
3454

55+
private static final String CUSTOM_INSTALLATION_ID = "123";
56+
private static final String FIREBASE_INSTANCE_ID = "cAAAAAAAAAA";
57+
3558
private FirebaseApp firebaseApp;
59+
@Mock private FirebaseInstanceId firebaseInstanceId;
60+
@Mock private SegmentationServiceClient backendClientReturnsOk;
61+
@Mock private SegmentationServiceClient backendClientReturnsError;
62+
private CustomInstallationIdCache actualCache;
63+
@Mock private CustomInstallationIdCache cacheReturnsError;
3664

3765
@Before
3866
public void setUp() {
67+
MockitoAnnotations.initMocks(this);
3968
FirebaseApp.clearInstancesForTest();
4069
firebaseApp =
4170
FirebaseApp.initializeApp(
4271
ApplicationProvider.getApplicationContext(),
43-
new FirebaseOptions.Builder().setApplicationId("1:123456789:android:abcdef").build());
72+
new FirebaseOptions.Builder()
73+
.setApplicationId("1" + ":123456789:android:abcdef")
74+
.build());
75+
actualCache = new CustomInstallationIdCache(firebaseApp);
76+
77+
when(backendClientReturnsOk.updateCustomInstallationId(
78+
anyLong(), anyString(), anyString(), anyString()))
79+
.thenReturn(Tasks.forResult(SegmentationServiceClient.Code.OK));
80+
when(backendClientReturnsOk.clearCustomInstallationId(anyLong(), anyString(), anyString()))
81+
.thenReturn(Tasks.forResult(SegmentationServiceClient.Code.OK));
82+
when(backendClientReturnsError.updateCustomInstallationId(
83+
anyLong(), anyString(), anyString(), anyString()))
84+
.thenReturn(Tasks.forResult(SegmentationServiceClient.Code.SERVER_INTERNAL_ERROR));
85+
when(backendClientReturnsError.clearCustomInstallationId(anyLong(), anyString(), anyString()))
86+
.thenReturn(Tasks.forResult(SegmentationServiceClient.Code.SERVER_INTERNAL_ERROR));
87+
when(firebaseInstanceId.getInstanceId())
88+
.thenReturn(
89+
Tasks.forResult(
90+
new InstanceIdResult() {
91+
@NonNull
92+
@Override
93+
public String getId() {
94+
return FIREBASE_INSTANCE_ID;
95+
}
96+
97+
@NonNull
98+
@Override
99+
public String getToken() {
100+
return "iid_token";
101+
}
102+
}));
103+
when(cacheReturnsError.insertOrUpdateCacheEntry(any())).thenReturn(Tasks.forResult(false));
104+
when(cacheReturnsError.readCacheEntryValue()).thenReturn(null);
105+
}
106+
107+
@After
108+
public void cleanUp() throws Exception {
109+
Tasks.await(actualCache.clear());
110+
}
111+
112+
@Test
113+
public void testUpdateCustomInstallationId_CacheOk_BackendOk() throws Exception {
114+
FirebaseSegmentation firebaseSegmentation =
115+
new FirebaseSegmentation(
116+
firebaseApp, firebaseInstanceId, actualCache, backendClientReturnsOk);
117+
118+
// No exception, means success.
119+
assertNull(Tasks.await(firebaseSegmentation.setCustomInstallationId(CUSTOM_INSTALLATION_ID)));
120+
CustomInstallationIdCacheEntryValue entryValue = actualCache.readCacheEntryValue();
121+
assertThat(entryValue.getCustomInstallationId()).isEqualTo(CUSTOM_INSTALLATION_ID);
122+
assertThat(entryValue.getFirebaseInstanceId()).isEqualTo(FIREBASE_INSTANCE_ID);
123+
assertThat(entryValue.getCacheStatus()).isEqualTo(CustomInstallationIdCache.CacheStatus.SYNCED);
124+
}
125+
126+
@Test
127+
public void testUpdateCustomInstallationId_CacheOk_BackendError() throws InterruptedException {
128+
FirebaseSegmentation firebaseSegmentation =
129+
new FirebaseSegmentation(
130+
firebaseApp, firebaseInstanceId, actualCache, backendClientReturnsError);
131+
132+
// Expect exception
133+
try {
134+
Tasks.await(firebaseSegmentation.setCustomInstallationId(CUSTOM_INSTALLATION_ID));
135+
fail();
136+
} catch (ExecutionException expected) {
137+
Throwable cause = expected.getCause();
138+
assertThat(cause).isInstanceOf(SetCustomInstallationIdException.class);
139+
assertThat(((SetCustomInstallationIdException) cause).getStatus())
140+
.isEqualTo(SetCustomInstallationIdException.Status.BACKEND_ERROR);
141+
}
142+
143+
CustomInstallationIdCacheEntryValue entryValue = actualCache.readCacheEntryValue();
144+
assertThat(entryValue.getCustomInstallationId()).isEqualTo(CUSTOM_INSTALLATION_ID);
145+
assertThat(entryValue.getFirebaseInstanceId()).isEqualTo(FIREBASE_INSTANCE_ID);
146+
assertThat(entryValue.getCacheStatus())
147+
.isEqualTo(CustomInstallationIdCache.CacheStatus.PENDING_UPDATE);
44148
}
45149

46150
@Test
47-
public void useAppContext() {
48-
assertNull(FirebaseSegmentation.getInstance().setCustomInstallationId("123123").getResult());
151+
public void testUpdateCustomInstallationId_CacheError_BackendOk() throws InterruptedException {
152+
FirebaseSegmentation firebaseSegmentation =
153+
new FirebaseSegmentation(
154+
firebaseApp, firebaseInstanceId, cacheReturnsError, backendClientReturnsOk);
155+
156+
// Expect exception
157+
try {
158+
Tasks.await(firebaseSegmentation.setCustomInstallationId(CUSTOM_INSTALLATION_ID));
159+
fail();
160+
} catch (ExecutionException expected) {
161+
Throwable cause = expected.getCause();
162+
assertThat(cause).isInstanceOf(SetCustomInstallationIdException.class);
163+
assertThat(((SetCustomInstallationIdException) cause).getStatus())
164+
.isEqualTo(SetCustomInstallationIdException.Status.CLIENT_ERROR);
165+
}
166+
}
167+
168+
@Test
169+
public void testClearCustomInstallationId_CacheOk_BackendOk() throws Exception {
170+
Tasks.await(
171+
actualCache.insertOrUpdateCacheEntry(
172+
CustomInstallationIdCacheEntryValue.create(
173+
CUSTOM_INSTALLATION_ID,
174+
FIREBASE_INSTANCE_ID,
175+
CustomInstallationIdCache.CacheStatus.SYNCED)));
176+
FirebaseSegmentation firebaseSegmentation =
177+
new FirebaseSegmentation(
178+
firebaseApp, firebaseInstanceId, actualCache, backendClientReturnsOk);
179+
180+
// No exception, means success.
181+
assertNull(Tasks.await(firebaseSegmentation.setCustomInstallationId(null)));
182+
CustomInstallationIdCacheEntryValue entryValue = actualCache.readCacheEntryValue();
183+
assertNull(entryValue);
184+
}
185+
186+
@Test
187+
public void testClearCustomInstallationId_CacheOk_BackendError() throws Exception {
188+
Tasks.await(
189+
actualCache.insertOrUpdateCacheEntry(
190+
CustomInstallationIdCacheEntryValue.create(
191+
CUSTOM_INSTALLATION_ID,
192+
FIREBASE_INSTANCE_ID,
193+
CustomInstallationIdCache.CacheStatus.SYNCED)));
194+
FirebaseSegmentation firebaseSegmentation =
195+
new FirebaseSegmentation(
196+
firebaseApp, firebaseInstanceId, actualCache, backendClientReturnsError);
197+
198+
// Expect exception
199+
try {
200+
Tasks.await(firebaseSegmentation.setCustomInstallationId(null));
201+
fail();
202+
} catch (ExecutionException expected) {
203+
Throwable cause = expected.getCause();
204+
assertThat(cause).isInstanceOf(SetCustomInstallationIdException.class);
205+
assertThat(((SetCustomInstallationIdException) cause).getStatus())
206+
.isEqualTo(SetCustomInstallationIdException.Status.BACKEND_ERROR);
207+
}
208+
209+
CustomInstallationIdCacheEntryValue entryValue = actualCache.readCacheEntryValue();
210+
assertThat(entryValue.getCustomInstallationId().isEmpty()).isTrue();
211+
assertThat(entryValue.getFirebaseInstanceId()).isEqualTo(FIREBASE_INSTANCE_ID);
212+
assertThat(entryValue.getCacheStatus())
213+
.isEqualTo(CustomInstallationIdCache.CacheStatus.PENDING_CLEAR);
214+
}
215+
216+
@Test
217+
public void testClearCustomInstallationId_CacheError_BackendOk() throws InterruptedException {
218+
FirebaseSegmentation firebaseSegmentation =
219+
new FirebaseSegmentation(
220+
firebaseApp, firebaseInstanceId, cacheReturnsError, backendClientReturnsOk);
221+
222+
// Expect exception
223+
try {
224+
Tasks.await(firebaseSegmentation.setCustomInstallationId(CUSTOM_INSTALLATION_ID));
225+
fail();
226+
} catch (ExecutionException expected) {
227+
Throwable cause = expected.getCause();
228+
assertThat(cause).isInstanceOf(SetCustomInstallationIdException.class);
229+
assertThat(((SetCustomInstallationIdException) cause).getStatus())
230+
.isEqualTo(SetCustomInstallationIdException.Status.CLIENT_ERROR);
231+
}
49232
}
50233
}

firebase-segmentation/src/androidTest/java/com/google/firebase/segmentation/local/CustomInstallationIdCacheTest.java

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ public class CustomInstallationIdCacheTest {
3434

3535
private FirebaseApp firebaseApp0;
3636
private FirebaseApp firebaseApp1;
37-
private CustomInstallationIdCache cache;
37+
private CustomInstallationIdCache cache0;
38+
private CustomInstallationIdCache cache1;
3839

3940
@Before
4041
public void setUp() {
@@ -48,42 +49,44 @@ public void setUp() {
4849
ApplicationProvider.getApplicationContext(),
4950
new FirebaseOptions.Builder().setApplicationId("1:987654321:android:abcdef").build(),
5051
"firebase_app_1");
51-
cache = CustomInstallationIdCache.getInstance();
52+
cache0 = new CustomInstallationIdCache(firebaseApp0);
53+
cache1 = new CustomInstallationIdCache(firebaseApp1);
5254
}
5355

5456
@After
5557
public void cleanUp() throws Exception {
56-
Tasks.await(cache.clearAll());
58+
Tasks.await(cache0.clear());
59+
Tasks.await(cache1.clear());
5760
}
5861

5962
@Test
6063
public void testReadCacheEntry_Null() {
61-
assertNull(cache.readCacheEntryValue(firebaseApp0));
62-
assertNull(cache.readCacheEntryValue(firebaseApp1));
64+
assertNull(cache0.readCacheEntryValue());
65+
assertNull(cache1.readCacheEntryValue());
6366
}
6467

6568
@Test
6669
public void testUpdateAndReadCacheEntry() throws Exception {
6770
assertTrue(
6871
Tasks.await(
69-
cache.insertOrUpdateCacheEntry(
70-
firebaseApp0,
72+
cache0.insertOrUpdateCacheEntry(
7173
CustomInstallationIdCacheEntryValue.create(
72-
"123456", "cAAAAAAAAAA", CustomInstallationIdCache.CacheStatus.PENDING))));
73-
CustomInstallationIdCacheEntryValue entryValue = cache.readCacheEntryValue(firebaseApp0);
74+
"123456",
75+
"cAAAAAAAAAA",
76+
CustomInstallationIdCache.CacheStatus.PENDING_UPDATE))));
77+
CustomInstallationIdCacheEntryValue entryValue = cache0.readCacheEntryValue();
7478
assertThat(entryValue.getCustomInstallationId()).isEqualTo("123456");
7579
assertThat(entryValue.getFirebaseInstanceId()).isEqualTo("cAAAAAAAAAA");
7680
assertThat(entryValue.getCacheStatus())
77-
.isEqualTo(CustomInstallationIdCache.CacheStatus.PENDING);
78-
assertNull(cache.readCacheEntryValue(firebaseApp1));
81+
.isEqualTo(CustomInstallationIdCache.CacheStatus.PENDING_UPDATE);
82+
assertNull(cache1.readCacheEntryValue());
7983

8084
assertTrue(
8185
Tasks.await(
82-
cache.insertOrUpdateCacheEntry(
83-
firebaseApp0,
86+
cache0.insertOrUpdateCacheEntry(
8487
CustomInstallationIdCacheEntryValue.create(
8588
"123456", "cAAAAAAAAAA", CustomInstallationIdCache.CacheStatus.SYNCED))));
86-
entryValue = cache.readCacheEntryValue(firebaseApp0);
89+
entryValue = cache0.readCacheEntryValue();
8790
assertThat(entryValue.getCustomInstallationId()).isEqualTo("123456");
8891
assertThat(entryValue.getFirebaseInstanceId()).isEqualTo("cAAAAAAAAAA");
8992
assertThat(entryValue.getCacheStatus()).isEqualTo(CustomInstallationIdCache.CacheStatus.SYNCED);

0 commit comments

Comments
 (0)