@@ -9836,7 +9836,7 @@ describe("a router", () => {
9836
9836
state : "submitting" ,
9837
9837
} ) ;
9838
9838
9839
- // After acton resolves, both fetchers go into a loading state, with
9839
+ // After action resolves, both fetchers go into a loading state, with
9840
9840
// the load fetcher still reflecting it's stale data
9841
9841
await C . actions . tasks . resolve ( "TASKS ACTION" ) ;
9842
9842
expect ( t . router . state . fetchers . get ( key ) ) . toMatchObject ( {
@@ -10032,6 +10032,183 @@ describe("a router", () => {
10032
10032
data : "C" ,
10033
10033
} ) ;
10034
10034
} ) ;
10035
+
10036
+ it ( "does not cancel pending action navigation on deletion of revalidating fetcher" , async ( ) => {
10037
+ let t = setup ( {
10038
+ routes : TASK_ROUTES ,
10039
+ initialEntries : [ "/" ] ,
10040
+ hydrationData : { loaderData : { root : "ROOT" , index : "INDEX" } } ,
10041
+ } ) ;
10042
+ expect ( t . router . state . navigation ) . toBe ( IDLE_NAVIGATION ) ;
10043
+
10044
+ let key1 = "key1" ;
10045
+ let A = await t . fetch ( "/tasks/1" , key1 ) ;
10046
+ await A . loaders . tasksId . resolve ( "TASKS 1" ) ;
10047
+
10048
+ let C = await t . navigate ( "/tasks" , {
10049
+ formMethod : "post" ,
10050
+ formData : createFormData ( { } ) ,
10051
+ } ) ;
10052
+ // Add a helper for the fetcher that will be revalidating
10053
+ t . shimHelper ( C . loaders , "navigation" , "loader" , "tasksId" ) ;
10054
+
10055
+ // Resolve the action
10056
+ await C . actions . tasks . resolve ( "TASKS ACTION" ) ;
10057
+
10058
+ // Fetcher should go back into a loading state
10059
+ expect ( t . router . state . fetchers . get ( key1 ) ) . toMatchObject ( {
10060
+ state : "loading" ,
10061
+ data : "TASKS 1" ,
10062
+ } ) ;
10063
+
10064
+ // Delete fetcher in the middle of the revalidation
10065
+ t . router . deleteFetcher ( key1 ) ;
10066
+ expect ( t . router . state . fetchers . get ( key1 ) ) . toBeUndefined ( ) ;
10067
+
10068
+ // Resolve navigation loaders
10069
+ await C . loaders . root . resolve ( "ROOT*" ) ;
10070
+ await C . loaders . tasks . resolve ( "TASKS LOADER" ) ;
10071
+
10072
+ expect ( t . router . state ) . toMatchObject ( {
10073
+ actionData : {
10074
+ tasks : "TASKS ACTION" ,
10075
+ } ,
10076
+ errors : null ,
10077
+ loaderData : {
10078
+ tasks : "TASKS LOADER" ,
10079
+ root : "ROOT*" ,
10080
+ } ,
10081
+ } ) ;
10082
+ expect ( t . router . state . fetchers . size ) . toBe ( 0 ) ;
10083
+ } ) ;
10084
+
10085
+ it ( "does not cancel pending loader navigation on deletion of revalidating fetcher" , async ( ) => {
10086
+ let t = setup ( {
10087
+ routes : TASK_ROUTES ,
10088
+ initialEntries : [ "/" ] ,
10089
+ hydrationData : { loaderData : { root : "ROOT" , index : "INDEX" } } ,
10090
+ } ) ;
10091
+ expect ( t . router . state . navigation ) . toBe ( IDLE_NAVIGATION ) ;
10092
+
10093
+ let key1 = "key1" ;
10094
+ let A = await t . fetch ( "/tasks/1" , key1 ) ;
10095
+ await A . loaders . tasksId . resolve ( "TASKS 1" ) ;
10096
+
10097
+ // Loading navigation with query param to trigger revalidations
10098
+ let C = await t . navigate ( "/tasks?key=value" ) ;
10099
+
10100
+ // Fetcher should go back into a loading state
10101
+ expect ( t . router . state . fetchers . get ( key1 ) ) . toMatchObject ( {
10102
+ state : "loading" ,
10103
+ data : "TASKS 1" ,
10104
+ } ) ;
10105
+
10106
+ // Delete fetcher in the middle of the revalidation
10107
+ t . router . deleteFetcher ( key1 ) ;
10108
+ expect ( t . router . state . fetchers . get ( key1 ) ) . toBeUndefined ( ) ;
10109
+
10110
+ // Resolve navigation loaders
10111
+ await C . loaders . root . resolve ( "ROOT*" ) ;
10112
+ await C . loaders . tasks . resolve ( "TASKS LOADER" ) ;
10113
+
10114
+ expect ( t . router . state ) . toMatchObject ( {
10115
+ errors : null ,
10116
+ loaderData : {
10117
+ tasks : "TASKS LOADER" ,
10118
+ root : "ROOT*" ,
10119
+ } ,
10120
+ } ) ;
10121
+ expect ( t . router . state . fetchers . size ) . toBe ( 0 ) ;
10122
+ } ) ;
10123
+
10124
+ it ( "does not cancel pending router.revalidate() on deletion of revalidating fetcher" , async ( ) => {
10125
+ let t = setup ( {
10126
+ routes : TASK_ROUTES ,
10127
+ initialEntries : [ "/" ] ,
10128
+ hydrationData : { loaderData : { root : "ROOT" , index : "INDEX" } } ,
10129
+ } ) ;
10130
+ expect ( t . router . state . navigation ) . toBe ( IDLE_NAVIGATION ) ;
10131
+
10132
+ let key1 = "key1" ;
10133
+ let A = await t . fetch ( "/tasks/1" , key1 ) ;
10134
+ await A . loaders . tasksId . resolve ( "TASKS 1" ) ;
10135
+
10136
+ // Trigger revalidations
10137
+ let C = await t . revalidate ( ) ;
10138
+
10139
+ // Fetcher should not go back into a loading state since it's a revalidation
10140
+ expect ( t . router . state . fetchers . get ( key1 ) ) . toMatchObject ( {
10141
+ state : "idle" ,
10142
+ data : "TASKS 1" ,
10143
+ } ) ;
10144
+
10145
+ // Delete fetcher in the middle of the revalidation
10146
+ t . router . deleteFetcher ( key1 ) ;
10147
+ expect ( t . router . state . fetchers . get ( key1 ) ) . toBeUndefined ( ) ;
10148
+
10149
+ // Resolve navigation loaders
10150
+ await C . loaders . root . resolve ( "ROOT*" ) ;
10151
+ await C . loaders . index . resolve ( "INDEX*" ) ;
10152
+
10153
+ expect ( t . router . state ) . toMatchObject ( {
10154
+ errors : null ,
10155
+ loaderData : {
10156
+ root : "ROOT*" ,
10157
+ index : "INDEX*" ,
10158
+ } ,
10159
+ } ) ;
10160
+ expect ( t . router . state . fetchers . size ) . toBe ( 0 ) ;
10161
+ } ) ;
10162
+
10163
+ it ( "does not cancel pending fetcher submission on deletion of revalidating fetcher" , async ( ) => {
10164
+ let key = "key" ;
10165
+ let actionKey = "actionKey" ;
10166
+ let t = setup ( {
10167
+ routes : TASK_ROUTES ,
10168
+ initialEntries : [ "/" ] ,
10169
+ hydrationData : { loaderData : { root : "ROOT" , index : "INDEX" } } ,
10170
+ } ) ;
10171
+
10172
+ // Load a fetcher
10173
+ let A = await t . fetch ( "/tasks/1" , key ) ;
10174
+ await A . loaders . tasksId . resolve ( "TASKS ID" ) ;
10175
+
10176
+ // Submit a fetcher, leaves loaded fetcher untouched
10177
+ let C = await t . fetch ( "/tasks" , actionKey , {
10178
+ formMethod : "post" ,
10179
+ formData : createFormData ( { } ) ,
10180
+ } ) ;
10181
+
10182
+ // After action resolves, both fetchers go into a loading state, with
10183
+ // the load fetcher still reflecting it's stale data
10184
+ await C . actions . tasks . resolve ( "TASKS ACTION" ) ;
10185
+ expect ( t . router . state . fetchers . get ( key ) ) . toMatchObject ( {
10186
+ state : "loading" ,
10187
+ data : "TASKS ID" ,
10188
+ } ) ;
10189
+ expect ( t . router . state . fetchers . get ( actionKey ) ) . toMatchObject ( {
10190
+ state : "loading" ,
10191
+ data : "TASKS ACTION" ,
10192
+ } ) ;
10193
+
10194
+ // Delete fetcher in the middle of the revalidation
10195
+ t . router . deleteFetcher ( key ) ;
10196
+ expect ( t . router . state . fetchers . get ( key ) ) . toBeUndefined ( ) ;
10197
+
10198
+ // Resolve only active route loaders since fetcher was deleted
10199
+ await C . loaders . root . resolve ( "ROOT*" ) ;
10200
+ await C . loaders . index . resolve ( "INDEX*" ) ;
10201
+
10202
+ expect ( t . router . state . loaderData ) . toMatchObject ( {
10203
+ root : "ROOT*" ,
10204
+ index : "INDEX*" ,
10205
+ } ) ;
10206
+ expect ( t . router . state . fetchers . get ( key ) ) . toBe ( undefined ) ;
10207
+ expect ( t . router . state . fetchers . get ( actionKey ) ) . toMatchObject ( {
10208
+ state : "idle" ,
10209
+ data : "TASKS ACTION" ,
10210
+ } ) ;
10211
+ } ) ;
10035
10212
} ) ;
10036
10213
10037
10214
describe ( "fetcher ?index params" , ( ) => {
0 commit comments