Skip to content

Commit 77b6d97

Browse files
authored
Adding Util class for FIrebaseInstallations APIs. (#676)
* Adding Firebase Installations module * Readding .idea files that were deleted in previous commit * Revert "Adding Firebase Installations module" This reverts commit 2ec4aef. * Revert "Readding .idea files that were deleted in previous commit" This reverts commit 7b4ebcf. * Adding Firebase Installations module. * Readding .idea files that were deleted in previous commit * Revert "Readding .idea files that were deleted in previous commit" This reverts commit 7b4ebcf. * Revert "Adding Firebase Installations module" with hidden files This reverts commit 2ec4aef. * Addressing review comments. * Http client to call FIS backend service. * Http client to call FIS backend service. * Http client to call FIS backend service. * Adding Firebase Installations module * Adding Firebase Installations module. * Readding .idea files that were deleted in previous commit * Readding .idea files that were deleted in previous commit * Revert "Adding Firebase Installations module" This reverts commit 2ec4aef. * Revert "Readding .idea files that were deleted in previous commit" This reverts commit 7b4ebcf. * Revert "Readding .idea files that were deleted in previous commit" This reverts commit 7b4ebcf. * Revert "Adding Firebase Installations module" with hidden files This reverts commit 2ec4aef. * Addressing review comments. * Http client to call FIS backend service. * Http client to call FIS backend service. * Initial Code structure for FIS Android SDK (#648) * Adding an interface library for Firebase Installations SDK * Adding Firebase Installations module * Adding Firebase Installations module. * Readding .idea files that were deleted in previous commit * Revert "Adding Firebase Installations module" This reverts commit 2ec4aef. * Revert "Readding .idea files that were deleted in previous commit" This reverts commit 7b4ebcf. * Add firebase installations project path * Adding Firebase Installations module. * Readding .idea files that were deleted in previous commit * Revert "Adding Firebase Installations module" This reverts commit 2ec4aef. * Revert "Readding .idea files that were deleted in previous commit" This reverts commit 7b4ebcf. * Add firebase installations project path * Fixing formattinf issues. * Revert "Adding Firebase Installations module" with hidden files This reverts commit 2ec4aef. * Addressing review comments. * Making InstallationTokenResult an AutoValue class. * Http client to call FIS backend service. * Addresing comments and introducing new FirebaseInstallationService Exception. * Implementing getId method in FirebaseInstallation to call backend. * 1. Adding instrumentation tests. 2. Introducing serviceClient level and main class exceptions. * Addressing Di's comments. * Addressing Rayo's comments * Updating parameters order in ServiceClient. * Updating createRandomFid as per Rayo's comments. * getId() implementation with instrumented tests. (#703) * getId() implementation with instrumented tests. * Addressing rayo's comments. - Detailed JavaDocs - Renaming FiidCache as PersistedFid * Addressing rayo's comments. - Detailed JavaDocs - Renaming FiidCache as PersistedFid * Addresing comments to resoleve the following: - Make registerAnsSaveFid non blocking call in getId() - PersistedFidEntry builder with default values * Addressing Ciaran and Rayo's comments. * Addressing Ciaran's comments * Addressing Ciaran's comments * Adding param comments and checking if registration status is valid. * Correcting lint warning: uses-permission should be declared before application in AndroidManifest.xml * Adding custom assertThat with more readable assertions * Correcting instrumented tests to be reliable.
1 parent c1f7dbe commit 77b6d97

File tree

18 files changed

+989
-249
lines changed

18 files changed

+989
-249
lines changed

firebase-installations-interop/src/main/java/com/google/firebase/installations/InstallationTokenResult.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@
2121
@AutoValue
2222
public abstract class InstallationTokenResult {
2323

24-
/** A new FIS Auth-Token, created for this firebase installation. */
24+
/** A new FIS Auth-Token, created for this Firebase Installation. */
2525
@NonNull
26-
public abstract String getAuthToken();
26+
public abstract String getToken();
2727
/**
28-
* The amount of time, in milliseconds, before the auth-token expires for this firebase
29-
* installation.
28+
* The amount of time, in milliseconds, before the auth-token expires for this Firebase
29+
* Installation.
3030
*/
3131
@NonNull
3232
public abstract long getTokenExpirationTimestampMillis();
@@ -43,7 +43,7 @@ public static InstallationTokenResult.Builder builder() {
4343
@AutoValue.Builder
4444
public abstract static class Builder {
4545
@NonNull
46-
public abstract Builder setAuthToken(@NonNull String value);
46+
public abstract Builder setToken(@NonNull String value);
4747

4848
@NonNull
4949
public abstract Builder setTokenExpirationTimestampMillis(@NonNull long value);

firebase-installations/firebase-installations.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,6 @@ dependencies {
5858
androidTestImplementation "com.google.truth:truth:$googleTruthVersion"
5959
androidTestImplementation 'junit:junit:4.12'
6060
androidTestImplementation "androidx.annotation:annotation:1.0.0"
61+
androidTestImplementation 'org.mockito:mockito-core:2.25.0'
62+
androidTestImplementation 'org.mockito:mockito-android:2.25.0'
6163
}

firebase-installations/src/androidTest/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<!-- limitations under the License. -->
1515

1616
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
17-
package="com.google.firebase.installation">
17+
package="com.google.firebase.installations">
1818

1919
<application>
2020
<uses-library android:name="android.test.runner"/>

firebase-installations/src/androidTest/java/com/google/firebase/installation/local/FiidCacheTest.java

Lines changed: 0 additions & 110 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
// Copyright 2019 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.installations;
16+
17+
import static com.google.common.truth.Truth.assertWithMessage;
18+
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_APP_ID_1;
19+
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_AUTH_TOKEN;
20+
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_CREATION_TIMESTAMP_1;
21+
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_FID_1;
22+
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_PROJECT_ID;
23+
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_REFRESH_TOKEN;
24+
import static com.google.firebase.installations.FisAndroidTestConstants.TEST_TOKEN_EXPIRATION_TIMESTAMP;
25+
import static org.junit.Assert.fail;
26+
import static org.mockito.ArgumentMatchers.any;
27+
import static org.mockito.ArgumentMatchers.anyString;
28+
import static org.mockito.Mockito.when;
29+
30+
import androidx.test.core.app.ApplicationProvider;
31+
import androidx.test.runner.AndroidJUnit4;
32+
import com.google.android.gms.common.util.Clock;
33+
import com.google.android.gms.tasks.Tasks;
34+
import com.google.firebase.FirebaseApp;
35+
import com.google.firebase.FirebaseOptions;
36+
import com.google.firebase.installations.local.PersistedFid;
37+
import com.google.firebase.installations.local.PersistedFidEntry;
38+
import com.google.firebase.installations.remote.FirebaseInstallationServiceClient;
39+
import com.google.firebase.installations.remote.FirebaseInstallationServiceException;
40+
import com.google.firebase.installations.remote.InstallationResponse;
41+
import java.util.concurrent.ExecutionException;
42+
import java.util.concurrent.ExecutorService;
43+
import java.util.concurrent.SynchronousQueue;
44+
import java.util.concurrent.ThreadPoolExecutor;
45+
import java.util.concurrent.TimeUnit;
46+
import org.junit.After;
47+
import org.junit.Before;
48+
import org.junit.FixMethodOrder;
49+
import org.junit.Test;
50+
import org.junit.runner.RunWith;
51+
import org.junit.runners.MethodSorters;
52+
import org.mockito.Mock;
53+
import org.mockito.MockitoAnnotations;
54+
55+
/**
56+
* Instrumented test, which will execute on an Android device.
57+
*
58+
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
59+
*/
60+
@RunWith(AndroidJUnit4.class)
61+
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
62+
public class FirebaseInstallationsInstrumentedTest {
63+
private FirebaseApp firebaseApp;
64+
private ExecutorService executor;
65+
private PersistedFid persistedFid;
66+
@Mock private FirebaseInstallationServiceClient backendClientReturnsOk;
67+
@Mock private FirebaseInstallationServiceClient backendClientReturnsError;
68+
@Mock private PersistedFid persistedFidReturnsError;
69+
@Mock private Utils mockUtils;
70+
@Mock private Clock mockClock;
71+
72+
@Before
73+
public void setUp() throws FirebaseInstallationServiceException {
74+
MockitoAnnotations.initMocks(this);
75+
FirebaseApp.clearInstancesForTest();
76+
executor = new ThreadPoolExecutor(0, 2, 10L, TimeUnit.SECONDS, new SynchronousQueue<>());
77+
firebaseApp =
78+
FirebaseApp.initializeApp(
79+
ApplicationProvider.getApplicationContext(),
80+
new FirebaseOptions.Builder()
81+
.setApplicationId(TEST_APP_ID_1)
82+
.setProjectId(TEST_PROJECT_ID)
83+
.setApiKey("api_key")
84+
.build());
85+
persistedFid = new PersistedFid(firebaseApp);
86+
when(backendClientReturnsOk.createFirebaseInstallation(
87+
anyString(), anyString(), anyString(), anyString()))
88+
.thenReturn(
89+
InstallationResponse.builder()
90+
.setName("/projects/" + TEST_PROJECT_ID + "/installations/" + TEST_FID_1)
91+
.setRefreshToken(TEST_REFRESH_TOKEN)
92+
.setAuthToken(
93+
InstallationTokenResult.builder()
94+
.setToken(TEST_AUTH_TOKEN)
95+
.setTokenExpirationTimestampMillis(TEST_TOKEN_EXPIRATION_TIMESTAMP)
96+
.build())
97+
.build());
98+
when(backendClientReturnsError.createFirebaseInstallation(
99+
anyString(), anyString(), anyString(), anyString()))
100+
.thenThrow(
101+
new FirebaseInstallationServiceException(
102+
"SDK Error", FirebaseInstallationServiceException.Status.SERVER_ERROR));
103+
when(persistedFidReturnsError.insertOrUpdatePersistedFidEntry(any())).thenReturn(false);
104+
when(persistedFidReturnsError.readPersistedFidEntryValue()).thenReturn(null);
105+
when(mockUtils.createRandomFid()).thenReturn(TEST_FID_1);
106+
when(mockClock.currentTimeMillis()).thenReturn(TEST_CREATION_TIMESTAMP_1);
107+
}
108+
109+
@After
110+
public void cleanUp() throws Exception {
111+
persistedFid.clear();
112+
}
113+
114+
@Test
115+
public void testGetId_PersistedFidOk_BackendOk() throws Exception {
116+
FirebaseInstallations firebaseInstallations =
117+
new FirebaseInstallations(
118+
mockClock, executor, firebaseApp, backendClientReturnsOk, persistedFid, mockUtils);
119+
120+
// No exception, means success.
121+
assertWithMessage("getId Task fails.")
122+
.that(Tasks.await(firebaseInstallations.getId()))
123+
.isNotEmpty();
124+
PersistedFidEntry entryValue = persistedFid.readPersistedFidEntryValue();
125+
assertWithMessage("Persisted Fid doesn't match")
126+
.that(entryValue.getFirebaseInstallationId())
127+
.isEqualTo(TEST_FID_1);
128+
129+
// Waiting for Task that registers FID on the FIS Servers
130+
executor.awaitTermination(500, TimeUnit.MILLISECONDS);
131+
132+
PersistedFidEntry updatedFidEntry = persistedFid.readPersistedFidEntryValue();
133+
assertWithMessage("Persisted Fid doesn't match")
134+
.that(updatedFidEntry.getFirebaseInstallationId())
135+
.isEqualTo(TEST_FID_1);
136+
assertWithMessage("Registration status doesn't match")
137+
.that(updatedFidEntry.getRegistrationStatus())
138+
.isEqualTo(PersistedFid.RegistrationStatus.REGISTERED);
139+
}
140+
141+
@Test
142+
public void testGetId_multipleCalls_sameFIDReturned() throws Exception {
143+
FirebaseInstallations firebaseInstallations =
144+
new FirebaseInstallations(
145+
mockClock, executor, firebaseApp, backendClientReturnsOk, persistedFid, mockUtils);
146+
147+
// No exception, means success.
148+
assertWithMessage("getId Task fails.")
149+
.that(Tasks.await(firebaseInstallations.getId()))
150+
.isNotEmpty();
151+
PersistedFidEntry entryValue = persistedFid.readPersistedFidEntryValue();
152+
assertWithMessage("Persisted Fid doesn't match")
153+
.that(entryValue.getFirebaseInstallationId())
154+
.isEqualTo(TEST_FID_1);
155+
156+
Tasks.await(firebaseInstallations.getId());
157+
158+
// Waiting for Task that registers FID on the FIS Servers
159+
executor.awaitTermination(500, TimeUnit.MILLISECONDS);
160+
161+
PersistedFidEntry updatedFidEntry = persistedFid.readPersistedFidEntryValue();
162+
assertWithMessage("Persisted Fid doesn't match")
163+
.that(updatedFidEntry.getFirebaseInstallationId())
164+
.isEqualTo(TEST_FID_1);
165+
assertWithMessage("Registration status doesn't match")
166+
.that(updatedFidEntry.getRegistrationStatus())
167+
.isEqualTo(PersistedFid.RegistrationStatus.REGISTERED);
168+
}
169+
170+
@Test
171+
public void testGetId_PersistedFidOk_BackendError() throws Exception {
172+
FirebaseInstallations firebaseInstallations =
173+
new FirebaseInstallations(
174+
mockClock, executor, firebaseApp, backendClientReturnsError, persistedFid, mockUtils);
175+
176+
Tasks.await(firebaseInstallations.getId());
177+
178+
PersistedFidEntry entryValue = persistedFid.readPersistedFidEntryValue();
179+
assertWithMessage("Persisted Fid doesn't match")
180+
.that(entryValue.getFirebaseInstallationId())
181+
.isEqualTo(TEST_FID_1);
182+
183+
// Waiting for Task that registers FID on the FIS Servers
184+
executor.awaitTermination(500, TimeUnit.MILLISECONDS);
185+
186+
PersistedFidEntry updatedFidEntry = persistedFid.readPersistedFidEntryValue();
187+
assertWithMessage("Persisted Fid doesn't match")
188+
.that(updatedFidEntry.getFirebaseInstallationId())
189+
.isEqualTo(TEST_FID_1);
190+
assertWithMessage("Registration Fid doesn't match")
191+
.that(updatedFidEntry.getRegistrationStatus())
192+
.isEqualTo(PersistedFid.RegistrationStatus.REGISTER_ERROR);
193+
}
194+
195+
@Test
196+
public void testGetId_PersistedFidError_BackendOk() throws InterruptedException {
197+
FirebaseInstallations firebaseInstallations =
198+
new FirebaseInstallations(
199+
mockClock,
200+
executor,
201+
firebaseApp,
202+
backendClientReturnsOk,
203+
persistedFidReturnsError,
204+
mockUtils);
205+
206+
// Expect exception
207+
try {
208+
Tasks.await(firebaseInstallations.getId());
209+
fail();
210+
} catch (ExecutionException expected) {
211+
Throwable cause = expected.getCause();
212+
assertWithMessage("Exception class doesn't match")
213+
.that(cause)
214+
.isInstanceOf(FirebaseInstallationsException.class);
215+
assertWithMessage("Exception status doesn't match")
216+
.that(((FirebaseInstallationsException) cause).getStatus())
217+
.isEqualTo(FirebaseInstallationsException.Status.CLIENT_ERROR);
218+
}
219+
}
220+
}

0 commit comments

Comments
 (0)