feat(cases): mídia no topo, títulos de busca curtos e CreativeWork
Case com mídia ao lado do título e play acessível; problema de cada cliente reescrito com base nos dados; serviços relacionados em 2 cards; FAQ antes do próximo passo e bloco 'Onde já apliquei isso'; Apolo citada em IoT e arquitetura. metaTitle até 43 caracteres e descrições até 155 com teste; JSON-LD CreativeWork; imagens de compartilhamento abaixo de 100 KB; 404 e robots corrigidos; server-only nos módulos com node:.
This commit is contained in:
1 parent
c9a0b80656
commit
e80f73d075
52 files changed
+2593
-439
No files matched your search
@@ -0,0 +1,130 @@
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { getShowcaseAssets } from "@/lib/project-showcase";
|
||||
import { caseStudies } from "@/lib/site-content";
|
||||
import { CaseHero } from "./CaseHero";
|
||||
import { getCaseMedia } from "./case-media";
|
||||
|
||||
/**
|
||||
* Testes de caminhos-base de CaseHero e dos fatos do projeto: com e sem captura gravada, case de cliente e de
|
||||
* laboratório, e a lista de fatos ausente, vazia ou preenchida. A existência da captura é simulada em getCaseMedia.
|
||||
*/
|
||||
|
||||
jest.mock("./case-media", () => ({ getCaseMedia: jest.fn() }));
|
||||
|
||||
const mockedGetCaseMedia = jest.mocked(getCaseMedia);
|
||||
|
||||
function getCase(id: string) {
|
||||
const caseStudy = caseStudies.find((item) => item.id === id);
|
||||
if (!caseStudy) throw new Error(`Missing case ${id}`);
|
||||
return caseStudy;
|
||||
}
|
||||
|
||||
const client = getCase("sev-modaintima");
|
||||
const lab = getCase("twins-lab");
|
||||
|
||||
function withCapture(has: boolean) {
|
||||
mockedGetCaseMedia.mockImplementation((id, device) =>
|
||||
has ? getShowcaseAssets(id, device) : undefined,
|
||||
);
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
mockedGetCaseMedia.mockReset();
|
||||
});
|
||||
|
||||
describe("CaseHero: captura gravada e tipo de case", () => {
|
||||
it("path: client case with a capture -> two columns, the cover on the right, the client eyebrow", () => {
|
||||
withCapture(true);
|
||||
const { container } = render(<CaseHero caseStudy={client} isClient />);
|
||||
|
||||
expect(container.querySelector(".ds-section-shell")).toHaveClass("grid");
|
||||
expect(container.querySelector(".ds-bframe")).toBeInTheDocument();
|
||||
expect(screen.getByText(/Case de cliente/)).toBeVisible();
|
||||
expect(
|
||||
screen.getByRole("heading", { level: 1, name: client.headline }),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
it("path: client case without a capture -> one column and no cover", () => {
|
||||
withCapture(false);
|
||||
const { container } = render(<CaseHero caseStudy={client} isClient />);
|
||||
|
||||
expect(container.querySelector(".ds-section-shell")).not.toHaveClass(
|
||||
"grid",
|
||||
);
|
||||
expect(container.querySelector(".ds-bframe")).toBeNull();
|
||||
expect(screen.getByText(client.summary)).toBeVisible();
|
||||
});
|
||||
|
||||
it("path: laboratory case with a capture -> the cover shows, with the laboratory eyebrow", () => {
|
||||
withCapture(true);
|
||||
const { container } = render(<CaseHero caseStudy={lab} isClient={false} />);
|
||||
|
||||
expect(container.querySelector(".ds-bframe")).toBeInTheDocument();
|
||||
expect(screen.getByText(/Projeto de laboratório/)).toBeVisible();
|
||||
expect(screen.queryByText(/Case de cliente/)).toBeNull();
|
||||
});
|
||||
|
||||
it("path: laboratory case without a capture -> one column, laboratory eyebrow, title and summary", () => {
|
||||
withCapture(false);
|
||||
const { container } = render(<CaseHero caseStudy={lab} isClient={false} />);
|
||||
|
||||
expect(container.querySelector(".ds-section-shell")).not.toHaveClass(
|
||||
"grid",
|
||||
);
|
||||
expect(container.querySelector(".ds-bframe")).toBeNull();
|
||||
expect(screen.getByText(/Projeto de laboratório/)).toBeVisible();
|
||||
expect(screen.getByText(lab.summary)).toBeVisible();
|
||||
});
|
||||
|
||||
it("path: breadcrumb -> Início, Cases and the case itself as the current page", () => {
|
||||
withCapture(false);
|
||||
render(<CaseHero caseStudy={client} isClient />);
|
||||
|
||||
const links = screen.getAllByRole("link");
|
||||
expect(links.map((link) => link.getAttribute("href"))).toEqual([
|
||||
"/",
|
||||
"/cases",
|
||||
`/cases/${client.id}`,
|
||||
]);
|
||||
expect(links[2]).toHaveAttribute("aria-current", "page");
|
||||
});
|
||||
});
|
||||
|
||||
describe("CaseHero: fatos do projeto", () => {
|
||||
const withFacts = (facts: string[] | undefined) => ({
|
||||
...client,
|
||||
facts,
|
||||
});
|
||||
|
||||
it("path: no facts field -> no list", () => {
|
||||
withCapture(false);
|
||||
render(<CaseHero caseStudy={withFacts(undefined)} isClient />);
|
||||
|
||||
expect(screen.queryByRole("list", { name: "Fatos do projeto" })).toBeNull();
|
||||
});
|
||||
|
||||
it("path: empty facts list -> no list", () => {
|
||||
withCapture(false);
|
||||
render(<CaseHero caseStudy={withFacts([])} isClient />);
|
||||
|
||||
expect(screen.queryByRole("list", { name: "Fatos do projeto" })).toBeNull();
|
||||
});
|
||||
|
||||
it("path: filled facts -> one item each, after the summary", () => {
|
||||
withCapture(false);
|
||||
render(
|
||||
<CaseHero
|
||||
caseStudy={withFacts(["No ar desde 2025", "Dois painéis"])}
|
||||
isClient
|
||||
/>,
|
||||
);
|
||||
|
||||
const list = screen.getByRole("list", { name: "Fatos do projeto" });
|
||||
expect(list.querySelectorAll("li")).toHaveLength(2);
|
||||
expect(
|
||||
screen.getByText(client.summary).compareDocumentPosition(list) &
|
||||
Node.DOCUMENT_POSITION_FOLLOWING,
|
||||
).toBeTruthy();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user