All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonTest.AuthTest.kt Maven / Gradle / Ivy

Go to download

Light the way for your app's backend with functional and testable Firebase components

There is a newer version: 1.0.0-alpha12
Show newest version
import enchant.flare.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import kotlinx.coroutines.yield
import kotlin.test.*

@OptIn(ExperimentalCoroutinesApi::class)
class AuthTest : FlareTest() {
    lateinit var auth: FirebaseAuth

    @BeforeTest
    fun initializeAuth() {
        auth = if (useLocal) LocalAuth() else FirebaseAuth.instance
    }

    @Test
    fun signInProviders() = runTest {
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        val providers = auth.fetchSignInProvidersForEmail("[email protected]")
        assertContentEquals(listOf(AuthProvider.EmailPassword), providers)
    }

    @Test
    fun resetPassword() = runTest {
        if (!useLocal) println("Skipped since test only supports LocalAuth").also { return@runTest }
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        auth.sendPasswordResetEmail("[email protected]")
        auth.verifyPasswordResetCode("100000")
        auth.confirmPasswordReset("100000", "mypassword2")
        auth.signOut()
        val info = auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword2"))
        assertFalse(info.isNewUser, "User should not be recreated after password change")
        assertNotNull(auth.currentUser, "User should be signed in")
    }

    @Test
    fun signInWithEmailLink() = runTest {
        if (!useLocal) println("Skipped since test only supports LocalAuth").also { return@runTest }
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        auth.signOut()
        auth.sendSignInLinkToEmail("[email protected]", ActionCodeSettings())
        val info = auth.signIn(AuthMethod.EmailLink("[email protected]", "100000"))
        assertFalse(info.isNewUser, "User should not be recreated after email link sign-in")
        assertNotNull(auth.currentUser, "User should be signed in")
    }

    @Test
    fun signInWithEmail() = runTest {
        val info = auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        assertTrue(info.isNewUser)
        assertEquals("[email protected]", auth.currentUser?.email)
        assertNotNull(auth.currentUser, "User should be signed in")
    }

    @Test
    fun signInAnonymous() = runTest {
        auth.signIn(AuthMethod.Anonymous)
        assertNotNull(auth.currentUser, "User should be signed in")
        assertTrue(auth.currentUser!!.isAnonymous)
    }

    @Test
    fun signInWithWeb() = runTest {
        if (!useLocal) println("Skipped since test only supports LocalAuth").also { return@runTest }
        auth.signIn(AuthMethod.Google(webClientId = "", ui = "[email protected]"))
        assertNotNull(auth.currentUser, "User should be signed in")
        auth.signOut()
        val info = auth.signIn(AuthMethod.Google(webClientId = "", ui = "[email protected]"))
        assertFalse(info.isNewUser, "User should not be recreated after web sign-in")
    }

    @Test
    fun authStateChanges() = runTest {
        var updates = 0
        val job = launch {
            auth.config.onAuthStateChange().collect {
                updates++
                println("update$updates")
            }
        }
        repeat(2) {
            auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
            yield()
            auth.signOut()
            yield()
        }
        assertEquals(4, updates, "Five auth state changes should have occurred")
        job.cancel()

    }

    @Test
    fun deleteUser() = runTest {
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        auth.currentUser!!.delete()
        assertNull(auth.currentUser, "User should be signed out after their account is deleted")
        val info = auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        assertTrue(info.isNewUser, "User should be recreated after deleted")
    }

    @Test
    fun userInfo() = runTest {
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        val user = auth.currentUser ?: fail("User should be signed in")
        assertNull(user.displayName)
        assertNull(user.phoneNumber)
        assertNull(user.photoUrl)
        assertNull(user.tenantId)
        assertEquals("[email protected]", user.email)
        assertEquals(
            user.creationTimestamp,
            user.lastSignInTimestamp,
            "Check the first sign in time is the creation time"
        )
        assertTrue("Uid needs to be 28 character letter and digit identifier") {
            user.uid.all(Char::isLetterOrDigit) && user.uid.length == 28
        }
    }

    @Test
    fun linkMethod() = runTest {
        if (!useLocal) println("Skipped since test only supports LocalAuth").also { return@runTest }
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        val user = auth.currentUser ?: fail("User should be signed in")
        user.linkMethod(AuthMethod.GitHub("[email protected]"))
        val providers = auth.fetchSignInProvidersForEmail("[email protected]")
        assertEquals(
            setOf(AuthProvider.EmailPassword, AuthProvider.GitHub),
            providers.toSet(),
            "User's methods should include EmailPassword and GitHub after GitHub is linked"
        )
        auth.signOut()
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        auth.signOut()
        auth.signIn(AuthMethod.GitHub("[email protected]"))
    }

    @Test
    fun unlinkMethod() = runTest {
        if (!useLocal) println("Skipped since test only supports LocalAuth").also { return@runTest }
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        val user = auth.currentUser ?: fail("User should be signed in")
        user.linkMethod(AuthMethod.GitHub("[email protected]"))
        user.unlinkMethod(AuthProvider.GitHub)
        val providers = auth.fetchSignInProvidersForEmail("[email protected]")
        assertEquals(
            listOf(AuthProvider.EmailPassword), providers,
            "User's methods should include EmailPassword after GitHub is unlinked"
        )
        auth.signOut()
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        auth.signOut()
        assertFails {
            auth.signIn(AuthMethod.GitHub("[email protected]"))
        }
    }

    @Test
    fun reauthenticate() = runTest {
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        val user = auth.currentUser ?: fail("User should be signed in")
        user.reauthenticate(AuthMethod.EmailPassword("[email protected]", "mypassword"))
    }

    @Test
    fun updateEmail() = runTest {
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        val user = auth.currentUser ?: fail("User should be signed in")
        user.updateEmail("[email protected]")
        assertEquals("[email protected]", user.email)
        auth.signOut()
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        auth.currentUser ?: fail("User should be signed in")
    }

    @Test
    fun updatePassword() = runTest {
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        val user = auth.currentUser ?: fail("User should be signed in")
        user.updatePassword("mypassword2")
        auth.signOut()
        assertFails { auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword")) }
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword2"))
        auth.currentUser ?: fail("User should be signed in")
    }

    @Test
    fun updateProfile() = runTest {
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        val user = auth.currentUser ?: fail("User should be signed in")
        user.updateProfile("My Name", "https://testphoto.com")
        assertEquals("My Name", user.displayName, "Ensure name was changed")
        assertEquals("https://testphoto.com", user.photoUrl, "Ensure photo url was changed")
    }


    @Test
    fun signOut() = runTest {
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        auth.signOut()
        assertNull(auth.currentUser)
    }

    @Test
    fun failSignIn() = runTest {
        auth.signIn(AuthMethod.EmailPassword("[email protected]", "mypassword"))
        auth.signOut()
        try {
            auth.signIn(AuthMethod.EmailPassword("[email protected]", "mywrongpassword"))
            fail()
        } catch (e: AuthException) {

        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy