@@ -736,6 +736,107 @@ test.describe("single-fetch", () => {
736736 expect ( urls ) . toEqual ( [ ] ) ;
737737 } ) ;
738738
739+ test ( "provides proper defaultShouldRevalidate value on 4xx/5xx action responses" , async ( {
740+ page,
741+ } ) => {
742+ let fixture = await createFixture ( {
743+ files : {
744+ ...files ,
745+ "app/routes/action.tsx" : js `
746+ import { Form, Link, useActionData, useLoaderData, useNavigation, data } from 'react-router';
747+
748+ export async function action({ request }) {
749+ let fd = await request.formData();
750+ if (fd.get('throw') === "5xx") {
751+ throw data("Thrown 500", { status: 500 });
752+ }
753+ if (fd.get('throw') === "4xx") {
754+ throw data("Thrown 400", { status: 400 });
755+ }
756+ if (fd.get('return') === "5xx") {
757+ return data("Returned 500", { status: 500 });
758+ }
759+ if (fd.get('return') === "4xx") {
760+ return data("Returned 400", { status: 400 });
761+ }
762+ return null;
763+ }
764+
765+ let count = 0;
766+ export function loader() {
767+ return { count: ++count };
768+ }
769+
770+ export function shouldRevalidate({ defaultShouldRevalidate }) {
771+ return defaultShouldRevalidate;
772+ }
773+
774+ export default function Comp() {
775+ let navigation = useNavigation();
776+ let data = useLoaderData();
777+ return (
778+ <Form method="post">
779+ <button type="submit" name="throw" value="5xx">Throw 5xx</button>
780+ <button type="submit" name="throw" value="4xx">Throw 4xx</button>
781+ <button type="submit" name="return" value="5xx">Return 5xx</button>
782+ <button type="submit" name="return" value="4xx">Return 4xx</button>
783+ <p id="data">{data.count}</p>
784+ {navigation.state === "idle" ? <p id="idle">idle</p> : null}
785+ </Form>
786+ );
787+ }
788+
789+ export function ErrorBoundary() {
790+ return (
791+ <div>
792+ <h1 id="error">Error</h1>
793+ <Link to="/action">Back</Link>
794+ </div>
795+ );
796+ }
797+ ` ,
798+ } ,
799+ } ) ;
800+
801+ let urls : string [ ] = [ ] ;
802+ page . on ( "request" , ( req ) => {
803+ if ( req . method ( ) === "GET" && req . url ( ) . includes ( ".data" ) ) {
804+ urls . push ( req . url ( ) ) ;
805+ }
806+ } ) ;
807+
808+ console . error = ( ) => { } ;
809+
810+ let appFixture = await createAppFixture ( fixture ) ;
811+ let app = new PlaywrightFixture ( appFixture , page ) ;
812+ await app . goto ( "/action" ) ;
813+ expect ( await app . getHtml ( "#data" ) ) . toContain ( "1" ) ;
814+ expect ( urls ) . toEqual ( [ ] ) ;
815+
816+ await page . click ( 'button[name="return"][value="5xx"]' ) ;
817+ await page . waitForSelector ( "#idle" ) ;
818+ expect ( await app . getHtml ( "#data" ) ) . toContain ( "1" ) ;
819+ expect ( urls ) . toEqual ( [ ] ) ;
820+
821+ await page . click ( 'button[name="return"][value="4xx"]' ) ;
822+ await page . waitForSelector ( "#idle" ) ;
823+ expect ( await app . getHtml ( "#data" ) ) . toContain ( "1" ) ;
824+ expect ( urls ) . toEqual ( [ ] ) ;
825+
826+ await page . click ( 'button[name="throw"][value="5xx"]' ) ;
827+ await page . waitForSelector ( "#error" ) ;
828+ expect ( urls ) . toEqual ( [ ] ) ;
829+
830+ await app . clickLink ( "/action" ) ;
831+ await page . waitForSelector ( "#data" ) ;
832+ expect ( await app . getHtml ( "#data" ) ) . toContain ( "2" ) ;
833+ urls = [ ] ;
834+
835+ await page . click ( 'button[name="throw"][value="4xx"]' ) ;
836+ await page . waitForSelector ( "#error" ) ;
837+ expect ( urls ) . toEqual ( [ ] ) ;
838+ } ) ;
839+
739840 test ( "returns headers correctly for singular loader and action calls" , async ( ) => {
740841 let fixture = await createFixture ( {
741842 files : {
0 commit comments