package com.peachpasswords.passkeys import java.io.File import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test class CredentialProviderContractTest { @Test fun authenticationActionPendingIntentIsMutableForFrameworkRequestAttachment() { val source = source("passkeys/PasskeyUnlockIntent.kt") assertTrue(source.contains("PendingIntent.FLAG_MUTABLE")) assertFalse(source.contains("PendingIntent.FLAG_IMMUTABLE")) } @Test fun selectedRowUsesOnlyTheFinalProviderRequest() { val selection = source("passkeys/PasskeyCredentialSelectionActivity.kt") assertTrue(selection.contains("retrieveProviderGetCredentialRequest(intent)")) assertFalse(selection.contains("selectionOrigin(")) assertFalse(selection.contains("selectionClientDataHash(")) assertFalse(selection.contains("selectionRequestJson(")) assertFalse(selection.contains("selectionRequiresUserVerification(")) assertFalse(selection.contains("EXTRA_AUTHENTICATED_CLIENT_DATA_HASH")) } @Test fun providerOffersAnExplicitManualPasskeyChooser() { val service = source("passkeys/PeachCredentialProviderService.kt") val unlock = source("credentials/CredentialProviderUnlockActivity.kt") val selection = source("passkeys/PasskeyCredentialSelectionActivity.kt") assertTrue(service.contains("Choose another Peach passkey")) assertTrue(unlock.contains("Choose another Peach passkey")) assertTrue(selection.contains("retrieveBeginGetCredentialRequest(intent)")) assertTrue(selection.contains("PasskeyCredentialPlanner.candidates")) } @Test fun api35PasskeyRowsDelegateVerificationToCredentialManager() { val service = source("passkeys/PeachCredentialProviderService.kt") val unlock = source("credentials/CredentialProviderUnlockActivity.kt") val factory = source("passkeys/PasskeyCredentialEntryFactory.kt") assertTrue(service.contains("PasskeyCredentialEntryFactory.create")) assertTrue(unlock.contains("PasskeyCredentialEntryFactory.create")) assertTrue(factory.contains("Build.VERSION_CODES.VANILLA_ICE_CREAM")) assertTrue(factory.contains("setBiometricPromptData")) assertTrue(factory.contains("BIOMETRIC_STRONG or DEVICE_CREDENTIAL")) } @Test fun credentialManagerVerificationResultHasOneOwner() { assertEquals( PasskeyVerificationRoute.ACCEPT, passkeyVerificationRoute( verifiedByUnlock = false, hasEmbeddedResult = true, embeddedSucceeded = true, ), ) assertEquals( PasskeyVerificationRoute.REJECT, passkeyVerificationRoute( verifiedByUnlock = false, hasEmbeddedResult = true, embeddedSucceeded = false, ), ) assertEquals( PasskeyVerificationRoute.PROMPT_IN_PEACH, passkeyVerificationRoute( verifiedByUnlock = false, hasEmbeddedResult = false, embeddedSucceeded = false, ), ) assertEquals( PasskeyVerificationRoute.ACCEPT, passkeyVerificationRoute( verifiedByUnlock = true, hasEmbeddedResult = false, embeddedSucceeded = false, ), ) } @Test fun authenticatedUnlockPreservesVaultForExactlyTheCredentialManagerHandoff() { val unlock = source("credentials/CredentialProviderUnlockActivity.kt") assertTrue(unlock.contains("vault.expectTransientBackground()")) assertTrue(unlock.contains("verifiedByUnlock = true")) assertTrue(source("passkeys/PasskeyCredentialSelectionActivity.kt").contains("PendingIntent.FLAG_ONE_SHOT")) } @Test fun pendingIntentRequestCodesAreNeverReusedWithinAProcess() { val codes = (1..1_000).map { PasskeyPendingIntentIds.next() } assertEquals(codes.size, codes.toSet().size) } private fun source(relativePath: String): String = File("src/main/java/com/peachpasswords/$relativePath").readText() }