fix(reaction): Refresh CA keep-alive timestamp so long conversations resume

This commit is contained in:
darken
2026-06-18 12:07:19 +02:00
committed by Matthias Urhahn
parent 246b96bfb4
commit 5c5cc6f28e
2 changed files with 43 additions and 3 deletions
@@ -448,6 +448,32 @@ class ConversationReactionTest : BaseTest() {
job.cancel()
}
@Test
fun `PAUSE resumes on the terminal even after a conversation longer than the resume window`() =
runTest(UnconfinedTestDispatcher()) {
// Each keep-alive frame refreshes the activity timestamp, so PAUSE_RESUME_WINDOW is
// measured from the last frame — not from engage. Without that refresh a 3-minute
// conversation would fail the age guard and strand media paused on its real terminal.
// Advance BOTH clocks so the window is genuinely exercised (the TestTimeSource drives age).
devicesFlow.value = listOf(mockPodDevice(primaryAddress, ConversationAction.PAUSE))
val job = launchReaction()
emit(primaryAddress, ConversationAwarenessEvent.START)
coVerify(exactly = 1) { mediaControl.sendPause(false) }
repeat(3) {
timeSource.advanceBy(java.time.Duration.ofSeconds(60))
advanceTimeBy(60_000) // < STALE_TIMEOUT, so the backstop never fires
runCurrent()
emit(primaryAddress, ConversationAwarenessEvent.RESUME) // keep-alive, refreshes `at`
}
coVerify(exactly = 0) { mediaControl.sendPlay() } // 3 min in, still paused
emit(primaryAddress, ConversationAwarenessEvent.STOP) // terminal right after last activity
coVerify(exactly = 1) { mediaControl.sendPlay() }
job.cancel()
}
@Test
fun `RESUME without a prior start is a no-op`() = runTest(UnconfinedTestDispatcher()) {
devicesFlow.value = listOf(mockPodDevice(primaryAddress, ConversationAction.PAUSE))