|
1 | | -import { togglePrep, toggleSpeech } from '@debatelab/core/free-tools/round-timer'; |
| 1 | +import { settlePrep, togglePrep, toggleSpeech } from '@debatelab/core/free-tools/round-timer'; |
2 | 2 | import { describe, expect, it } from 'vitest'; |
3 | 3 |
|
4 | 4 | import { |
|
7 | 7 | parseSavedFormats, |
8 | 8 | parseSession, |
9 | 9 | serializeSession, |
| 10 | + settleHeld, |
10 | 11 | timerActivityState, |
11 | 12 | timerAlertAt, |
12 | 13 | type TimerSession, |
@@ -71,9 +72,37 @@ describe('Live Activity buttons and the time-up alert', () => { |
71 | 72 | const paused = applyTimerActivityAction(session, 'toggle', T0 + 20_000); |
72 | 73 | expect(paused.round.prep.b.deadline).toBeNull(); |
73 | 74 | expect(paused.round.speech.startedAt).toBeNull(); |
74 | | - // With no prep running, the same button resumes the speech where it stopped. |
| 75 | + // The paused bank stays on the Lock Screen, so the same button restarts it, not the speech. |
75 | 76 | const resumed = applyTimerActivityAction(paused, 'toggle', T0 + 30_000); |
76 | | - expect(resumed.round.speech).toEqual({ elapsedMs: 10_000, startedAt: T0 + 30_000 }); |
| 77 | + expect(resumed.round.prep.b.deadline).not.toBeNull(); |
| 78 | + expect(resumed.round.speech).toEqual({ elapsedMs: 10_000, startedAt: null }); |
| 79 | + // With no bank held, it resumes the speech where it stopped. |
| 80 | + const speech = applyTimerActivityAction({ ...paused, held: null }, 'toggle', T0 + 30_000); |
| 81 | + expect(speech.round.speech).toEqual({ elapsedMs: 10_000, startedAt: T0 + 30_000 }); |
| 82 | + }); |
| 83 | + |
| 84 | + it('keeps a prep bank paused from the Lock Screen on it, so Resume restarts that prep', () => { |
| 85 | + let session = initialSession({ id: 'custom', custom }); |
| 86 | + session = { ...session, round: togglePrep(session.round, 'b', T0) }; |
| 87 | + const paused = applyTimerActivityAction(session, 'toggle', T0 + 30_000); |
| 88 | + const shown = timerActivityState(paused, T0 + 40_000, { ...text, controls: true }); |
| 89 | + expect(shown).toMatchObject({ kind: 'prep', side: 'b', pausedAt: T0 + 40_000, endsAt: T0 + 40_000 + 90_000 }); |
| 90 | + const resumed = applyTimerActivityAction(paused, 'toggle', T0 + 50_000); |
| 91 | + expect(resumed.round.prep.b.deadline).toBe(T0 + 50_000 + 90_000); |
| 92 | + expect(resumed.round.speech.startedAt).toBeNull(); |
| 93 | + }); |
| 94 | + |
| 95 | + it('lets go of a paused bank once another clock starts, it runs out, or the format changes', () => { |
| 96 | + let session = initialSession({ id: 'custom', custom }); |
| 97 | + session = { ...session, round: togglePrep(session.round, 'a', T0) }; |
| 98 | + const paused = applyTimerActivityAction(session, 'toggle', T0 + 10_000); |
| 99 | + expect(paused.held).toBe('a'); |
| 100 | + expect(settleHeld(paused, { ...paused, round: toggleSpeech(paused.round, T0 + 20_000) }).held).toBeUndefined(); |
| 101 | + expect(settleHeld(paused, { ...paused, choice: { id: 'bp' }, round: initialSession({ id: 'bp' }).round }).held).toBeUndefined(); |
| 102 | + const emptied = { ...session, round: settlePrep(session.round, T0 + 121_000) }; |
| 103 | + expect(settleHeld(session, emptied).held).toBeUndefined(); |
| 104 | + // Stored and read back with the round. |
| 105 | + expect(parseSession(JSON.parse(JSON.stringify(serializeSession(paused))))?.held).toBe('a'); |
77 | 106 | }); |
78 | 107 |
|
79 | 108 | it('moves on to a fresh, paused next speech, and not past the last one', () => { |
|
0 commit comments