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:.
37 lines
1.2 KiB
TypeScript
37 lines
1.2 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
|
|
const root = join(__dirname, "..");
|
|
|
|
describe("fronteira entre servidor e cliente", () => {
|
|
it.each([
|
|
"app/cases/_components/case-media.ts",
|
|
"lib/og-card.tsx",
|
|
"lib/portfolio-data.server.ts",
|
|
])("%s só pode ser importado no servidor", (file) => {
|
|
const source = readFileSync(join(root, file), "utf8");
|
|
expect(source).toMatch(/^import "server-only";$/m);
|
|
});
|
|
|
|
it("declara server-only como dependência", () => {
|
|
const manifest = JSON.parse(
|
|
readFileSync(join(root, "package.json"), "utf8"),
|
|
) as { dependencies: Record<string, string> };
|
|
expect(manifest.dependencies["server-only"]).toBeDefined();
|
|
});
|
|
|
|
it("não deixa nenhum componente de cliente importar um módulo só de servidor", () => {
|
|
const serverOnly =
|
|
/from "(?:@\/lib\/og-card|@\/lib\/portfolio-data\.server|(?:\.{1,2}\/)+(?:[\w-]+\/)*case-media)"/;
|
|
const clientFiles = [
|
|
"app/cases/_components/CasePlayer.tsx",
|
|
"app/curriculo/CvDownloadLink.tsx",
|
|
];
|
|
for (const file of clientFiles) {
|
|
const source = readFileSync(join(root, file), "utf8");
|
|
expect(source).toMatch(/^"use client";/);
|
|
expect(source).not.toMatch(serverOnly);
|
|
}
|
|
});
|
|
});
|