import { queryKey, sleep } from '@tanstack/query-test-utils' import { fireEvent, render } from '@testing-library/preact' import { useEffect } from 'preact/hooks' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { QueryClient, useIsMutating, useMutation, useMutationState } from '..' import { renderWithClient } from './utils' describe('useIsMutating', () => { beforeEach(() => { vi.useFakeTimers() }) afterEach(() => { vi.useRealTimers() }) it('should return the number of fetching mutations', async () => { const isMutatingArray: Array = [] const queryClient = new QueryClient() const mutationKey1 = queryKey() const mutationKey2 = queryKey() function IsMutating() { const isMutating = useIsMutating() isMutatingArray.push(isMutating) return null } function Mutations() { const { mutate: mutate1 } = useMutation({ mutationKey: mutationKey1, mutationFn: () => sleep(50).then(() => 'data'), }) const { mutate: mutate2 } = useMutation({ mutationKey: mutationKey2, mutationFn: () => sleep(10).then(() => 'data'), }) return (
) } function Page() { return (
) } const rendered = renderWithClient(queryClient, ) fireEvent.click(rendered.getByRole('button', { name: /mutate1/i })) await vi.advanceTimersByTimeAsync(10) fireEvent.click(rendered.getByRole('button', { name: /mutate2/i })) // we don't really care if this yields // [ +0, 1, 2, +0 ] // or // [ +0, 1, 2, 1, +0 ] // our batching strategy might yield different results await vi.advanceTimersByTimeAsync(41) expect(isMutatingArray[0]).toEqual(0) expect(isMutatingArray[1]).toEqual(1) expect(isMutatingArray[2]).toEqual(2) expect(isMutatingArray[3]).toEqual(1) expect(isMutatingArray[4]).toEqual(0) expect(isMutatingArray).toEqual([0, 1, 2, 1, 0]) }) it('should filter correctly by mutationKey', async () => { const isMutatingArray: Array = [] const queryClient = new QueryClient() const mutationKey1 = queryKey() const mutationKey2 = queryKey() function IsMutating() { const isMutating = useIsMutating({ mutationKey: mutationKey1 }) isMutatingArray.push(isMutating) return null } function Page() { const { mutate: mutate1 } = useMutation({ mutationKey: mutationKey1, mutationFn: () => sleep(100).then(() => 'data'), }) const { mutate: mutate2 } = useMutation({ mutationKey: mutationKey2, mutationFn: () => sleep(100).then(() => 'data'), }) useEffect(() => { mutate1() mutate2() }, [mutate1, mutate2]) return } renderWithClient(queryClient, ) await vi.advanceTimersByTimeAsync(101) expect(isMutatingArray).toEqual([0, 1, 0]) }) it('should filter correctly by predicate', async () => { const isMutatingArray: Array = [] const queryClient = new QueryClient() const mutationKey1 = queryKey() const mutationKey2 = queryKey() function IsMutating() { const isMutating = useIsMutating({ predicate: (mutation) => mutation.options.mutationKey?.[0] === mutationKey1[0], }) isMutatingArray.push(isMutating) return null } function Page() { const { mutate: mutate1 } = useMutation({ mutationKey: mutationKey1, mutationFn: () => sleep(100).then(() => 'data'), }) const { mutate: mutate2 } = useMutation({ mutationKey: mutationKey2, mutationFn: () => sleep(100).then(() => 'data'), }) useEffect(() => { mutate1() mutate2() }, [mutate1, mutate2]) return } renderWithClient(queryClient, ) await vi.advanceTimersByTimeAsync(101) expect(isMutatingArray).toEqual([0, 1, 0]) }) it('should use provided custom queryClient', async () => { const queryClient = new QueryClient() const key = queryKey() function Page() { const isMutating = useIsMutating({}, queryClient) const { mutate } = useMutation( { mutationKey: key, mutationFn: () => sleep(10).then(() => 'data'), }, queryClient, ) useEffect(() => { mutate() }, [mutate]) return (
mutating: {isMutating}
) } const rendered = render() await vi.advanceTimersByTimeAsync(0) expect(rendered.getByText('mutating: 1')).toBeInTheDocument() }) }) describe('useMutationState', () => { beforeEach(() => { vi.useFakeTimers() }) afterEach(() => { vi.useRealTimers() }) it('should return variables after calling mutate', async () => { const queryClient = new QueryClient() const variables: Array> = [] const mutationKey = queryKey() function Variables() { variables.push( useMutationState({ filters: { mutationKey, status: 'pending' }, select: (mutation) => mutation.state.variables, }), ) return null } function Mutate() { const { mutate, data } = useMutation({ mutationKey, mutationFn: (input: number) => sleep(150).then(() => `data${input}`), }) return (
data: {data ?? 'null'}
) } function Page() { return (
) } const rendered = renderWithClient(queryClient, ) expect(rendered.getByText('data: null')).toBeInTheDocument() fireEvent.click(rendered.getByRole('button', { name: /mutate/i })) await vi.advanceTimersByTimeAsync(151) expect(rendered.getByText('data: data1')).toBeInTheDocument() expect(variables).toEqual([[], [1], []]) }) })