CredentialProviderContractTest.kt

4.2 KB · raw

1package com.peachpasswords.passkeys23import java.io.File4import org.junit.Assert.assertEquals5import org.junit.Assert.assertFalse6import org.junit.Assert.assertTrue7import org.junit.Test89class CredentialProviderContractTest {10    @Test11    fun authenticationActionPendingIntentIsMutableForFrameworkRequestAttachment() {12        val source = source("passkeys/PasskeyUnlockIntent.kt")1314        assertTrue(source.contains("PendingIntent.FLAG_MUTABLE"))15        assertFalse(source.contains("PendingIntent.FLAG_IMMUTABLE"))16    }1718    @Test19    fun selectedRowUsesOnlyTheFinalProviderRequest() {20        val selection = source("passkeys/PasskeyCredentialSelectionActivity.kt")2122        assertTrue(selection.contains("retrieveProviderGetCredentialRequest(intent)"))23        assertFalse(selection.contains("selectionOrigin("))24        assertFalse(selection.contains("selectionClientDataHash("))25        assertFalse(selection.contains("selectionRequestJson("))26        assertFalse(selection.contains("selectionRequiresUserVerification("))27        assertFalse(selection.contains("EXTRA_AUTHENTICATED_CLIENT_DATA_HASH"))28    }2930    @Test31    fun providerOffersAnExplicitManualPasskeyChooser() {32        val service = source("passkeys/PeachCredentialProviderService.kt")33        val unlock = source("credentials/CredentialProviderUnlockActivity.kt")34        val selection = source("passkeys/PasskeyCredentialSelectionActivity.kt")3536        assertTrue(service.contains("Choose another Peach passkey"))37        assertTrue(unlock.contains("Choose another Peach passkey"))38        assertTrue(selection.contains("retrieveBeginGetCredentialRequest(intent)"))39        assertTrue(selection.contains("PasskeyCredentialPlanner.candidates"))40    }4142    @Test43    fun api35PasskeyRowsDelegateVerificationToCredentialManager() {44        val service = source("passkeys/PeachCredentialProviderService.kt")45        val unlock = source("credentials/CredentialProviderUnlockActivity.kt")46        val factory = source("passkeys/PasskeyCredentialEntryFactory.kt")4748        assertTrue(service.contains("PasskeyCredentialEntryFactory.create"))49        assertTrue(unlock.contains("PasskeyCredentialEntryFactory.create"))50        assertTrue(factory.contains("Build.VERSION_CODES.VANILLA_ICE_CREAM"))51        assertTrue(factory.contains("setBiometricPromptData"))52        assertTrue(factory.contains("BIOMETRIC_STRONG or DEVICE_CREDENTIAL"))53    }5455    @Test56    fun credentialManagerVerificationResultHasOneOwner() {57        assertEquals(58            PasskeyVerificationRoute.ACCEPT,59            passkeyVerificationRoute(60                verifiedByUnlock = false,61                hasEmbeddedResult = true,62                embeddedSucceeded = true,63            ),64        )65        assertEquals(66            PasskeyVerificationRoute.REJECT,67            passkeyVerificationRoute(68                verifiedByUnlock = false,69                hasEmbeddedResult = true,70                embeddedSucceeded = false,71            ),72        )73        assertEquals(74            PasskeyVerificationRoute.PROMPT_IN_PEACH,75            passkeyVerificationRoute(76                verifiedByUnlock = false,77                hasEmbeddedResult = false,78                embeddedSucceeded = false,79            ),80        )81        assertEquals(82            PasskeyVerificationRoute.ACCEPT,83            passkeyVerificationRoute(84                verifiedByUnlock = true,85                hasEmbeddedResult = false,86                embeddedSucceeded = false,87            ),88        )89    }9091    @Test92    fun authenticatedUnlockPreservesVaultForExactlyTheCredentialManagerHandoff() {93        val unlock = source("credentials/CredentialProviderUnlockActivity.kt")9495        assertTrue(unlock.contains("vault.expectTransientBackground()"))96        assertTrue(unlock.contains("verifiedByUnlock = true"))97        assertTrue(source("passkeys/PasskeyCredentialSelectionActivity.kt").contains("PendingIntent.FLAG_ONE_SHOT"))98    }99100    @Test101    fun pendingIntentRequestCodesAreNeverReusedWithinAProcess() {102        val codes = (1..1_000).map { PasskeyPendingIntentIds.next() }103104        assertEquals(codes.size, codes.toSet().size)105    }106107    private fun source(relativePath: String): String =108        File("src/main/java/com/peachpasswords/$relativePath").readText()109}