test: cover DashboardFamilyPulse and UserMenu branches

DashboardFamilyPulse: null-pulse early return, eyebrow always shown,
headline gated on pages>0, you-line gated on yourPages>0, contributor
chips visibility, count tile rendering.

UserMenu: avatar button vs icon-only branch, aria-expanded matrix,
menu open/close, profile link + logout form rendering, POST/logout
form attributes.

14 tests covering ~30 branches.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-10 00:37:15 +02:00
parent 9af2b27b83
commit 8f15eea78d
2 changed files with 142 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
import { describe, it, expect, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import DashboardFamilyPulse from './DashboardFamilyPulse.svelte';
afterEach(cleanup);
const basePulse = (overrides: Record<string, unknown> = {}) => ({
pages: 0,
yourPages: 0,
contributors: [] as { initials: string; color: string; name?: string | null }[],
annotated: 0,
transcribed: 0,
uploaded: 0,
reviewed: 0,
...overrides
});
describe('DashboardFamilyPulse', () => {
it('renders nothing when pulse is null', async () => {
render(DashboardFamilyPulse, { props: { pulse: null } });
expect(document.querySelector('section')).toBeNull();
});
it('renders the eyebrow when pulse is not null', async () => {
render(DashboardFamilyPulse, { props: { pulse: basePulse() } });
await expect.element(page.getByText('Diese Woche')).toBeVisible();
});
it('hides the headline when pages is 0', async () => {
render(DashboardFamilyPulse, { props: { pulse: basePulse({ pages: 0 }) } });
await expect.element(page.getByRole('heading')).not.toBeInTheDocument();
});
it('renders the headline when pages > 0', async () => {
render(DashboardFamilyPulse, { props: { pulse: basePulse({ pages: 12 }) } });
await expect.element(page.getByText(/12 Seiten bearbeitet/)).toBeVisible();
});
it('renders the "you" line only when yourPages > 0', async () => {
render(DashboardFamilyPulse, { props: { pulse: basePulse({ yourPages: 3 }) } });
await expect.element(page.getByText(/3 davon bearbeitet/)).toBeVisible();
});
it('omits the contributors section when there are none', async () => {
render(DashboardFamilyPulse, { props: { pulse: basePulse() } });
await expect.element(page.getByText('Mitwirkende')).not.toBeInTheDocument();
});
it('renders one chip per contributor', async () => {
render(DashboardFamilyPulse, {
props: {
pulse: basePulse({
contributors: [
{ initials: 'AS', color: '#012851', name: 'Anna Schmidt' },
{ initials: 'BM', color: '#5a3080', name: 'Bert Meier' }
]
})
}
});
await expect.element(page.getByText('AS')).toBeVisible();
await expect.element(page.getByText('BM')).toBeVisible();
});
it('renders the three count tiles', async () => {
render(DashboardFamilyPulse, {
props: {
pulse: basePulse({ annotated: 15, transcribed: 7, uploaded: 3 })
}
});
await expect.element(page.getByText('15')).toBeVisible();
await expect.element(page.getByText('7')).toBeVisible();
await expect.element(page.getByText('3')).toBeVisible();
});
});