feat(planner): implement C1 weekly planner home screen (#26)
Three-breakpoint layout (mobile/tablet/desktop) with VarietyScoreCard, WeekStrip, DayMealCard components. Server loads week plan and variety score via API; read-only role behavior derived from benutzer.rolle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
59
frontend/src/lib/planner/WeekStrip.test.ts
Normal file
59
frontend/src/lib/planner/WeekStrip.test.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { render, screen } from '@testing-library/svelte';
|
||||
import WeekStrip from './WeekStrip.svelte';
|
||||
|
||||
const weekStart = '2026-03-30'; // Monday
|
||||
|
||||
const slots = [
|
||||
{ id: 's1', slotDate: '2026-03-30', recipe: { id: 'r1', name: 'Pasta', effort: 'Easy' } },
|
||||
{ id: 's2', slotDate: '2026-03-31', recipe: { id: 'r2', name: 'Curry', effort: 'Medium' } }
|
||||
];
|
||||
|
||||
describe('WeekStrip', () => {
|
||||
it('renders 7 day chips', () => {
|
||||
render(WeekStrip, { props: { weekStart, slots, selectedDay: '2026-03-30', today: '2026-04-03' } });
|
||||
const chips = screen.getAllByRole('button');
|
||||
expect(chips).toHaveLength(7);
|
||||
});
|
||||
|
||||
it('marks today chip with data-today attribute', () => {
|
||||
render(WeekStrip, { props: { weekStart, slots, selectedDay: '2026-03-30', today: '2026-04-03' } });
|
||||
const todayChip = screen.getByTestId('day-chip-2026-04-03');
|
||||
expect(todayChip.getAttribute('data-today')).toBe('true');
|
||||
});
|
||||
|
||||
it('marks selected chip with data-selected attribute', () => {
|
||||
render(WeekStrip, { props: { weekStart, slots, selectedDay: '2026-03-30', today: '2026-04-03' } });
|
||||
const selectedChip = screen.getByTestId('day-chip-2026-03-30');
|
||||
expect(selectedChip.getAttribute('data-selected')).toBe('true');
|
||||
});
|
||||
|
||||
it('shows meal indicator dot for days with a meal', () => {
|
||||
render(WeekStrip, { props: { weekStart, slots, selectedDay: '2026-03-30', today: '2026-04-03' } });
|
||||
const dot = screen.getByTestId('dot-2026-03-30');
|
||||
expect(dot.getAttribute('data-has-meal')).toBe('true');
|
||||
});
|
||||
|
||||
it('shows empty dot for days without a meal', () => {
|
||||
render(WeekStrip, { props: { weekStart, slots, selectedDay: '2026-03-30', today: '2026-04-03' } });
|
||||
// 2026-04-01 has no meal
|
||||
const dot = screen.getByTestId('dot-2026-04-01');
|
||||
expect(dot.getAttribute('data-has-meal')).toBe('false');
|
||||
});
|
||||
|
||||
it('calls onselectDay callback when chip is clicked', async () => {
|
||||
let emitted: string | null = null;
|
||||
render(WeekStrip, {
|
||||
props: {
|
||||
weekStart,
|
||||
slots,
|
||||
selectedDay: '2026-03-30',
|
||||
today: '2026-04-03',
|
||||
onselectDay: (day: string) => { emitted = day; }
|
||||
}
|
||||
});
|
||||
const chip = screen.getByTestId('day-chip-2026-03-31');
|
||||
chip.click();
|
||||
expect(emitted).toBe('2026-03-31');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user