82 tests covering download.ts and all React Query hooks. API modules are mocked with vi.mock; mutation tests spy on queryClient.invalidateQueries to verify cache invalidation. Conditional queries (null id) are verified to stay idle. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
90 lines
3.1 KiB
TypeScript
90 lines
3.1 KiB
TypeScript
import { QueryClientProvider } from '@tanstack/react-query'
|
|
import { renderHook, waitFor } from '@testing-library/react'
|
|
import { createTestQueryClient } from '../test/utils'
|
|
import { useGames, useGame, useGameRoutes, useRoutePokemon } from './useGames'
|
|
|
|
vi.mock('../api/games')
|
|
|
|
import { getGames, getGame, getGameRoutes, getRoutePokemon } from '../api/games'
|
|
|
|
function createWrapper() {
|
|
const queryClient = createTestQueryClient()
|
|
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
|
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
|
)
|
|
return { queryClient, wrapper }
|
|
}
|
|
|
|
describe('useGames', () => {
|
|
it('calls getGames and returns data', async () => {
|
|
const games = [{ id: 1, name: 'Red' }]
|
|
vi.mocked(getGames).mockResolvedValue(games as never)
|
|
const { wrapper } = createWrapper()
|
|
|
|
const { result } = renderHook(() => useGames(), { wrapper })
|
|
await waitFor(() => expect(result.current.isSuccess).toBe(true))
|
|
|
|
expect(getGames).toHaveBeenCalledOnce()
|
|
expect(result.current.data).toEqual(games)
|
|
})
|
|
})
|
|
|
|
describe('useGame', () => {
|
|
it('calls getGame with the given id', async () => {
|
|
const game = { id: 2, name: 'Blue' }
|
|
vi.mocked(getGame).mockResolvedValue(game as never)
|
|
const { wrapper } = createWrapper()
|
|
|
|
const { result } = renderHook(() => useGame(2), { wrapper })
|
|
await waitFor(() => expect(result.current.isSuccess).toBe(true))
|
|
|
|
expect(getGame).toHaveBeenCalledWith(2)
|
|
})
|
|
})
|
|
|
|
describe('useGameRoutes', () => {
|
|
it('is disabled when gameId is null', () => {
|
|
const { wrapper } = createWrapper()
|
|
const { result } = renderHook(() => useGameRoutes(null), { wrapper })
|
|
expect(result.current.fetchStatus).toBe('idle')
|
|
expect(getGameRoutes).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('fetches routes when gameId is provided', async () => {
|
|
const routes = [{ id: 10, name: 'Route 1' }]
|
|
vi.mocked(getGameRoutes).mockResolvedValue(routes as never)
|
|
const { wrapper } = createWrapper()
|
|
|
|
const { result } = renderHook(() => useGameRoutes(1), { wrapper })
|
|
await waitFor(() => expect(result.current.isSuccess).toBe(true))
|
|
|
|
expect(getGameRoutes).toHaveBeenCalledWith(1, undefined)
|
|
expect(result.current.data).toEqual(routes)
|
|
})
|
|
|
|
it('passes allowedTypes to the API', async () => {
|
|
vi.mocked(getGameRoutes).mockResolvedValue([] as never)
|
|
const { wrapper } = createWrapper()
|
|
|
|
renderHook(() => useGameRoutes(5, ['grass', 'water']), { wrapper })
|
|
await waitFor(() => expect(getGameRoutes).toHaveBeenCalledWith(5, ['grass', 'water']))
|
|
})
|
|
})
|
|
|
|
describe('useRoutePokemon', () => {
|
|
it('is disabled when routeId is null', () => {
|
|
const { wrapper } = createWrapper()
|
|
const { result } = renderHook(() => useRoutePokemon(null), { wrapper })
|
|
expect(result.current.fetchStatus).toBe('idle')
|
|
expect(getRoutePokemon).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('fetches pokemon for a given route', async () => {
|
|
vi.mocked(getRoutePokemon).mockResolvedValue([] as never)
|
|
const { wrapper } = createWrapper()
|
|
|
|
renderHook(() => useRoutePokemon(3, 1), { wrapper })
|
|
await waitFor(() => expect(getRoutePokemon).toHaveBeenCalledWith(3, 1))
|
|
})
|
|
})
|