import { QueryClientProvider } from '@tanstack/react-query' import { renderHook, waitFor, act } from '@testing-library/react' import { createTestQueryClient } from '../test/utils' import { useGameBosses, useBossResults, useCreateBossResult, useDeleteBossResult, } from './useBosses' vi.mock('../api/bosses') vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } })) import { getGameBosses, getBossResults, createBossResult, deleteBossResult } from '../api/bosses' function createWrapper() { const queryClient = createTestQueryClient() const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} ) return { queryClient, wrapper } } describe('useGameBosses', () => { it('is disabled when gameId is null', () => { const { wrapper } = createWrapper() const { result } = renderHook(() => useGameBosses(null), { wrapper }) expect(result.current.fetchStatus).toBe('idle') expect(getGameBosses).not.toHaveBeenCalled() }) it('fetches bosses for a given game', async () => { const bosses = [{ id: 1, name: 'Brock' }] vi.mocked(getGameBosses).mockResolvedValue(bosses as never) const { wrapper } = createWrapper() const { result } = renderHook(() => useGameBosses(1), { wrapper }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) expect(getGameBosses).toHaveBeenCalledWith(1, undefined) expect(result.current.data).toEqual(bosses) }) it('passes the all flag to the API', async () => { vi.mocked(getGameBosses).mockResolvedValue([] as never) const { wrapper } = createWrapper() renderHook(() => useGameBosses(2, true), { wrapper }) await waitFor(() => expect(getGameBosses).toHaveBeenCalledWith(2, true)) }) }) describe('useBossResults', () => { it('fetches boss results for a given run', async () => { vi.mocked(getBossResults).mockResolvedValue([] as never) const { wrapper } = createWrapper() const { result } = renderHook(() => useBossResults(10), { wrapper }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) expect(getBossResults).toHaveBeenCalledWith(10) }) }) describe('useCreateBossResult', () => { it('calls createBossResult with the run id and input', async () => { vi.mocked(createBossResult).mockResolvedValue({} as never) const { wrapper } = createWrapper() const { result } = renderHook(() => useCreateBossResult(5), { wrapper }) const input = { bossId: 1, won: true } await act(async () => { await result.current.mutateAsync(input as never) }) expect(createBossResult).toHaveBeenCalledWith(5, input) }) it('invalidates boss results for the run on success', async () => { vi.mocked(createBossResult).mockResolvedValue({} as never) const { queryClient, wrapper } = createWrapper() const spy = vi.spyOn(queryClient, 'invalidateQueries') const { result } = renderHook(() => useCreateBossResult(5), { wrapper }) await act(async () => { await result.current.mutateAsync({} as never) }) expect(spy).toHaveBeenCalledWith({ queryKey: ['runs', 5, 'boss-results'] }) }) }) describe('useDeleteBossResult', () => { it('calls deleteBossResult with the run id and result id', async () => { vi.mocked(deleteBossResult).mockResolvedValue(undefined as never) const { wrapper } = createWrapper() const { result } = renderHook(() => useDeleteBossResult(5), { wrapper }) await act(async () => { await result.current.mutateAsync(99) }) expect(deleteBossResult).toHaveBeenCalledWith(5, 99) }) it('invalidates boss results for the run on success', async () => { vi.mocked(deleteBossResult).mockResolvedValue(undefined as never) const { queryClient, wrapper } = createWrapper() const spy = vi.spyOn(queryClient, 'invalidateQueries') const { result } = renderHook(() => useDeleteBossResult(5), { wrapper }) await act(async () => { await result.current.mutateAsync(99) }) expect(spy).toHaveBeenCalledWith({ queryKey: ['runs', 5, 'boss-results'] }) }) })