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(hasEmbeddedResult = true, embeddedSucceeded = true),60 )61 assertEquals(62 PasskeyVerificationRoute.REJECT,63 passkeyVerificationRoute(hasEmbeddedResult = true, embeddedSucceeded = false),64 )65 assertEquals(66 PasskeyVerificationRoute.PROMPT_IN_PEACH,67 passkeyVerificationRoute(hasEmbeddedResult = false, embeddedSucceeded = false),68 )69 }7071 @Test72 fun pendingIntentRequestCodesAreNeverReusedWithinAProcess() {73 val codes = (1..1_000).map { PasskeyPendingIntentIds.next() }7475 assertEquals(codes.size, codes.toSet().size)76 }7778 private fun source(relativePath: String): String =79 File("src/main/java/com/peachpasswords/$relativePath").readText()80}