/** * Component: Home Page Tests * Documentation: documentation/frontend/components.md */ // @vitest-environment jsdom import React from 'react'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { resetMockAuthState } from '../helpers/mock-auth'; import { resetMockRouter } from '../helpers/mock-next-navigation'; const useAudiobooksMock = vi.hoisted(() => vi.fn()); const usePreferencesMock = vi.hoisted(() => ({ cardSize: 5, setCardSize: vi.fn(), })); vi.mock('@/lib/hooks/useAudiobooks', () => ({ useAudiobooks: useAudiobooksMock, })); vi.mock('@/contexts/PreferencesContext', () => ({ usePreferences: () => usePreferencesMock, })); vi.mock('@/components/auth/ProtectedRoute', () => ({ ProtectedRoute: ({ children }: { children: React.ReactNode }) => <>{children}, })); vi.mock('@/components/layout/Header', () => ({ Header: () =>
, })); vi.mock('@/components/audiobooks/AudiobookGrid', () => ({ AudiobookGrid: ({ audiobooks, cardSize }: { audiobooks: any[]; cardSize?: number }) => (
{audiobooks.map((book) => (
{book.title}
))}
), })); vi.mock('@/components/ui/CardSizeControls', () => ({ CardSizeControls: ({ size }: { size: number }) =>
, })); vi.mock('@/components/ui/UnifiedPagination', () => ({ UnifiedPagination: ({ sections, }: { sections: Array<{ label: string; onPageChange: (page: number) => void; }>; }) => (
{sections.map((s) => ( ))}
), })); describe('HomePage', () => { beforeEach(() => { resetMockAuthState(); resetMockRouter(); useAudiobooksMock.mockReset(); usePreferencesMock.cardSize = 5; usePreferencesMock.setCardSize.mockReset(); vi.resetModules(); }); it('renders empty state messaging for popular audiobooks', async () => { useAudiobooksMock.mockImplementation((category: string) => { if (category === 'popular') { return { audiobooks: [], isLoading: false, totalPages: 1, message: 'Nothing here', }; } return { audiobooks: [{ asin: 'n1', title: 'New Release', author: 'Author' }], isLoading: false, totalPages: 2, message: null, }; }); const { default: HomePage } = await import('@/app/page'); render(); expect(screen.getByText('No popular audiobooks found')).toBeInTheDocument(); expect(screen.getByText('Nothing here')).toBeInTheDocument(); expect(screen.getByText('New Release')).toBeInTheDocument(); }); it('updates pagination when the sticky controls request a new page', async () => { useAudiobooksMock.mockImplementation((category: string, _limit: number, page: number) => { return { audiobooks: [{ asin: `${category}-${page}`, title: `${category}-${page}`, author: 'Author' }], isLoading: false, totalPages: 3, message: null, }; }); const { default: HomePage } = await import('@/app/page'); render(); fireEvent.click(screen.getByRole('button', { name: 'Popular Audiobooks next' })); await waitFor(() => { expect(useAudiobooksMock).toHaveBeenCalledWith('popular', 20, 2, undefined); }); }); });