- Fix logic bug `{#if !isPlanner === false}` - view/cook buttons now visible for all roles, swap only for planner
- Convert Tauschen from dead button to link with suggestions href
- Add week.ts unit tests (23 tests covering getWeekStart Sunday edge case, prevWeek/nextWeek, weekDays, isToday, formatWeekRange)
- Fix isToday to use UTC consistently (.toISOString().slice(0,10)) instead of local date
- Add server-side role guard to createPlan action (403 for members)
- Add weekStart format validation in createPlan action
- Add isSelected prop to DayMealCard with green treatment
- Make variety banner sticky on mobile (always visible per spec)
- Add day name abbreviation above date badge in desktop column headers
- Remove placeholder Navigation text from desktop sidebar
- Add aria-label to desktop empty tile buttons
- Add variety score partial failure test, multiple overlaps test, WeekStrip today+selected test
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
74 lines
2.4 KiB
TypeScript
74 lines
2.4 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { render, screen } from '@testing-library/svelte';
|
|
import VarietyScoreCard from './VarietyScoreCard.svelte';
|
|
|
|
const baseProps = {
|
|
score: 7.5,
|
|
ingredientOverlaps: [],
|
|
showReviewLink: false
|
|
};
|
|
|
|
describe('VarietyScoreCard', () => {
|
|
it('renders the variety score', () => {
|
|
render(VarietyScoreCard, { props: baseProps });
|
|
expect(screen.getByText('7.5')).toBeTruthy();
|
|
});
|
|
|
|
it('renders "/10" denominator', () => {
|
|
render(VarietyScoreCard, { props: baseProps });
|
|
expect(screen.getByText('/10')).toBeTruthy();
|
|
});
|
|
|
|
it('renders a progress bar with correct aria attributes', () => {
|
|
render(VarietyScoreCard, { props: baseProps });
|
|
const bar = screen.getByRole('progressbar');
|
|
expect(bar.getAttribute('aria-valuenow')).toBe('7.5');
|
|
expect(bar.getAttribute('aria-valuemin')).toBe('0');
|
|
expect(bar.getAttribute('aria-valuemax')).toBe('10');
|
|
});
|
|
|
|
it('renders ingredient overlap warnings', () => {
|
|
render(VarietyScoreCard, {
|
|
props: {
|
|
...baseProps,
|
|
ingredientOverlaps: [{ ingredientName: 'Tomate', days: ['2026-03-30', '2026-03-31'] }]
|
|
}
|
|
});
|
|
expect(screen.getByText(/Tomate/)).toBeTruthy();
|
|
expect(screen.getByText(/2 Mahlzeiten/)).toBeTruthy();
|
|
});
|
|
|
|
it('shows review link when showReviewLink is true', () => {
|
|
render(VarietyScoreCard, { props: { ...baseProps, showReviewLink: true } });
|
|
const link = screen.getByRole('link', { name: /Variety.*überprüfen|Review variety/i });
|
|
expect(link).toBeTruthy();
|
|
});
|
|
|
|
it('hides review link by default', () => {
|
|
render(VarietyScoreCard, { props: baseProps });
|
|
expect(screen.queryByRole('link', { name: /variety/i })).toBeNull();
|
|
});
|
|
|
|
it('renders with score 0', () => {
|
|
render(VarietyScoreCard, { props: { ...baseProps, score: 0 } });
|
|
expect(screen.getByText('0')).toBeTruthy();
|
|
});
|
|
|
|
it('renders multiple ingredient overlap warnings', () => {
|
|
render(VarietyScoreCard, {
|
|
props: {
|
|
...baseProps,
|
|
ingredientOverlaps: [
|
|
{ ingredientName: 'Tomate', days: ['2026-03-30', '2026-03-31'] },
|
|
{ ingredientName: 'Zwiebel', days: ['2026-03-30', '2026-04-01', '2026-04-02'] },
|
|
{ ingredientName: 'Knoblauch', days: ['2026-03-31', '2026-04-01'] }
|
|
]
|
|
}
|
|
});
|
|
expect(screen.getByText(/Tomate/)).toBeTruthy();
|
|
expect(screen.getByText(/Zwiebel/)).toBeTruthy();
|
|
expect(screen.getByText(/Knoblauch/)).toBeTruthy();
|
|
expect(screen.getByText(/3 Mahlzeiten/)).toBeTruthy();
|
|
});
|
|
});
|