import { describe, it, expect, vi, beforeEach } from 'vitest'; vi.mock('$env/dynamic/private', () => ({ env: { BACKEND_URL: 'http://localhost:8080' } })); const mockGet = vi.fn(); vi.mock('$lib/server/api', () => ({ apiClient: () => ({ GET: mockGet }) })); describe('recipe detail page — load', () => { let load: any; beforeEach(async () => { mockGet.mockReset(); vi.resetModules(); const mod = await import('./+page.server'); load = mod.load; }); const mockRecipe = { id: 'r1', name: 'Spaghetti Bolognese', serves: 4, cookTimeMin: 30, effort: 'Easy', heroImageUrl: undefined, ingredients: [ { ingredientId: 'i1', name: 'Spaghetti', quantity: 200, unit: 'g' } ], steps: [{ stepNumber: 1, instruction: 'Kochen' }], tags: [] }; it('fetches recipe from GET /v1/recipes/{id}', async () => { mockGet.mockResolvedValue({ data: mockRecipe, error: undefined }); await load({ fetch: vi.fn(), params: { id: 'r1' } } as any); expect(mockGet).toHaveBeenCalledWith('/v1/recipes/{id}', expect.objectContaining({ params: { path: { id: 'r1' } } })); }); it('returns recipe data on success', async () => { mockGet.mockResolvedValue({ data: mockRecipe, error: undefined }); const result = await load({ fetch: vi.fn(), params: { id: 'r1' } } as any); expect(result.recipe.name).toBe('Spaghetti Bolognese'); expect(result.recipe.serves).toBe(4); }); it('throws 404 error when API returns error', async () => { mockGet.mockResolvedValue({ data: undefined, error: { status: 404 } }); await expect( load({ fetch: vi.fn(), params: { id: 'nonexistent' } } as any) ).rejects.toMatchObject({ status: 404 }); }); it('throws 404 error when API returns 403 (different household — intentional)', async () => { // Security design: we return 404 for both "not found" and "forbidden" // to avoid revealing resource existence to unauthorized users mockGet.mockResolvedValue({ data: undefined, error: { status: 403 } }); await expect( load({ fetch: vi.fn(), params: { id: 'r-other-household' } } as any) ).rejects.toMatchObject({ status: 404 }); }); });