Skip to content

test(react-query/useSuspenseQueries): simplify 'queryFn' and add 'expect' for 'loading' text #9477

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 80 additions & 66 deletions packages/react-query/src/__tests__/useSuspenseQueries.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ const QUERY_DURATION = 1000

const createQuery: (id: number) => NumberQueryOptions = (id) => ({
queryKey: [id],
queryFn: async () => {
await sleep(QUERY_DURATION)
return id
},
queryFn: () => sleep(QUERY_DURATION).then(() => id),
})
const resolveQueries = () => vi.advanceTimersByTimeAsync(QUERY_DURATION)

Expand Down Expand Up @@ -59,7 +56,7 @@ describe('useSuspenseQueries', () => {
onSuspend()
}, [])

return null
return <div>loading</div>
}

const withSuspenseWrapper = <T extends object>(Component: React.FC<T>) => {
Expand Down Expand Up @@ -158,10 +155,7 @@ describe('useSuspenseQueries', () => {
const data = useSuspenseQueries({
queries: [1, 2, 3].map((value) => ({
queryKey: [...key, { value }],
queryFn: async () => {
await sleep(value * 10)
return { value: value * 10 }
},
queryFn: () => sleep(value * 10).then(() => ({ value: value * 10 })),
})),
combine: (result) => {
spy(result)
Expand All @@ -174,15 +168,18 @@ describe('useSuspenseQueries', () => {

const rendered = renderWithClient(
queryClient,
<React.Suspense fallback="loading...">
<React.Suspense fallback="loading">
<Page />
</React.Suspense>,
)

expect(rendered.getByText('loading...')).toBeInTheDocument()
expect(rendered.getByText('loading')).toBeInTheDocument()

expect(spy).not.toHaveBeenCalled()

await act(() => vi.advanceTimersByTimeAsync(30))
expect(rendered.getByText('data')).toBeInTheDocument()

expect(spy).toHaveBeenCalled()
})
})
Expand Down Expand Up @@ -211,22 +208,23 @@ describe('useSuspenseQueries 2', () => {
queries: [
{
queryKey: key1,
queryFn: async () => {
results.push('1')
await sleep(10)
return '1'
},
queryFn: () =>
sleep(10).then(() => {
results.push('1')
return '1'
}),
},
{
queryKey: key2,
queryFn: async () => {
results.push('2')
await sleep(20)
return '2'
},
queryFn: () =>
sleep(20).then(() => {
results.push('2')
return '2'
}),
},
],
})

return (
<div>
<h1>data: {result.map((item) => item.data ?? 'null').join(',')}</h1>
Expand All @@ -244,7 +242,8 @@ describe('useSuspenseQueries 2', () => {
expect(rendered.getByText('loading')).toBeInTheDocument()
await act(() => vi.advanceTimersByTimeAsync(20))
expect(rendered.getByText('data: 1,2')).toBeInTheDocument()
expect(results).toEqual(['1', '2', 'loading'])

expect(results).toEqual(['loading', '1', '2'])
})

it("shouldn't unmount before all promises fetched", async () => {
Expand All @@ -264,24 +263,25 @@ describe('useSuspenseQueries 2', () => {
queries: [
{
queryKey: key1,
queryFn: async () => {
refs.push(ref.current)
results.push('1')
await sleep(10)
return '1'
},
queryFn: () =>
sleep(10).then(() => {
refs.push(ref.current)
results.push('1')
return '1'
}),
},
{
queryKey: key2,
queryFn: async () => {
refs.push(ref.current)
results.push('2')
await sleep(20)
return '2'
},
queryFn: () =>
sleep(20).then(() => {
refs.push(ref.current)
results.push('2')
return '2'
}),
},
],
})

return (
<div>
<h1>data: {result.map((item) => item.data ?? 'null').join(',')}</h1>
Expand All @@ -297,9 +297,11 @@ describe('useSuspenseQueries 2', () => {
)

expect(rendered.getByText('loading')).toBeInTheDocument()
expect(refs.length).toBe(2)

await act(() => vi.advanceTimersByTimeAsync(20))
expect(rendered.getByText('data: 1,2')).toBeInTheDocument()

expect(refs.length).toBe(2)
expect(refs[0]).toBe(refs[1])
})

Expand Down Expand Up @@ -348,6 +350,7 @@ describe('useSuspenseQueries 2', () => {
document.dispatchEvent(new CustomEvent('online'))

fireEvent.click(rendered.getByText('fetch'))
expect(rendered.getByText('loading')).toBeInTheDocument()
await act(() => vi.advanceTimersByTimeAsync(10))
// query should resume
expect(rendered.getByText('Data 1')).toBeInTheDocument()
Expand All @@ -374,30 +377,33 @@ describe('useSuspenseQueries 2', () => {
return (
<div>
<button onClick={() => setFail(true)}>trigger fail</button>

<div>rendered: {String(data)}</div>
<div>rendered: {data}</div>
</div>
)
}

const rendered = renderWithClient(
queryClient,
<ErrorBoundary fallbackRender={() => <div>error boundary</div>}>
<React.Suspense fallback={'Loading...'}>
<React.Suspense fallback="loading">
<Page />
</React.Suspense>
</ErrorBoundary>,
)

expect(rendered.getByText('Loading...')).toBeInTheDocument()
expect(rendered.getByText('loading')).toBeInTheDocument()
await act(() => vi.advanceTimersByTimeAsync(10))
expect(rendered.getByText('rendered: data')).toBeInTheDocument()

fireEvent.click(rendered.getByText('trigger fail'))
expect(rendered.getByText('loading')).toBeInTheDocument()
await act(() => vi.advanceTimersByTimeAsync(10))
expect(rendered.getByText('error boundary')).toBeInTheDocument()

expect(consoleMock.mock.calls[0]?.[1]).toStrictEqual(
new Error('Suspense Error Bingo'),
)

consoleMock.mockRestore()
})

Expand All @@ -409,7 +415,7 @@ describe('useSuspenseQueries 2', () => {
const [isPending, startTransition] = React.useTransition()
const { data } = useSuspenseQuery({
queryKey: [key, count],
queryFn: async () => sleep(10).then(() => 'data' + count),
queryFn: () => sleep(10).then(() => 'data' + count),
})

return (
Expand All @@ -418,23 +424,24 @@ describe('useSuspenseQueries 2', () => {
inc
</button>

<div>{isPending ? 'Pending...' : String(data)}</div>
<div>{isPending ? 'pending' : data}</div>
</div>
)
}

const rendered = renderWithClient(
queryClient,
<React.Suspense fallback={'Loading...'}>
<React.Suspense fallback="loading">
<Page />
</React.Suspense>,
)

expect(rendered.getByText('Loading...')).toBeInTheDocument()
expect(rendered.getByText('loading')).toBeInTheDocument()
await act(() => vi.advanceTimersByTimeAsync(10))
expect(rendered.getByText('data0')).toBeInTheDocument()

fireEvent.click(rendered.getByText('inc'))
expect(rendered.getByText('Pending...')).toBeInTheDocument()
expect(rendered.getByText('pending')).toBeInTheDocument()
await act(() => vi.advanceTimersByTimeAsync(10))
expect(rendered.getByText('data1')).toBeInTheDocument()
})
Expand All @@ -453,7 +460,7 @@ describe('useSuspenseQueries 2', () => {
>
inc
</button>
<React.Suspense fallback={'Loading...'}>
<React.Suspense fallback="loading">
<Page count={count} />
</React.Suspense>
</div>
Expand All @@ -463,11 +470,11 @@ describe('useSuspenseQueries 2', () => {
function Page({ count }: { count: number }) {
const { data } = useSuspenseQuery({
queryKey: [key, count],
queryFn: async () => {
queryFnCount++
await sleep(10)
return 'data' + count
},
queryFn: () =>
sleep(10).then(() => {
queryFnCount++
return 'data' + count
}),
})

return (
Expand All @@ -483,12 +490,14 @@ describe('useSuspenseQueries 2', () => {
<App />,
)

expect(rendered.getByText('Loading...')).toBeInTheDocument()
expect(rendered.getByText('loading')).toBeInTheDocument()
await act(() => vi.advanceTimersByTimeAsync(10))
expect(rendered.getByText('data0')).toBeInTheDocument()

fireEvent.click(rendered.getByText('inc'))
await act(() => vi.advanceTimersByTimeAsync(10))
expect(rendered.getByText('data1')).toBeInTheDocument()

expect(queryFnCount).toBe(2)
})

Expand All @@ -507,32 +516,32 @@ describe('useSuspenseQueries 2', () => {
const [isPending, startTransition] = React.useTransition()
const { data } = useSuspenseQuery({
queryKey: [key, count],
queryFn: async () => sleep(10).then(() => 'data' + count),
queryFn: () => sleep(10).then(() => 'data' + count),
})

return (
<div>
<button onClick={() => startTransition(() => setCount(count + 1))}>
inc
</button>

<div>{isPending ? 'Pending...' : String(data)}</div>
<div>{isPending ? 'pending' : data}</div>
</div>
)
}

const rendered = renderWithClient(
queryClientWithPlaceholder,
<React.Suspense fallback={'Loading...'}>
<React.Suspense fallback="loading">
<Page />
</React.Suspense>,
)

expect(rendered.getByText('Loading...')).toBeInTheDocument()
expect(rendered.getByText('loading')).toBeInTheDocument()
await act(() => vi.advanceTimersByTimeAsync(10))
expect(rendered.getByText('data0')).toBeInTheDocument()

fireEvent.click(rendered.getByText('inc'))
expect(rendered.getByText('Pending...')).toBeInTheDocument()
expect(rendered.getByText('pending')).toBeInTheDocument()
await act(() => vi.advanceTimersByTimeAsync(10))
expect(rendered.getByText('data1')).toBeInTheDocument()
})
Expand All @@ -547,11 +556,11 @@ describe('useSuspenseQueries 2', () => {
function Page() {
useSuspenseQuery({
queryKey: key,
queryFn: async () => {
count++
await sleep(10)
return Promise.reject(new Error('Query failed'))
},
queryFn: () =>
sleep(10).then(() => {
count++
throw new Error('Query failed')
}),
gcTime: 0,
retry: false,
})
Expand All @@ -575,9 +584,12 @@ describe('useSuspenseQueries 2', () => {

const rendered = renderWithClient(queryClient, <App />)

expect(rendered.getByText('loading')).toBeInTheDocument()
await act(() => vi.advanceTimersByTimeAsync(10))
expect(rendered.getByText('There was an error!')).toBeInTheDocument()

expect(count).toBe(1)

consoleMock.mockRestore()
})

Expand All @@ -604,7 +616,7 @@ describe('useSuspenseQueries 2', () => {
function Component() {
const { data } = useSuspenseQuery({
queryKey: key,
queryFn: async () => sleep(3000).then(() => 'data'),
queryFn: () => sleep(3000).then(() => 'data'),
gcTime: 1000,
})

Expand All @@ -617,6 +629,7 @@ describe('useSuspenseQueries 2', () => {

function App() {
const [show, setShow] = React.useState(true)

return (
<div>
{show ? <Page /> : <Page2 />}
Expand All @@ -628,6 +641,7 @@ describe('useSuspenseQueries 2', () => {
const rendered = renderWithClient(queryClient, <App />)

expect(rendered.getByText('loading')).toBeInTheDocument()

fireEvent.click(rendered.getByText('hide'))
expect(rendered.getByText('page2')).toBeInTheDocument()
// wait for query to be resolved
Expand Down Expand Up @@ -661,7 +675,7 @@ describe('useSuspenseQueries 2', () => {

function App() {
return (
<React.Suspense fallback="Loading...">
<React.Suspense fallback="loading">
<Page />
</React.Suspense>
)
Expand Down Expand Up @@ -699,7 +713,7 @@ describe('useSuspenseQueries 2', () => {

renderWithClient(
queryClient,
<React.Suspense fallback="Loading...">
<React.Suspense fallback="loading">
<Page />
</React.Suspense>,
)
Expand Down Expand Up @@ -735,7 +749,7 @@ describe('useSuspenseQueries 2', () => {

renderWithClient(
queryClient,
<React.Suspense fallback="Loading...">
<React.Suspense fallback="loading">
<Page />
</React.Suspense>,
)
Expand Down
Loading