1
0
Files
record-shop/web/test/stats.test.tsx

84 lines
2.6 KiB
TypeScript
Raw Normal View History

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<typeof import('../src/api.js')>()
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(
<MemoryRouter>
<StatsPage />
</MemoryRouter>
)
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(
<MemoryRouter>
<StatsPage />
</MemoryRouter>
)
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(
<MemoryRouter>
<StatsPage />
</MemoryRouter>
)
expect(await screen.findByText(/could not load stats/i)).toBeTruthy()
})
})