import { render } from "@testing-library/react"; import type { ComponentProps } from "react"; import { clientCasesForListing as clientCases } from "@/lib/site-content"; import CasesPage from "./page"; /** * Carregamento da lista de cases: sem mosaico no topo, a capa do primeiro cartão (a maior imagem acima da dobra) carrega * na hora e com prioridade alta, as outras capas são preguiçosas, e os links não pré-carregam as páginas dos cases sozinhos. */ type LinkProps = ComponentProps; /** Propriedades de cada `Link` renderizado: o `prefetch` não aparece no HTML, então a rota é espiada aqui. */ const mockLinkProps: LinkProps[] = []; jest.mock("next/link", () => ({ __esModule: true, default: ({ children, href, prefetch, ...anchor }: LinkProps) => { mockLinkProps.push({ children, href, prefetch, ...anchor }); return ( )}> {children} ); }, })); beforeEach(() => { mockLinkProps.length = 0; }); function coverImages(container: HTMLElement) { return clientCases.map((caseStudy) => { const image = container .querySelector(`a[href="/cases/${caseStudy.id}"][aria-hidden="true"]`) ?.querySelector("img"); if (!image) throw new Error(`Missing cover of ${caseStudy.id}`); return image; }); } describe("CasesPage: carregamento das capas", () => { it("loads the first card cover at once with high priority, and every other image lazily", () => { const { container } = render(); // sem mosaico: a única imagem decorativa (alt vazio) é a peça de blocos do topo, preguiçosa e sem prioridade const decorative = Array.from( container.querySelectorAll("img"), ).filter((image) => image.getAttribute("alt") === ""); expect(decorative).toHaveLength(1); expect(decorative[0].getAttribute("src")).toContain("estado-tela.webp"); expect(decorative[0]).toHaveAttribute("loading", "lazy"); expect(decorative[0]).not.toHaveAttribute("fetchpriority"); const [first, ...others] = coverImages(container); expect(first).toHaveAttribute("loading", "eager"); expect(first).toHaveAttribute("fetchpriority", "high"); expect(others.length).toBeGreaterThan(0); for (const image of others) { expect(image).toHaveAttribute("loading", "lazy"); expect(image).not.toHaveAttribute("fetchpriority"); } }); it("does not prefetch the case pages from the cover links, nor from the card buttons", () => { render(); const toCases = mockLinkProps.filter(({ href }) => String(href).startsWith("/cases/"), ); // uma capa e um botão por case de cliente, e um botão por projeto do laboratório expect(toCases.length).toBeGreaterThanOrEqual(clientCases.length * 2); for (const props of toCases) { expect(props.prefetch).toBe(false); } }); });