From 5e04b09b6625a305b3dc115914a1f0212795ff6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Norrliden?= Date: Mon, 16 Jun 2025 14:49:10 +0200 Subject: [PATCH 1/2] test(integration): bug-report - param containing forward slash encoded with encodeURIComponent should not be decoded by useParams/matchPath --- integration/bug-report-test.ts | 59 ++++++++++++++++------------------ 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/integration/bug-report-test.ts b/integration/bug-report-test.ts index 8be63c7fc2..5d11be530a 100644 --- a/integration/bug-report-test.ts +++ b/integration/bug-report-test.ts @@ -64,27 +64,22 @@ test.beforeAll(async () => { // `createFixture` will make an app and run your tests against it. //////////////////////////////////////////////////////////////////////////// files: { - "app/routes/_index.tsx": js` - import { useLoaderData, Link } from "react-router"; + "app/routes/use-params.$id.tsx": js` + import { useParams } from "react-router"; - export function loader() { - return "pizza"; - } - - export default function Index() { - let data = useLoaderData(); - return ( -
- {data} - Other Route -
- ) + export default function ItemPage() { + let params = useParams(); + return
Item ID: {params.id}
; } `, - "app/routes/burgers.tsx": js` - export default function Index() { - return
cheeseburger
; + "app/routes/match-path.$id.tsx": js` + import { matchPath, useLocation } from "react-router"; + + export default function ItemPage() { + const location = useLocation() + const match = matchPath({ path: '/match-path/:id' }, location.pathname) + return
Item ID: {match.params.id}
; } `, }, @@ -103,22 +98,24 @@ test.afterAll(() => { // add a good description for what you expect React Router to do 👇🏽 //////////////////////////////////////////////////////////////////////////////// -test("[description of what you expect it to do]", async ({ page }) => { +test("useParams should not decode param containing double-encoded forward slash", async ({ + page, +}) => { let app = new PlaywrightFixture(appFixture, page); - // You can test any request your app might get using `fixture`. - let response = await fixture.requestDocument("/"); - expect(await response.text()).toMatch("pizza"); - - // If you need to test interactivity use the `app` - await app.goto("/"); - await app.clickLink("/burgers"); - await page.waitForSelector("text=cheeseburger"); - - // If you're not sure what's going on, you can "poke" the app, it'll - // automatically open up in your browser for 20 seconds, so be quick! - // await app.poke(20); + const encodedId = encodeURIComponent(encodeURIComponent("beforeslash/afterslash@")); + await app.goto(`/use-params/${encodedId}`); + let el = page.locator("[data-testid='item-id']"); + await expect(el).toHaveText(`Item ID: ${encodedId}`); +}); - // Go check out the other tests to see what else you can do. +test("matchPath should not decode param containing double-encoded forward slash", async ({ + page, +}) => { + let app = new PlaywrightFixture(appFixture, page); + const encodedId = encodeURIComponent(encodeURIComponent("beforeslash/afterslash@")); + await app.goto(`/match-path/${encodedId}`); + let el = page.locator("[data-testid='item-id']"); + await expect(el).toHaveText(`Item ID: ${encodedId}`); }); //////////////////////////////////////////////////////////////////////////////// From 9b855abf6abbc2c70389490a10fb86b0e803ab2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Norrliden?= Date: Mon, 16 Jun 2025 14:55:13 +0200 Subject: [PATCH 2/2] Update contributors.yml --- contributors.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/contributors.yml b/contributors.yml index 8cbb9ba517..08bacb7445 100644 --- a/contributors.yml +++ b/contributors.yml @@ -288,6 +288,7 @@ - pruszel - pwdcd - pyitphyoaung +- qtoden - refusado - renyu-io - reyronald