/** * Component: Profile Page Tests * Documentation: documentation/frontend/components.md */ // @vitest-environment jsdom import React from 'react'; import { render, screen } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { resetMockAuthState, setMockAuthState } from '../helpers/mock-auth'; import { resetMockRouter } from '../helpers/mock-next-navigation'; const useRequestsMock = vi.hoisted(() => vi.fn()); vi.mock('@/lib/hooks/useRequests', () => ({ useRequests: useRequestsMock, })); vi.mock('@/components/layout/Header', () => ({ Header: () =>
, })); vi.mock('@/components/requests/RequestCard', () => ({ RequestCard: ({ request, showActions }: { request: any; showActions?: boolean }) => (
{request.id}
), })); const getStatValue = (label: string) => { const labelNode = screen.getByText(label); const container = labelNode.parentElement; const valueNode = container?.querySelector('p:nth-of-type(2)'); return valueNode?.textContent; }; describe('ProfilePage', () => { beforeEach(() => { resetMockAuthState(); resetMockRouter(); useRequestsMock.mockReset(); vi.resetModules(); }); it('prompts for authentication when no user is available', async () => { setMockAuthState({ user: null }); useRequestsMock.mockReturnValue({ requests: [], isLoading: false }); const { default: ProfilePage } = await import('@/app/profile/page'); render(); expect(screen.getByText('Authentication Required')).toBeInTheDocument(); expect(screen.getByText('Please log in to view your profile')).toBeInTheDocument(); }); it('calculates stats and orders recent requests', async () => { setMockAuthState({ user: { id: 'user-1', plexId: 'plex-1', username: 'user', role: 'user', }, isLoading: false, }); const requests = [ { id: 'req-1', status: 'pending', createdAt: '2025-01-01T10:00:00Z', audiobook: {} }, { id: 'req-2', status: 'awaiting_search', createdAt: '2025-01-02T10:00:00Z', audiobook: {} }, { id: 'req-3', status: 'available', createdAt: '2025-01-03T10:00:00Z', audiobook: {} }, { id: 'req-4', status: 'failed', createdAt: '2025-01-04T10:00:00Z', audiobook: {} }, { id: 'req-5', status: 'cancelled', createdAt: '2025-01-05T10:00:00Z', audiobook: {} }, { id: 'req-6', status: 'searching', createdAt: '2025-01-06T10:00:00Z', audiobook: {} }, ]; useRequestsMock.mockReturnValue({ requests, isLoading: false }); const { default: ProfilePage } = await import('@/app/profile/page'); render(); expect(getStatValue('Total')).toBe('6'); expect(getStatValue('Active')).toBe('2'); expect(getStatValue('Waiting')).toBe('1'); expect(getStatValue('Completed')).toBe('1'); expect(getStatValue('Failed')).toBe('1'); expect(getStatValue('Cancelled')).toBe('1'); const cards = screen.getAllByTestId('request-card'); expect(cards).toHaveLength(5); expect(cards[0]).toHaveAttribute('data-request-id', 'req-6'); }); it('shows active downloads when downloading requests exist', async () => { setMockAuthState({ user: { id: 'user-2', plexId: 'plex-2', username: 'download-user', role: 'user', }, isLoading: false, }); const requests = [ { id: 'req-downloading', status: 'downloading', createdAt: '2025-02-01T10:00:00Z', audiobook: {} }, { id: 'req-processing', status: 'processing', createdAt: '2025-02-02T10:00:00Z', audiobook: {} }, { id: 'req-pending', status: 'pending', createdAt: '2025-02-03T10:00:00Z', audiobook: {} }, ]; useRequestsMock.mockReturnValue({ requests, isLoading: false }); const { default: ProfilePage } = await import('@/app/profile/page'); render(); expect(screen.getByText('Active Downloads')).toBeInTheDocument(); const cards = screen.getAllByTestId('request-card'); expect(cards.length).toBeGreaterThan(0); }); });