PeachClipboardTest.kt

2.3 KB · raw

1package com.peachpasswords.shared23import kotlinx.coroutines.CoroutineScope4import kotlinx.coroutines.test.StandardTestDispatcher5import kotlinx.coroutines.test.advanceTimeBy6import kotlinx.coroutines.test.runCurrent7import kotlinx.coroutines.test.runTest8import org.junit.Assert.assertEquals9import org.junit.Assert.assertFalse10import org.junit.Assert.assertTrue11import org.junit.Test1213/**14 * MF-8: a sensitive copy auto-clears after 30s — but only if our value is still on15 * the clipboard. Drives the pure [PeachClipboard.scheduleClear] seam on a virtual16 * scheduler (the Android ClipboardManager is faked with a plain string box).17 */18class PeachClipboardTest {1920    @Test fun clears_after_delay_when_value_unchanged() = runTest {21        var clipboard: String? = "s3cret"22        PeachClipboard.scheduleClear(23            scope = CoroutineScope(StandardTestDispatcher(testScheduler)),24            expected = "s3cret",25            readCurrent = { clipboard },26            clear = { clipboard = "" },27        )28        advanceTimeBy(PeachClipboard.CLEAR_DELAY_MS - 1_000); runCurrent()29        assertEquals("not cleared before the window elapses", "s3cret", clipboard)30        advanceTimeBy(2_000); runCurrent()31        assertEquals("cleared once the 30s window elapses", "", clipboard)32    }3334    @Test fun does_not_clear_when_user_copied_something_else() = runTest {35        var clipboard: String? = "s3cret"36        var cleared = false37        PeachClipboard.scheduleClear(38            scope = CoroutineScope(StandardTestDispatcher(testScheduler)),39            expected = "s3cret",40            readCurrent = { clipboard },41            clear = { cleared = true },42        )43        clipboard = "user typed this after copying" // user copied something else within 30s44        advanceTimeBy(PeachClipboard.CLEAR_DELAY_MS + 1_000); runCurrent()45        assertFalse("must never wipe what the user copied afterwards", cleared)46        assertEquals("user typed this after copying", clipboard)47    }4849    @Test fun thirty_second_default_matches_browser() {50        assertTrue(PeachClipboard.CLEAR_DELAY_MS == 30_000L)51    }5253    @Test fun copy_feedback_bus_pulses_monotonically() {54        val before = CopyFeedbackBus.pulses.value55        CopyFeedbackBus.pulse()56        CopyFeedbackBus.pulse()5758        assertEquals(before + 2, CopyFeedbackBus.pulses.value)59    }60}