From e50aab257802f41327d7b9183ec0dfaa46856225 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 29 Apr 2026 00:33:35 +0200 Subject: [PATCH] test(autosave): preserve text + mentionedPersons across save failure (B12) Locks in the behaviour added with the saveFn signature widening: a rejected save keeps the in-flight payload around so handleRetry resends it without the caller having to re-pass anything. Co-Authored-By: Claude Sonnet 4.6 --- .../__tests__/useBlockAutoSave.svelte.test.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/frontend/src/lib/hooks/__tests__/useBlockAutoSave.svelte.test.ts b/frontend/src/lib/hooks/__tests__/useBlockAutoSave.svelte.test.ts index 8e2633e0..93806949 100644 --- a/frontend/src/lib/hooks/__tests__/useBlockAutoSave.svelte.test.ts +++ b/frontend/src/lib/hooks/__tests__/useBlockAutoSave.svelte.test.ts @@ -71,6 +71,22 @@ describe('createBlockAutoSave', () => { expect(as.getSaveState('block-1')).toBe('saved'); }); + it('preserves the in-flight text + mentionedPersons across a save failure (B12)', async () => { + mockSaveFn.mockRejectedValueOnce(new Error('boom')); + mockSaveFn.mockResolvedValueOnce(undefined); + const as = createBlockAutoSave({ saveFn: mockSaveFn, documentId: 'doc-1' }); + + const mentions: PersonMention[] = [{ personId: 'p-aug', displayName: 'Auguste Raddatz' }]; + as.handleTextChange('block-1', '@Auguste Raddatz hi', mentions); + await vi.advanceTimersByTimeAsync(1500); + expect(as.getSaveState('block-1')).toBe('error'); + + // Retry without re-passing the data — the hook resends the preserved payload. + await as.handleRetry('block-1', 'should-not-be-used', []); + expect(mockSaveFn).toHaveBeenLastCalledWith('block-1', '@Auguste Raddatz hi', mentions); + expect(as.getSaveState('block-1')).toBe('saved'); + }); + it('clearBlock removes all state for a block', () => { const as = createBlockAutoSave({ saveFn: mockSaveFn, documentId: 'doc-1' }); as.handleTextChange('block-1', 'text', NO_MENTIONS);