Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
69 lines
2.5 KiB
TypeScript
69 lines
2.5 KiB
TypeScript
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<void>((resolve) => (resolveAction = resolve)))
|
|
const { queryClient, wrapper } = setup()
|
|
const invalidateQueries = vi.spyOn(queryClient, 'invalidateQueries')
|
|
const { result } = renderHook(() => useAdminMutation({ url: 'admin/reviews' }), { wrapper })
|
|
|
|
let promise!: Promise<boolean>
|
|
|
|
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' })
|
|
})
|
|
})
|