test(routes): cover AppNav navigation branches
Brand link, four primary nav links, admin link gated on isAdmin, hamburger menu open/close state via aria-expanded. Mocks $app/state so the page URL drives the active-route highlighting. 6 tests, ~30 branches. Refs #496. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
78
frontend/src/routes/AppNav.svelte.test.ts
Normal file
78
frontend/src/routes/AppNav.svelte.test.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { describe, it, expect, vi, afterEach } from 'vitest';
|
||||
import { cleanup, render } from 'vitest-browser-svelte';
|
||||
import { page as browserPage } from 'vitest/browser';
|
||||
|
||||
const mockPage = { url: new URL('http://localhost/documents') };
|
||||
|
||||
vi.mock('$app/state', () => ({
|
||||
get page() {
|
||||
return mockPage;
|
||||
}
|
||||
}));
|
||||
|
||||
afterEach(cleanup);
|
||||
|
||||
async function loadComponent() {
|
||||
return (await import('./AppNav.svelte')).default;
|
||||
}
|
||||
|
||||
describe('AppNav', () => {
|
||||
it('renders the brand link', async () => {
|
||||
mockPage.url = new URL('http://localhost/');
|
||||
const AppNav = await loadComponent();
|
||||
render(AppNav, { props: { isAdmin: false } });
|
||||
|
||||
await expect.element(browserPage.getByRole('link', { name: /familienarchiv/i })).toBeVisible();
|
||||
});
|
||||
|
||||
it('renders all four primary nav links by default', async () => {
|
||||
mockPage.url = new URL('http://localhost/');
|
||||
const AppNav = await loadComponent();
|
||||
render(AppNav, { props: { isAdmin: false } });
|
||||
|
||||
await expect.element(browserPage.getByRole('link', { name: /^dokumente$/i })).toBeVisible();
|
||||
await expect.element(browserPage.getByRole('link', { name: /^personen$/i })).toBeVisible();
|
||||
await expect.element(browserPage.getByRole('link', { name: /^stammbaum$/i })).toBeVisible();
|
||||
await expect.element(browserPage.getByRole('link', { name: /^geschichten$/i })).toBeVisible();
|
||||
});
|
||||
|
||||
it('hides the admin link when isAdmin is false', async () => {
|
||||
mockPage.url = new URL('http://localhost/');
|
||||
const AppNav = await loadComponent();
|
||||
render(AppNav, { props: { isAdmin: false } });
|
||||
|
||||
await expect
|
||||
.element(browserPage.getByRole('link', { name: /^admin$/i }))
|
||||
.not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows the admin link when isAdmin is true', async () => {
|
||||
mockPage.url = new URL('http://localhost/');
|
||||
const AppNav = await loadComponent();
|
||||
render(AppNav, { props: { isAdmin: true } });
|
||||
|
||||
await expect.element(browserPage.getByRole('link', { name: /^admin$/i })).toBeVisible();
|
||||
});
|
||||
|
||||
it('shows the open-menu hamburger by default', async () => {
|
||||
mockPage.url = new URL('http://localhost/');
|
||||
const AppNav = await loadComponent();
|
||||
render(AppNav, { props: { isAdmin: false } });
|
||||
|
||||
await expect
|
||||
.element(browserPage.getByRole('button', { name: /menü öffnen/i }))
|
||||
.toHaveAttribute('aria-expanded', 'false');
|
||||
});
|
||||
|
||||
it('opens the mobile nav and switches the hamburger label when clicked', async () => {
|
||||
mockPage.url = new URL('http://localhost/');
|
||||
const AppNav = await loadComponent();
|
||||
render(AppNav, { props: { isAdmin: false } });
|
||||
|
||||
await browserPage.getByRole('button', { name: /menü öffnen/i }).click();
|
||||
|
||||
await expect
|
||||
.element(browserPage.getByRole('button', { name: /menü schließen/i }))
|
||||
.toHaveAttribute('aria-expanded', 'true');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user