@@ -18,6 +18,7 @@ import android.content.Context
1818import android.content.Intent
1919import android.net.Uri
2020import androidx.test.core.app.ApplicationProvider
21+ import com.firebase.ui.auth.configuration.auth_provider.AuthProvider
2122import com.google.android.gms.tasks.TaskCompletionSource
2223import com.google.common.truth.Truth.assertThat
2324import com.google.firebase.FirebaseApp
@@ -26,6 +27,7 @@ import com.google.firebase.FirebaseOptions
2627import com.google.firebase.auth.FirebaseAuth
2728import com.google.firebase.auth.FirebaseAuthRecentLoginRequiredException
2829import com.google.firebase.auth.FirebaseUser
30+ import com.google.firebase.auth.UserInfo
2931import kotlinx.coroutines.CancellationException
3032import kotlinx.coroutines.test.runTest
3133import org.junit.After
@@ -401,6 +403,156 @@ class FirebaseAuthUITest {
401403 }
402404 }
403405
406+ @Test
407+ fun `signOut() calls Google sign out when user provider is Google` () = runTest {
408+ // Setup mock user with Google provider
409+ val mockUser = mock(FirebaseUser ::class .java)
410+ val mockUserInfo = mock(UserInfo ::class .java)
411+ `when `(mockUserInfo.providerId).thenReturn(" google.com" )
412+ `when `(mockUser.providerId).thenReturn(" google.com" )
413+ `when `(mockUser.providerData).thenReturn(listOf (mockUserInfo))
414+
415+ // Setup mock auth
416+ val mockAuth = mock(FirebaseAuth ::class .java)
417+ `when `(mockAuth.currentUser).thenReturn(mockUser)
418+ doNothing().`when `(mockAuth).signOut()
419+
420+ // Create mock credential manager provider
421+ var googleSignOutCalled = false
422+ val mockCredentialManagerProvider = object : AuthProvider .Google .CredentialManagerProvider {
423+ override suspend fun getGoogleCredential (
424+ context : Context ,
425+ credentialManager : androidx.credentials.CredentialManager ,
426+ serverClientId : String ,
427+ filterByAuthorizedAccounts : Boolean ,
428+ autoSelectEnabled : Boolean ,
429+ ): AuthProvider .Google .GoogleSignInResult {
430+ throw UnsupportedOperationException (" Not used in this test" )
431+ }
432+
433+ override suspend fun clearCredentialState (
434+ context : Context ,
435+ credentialManager : androidx.credentials.CredentialManager ,
436+ ) {
437+ googleSignOutCalled = true
438+ }
439+ }
440+
441+ // Create instance with mock auth and inject test provider
442+ val instance = FirebaseAuthUI .create(defaultApp, mockAuth)
443+ instance.testCredentialManagerProvider = mockCredentialManagerProvider
444+ val context = ApplicationProvider .getApplicationContext<Context >()
445+
446+ // Perform sign out
447+ instance.signOut(context)
448+
449+ // Verify Google sign out was called
450+ assertThat(googleSignOutCalled).isTrue()
451+ verify(mockAuth).signOut()
452+ }
453+
454+ @Test
455+ fun `signOut() calls Facebook sign out when user provider is Facebook` () = runTest {
456+ // Setup mock user with Facebook provider
457+ val mockUser = mock(FirebaseUser ::class .java)
458+ val mockUserInfo = mock(UserInfo ::class .java)
459+ `when `(mockUserInfo.providerId).thenReturn(" facebook.com" )
460+ `when `(mockUser.providerId).thenReturn(" facebook.com" )
461+ `when `(mockUser.providerData).thenReturn(listOf (mockUserInfo))
462+
463+ // Setup mock auth
464+ val mockAuth = mock(FirebaseAuth ::class .java)
465+ `when `(mockAuth.currentUser).thenReturn(mockUser)
466+ doNothing().`when `(mockAuth).signOut()
467+
468+ // Create mock login manager provider
469+ var facebookSignOutCalled = false
470+ val mockLoginManagerProvider = object : AuthProvider .Facebook .LoginManagerProvider {
471+ override fun getCredential (token : String ): com.google.firebase.auth.AuthCredential {
472+ throw UnsupportedOperationException (" Not used in this test" )
473+ }
474+
475+ override fun logOut () {
476+ facebookSignOutCalled = true
477+ }
478+ }
479+
480+ // Create instance with mock auth and inject test provider
481+ val instance = FirebaseAuthUI .create(defaultApp, mockAuth)
482+ instance.testLoginManagerProvider = mockLoginManagerProvider
483+ val context = ApplicationProvider .getApplicationContext<Context >()
484+
485+ // Perform sign out
486+ instance.signOut(context)
487+
488+ // Verify Facebook sign out was called
489+ assertThat(facebookSignOutCalled).isTrue()
490+ verify(mockAuth).signOut()
491+ }
492+
493+ @Test
494+ fun `signOut() does not call Google or Facebook sign out when user provider is Email` () =
495+ runTest {
496+ // Setup mock user with Email provider
497+ val mockUser = mock(FirebaseUser ::class .java)
498+ val mockUserInfo = mock(UserInfo ::class .java)
499+ `when `(mockUserInfo.providerId).thenReturn(" password" )
500+ `when `(mockUser.providerId).thenReturn(" password" )
501+ `when `(mockUser.providerData).thenReturn(listOf (mockUserInfo))
502+
503+ // Setup mock auth
504+ val mockAuth = mock(FirebaseAuth ::class .java)
505+ `when `(mockAuth.currentUser).thenReturn(mockUser)
506+ doNothing().`when `(mockAuth).signOut()
507+
508+ // Create mock providers
509+ var googleSignOutCalled = false
510+ val mockCredentialManagerProvider =
511+ object : AuthProvider .Google .CredentialManagerProvider {
512+ override suspend fun getGoogleCredential (
513+ context : Context ,
514+ credentialManager : androidx.credentials.CredentialManager ,
515+ serverClientId : String ,
516+ filterByAuthorizedAccounts : Boolean ,
517+ autoSelectEnabled : Boolean ,
518+ ): AuthProvider .Google .GoogleSignInResult {
519+ throw UnsupportedOperationException (" Not used in this test" )
520+ }
521+
522+ override suspend fun clearCredentialState (
523+ context : Context ,
524+ credentialManager : androidx.credentials.CredentialManager ,
525+ ) {
526+ googleSignOutCalled = true
527+ }
528+ }
529+
530+ var facebookSignOutCalled = false
531+ val mockLoginManagerProvider = object : AuthProvider .Facebook .LoginManagerProvider {
532+ override fun getCredential (token : String ): com.google.firebase.auth.AuthCredential {
533+ throw UnsupportedOperationException (" Not used in this test" )
534+ }
535+
536+ override fun logOut () {
537+ facebookSignOutCalled = true
538+ }
539+ }
540+
541+ // Create instance with mock auth and inject test providers
542+ val instance = FirebaseAuthUI .create(defaultApp, mockAuth)
543+ instance.testCredentialManagerProvider = mockCredentialManagerProvider
544+ instance.testLoginManagerProvider = mockLoginManagerProvider
545+ val context = ApplicationProvider .getApplicationContext<Context >()
546+
547+ // Perform sign out
548+ instance.signOut(context)
549+
550+ // Verify neither Google nor Facebook sign out was called
551+ assertThat(googleSignOutCalled).isFalse()
552+ assertThat(facebookSignOutCalled).isFalse()
553+ verify(mockAuth).signOut()
554+ }
555+
404556 // =============================================================================================
405557 // Delete Account Tests
406558 // =============================================================================================
0 commit comments