feat(servicos): topo, entregáveis e cases por serviço, assunto próprio no WhatsApp e títulos curtos
This commit is contained in:
1 parent
cf360041bd
commit
2fd8b063d9
33 files changed
+1578
-300
No files matched your search
+31
-15
@@ -1,5 +1,5 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { Geist_Mono, Space_Grotesk } from "next/font/google";
|
||||
import localFont from "next/font/local";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import { caseStudies, serviceHubLinks, servicePages } from "@/lib/site-content";
|
||||
import RootLayout, { metadata } from "./layout";
|
||||
@@ -14,9 +14,10 @@ const mockFloatingProps = jest.fn();
|
||||
const mockFooterProps = jest.fn();
|
||||
|
||||
jest.mock("next/font/google", () => ({
|
||||
Geist_Mono: () => ({ variable: "font-mono-var" }),
|
||||
Space_Grotesk: () => ({ variable: "font-display-var" }),
|
||||
Geist_Mono: jest.fn(() => ({ variable: "font-mono-var" })),
|
||||
Space_Grotesk: jest.fn(() => ({ variable: "font-display-var" })),
|
||||
}));
|
||||
jest.mock("next/font/local", () => ({ __esModule: true, default: jest.fn() }));
|
||||
jest.mock("./globals.css", () => ({}));
|
||||
jest.mock("./components/cinematic/CinematicOverlays", () => ({
|
||||
__esModule: true,
|
||||
@@ -47,6 +48,12 @@ jest.mock("./components/FloatingWhatsApp", () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
// as fontes são pedidas ao carregar o layout (uma vez, na importação): lê-se o que foi pedido antes de qualquer
|
||||
// jest.clearAllMocks
|
||||
const monoFontOptions = jest.mocked(Geist_Mono).mock.calls[0]?.[0];
|
||||
const displayFontOptions = jest.mocked(Space_Grotesk).mock.calls[0]?.[0];
|
||||
const localFontCalls = jest.mocked(localFont).mock.calls.length;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
@@ -119,12 +126,12 @@ describe("what the layout mounts", () => {
|
||||
expect(html.match(/id="site-footer"/g)).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("gives the header and the button the service and case names, and only names", () => {
|
||||
it("gives the header and the button the whatsappSubject of each service and the case names, and only those", () => {
|
||||
markup();
|
||||
|
||||
const expected = {
|
||||
services: Object.fromEntries(
|
||||
servicePages.map((service) => [service.slug, service.navLabel]),
|
||||
servicePages.map((service) => [service.slug, service.whatsappSubject]),
|
||||
),
|
||||
cases: Object.fromEntries(
|
||||
caseStudies.map((caseStudy) => [caseStudy.id, caseStudy.title]),
|
||||
@@ -135,9 +142,19 @@ describe("what the layout mounts", () => {
|
||||
whatsAppContexts: expected,
|
||||
});
|
||||
expect(Object.keys(expected.services).length).toBeGreaterThan(0);
|
||||
// a mensagem lê "Quero conversar sobre {assunto}.": nenhum assunto de serviço começa em maiúscula
|
||||
for (const subject of Object.values(expected.services)) {
|
||||
expect(subject).toMatch(/^[a-zà-ú]/);
|
||||
}
|
||||
expect(Object.keys(expected.cases).length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("keeps the smooth anchors but opens each new page at the top: the html carries data-scroll-behavior, which makes Next turn the smooth scroll off only during the route change", () => {
|
||||
// o atributo é o que o Next lê para desligar a rolagem suave só durante a troca de rota (o e2e navigation.spec.ts
|
||||
// confere no navegador que a página nova abre em scrollY 0, sem deslizar)
|
||||
expect(markup()).toMatch(/<html[^>]* data-scroll-behavior="smooth"/);
|
||||
});
|
||||
|
||||
it("hides the JavaScript-only parts of the page when scripts are off", () => {
|
||||
expect(markup()).toContain(".js-only{display:none!important}");
|
||||
});
|
||||
@@ -145,18 +162,17 @@ describe("what the layout mounts", () => {
|
||||
|
||||
describe("fonts", () => {
|
||||
it("does not preload Geist Mono (only small labels use it), while the display font keeps its preload", () => {
|
||||
const source = readFileSync(join(__dirname, "layout.tsx"), "utf8");
|
||||
|
||||
const mono = source.match(/Geist_Mono\(\{[^}]*\}\)/)?.[0] ?? "";
|
||||
expect(mono).toMatch(/preload:\s*false/);
|
||||
const display = source.match(/Space_Grotesk\(\{[^}]*\}\)/)?.[0] ?? "";
|
||||
expect(display).not.toMatch(/preload:\s*false/);
|
||||
expect(monoFontOptions).toEqual(
|
||||
expect.objectContaining({ preload: false }),
|
||||
);
|
||||
expect(displayFontOptions).toBeDefined();
|
||||
expect(displayFontOptions).not.toEqual(
|
||||
expect.objectContaining({ preload: false }),
|
||||
);
|
||||
});
|
||||
|
||||
it("no longer loads the unused Monument Extended font", () => {
|
||||
const source = readFileSync(join(__dirname, "layout.tsx"), "utf8");
|
||||
|
||||
expect(source).not.toMatch(/Monument|next\/font\/local/i);
|
||||
expect(localFontCalls).toBe(0);
|
||||
expect(markupClassName()).not.toMatch(/monument/i);
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user