@@ -445,6 +445,101 @@ describe('useMutation', () => {
445445 onlineMock . mockRestore ( )
446446 } )
447447
448+ it ( 'should call onMutate even if paused' , async ( ) => {
449+ const onlineMock = mockNavigatorOnLine ( false )
450+ const onMutate = jest . fn ( )
451+ let count = 0
452+
453+ function Page ( ) {
454+ const mutation = useMutation (
455+ async ( _text : string ) => {
456+ count ++
457+ await sleep ( 10 )
458+ return count
459+ } ,
460+ {
461+ onMutate,
462+ }
463+ )
464+
465+ return (
466+ < div >
467+ < button onClick = { ( ) => mutation . mutate ( 'todo' ) } > mutate</ button >
468+ < div >
469+ data: { mutation . data ?? 'null' } , status: { mutation . status } ,
470+ isPaused: { String ( mutation . isPaused ) }
471+ </ div >
472+ </ div >
473+ )
474+ }
475+
476+ const rendered = renderWithClient ( queryClient , < Page /> )
477+
478+ await rendered . findByText ( 'data: null, status: idle, isPaused: false' )
479+
480+ rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) . click ( )
481+
482+ await rendered . findByText ( 'data: null, status: loading, isPaused: true' )
483+
484+ expect ( onMutate ) . toHaveBeenCalledTimes ( 1 )
485+ expect ( onMutate ) . toHaveBeenCalledWith ( 'todo' )
486+
487+ onlineMock . mockReturnValue ( true )
488+ window . dispatchEvent ( new Event ( 'online' ) )
489+
490+ await rendered . findByText ( 'data: 1, status: success, isPaused: false' )
491+
492+ expect ( onMutate ) . toHaveBeenCalledTimes ( 1 )
493+ expect ( count ) . toBe ( 1 )
494+
495+ onlineMock . mockRestore ( )
496+ } )
497+
498+ it ( 'should optimistically go to paused state if offline' , async ( ) => {
499+ const onlineMock = mockNavigatorOnLine ( false )
500+ let count = 0
501+ const states : Array < string > = [ ]
502+
503+ function Page ( ) {
504+ const mutation = useMutation ( async ( _text : string ) => {
505+ count ++
506+ await sleep ( 10 )
507+ return count
508+ } )
509+
510+ states . push ( `${ mutation . status } , ${ mutation . isPaused } ` )
511+
512+ return (
513+ < div >
514+ < button onClick = { ( ) => mutation . mutate ( 'todo' ) } > mutate</ button >
515+ < div >
516+ data: { mutation . data ?? 'null' } , status: { mutation . status } ,
517+ isPaused: { String ( mutation . isPaused ) }
518+ </ div >
519+ </ div >
520+ )
521+ }
522+
523+ const rendered = renderWithClient ( queryClient , < Page /> )
524+
525+ await rendered . findByText ( 'data: null, status: idle, isPaused: false' )
526+
527+ rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) . click ( )
528+
529+ await rendered . findByText ( 'data: null, status: loading, isPaused: true' )
530+
531+ // no intermediate 'loading, false' state is expected because we don't start mutating!
532+ expect ( states [ 0 ] ) . toBe ( 'idle, false' )
533+ expect ( states [ 1 ] ) . toBe ( 'loading, true' )
534+
535+ onlineMock . mockReturnValue ( true )
536+ window . dispatchEvent ( new Event ( 'online' ) )
537+
538+ await rendered . findByText ( 'data: 1, status: success, isPaused: false' )
539+
540+ onlineMock . mockRestore ( )
541+ } )
542+
448543 it ( 'should be able to retry a mutation when online' , async ( ) => {
449544 const consoleMock = mockConsoleError ( )
450545 const onlineMock = mockNavigatorOnLine ( false )
0 commit comments