-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Expand file tree
/
Copy pathuseInfiniteQuery.test.ts
More file actions
151 lines (123 loc) · 4.67 KB
/
useInfiniteQuery.test.ts
File metadata and controls
151 lines (123 loc) · 4.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
import { getCurrentInstance } from 'vue-demi'
import { sleep } from '@tanstack/query-test-utils'
import { useInfiniteQuery } from '../useInfiniteQuery'
import { infiniteQueryOptions } from '../infiniteQueryOptions'
import type { Mock } from 'vitest'
vi.mock('../useQueryClient')
vi.mock('../useBaseQuery')
describe('useInfiniteQuery', () => {
beforeEach(() => {
vi.useFakeTimers()
})
afterEach(() => {
vi.useRealTimers()
})
test('should properly execute infinite query', async () => {
const { data, fetchNextPage, status } = useInfiniteQuery({
queryKey: ['infiniteQuery'],
queryFn: ({ pageParam }) =>
sleep(0).then(() => 'data on page ' + pageParam),
initialPageParam: 0,
getNextPageParam: () => 12,
})
expect(data.value).toStrictEqual(undefined)
expect(status.value).toStrictEqual('pending')
await vi.advanceTimersByTimeAsync(0)
expect(data.value).toStrictEqual({
pageParams: [0],
pages: ['data on page 0'],
})
expect(status.value).toStrictEqual('success')
fetchNextPage()
await vi.advanceTimersByTimeAsync(0)
expect(data.value).toStrictEqual({
pageParams: [0, 12],
pages: ['data on page 0', 'data on page 12'],
})
expect(status.value).toStrictEqual('success')
})
test('should properly execute infinite query using infiniteQueryOptions', async () => {
const options = infiniteQueryOptions({
queryKey: ['infiniteQueryOptions'],
queryFn: ({ pageParam }) =>
sleep(0).then(() => 'data on page ' + pageParam),
initialPageParam: 0,
getNextPageParam: () => 12,
})
const { data, fetchNextPage, status } = useInfiniteQuery(options)
expect(data.value).toStrictEqual(undefined)
expect(status.value).toStrictEqual('pending')
await vi.advanceTimersByTimeAsync(0)
expect(data.value).toStrictEqual({
pageParams: [0],
pages: ['data on page 0'],
})
expect(status.value).toStrictEqual('success')
fetchNextPage()
await vi.advanceTimersByTimeAsync(0)
expect(data.value).toStrictEqual({
pageParams: [0, 12],
pages: ['data on page 0', 'data on page 12'],
})
expect(status.value).toStrictEqual('success')
})
describe('throwOnError', () => {
test('should throw from error watcher when throwOnError is true and suspense is not used', async () => {
const throwOnErrorFn = vi.fn().mockReturnValue(true)
useInfiniteQuery({
queryKey: ['infiniteThrowOnErrorWithoutSuspense'],
queryFn: () =>
sleep(10).then(() => Promise.reject(new Error('Some error'))),
initialPageParam: 0,
getNextPageParam: () => 12,
retry: false,
throwOnError: throwOnErrorFn,
})
// Suppress the Unhandled Rejection caused by watcher throw in Vue 3
const rejectionHandler = () => {}
process.on('unhandledRejection', rejectionHandler)
await vi.advanceTimersByTimeAsync(10)
process.off('unhandledRejection', rejectionHandler)
// throwOnError is evaluated and throw is attempted (not suppressed by suspense)
expect(throwOnErrorFn).toHaveBeenCalledTimes(1)
expect(throwOnErrorFn).toHaveBeenCalledWith(
Error('Some error'),
expect.objectContaining({
state: expect.objectContaining({ status: 'error' }),
}),
)
})
})
describe('suspense', () => {
test('should not throw from error watcher when suspense is handling the error with throwOnError: true', async () => {
const getCurrentInstanceSpy = getCurrentInstance as Mock
getCurrentInstanceSpy.mockImplementation(() => ({ suspense: {} }))
const throwOnErrorFn = vi.fn().mockReturnValue(true)
const query = useInfiniteQuery({
queryKey: ['infiniteSuspenseThrowOnError'],
queryFn: () =>
sleep(10).then(() => Promise.reject(new Error('Some error'))),
initialPageParam: 0,
getNextPageParam: () => 12,
retry: false,
throwOnError: throwOnErrorFn,
})
let rejectedError: unknown
const promise = query.suspense().catch((error) => {
rejectedError = error
})
await vi.advanceTimersByTimeAsync(10)
await promise
expect(rejectedError).toBeInstanceOf(Error)
expect((rejectedError as Error).message).toBe('Some error')
// throwOnError is evaluated in both suspense() and the error watcher
expect(throwOnErrorFn).toHaveBeenCalledTimes(2)
// but the error watcher should not throw when suspense is active
expect(query).toMatchObject({
status: { value: 'error' },
isError: { value: true },
})
})
})
})