import { fireEvent, render, screen } from "@testing-library/react"; import { coverSizes } from "@/app/cases/_components/CaseCover"; import { getCaseMedia } from "@/app/cases/_components/case-media"; import { getShowcaseAssets } from "@/lib/project-showcase"; import { caseStudies } from "@/lib/site-content"; import { ServiceHeroCover } from "./ServiceHeroCover"; /** * Capa de destaque do serviço: sem case não mostra nada; com case, é a imagem que abre a página (carga na hora, * prioridade alta e a largura real da coluna) e o link só pré-carrega o case quando a pessoa chega nele. */ jest.mock("@/app/cases/_components/case-media", () => ({ getCaseMedia: jest.fn(), })); jest.mock("next/link", () => ({ __esModule: true, default: ({ children, prefetch, ...props }: { children?: React.ReactNode; prefetch?: boolean | null } & Record< string, unknown >) => ( {children} ), })); const mockedGetCaseMedia = jest.mocked(getCaseMedia); const sev = caseStudies.filter(({ id }) => id === "sev-modaintima")[0]; afterEach(() => { mockedGetCaseMedia.mockReset(); }); describe("ServiceHeroCover", () => { it("path: no case -> renders nothing", () => { const { container } = render(); expect(container).toBeEmptyDOMElement(); }); it("path: case with a capture -> a cover that loads first and a caption with the case name, the relevance and 'Ver case'", () => { mockedGetCaseMedia.mockImplementation(getShowcaseAssets); const { container } = render( , ); const link = screen.getByRole("link", { name: `Ver case ${sev.title}`, }); expect(link).toHaveAttribute("href", `/cases/${sev.id}`); const image = screen.getByAltText(`Captura de tela do site ${sev.title}`); expect(image).toHaveAttribute("loading", "eager"); expect(image).toHaveAttribute("fetchpriority", "high"); expect(image).toHaveAttribute("sizes", coverSizes.hero); // a imagem também leva ao case, mas fica fora da leitura e da tabulação: o link da legenda já leva ao mesmo lugar const coverLink = image.closest("a"); expect(coverLink).toHaveAttribute("aria-hidden", "true"); expect(coverLink).toHaveAttribute("tabindex", "-1"); const caption = container.querySelector("figcaption"); expect(caption).toHaveTextContent(sev.title); expect(caption).toHaveTextContent("Frase sobre a relação com o serviço."); expect(caption).toContainElement(link); }); it("path: no relevance sentence -> the caption keeps the name and the button", () => { mockedGetCaseMedia.mockImplementation(getShowcaseAssets); const { container } = render(); expect(container.querySelector("figcaption")).toHaveTextContent( new RegExp(`^${sev.title}Ver case`), ); expect( screen.getByRole("link", { name: `Ver case ${sev.title}` }), ).toBeVisible(); }); it("path: mobile device -> the phone poster in a phone frame, a link to the case, no browser frame", () => { mockedGetCaseMedia.mockImplementation(getShowcaseAssets); const { container } = render( , ); expect(mockedGetCaseMedia).toHaveBeenCalledWith(sev.id, "mobile"); const link = screen.getByRole("link", { name: `Ver case ${sev.title}`, }); expect(link).toHaveAttribute("href", `/cases/${sev.id}`); const screenElement = container.querySelector(".ds-phone-screen"); expect(screenElement).not.toBeNull(); expect( decodeURIComponent( (screenElement as HTMLElement).style.backgroundImage ?? "", ), ).toContain(`/videos/${sev.id}/mobile.webp`); expect(container.querySelector(".ds-bframe")).toBeNull(); expect(container.querySelector("img")).toBeNull(); }); it("path: mobile device but no mobile capture -> renders nothing", () => { mockedGetCaseMedia.mockImplementation((id, device) => device === "mobile" ? undefined : getShowcaseAssets(id, device), ); const { container } = render( , ); expect(container).toBeEmptyDOMElement(); }); it("path: link -> pre-fetches the case only after the pointer reaches it", () => { mockedGetCaseMedia.mockImplementation(getShowcaseAssets); render(); const link = screen.getByRole("link"); expect(link).toHaveAttribute("data-prefetch", "false"); fireEvent.mouseEnter(link); expect(link).toHaveAttribute("data-prefetch", "null"); }); });