184 lines
6.2 KiB
TypeScript
184 lines
6.2 KiB
TypeScript
import { servicePages } from "./site-content";
|
|
import {
|
|
AI_REVIEW_SUBJECT,
|
|
buildWhatsAppUrl,
|
|
CASES_SUBJECT,
|
|
HOME_SUBJECT,
|
|
headerOpensWhatsApp,
|
|
isServiceOrCasePath,
|
|
OFFER_SUBJECTS,
|
|
RESUME_SUBJECT,
|
|
SERVICES_SUBJECT,
|
|
similarProjectSubject,
|
|
type WhatsAppContexts,
|
|
whatsAppSubjectForPath,
|
|
} from "./whatsapp";
|
|
|
|
const contexts: WhatsAppContexts = {
|
|
// 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> 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", () => {
|
|
expect(whatsAppSubjectForPath("/cases/sev-modaintima", contexts)).toBe(
|
|
"um projeto parecido com o case SEV Moda Íntima",
|
|
);
|
|
expect(similarProjectSubject("Lavação 047")).toBe(
|
|
"um projeto parecido com o case Lavação 047",
|
|
);
|
|
});
|
|
|
|
it("speaks of the page itself on the home and the index pages, the same as the body buttons of /cases and /servicos", () => {
|
|
expect(whatsAppSubjectForPath("/", contexts)).toBe(HOME_SUBJECT);
|
|
expect(whatsAppSubjectForPath("/cases", contexts)).toBe(CASES_SUBJECT);
|
|
expect(CASES_SUBJECT).toBe("um projeto parecido com os cases do portfólio");
|
|
expect(whatsAppSubjectForPath("/servicos", contexts)).toBe(
|
|
SERVICES_SUBJECT,
|
|
);
|
|
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);
|
|
expect(whatsAppSubjectForPath("/curriculo/")).toBe(RESUME_SUBJECT);
|
|
});
|
|
|
|
it("cites the AI review on /ia", () => {
|
|
expect(whatsAppSubjectForPath("/ia", contexts)).toBe(AI_REVIEW_SUBJECT);
|
|
expect(whatsAppSubjectForPath("/ia/", undefined)).toBe(AI_REVIEW_SUBJECT);
|
|
});
|
|
|
|
it("ignores a trailing slash", () => {
|
|
expect(
|
|
whatsAppSubjectForPath("/servicos/criacao-de-sites/", contexts),
|
|
).toBe("um site que traz pedidos pelo WhatsApp");
|
|
});
|
|
|
|
it.each([
|
|
"/privacidade",
|
|
"/notebook-smoke",
|
|
"/servicos/inexistente",
|
|
"/cases/inexistente",
|
|
"/servicos/criacao-de-sites/extra",
|
|
// nomes que existem em todo objeto não podem virar assunto
|
|
"/servicos/constructor",
|
|
"/cases/__proto__",
|
|
"/cases/toString",
|
|
])("falls back to a generic message on %s", (pathname) => {
|
|
expect(whatsAppSubjectForPath(pathname, contexts)).toBeUndefined();
|
|
});
|
|
|
|
it("treats an empty or blank name as missing, so the message never reads 'sobre .'", () => {
|
|
const blank: WhatsAppContexts = {
|
|
services: { vazio: "", espacos: " " },
|
|
cases: { vazio: "", espacos: " " },
|
|
};
|
|
for (const pathname of [
|
|
"/servicos/vazio",
|
|
"/servicos/espacos",
|
|
"/cases/vazio",
|
|
"/cases/espacos",
|
|
]) {
|
|
expect(whatsAppSubjectForPath(pathname, blank)).toBeUndefined();
|
|
}
|
|
});
|
|
|
|
it("is generic without contexts, without a pathname or outside the router", () => {
|
|
expect(
|
|
whatsAppSubjectForPath("/servicos/criacao-de-sites"),
|
|
).toBeUndefined();
|
|
expect(whatsAppSubjectForPath(null, contexts)).toBeUndefined();
|
|
expect(whatsAppSubjectForPath(undefined, contexts)).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("isServiceOrCasePath", () => {
|
|
it.each([
|
|
["/servicos/criacao-de-sites", true],
|
|
["/servicos/qualquer-coisa/", true],
|
|
["/cases/sev-modaintima", true],
|
|
["/", false],
|
|
["/servicos", false],
|
|
["/cases", false],
|
|
["/ia", false],
|
|
["/servicos/a/b", false],
|
|
[null, false],
|
|
[undefined, false],
|
|
])("%s -> %s", (pathname, expected) => {
|
|
expect(isServiceOrCasePath(pathname)).toBe(expected);
|
|
});
|
|
});
|
|
|
|
describe("headerOpensWhatsApp", () => {
|
|
it.each([
|
|
["/servicos/criacao-de-sites", true],
|
|
["/servicos/inexistente", true],
|
|
["/cases/sev-modaintima", true],
|
|
["/ia", true],
|
|
["/ia/", true],
|
|
["/cases", true],
|
|
["/servicos", true],
|
|
["/curriculo", true],
|
|
["/curriculo/", true],
|
|
// a home já tem o formulário na própria página; as demais rotas não têm assunto
|
|
["/", false],
|
|
["/privacidade", false],
|
|
["/cases/a/b", false],
|
|
["/ia/extra", false],
|
|
[null, false],
|
|
[undefined, false],
|
|
])("%s -> %s", (pathname, expected) => {
|
|
expect(headerOpensWhatsApp(pathname)).toBe(expected);
|
|
});
|
|
});
|
|
|
|
describe("buildWhatsAppUrl", () => {
|
|
it("encodes the message in the text parameter of a wa.me link", () => {
|
|
const url = new URL(buildWhatsAppUrl("Olá & tudo? #1"));
|
|
|
|
expect(url.origin).toBe("https://wa.me");
|
|
expect(url.pathname).toMatch(/^\/\d{12,13}$/);
|
|
expect(url.searchParams.get("text")).toBe("Olá & tudo? #1");
|
|
});
|
|
});
|