From 22e4b98229a5afb61a8513b8632b90505459b528 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 10 May 2026 02:57:36 +0200 Subject: [PATCH] test(activity): cover ChronikFilterPills branches Radiogroup with label, all five filter pills, aria-checked for active filter, tabindex matrix (0 active vs -1 inactive), onChange callback when clicked. 5 tests, ~15 branches. Refs #496. Co-Authored-By: Claude Sonnet 4.6 --- .../ChronikFilterPills.svelte.test.ts | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 frontend/src/lib/activity/ChronikFilterPills.svelte.test.ts diff --git a/frontend/src/lib/activity/ChronikFilterPills.svelte.test.ts b/frontend/src/lib/activity/ChronikFilterPills.svelte.test.ts new file mode 100644 index 00000000..c04fdf4b --- /dev/null +++ b/frontend/src/lib/activity/ChronikFilterPills.svelte.test.ts @@ -0,0 +1,53 @@ +import { describe, it, expect, vi, afterEach } from 'vitest'; +import { cleanup, render } from 'vitest-browser-svelte'; +import { page } from 'vitest/browser'; +import ChronikFilterPills from './ChronikFilterPills.svelte'; + +afterEach(cleanup); + +describe('ChronikFilterPills', () => { + it('renders the radiogroup with the label', async () => { + render(ChronikFilterPills, { props: { value: 'alle' as const, onChange: () => {} } }); + + await expect + .element(page.getByRole('radiogroup', { name: /aktivitäten filtern/i })) + .toBeVisible(); + }); + + it('renders all five filter pills', async () => { + render(ChronikFilterPills, { props: { value: 'alle' as const, onChange: () => {} } }); + + const radios = document.querySelectorAll('[role="radio"]'); + expect(radios.length).toBe(5); + }); + + it('marks the active filter as aria-checked=true', async () => { + render(ChronikFilterPills, { props: { value: 'fuer-dich' as const, onChange: () => {} } }); + + const active = document.querySelector('[data-filter-value="fuer-dich"]') as HTMLElement; + expect(active.getAttribute('aria-checked')).toBe('true'); + }); + + it('sets tabindex=0 on the active pill and -1 on others', async () => { + render(ChronikFilterPills, { props: { value: 'kommentare' as const, onChange: () => {} } }); + + const active = document.querySelector('[data-filter-value="kommentare"]') as HTMLElement; + const others = Array.from(document.querySelectorAll('[role="radio"]')).filter( + (el) => el !== active + ) as HTMLElement[]; + expect(active.tabIndex).toBe(0); + others.forEach((el) => expect(el.tabIndex).toBe(-1)); + }); + + it('calls onChange with the new filter value when clicked', async () => { + const onChange = vi.fn(); + render(ChronikFilterPills, { props: { value: 'alle' as const, onChange } }); + + const transcription = document.querySelector( + '[data-filter-value="transkription"]' + ) as HTMLElement; + transcription.click(); + + expect(onChange).toHaveBeenCalledWith('transkription'); + }); +});