@@ -3,9 +3,10 @@ import { server, baseUrl, useMockRequestHandler } from "./fixtures/mock-server.j
3
3
import type { paths } from "./fixtures/api.js" ;
4
4
import createClient from "../src/index.js" ;
5
5
import createFetchClient from "openapi-fetch" ;
6
- import { renderHook , waitFor } from "@testing-library/react" ;
7
- import { QueryClient , QueryClientProvider } from "@tanstack/react-query" ;
8
- import React , { type ReactNode } from "react" ;
6
+ import { act , render , renderHook , screen , waitFor } from "@testing-library/react" ;
7
+ import { QueryClient , QueryClientProvider , QueryErrorResetBoundary } from "@tanstack/react-query" ;
8
+ import React , { Suspense , type ReactNode } from "react" ;
9
+ import { ErrorBoundary } from "react-error-boundary" ;
9
10
10
11
const queryClient = new QueryClient ( {
11
12
defaultOptions : {
@@ -70,7 +71,7 @@ describe("client", () => {
70
71
expect ( error ) . toBeNull ( ) ;
71
72
} ) ;
72
73
73
- it ( "should resolve error properlly and have undefined data when failed request" , async ( ) => {
74
+ it ( "should resolve error properly and have undefined data when failed request" , async ( ) => {
74
75
const fetchClient = createFetchClient < paths > ( { baseUrl } ) ;
75
76
const client = createClient ( fetchClient ) ;
76
77
@@ -109,7 +110,7 @@ describe("client", () => {
109
110
} ) ;
110
111
111
112
describe ( "params" , ( ) => {
112
- it ( "typechecks " , async ( ) => {
113
+ it ( "should be required if OpenAPI schema requires params " , async ( ) => {
113
114
const fetchClient = createFetchClient < paths > ( { baseUrl } ) ;
114
115
const client = createClient ( fetchClient ) ;
115
116
@@ -132,56 +133,158 @@ describe("client", () => {
132
133
} ) ;
133
134
134
135
describe ( "useSuspenseQuery" , ( ) => {
135
- it ( "should work " , async ( ) => {
136
+ it ( "should resolve data properly and have error as null when successfull request " , async ( ) => {
136
137
const fetchClient = createFetchClient < paths > ( { baseUrl } ) ;
137
138
const client = createClient ( fetchClient ) ;
138
139
139
140
useMockRequestHandler ( {
140
141
baseUrl,
141
142
method : "get" ,
142
- path : "/self " ,
143
+ path : "/string-array " ,
143
144
status : 200 ,
144
- body : { message : "OK" } ,
145
+ body : [ "one" , "two" , "three" ] ,
145
146
} ) ;
146
147
147
- const { result } = renderHook ( ( ) => client . useSuspenseQuery ( "get" , "/self " ) , {
148
+ const { result } = renderHook ( ( ) => client . useSuspenseQuery ( "get" , "/string-array " ) , {
148
149
wrapper,
149
150
} ) ;
150
151
151
- await waitFor ( ( ) => expect ( result . current . isSuccess ) . toBe ( true ) ) ;
152
+ await waitFor ( ( ) => expect ( result . current . isFetching ) . toBe ( false ) ) ;
152
153
153
- expect ( result . current . data ) . toEqual ( { message : "OK" } ) ;
154
+ const { data, error } = result . current ;
155
+
156
+ expect ( data [ 0 ] ) . toBe ( "one" ) ;
157
+ expect ( error ) . toBeNull ( ) ;
154
158
} ) ;
155
- } ) ;
156
159
157
- describe ( "useMutation" , ( ) => {
158
- it ( "should work" , async ( ) => {
160
+ it ( "should properly propagate error to suspense with a failed http request" , async ( ) => {
159
161
const fetchClient = createFetchClient < paths > ( { baseUrl } ) ;
160
162
const client = createClient ( fetchClient ) ;
163
+ const errorSpy = vi . spyOn ( console , "error" ) . mockImplementation ( ( ) => { } ) ; // to avoid sending errors to console
161
164
162
165
useMockRequestHandler ( {
163
166
baseUrl,
164
167
method : "get" ,
165
- path : "/tag/* " ,
166
- status : 200 ,
167
- body : { message : "OK " } ,
168
+ path : "/string-array " ,
169
+ status : 500 ,
170
+ body : { code : 500 , message : "Something went wrong " } ,
168
171
} ) ;
169
172
170
- const { result } = renderHook ( ( ) => client . useMutation ( "get" , "/tag/{name}" ) , {
171
- wrapper,
173
+ const TestComponent = ( ) => {
174
+ client . useSuspenseQuery ( "get" , "/string-array" ) ;
175
+ return < div /> ;
176
+ } ;
177
+
178
+ render (
179
+ < QueryClientProvider client = { queryClient } >
180
+ < ErrorBoundary fallbackRender = { ( { error } ) => < p > { error . message } </ p > } >
181
+ < Suspense fallback = { < p > loading</ p > } >
182
+ < TestComponent />
183
+ </ Suspense >
184
+ </ ErrorBoundary >
185
+ </ QueryClientProvider > ,
186
+ ) ;
187
+
188
+ expect ( await screen . findByText ( "Something went wrong" ) ) . toBeDefined ( ) ;
189
+ errorSpy . mockRestore ( ) ;
190
+ } ) ;
191
+ } ) ;
192
+
193
+ describe ( "useMutation" , ( ) => {
194
+ describe ( "mutate" , ( ) => {
195
+ it ( "should resolve data properly and have error as null when successfull request" , async ( ) => {
196
+ const fetchClient = createFetchClient < paths > ( { baseUrl } ) ;
197
+ const client = createClient ( fetchClient ) ;
198
+
199
+ useMockRequestHandler ( {
200
+ baseUrl,
201
+ method : "put" ,
202
+ path : "/comment" ,
203
+ status : 200 ,
204
+ body : { message : "Hello" } ,
205
+ } ) ;
206
+
207
+ const { result } = renderHook ( ( ) => client . useMutation ( "put" , "/comment" ) , {
208
+ wrapper,
209
+ } ) ;
210
+
211
+ result . current . mutate ( { body : { message : "Hello" , replied_at : 0 } } ) ;
212
+
213
+ await waitFor ( ( ) => expect ( result . current . isPending ) . toBe ( false ) ) ;
214
+
215
+ const { data, error } = result . current ;
216
+
217
+ expect ( data ?. message ) . toBe ( "Hello" ) ;
218
+ expect ( error ) . toBeNull ( ) ;
172
219
} ) ;
173
220
174
- result . current . mutate ( {
175
- params : {
176
- path : {
177
- name : "test" ,
178
- } ,
179
- } ,
221
+ it ( "should resolve error properly and have undefined data when failed request" , async ( ) => {
222
+ const fetchClient = createFetchClient < paths > ( { baseUrl } ) ;
223
+ const client = createClient ( fetchClient ) ;
224
+
225
+ useMockRequestHandler ( {
226
+ baseUrl,
227
+ method : "put" ,
228
+ path : "/comment" ,
229
+ status : 500 ,
230
+ body : { code : 500 , message : "Something went wrong" } ,
231
+ } ) ;
232
+
233
+ const { result } = renderHook ( ( ) => client . useMutation ( "put" , "/comment" ) , {
234
+ wrapper,
235
+ } ) ;
236
+
237
+ result . current . mutate ( { body : { message : "Hello" , replied_at : 0 } } ) ;
238
+
239
+ await waitFor ( ( ) => expect ( result . current . isPending ) . toBe ( false ) ) ;
240
+
241
+ const { data, error } = result . current ;
242
+
243
+ expect ( data ) . toBeUndefined ( ) ;
244
+ expect ( error ?. message ) . toBe ( "Something went wrong" ) ;
180
245
} ) ;
246
+ } ) ;
247
+
248
+ describe ( "mutateAsync" , ( ) => {
249
+ it ( "should resolve data properly" , async ( ) => {
250
+ const fetchClient = createFetchClient < paths > ( { baseUrl } ) ;
251
+ const client = createClient ( fetchClient ) ;
181
252
182
- await waitFor ( ( ) => expect ( result . current . isSuccess ) . toBe ( true ) ) ;
253
+ useMockRequestHandler ( {
254
+ baseUrl,
255
+ method : "put" ,
256
+ path : "/comment" ,
257
+ status : 200 ,
258
+ body : { message : "Hello" } ,
259
+ } ) ;
183
260
184
- expect ( result . current . data ) . toEqual ( { message : "OK" } ) ;
261
+ const { result } = renderHook ( ( ) => client . useMutation ( "put" , "/comment" ) , {
262
+ wrapper,
263
+ } ) ;
264
+
265
+ const data = await result . current . mutateAsync ( { body : { message : "Hello" , replied_at : 0 } } ) ;
266
+
267
+ expect ( data . message ) . toBe ( "Hello" ) ;
268
+ } ) ;
269
+
270
+ it ( "should throw an error when failed request" , async ( ) => {
271
+ const fetchClient = createFetchClient < paths > ( { baseUrl } ) ;
272
+ const client = createClient ( fetchClient ) ;
273
+
274
+ useMockRequestHandler ( {
275
+ baseUrl,
276
+ method : "put" ,
277
+ path : "/comment" ,
278
+ status : 500 ,
279
+ body : { code : 500 , message : "Something went wrong" } ,
280
+ } ) ;
281
+
282
+ const { result } = renderHook ( ( ) => client . useMutation ( "put" , "/comment" ) , {
283
+ wrapper,
284
+ } ) ;
285
+
286
+ expect ( result . current . mutateAsync ( { body : { message : "Hello" , replied_at : 0 } } ) ) . rejects . toThrow ( ) ;
287
+ } ) ;
185
288
} ) ;
186
289
} ) ;
187
290
} ) ;
0 commit comments