feat(planner): add UndoBar component with 4s auto-dismiss
Shows undo notification after slot add/replace. Rückgängig button calls onundo, auto-dismisses after 4s via ondismiss callback. Also patches test-setup for userEvent + fake timers compatibility. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
56
frontend/src/lib/planner/UndoBar.test.ts
Normal file
56
frontend/src/lib/planner/UndoBar.test.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||
import { render, screen, act } from '@testing-library/svelte';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import UndoBar from './UndoBar.svelte';
|
||||
|
||||
describe('UndoBar', () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it('is not mounted when visible is false', () => {
|
||||
render(UndoBar, { props: { visible: false, message: 'Test', onundo: vi.fn(), ondismiss: vi.fn() } });
|
||||
expect(screen.queryByTestId('undo-bar')).toBeNull();
|
||||
});
|
||||
|
||||
it('is mounted and shows message when visible is true', () => {
|
||||
render(UndoBar, { props: { visible: true, message: 'Gericht hinzugefügt', onundo: vi.fn(), ondismiss: vi.fn() } });
|
||||
expect(screen.getByTestId('undo-bar')).toBeTruthy();
|
||||
expect(screen.getByText('Gericht hinzugefügt')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('shows Rückgängig button', () => {
|
||||
render(UndoBar, { props: { visible: true, message: 'Test', onundo: vi.fn(), ondismiss: vi.fn() } });
|
||||
expect(screen.getByRole('button', { name: /Rückgängig/i })).toBeTruthy();
|
||||
});
|
||||
|
||||
it('calls onundo when Rückgängig is clicked', async () => {
|
||||
const onundo = vi.fn();
|
||||
render(UndoBar, { props: { visible: true, message: 'Test', onundo, ondismiss: vi.fn() } });
|
||||
await userEvent.click(screen.getByRole('button', { name: /Rückgängig/i }));
|
||||
expect(onundo).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it('calls ondismiss after 4 seconds', async () => {
|
||||
const ondismiss = vi.fn();
|
||||
render(UndoBar, { props: { visible: true, message: 'Test', onundo: vi.fn(), ondismiss } });
|
||||
await act(() => { vi.advanceTimersByTime(4000); });
|
||||
expect(ondismiss).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it('does not call ondismiss before 4 seconds', async () => {
|
||||
const ondismiss = vi.fn();
|
||||
render(UndoBar, { props: { visible: true, message: 'Test', onundo: vi.fn(), ondismiss } });
|
||||
await act(() => { vi.advanceTimersByTime(3999); });
|
||||
expect(ondismiss).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('has role="status" for accessibility', () => {
|
||||
render(UndoBar, { props: { visible: true, message: 'Test', onundo: vi.fn(), ondismiss: vi.fn() } });
|
||||
expect(screen.getByRole('status')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user