refactor: move shared utilities to lib/shared/ sub-packages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
|
||||
// Capture the beforeNavigate callback so tests can simulate navigation events
|
||||
let registeredBeforeNavigate:
|
||||
| ((nav: { cancel: () => void; to: { url: { href: string } } | null }) => void)
|
||||
| null = null;
|
||||
|
||||
const mockGoto = vi.fn();
|
||||
|
||||
vi.mock('$app/navigation', () => ({
|
||||
beforeNavigate: vi.fn((fn: typeof registeredBeforeNavigate) => {
|
||||
registeredBeforeNavigate = fn;
|
||||
}),
|
||||
goto: mockGoto
|
||||
}));
|
||||
|
||||
const { createUnsavedWarning } = await import('../useUnsavedWarning.svelte');
|
||||
|
||||
function simulateNavigate(href: string | null = '/somewhere') {
|
||||
const cancel = vi.fn();
|
||||
registeredBeforeNavigate?.({
|
||||
cancel,
|
||||
to: href ? { url: { href } } : null
|
||||
});
|
||||
return cancel;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
registeredBeforeNavigate = null;
|
||||
mockGoto.mockClear();
|
||||
});
|
||||
|
||||
describe('createUnsavedWarning', () => {
|
||||
it('isDirty starts false', () => {
|
||||
const w = createUnsavedWarning();
|
||||
expect(w.isDirty).toBe(false);
|
||||
});
|
||||
|
||||
it('markDirty sets isDirty to true', () => {
|
||||
const w = createUnsavedWarning();
|
||||
w.markDirty();
|
||||
expect(w.isDirty).toBe(true);
|
||||
});
|
||||
|
||||
it('markDirty hides any existing warning banner', () => {
|
||||
const w = createUnsavedWarning();
|
||||
// Simulate a navigation event that showed the banner
|
||||
w.markDirty();
|
||||
simulateNavigate();
|
||||
expect(w.showUnsavedWarning).toBe(true);
|
||||
// Typing again should hide the banner (form input re-triggers markDirty)
|
||||
w.markDirty();
|
||||
expect(w.showUnsavedWarning).toBe(false);
|
||||
});
|
||||
|
||||
it('beforeNavigate cancels and shows banner when dirty', () => {
|
||||
const w = createUnsavedWarning();
|
||||
w.markDirty();
|
||||
const cancel = simulateNavigate('/admin/users');
|
||||
expect(cancel).toHaveBeenCalled();
|
||||
expect(w.showUnsavedWarning).toBe(true);
|
||||
});
|
||||
|
||||
it('beforeNavigate stores the target URL', () => {
|
||||
const w = createUnsavedWarning();
|
||||
w.markDirty();
|
||||
simulateNavigate('/admin/users');
|
||||
expect(w.discardTarget).toBe('/admin/users');
|
||||
});
|
||||
|
||||
it('beforeNavigate does not cancel when not dirty', () => {
|
||||
createUnsavedWarning();
|
||||
const cancel = simulateNavigate('/admin/users');
|
||||
expect(cancel).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('discard resets state and navigates to target', () => {
|
||||
const w = createUnsavedWarning();
|
||||
w.markDirty();
|
||||
simulateNavigate('/admin/tags');
|
||||
w.discard();
|
||||
expect(w.isDirty).toBe(false);
|
||||
expect(w.showUnsavedWarning).toBe(false);
|
||||
expect(mockGoto).toHaveBeenCalledWith('/admin/tags');
|
||||
});
|
||||
|
||||
it('clearOnSuccess resets isDirty and warning', () => {
|
||||
const w = createUnsavedWarning();
|
||||
w.markDirty();
|
||||
simulateNavigate('/somewhere');
|
||||
w.clearOnSuccess();
|
||||
expect(w.isDirty).toBe(false);
|
||||
expect(w.showUnsavedWarning).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user