Files
familienarchiv/frontend/src/routes/admin/layout.svelte.spec.ts
Marcel 154f859efc
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Failing after 1m36s
CI / Backend Unit Tests (pull_request) Failing after 2m36s
CI / E2E Tests (pull_request) Failing after 1h49m0s
feat(korrespondenz): address PR #164 review – blockers and suggestions
Blockers (14):
- B1: fix senderName/receiverName to use $derived instead of $state + sync $effect
- B2: migrate all korrespondenz components from messages-extra shim to paraglide m.*
- B3: i18n CorrespondenzEmptyState (heading, subtext, search placeholder)
- B4: add response.ok checks to admin layout server load
- B5: add response.ok checks to korrespondenz page server load
- B6: add page.server.spec.ts with 5 test suites for korrespondenz load function
- B7: add axe-core accessibility checks to all e2e korrespondenz tests
- B8: add Testcontainers JPQL tests for findSinglePersonCorrespondence (DISTINCT + sender)
- B9: hide auth reset-token endpoint from OpenAPI spec; remove from generated api.ts
- B11: replace amber hardcoded hex colors in SinglePersonHintBar with brand tokens
- B12: replace clipboard emoji with Heroicons SVG in SinglePersonHintBar
- B13: create DateInput component (German dd.mm.yyyy); use it in CorrespondenzFilterControls
- B14: add Paraglide compile step to CI workflow before lint/test

Suggestions (11):
- S1: make CorrespondentSuggestionsDropdown a pure display component; lift fetch to PersonBar
- S2: fix leftover messages-extra import in ConversationTimeline; use brand tokens for status dots
- S3: add intent comment to EntityNav openFlyout behavior
- S4: rename canManageGroups → canManagePermissions throughout admin
- S6: remove domFlush helper from DateInput spec; use expect.poll instead
- S7: replace test.skip with throw new Error in bilateral e2e tests
- S8: add inverse aria-disabled test for filter strip
- S9: remove sm:min-h-0 from sort button to preserve 44px touch target
- S10: add title attributes to tablet trigger buttons in EntityNav
- S11: delete messages-extra.ts shim entirely

Also: fix admin pages revealing blank strip at bottom (-mb-6 on admin layout)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 19:57:48 +02:00

88 lines
2.8 KiB
TypeScript

/**
* Layout shell tests — we test EntityNav.svelte directly since the layout
* itself is a thin shell that just composes EntityNav and renders children.
*/
import { afterEach, describe, it, expect, vi } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import EntityNav from './EntityNav.svelte';
vi.mock('$app/state', () => ({
page: { url: { pathname: '/admin/users' } }
}));
afterEach(cleanup);
const fullPerms = {
userCount: 4,
groupCount: 3,
tagCount: 7,
canManageUsers: true,
canManageTags: true,
canManagePermissions: true,
canRunMaintenance: true
};
describe('admin EntityNav — links', () => {
it('renders users nav link pointing to /admin/users', async () => {
render(EntityNav, fullPerms);
await expect
.element(page.getByRole('link', { name: /benutzer/i }))
.toHaveAttribute('href', '/admin/users');
});
it('renders groups nav link pointing to /admin/groups', async () => {
render(EntityNav, fullPerms);
await expect
.element(page.getByRole('link', { name: /gruppen/i }))
.toHaveAttribute('href', '/admin/groups');
});
it('renders tags nav link pointing to /admin/tags', async () => {
render(EntityNav, fullPerms);
await expect
.element(page.getByRole('link', { name: /schlagworte/i }))
.toHaveAttribute('href', '/admin/tags');
});
it('renders system nav link pointing to /admin/system', async () => {
render(EntityNav, fullPerms);
await expect
.element(page.getByRole('link', { name: /system/i }))
.toHaveAttribute('href', '/admin/system');
});
});
describe('admin EntityNav — permission-based rendering', () => {
it('hides users link when canManageUsers is false', async () => {
render(EntityNav, { ...fullPerms, canManageUsers: false });
await expect.element(page.getByRole('link', { name: /benutzer/i })).not.toBeInTheDocument();
});
it('hides tags link when canManageTags is false', async () => {
render(EntityNav, { ...fullPerms, canManageTags: false });
await expect.element(page.getByRole('link', { name: /schlagworte/i })).not.toBeInTheDocument();
});
it('hides system link when canRunMaintenance is false', async () => {
render(EntityNav, { ...fullPerms, canRunMaintenance: false });
await expect.element(page.getByRole('link', { name: /system/i })).not.toBeInTheDocument();
});
});
describe('admin EntityNav — active state', () => {
it('marks users link as aria-current=page when on /admin/users', async () => {
render(EntityNav, fullPerms);
await expect
.element(page.getByRole('link', { name: /benutzer/i }))
.toHaveAttribute('aria-current', 'page');
});
it('does not mark groups link as current when on /admin/users', async () => {
render(EntityNav, fullPerms);
await expect
.element(page.getByRole('link', { name: /gruppen/i }))
.not.toHaveAttribute('aria-current');
});
});