Files
portifolio-evandrodevbr/app/servicos/_components/ServiceHeroCover.test.tsx
T
Evandro Fonseca Junior fc44a69fb3 feat(servicos): ofertas no topo de /servicos, capa por assunto e diagramas
/servicos abre com as 3 ofertas e depois outros serviços; H1 de criação de sites e de engenharia com o nome da oferta; capa de cada serviço pelo assunto (SEV fora do próprio case cai de ~11 para 2 imagens); diagrama de fluxo em SVG nos serviços sem case; cases com o que o cliente passou a poder fazer e contato logo depois de Como ficou; FAQ num componente só; lastmod por rota; ProfessionalService com areaServed.
2026-10-14 19:14:46 -03:00

128 lines
4.7 KiB
TypeScript

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
>) => (
<a data-prefetch={String(prefetch)} {...props}>
{children}
</a>
),
}));
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(<ServiceHeroCover />);
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(
<ServiceHeroCover
caseStudy={sev}
relevance="Frase sobre a relação com o serviço."
/>,
);
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(<ServiceHeroCover caseStudy={sev} />);
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(
<ServiceHeroCover caseStudy={sev} device="mobile" />,
);
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(
<ServiceHeroCover caseStudy={sev} device="mobile" />,
);
expect(container).toBeEmptyDOMElement();
});
it("path: link -> pre-fetches the case only after the pointer reaches it", () => {
mockedGetCaseMedia.mockImplementation(getShowcaseAssets);
render(<ServiceHeroCover caseStudy={sev} />);
const link = screen.getByRole("link");
expect(link).toHaveAttribute("data-prefetch", "false");
fireEvent.mouseEnter(link);
expect(link).toHaveAttribute("data-prefetch", "null");
});
});