import { fireEvent, render, screen } from "@testing-library/react"; import { usePathname } from "next/navigation"; import HoverPrefetchLink from "./HoverPrefetchLink"; /** * Testes de caminhos-base do pré-carregamento de âncoras da home em HoverPrefetchLink (complemento de * HoverPrefetchLink.test.tsx). * * isHomeAnchor (CC 3): href em texto (é âncora da home | não é) | href em objeto (caminho "/" e hash | caminho "/" sem * hash | outro caminho). O que faltava: o objeto com caminho "/" e SEM hash, que não é âncora e pré-carrega. * HoverPrefetchLink (CC 5): caminho desconhecido | na home | fora da home com âncora da home | fora da home com outro * link, cada um ativado ou não. Já cobertos; aqui entram as trocas de página com o link já ativado. * O dublê de next/navigation sem `usePathname` está em HoverPrefetchLink.nopathname.paths.test.tsx. */ jest.mock("next/link", () => ({ __esModule: true, default: ({ children, prefetch, ...props }: { children?: React.ReactNode; prefetch?: boolean | null } & Record< string, unknown >) => ( {children} ), })); const link = () => screen.getByRole("link", { name: "Ir" }); beforeEach(() => { jest.mocked(usePathname).mockReturnValue("/privacidade"); }); describe("isHomeAnchor, vista de fora da home", () => { it.each([ ["objeto com caminho / e sem hash", { pathname: "/" }], ["objeto com caminho / e hash vazio", { pathname: "/", hash: "" }], ["objeto com outro caminho e hash", { pathname: "/cases", hash: "#x" }], ["objeto só com hash (a página aberta)", { hash: "#x" }], ["objeto com caminho / e só a busca", { pathname: "/", query: { a: "b" } }], ])( "path: %s -> não é âncora da home, pré-carrega ao chegar", (_name, href) => { render(Ir); fireEvent.mouseEnter(link()); expect(link()).toHaveAttribute("data-prefetch", "null"); }, ); it.each([ [ "objeto com caminho /, hash e busca", { pathname: "/", hash: "#contact", query: { tipo: "site" } }, ], ["objeto com caminho / e hash sem #", { pathname: "/", hash: "contact" }], ["texto com busca e hash", "/?tipo=site#contact"], ["texto com busca de vários parâmetros e hash", "/?a=b&c=d#contact"], ])("path: %s -> é âncora da home, nunca pré-carrega", (_name, href) => { render(Ir); fireEvent.mouseEnter(link()); fireEvent.focus(link()); fireEvent.touchStart(link()); expect(link()).toHaveAttribute("data-prefetch", "false"); }); it.each([ ["texto com busca e sem hash", "/?tipo=site"], ["texto de outra página com hash", "/cases#x"], ["texto de outra página com busca e hash", "/cases?a=b#x"], ["texto com dois caminhos e hash (//host)", "//cdn.example.com/#x"], ])( "path: %s -> não é âncora da home, pré-carrega ao chegar", (_name, href) => { render(Ir); fireEvent.mouseEnter(link()); expect(link()).toHaveAttribute("data-prefetch", "null"); }, ); }); describe("HoverPrefetchLink: quando a página aberta muda", () => { it("path: leaves the home anchor, comes back to the home and goes away again -> prefetching follows the page, never the link's earlier state", () => { jest.mocked(usePathname).mockReturnValue("/"); const { rerender } = render( Ir, ); fireEvent.mouseEnter(link()); expect(link()).toHaveAttribute("data-prefetch", "null"); jest.mocked(usePathname).mockReturnValue("/servicos"); rerender(Ir); expect(link()).toHaveAttribute("data-prefetch", "false"); jest.mocked(usePathname).mockReturnValue("/"); rerender(Ir); expect(link()).toHaveAttribute("data-prefetch", "null"); jest.mocked(usePathname).mockReturnValue("/cases/lavacao-047"); rerender(Ir); expect(link()).toHaveAttribute("data-prefetch", "false"); }); it("path: a home anchor never reached from another page, then the visitor reaches the home -> prefetching only starts with the first touch", () => { const { rerender } = render( Ir, ); expect(link()).toHaveAttribute("data-prefetch", "false"); jest.mocked(usePathname).mockReturnValue("/"); rerender(Ir); expect(link()).toHaveAttribute("data-prefetch", "false"); fireEvent.touchStart(link()); expect(link()).toHaveAttribute("data-prefetch", "null"); }); });