package com.peachpasswords.sync import kotlinx.coroutines.async import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test /** * PB-26-116: the vault-owning device must approve a pairing before the root key * is read. The historical defect was a consent callback that returned true as * soon as the SAS had been displayed, so nothing on the source side ever asked. */ @OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class) class SourceConsentGateTest { @Test fun a_grant_waits_until_someone_decides() = runTest { val gate = SourceConsentGate() val decision = async { gate.await() } runCurrent() assertFalse("must not approve before a decision exists", decision.isCompleted) gate.resolve(true) assertTrue(decision.await()) } @Test fun leaving_the_screen_denies_rather_than_hanging() = runTest { val gate = SourceConsentGate() val decision = async { gate.await() } runCurrent() gate.resolve(false) assertFalse(decision.await()) } @Test fun an_answer_with_no_live_prompt_is_ignored() = runTest { val gate = SourceConsentGate() gate.resolve(true) val decision = async { gate.await() } runCurrent() assertFalse("a stale answer must not pre-approve a later prompt", decision.isCompleted) decision.cancel() } }