import { describe, it, expect, vi } from 'vitest'; import { render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; import TranscriptionPanelHeader from './TranscriptionPanelHeader.svelte'; describe('TranscriptionPanelHeader', () => { it('should render Lesen and Bearbeiten buttons', async () => { render(TranscriptionPanelHeader, { mode: 'read', hasBlocks: true, blockCount: 3, lastEditedAt: null, onModeChange: () => {}, onClose: () => {} }); await expect.element(page.getByText('Lesen')).toBeInTheDocument(); await expect.element(page.getByText('Bearbeiten')).toBeInTheDocument(); }); it('should disable Lesen button when hasBlocks is false', async () => { render(TranscriptionPanelHeader, { mode: 'edit', hasBlocks: false, blockCount: 0, lastEditedAt: null, onModeChange: () => {}, onClose: () => {} }); const lesenBtn = document.querySelector('[data-testid="mode-read"]') as HTMLButtonElement; expect(lesenBtn.getAttribute('aria-disabled')).toBe('true'); }); it('should call onModeChange when clicking Bearbeiten', async () => { const onModeChange = vi.fn(); render(TranscriptionPanelHeader, { mode: 'read', hasBlocks: true, blockCount: 3, lastEditedAt: null, onModeChange, onClose: () => {} }); const editBtn = document.querySelector('[data-testid="mode-edit"]')!; editBtn.dispatchEvent(new MouseEvent('click', { bubbles: true })); expect(onModeChange).toHaveBeenCalledWith('edit'); }); it('should not call onModeChange when clicking disabled Lesen', async () => { const onModeChange = vi.fn(); render(TranscriptionPanelHeader, { mode: 'edit', hasBlocks: false, blockCount: 0, lastEditedAt: null, onModeChange, onClose: () => {} }); const readBtn = document.querySelector('[data-testid="mode-read"]')!; readBtn.dispatchEvent(new MouseEvent('click', { bubbles: true })); expect(onModeChange).not.toHaveBeenCalled(); }); it('should call onClose when clicking close button', async () => { const onClose = vi.fn(); render(TranscriptionPanelHeader, { mode: 'read', hasBlocks: true, blockCount: 3, lastEditedAt: null, onModeChange: () => {}, onClose }); const closeBtn = document.querySelector('[data-testid="panel-close"]')!; closeBtn.dispatchEvent(new MouseEvent('click', { bubbles: true })); expect(onClose).toHaveBeenCalled(); }); it('should show singular block count for 1 block', async () => { render(TranscriptionPanelHeader, { mode: 'read', hasBlocks: true, blockCount: 1, lastEditedAt: null, onModeChange: () => {}, onClose: () => {} }); await expect.element(page.getByText('1 Abschnitt')).toBeInTheDocument(); }); it('should show plural block count for multiple blocks', async () => { render(TranscriptionPanelHeader, { mode: 'read', hasBlocks: true, blockCount: 5, lastEditedAt: null, onModeChange: () => {}, onClose: () => {} }); await expect.element(page.getByText('5 Abschnitte')).toBeInTheDocument(); }); it('should show "0 Abschnitte" when blockCount is 0', async () => { render(TranscriptionPanelHeader, { mode: 'edit', hasBlocks: false, blockCount: 0, lastEditedAt: null, onModeChange: () => {}, onClose: () => {} }); await expect.element(page.getByText('0 Abschnitte')).toBeInTheDocument(); }); it('should have close button with 44px touch target classes', async () => { render(TranscriptionPanelHeader, { mode: 'read', hasBlocks: true, blockCount: 3, lastEditedAt: null, onModeChange: () => {}, onClose: () => {} }); const closeBtn = document.querySelector('[data-testid="panel-close"]') as HTMLElement; expect(closeBtn.classList.contains('h-11')).toBe(true); expect(closeBtn.classList.contains('w-11')).toBe(true); }); it('should show formatted date when lastEditedAt is provided', async () => { render(TranscriptionPanelHeader, { mode: 'read', hasBlocks: true, blockCount: 3, lastEditedAt: '2026-04-07T10:00:00Z', onModeChange: () => {}, onClose: () => {} }); const statusText = document.querySelector('.hidden.md\\:block'); expect(statusText).not.toBeNull(); expect(statusText!.textContent).toContain('2026'); }); });