fix(cases): um só convite ao WhatsApp no fim do case e testes alinhados

This commit is contained in:
Evandro Fonseca Junior committed 2026-10-14 22:54:19 -03:00
1 parent 2fd8b063d9
commit d356c364e0
7 files changed
+124 -197

No files matched your search

@@ -1,46 +1,26 @@
import { render, screen } from "@testing-library/react";
import { getShowcaseAssets } from "@/lib/project-showcase";
import { buttonLabels } from "@/lib/site-content";
import { similarProjectSubject } from "@/lib/whatsapp";
import { setNavigation } from "@/__mocks__/next/navigation";
import { CaseCapabilitiesSection } from "./CaseCapabilitiesSection";
import { getCaseMedia } from "./case-media";
/**
* Testes de caminhos-base de CaseCapabilitiesSection: com itens e "Como ficou" (lista e botão), só com "Como ficou"
* (só o botão), só com itens (só a lista, sem repetir o botão que o fecho da página já traz) e sem nada (não aparece).
* A existência das capturas em disco é simulada em getCaseMedia.
* Testes de caminhos-base de CaseCapabilitiesSection: com itens (a lista sob o título do cliente ou do laboratório, sem
* botão de contato: o fecho do case vem logo depois e é o único convite, para não haver dois "Falar sobre meu projeto"
* seguidos) e sem itens (a seção não aparece, tenha o case site no ar ou captura ou não).
*/
jest.mock("next/navigation", () => ({ usePathname: () => "/cases" }));
jest.mock("./case-media", () => ({ getCaseMedia: jest.fn() }));
const mockedGetCaseMedia = jest.mocked(getCaseMedia);
beforeEach(() => {
setNavigation({ pathname: "/cases" });
});
const capabilities = [
"O dono muda os preços sem pedir a ninguém.",
"O cliente pede pelo WhatsApp com a mensagem pronta.",
];
const withSite = {
id: "projeto-teste",
title: "Projeto Teste",
demoUrl: "https://exemplo.com.br",
};
function messageOf(link: HTMLElement) {
return new URL(link.getAttribute("href") ?? "").searchParams.get("text");
}
beforeEach(() => {
mockedGetCaseMedia.mockReturnValue(undefined);
});
describe("CaseCapabilitiesSection", () => {
it("path: items and a site on the air -> the list under the client title, then the contact button", () => {
render(
<CaseCapabilitiesSection
caseStudy={{ ...withSite, capabilities }}
isClient
/>,
it("path: items -> the list under the client title, with no contact button of its own", () => {
const { container } = render(
<CaseCapabilitiesSection caseStudy={{ capabilities }} isClient />,
);
expect(
@@ -52,25 +32,14 @@ describe("CaseCapabilitiesSection", () => {
for (const item of capabilities) {
expect(screen.getByText(item)).toBeVisible();
}
const button = screen.getByRole("link", { name: buttonLabels.contact });
expect(button).toHaveAttribute("target", "_blank");
expect(button.className).toContain("bg-[var(--slash)]");
expect(messageOf(button)).toContain(
`Quero conversar sobre ${similarProjectSubject(withSite.title)}.`,
);
// o botão vem depois da lista
expect(
screen.getByText(capabilities[1]).compareDocumentPosition(button) &
Node.DOCUMENT_POSITION_FOLLOWING,
).toBeTruthy();
// o botão "Falar sobre meu projeto" é do fecho do case (CaseContactSection), não desta seção
expect(screen.queryByRole("link")).toBeNull();
expect(container.querySelectorAll("a")).toHaveLength(0);
});
it("path: a laboratory case with items -> the title does not talk about a client", () => {
render(
<CaseCapabilitiesSection
caseStudy={{ ...withSite, capabilities }}
isClient={false}
/>,
<CaseCapabilitiesSection caseStudy={{ capabilities }} isClient={false} />,
);
expect(
@@ -82,55 +51,17 @@ describe("CaseCapabilitiesSection", () => {
expect(screen.queryByText(/o cliente passou a poder fazer/i)).toBeNull();
});
it("path: no items but a capture on disk (no site) -> only the contact button, under a heading that only screen readers get", () => {
mockedGetCaseMedia.mockImplementation((id, device) =>
id === "projeto-teste" ? getShowcaseAssets(id, device) : undefined,
);
it("path: no items -> renders nothing, with no button on its own even when the case has a capture or a site", () => {
const { container } = render(
<CaseCapabilitiesSection
caseStudy={{
id: "projeto-teste",
title: "Projeto Teste",
demoUrl: null,
}}
isClient
/>,
<CaseCapabilitiesSection caseStudy={{}} isClient />,
);
expect(container.querySelector("ul")).toBeNull();
expect(
screen.getByRole("link", { name: buttonLabels.contact }),
).toBeVisible();
expect(screen.getByRole("heading", { level: 2 })).toHaveClass("sr-only");
expect(container).toBeEmptyDOMElement();
});
it("path: items but no 'Como ficou' -> the list stays and the button is not repeated", () => {
render(
<CaseCapabilitiesSection
caseStudy={{
id: "projeto-teste",
title: "Projeto Teste",
demoUrl: null,
capabilities,
}}
isClient
/>,
);
expect(screen.getByText(capabilities[0])).toBeVisible();
expect(screen.queryByRole("link")).toBeNull();
});
it("path: no items and no 'Como ficou' -> renders nothing", () => {
it("path: an empty list of items -> renders nothing", () => {
const { container } = render(
<CaseCapabilitiesSection
caseStudy={{
id: "projeto-teste",
title: "Projeto Teste",
demoUrl: null,
}}
isClient
/>,
<CaseCapabilitiesSection caseStudy={{ capabilities: [] }} isClient />,
);
expect(container).toBeEmptyDOMElement();