@@ -10280,6 +10280,150 @@ describe("a router", () => {
10280
10280
await F . actions . index . resolve ( "INDEX ACTION" ) ;
10281
10281
expect ( t . router . getFetcher ( key ) . data ) . toBe ( "INDEX ACTION" ) ;
10282
10282
} ) ;
10283
+
10284
+ it ( "throws a 404 ErrorResponse without ?index and parent route has no loader" , async ( ) => {
10285
+ let t = setup ( {
10286
+ routes : [
10287
+ {
10288
+ id : "parent" ,
10289
+ path : "parent" ,
10290
+ children : [
10291
+ {
10292
+ id : "index" ,
10293
+ index : true ,
10294
+ loader : true ,
10295
+ } ,
10296
+ ] ,
10297
+ } ,
10298
+ ] ,
10299
+ initialEntries : [ "/parent" ] ,
10300
+ hydrationData : { loaderData : { index : "INDEX" } } ,
10301
+ } ) ;
10302
+
10303
+ let key = "KEY" ;
10304
+ await t . fetch ( "/parent" ) ;
10305
+ expect ( t . router . state . errors ) . toMatchInlineSnapshot ( `
10306
+ {
10307
+ "parent": ErrorResponse {
10308
+ "data": "Error: No route matches URL "/parent"",
10309
+ "error": [Error: No route matches URL "/parent"],
10310
+ "internal": true,
10311
+ "status": 404,
10312
+ "statusText": "Not Found",
10313
+ },
10314
+ }
10315
+ ` ) ;
10316
+ expect ( t . router . getFetcher ( key ) . data ) . toBe ( undefined ) ;
10317
+ } ) ;
10318
+
10319
+ it ( "throws a 404 ErrorResponse with ?index and index route has no loader" , async ( ) => {
10320
+ let t = setup ( {
10321
+ routes : [
10322
+ {
10323
+ id : "parent" ,
10324
+ path : "parent" ,
10325
+ loader : true ,
10326
+ children : [
10327
+ {
10328
+ id : "index" ,
10329
+ index : true ,
10330
+ } ,
10331
+ ] ,
10332
+ } ,
10333
+ ] ,
10334
+ initialEntries : [ "/parent" ] ,
10335
+ hydrationData : { loaderData : { parent : "PARENT" } } ,
10336
+ } ) ;
10337
+
10338
+ let key = "KEY" ;
10339
+ await t . fetch ( "/parent?index" ) ;
10340
+ expect ( t . router . state . errors ) . toMatchInlineSnapshot ( `
10341
+ {
10342
+ "parent": ErrorResponse {
10343
+ "data": "Error: No route matches URL "/parent?index"",
10344
+ "error": [Error: No route matches URL "/parent?index"],
10345
+ "internal": true,
10346
+ "status": 404,
10347
+ "statusText": "Not Found",
10348
+ },
10349
+ }
10350
+ ` ) ;
10351
+ expect ( t . router . getFetcher ( key ) . data ) . toBe ( undefined ) ;
10352
+ } ) ;
10353
+
10354
+ it ( "throws a 405 ErrorResponse without ?index and parent route has no action" , async ( ) => {
10355
+ let t = setup ( {
10356
+ routes : [
10357
+ {
10358
+ id : "parent" ,
10359
+ path : "parent" ,
10360
+ children : [
10361
+ {
10362
+ id : "index" ,
10363
+ index : true ,
10364
+ action : true ,
10365
+ } ,
10366
+ ] ,
10367
+ } ,
10368
+ ] ,
10369
+ initialEntries : [ "/parent" ] ,
10370
+ } ) ;
10371
+
10372
+ let key = "KEY" ;
10373
+ await t . fetch ( "/parent" , {
10374
+ formMethod : "post" ,
10375
+ formData : createFormData ( { } ) ,
10376
+ } ) ;
10377
+ expect ( t . router . state . errors ) . toMatchInlineSnapshot ( `
10378
+ {
10379
+ "parent": ErrorResponse {
10380
+ "data": "Error: You made a POST request to "/parent" but did not provide an \`action\` for route "parent", so there is no way to handle the request.",
10381
+ "error": [Error: You made a POST request to "/parent" but did not provide an \`action\` for route "parent", so there is no way to handle the request.],
10382
+ "internal": true,
10383
+ "status": 405,
10384
+ "statusText": "Method Not Allowed",
10385
+ },
10386
+ }
10387
+ ` ) ;
10388
+ expect ( t . router . getFetcher ( key ) . data ) . toBe ( undefined ) ;
10389
+ } ) ;
10390
+
10391
+ it ( "throws a 405 ErrorResponse with ?index and index route has no action" , async ( ) => {
10392
+ let t = setup ( {
10393
+ routes : [
10394
+ {
10395
+ id : "parent" ,
10396
+ path : "parent" ,
10397
+ action : true ,
10398
+ children : [
10399
+ {
10400
+ id : "index" ,
10401
+ index : true ,
10402
+ } ,
10403
+ ] ,
10404
+ } ,
10405
+ ] ,
10406
+ initialEntries : [ "/parent" ] ,
10407
+ } ) ;
10408
+
10409
+ let key = "KEY" ;
10410
+ await t . fetch ( "/parent?index" , {
10411
+ formMethod : "post" ,
10412
+ formData : createFormData ( { } ) ,
10413
+ } ) ;
10414
+ expect ( t . router . state . errors ) . toMatchInlineSnapshot ( `
10415
+ {
10416
+ "parent": ErrorResponse {
10417
+ "data": "Error: You made a POST request to "/parent?index" but did not provide an \`action\` for route "parent", so there is no way to handle the request.",
10418
+ "error": [Error: You made a POST request to "/parent?index" but did not provide an \`action\` for route "parent", so there is no way to handle the request.],
10419
+ "internal": true,
10420
+ "status": 405,
10421
+ "statusText": "Method Not Allowed",
10422
+ },
10423
+ }
10424
+ ` ) ;
10425
+ expect ( t . router . getFetcher ( key ) . data ) . toBe ( undefined ) ;
10426
+ } ) ;
10283
10427
} ) ;
10284
10428
} ) ;
10285
10429
@@ -15444,12 +15588,20 @@ describe("a router", () => {
15444
15588
expect ( currentRouter . state . loaderData ) . toEqual ( {
15445
15589
root : "ROOT*" ,
15446
15590
} ) ;
15447
- // Fetcher should have been revalidated but thrown an errow since the
15591
+ // Fetcher should have been revalidated but throw an error since the
15448
15592
// loader was removed
15449
15593
expect ( currentRouter . state . fetchers . get ( "key" ) ?. data ) . toBe ( undefined ) ;
15450
- expect ( currentRouter . state . errors ) . toEqual ( {
15451
- root : new Error ( 'Could not find the loader to run on the "foo" route' ) ,
15452
- } ) ;
15594
+ expect ( currentRouter . state . errors ) . toMatchInlineSnapshot ( `
15595
+ {
15596
+ "root": ErrorResponse {
15597
+ "data": "Error: No route matches URL "/foo"",
15598
+ "error": [Error: No route matches URL "/foo"],
15599
+ "internal": true,
15600
+ "status": 404,
15601
+ "statusText": "Not Found",
15602
+ },
15603
+ }
15604
+ ` ) ;
15453
15605
} ) ;
15454
15606
15455
15607
it ( "should retain existing routes until revalidation completes on route removal (fetch)" , async ( ) => {
0 commit comments