import { describe, it, expect, afterEach } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; import AnnotationLayer from './AnnotationLayer.svelte'; afterEach(cleanup); type Annotation = { id: string; documentId: string; pageNumber: number; x: number; y: number; width: number; height: number; color: string; createdAt: string; }; function makeAnnotation(id = 'ann-1', color = '#00C7B1'): Annotation { return { id, documentId: 'doc-1', pageNumber: 1, x: 0.1, y: 0.1, width: 0.3, height: 0.2, color, createdAt: new Date().toISOString() }; } describe('AnnotationLayer', () => { it('renders a colored element for each annotation', async () => { render(AnnotationLayer, { annotations: [makeAnnotation('ann-1'), makeAnnotation('ann-2')], canDraw: false, color: '#00C7B1', onDraw: () => {} }); await expect.element(page.getByTestId('annotation-ann-1')).toBeInTheDocument(); await expect.element(page.getByTestId('annotation-ann-2')).toBeInTheDocument(); }); it('has crosshair cursor when canDraw is true', async () => { render(AnnotationLayer, { annotations: [], canDraw: true, color: '#00C7B1', onDraw: () => {} }); const container = document.querySelector('[role="presentation"]')!; expect(container.getAttribute('style')).toContain('cursor: crosshair'); }); it('does not have crosshair cursor when canDraw is false', async () => { render(AnnotationLayer, { annotations: [], canDraw: false, color: '#00C7B1', onDraw: () => {} }); const container = document.querySelector('[role="presentation"]')!; expect(container.getAttribute('style')).not.toContain('cursor: crosshair'); }); it('dims non-active annotations when activeAnnotationId is set', async () => { render(AnnotationLayer, { annotations: [makeAnnotation('ann-1'), makeAnnotation('ann-2')], canDraw: false, color: '#00C7B1', activeAnnotationId: 'ann-1', onDraw: () => {} }); const active = page.getByTestId('annotation-ann-1').element(); const dimmed = page.getByTestId('annotation-ann-2').element(); expect(active.style.opacity).toBe('1'); expect(dimmed.style.opacity).toBe('0.3'); }); it('shows all annotations at full opacity when no activeAnnotationId', async () => { render(AnnotationLayer, { annotations: [makeAnnotation('ann-1'), makeAnnotation('ann-2')], canDraw: false, color: '#00C7B1', onDraw: () => {} }); const el1 = page.getByTestId('annotation-ann-1').element(); const el2 = page.getByTestId('annotation-ann-2').element(); expect(el1.style.opacity).toBe('1'); expect(el2.style.opacity).toBe('1'); }); it('does not show delete buttons (annotations owned by blocks)', async () => { render(AnnotationLayer, { annotations: [makeAnnotation('ann-1')], canDraw: true, color: '#00C7B1', onDraw: () => {} }); await expect.element(page.getByTestId('annotation-ann-1')).toBeInTheDocument(); expect(page.getByRole('button', { name: /löschen/i }).query()).toBeNull(); }); });