Fix root path redirect matching all routes
Special-case `from: '/'` in redirect config to use an exact path match instead of the `/*` wildcard, which would match the entire app. Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> Made-with: Cursor
This commit is contained in:
@@ -370,6 +370,79 @@ describe('AppRoutes', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should only redirect the root path when from is /', async () => {
|
||||
const LocationDisplay = () => {
|
||||
const location = useLocation();
|
||||
return <div data-testid="location">{location.pathname}</div>;
|
||||
};
|
||||
|
||||
const catalogPage = PageBlueprint.make({
|
||||
name: 'catalog',
|
||||
params: {
|
||||
path: '/catalog',
|
||||
loader: async () => (
|
||||
<div>
|
||||
Catalog Page
|
||||
<LocationDisplay />
|
||||
</div>
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
const homePage = PageBlueprint.make({
|
||||
name: 'home',
|
||||
params: {
|
||||
path: '/home',
|
||||
loader: async () => (
|
||||
<div>
|
||||
Home Page
|
||||
<LocationDisplay />
|
||||
</div>
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
const redirectsConfig = {
|
||||
...DEFAULT_CONFIG,
|
||||
app: {
|
||||
...DEFAULT_CONFIG.app,
|
||||
extensions: [
|
||||
{
|
||||
'app/routes': {
|
||||
config: {
|
||||
redirects: [{ from: '/', to: '/home' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const { unmount } = renderTestApp({
|
||||
extensions: [catalogPage, homePage],
|
||||
initialRouteEntries: ['/'],
|
||||
config: redirectsConfig,
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Home Page')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('location')).toHaveTextContent('/home');
|
||||
});
|
||||
|
||||
unmount();
|
||||
|
||||
renderTestApp({
|
||||
extensions: [catalogPage, homePage],
|
||||
initialRouteEntries: ['/catalog'],
|
||||
config: redirectsConfig,
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Catalog Page')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('location')).toHaveTextContent('/catalog');
|
||||
});
|
||||
});
|
||||
|
||||
it('should not interfere with normal routes when redirects are configured', async () => {
|
||||
const homePage = PageBlueprint.make({
|
||||
name: 'home',
|
||||
|
||||
@@ -52,7 +52,10 @@ export const AppRoutes = createExtension({
|
||||
const Routes = () => {
|
||||
const element = useRoutes([
|
||||
...redirects.map(redirect => ({
|
||||
path: `${redirect.from.replace(/\/$/, '')}/*`,
|
||||
path:
|
||||
redirect.from === '/'
|
||||
? redirect.from
|
||||
: `${redirect.from.replace(/\/$/, '')}/*`,
|
||||
element: <Navigate to={redirect.to} replace />,
|
||||
})),
|
||||
...inputs.routes.map(route => {
|
||||
|
||||
Reference in New Issue
Block a user