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 }) => ( {children} ) 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] }) }) })