import { describe, it, expect, vi, beforeEach } from 'vitest'; import { render, screen } from '@testing-library/react'; const { mockUseApi } = vi.hoisted(() => ({ mockUseApi: vi.fn(), })); vi.mock('@/lib/useApi', () => ({ useApi: mockUseApi })); vi.mock('@/services/recipes', () => ({ createRecipe: vi.fn(), updateRecipe: vi.fn(), listRecipes: vi.fn(), deleteRecipe: vi.fn(), getRecipe: vi.fn(), scaleRecipe: vi.fn(), importRecipeFromText: vi.fn(), importRecipeFromUrl: vi.fn(), listRecipesByProduct: vi.fn(), })); vi.mock('next/navigation', () => ({ useRouter: () => ({ push: vi.fn(), back: vi.fn() }), })); vi.mock('next/link', () => ({ // eslint-disable-next-line @typescript-eslint/no-explicit-any default: (props: any) => {props.children}, })); import NewRecipePage from '../../../../../src/app/(dashboard)/recipes/new/page'; beforeEach(() => vi.clearAllMocks()); describe('NewRecipePage', () => { it('shows loading state', () => { mockUseApi.mockReturnValue({ householdId: null, isLoading: true }); render(); expect(screen.getByText('New Recipe')).toBeInTheDocument(); expect(screen.getByText('Loading...')).toBeInTheDocument(); }); it('shows household prompt when no householdId', () => { mockUseApi.mockReturnValue({ householdId: null, isLoading: false }); render(); expect(screen.getByText(/create or join a household/)).toBeInTheDocument(); }); it('renders editor when household exists', () => { mockUseApi.mockReturnValue({ householdId: 'hh1', isLoading: false }); render(); expect(screen.getByPlaceholderText('Recipe name')).toBeInTheDocument(); expect(screen.getByText('Create recipe')).toBeInTheDocument(); }); });