/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.
128 lines
4.7 KiB
TypeScript
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");
|
|
});
|
|
});
|