import { queryKey, sleep } from '@tanstack/query-test-utils' import { render } from '@testing-library/preact' import type { ComponentChildren } from 'preact' import { Suspense } from 'preact/compat' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { QueryClient, QueryClientProvider, useSuspenseQuery } from '..' import type { StaleTime } from '@tanstack/query-core' import type { QueryKey } from '..' function renderWithSuspense(client: QueryClient, ui: ComponentChildren) { return render( {ui} , ) } function createTestQuery(options: { fetchCount: { count: number } queryKey: QueryKey staleTime?: StaleTime | (() => StaleTime) }) { return function TestComponent() { const { data } = useSuspenseQuery({ queryKey: options.queryKey, queryFn: () => sleep(10).then(() => { options.fetchCount.count++ return 'data' }), staleTime: options.staleTime, }) return
data: {data}
} } describe('Suspense Timer Tests', () => { let queryClient: QueryClient let fetchCount: { count: number } beforeEach(() => { vi.useFakeTimers() queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, }, }, }) fetchCount = { count: 0 } }) afterEach(() => { queryClient.clear() vi.useRealTimers() }) it('should enforce minimum staleTime of 1000ms when using suspense with number', async () => { const TestComponent = createTestQuery({ fetchCount, queryKey: queryKey(), staleTime: 10, }) const rendered = renderWithSuspense(queryClient, ) expect(rendered.getByText('loading')).toBeInTheDocument() await vi.advanceTimersByTimeAsync(10) expect(rendered.getByText('data: data')).toBeInTheDocument() rendered.rerender( , ) await vi.advanceTimersByTimeAsync(10) expect(fetchCount.count).toBe(1) }) it('should enforce minimum staleTime of 1000ms when using suspense with function', async () => { const TestComponent = createTestQuery({ fetchCount, queryKey: queryKey(), staleTime: () => 10, }) const rendered = renderWithSuspense(queryClient, ) expect(rendered.getByText('loading')).toBeInTheDocument() await vi.advanceTimersByTimeAsync(10) expect(rendered.getByText('data: data')).toBeInTheDocument() rendered.rerender( , ) await vi.advanceTimersByTimeAsync(10) expect(fetchCount.count).toBe(1) }) it('should respect staleTime when value is greater than 1000ms', async () => { const TestComponent = createTestQuery({ fetchCount, queryKey: queryKey(), staleTime: 2000, }) const rendered = renderWithSuspense(queryClient, ) expect(rendered.getByText('loading')).toBeInTheDocument() await vi.advanceTimersByTimeAsync(10) expect(rendered.getByText('data: data')).toBeInTheDocument() rendered.rerender( , ) await vi.advanceTimersByTimeAsync(1500) expect(fetchCount.count).toBe(1) }) it('should enforce minimum staleTime when undefined is provided', async () => { const TestComponent = createTestQuery({ fetchCount, queryKey: queryKey(), staleTime: undefined, }) const rendered = renderWithSuspense(queryClient, ) expect(rendered.getByText('loading')).toBeInTheDocument() await vi.advanceTimersByTimeAsync(10) expect(rendered.getByText('data: data')).toBeInTheDocument() rendered.rerender( , ) await vi.advanceTimersByTimeAsync(500) expect(fetchCount.count).toBe(1) }) it('should preserve staleTime when value is static', async () => { const TestComponent = createTestQuery({ fetchCount, queryKey: queryKey(), staleTime: 'static', }) const rendered = renderWithSuspense(queryClient, ) expect(rendered.getByText('loading')).toBeInTheDocument() await vi.advanceTimersByTimeAsync(10) expect(rendered.getByText('data: data')).toBeInTheDocument() rendered.rerender( , ) await vi.advanceTimersByTimeAsync(2000) expect(fetchCount.count).toBe(1) }) it('should preserve staleTime when function returns static', async () => { const TestComponent = createTestQuery({ fetchCount, queryKey: queryKey(), staleTime: () => 'static', }) const rendered = renderWithSuspense(queryClient, ) expect(rendered.getByText('loading')).toBeInTheDocument() await vi.advanceTimersByTimeAsync(10) expect(rendered.getByText('data: data')).toBeInTheDocument() rendered.rerender( , ) await vi.advanceTimersByTimeAsync(2000) expect(fetchCount.count).toBe(1) }) it('should respect staleTime when function returns value greater than 1000ms', async () => { const TestComponent = createTestQuery({ fetchCount, queryKey: queryKey(), staleTime: () => 3000, }) const rendered = renderWithSuspense(queryClient, ) expect(rendered.getByText('loading')).toBeInTheDocument() await vi.advanceTimersByTimeAsync(10) expect(rendered.getByText('data: data')).toBeInTheDocument() rendered.rerender( , ) await vi.advanceTimersByTimeAsync(2000) expect(fetchCount.count).toBe(1) }) })