feat(recipes): add RecipeHero component with image/no-image variants

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-03 09:56:35 +02:00
parent a34c6f30f2
commit 86a25eb038
2 changed files with 133 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/svelte';
import RecipeHero from './RecipeHero.svelte';
const baseRecipe = {
id: 'r1',
name: 'Spaghetti Bolognese',
serves: 4,
cookTimeMin: 30,
effort: 'Easy',
heroImageUrl: undefined as string | undefined,
tags: [] as { id: string; name: string; tagType?: string }[]
};
describe('RecipeHero', () => {
it('renders the recipe name', () => {
render(RecipeHero, { props: { recipe: baseRecipe } });
expect(screen.getByText('Spaghetti Bolognese')).toBeInTheDocument();
});
it('renders green-tint hero when no image', () => {
render(RecipeHero, { props: { recipe: baseRecipe } });
const hero = document.querySelector('[data-testid="recipe-hero"]');
expect(hero?.className).toContain('bg-[var(--green-tint)]');
});
it('renders image when heroImageUrl is provided', () => {
render(RecipeHero, {
props: { recipe: { ...baseRecipe, heroImageUrl: '/uploads/pasta.jpg' } }
});
const img = screen.getByRole('img', { name: /spaghetti bolognese/i });
expect(img).toHaveAttribute('src', '/uploads/pasta.jpg');
});
it('renders cook time pill', () => {
render(RecipeHero, { props: { recipe: baseRecipe } });
expect(screen.getByText(/30 Min/)).toBeInTheDocument();
});
it('renders effort pill', () => {
render(RecipeHero, { props: { recipe: baseRecipe } });
expect(screen.getByText(/Easy/)).toBeInTheDocument();
});
it('renders serves pill', () => {
render(RecipeHero, { props: { recipe: baseRecipe } });
expect(screen.getByText(/4/)).toBeInTheDocument();
});
it('renders back link to /recipes', () => {
render(RecipeHero, { props: { recipe: baseRecipe } });
const backLink = screen.getByRole('link', { name: /zurück/i });
expect(backLink).toHaveAttribute('href', '/recipes');
});
it('renders cook now link to /cook/[id]', () => {
render(RecipeHero, { props: { recipe: baseRecipe } });
const cookLink = screen.getByRole('link', { name: /jetzt kochen/i });
expect(cookLink).toHaveAttribute('href', '/cook/r1');
});
it('does not render img when no heroImageUrl', () => {
render(RecipeHero, { props: { recipe: baseRecipe } });
expect(screen.queryByRole('img')).not.toBeInTheDocument();
});
});