Skip to content

Commit

Permalink
encode pathnames in NavLink check
Browse files Browse the repository at this point in the history
  • Loading branch information
brophdawg11 committed Nov 17, 2022
1 parent e29a004 commit 43de13c
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 1 deletion.
90 changes: 90 additions & 0 deletions packages/react-router-dom/__tests__/nav-link-active-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { JSDOM } from "jsdom";
import * as React from "react";
import * as TestRenderer from "react-test-renderer";
import {
BrowserRouter,
MemoryRouter,
Routes,
Route,
Expand Down Expand Up @@ -189,6 +190,37 @@ describe("NavLink", () => {

expect(anchor.children[0]).toMatch("Home (current)");
});

it("matches when portions of the url are encoded", () => {
let renderer: TestRenderer.ReactTestRenderer;

TestRenderer.act(() => {
renderer = TestRenderer.create(
<BrowserRouter window={getWindow("/users/matt brophy")}>
<Routes>
<Route
path="/users/:name"
element={
<>
<NavLink to=".">Matt</NavLink>
<NavLink to="/users/matt brophy">Matt</NavLink>
<NavLink to="/users/michael jackson">Michael</NavLink>
</>
}
/>
</Routes>
</BrowserRouter>
);
});

let anchors = renderer.root.findAllByType("a");

expect(anchors.map((a) => a.props.className)).toEqual([
"active",
"active",
"",
]);
});
});

describe("when it matches a partial URL segment", () => {
Expand Down Expand Up @@ -712,6 +744,64 @@ describe("NavLink using a data router", () => {
await waitFor(() => screen.getByText("Baz page"));
expect(screen.getByText("Link to Bar").className).toBe("");
});

it("applies the default 'active'/'pending' classNames when the url has encoded characters", async () => {
let barDfd = createDeferred();
let bazDfd = createDeferred();
let router = createBrowserRouter(
createRoutesFromElements(
<Route path="/" element={<Layout />}>
<Route path="foo" element={<p>Foo page</p>} />
<Route
path="bar/:param"
loader={() => barDfd.promise}
element={<p>Bar page</p>}
/>
<Route
path="baz-✅"
loader={() => bazDfd.promise}
element={<p>Baz page</p>}
/>
</Route>
),
{
window: getWindow("/foo"),
}
);
render(<RouterProvider router={router} />);

function Layout() {
return (
<>
<NavLink to="/foo">Link to Foo</NavLink>
<NavLink to="/bar/matt brophy">Link to Bar</NavLink>
<NavLink to="/baz-✅">Link to Baz</NavLink>
<Outlet />
</>
);
}

expect(screen.getByText("Link to Bar").className).toBe("");
expect(screen.getByText("Link to Baz").className).toBe("");

fireEvent.click(screen.getByText("Link to Bar"));
expect(screen.getByText("Link to Bar").className).toBe("pending");
expect(screen.getByText("Link to Baz").className).toBe("");

barDfd.resolve(null);
await waitFor(() => screen.getByText("Bar page"));
expect(screen.getByText("Link to Bar").className).toBe("active");
expect(screen.getByText("Link to Baz").className).toBe("");

fireEvent.click(screen.getByText("Link to Baz"));
expect(screen.getByText("Link to Bar").className).toBe("active");
expect(screen.getByText("Link to Baz").className).toBe("pending");

bazDfd.resolve(null);
await waitFor(() => screen.getByText("Baz page"));
expect(screen.getByText("Link to Bar").className).toBe("");
expect(screen.getByText("Link to Baz").className).toBe("active");
});
});

describe("NavLink under a Routes with a basename", () => {
Expand Down
3 changes: 2 additions & 1 deletion packages/react-router-dom/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,9 @@ export const NavLink = React.forwardRef<HTMLAnchorElement, NavLinkProps>(
let path = useResolvedPath(to, { relative: rest.relative });
let location = useLocation();
let routerState = React.useContext(DataRouterStateContext);
let { navigator } = React.useContext(NavigationContext);

let toPathname = path.pathname;
let toPathname = navigator.encodeLocation(path).pathname;
let locationPathname = location.pathname;
let nextLocationPathname =
routerState && routerState.navigation && routerState.navigation.location
Expand Down

0 comments on commit 43de13c

Please sign in to comment.