import { render, screen } from "@testing-library/react"; import { useEffect, useState } from "react"; import Template from "./template"; let mockPathname = "/cases"; jest.mock("next/navigation", () => ({ usePathname: () => mockPathname })); const mockMounts = jest.fn(); const mockProps: Array> = []; // o React estável do Jest não exporta (só o canary do Next); este dublê conta as montagens jest.mock("react", () => { const actual = jest.requireActual("react"); function ViewTransition({ children, ...props }: { children?: React.ReactNode } & Record) { mockProps.push(props); actual.useEffect(() => { mockMounts(); }, []); return actual.createElement("div", { "data-testid": "vt" }, children); } return { ...actual, ViewTransition }; }); function Counter() { const [count, setCount] = useState(0); useEffect(() => { setCount(1); }, []); return

{count}

; } beforeEach(() => { mockPathname = "/cases"; mockMounts.mockClear(); mockProps.length = 0; }); describe("app/template", () => { it("wraps the page in a ViewTransition named page that does not animate in-place updates", () => { render( , ); expect(screen.getByTestId("vt")).toContainElement(screen.getByRole("main")); expect(mockProps[0]).toMatchObject({ name: "page", update: "none" }); }); it("makes the page leaving and the page entering a pair when only the second segment changes (/cases -> /cases/um-projeto)", () => { const { rerender } = render( , ); expect(mockMounts).toHaveBeenCalledTimes(1); expect(screen.getByTestId("state")).toHaveTextContent("1"); mockPathname = "/cases/sev-modaintima"; rerender( , ); // a chave é o caminho: a transição desmonta a página que sai e monta a que entra (e o estado dela recomeça) expect(mockMounts).toHaveBeenCalledTimes(2); }); it("does not remount when the path stays the same (only a re-render, or a #fragment change)", () => { const { rerender } = render( , ); rerender( , ); expect(mockMounts).toHaveBeenCalledTimes(1); }); });