diff --git a/appcheck/firebase-appcheck-recaptchaenterprise/api.txt b/appcheck/firebase-appcheck-recaptchaenterprise/api.txt index 99d21ff038c..eb46074a5fe 100644 --- a/appcheck/firebase-appcheck-recaptchaenterprise/api.txt +++ b/appcheck/firebase-appcheck-recaptchaenterprise/api.txt @@ -3,7 +3,7 @@ package com.google.firebase.appcheck.recaptchaenterprise { public class RecaptchaEnterpriseAppCheckProviderFactory implements com.google.firebase.appcheck.AppCheckProviderFactory { method public com.google.firebase.appcheck.AppCheckProvider create(com.google.firebase.FirebaseApp); - method public static com.google.firebase.appcheck.recaptchaenterprise.RecaptchaEnterpriseAppCheckProviderFactory getInstance(String); + method public static com.google.firebase.appcheck.recaptchaenterprise.RecaptchaEnterpriseAppCheckProviderFactory getInstance(); } } diff --git a/appcheck/firebase-appcheck-recaptchaenterprise/firebase-appcheck-recaptchaenterprise.gradle b/appcheck/firebase-appcheck-recaptchaenterprise/firebase-appcheck-recaptchaenterprise.gradle index 045736b6f4f..07142dbd23e 100644 --- a/appcheck/firebase-appcheck-recaptchaenterprise/firebase-appcheck-recaptchaenterprise.gradle +++ b/appcheck/firebase-appcheck-recaptchaenterprise/firebase-appcheck-recaptchaenterprise.gradle @@ -50,7 +50,7 @@ dependencies { implementation(libs.dagger.dagger) api project(':appcheck:firebase-appcheck') - api libs.firebase.common + api project(':firebase-common') api libs.firebase.components api 'com.google.android.recaptcha:recaptcha:18.7.1' diff --git a/appcheck/firebase-appcheck-recaptchaenterprise/src/main/java/com/google/firebase/appcheck/recaptchaenterprise/RecaptchaEnterpriseAppCheckProviderFactory.java b/appcheck/firebase-appcheck-recaptchaenterprise/src/main/java/com/google/firebase/appcheck/recaptchaenterprise/RecaptchaEnterpriseAppCheckProviderFactory.java index e051f54d0e9..6a559ee37bf 100644 --- a/appcheck/firebase-appcheck-recaptchaenterprise/src/main/java/com/google/firebase/appcheck/recaptchaenterprise/RecaptchaEnterpriseAppCheckProviderFactory.java +++ b/appcheck/firebase-appcheck-recaptchaenterprise/src/main/java/com/google/firebase/appcheck/recaptchaenterprise/RecaptchaEnterpriseAppCheckProviderFactory.java @@ -15,13 +15,13 @@ package com.google.firebase.appcheck.recaptchaenterprise; import androidx.annotation.NonNull; +import com.google.android.gms.common.internal.Preconditions; import com.google.firebase.FirebaseApp; import com.google.firebase.appcheck.AppCheckProvider; import com.google.firebase.appcheck.AppCheckProviderFactory; import com.google.firebase.appcheck.FirebaseAppCheck; import com.google.firebase.appcheck.recaptchaenterprise.internal.ProviderMultiResourceComponent; import com.google.firebase.appcheck.recaptchaenterprise.internal.RecaptchaEnterpriseAppCheckProvider; -import java.util.Objects; /** * Implementation of an {@link AppCheckProviderFactory} that builds
@@ -29,34 +29,26 @@ */ public class RecaptchaEnterpriseAppCheckProviderFactory implements AppCheckProviderFactory { - private final String siteKey; - private volatile RecaptchaEnterpriseAppCheckProvider provider; - - private RecaptchaEnterpriseAppCheckProviderFactory(@NonNull String siteKey) { - this.siteKey = siteKey; - } + private RecaptchaEnterpriseAppCheckProviderFactory() {} /** Gets an instance of this class for installation into a {@link FirebaseAppCheck} instance. */ @NonNull - public static RecaptchaEnterpriseAppCheckProviderFactory getInstance(@NonNull String siteKey) { - Objects.requireNonNull(siteKey, "siteKey cannot be null"); - return new RecaptchaEnterpriseAppCheckProviderFactory(siteKey); + public static RecaptchaEnterpriseAppCheckProviderFactory getInstance() { + return new RecaptchaEnterpriseAppCheckProviderFactory(); } @NonNull @Override @SuppressWarnings("FirebaseUseExplicitDependencies") public AppCheckProvider create(@NonNull FirebaseApp firebaseApp) { - if (provider == null) { - synchronized (this) { - if (provider == null) { - ProviderMultiResourceComponent component = - firebaseApp.get(ProviderMultiResourceComponent.class); - provider = component.get(siteKey); - provider.initializeRecaptchaClient(); - } - } - } + String siteKey = firebaseApp.getOptions().getRecaptchaSiteKey(); + Preconditions.checkNotEmpty( + siteKey, + "Missing site key from configuration. Verify your google-services.json file is updated."); + ProviderMultiResourceComponent component = + firebaseApp.get(ProviderMultiResourceComponent.class); + RecaptchaEnterpriseAppCheckProvider provider = component.get(siteKey); + provider.initializeRecaptchaClient(); return provider; } } diff --git a/appcheck/firebase-appcheck-recaptchaenterprise/src/test/java/com/google/firebase/appcheck/recaptchaenterprise/RecaptchaEnterpriseAppCheckProviderFactoryTest.java b/appcheck/firebase-appcheck-recaptchaenterprise/src/test/java/com/google/firebase/appcheck/recaptchaenterprise/RecaptchaEnterpriseAppCheckProviderFactoryTest.java index 865b69e409c..cca7f71832d 100644 --- a/appcheck/firebase-appcheck-recaptchaenterprise/src/test/java/com/google/firebase/appcheck/recaptchaenterprise/RecaptchaEnterpriseAppCheckProviderFactoryTest.java +++ b/appcheck/firebase-appcheck-recaptchaenterprise/src/test/java/com/google/firebase/appcheck/recaptchaenterprise/RecaptchaEnterpriseAppCheckProviderFactoryTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.when; import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; import com.google.firebase.appcheck.AppCheckProvider; import com.google.firebase.appcheck.recaptchaenterprise.internal.ProviderMultiResourceComponent; import com.google.firebase.appcheck.recaptchaenterprise.internal.RecaptchaEnterpriseAppCheckProvider; @@ -31,54 +32,66 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; /** Tests for {@link RecaptchaEnterpriseAppCheckProviderFactory}. */ -@RunWith(MockitoJUnitRunner.class) +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) public class RecaptchaEnterpriseAppCheckProviderFactoryTest { static final String SITE_KEY_1 = "siteKey1"; @Mock private FirebaseApp mockFirebaseApp; + @Mock private FirebaseOptions mockFirebaseOptions; @Mock private ProviderMultiResourceComponent mockComponent; @Mock private RecaptchaEnterpriseAppCheckProvider mockProvider; @Before public void setUp() { + MockitoAnnotations.openMocks(this); when(mockFirebaseApp.get(eq(ProviderMultiResourceComponent.class))).thenReturn(mockComponent); when(mockComponent.get(anyString())).thenReturn(mockProvider); + when(mockFirebaseApp.getOptions()).thenReturn(mockFirebaseOptions); } @Test - public void getInstance_nonNullSiteKey_returnsNonNullInstance() { + public void getInstance_returnsNonNullInstance() { RecaptchaEnterpriseAppCheckProviderFactory factory = - RecaptchaEnterpriseAppCheckProviderFactory.getInstance(SITE_KEY_1); + RecaptchaEnterpriseAppCheckProviderFactory.getInstance(); assertNotNull(factory); } @Test - public void getInstance_nullSiteKey_expectThrows() { - assertThrows( - NullPointerException.class, - () -> RecaptchaEnterpriseAppCheckProviderFactory.getInstance(null)); - } - - @Test - public void create_nonNullFirebaseApp_returnsRecaptchaEnterpriseAppCheckProvider() { + public void create_siteKeyInOptions_returnsRecaptchaEnterpriseAppCheckProvider() { + when(mockFirebaseOptions.getRecaptchaSiteKey()).thenReturn(SITE_KEY_1); RecaptchaEnterpriseAppCheckProviderFactory factory = - RecaptchaEnterpriseAppCheckProviderFactory.getInstance(SITE_KEY_1); + RecaptchaEnterpriseAppCheckProviderFactory.getInstance(); AppCheckProvider provider = factory.create(mockFirebaseApp); assertNotNull(provider); assertEquals(RecaptchaEnterpriseAppCheckProvider.class, provider.getClass()); + verify(mockComponent).get(SITE_KEY_1); + } + + @Test + public void create_noSiteKeyInOptionsOrFactory_expectThrows() { + when(mockFirebaseOptions.getRecaptchaSiteKey()).thenReturn(null); + RecaptchaEnterpriseAppCheckProviderFactory factory = + RecaptchaEnterpriseAppCheckProviderFactory.getInstance(); + assertThrows(IllegalArgumentException.class, () -> factory.create(mockFirebaseApp)); } @Test - public void create_callMultipleTimes_providerIsInitializedOnlyOnce() { + public void create_callMultipleTimes_initializesProviderEveryTime() { + when(mockFirebaseOptions.getRecaptchaSiteKey()).thenReturn(SITE_KEY_1); RecaptchaEnterpriseAppCheckProviderFactory factory = - RecaptchaEnterpriseAppCheckProviderFactory.getInstance(SITE_KEY_1); + RecaptchaEnterpriseAppCheckProviderFactory.getInstance(); factory.create(mockFirebaseApp); factory.create(mockFirebaseApp); factory.create(mockFirebaseApp); - verify(mockProvider, times(1)).initializeRecaptchaClient(); + + verify(mockComponent, times(3)).get(SITE_KEY_1); + verify(mockProvider, times(3)).initializeRecaptchaClient(); } }