import { describe, it, expect, vi, afterEach } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; import AnnotationSidePanel from './AnnotationSidePanel.svelte'; afterEach(() => { cleanup(); vi.restoreAllMocks(); }); vi.stubGlobal( 'fetch', vi.fn().mockResolvedValue({ ok: true, json: async () => [] }) ); const baseProps = { documentId: 'doc-1', activeAnnotationPage: 1, canComment: true, currentUserId: 'user-1', canAdmin: false, onClose: vi.fn() }; describe('AnnotationSidePanel – visibility', () => { it('is hidden (translated off-screen) when activeAnnotationId is null', async () => { render(AnnotationSidePanel, { ...baseProps, activeAnnotationId: null }); const panel = document.querySelector('[data-testid="annotation-side-panel"]'); expect(panel?.classList.contains('translate-x-full')).toBe(true); expect(panel?.classList.contains('translate-x-0')).toBe(false); }); it('is visible when activeAnnotationId is set', async () => { render(AnnotationSidePanel, { ...baseProps, activeAnnotationId: 'ann-1' }); const panel = document.querySelector('[data-testid="annotation-side-panel"]'); expect(panel?.classList.contains('translate-x-0')).toBe(true); expect(panel?.classList.contains('translate-x-full')).toBe(false); }); }); describe('AnnotationSidePanel – close button', () => { it('calls onClose when the close button is clicked', async () => { const onClose = vi.fn(); render(AnnotationSidePanel, { ...baseProps, activeAnnotationId: 'ann-1', onClose }); await page.getByRole('button', { name: /schließen/i }).click(); expect(onClose).toHaveBeenCalledOnce(); }); }); describe('AnnotationSidePanel – targetCommentId forwarding', () => { it('renders CommentThread when annotation is active', async () => { render(AnnotationSidePanel, { ...baseProps, activeAnnotationId: 'ann-1', targetCommentId: 'comment-42' }); // CommentThread renders inside the panel when activeAnnotationId is set const panel = document.querySelector('[data-testid="annotation-side-panel"]'); expect(panel).not.toBeNull(); expect(panel?.classList.contains('translate-x-0')).toBe(true); }); it('does not render CommentThread when annotation is null', async () => { render(AnnotationSidePanel, { ...baseProps, activeAnnotationId: null, targetCommentId: 'comment-42' }); // Panel is hidden and no fetch should have been triggered for comments const panel = document.querySelector('[data-testid="annotation-side-panel"]'); expect(panel?.classList.contains('translate-x-full')).toBe(true); }); });