diff --git a/frontend/src/lib/onboarding/CategorySection.svelte b/frontend/src/lib/onboarding/CategorySection.svelte new file mode 100644 index 0000000..d9e4f4d --- /dev/null +++ b/frontend/src/lib/onboarding/CategorySection.svelte @@ -0,0 +1,26 @@ + + +
+

+ {name} +

+
+ {#each ingredients as ingredient (ingredient.id)} + onToggle(ingredient.id, value)} + /> + {/each} +
+
diff --git a/frontend/src/lib/onboarding/CategorySection.test.ts b/frontend/src/lib/onboarding/CategorySection.test.ts new file mode 100644 index 0000000..b37579f --- /dev/null +++ b/frontend/src/lib/onboarding/CategorySection.test.ts @@ -0,0 +1,55 @@ +import { describe, it, expect, vi } from 'vitest'; +import { render, screen } from '@testing-library/svelte'; +import CategorySection from './CategorySection.svelte'; + +const mockIngredients = [ + { id: '1', name: 'Olivenöl', isStaple: true }, + { id: '2', name: 'Butter', isStaple: false }, + { id: '3', name: 'Kokosöl', isStaple: false } +]; + +describe('CategorySection', () => { + it('renders the category name as a heading', () => { + render(CategorySection, { + props: { name: 'Öle & Fette', ingredients: mockIngredients, onToggle: vi.fn() } + }); + expect(screen.getByText('Öle & Fette')).toBeInTheDocument(); + }); + + it('renders a chip for each ingredient', () => { + render(CategorySection, { + props: { name: 'Öle & Fette', ingredients: mockIngredients, onToggle: vi.fn() } + }); + expect(screen.getByRole('button', { name: 'Olivenöl' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Butter' })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Kokosöl' })).toBeInTheDocument(); + }); + + it('reflects isStaple state on each chip', () => { + render(CategorySection, { + props: { name: 'Öle & Fette', ingredients: mockIngredients, onToggle: vi.fn() } + }); + expect(screen.getByRole('button', { name: 'Olivenöl' })).toHaveAttribute('aria-pressed', 'true'); + expect(screen.getByRole('button', { name: 'Butter' })).toHaveAttribute('aria-pressed', 'false'); + }); + + it('calls onToggle with ingredient id and new value when chip is clicked', async () => { + const { userEvent } = await import('@testing-library/user-event'); + const user = userEvent.setup(); + const onToggle = vi.fn(); + render(CategorySection, { + props: { name: 'Öle & Fette', ingredients: mockIngredients, onToggle } + }); + + await user.click(screen.getByRole('button', { name: 'Butter' })); + expect(onToggle).toHaveBeenCalledWith('2', true); + }); + + it('renders an empty category without crashing', () => { + render(CategorySection, { + props: { name: 'Leer', ingredients: [], onToggle: vi.fn() } + }); + expect(screen.getByText('Leer')).toBeInTheDocument(); + expect(screen.queryByRole('button')).not.toBeInTheDocument(); + }); +});