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>
94 lines
3.2 KiB
TypeScript
94 lines
3.2 KiB
TypeScript
import { QueryClientProvider } from '@tanstack/react-query'
|
|
import { renderHook, waitFor } from '@testing-library/react'
|
|
import { createTestQueryClient } from '../test/utils'
|
|
import {
|
|
usePokemon,
|
|
usePokemonFamilies,
|
|
usePokemonEncounterLocations,
|
|
usePokemonEvolutionChain,
|
|
} from './usePokemon'
|
|
|
|
vi.mock('../api/pokemon')
|
|
|
|
import {
|
|
getPokemon,
|
|
fetchPokemonFamilies,
|
|
fetchPokemonEncounterLocations,
|
|
fetchPokemonEvolutionChain,
|
|
} from '../api/pokemon'
|
|
|
|
function createWrapper() {
|
|
const queryClient = createTestQueryClient()
|
|
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
|
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
|
)
|
|
return { queryClient, wrapper }
|
|
}
|
|
|
|
describe('usePokemon', () => {
|
|
it('is disabled when id is null', () => {
|
|
const { wrapper } = createWrapper()
|
|
const { result } = renderHook(() => usePokemon(null), { wrapper })
|
|
expect(result.current.fetchStatus).toBe('idle')
|
|
expect(getPokemon).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('fetches a pokemon by id', async () => {
|
|
const mon = { id: 25, name: 'pikachu' }
|
|
vi.mocked(getPokemon).mockResolvedValue(mon as never)
|
|
const { wrapper } = createWrapper()
|
|
|
|
const { result } = renderHook(() => usePokemon(25), { wrapper })
|
|
await waitFor(() => expect(result.current.isSuccess).toBe(true))
|
|
|
|
expect(getPokemon).toHaveBeenCalledWith(25)
|
|
expect(result.current.data).toEqual(mon)
|
|
})
|
|
})
|
|
|
|
describe('usePokemonFamilies', () => {
|
|
it('calls fetchPokemonFamilies and returns data', async () => {
|
|
const families = [{ id: 1, members: [] }]
|
|
vi.mocked(fetchPokemonFamilies).mockResolvedValue(families as never)
|
|
const { wrapper } = createWrapper()
|
|
|
|
const { result } = renderHook(() => usePokemonFamilies(), { wrapper })
|
|
await waitFor(() => expect(result.current.isSuccess).toBe(true))
|
|
|
|
expect(fetchPokemonFamilies).toHaveBeenCalledOnce()
|
|
expect(result.current.data).toEqual(families)
|
|
})
|
|
})
|
|
|
|
describe('usePokemonEncounterLocations', () => {
|
|
it('is disabled when pokemonId is null', () => {
|
|
const { wrapper } = createWrapper()
|
|
const { result } = renderHook(() => usePokemonEncounterLocations(null), { wrapper })
|
|
expect(result.current.fetchStatus).toBe('idle')
|
|
})
|
|
|
|
it('fetches encounter locations for a given pokemon', async () => {
|
|
vi.mocked(fetchPokemonEncounterLocations).mockResolvedValue([] as never)
|
|
const { wrapper } = createWrapper()
|
|
|
|
renderHook(() => usePokemonEncounterLocations(25), { wrapper })
|
|
await waitFor(() => expect(fetchPokemonEncounterLocations).toHaveBeenCalledWith(25))
|
|
})
|
|
})
|
|
|
|
describe('usePokemonEvolutionChain', () => {
|
|
it('is disabled when pokemonId is null', () => {
|
|
const { wrapper } = createWrapper()
|
|
const { result } = renderHook(() => usePokemonEvolutionChain(null), { wrapper })
|
|
expect(result.current.fetchStatus).toBe('idle')
|
|
})
|
|
|
|
it('fetches the evolution chain for a given pokemon', async () => {
|
|
vi.mocked(fetchPokemonEvolutionChain).mockResolvedValue([] as never)
|
|
const { wrapper } = createWrapper()
|
|
|
|
renderHook(() => usePokemonEvolutionChain(4), { wrapper })
|
|
await waitFor(() => expect(fetchPokemonEvolutionChain).toHaveBeenCalledWith(4))
|
|
})
|
|
})
|