Skip to content

Commit db5b277

Browse files
committed
Add unit tests.
1 parent 5fc39cd commit db5b277

File tree

4 files changed

+238
-8
lines changed

4 files changed

+238
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2022 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.appcheck.playintegrity.internal;
16+
17+
import static com.google.common.truth.Truth.assertThat;
18+
19+
import org.junit.Test;
20+
import org.junit.runner.RunWith;
21+
import org.robolectric.RobolectricTestRunner;
22+
import org.robolectric.annotation.Config;
23+
24+
/** Tests for {@link GeneratePlayIntegrityChallengeRequest}. */
25+
@RunWith(RobolectricTestRunner.class)
26+
@Config(manifest = Config.NONE)
27+
public class GeneratePlayIntegrityChallengeRequestTest {
28+
private static final String EMPTY_JSON = "{}";
29+
30+
@Test
31+
public void toJsonString_expectSerialized() throws Exception {
32+
GeneratePlayIntegrityChallengeRequest generatePlayIntegrityChallengeRequest =
33+
new GeneratePlayIntegrityChallengeRequest();
34+
35+
assertThat(generatePlayIntegrityChallengeRequest.toJsonString()).isEqualTo(EMPTY_JSON);
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright 2022 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.appcheck.playintegrity.internal;
16+
17+
import static com.google.common.truth.Truth.assertThat;
18+
import static org.junit.Assert.assertThrows;
19+
20+
import org.json.JSONObject;
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
import org.robolectric.RobolectricTestRunner;
24+
import org.robolectric.annotation.Config;
25+
26+
/** Tests for {@link GeneratePlayIntegrityChallengeResponse}. */
27+
@RunWith(RobolectricTestRunner.class)
28+
@Config(manifest = Config.NONE)
29+
public class GeneratePlayIntegrityChallengeResponseTest {
30+
private static final String CHALLENGE = "testChallenge";
31+
private static final String TIME_TO_LIVE = "3600s";
32+
33+
@Test
34+
public void fromJsonString_expectDeserialized() throws Exception {
35+
JSONObject jsonObject = new JSONObject();
36+
jsonObject.put(GeneratePlayIntegrityChallengeResponse.CHALLENGE_KEY, CHALLENGE);
37+
jsonObject.put(GeneratePlayIntegrityChallengeResponse.TIME_TO_LIVE_KEY, TIME_TO_LIVE);
38+
39+
GeneratePlayIntegrityChallengeResponse generatePlayIntegrityChallengeResponse =
40+
GeneratePlayIntegrityChallengeResponse.fromJsonString(jsonObject.toString());
41+
assertThat(generatePlayIntegrityChallengeResponse.getChallenge()).isEqualTo(CHALLENGE);
42+
assertThat(generatePlayIntegrityChallengeResponse.getTimeToLive()).isEqualTo(TIME_TO_LIVE);
43+
}
44+
45+
@Test
46+
public void fromJsonString_nullChallenge_throwsException() throws Exception {
47+
JSONObject jsonObject = new JSONObject();
48+
jsonObject.put(GeneratePlayIntegrityChallengeResponse.TIME_TO_LIVE_KEY, TIME_TO_LIVE);
49+
50+
assertThrows(
51+
NullPointerException.class,
52+
() -> GeneratePlayIntegrityChallengeResponse.fromJsonString(jsonObject.toString()));
53+
}
54+
55+
@Test
56+
public void fromJsonString_nullTimeToLive_throwsException() throws Exception {
57+
JSONObject jsonObject = new JSONObject();
58+
jsonObject.put(GeneratePlayIntegrityChallengeResponse.CHALLENGE_KEY, CHALLENGE);
59+
60+
assertThrows(
61+
NullPointerException.class,
62+
() -> GeneratePlayIntegrityChallengeResponse.fromJsonString(jsonObject.toString()));
63+
}
64+
}

appcheck/firebase-appcheck-playintegrity/src/test/java/com/google/firebase/appcheck/playintegrity/internal/PlayIntegrityAppCheckProviderTest.java

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
import static com.google.common.truth.Truth.assertThat;
1818
import static org.junit.Assert.assertThrows;
1919
import static org.mockito.ArgumentMatchers.any;
20+
import static org.mockito.ArgumentMatchers.anyInt;
2021
import static org.mockito.ArgumentMatchers.eq;
22+
import static org.mockito.Mockito.never;
2123
import static org.mockito.Mockito.verify;
2224
import static org.mockito.Mockito.when;
2325

@@ -34,6 +36,8 @@
3436
import com.google.firebase.appcheck.internal.RetryManager;
3537
import java.io.IOException;
3638
import java.util.concurrent.ExecutorService;
39+
import java.util.concurrent.TimeoutException;
40+
import org.json.JSONObject;
3741
import org.junit.Before;
3842
import org.junit.Test;
3943
import org.junit.runner.RunWith;
@@ -53,8 +57,6 @@ public class PlayIntegrityAppCheckProviderTest {
5357
private static final String ATTESTATION_TOKEN = "token";
5458
private static final String TIME_TO_LIVE = "3600s";
5559
private static final String CHALLENGE = "testChallenge";
56-
private static final String CHALLENGE_JSON_RESPONSE =
57-
"{\"challenge\":\"" + CHALLENGE + "\",\"ttl\":\"3600s\"}";
5860
private static final String INTEGRITY_TOKEN = "integrityToken";
5961

6062
@Mock private IntegrityManager mockIntegrityManager;
@@ -88,7 +90,7 @@ public void testPublicConstructor_nullFirebaseApp_expectThrows() {
8890
@Test
8991
public void getToken_onSuccess_setsTaskResult() throws Exception {
9092
when(mockNetworkClient.generatePlayIntegrityChallenge(any(), eq(mockRetryManager)))
91-
.thenReturn(CHALLENGE_JSON_RESPONSE);
93+
.thenReturn(createGeneratePlayIntegrityChallengeResponse());
9294
when(mockIntegrityManager.requestIntegrityToken(any()))
9395
.thenReturn(Tasks.forResult(mockIntegrityTokenResponse));
9496
when(mockNetworkClient.exchangeAttestationForAppCheckToken(
@@ -108,6 +110,8 @@ public void getToken_onSuccess_setsTaskResult() throws Exception {
108110
assertThat(token).isInstanceOf(DefaultAppCheckToken.class);
109111
assertThat(token.getToken()).isEqualTo(ATTESTATION_TOKEN);
110112

113+
verify(mockNetworkClient).generatePlayIntegrityChallenge(any(), eq(mockRetryManager));
114+
111115
verify(mockIntegrityManager).requestIntegrityToken(integrityTokenRequestCaptor.capture());
112116
assertThat(integrityTokenRequestCaptor.getValue().cloudProjectNumber())
113117
.isEqualTo(Long.parseLong(PROJECT_NUMBER));
@@ -124,9 +128,59 @@ public void getToken_onSuccess_setsTaskResult() throws Exception {
124128
}
125129

126130
@Test
127-
public void getToken_tokenExchangeFailure_setsTaskException() throws Exception {
131+
public void getToken_generateChallengeFails_setsTaskException() throws Exception {
128132
when(mockNetworkClient.generatePlayIntegrityChallenge(any(), eq(mockRetryManager)))
129-
.thenReturn(CHALLENGE_JSON_RESPONSE);
133+
.thenThrow(new IOException());
134+
135+
PlayIntegrityAppCheckProvider provider =
136+
new PlayIntegrityAppCheckProvider(
137+
PROJECT_NUMBER,
138+
mockIntegrityManager,
139+
mockNetworkClient,
140+
backgroundExecutor,
141+
mockRetryManager);
142+
Task<AppCheckToken> task = provider.getToken();
143+
144+
assertThat(task.isSuccessful()).isFalse();
145+
assertThat(task.getException()).isInstanceOf(IOException.class);
146+
147+
verify(mockNetworkClient).generatePlayIntegrityChallenge(any(), eq(mockRetryManager));
148+
verify(mockNetworkClient, never()).exchangeAttestationForAppCheckToken(any(), anyInt(), any());
149+
verify(mockIntegrityManager, never()).requestIntegrityToken(any());
150+
}
151+
152+
@Test
153+
public void getToken_requestIntegrityTokenFails_setsTaskException() throws Exception {
154+
when(mockNetworkClient.generatePlayIntegrityChallenge(any(), eq(mockRetryManager)))
155+
.thenReturn(createGeneratePlayIntegrityChallengeResponse());
156+
when(mockIntegrityManager.requestIntegrityToken(any()))
157+
.thenReturn(Tasks.forException(new TimeoutException()));
158+
159+
PlayIntegrityAppCheckProvider provider =
160+
new PlayIntegrityAppCheckProvider(
161+
PROJECT_NUMBER,
162+
mockIntegrityManager,
163+
mockNetworkClient,
164+
backgroundExecutor,
165+
mockRetryManager);
166+
Task<AppCheckToken> task = provider.getToken();
167+
168+
assertThat(task.isSuccessful()).isFalse();
169+
assertThat(task.getException()).isInstanceOf(TimeoutException.class);
170+
171+
verify(mockNetworkClient).generatePlayIntegrityChallenge(any(), eq(mockRetryManager));
172+
verify(mockNetworkClient, never()).exchangeAttestationForAppCheckToken(any(), anyInt(), any());
173+
174+
verify(mockIntegrityManager).requestIntegrityToken(integrityTokenRequestCaptor.capture());
175+
assertThat(integrityTokenRequestCaptor.getValue().cloudProjectNumber())
176+
.isEqualTo(Long.parseLong(PROJECT_NUMBER));
177+
assertThat(integrityTokenRequestCaptor.getValue().nonce()).isEqualTo(CHALLENGE);
178+
}
179+
180+
@Test
181+
public void getToken_tokenExchangeFails_setsTaskException() throws Exception {
182+
when(mockNetworkClient.generatePlayIntegrityChallenge(any(), eq(mockRetryManager)))
183+
.thenReturn(createGeneratePlayIntegrityChallengeResponse());
130184
when(mockIntegrityManager.requestIntegrityToken(any()))
131185
.thenReturn(Tasks.forResult(mockIntegrityTokenResponse));
132186
when(mockNetworkClient.exchangeAttestationForAppCheckToken(
@@ -145,6 +199,8 @@ public void getToken_tokenExchangeFailure_setsTaskException() throws Exception {
145199
assertThat(task.isSuccessful()).isFalse();
146200
assertThat(task.getException()).isInstanceOf(IOException.class);
147201

202+
verify(mockNetworkClient).generatePlayIntegrityChallenge(any(), eq(mockRetryManager));
203+
148204
verify(mockIntegrityManager).requestIntegrityToken(integrityTokenRequestCaptor.capture());
149205
assertThat(integrityTokenRequestCaptor.getValue().cloudProjectNumber())
150206
.isEqualTo(Long.parseLong(PROJECT_NUMBER));
@@ -159,4 +215,12 @@ public void getToken_tokenExchangeFailure_setsTaskException() throws Exception {
159215
new String(exchangePlayIntegrityTokenRequestCaptor.getValue());
160216
assertThat(exchangePlayIntegrityTokenRequestJsonString).contains(INTEGRITY_TOKEN);
161217
}
218+
219+
private static String createGeneratePlayIntegrityChallengeResponse() throws Exception {
220+
JSONObject responseBodyJson = new JSONObject();
221+
responseBodyJson.put(GeneratePlayIntegrityChallengeResponse.CHALLENGE_KEY, CHALLENGE);
222+
responseBodyJson.put(GeneratePlayIntegrityChallengeResponse.TIME_TO_LIVE_KEY, TIME_TO_LIVE);
223+
224+
return responseBodyJson.toString();
225+
}
162226
}

appcheck/firebase-appcheck/src/test/java/com/google/firebase/appcheck/internal/NetworkClientTest.java

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ public class NetworkClientTest {
6969
"https://firebaseappcheck.googleapis.com/v1beta/projects/projectId/apps/appId:exchangeSafetyNetToken?key=apiKey";
7070
private static final String DEBUG_EXPECTED_URL =
7171
"https://firebaseappcheck.googleapis.com/v1beta/projects/projectId/apps/appId:exchangeDebugToken?key=apiKey";
72-
private static final String PLAY_INTEGRITY_EXPECTED_URL =
72+
private static final String PLAY_INTEGRITY_CHALLENGE_EXPECTED_URL =
73+
"https://firebaseappcheck.googleapis.com/v1/projects/projectId/apps/appId:generatePlayIntegrityChallenge?key=apiKey";
74+
private static final String PLAY_INTEGRITY_EXCHANGE_EXPECTED_URL =
7375
"https://firebaseappcheck.googleapis.com/v1/projects/projectId/apps/appId:exchangePlayIntegrityToken?key=apiKey";
7476
private static final String JSON_REQUEST = "jsonRequest";
7577
private static final int SUCCESS_CODE = 200;
@@ -78,6 +80,7 @@ public class NetworkClientTest {
7880
private static final String TIME_TO_LIVE = "3600s";
7981
private static final String ERROR_MESSAGE = "error message";
8082
private static final String HEART_BEAT_HEADER_TEST = "test-header";
83+
private static final String CHALLENGE_RESPONSE = "challengeResponse";
8184

8285
@Mock HeartBeatController mockHeartBeatController;
8386
@Mock HttpURLConnection mockHttpUrlConnection;
@@ -228,7 +231,7 @@ public void exchangePlayIntegrityToken_successResponse_returnsAppCheckTokenRespo
228231
assertThat(tokenResponse.getAttestationToken()).isEqualTo(ATTESTATION_TOKEN);
229232
assertThat(tokenResponse.getTimeToLive()).isEqualTo(TIME_TO_LIVE);
230233

231-
URL expectedUrl = new URL(PLAY_INTEGRITY_EXPECTED_URL);
234+
URL expectedUrl = new URL(PLAY_INTEGRITY_EXCHANGE_EXPECTED_URL);
232235
verify(networkClient).createHttpUrlConnection(expectedUrl);
233236
verify(mockOutputStream)
234237
.write(JSON_REQUEST.getBytes(), /* off= */ 0, JSON_REQUEST.getBytes().length);
@@ -254,7 +257,7 @@ public void exchangePlayIntegrityToken_errorResponse_throwsException() throws Ex
254257
JSON_REQUEST.getBytes(), NetworkClient.PLAY_INTEGRITY, mockRetryManager));
255258

256259
assertThat(exception.getMessage()).contains(ERROR_MESSAGE);
257-
URL expectedUrl = new URL(PLAY_INTEGRITY_EXPECTED_URL);
260+
URL expectedUrl = new URL(PLAY_INTEGRITY_EXCHANGE_EXPECTED_URL);
258261
verify(networkClient).createHttpUrlConnection(expectedUrl);
259262
verify(mockOutputStream)
260263
.write(JSON_REQUEST.getBytes(), /* off= */ 0, JSON_REQUEST.getBytes().length);
@@ -306,6 +309,68 @@ public void exchangeAttestation_cannotRetry_throwsException() {
306309
verify(mockRetryManager, never()).resetBackoffOnSuccess();
307310
}
308311

312+
@Test
313+
public void generatePlayIntegrityChallenge_successResponse_returnsJsonString() throws Exception {
314+
when(mockHttpUrlConnection.getOutputStream()).thenReturn(mockOutputStream);
315+
when(mockHttpUrlConnection.getInputStream())
316+
.thenReturn(new ByteArrayInputStream(CHALLENGE_RESPONSE.getBytes()));
317+
when(mockHttpUrlConnection.getResponseCode()).thenReturn(SUCCESS_CODE);
318+
319+
String challengeResponse =
320+
networkClient.generatePlayIntegrityChallenge(JSON_REQUEST.getBytes(), mockRetryManager);
321+
assertThat(challengeResponse).isEqualTo(CHALLENGE_RESPONSE);
322+
323+
URL expectedUrl = new URL(PLAY_INTEGRITY_CHALLENGE_EXPECTED_URL);
324+
verify(networkClient).createHttpUrlConnection(expectedUrl);
325+
verify(mockOutputStream)
326+
.write(JSON_REQUEST.getBytes(), /* off= */ 0, JSON_REQUEST.getBytes().length);
327+
verify(mockRetryManager, never()).updateBackoffOnFailure(anyInt());
328+
verify(mockRetryManager).resetBackoffOnSuccess();
329+
verifyRequestHeaders();
330+
}
331+
332+
@Test
333+
public void generatePlayIntegrityChallenge_errorResponse_throwsException() throws Exception {
334+
JSONObject responseBodyJson = createHttpErrorResponse();
335+
336+
when(mockHttpUrlConnection.getOutputStream()).thenReturn(mockOutputStream);
337+
when(mockHttpUrlConnection.getErrorStream())
338+
.thenReturn(new ByteArrayInputStream(responseBodyJson.toString().getBytes()));
339+
when(mockHttpUrlConnection.getResponseCode()).thenReturn(ERROR_CODE);
340+
341+
FirebaseException exception =
342+
assertThrows(
343+
FirebaseException.class,
344+
() ->
345+
networkClient.generatePlayIntegrityChallenge(
346+
JSON_REQUEST.getBytes(), mockRetryManager));
347+
348+
assertThat(exception.getMessage()).contains(ERROR_MESSAGE);
349+
URL expectedUrl = new URL(PLAY_INTEGRITY_CHALLENGE_EXPECTED_URL);
350+
verify(networkClient).createHttpUrlConnection(expectedUrl);
351+
verify(mockOutputStream)
352+
.write(JSON_REQUEST.getBytes(), /* off= */ 0, JSON_REQUEST.getBytes().length);
353+
verify(mockRetryManager).updateBackoffOnFailure(ERROR_CODE);
354+
verify(mockRetryManager, never()).resetBackoffOnSuccess();
355+
verifyRequestHeaders();
356+
}
357+
358+
@Test
359+
public void generatePlayIntegrityChallenge_cannotRetry_throwsException() {
360+
when(mockRetryManager.canRetry()).thenReturn(false);
361+
362+
FirebaseException exception =
363+
assertThrows(
364+
FirebaseException.class,
365+
() ->
366+
networkClient.generatePlayIntegrityChallenge(
367+
JSON_REQUEST.getBytes(), mockRetryManager));
368+
369+
assertThat(exception.getMessage()).contains("Too many attempts");
370+
verify(mockRetryManager, never()).updateBackoffOnFailure(anyInt());
371+
verify(mockRetryManager, never()).resetBackoffOnSuccess();
372+
}
373+
309374
private void verifyRequestHeaders() {
310375
verify(networkClient).getHeartBeat();
311376
verify(mockHttpUrlConnection).setRequestProperty(X_FIREBASE_CLIENT, HEART_BEAT_HEADER_TEST);

0 commit comments

Comments
 (0)