Skip to content

Commit

Permalink
Update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
brophdawg11 committed Jul 13, 2023
1 parent 9d708b5 commit d470e99
Showing 1 changed file with 85 additions and 110 deletions.
195 changes: 85 additions & 110 deletions packages/react-router-dom/__tests__/use-prompt-test.tsx
Original file line number Diff line number Diff line change
@@ -1,151 +1,126 @@
import * as React from "react";
import { act, render, screen } from "@testing-library/react";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import {
Link,
RouterProvider,
createBrowserRouter,
unstable_usePrompt as usePrompt,
} from "../index";
import "@testing-library/jest-dom";

const PromptRoute = ({ when, message }: Parameters<typeof usePrompt>[0]) => {
usePrompt({ when, message });

return (
<>
<h1>Prompt Route</h1>

<Link to="/arbitrary">Navigate to arbitrary route</Link>
</>
);
};

const ArbitraryRoute = () => {
return <h1>Arbitrary Route</h1>;
};
import { JSDOM } from "jsdom";

describe("usePrompt", () => {
afterEach(() => {
jest.clearAllMocks();

window.history.pushState({}, "", "/");
});

describe("when navigation is blocked", () => {
it("shows the confirmation prompt and does not navigate when the confirmation prompt is cancelled", () => {
const when = true;
const message = "__MESSAGE__";

const router = createBrowserRouter([
{
path: "/",
element: <PromptRoute when={when} message={message} />,
},
{
path: "/arbitrary",
element: <ArbitraryRoute />,
},
]);

render(<RouterProvider router={router} />);

expect(
screen.getByRole("heading", { name: "Prompt Route" })
).toBeInTheDocument();

it("shows window.confirm and blocks navigation when it returns false", async () => {
let testWindow = getWindowImpl("/");
const windowConfirmMock = jest
.spyOn(window, "confirm")
.mockImplementationOnce(() => false);

act(() => {
screen
.getByRole("link", { name: "Navigate to arbitrary route" })
.click();
});

expect(windowConfirmMock).toHaveBeenNthCalledWith(1, message);

expect(
screen.getByRole("heading", { name: "Prompt Route" })
).toBeInTheDocument();
});

it("shows the confirmation prompt and navigates when the confirmation prompt is accepted", () => {
const when = true;
const message = "__MESSAGE__";

const router = createBrowserRouter([
{
path: "/",
element: <PromptRoute when={when} message={message} />,
},
{
path: "/arbitrary",
element: <ArbitraryRoute />,
},
]);
let router = createBrowserRouter(
[
{
path: "/",
Component() {
usePrompt({ when: true, message: "Are you sure??" });
return <Link to="/arbitrary">Navigate</Link>;
},
},
{
path: "/arbitrary",
Component: () => <h1>Arbitrary</h1>,
},
],
{ window: testWindow }
);

render(<RouterProvider router={router} />);
expect(screen.getByText("Navigate")).toBeInTheDocument();

expect(
screen.getByRole("heading", { name: "Prompt Route" })
).toBeInTheDocument();
fireEvent.click(screen.getByText("Navigate"));
await new Promise((r) => setTimeout(r, 0));

expect(windowConfirmMock).toHaveBeenNthCalledWith(1, "Are you sure??");
expect(screen.getByText("Navigate")).toBeInTheDocument();
});

it("shows window.confirm and navigates when it returns true", async () => {
let testWindow = getWindowImpl("/");
const windowConfirmMock = jest
.spyOn(window, "confirm")
.mockImplementationOnce(() => true);

act(() => {
screen
.getByRole("link", { name: "Navigate to arbitrary route" })
.click();
});
let router = createBrowserRouter(
[
{
path: "/",
Component() {
usePrompt({ when: true, message: "Are you sure??" });
return <Link to="/arbitrary">Navigate</Link>;
},
},
{
path: "/arbitrary",
Component: () => <h1>Arbitrary</h1>,
},
],
{ window: testWindow }
);

render(<RouterProvider router={router} />);
expect(screen.getByText("Navigate")).toBeInTheDocument();

expect(windowConfirmMock).toHaveBeenNthCalledWith(1, message);
fireEvent.click(screen.getByText("Navigate"));
await waitFor(() => screen.getByText("Arbitrary"));

expect(
screen.getByRole("heading", { name: "Arbitrary Route" })
).toBeInTheDocument();
expect(windowConfirmMock).toHaveBeenNthCalledWith(1, "Are you sure??");
expect(screen.getByText("Arbitrary")).toBeInTheDocument();
});
});

describe("when navigation is not blocked", () => {
it("navigates without showing the confirmation prompt", () => {
const when = false;
const message = "__MESSAGE__";

const router = createBrowserRouter([
{
path: "/",
element: <PromptRoute when={when} message={message} />,
},
{
path: "/arbitrary",
element: <ArbitraryRoute />,
},
]);

render(<RouterProvider router={router} />);

expect(
screen.getByRole("heading", { name: "Prompt Route" })
).toBeInTheDocument();

it("navigates without showing window.confirm", async () => {
let testWindow = getWindowImpl("/");
const windowConfirmMock = jest
.spyOn(window, "confirm")
.mockImplementationOnce(() => false);
.mockImplementation(() => true);

let router = createBrowserRouter(
[
{
path: "/",
Component() {
usePrompt({ when: false, message: "Are you sure??" });
return <Link to="/arbitrary">Navigate</Link>;
},
},
{
path: "/arbitrary",
Component: () => <h1>Arbitrary</h1>,
},
],
{ window: testWindow }
);

render(<RouterProvider router={router} />);
expect(screen.getByText("Navigate")).toBeInTheDocument();

act(() => {
screen
.getByRole("link", { name: "Navigate to arbitrary route" })
.click();
});
fireEvent.click(screen.getByText("Navigate"));
await waitFor(() => screen.getByText("Arbitrary"));

expect(windowConfirmMock).not.toHaveBeenCalled();

expect(
screen.getByRole("heading", { name: "Arbitrary Route" })
).toBeInTheDocument();
expect(screen.getByText("Arbitrary")).toBeInTheDocument();
});
});
});

function getWindowImpl(initialUrl: string, isHash = false): Window {
// Need to use our own custom DOM in order to get a working history
const dom = new JSDOM(`<!DOCTYPE html>`, { url: "http://localhost/" });
dom.window.history.replaceState(null, "", (isHash ? "#" : "") + initialUrl);
return dom.window as unknown as Window;
}

0 comments on commit d470e99

Please sign in to comment.