feat(servicos): topo, entregáveis e cases por serviço, assunto próprio no WhatsApp e títulos curtos

This commit is contained in:
Evandro Fonseca Junior committed 2026-10-14 22:54:18 -03:00
1 parent cf360041bd
commit 2fd8b063d9
33 files changed
+1578 -300

No files matched your search

+42 -6
View File
@@ -1,3 +1,4 @@
import { servicePages } from "./site-content";
import {
AI_REVIEW_SUBJECT,
buildWhatsAppUrl,
@@ -5,6 +6,7 @@ import {
HOME_SUBJECT,
headerOpensWhatsApp,
isServiceOrCasePath,
OFFER_SUBJECTS,
RESUME_SUBJECT,
SERVICES_SUBJECT,
similarProjectSubject,
@@ -13,15 +15,39 @@ import {
} from "./whatsapp";
const contexts: WhatsAppContexts = {
services: { "criacao-de-sites": "Sites profissionais" },
// o whatsappSubject do serviço, como app/layout.tsx o monta: uma frase em minúsculas, e não o nome do serviço
services: { "criacao-de-sites": "um site que traz pedidos pelo WhatsApp" },
cases: { "sev-modaintima": "SEV Moda Íntima" },
};
describe("whatsAppSubjectForPath", () => {
it("cites the service on /servicos/<slug>", () => {
expect(whatsAppSubjectForPath("/servicos/criacao-de-sites", contexts)).toBe(
"Sites profissionais",
it("cites the service on /servicos/<slug> with its whatsappSubject, a lowercase phrase, so the message reads as a sentence", () => {
const subject = whatsAppSubjectForPath(
"/servicos/criacao-de-sites",
contexts,
);
expect(subject).toBe("um site que traz pedidos pelo WhatsApp");
expect(`Quero conversar sobre ${subject}.`).not.toMatch(
/sobre Sites profissionais/,
);
});
it("has a whatsappSubject, in lowercase and with no final period, for every service page and offer of site-content", () => {
expect(servicePages.length).toBeGreaterThan(0);
for (const { slug, navLabel, whatsappSubject } of servicePages) {
// não é o nome do serviço (que tem inicial maiúscula): é uma frase que entra depois de "sobre"
expect(whatsappSubject).toMatch(/^[a-zà-ú].*[^.]$/);
expect(whatsappSubject).not.toBe(navLabel);
expect(
whatsAppSubjectForPath(`/servicos/${slug}`, {
services: { [slug]: whatsappSubject },
cases: {},
}),
).toBe(whatsappSubject);
}
for (const subject of Object.values(OFFER_SUBJECTS)) {
expect(subject).toMatch(/^[a-zà-ú].*[^.]$/);
}
});
it("cites the case on /cases/<slug>, with the phrase every page uses for a similar project", () => {
@@ -40,7 +66,17 @@ describe("whatsAppSubjectForPath", () => {
expect(whatsAppSubjectForPath("/servicos", contexts)).toBe(
SERVICES_SUBJECT,
);
expect(SERVICES_SUBJECT).toBe("Sites, sistemas e aplicativos");
expect(SERVICES_SUBJECT).toBe("sites, sistemas e aplicativos");
// nenhum assunto fixo começa em maiúscula: "Quero conversar sobre Sites, sistemas..." era o erro
for (const subject of [
AI_REVIEW_SUBJECT,
HOME_SUBJECT,
CASES_SUBJECT,
SERVICES_SUBJECT,
RESUME_SUBJECT,
]) {
expect(subject).toMatch(/^[a-zà-ú]/);
}
expect(whatsAppSubjectForPath("/curriculo", contexts)).toBe(RESUME_SUBJECT);
// sem contextos, a página-índice continua falando de si
expect(whatsAppSubjectForPath("/cases/")).toBe(CASES_SUBJECT);
@@ -55,7 +91,7 @@ describe("whatsAppSubjectForPath", () => {
it("ignores a trailing slash", () => {
expect(
whatsAppSubjectForPath("/servicos/criacao-de-sites/", contexts),
).toBe("Sites profissionais");
).toBe("um site que traz pedidos pelo WhatsApp");
});
it.each([