diff --git a/packages/solid-query/src/__tests__/useMutation.test.tsx b/packages/solid-query/src/__tests__/useMutation.test.tsx index 4c23bf383e7..d1d4a8a579b 100644 --- a/packages/solid-query/src/__tests__/useMutation.test.tsx +++ b/packages/solid-query/src/__tests__/useMutation.test.tsx @@ -1,11 +1,11 @@ -import { describe, expect, it, vi } from 'vitest' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { ErrorBoundary, createEffect, createRenderEffect, createSignal, } from 'solid-js' -import { fireEvent, render, waitFor } from '@solidjs/testing-library' +import { fireEvent, render } from '@solidjs/testing-library' import { MutationCache, QueryCache, QueryClientProvider, useMutation } from '..' import { createQueryClient, @@ -17,6 +17,14 @@ import { import type { UseMutationResult } from '../types' describe('useMutation', () => { + beforeEach(() => { + vi.useFakeTimers() + }) + + afterEach(() => { + vi.useRealTimers() + }) + const queryCache = new QueryCache() const mutationCache = new MutationCache() const queryClient = createQueryClient({ queryCache, mutationCache }) @@ -46,15 +54,14 @@ describe('useMutation', () => { fireEvent.click(rendered.getByRole('button', { name: /mutate/i })) - await waitFor(() => { + await vi.waitFor(() => { expect(rendered.getByRole('heading').textContent).toBe('mutation') }) fireEvent.click(rendered.getByRole('button', { name: /reset/i })) - await waitFor(() => { - expect(rendered.getByRole('heading').textContent).toBe('empty') - }) + await vi.waitFor(() => {}) + expect(rendered.getByRole('heading').textContent).toBe('empty') }) it('should be able to reset `error`', async () => { @@ -86,13 +93,11 @@ describe('useMutation', () => { )) - await waitFor(() => { - expect(rendered.queryByRole('heading')).toBeNull() - }) + expect(rendered.queryByRole('heading')).toBeNull() fireEvent.click(rendered.getByRole('button', { name: /mutate/i })) - await waitFor(() => { + await vi.waitFor(() => { expect(rendered.getByRole('heading').textContent).toBe( 'Expected mock error. All is well!', ) @@ -100,7 +105,7 @@ describe('useMutation', () => { fireEvent.click(rendered.getByRole('button', { name: /reset/i })) - await waitFor(() => { + await vi.waitFor(() => { expect(rendered.queryByRole('heading')).toBeNull() }) @@ -150,11 +155,11 @@ describe('useMutation', () => { fireEvent.click(rendered.getByRole('button', { name: /mutate/i })) fireEvent.click(rendered.getByRole('button', { name: /mutate/i })) - await waitFor(() => { + await vi.waitFor(() => { expect(rendered.getByRole('heading').textContent).toBe('3') }) - await waitFor(() => { + await vi.waitFor(() => { expect(onSuccessMock).toHaveBeenCalledTimes(3) }) @@ -162,7 +167,7 @@ describe('useMutation', () => { expect(onSuccessMock).toHaveBeenCalledWith(2) expect(onSuccessMock).toHaveBeenCalledWith(3) - await waitFor(() => { + await vi.waitFor(() => { expect(onSettledMock).toHaveBeenCalledTimes(3) }) @@ -177,14 +182,11 @@ describe('useMutation', () => { const mutateFn = vi.fn<(value: Value) => Promise>() - mutateFn.mockImplementationOnce(() => { - return Promise.reject(new Error('Error test Jonas')) - }) + mutateFn.mockImplementationOnce(() => + Promise.reject(new Error('Error test Jonas')), + ) - mutateFn.mockImplementation(async (value) => { - await sleep(10) - return Promise.resolve(value) - }) + mutateFn.mockImplementation((value) => sleep(10).then(() => value)) function Page() { const mutation = useMutation(() => ({ @@ -215,20 +217,22 @@ describe('useMutation', () => { )) - await waitFor(() => rendered.getByText('Data')) + rendered.getByText('Data') fireEvent.click(rendered.getByRole('button', { name: /mutate/i })) - await waitFor(() => rendered.getByText('Data')) - await waitFor(() => rendered.getByText('Status error')) - await waitFor(() => rendered.getByText('Failed 1 times')) - await waitFor(() => rendered.getByText('Failed because Error test Jonas')) + rendered.getByText('Data') + await vi.waitFor(() => rendered.getByText('Status error')) + await vi.waitFor(() => rendered.getByText('Failed 1 times')) + await vi.waitFor(() => + rendered.getByText('Failed because Error test Jonas'), + ) fireEvent.click(rendered.getByRole('button', { name: /mutate/i })) - await waitFor(() => rendered.getByText('Status pending')) - await waitFor(() => rendered.getByText('Status success')) - await waitFor(() => rendered.getByText('Data 2')) - await waitFor(() => rendered.getByText('Failed 0 times')) - await waitFor(() => rendered.getByText('Failed because null')) + await vi.waitFor(() => rendered.getByText('Status pending')) + await vi.waitFor(() => rendered.getByText('Status success')) + await vi.waitFor(() => rendered.getByText('Data 2')) + await vi.waitFor(() => rendered.getByText('Failed 0 times')) + await vi.waitFor(() => rendered.getByText('Failed because null')) }) it('should be able to call `onError` and `onSettled` after each failed mutate', async () => { @@ -280,11 +284,11 @@ describe('useMutation', () => { fireEvent.click(rendered.getByRole('button', { name: /mutate/i })) fireEvent.click(rendered.getByRole('button', { name: /mutate/i })) - await waitFor(() => { + await vi.waitFor(() => { expect(rendered.getByRole('heading').textContent).toBe('3') }) - await waitFor(() => { + await vi.waitFor(() => { expect(onErrorMock).toHaveBeenCalledTimes(3) }) expect(onErrorMock).toHaveBeenCalledWith( @@ -297,7 +301,7 @@ describe('useMutation', () => { 'Expected mock error. All is well! 3', ) - await waitFor(() => { + await vi.waitFor(() => { expect(onSettledMock).toHaveBeenCalledTimes(3) }) expect(onSettledMock).toHaveBeenCalledWith( @@ -351,7 +355,7 @@ describe('useMutation', () => { )) - await sleep(100) + await vi.advanceTimersByTimeAsync(10) expect(callbacks).toEqual([ 'useMutation.onSuccess', @@ -367,7 +371,7 @@ describe('useMutation', () => { function Page() { const mutation = useMutation(() => ({ - mutationFn: async (_text: string) => Promise.reject(new Error('oops')), + mutationFn: (_text: string) => Promise.reject(new Error('oops')), onError: () => { callbacks.push('useMutation.onError') @@ -404,7 +408,7 @@ describe('useMutation', () => { )) - await sleep(100) + await vi.advanceTimersByTimeAsync(10) expect(callbacks).toEqual([ 'useMutation.onError', @@ -419,10 +423,7 @@ describe('useMutation', () => { const key = queryKey() queryClient.setMutationDefaults(key, { - mutationFn: async (text: string) => { - await sleep(10) - return text - }, + mutationFn: (text: string) => sleep(10).then(() => text), }) const states: Array> = [] @@ -452,7 +453,7 @@ describe('useMutation', () => { )) - await sleep(100) + await vi.advanceTimersByTimeAsync(20) expect(states.length).toBe(3) expect(states[0]).toMatchObject({ data: undefined, isPending: false }) @@ -489,7 +490,7 @@ describe('useMutation', () => { )) - await sleep(100) + await vi.advanceTimersByTimeAsync(20) expect(count).toBe(2) }) @@ -529,34 +530,27 @@ describe('useMutation', () => { )) - await waitFor(() => { - expect( - rendered.getByText('error: null, status: idle, isPaused: false'), - ).toBeInTheDocument() - }) + expect( + rendered.getByText('error: null, status: idle, isPaused: false'), + ).toBeInTheDocument() window.dispatchEvent(new Event('offline')) fireEvent.click(rendered.getByRole('button', { name: /mutate/i })) - await waitFor(() => { - expect( - rendered.getByText('error: null, status: pending, isPaused: true'), - ).toBeInTheDocument() - }) + expect( + rendered.getByText('error: null, status: pending, isPaused: true'), + ).toBeInTheDocument() expect(count).toBe(0) onlineMock.mockRestore() window.dispatchEvent(new Event('online')) - await sleep(100) - - await waitFor(() => { - expect( - rendered.getByText('error: oops, status: error, isPaused: false'), - ).toBeInTheDocument() - }) + await vi.advanceTimersByTimeAsync(5) + expect( + rendered.getByText('error: oops, status: error, isPaused: false'), + ).toBeInTheDocument() expect(count).toBe(2) }) @@ -607,6 +601,7 @@ describe('useMutation', () => { onlineMock.mockRestore() window.dispatchEvent(new Event('online')) + await vi.advanceTimersByTimeAsync(10) await rendered.findByText('data: 1, status: success, isPaused: false') expect(onMutate).toHaveBeenCalledTimes(1) @@ -661,6 +656,7 @@ describe('useMutation', () => { onlineMock.mockReturnValue(true) window.dispatchEvent(new Event('online')) + await vi.advanceTimersByTimeAsync(10) await rendered.findByText('data: 1, status: success, isPaused: false') onlineMock.mockRestore() @@ -707,7 +703,7 @@ describe('useMutation', () => { )) - await sleep(50) + await vi.advanceTimersByTimeAsync(16) expect(states.length).toBe(4) expect(states[0]).toMatchObject({ @@ -738,7 +734,7 @@ describe('useMutation', () => { onlineMock.mockRestore() window.dispatchEvent(new Event('online')) - await sleep(50) + await vi.advanceTimersByTimeAsync(1) expect(states.length).toBe(6) expect(states[4]).toMatchObject({ @@ -818,7 +814,7 @@ describe('useMutation', () => { fireEvent.click(rendered.getByText('mutate')) - await waitFor(() => { + await vi.waitFor(() => { expect(rendered.queryByText('error')).not.toBeNull() }) @@ -868,13 +864,13 @@ describe('useMutation', () => { // first error goes to component fireEvent.click(rendered.getByText('mutate')) - await waitFor(() => { + await vi.waitFor(() => { expect(rendered.queryByText('mock error')).not.toBeNull() }) // second error goes to boundary fireEvent.click(rendered.getByText('mutate')) - await waitFor(() => { + await vi.waitFor(() => { expect(rendered.queryByText('error boundary')).not.toBeNull() }) @@ -930,7 +926,7 @@ describe('useMutation', () => { fireEvent.click(rendered.getByText('succeed')) fireEvent.click(rendered.getByText('error')) - await waitFor(() => { + await vi.waitFor(() => { expect(rendered.queryByText('successTest')).not.toBeNull() expect(rendered.queryByText('errorTest')).not.toBeNull() }) @@ -1003,7 +999,7 @@ describe('useMutation', () => { fireEvent.click(rendered.getByRole('button', { name: /mutate/i })) fireEvent.click(rendered.getByRole('button', { name: /hide/i })) - await waitFor(() => { + await vi.waitFor(() => { expect( queryClient.getMutationCache().findAll({ mutationKey: mutationKey }), ).toHaveLength(0) @@ -1065,6 +1061,7 @@ describe('useMutation', () => { fireEvent.click(rendered.getByRole('button', { name: /mutate/i })) fireEvent.click(rendered.getByRole('button', { name: /mutate/i })) + await vi.advanceTimersByTimeAsync(10) await rendered.findByText('data: result2, status: success') expect(count).toBe(2) @@ -1114,6 +1111,7 @@ describe('useMutation', () => { rendered.getByRole('button', { name: /mutate/i }).click() + await vi.advanceTimersByTimeAsync(10) await rendered.findByText('status: error') expect(onError).toHaveBeenCalledWith(error, 'todo', undefined) @@ -1154,6 +1152,7 @@ describe('useMutation', () => { rendered.getByRole('button', { name: /mutate/i }).click() + await vi.advanceTimersByTimeAsync(10) await rendered.findByText('error: mutateFnError, status: error') }) @@ -1194,6 +1193,7 @@ describe('useMutation', () => { rendered.getByRole('button', { name: /mutate/i }).click() + await vi.advanceTimersByTimeAsync(10) await rendered.findByText('error: mutateFnError, status: error') expect(onError).toHaveBeenCalledWith(mutateFnError, 'todo', undefined)