import { createElement, type ReactNode } from 'react' import { act, renderHook, waitFor } from '@testing-library/react' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { beforeEach, describe, expect, it, vi } from 'vitest' import useAdminMutation from '@/hooks/useAdminMutation' import { adminKeys } from '@/queries/admin/adminKeys' const addToast = vi.fn() vi.mock('@/lib/toast', () => ({ addToast: (...args: unknown[]) => addToast(...args) })) const setup = () => { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false }, mutations: { retry: false } }, }) const wrapper = ({ children }: { children: ReactNode }) => createElement(QueryClientProvider, { client: queryClient }, children) return { queryClient, wrapper } } describe('useAdminMutation', () => { beforeEach(() => addToast.mockClear()) it('tracks the pending row, reports success and invalidates every list variation for the URL', async () => { let resolveAction!: () => void const action = vi.fn(() => new Promise((resolve) => (resolveAction = resolve))) const { queryClient, wrapper } = setup() const invalidateQueries = vi.spyOn(queryClient, 'invalidateQueries') const { result } = renderHook(() => useAdminMutation({ url: 'admin/reviews' }), { wrapper }) let promise!: Promise act(() => { promise = result.current.runAction('row-1', action, 'انجام شد') }) expect(result.current.pendingId).toBe('row-1') await waitFor(() => { expect(action).toHaveBeenCalledOnce() }) await act(async () => { resolveAction() await promise }) expect(result.current.pendingId).toBeNull() expect(invalidateQueries).toHaveBeenCalledWith({ queryKey: adminKeys.listByUrl('admin/reviews') }) expect(addToast).toHaveBeenCalledWith({ title: 'انجام شد', color: 'success' }) }) it('shows the server error and does not invalidate after failure', async () => { const { queryClient, wrapper } = setup() const invalidateQueries = vi.spyOn(queryClient, 'invalidateQueries') const { result } = renderHook(() => useAdminMutation({ url: 'admin/reviews' }), { wrapper }) let succeeded!: boolean await act(async () => { succeeded = await result.current.runAction('row-1', () => Promise.reject(new Error('خطای سرور')), 'انجام شد') }) expect(succeeded).toBe(false) expect(invalidateQueries).not.toHaveBeenCalled() expect(addToast).toHaveBeenCalledWith({ title: 'خطای سرور', color: 'danger' }) }) })