Extract ScheduleScreen from App.tsx into screens/SchedulesScreen.tsx + schedules/ domain folder (itemRules, pickers, inspector, ScheduleForm). Draft model with explicit Save (single destructive PUT), Discard, dirty guard (navigationGuard + beforeunload), schedule CRUD, and all Blazor item fields/gates/resets. Rewrite api/schedules.ts to the flat DTO + CRUD + languages/filler-by-kind pickers. Live TopBar Add Schedule via a window CustomEvent. Screen + nav-guard tests; App.test updated for the extracted screen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
33 lines
1.1 KiB
TypeScript
33 lines
1.1 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
import { canLeaveCurrentScreen, registerNavigationGuard } from './navigationGuard';
|
|
|
|
afterEach(() => {
|
|
// ensure no guard leaks between tests
|
|
const unregister = registerNavigationGuard(() => true);
|
|
unregister();
|
|
});
|
|
|
|
describe('navigationGuard', () => {
|
|
it('allows navigation when no guard is registered', () => {
|
|
expect(canLeaveCurrentScreen()).toBe(true);
|
|
});
|
|
|
|
it('consults the registered guard', () => {
|
|
const guard = vi.fn(() => false);
|
|
const unregister = registerNavigationGuard(guard);
|
|
expect(canLeaveCurrentScreen()).toBe(false);
|
|
expect(guard).toHaveBeenCalledTimes(1);
|
|
unregister();
|
|
expect(canLeaveCurrentScreen()).toBe(true);
|
|
});
|
|
|
|
it('unregister only clears its own guard', () => {
|
|
const first = registerNavigationGuard(() => false);
|
|
const secondGuard = vi.fn(() => false);
|
|
registerNavigationGuard(secondGuard);
|
|
first(); // stale unregister must not clear the second guard
|
|
expect(canLeaveCurrentScreen()).toBe(false);
|
|
expect(secondGuard).toHaveBeenCalled();
|
|
});
|
|
});
|