1
1
import { afterEach , beforeEach , describe , expect , test , vi } from 'vitest'
2
2
import { queryKey , sleep } from '@tanstack/query-test-utils'
3
3
import {
4
+ CancelledError ,
4
5
MutationObserver ,
5
6
QueryClient ,
6
7
QueryObserver ,
@@ -993,54 +994,25 @@ describe('queryClient', () => {
993
994
describe ( 'cancelQueries' , ( ) => {
994
995
test ( 'should revert queries to their previous state' , async ( ) => {
995
996
const key1 = queryKey ( )
996
- const key2 = queryKey ( )
997
- const key3 = queryKey ( )
998
- await queryClient . fetchQuery ( {
999
- queryKey : key1 ,
1000
- queryFn : ( ) => 'data' ,
1001
- } )
1002
- try {
1003
- await queryClient . fetchQuery ( {
1004
- queryKey : key2 ,
1005
- queryFn : async ( ) => {
1006
- return Promise . reject < unknown > ( 'err' )
1007
- } ,
1008
- } )
1009
- } catch { }
1010
- queryClient . fetchQuery ( {
997
+ queryClient . setQueryData ( key1 , 'data' )
998
+
999
+ const pending = queryClient . fetchQuery ( {
1011
1000
queryKey : key1 ,
1012
1001
queryFn : ( ) => sleep ( 1000 ) . then ( ( ) => 'data2' ) ,
1013
1002
} )
1014
- try {
1015
- queryClient . fetchQuery ( {
1016
- queryKey : key2 ,
1017
- queryFn : ( ) =>
1018
- sleep ( 1000 ) . then ( ( ) => Promise . reject < unknown > ( 'err2' ) ) ,
1019
- } )
1020
- } catch { }
1021
- queryClient . fetchQuery ( {
1022
- queryKey : key3 ,
1023
- queryFn : ( ) => sleep ( 1000 ) . then ( ( ) => 'data3' ) ,
1024
- } )
1003
+
1025
1004
await vi . advanceTimersByTimeAsync ( 10 )
1005
+
1026
1006
await queryClient . cancelQueries ( )
1007
+
1008
+ // with previous data present, imperative fetch should resolve to that data after cancel
1009
+ await expect ( pending ) . resolves . toBe ( 'data' )
1010
+
1027
1011
const state1 = queryClient . getQueryState ( key1 )
1028
- const state2 = queryClient . getQueryState ( key2 )
1029
- const state3 = queryClient . getQueryState ( key3 )
1030
1012
expect ( state1 ) . toMatchObject ( {
1031
1013
data : 'data' ,
1032
1014
status : 'success' ,
1033
1015
} )
1034
- expect ( state2 ) . toMatchObject ( {
1035
- data : undefined ,
1036
- error : 'err' ,
1037
- status : 'error' ,
1038
- } )
1039
- expect ( state3 ) . toMatchObject ( {
1040
- data : undefined ,
1041
- status : 'pending' ,
1042
- fetchStatus : 'idle' ,
1043
- } )
1044
1016
} )
1045
1017
1046
1018
test ( 'should not revert if revert option is set to false' , async ( ) => {
@@ -1060,6 +1032,34 @@ describe('queryClient', () => {
1060
1032
status : 'error' ,
1061
1033
} )
1062
1034
} )
1035
+
1036
+ test ( 'should throw CancelledError for imperative methods when initial fetch is cancelled' , async ( ) => {
1037
+ const key = queryKey ( )
1038
+
1039
+ const promise = queryClient . fetchQuery ( {
1040
+ queryKey : key ,
1041
+ queryFn : async ( ) => {
1042
+ await sleep ( 50 )
1043
+ return 25
1044
+ } ,
1045
+ } )
1046
+
1047
+ await vi . advanceTimersByTimeAsync ( 10 )
1048
+
1049
+ await queryClient . cancelQueries ( { queryKey : key } )
1050
+
1051
+ // we have to reject here because we can't resolve with `undefined`
1052
+ // the alternative would be a never-ending promise
1053
+ await expect ( promise ) . rejects . toBeInstanceOf ( CancelledError )
1054
+
1055
+ // however, the query was correctly reverted to pending state
1056
+ expect ( queryClient . getQueryState ( key ) ) . toMatchObject ( {
1057
+ status : 'pending' ,
1058
+ fetchStatus : 'idle' ,
1059
+ data : undefined ,
1060
+ error : null ,
1061
+ } )
1062
+ } )
1063
1063
} )
1064
1064
1065
1065
describe ( 'refetchQueries' , ( ) => {
0 commit comments