Files
webmail/lib/compose/__tests__/draft-close-toast.test.ts
T
Linus Rath d98132b8e1 fix: close every composer the same way, keeping the draft with Draft saved and Discard
X, Escape, clicking another message and Escape in a pop-out window
now all save the draft and close, with a "Draft saved" toast that has
Discard (with Undo). The Save or discard question shows only when that
save fails. A Reply or Forward closed before the user changed anything
leaves no draft. Undo send being on by default no longer asks "Send
without a delay?" on servers without delayed sending; only a delay the
user picked does.

Changed test assertions: the close-guard, priority, account-switch,
threading, sign-out, mention, draft-attachments, discard-uploads and
save-pending-attachments tests reached saving or discarding through the
Save or discard dialog on close, which now only appears after a failed
save. They now close directly, or use the Discard button, or check the
failed-save question. The send-delay test marks its delay as chosen.
2026-11-04 08:22:56 +01:00

58 lines
2.0 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { discardWithUndo, showDraftSavedToast } from '../draft-close-toast';
import { useToastStore } from '@/stores/toast-store';
const labels = { saved: 'Draft saved', discard: 'Discard', discarded: 'Draft discarded', undo: 'Undo' };
const shown = () => useToastStore.getState().toasts;
describe('closing a composer that kept its draft', () => {
beforeEach(() => {
vi.useFakeTimers();
useToastStore.getState().clearToasts();
});
afterEach(() => {
vi.useRealTimers();
useToastStore.getState().clearToasts();
});
it('says "Draft saved" and offers Discard', () => {
const discard = vi.fn();
showDraftSavedToast(discard, labels);
expect(shown()).toHaveLength(1);
expect(shown()[0].title).toBe('Draft saved');
expect(shown()[0].action?.label).toBe('Discard');
expect(discard).not.toHaveBeenCalled();
});
it('deletes only once the Undo window is over', () => {
const discard = vi.fn();
showDraftSavedToast(discard, labels);
shown()[0].action!.onClick();
const undoToast = shown().find((t) => t.title === 'Draft discarded')!;
expect(undoToast.action?.label).toBe('Undo');
expect(undoToast.pauseOnHover).toBe(false);
expect(discard).not.toHaveBeenCalled();
vi.advanceTimersByTime(undoToast.duration!);
expect(discard).toHaveBeenCalledTimes(1);
});
it('keeps the draft on Undo and puts back what was taken away', () => {
const discard = vi.fn();
const restore = vi.fn();
discardWithUndo(discard, labels, restore);
shown()[0].action!.onClick();
vi.advanceTimersByTime(60_000);
expect(discard).not.toHaveBeenCalled();
expect(restore).toHaveBeenCalledTimes(1);
});
it('deletes at once when the page goes away during the Undo window', () => {
const discard = vi.fn();
discardWithUndo(discard, labels);
window.dispatchEvent(new Event('pagehide'));
expect(discard).toHaveBeenCalledTimes(1);
vi.advanceTimersByTime(60_000);
expect(discard).toHaveBeenCalledTimes(1);
});
});