import { fireEvent, render, screen } from '@testing-library/svelte'; import { describe, expect, it, test, vi } from 'vitest'; import NameItemEditor from '$lib/components/NameItemEditor.svelte'; import { baseData } from '../fixtures'; const testCrimesListIndex = 0; const testItem = baseData.crimesList[testCrimesListIndex]; const testCurrentName = testItem.name; const testLocalName = 'Fall-C'; describe('NameItemEditor - Funktionalität', () => { const onSave = vi.fn(); const onDelete = vi.fn(); const baseProps = { list: baseData.crimesList, currentName: testCurrentName, onSave, onDelete }; test.todo('FocusIn nach Klick auf edit'); it('zeigt initial Edit/Delete Buttons und aktuellen Namen', () => { render(NameItemEditor, { props: baseProps }); expect(screen.getByTestId('edit-button')).toBeInTheDocument(); expect(screen.getByTestId('delete-button')).toBeInTheDocument(); expect(screen.queryByTestId('commit-button')).toBeNull(); expect(screen.queryByTestId('cancel-button')).toBeNull(); expect(screen.getByText(testCurrentName)).toBeInTheDocument(); }); it('wechselt zu Commit/Cancel nach Klick auf Edit', async () => { render(NameItemEditor, { props: baseProps }); await fireEvent.click(screen.getByTestId('edit-button')); const input = screen.getByTestId('test-input'); expect(screen.getByTestId('commit-button')).toBeInTheDocument(); expect(screen.getByTestId('cancel-button')).toBeInTheDocument(); expect(screen.queryByTestId('edit-button')).toBeNull(); expect(screen.queryByTestId('delete-button')).toBeNull(); expect(screen.getAllByRole('textbox')).toHaveLength(1); expect(input).toHaveValue(testCurrentName); }); it('zeigt Fehlermeldung bei leerem Namen', async () => { render(NameItemEditor, { props: baseProps }); await fireEvent.click(screen.getByTestId('edit-button')); const input = screen.getByTestId('test-input'); await fireEvent.input(input, { target: { value: '' } }); expect(screen.getByText('Name darf nicht leer sein.')).toBeInTheDocument(); expect(onSave).not.toHaveBeenCalled(); }); it('entfernt Fehlermeldung live beim nächsten gültigen Tastendruck', async () => { render(NameItemEditor, { props: { list: baseData.crimesList, currentName: baseData.crimesList[0].name, onSave: vi.fn(), onDelete: vi.fn() } }); await fireEvent.click(screen.getByTestId('edit-button')); const input = screen.getByTestId('test-input'); await fireEvent.input(input, { target: { value: '' } }); expect(screen.getByText('Name darf nicht leer sein.')).toBeInTheDocument(); await fireEvent.input(input, { target: { value: 'Fall-C' } }); expect(screen.queryByText('Name darf nicht leer sein.')).toBeNull(); }); it('zeigt Fehlermeldung bei Duplikat', async () => { const duplicateName = baseData.crimesList[1].name; render(NameItemEditor, { props: baseProps }); await fireEvent.click(screen.getByTestId('edit-button')); const input = screen.getByTestId('test-input'); await fireEvent.input(input, { target: { value: duplicateName } }); expect(screen.getByText('Name existiert bereits.')).toBeInTheDocument(); expect(onSave).not.toHaveBeenCalled(); }); it('ruft onSave korrekt auf bei gültigem Namen', async () => { render(NameItemEditor, { props: baseProps }); await fireEvent.click(screen.getByTestId('edit-button')); const input = screen.getByTestId('test-input'); await fireEvent.input(input, { target: { value: testLocalName } }); await fireEvent.click(screen.getByTestId('commit-button')); expect(onSave).toHaveBeenCalledWith(testLocalName, testCurrentName); }); it('ruft onDelete korrekt auf', async () => { render(NameItemEditor, { props: baseProps }); await fireEvent.click(screen.getByTestId('delete-button')); expect(onDelete).toHaveBeenCalledWith(testCurrentName); }); it('setzt Zustand zurück bei Cancel', async () => { render(NameItemEditor, { props: baseProps }); await fireEvent.click(screen.getByTestId('edit-button')); const input = screen.getByTestId('test-input'); await fireEvent.input(input, { target: { value: 'Zwischentext' } }); await fireEvent.click(screen.getByTestId('cancel-button')); expect(screen.getByText(testCurrentName)).toBeInTheDocument(); expect(screen.getByTestId('edit-button')).toBeInTheDocument(); }); it('triggert Save bei Enter-Taste', async () => { render(NameItemEditor, { props: baseProps }); await fireEvent.click(screen.getByTestId('edit-button')); const input = screen.getByTestId('test-input'); await fireEvent.input(input, { target: { value: 'ViaEnter' } }); await fireEvent.keyDown(input, { key: 'Enter' }); expect(onSave).toHaveBeenCalledWith('ViaEnter', testCurrentName); }); it('bricht ab bei Escape-Taste', async () => { render(NameItemEditor, { props: baseProps }); await fireEvent.click(screen.getByTestId('edit-button')); const input = screen.getByTestId('test-input'); await fireEvent.input(input, { target: { value: 'Zwischentext' } }); await fireEvent.keyDown(input, { key: 'Escape' }); expect(screen.getByText(testCurrentName)).toBeInTheDocument(); expect(onSave).not.toHaveBeenCalled(); }); });