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.
This commit is contained in:
Evandro Fonseca Junior committed 2026-10-14 19:14:46 -03:00
1 parent e63f3c2ebd
commit fc44a69fb3
41 files changed
+2486 -550

No files matched your search

+8 -5
View File
@@ -10,10 +10,12 @@ import CasePage, { generateMetadata } from "./page";
* demonstração sem captura, resultado vazio e case sem serviço relacionado.
*/
// usePathname: o HoverPrefetchLink (trilha, cartões) lê o caminho para saber se está na home
jest.mock("next/navigation", () => ({
notFound: jest.fn(() => {
throw new Error("NEXT_NOT_FOUND");
}),
usePathname: () => "/cases",
}));
jest.mock("../_components/case-media", () => {
@@ -125,11 +127,12 @@ describe("CasePage: caminhos que o teste principal não cobre", () => {
expect(screen.getByText(/Projeto de laboratório/)).toBeVisible();
expect(screen.queryByRole("link", { name: /^Ver o serviço:/ })).toBeNull();
expect(screen.queryByText("Serviços ligados a este projeto")).toBeNull();
expect(
screen.getByRole("link", {
name: "Tem um problema parecido? Vamos conversar.",
}),
).toBeVisible();
// o NutriScan tem "Como ficou": o botão de contato vem depois dele e de novo no fecho, com o mesmo rótulo
const contacts = screen.getAllByRole("link", {
name: "Falar sobre meu projeto",
});
expect(contacts).toHaveLength(2);
for (const contact of contacts) expect(contact).toBeVisible();
expect(
screen.getByRole("link", { name: "Ver outros cases" }),
).toHaveAttribute("href", "/cases");