From 124505238d7945ba0fb349cf154469c4941de644 Mon Sep 17 00:00:00 2001 From: Sheraff Date: Sun, 17 Aug 2025 11:32:50 +0200 Subject: [PATCH 1/3] test(react-router): throw redirect during preload --- packages/react-router/tests/redirect.test.tsx | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/packages/react-router/tests/redirect.test.tsx b/packages/react-router/tests/redirect.test.tsx index 3009c9ddd1..854d67705c 100644 --- a/packages/react-router/tests/redirect.test.tsx +++ b/packages/react-router/tests/redirect.test.tsx @@ -191,6 +191,69 @@ describe('redirect', () => { expect(nestedFooLoaderMock).toHaveBeenCalled() }) + test('when `redirect` is thrown during preload', async () => { + let signedIn = false // Simulate user authentication state + const beforeRedirectMock = vi.fn() + const afterRedirectMock = vi.fn() + + const rootRoute = createRootRoute({}) + const indexRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/', + component: () => { + return ( +
+

Index page

+ link to protected +
+ ) + }, + }) + const protectedRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/protected', + beforeLoad: () => { + beforeRedirectMock() + if (!signedIn) throw redirect({ to: '/login' }) + afterRedirectMock() + }, + component: () =>
Protected page
, + }) + const signInRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/login', + component: () =>
Sign In page
, + }) + const routeTree = rootRoute.addChildren([ + signInRoute, + protectedRoute, + indexRoute, + ]) + const router = createRouter({ routeTree, history, defaultPreload: 'intent' }) + + render() + + const linkToProtected = await screen.findByText('link to protected') + expect(linkToProtected).toBeInTheDocument() + + // preload + fireEvent.focus(linkToProtected) + await sleep(WAIT_TIME) + + // sign-in + signedIn = true + + // navigate + fireEvent.click(linkToProtected) + + const protectedElement = await screen.findByText('Protected page') + expect(protectedElement).toBeInTheDocument() + expect(router.state.location.href).toBe('/protected') + expect(window.location.pathname).toBe('/protected') + expect(beforeRedirectMock).toHaveBeenCalledTimes(2) + expect(afterRedirectMock).toHaveBeenCalledTimes(1) + }) + test('when `redirect` is thrown in `loader` after `router.invalidate()`', async () => { let shouldRedirect = false From 6a232442f7659db317825274ca41437dd0e65ad7 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Sun, 17 Aug 2025 09:35:12 +0000 Subject: [PATCH 2/3] ci: apply automated fixes --- packages/react-router/tests/redirect.test.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/react-router/tests/redirect.test.tsx b/packages/react-router/tests/redirect.test.tsx index 854d67705c..d490d08c23 100644 --- a/packages/react-router/tests/redirect.test.tsx +++ b/packages/react-router/tests/redirect.test.tsx @@ -229,7 +229,11 @@ describe('redirect', () => { protectedRoute, indexRoute, ]) - const router = createRouter({ routeTree, history, defaultPreload: 'intent' }) + const router = createRouter({ + routeTree, + history, + defaultPreload: 'intent', + }) render() From 8a18a9f04b9365866afe71ff55591ade19e98b18 Mon Sep 17 00:00:00 2001 From: Sheraff Date: Sun, 17 Aug 2025 14:28:13 +0200 Subject: [PATCH 3/3] i wanna see what fails --- packages/router-core/src/router.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/router-core/src/router.ts b/packages/router-core/src/router.ts index c4409961b8..8293da6cd2 100644 --- a/packages/router-core/src/router.ts +++ b/packages/router-core/src/router.ts @@ -507,6 +507,7 @@ export type SubscribeFn = ( export interface MatchRoutesOpts { preload?: boolean throwOnError?: boolean + /** @internal */ _buildLocation?: boolean dest?: BuildNextOptions } @@ -909,14 +910,14 @@ export class RouterCore< if (!this.__store) { this.__store = new Store(getInitialRouterState(this.latestLocation), { - onUpdate: () => { - this.__store.state = { - ...this.state, - cachedMatches: this.state.cachedMatches.filter( - (d) => !['redirected'].includes(d.status), - ), - } - }, + // onUpdate: () => { + // this.__store.state = { + // ...this.state, + // cachedMatches: this.state.cachedMatches.filter( + // (d) => !['redirected'].includes(d.status), + // ), + // } + // }, }) setupScrollRestoration(this)