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