From f479f7a66071bf9dc628a5bfe00455e2a806d360 Mon Sep 17 00:00:00 2001 From: han <2992336417@qq.com> Date: Wed, 10 Jun 2026 23:14:10 +0800 Subject: [PATCH] test: cover rewind selector fallback states (#4905) --- .../src/ui/components/RewindSelector.test.tsx | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/packages/cli/src/ui/components/RewindSelector.test.tsx b/packages/cli/src/ui/components/RewindSelector.test.tsx index 6ae676bcbf..1b3f5b6207 100644 --- a/packages/cli/src/ui/components/RewindSelector.test.tsx +++ b/packages/cli/src/ui/components/RewindSelector.test.tsx @@ -154,4 +154,88 @@ describe('RewindSelector', () => { expect(lastFrame()).toContain('› #2 second prompt'); expect(lastFrame()).not.toContain('Restore conversation only'); }); + + it('falls back to conversation-only options when diff stats fail', async () => { + vi.spyOn(fileHistoryService, 'getDiffStats').mockRejectedValue( + new Error('diff unavailable'), + ); + + const { lastFrame } = render( + , + ); + + pressKey({ name: 'return' }); + await flush(); + + expect(fileHistoryService.getDiffStats).toHaveBeenCalledWith('prompt-2'); + expect(lastFrame()).toContain('Restore conversation only'); + expect(lastFrame()).toContain('Never mind'); + expect(lastFrame()).toContain('File restore is unavailable for this turn'); + expect(lastFrame()).not.toContain('Restore code and conversation'); + expect(lastFrame()).not.toContain('Restore code only'); + }); + + it('does not request diff stats when the selected turn has no prompt id', async () => { + vi.spyOn(fileHistoryService, 'getDiffStats').mockResolvedValue({ + filesChanged: ['src/foo.ts'], + insertions: 2, + deletions: 0, + }); + + const { lastFrame } = render( + , + ); + + pressKey({ name: 'return' }); + await flush(); + + expect(fileHistoryService.getDiffStats).not.toHaveBeenCalled(); + expect(lastFrame()).toContain('Restore conversation only'); + expect(lastFrame()).toContain('Never mind'); + expect(lastFrame()).toContain('File restore is unavailable for this turn'); + expect(lastFrame()).not.toContain('Restore code and conversation'); + expect(lastFrame()).not.toContain('Restore code only'); + }); + + it('confirms a conversation-only rewind when checkpointing is disabled', () => { + const onRewind = vi.fn(); + + const { lastFrame } = render( + , + ); + + pressKey({ name: 'return' }); + + expect(lastFrame()).toContain( + 'This will remove all conversation after this turn.', + ); + + pressKey({ sequence: 'y' }); + + expect(onRewind).toHaveBeenCalledWith( + expect.objectContaining({ id: 2 }), + 'conversation', + ); + }); });