diff --git a/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte b/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte
index f78a9b6a..e91a4310 100644
--- a/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte
+++ b/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte
@@ -27,37 +27,34 @@ interface Props {
const { persons }: Props = $props();
-
-
- {m.dashboard_reader_person_chips_heading()}
-
+
{#if persons.length === 0}
{m.dashboard_reader_no_persons()}
{/if}
-
+
diff --git a/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte.spec.ts b/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte.spec.ts
index 4aebb735..0ae40474 100644
--- a/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte.spec.ts
+++ b/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte.spec.ts
@@ -32,7 +32,7 @@ const person2: PersonSummaryDTO = {
};
describe('ReaderPersonChips', () => {
- it('renders a chip for each person with correct href', async () => {
+ it('renders a card for each person with correct href', async () => {
render(ReaderPersonChips, { persons: [person1, person2] });
const link1 = page.getByRole('link', { name: /Anna Müller/ });
await expect
@@ -44,12 +44,44 @@ describe('ReaderPersonChips', () => {
.toHaveAttribute('href', '/persons/aaaaaaaa-0000-0000-0000-000000000002');
});
- it('shows document count in each chip', async () => {
+ it('person card has min-h-[44px] touch target', async () => {
render(ReaderPersonChips, { persons: [person1] });
- const chip = page.getByRole('link', { name: /Anna Müller/ });
- await expect.element(chip).toBeInTheDocument();
- const text = ((await chip.element()) as HTMLElement).textContent;
- expect(text).toContain('23');
+ const link = page.getByRole('link', { name: /Anna Müller/ });
+ const cls = ((await link.element()) as HTMLElement).className;
+ expect(cls).toMatch(/min-h-\[44px\]/);
+ });
+
+ it('doc count renders as mint pill with bg-mint-soft', async () => {
+ render(ReaderPersonChips, { persons: [person1] });
+ const link = page.getByRole('link', { name: /Anna Müller/ });
+ const el = (await link.element()) as HTMLElement;
+ const pill = el.querySelector('[class*="bg-mint-soft"]');
+ expect(pill).not.toBeNull();
+ expect(pill!.textContent).toContain('23');
+ });
+
+ it('doc count pill has rounded-full class', async () => {
+ render(ReaderPersonChips, { persons: [person1] });
+ const link = page.getByRole('link', { name: /Anna Müller/ });
+ const el = (await link.element()) as HTMLElement;
+ const pill = el.querySelector('[class*="rounded-full"]');
+ expect(pill).not.toBeNull();
+ });
+
+ it('person grid uses grid layout', async () => {
+ render(ReaderPersonChips, { persons: [person1, person2] });
+ const section = page.getByRole('region');
+ const el = (await section.element()) as HTMLElement;
+ const grid = el.querySelector('[class*="grid"]');
+ expect(grid).not.toBeNull();
+ });
+
+ it('wrapper is a section with aria-label', async () => {
+ render(ReaderPersonChips, { persons: [person1] });
+ const section = page.getByRole('region');
+ await expect.element(section).toBeInTheDocument();
+ const label = ((await section.element()) as HTMLElement).getAttribute('aria-label');
+ expect(label).toBeTruthy();
});
it('renders an "Alle Personen" link to /persons', async () => {
@@ -58,6 +90,13 @@ describe('ReaderPersonChips', () => {
await expect.element(allLink).toHaveAttribute('href', '/persons');
});
+ it('"Alle Personen" link has text-link-quiet class', async () => {
+ render(ReaderPersonChips, { persons: [person1] });
+ const allLink = page.getByRole('link', { name: /Alle Personen/i });
+ const cls = ((await allLink.element()) as HTMLElement).className;
+ expect(cls).toMatch(/text-link-quiet/);
+ });
+
it('exposes a focus-visible ring on the "Alle Personen" link', async () => {
render(ReaderPersonChips, { persons: [person1] });
const allLink = page.getByRole('link', { name: /Alle Personen/i });
@@ -73,7 +112,13 @@ describe('ReaderPersonChips', () => {
expect(cls).toMatch(/min-h-\[44px\]/);
});
- it('renders empty state without chips when persons array is empty', async () => {
+ it('does not render h2 heading', async () => {
+ render(ReaderPersonChips, { persons: [person1] });
+ const heading = page.getByRole('heading', { level: 2 });
+ await expect.element(heading).not.toBeInTheDocument();
+ });
+
+ it('renders empty state without person cards when persons array is empty', async () => {
render(ReaderPersonChips, { persons: [] });
const chips = page.getByRole('link', { name: /Müller|Schmidt/ });
await expect.element(chips).not.toBeInTheDocument();