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>
162 lines
5.2 KiB
TypeScript
162 lines
5.2 KiB
TypeScript
import { QueryClientProvider } from '@tanstack/react-query'
|
|
import { renderHook, waitFor, act } from '@testing-library/react'
|
|
import { createTestQueryClient } from '../test/utils'
|
|
import {
|
|
useCreateEncounter,
|
|
useUpdateEncounter,
|
|
useDeleteEncounter,
|
|
useEvolutions,
|
|
useForms,
|
|
useBulkRandomize,
|
|
} from './useEncounters'
|
|
|
|
vi.mock('../api/encounters')
|
|
|
|
import {
|
|
createEncounter,
|
|
updateEncounter,
|
|
deleteEncounter,
|
|
fetchEvolutions,
|
|
fetchForms,
|
|
bulkRandomizeEncounters,
|
|
} from '../api/encounters'
|
|
|
|
function createWrapper() {
|
|
const queryClient = createTestQueryClient()
|
|
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
|
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
|
)
|
|
return { queryClient, wrapper }
|
|
}
|
|
|
|
describe('useCreateEncounter', () => {
|
|
it('calls createEncounter with the run id and input', async () => {
|
|
vi.mocked(createEncounter).mockResolvedValue({} as never)
|
|
const { wrapper } = createWrapper()
|
|
|
|
const { result } = renderHook(() => useCreateEncounter(3), { wrapper })
|
|
const input = { routeId: 1, pokemonId: 25, status: 'caught' }
|
|
await act(async () => {
|
|
await result.current.mutateAsync(input as never)
|
|
})
|
|
|
|
expect(createEncounter).toHaveBeenCalledWith(3, input)
|
|
})
|
|
|
|
it('invalidates the run query on success', async () => {
|
|
vi.mocked(createEncounter).mockResolvedValue({} as never)
|
|
const { queryClient, wrapper } = createWrapper()
|
|
const spy = vi.spyOn(queryClient, 'invalidateQueries')
|
|
|
|
const { result } = renderHook(() => useCreateEncounter(3), { wrapper })
|
|
await act(async () => {
|
|
await result.current.mutateAsync({} as never)
|
|
})
|
|
|
|
expect(spy).toHaveBeenCalledWith({ queryKey: ['runs', 3] })
|
|
})
|
|
})
|
|
|
|
describe('useUpdateEncounter', () => {
|
|
it('calls updateEncounter with id and data', async () => {
|
|
vi.mocked(updateEncounter).mockResolvedValue({} as never)
|
|
const { wrapper } = createWrapper()
|
|
|
|
const { result } = renderHook(() => useUpdateEncounter(3), { wrapper })
|
|
await act(async () => {
|
|
await result.current.mutateAsync({ id: 42, data: { status: 'dead' } } as never)
|
|
})
|
|
|
|
expect(updateEncounter).toHaveBeenCalledWith(42, { status: 'dead' })
|
|
})
|
|
|
|
it('invalidates the run query on success', async () => {
|
|
vi.mocked(updateEncounter).mockResolvedValue({} as never)
|
|
const { queryClient, wrapper } = createWrapper()
|
|
const spy = vi.spyOn(queryClient, 'invalidateQueries')
|
|
|
|
const { result } = renderHook(() => useUpdateEncounter(3), { wrapper })
|
|
await act(async () => {
|
|
await result.current.mutateAsync({ id: 1, data: {} } as never)
|
|
})
|
|
|
|
expect(spy).toHaveBeenCalledWith({ queryKey: ['runs', 3] })
|
|
})
|
|
})
|
|
|
|
describe('useDeleteEncounter', () => {
|
|
it('calls deleteEncounter with the encounter id', async () => {
|
|
vi.mocked(deleteEncounter).mockResolvedValue(undefined as never)
|
|
const { wrapper } = createWrapper()
|
|
|
|
const { result } = renderHook(() => useDeleteEncounter(3), { wrapper })
|
|
await act(async () => {
|
|
await result.current.mutateAsync(55)
|
|
})
|
|
|
|
expect(deleteEncounter).toHaveBeenCalledWith(55)
|
|
})
|
|
|
|
it('invalidates the run query on success', async () => {
|
|
vi.mocked(deleteEncounter).mockResolvedValue(undefined as never)
|
|
const { queryClient, wrapper } = createWrapper()
|
|
const spy = vi.spyOn(queryClient, 'invalidateQueries')
|
|
|
|
const { result } = renderHook(() => useDeleteEncounter(3), { wrapper })
|
|
await act(async () => {
|
|
await result.current.mutateAsync(55)
|
|
})
|
|
|
|
expect(spy).toHaveBeenCalledWith({ queryKey: ['runs', 3] })
|
|
})
|
|
})
|
|
|
|
describe('useEvolutions', () => {
|
|
it('is disabled when pokemonId is null', () => {
|
|
const { wrapper } = createWrapper()
|
|
const { result } = renderHook(() => useEvolutions(null), { wrapper })
|
|
expect(result.current.fetchStatus).toBe('idle')
|
|
expect(fetchEvolutions).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('fetches evolutions for a given pokemon', async () => {
|
|
vi.mocked(fetchEvolutions).mockResolvedValue([] as never)
|
|
const { wrapper } = createWrapper()
|
|
|
|
renderHook(() => useEvolutions(25, 'kanto'), { wrapper })
|
|
await waitFor(() => expect(fetchEvolutions).toHaveBeenCalledWith(25, 'kanto'))
|
|
})
|
|
})
|
|
|
|
describe('useForms', () => {
|
|
it('is disabled when pokemonId is null', () => {
|
|
const { wrapper } = createWrapper()
|
|
const { result } = renderHook(() => useForms(null), { wrapper })
|
|
expect(result.current.fetchStatus).toBe('idle')
|
|
})
|
|
|
|
it('fetches forms for a given pokemon', async () => {
|
|
vi.mocked(fetchForms).mockResolvedValue([] as never)
|
|
const { wrapper } = createWrapper()
|
|
|
|
renderHook(() => useForms(133), { wrapper })
|
|
await waitFor(() => expect(fetchForms).toHaveBeenCalledWith(133))
|
|
})
|
|
})
|
|
|
|
describe('useBulkRandomize', () => {
|
|
it('calls bulkRandomizeEncounters and invalidates the run', async () => {
|
|
vi.mocked(bulkRandomizeEncounters).mockResolvedValue([] as never)
|
|
const { queryClient, wrapper } = createWrapper()
|
|
const spy = vi.spyOn(queryClient, 'invalidateQueries')
|
|
|
|
const { result } = renderHook(() => useBulkRandomize(4), { wrapper })
|
|
await act(async () => {
|
|
await result.current.mutateAsync()
|
|
})
|
|
|
|
expect(bulkRandomizeEncounters).toHaveBeenCalledWith(4)
|
|
expect(spy).toHaveBeenCalledWith({ queryKey: ['runs', 4] })
|
|
})
|
|
})
|