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:
45
frontend/src/lib/planner/DayMealCard.test.ts
Normal file
45
frontend/src/lib/planner/DayMealCard.test.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { render, screen } from '@testing-library/svelte';
|
||||
import DayMealCard from './DayMealCard.svelte';
|
||||
|
||||
const slot = {
|
||||
id: 's1',
|
||||
slotDate: '2026-03-30',
|
||||
recipe: { id: 'r1', name: 'Pasta Bolognese', effort: 'Easy', cookTimeMin: 30 }
|
||||
};
|
||||
|
||||
describe('DayMealCard', () => {
|
||||
it('renders recipe name', () => {
|
||||
render(DayMealCard, { props: { slot, isToday: false, readonly: false } });
|
||||
expect(screen.getByText('Pasta Bolognese')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('shows Cook now and Swap buttons when not readonly', () => {
|
||||
render(DayMealCard, { props: { slot, isToday: false, readonly: false } });
|
||||
expect(screen.getByRole('link', { name: /Jetzt kochen/i })).toBeTruthy();
|
||||
expect(screen.getByRole('button', { name: /Tauschen/i })).toBeTruthy();
|
||||
});
|
||||
|
||||
it('hides action buttons when readonly', () => {
|
||||
render(DayMealCard, { props: { slot, isToday: false, readonly: true } });
|
||||
expect(screen.queryByRole('link', { name: /Jetzt kochen/i })).toBeNull();
|
||||
expect(screen.queryByRole('button', { name: /Tauschen/i })).toBeNull();
|
||||
});
|
||||
|
||||
it('applies today styling when isToday is true', () => {
|
||||
render(DayMealCard, { props: { slot, isToday: true, readonly: false } });
|
||||
const card = screen.getByTestId('day-meal-card');
|
||||
expect(card.getAttribute('data-today')).toBe('true');
|
||||
});
|
||||
|
||||
it('renders empty state when slot has no recipe', () => {
|
||||
render(DayMealCard, { props: { slot: { id: 's2', slotDate: '2026-03-31', recipe: null }, isToday: false, readonly: false } });
|
||||
expect(screen.getByText(/Kein Gericht/i)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('shows cook time and effort metadata', () => {
|
||||
render(DayMealCard, { props: { slot, isToday: false, readonly: false } });
|
||||
expect(screen.getByText(/30 Min/)).toBeTruthy();
|
||||
expect(screen.getByText(/Easy/)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user