Skip to content

Commit dde05ae

Browse files
test(appcheck-recaptcha-enterprise): Add unit tests for reCAPTCHA Enterprise module
1 parent 93ba811 commit dde05ae

File tree

5 files changed

+325
-0
lines changed

5 files changed

+325
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.google.firebase.appcheck.recaptchaenterprise;
2+
3+
import static com.google.common.truth.Truth.assertThat;
4+
5+
import android.app.Application;
6+
import android.content.Context;
7+
8+
import com.google.firebase.FirebaseApp;
9+
import com.google.firebase.annotations.concurrent.Blocking;
10+
import com.google.firebase.annotations.concurrent.Lightweight;
11+
import com.google.firebase.appcheck.recaptchaenterprise.internal.SiteKey;
12+
import com.google.firebase.components.Component;
13+
import com.google.firebase.components.Dependency;
14+
import com.google.firebase.components.Qualified;
15+
16+
import org.junit.Test;
17+
import org.junit.runner.RunWith;
18+
import org.robolectric.RobolectricTestRunner;
19+
20+
import java.util.List;
21+
import java.util.concurrent.Executor;
22+
23+
/** Tests for {@link FirebaseAppCheckRecaptchaEnterpriseRegistrar}. */
24+
@RunWith(RobolectricTestRunner.class)
25+
public class FirebaseAppCheckRecaptchaEnterpriseRegistrarTest {
26+
@Test
27+
public void testGetComponents() {
28+
FirebaseAppCheckRecaptchaEnterpriseRegistrar registrar =
29+
new FirebaseAppCheckRecaptchaEnterpriseRegistrar();
30+
List<Component<?>> components = registrar.getComponents();
31+
assertThat(components).isNotEmpty();
32+
assertThat(components).hasSize(4);
33+
Component<?> applicationComponent = components.get(0);
34+
assertThat(applicationComponent.getDependencies())
35+
.containsExactly(Dependency.required(Context.class));
36+
assertThat(applicationComponent.isLazy()).isTrue();
37+
Component<?> siteKeyComponent = components.get(1);
38+
assertThat(siteKeyComponent.isLazy()).isTrue();
39+
Component<?> appCheckRecaptchaEnterpriseComponent = components.get(2);
40+
assertThat(appCheckRecaptchaEnterpriseComponent.getDependencies())
41+
.containsExactly(
42+
Dependency.required(FirebaseApp.class),
43+
Dependency.required(Application.class),
44+
Dependency.required(SiteKey.class),
45+
Dependency.required(Qualified.qualified(Lightweight.class, Executor.class)),
46+
Dependency.required(Qualified.qualified(Blocking.class, Executor.class)));
47+
assertThat(appCheckRecaptchaEnterpriseComponent.isLazy()).isTrue();
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.google.firebase.appcheck.recaptchaenterprise;
2+
3+
import static com.google.common.truth.Truth.assertThat;
4+
5+
import org.junit.Test;
6+
import org.junit.runner.RunWith;
7+
import org.robolectric.RobolectricTestRunner;
8+
import org.robolectric.annotation.Config;
9+
10+
/** Tests for {@link RecaptchaEnterpriseAppCheckProviderFactory}. */
11+
@RunWith(RobolectricTestRunner.class)
12+
@Config(manifest = Config.NONE)
13+
public class RecaptchaEnterpriseAppCheckProviderFactoryTest {
14+
static final String SITE_KEY = "siteKey";
15+
16+
@Test
17+
public void testGetInstance_callTwice_sameInstance() {
18+
RecaptchaEnterpriseAppCheckProviderFactory firstInstance =
19+
RecaptchaEnterpriseAppCheckProviderFactory.getInstance(SITE_KEY);
20+
RecaptchaEnterpriseAppCheckProviderFactory secondInstance =
21+
RecaptchaEnterpriseAppCheckProviderFactory.getInstance(SITE_KEY);
22+
23+
assertThat(firstInstance).isEqualTo(secondInstance);
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.google.firebase.appcheck.recaptchaenterprise.internal;
2+
3+
import static com.google.common.truth.Truth.assertThat;
4+
5+
import org.json.JSONObject;
6+
import org.junit.Test;
7+
import org.junit.runner.RunWith;
8+
import org.robolectric.RobolectricTestRunner;
9+
import org.robolectric.annotation.Config;
10+
11+
/** Tests for {@link ExchangeRecaptchaEnterpriseTokenRequest}. */
12+
@RunWith(RobolectricTestRunner.class)
13+
@Config(manifest = Config.NONE)
14+
public class ExchangeRecaptchaEnterpriseTokenRequestTest {
15+
private static final String RECAPTCHA_ENTERPRISE_TOKEN = "recaptchaEnterpriseToken";
16+
17+
@Test
18+
public void toJsonString_expectSerialized() throws Exception {
19+
ExchangeRecaptchaEnterpriseTokenRequest exchangeRecaptchaEnterpriseTokenRequest =
20+
new ExchangeRecaptchaEnterpriseTokenRequest(RECAPTCHA_ENTERPRISE_TOKEN);
21+
22+
String jsonString = exchangeRecaptchaEnterpriseTokenRequest.toJsonString();
23+
JSONObject jsonObject = new JSONObject(jsonString);
24+
25+
assertThat(
26+
jsonObject.getString(
27+
ExchangeRecaptchaEnterpriseTokenRequest.RECAPTCHA_ENTERPRISE_TOKEN_KEY))
28+
.isEqualTo(RECAPTCHA_ENTERPRISE_TOKEN);
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
package com.google.firebase.appcheck.recaptchaenterprise.internal;
2+
3+
import static com.google.common.truth.Truth.assertThat;
4+
import static org.junit.Assert.assertThrows;
5+
import static org.mockito.ArgumentMatchers.any;
6+
import static org.mockito.ArgumentMatchers.eq;
7+
import static org.mockito.Mockito.verify;
8+
import static org.mockito.Mockito.when;
9+
10+
import android.app.Application;
11+
12+
import com.google.android.gms.tasks.Task;
13+
import com.google.android.gms.tasks.Tasks;
14+
import com.google.android.recaptcha.RecaptchaAction;
15+
import com.google.android.recaptcha.RecaptchaTasksClient;
16+
import com.google.common.util.concurrent.MoreExecutors;
17+
import com.google.firebase.FirebaseApp;
18+
import com.google.firebase.FirebaseException;
19+
import com.google.firebase.appcheck.AppCheckToken;
20+
import com.google.firebase.appcheck.internal.AppCheckTokenResponse;
21+
import com.google.firebase.appcheck.internal.DefaultAppCheckToken;
22+
import com.google.firebase.appcheck.internal.NetworkClient;
23+
import com.google.firebase.appcheck.internal.RetryManager;
24+
import com.google.firebase.concurrent.TestOnlyExecutors;
25+
26+
import org.json.JSONException;
27+
import org.json.JSONObject;
28+
import org.junit.Before;
29+
import org.junit.Test;
30+
import org.junit.runner.RunWith;
31+
import org.mockito.ArgumentCaptor;
32+
import org.mockito.Mock;
33+
import org.mockito.MockitoAnnotations;
34+
import org.robolectric.RobolectricTestRunner;
35+
import org.robolectric.annotation.Config;
36+
import org.robolectric.annotation.LooperMode;
37+
38+
import java.io.IOException;
39+
import java.util.concurrent.Executor;
40+
41+
/** Tests for {@link RecaptchaEnterpriseAppCheckProvider}. */
42+
@RunWith(RobolectricTestRunner.class)
43+
@Config(manifest = Config.NONE)
44+
@LooperMode(LooperMode.Mode.LEGACY)
45+
public class RecaptchaEnterpriseAppCheckProviderTest {
46+
private static final String APP_CHECK_TOKEN = "appCheckToken";
47+
private static final String RECAPTCHA_ENTERPRISE_TOKEN = "recaptchaEnterpriseToken";
48+
private final Executor liteExecutor = MoreExecutors.directExecutor();
49+
private final Executor blockingExecutor = MoreExecutors.directExecutor();
50+
private final SiteKey siteKey = new SiteKey("siteKey");
51+
52+
@Mock private NetworkClient mockNetworkClient;
53+
@Mock private Application mockApplication;
54+
@Mock FirebaseApp mockFirebaseApp;
55+
@Mock RecaptchaTasksClient mockRecaptchaTasksClient;
56+
@Mock RetryManager mockRetryManager;
57+
58+
@Before
59+
public void setup() {
60+
MockitoAnnotations.openMocks(this);
61+
}
62+
63+
@Test
64+
public void testPublicConstructor_nullFirebaseApp_expectThrows() {
65+
assertThrows(
66+
NullPointerException.class,
67+
() ->
68+
new RecaptchaEnterpriseAppCheckProvider(
69+
null,
70+
mockApplication,
71+
siteKey,
72+
TestOnlyExecutors.lite(),
73+
TestOnlyExecutors.blocking()));
74+
}
75+
76+
@Test
77+
public void testPublicConstructor_nullApplication_expectThrows() {
78+
assertThrows(
79+
NullPointerException.class,
80+
() ->
81+
new RecaptchaEnterpriseAppCheckProvider(
82+
mockFirebaseApp,
83+
null,
84+
siteKey,
85+
TestOnlyExecutors.lite(),
86+
TestOnlyExecutors.blocking()));
87+
}
88+
89+
@Test
90+
public void testPublicConstructor_nullSiteKey_expectThrows() {
91+
assertThrows(
92+
NullPointerException.class,
93+
() ->
94+
new RecaptchaEnterpriseAppCheckProvider(
95+
mockFirebaseApp,
96+
mockApplication,
97+
siteKey,
98+
TestOnlyExecutors.lite(),
99+
TestOnlyExecutors.blocking()));
100+
}
101+
102+
@Test
103+
public void getToken_onSuccess_setsTaskResult() throws Exception {
104+
when(mockRecaptchaTasksClient.executeTask(any(RecaptchaAction.class)))
105+
.thenReturn(Tasks.forResult(RECAPTCHA_ENTERPRISE_TOKEN));
106+
String jsonResponse =
107+
new JSONObject().put("token", APP_CHECK_TOKEN).put("ttl", 3600).toString();
108+
when(mockNetworkClient.exchangeAttestationForAppCheckToken(
109+
any(byte[].class), eq(NetworkClient.RECAPTCHA_ENTERPRISE), eq(mockRetryManager)))
110+
.thenReturn(AppCheckTokenResponse.fromJsonString(jsonResponse));
111+
112+
RecaptchaEnterpriseAppCheckProvider provider =
113+
new RecaptchaEnterpriseAppCheckProvider(
114+
liteExecutor,
115+
blockingExecutor,
116+
mockRetryManager,
117+
mockNetworkClient,
118+
mockRecaptchaTasksClient);
119+
Task<AppCheckToken> task = provider.getToken();
120+
121+
assertThat(task.isSuccessful()).isTrue();
122+
AppCheckToken token = task.getResult();
123+
assertThat(token).isInstanceOf(DefaultAppCheckToken.class);
124+
assertThat(token.getToken()).isEqualTo(APP_CHECK_TOKEN);
125+
126+
ArgumentCaptor<RecaptchaAction> recaptchaActionCaptor =
127+
ArgumentCaptor.forClass(RecaptchaAction.class);
128+
verify(mockRecaptchaTasksClient).executeTask(recaptchaActionCaptor.capture());
129+
assertThat(recaptchaActionCaptor.getValue().getAction()).isEqualTo("fire_app_check");
130+
ArgumentCaptor<byte[]> requestCaptor = ArgumentCaptor.forClass(byte[].class);
131+
verify(mockNetworkClient)
132+
.exchangeAttestationForAppCheckToken(
133+
requestCaptor.capture(), eq(NetworkClient.RECAPTCHA_ENTERPRISE), eq(mockRetryManager));
134+
}
135+
136+
@Test
137+
public void getToken_invalidSiteKey_returnException() {
138+
Exception exception = new Exception("Site key invalid");
139+
when(mockRecaptchaTasksClient.executeTask(any(RecaptchaAction.class)))
140+
.thenReturn(Tasks.forException(exception));
141+
142+
RecaptchaEnterpriseAppCheckProvider provider =
143+
new RecaptchaEnterpriseAppCheckProvider(
144+
liteExecutor,
145+
blockingExecutor,
146+
mockRetryManager,
147+
mockNetworkClient,
148+
mockRecaptchaTasksClient);
149+
Task<AppCheckToken> task = provider.getToken();
150+
assertThat(task.isSuccessful()).isFalse();
151+
assertThat(task.getException()).isEqualTo(exception);
152+
}
153+
154+
@Test
155+
public void getToken_recaptchaFails_returnException() {
156+
Exception exception = new Exception("Recaptcha error");
157+
when(mockRecaptchaTasksClient.executeTask(any(RecaptchaAction.class)))
158+
.thenReturn(Tasks.forException(exception));
159+
160+
RecaptchaEnterpriseAppCheckProvider provider =
161+
new RecaptchaEnterpriseAppCheckProvider(
162+
liteExecutor,
163+
blockingExecutor,
164+
mockRetryManager,
165+
mockNetworkClient,
166+
mockRecaptchaTasksClient);
167+
Task<AppCheckToken> task = provider.getToken();
168+
assertThat(task.isSuccessful()).isFalse();
169+
assertThat(task.getException()).isEqualTo(exception);
170+
}
171+
172+
@Test
173+
public void getToken_networkFails_returnException()
174+
throws FirebaseException, JSONException, IOException {
175+
when(mockRecaptchaTasksClient.executeTask(any(RecaptchaAction.class)))
176+
.thenReturn(Tasks.forResult(RECAPTCHA_ENTERPRISE_TOKEN));
177+
Exception exception = new IOException("Network error");
178+
when(mockNetworkClient.exchangeAttestationForAppCheckToken(
179+
any(byte[].class), eq(NetworkClient.RECAPTCHA_ENTERPRISE), eq(mockRetryManager)))
180+
.thenThrow(exception);
181+
182+
RecaptchaEnterpriseAppCheckProvider provider =
183+
new RecaptchaEnterpriseAppCheckProvider(
184+
liteExecutor,
185+
blockingExecutor,
186+
mockRetryManager,
187+
mockNetworkClient,
188+
mockRecaptchaTasksClient);
189+
Task<AppCheckToken> task = provider.getToken();
190+
assertThat(task.isSuccessful()).isFalse();
191+
assertThat(task.getException()).isEqualTo(exception);
192+
}
193+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.google.firebase.appcheck.recaptchaenterprise.internal;
2+
3+
import static org.junit.Assert.assertThrows;
4+
5+
import com.google.common.truth.Truth;
6+
7+
import org.junit.Test;
8+
import org.junit.runner.RunWith;
9+
import org.robolectric.RobolectricTestRunner;
10+
import org.robolectric.annotation.Config;
11+
12+
/** Tests for {@Link SiteKey}. */
13+
@RunWith(RobolectricTestRunner.class)
14+
@Config(manifest = Config.NONE)
15+
public class SiteKeyTest {
16+
private static final String VALUE = "siteKey";
17+
18+
@Test
19+
public void testConstructor_nullValue_expectThrows() {
20+
assertThrows(NullPointerException.class, () -> new SiteKey(null));
21+
}
22+
23+
@Test
24+
public void testConstructor_nonNullValue_succeeds() {
25+
SiteKey siteKey = new SiteKey(VALUE);
26+
Truth.assertThat(siteKey.value()).isEqualTo(VALUE);
27+
}
28+
}

0 commit comments

Comments
 (0)