1package com.peachpasswords.passkeys23import java.io.File4import org.junit.Assert.assertFalse5import org.junit.Assert.assertTrue6import org.junit.Test78class CredentialProviderContractTest {9 @Test10 fun authenticationActionPendingIntentIsMutableForFrameworkRequestAttachment() {11 val source = source("passkeys/PasskeyUnlockIntent.kt")1213 assertTrue(source.contains("PendingIntent.FLAG_MUTABLE"))14 assertFalse(source.contains("PendingIntent.FLAG_IMMUTABLE"))15 }1617 @Test18 fun selectionPrefersTheFinalFrameworkOrigin() {19 assertTrue(20 selectionOrigin("https://github.com", "https://example.com") ==21 "https://github.com",22 )23 }2425 @Test26 fun selectionRetainsAuthenticatedBeginRequestOriginWhenOemOmitsFinalRequest() {27 assertTrue(28 selectionOrigin(null, "https://github.com") == "https://github.com",29 )30 }3132 @Test33 fun selectionStillFailsClosedWithoutAnyVerifiedOrigin() {34 assertTrue(selectionOrigin(null, null) == null)35 assertTrue(selectionOrigin(" ", "") == null)36 }3738 @Test39 fun selectionRetainsAuthenticatedBeginRequestHashWhenOemOmitsFinalRequest() {40 val authenticatedHash = byteArrayOf(1, 2, 3)4142 assertTrue(selectionClientDataHash(null, authenticatedHash)!!.contentEquals(authenticatedHash))43 }4445 @Test46 fun selectionKeepsTheAuthenticatedBeginHashWhenSamsungReplacesFinalHash() {47 val frameworkHash = byteArrayOf(4, 5, 6)48 val authenticatedHash = byteArrayOf(1, 2, 3)4950 assertTrue(51 selectionClientDataHash(frameworkHash, authenticatedHash)!!52 .contentEquals(authenticatedHash),53 )54 }5556 @Test57 fun selectionKeepsFinalJsonForTheSignedAssertion() {58 val frameworkJson = """{"challenge":"final"}"""59 val authenticatedJson =60 """{"challenge":"begin","userVerification":"required"}"""6162 assertTrue(63 selectionRequestJson(frameworkJson, authenticatedJson) == frameworkJson,64 )65 }6667 @Test68 fun selectionUsesFinalJsonOnlyWithoutAuthenticatedBeginJson() {69 val frameworkJson = """{"challenge":"final"}"""7071 assertTrue(selectionRequestJson(frameworkJson, null) == frameworkJson)72 }7374 @Test75 fun authenticatedBeginJsonCanRequireUvWithoutReplacingFinalAssertionJson() {76 val frameworkJson = """{"challenge":"final"}"""77 val authenticatedJson =78 """{"challenge":"begin","userVerification":"required"}"""7980 assertTrue(selectionRequiresUserVerification(frameworkJson, authenticatedJson))81 assertTrue(selectionRequestJson(frameworkJson, authenticatedJson) == frameworkJson)82 }8384 @Test85 fun providerOffersAnExplicitManualPasskeyChooser() {86 val service = source("passkeys/PeachCredentialProviderService.kt")87 val unlock = source("credentials/CredentialProviderUnlockActivity.kt")88 val selection = source("passkeys/PasskeyCredentialSelectionActivity.kt")8990 assertTrue(service.contains("Choose another Peach passkey"))91 assertTrue(unlock.contains("Choose another Peach passkey"))92 assertTrue(selection.contains("retrieveBeginGetCredentialRequest(intent)"))93 assertTrue(selection.contains("PasskeyCredentialPlanner.candidates"))94 }9596 private fun source(relativePath: String): String =97 File("src/main/java/com/peachpasswords/$relativePath").readText()98}