1
1
import { createApi } from '@reduxjs/toolkit/query/react'
2
2
import { actionsReducer , hookWaitFor , setupApiStore , waitMs } from './helpers'
3
3
import { skipToken } from '../core/buildSelectors'
4
- import { renderHook , act } from '@testing-library/react-hooks '
4
+ import { renderHook , act } from '@testing-library/react'
5
5
6
6
interface Post {
7
7
id : string
@@ -33,13 +33,16 @@ const api = createApi({
33
33
method : 'PATCH' ,
34
34
body : patch ,
35
35
} ) ,
36
- async onQueryStarted ( { id, ...patch } , { dispatch, queryFulfilled } ) {
37
- const { undo } = dispatch (
38
- api . util . upsertQueryData ( 'post' , id , ( draft ) => {
39
- Object . assign ( draft , patch )
40
- } )
41
- )
42
- queryFulfilled . catch ( undo )
36
+ async onQueryStarted ( arg , { dispatch, queryFulfilled, getState } ) {
37
+ const currentItem = api . endpoints . post . select ( arg . id ) ( getState ( ) )
38
+ if ( currentItem ?. data ) {
39
+ dispatch (
40
+ api . util . upsertQueryData ( 'post' , arg . id , {
41
+ ...currentItem . data ,
42
+ ...arg ,
43
+ } )
44
+ )
45
+ }
43
46
} ,
44
47
invalidatesTags : ( result ) => ( result ? [ 'Post' ] : [ ] ) ,
45
48
} ) ,
@@ -154,13 +157,12 @@ describe('upsertQueryData', () => {
154
157
contents : 'TODO' ,
155
158
} )
156
159
157
- let returnValue ! : ReturnType < ReturnType < typeof api . util . upsertQueryData > >
158
- act ( ( ) => {
159
- returnValue = storeRef . store . dispatch (
160
- api . util . upsertQueryData ( 'post' , '3' , ( draft ) => {
161
- if ( draft ) {
162
- draft . contents = 'I love cheese!'
163
- }
160
+ await act ( async ( ) => {
161
+ storeRef . store . dispatch (
162
+ api . util . upsertQueryData ( 'post' , '3' , {
163
+ id : '3' ,
164
+ title : 'All about cheese.' ,
165
+ contents : 'I love cheese!' ,
164
166
} )
165
167
)
166
168
} )
@@ -171,20 +173,6 @@ describe('upsertQueryData', () => {
171
173
title : 'All about cheese.' ,
172
174
contents : 'I love cheese!' ,
173
175
} )
174
-
175
- expect ( returnValue ) . toEqual ( {
176
- inversePatches : [ { op : 'replace' , path : [ 'contents' ] , value : 'TODO' } ] ,
177
- patches : [ { op : 'replace' , path : [ 'contents' ] , value : 'I love cheese!' } ] ,
178
- undo : expect . any ( Function ) ,
179
- } )
180
-
181
- act ( ( ) => {
182
- storeRef . store . dispatch (
183
- api . util . patchQueryData ( 'post' , '3' , returnValue . inversePatches )
184
- )
185
- } )
186
-
187
- expect ( result . current . data ) . toEqual ( dataBefore )
188
176
} )
189
177
190
178
test ( 'does update non-existing values' , async ( ) => {
@@ -211,30 +199,14 @@ describe('upsertQueryData', () => {
211
199
// upsert the data
212
200
act ( ( ) => {
213
201
returnValue = storeRef . store . dispatch (
214
- api . util . upsertQueryData ( 'post' , '4' , ( draft ) => {
215
- if ( draft ) {
216
- draft . contents = 'I love cheese!'
217
- } else {
218
- return {
219
- id : '4' ,
220
- title : 'All about cheese' ,
221
- contents : 'I love cheese!' ,
222
- }
223
- }
202
+ api . util . upsertQueryData ( 'post' , '4' , {
203
+ id : '4' ,
204
+ title : 'All about cheese' ,
205
+ contents : 'I love cheese!' ,
224
206
} )
225
207
)
226
208
} )
227
209
228
- // the patch would remove the result again
229
- // maybe this needs to be implemented differently in order
230
- // for the whole thing to work correctly, I suppose that
231
- // this would only revert the data but would not invalidate it
232
- expect ( returnValue ) . toEqual ( {
233
- inversePatches : [ { op : 'replace' , path : [ ] , value : undefined } ] ,
234
- patches : [ ] ,
235
- undo : expect . any ( Function ) ,
236
- } )
237
-
238
210
// rerender the hook
239
211
rerender ( )
240
212
// wait until everything has settled
@@ -285,13 +257,16 @@ describe('full integration', () => {
285
257
contents : 'TODO' ,
286
258
} )
287
259
288
- act ( ( ) => {
289
- result . current . mutation [ 0 ] ( { id : '3' , contents : 'Delicious cheese!' } )
260
+ await act ( async ( ) => {
261
+ await result . current . mutation [ 0 ] ( {
262
+ id : '3' ,
263
+ contents : 'Delicious cheese!' ,
264
+ } )
290
265
} )
291
266
292
267
expect ( result . current . query . data ) . toEqual ( {
293
268
id : '3' ,
294
- title : 'All about cheese .' ,
269
+ title : 'Meanwhile, this changed server-side .' ,
295
270
contents : 'Delicious cheese!' ,
296
271
} )
297
272
@@ -336,8 +311,11 @@ describe('full integration', () => {
336
311
contents : 'TODO' ,
337
312
} )
338
313
339
- act ( ( ) => {
340
- result . current . mutation [ 0 ] ( { id : '3' , contents : 'Delicious cheese!' } )
314
+ await act ( async ( ) => {
315
+ await result . current . mutation [ 0 ] ( {
316
+ id : '3' ,
317
+ contents : 'Delicious cheese!' ,
318
+ } )
341
319
} )
342
320
343
321
// optimistic update
@@ -347,15 +325,6 @@ describe('full integration', () => {
347
325
contents : 'Delicious cheese!' ,
348
326
} )
349
327
350
- // rollback
351
- await hookWaitFor ( ( ) =>
352
- expect ( result . current . query . data ) . toEqual ( {
353
- id : '3' ,
354
- title : 'All about cheese.' ,
355
- contents : 'TODO' ,
356
- } )
357
- )
358
-
359
328
// mutation failed - will not invalidate query and not refetch data from the server
360
329
await expect ( ( ) =>
361
330
hookWaitFor (
0 commit comments