import { describe, it, expect, vi, beforeEach } from 'vitest' import { render, screen, waitFor, within } from '@testing-library/react' import { MemoryRouter } from 'react-router-dom' import StatsPage from '../src/pages/StatsPage.js' import type { Stats } from '../src/types.js' vi.mock('../src/api.js', async (importOriginal) => { const actual = await importOriginal() return { ...actual, api: { ...actual.api, getStats: vi.fn() } } }) import { api } from '../src/api.js' const stats: Stats = { totals: { items: 4, ripped: 1, notRipped: 3, onLoan: 1 }, ripRatio: 0.25, formats: [ { name: 'CD', count: 3 }, { name: 'Vinyl', count: 1 }, ], decades: [{ name: '1990s', count: 4 }], topGenres: [ { name: 'Electronic', count: 3 }, { name: 'Downtempo', count: 2 }, ], topArtists: [{ name: 'Massive Attack', count: 2 }], addedByMonth: [ { month: '2025-10', count: 0 }, { month: '2025-11', count: 0 }, { month: '2025-12', count: 0 }, { month: '2026-01', count: 0 }, { month: '2026-02', count: 0 }, { month: '2026-03', count: 0 }, { month: '2026-04', count: 0 }, { month: '2026-05', count: 0 }, { month: '2026-06', count: 0 }, { month: '2026-07', count: 0 }, { month: '2026-08', count: 4 }, { month: '2026-09', count: 0 }, ], } beforeEach(() => { vi.mocked(api.getStats).mockReset() vi.mocked(api.getStats).mockResolvedValue(stats as never) }) describe('StatsPage', () => { it('renders totals and rip ratio', async () => { render( ) expect((await screen.findAllByText('4')).length).toBeGreaterThanOrEqual(1) expect(screen.getByText(/25% ripped/i)).toBeTruthy() const onLoanLabel = screen.getByText('on loan') expect(within(onLoanLabel.parentElement as HTMLElement).getByText('1')).toBeTruthy() }) it('renders format, genre, artist and month bars', async () => { render( ) expect(await screen.findByText('CD')).toBeTruthy() expect(screen.getByText('Electronic')).toBeTruthy() expect(screen.getByText('Massive Attack')).toBeTruthy() expect(screen.getByText('1990s')).toBeTruthy() // month bars: 12 bars rendered expect(document.querySelectorAll('[data-bar]').length).toBeGreaterThanOrEqual(12) }) it('error state on failure', async () => { vi.mocked(api.getStats).mockRejectedValue(new TypeError('fetch failed')) render( ) expect(await screen.findByText(/could not load stats/i)).toBeTruthy() }) })