import useForm, { SubmitPromise } from "@saleor/hooks/useForm"; import { act, renderHook } from "@testing-library/react-hooks"; import React from "react"; import { useHistory } from "react-router"; import { MemoryRouter } from "react-router-dom"; import { ExitFormDialogContext, useExitFormDialogProvider, } from "./ExitFormDialogProvider"; import { useExitFormDialog } from "./useExitFormDialog"; jest.mock("../../hooks/useNotifier", () => undefined); const MockExitFormDialogProvider = ({ children }) => { const { providerData } = useExitFormDialogProvider(); return ( {children} ); }; const initialPath = "/"; const targetPath = "/path"; const setup = (submitFn: () => SubmitPromise, confirmLeave = true) => renderHook( () => { const form = useForm({ field: "" }, submitFn, { confirmLeave }); const exit = useExitFormDialog(); const history = useHistory(); return { form, exit, history, }; }, { wrapper: ({ children }) => ( {children} ), }, ); describe("useExitFormDialog", () => { it("blocks navigation after leaving dirty form", async () => { // Given const submitFn = jest.fn(() => Promise.resolve([])); const { result } = setup(submitFn); // When act(() => { result.current.form.change({ target: { name: "field", value: "something" }, }); }); act(() => { result.current.history.push(targetPath); }); // Then expect(result.current.exit.shouldBlockNavigation()).toBe(true); expect(result.current.history.location.pathname).toBe(initialPath); }); it("allows navigation after leaving dirty form if no confirmation is needed", async () => { // Given const submitFn = jest.fn(() => Promise.resolve([])); const { result } = setup(submitFn, false); // When act(() => { result.current.form.change({ target: { name: "field", value: "something" }, }); }); act(() => { result.current.history.push(targetPath); }); // Then expect(result.current.exit.shouldBlockNavigation()).toBe(false); expect(result.current.history.location.pathname).toBe(targetPath); }); it("navigates to full url with querystring", async () => { // Given const submitFn = jest.fn(() => Promise.resolve([])); const { result } = setup(submitFn); const qs = "?param=value"; const targetPathWithQs = targetPath + qs; // When act(() => { result.current.form.change({ target: { name: "field", value: "something" }, }); }); act(() => { result.current.history.push(targetPathWithQs); result.current.exit.leave(); }); // Then expect(result.current.history.location.pathname).toBe(targetPath); expect(result.current.history.location.search).toBe(qs); }); });