import { afterEach, describe, expect, it, vi } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page, userEvent } from 'vitest/browser'; import { createRawSnippet } from 'svelte'; vi.mock('$env/static/public', () => ({ PUBLIC_NOTIFICATION_POLL_MS: '60000' })); afterEach(cleanup); const emptySnippet = createRawSnippet(() => ({ render: () => '' })); import Layout from './+layout.svelte'; const tick = () => new Promise((r) => setTimeout(r, 0)); // Minimal data required by the layout const makeData = (overrides = {}) => ({ user: { id: '1', username: 'max', firstName: 'Max', lastName: 'Müller', groups: [], enabled: true, createdAt: '' }, canWrite: true, canAnnotate: false, ...overrides }); // ─── User avatar ────────────────────────────────────────────────────────────── describe('Layout – user avatar button', () => { it('shows user initials when first and last name are set', async () => { render(Layout, { data: makeData(), children: emptySnippet }); await expect.element(page.getByRole('button', { name: /MM/ })).toBeInTheDocument(); }); it('shows fallback icon button when names are not set', async () => { render(Layout, { data: makeData({ user: { id: '1', username: 'x', groups: [], enabled: true, createdAt: '' } }), children: emptySnippet }); // Button should still exist (with aria-label for accessibility) await expect.element(page.getByRole('button', { name: /Profil/i })).toBeInTheDocument(); }); }); // ─── Dropdown ───────────────────────────────────────────────────────────────── describe('Layout – user dropdown', () => { it('dropdown is hidden initially', async () => { render(Layout, { data: makeData(), children: emptySnippet }); await tick(); await expect.element(page.getByRole('link', { name: /Profil/i })).not.toBeInTheDocument(); }); it('opens dropdown on button click', async () => { render(Layout, { data: makeData(), children: emptySnippet }); await page.getByRole('button', { name: /MM/ }).click(); await expect.element(page.getByRole('link', { name: /Profil/i })).toBeInTheDocument(); }); it('profile link points to /profile', async () => { render(Layout, { data: makeData(), children: emptySnippet }); await page.getByRole('button', { name: /MM/ }).click(); await expect .element(page.getByRole('link', { name: /Profil/i })) .toHaveAttribute('href', '/profile'); }); it('logout button is in the dropdown', async () => { render(Layout, { data: makeData(), children: emptySnippet }); await page.getByRole('button', { name: /MM/ }).click(); await expect.element(page.getByRole('button', { name: /Abmelden/i })).toBeInTheDocument(); }); it('closes dropdown when Escape is pressed', async () => { render(Layout, { data: makeData(), children: emptySnippet }); const btn = page.getByRole('button', { name: /MM/ }); await btn.click(); await expect.element(page.getByRole('link', { name: /Profil/i })).toBeInTheDocument(); await userEvent.keyboard('{Escape}'); await tick(); await expect.element(page.getByRole('link', { name: /Profil/i })).not.toBeInTheDocument(); }); });