feat(cases): mídia no topo, títulos de busca curtos e CreativeWork
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:.
This commit is contained in:
1 parent
c9a0b80656
commit
e80f73d075
52 files changed
+2593
-439
No files matched your search
+74
-8
@@ -1,16 +1,82 @@
|
||||
import { statSync } from "node:fs";
|
||||
import { render } from "@testing-library/react";
|
||||
import { OgCard, readProjectOgBackground } from "./og-card";
|
||||
import { OG_IMAGE_MAX_BYTES, OgCard, readProjectOgImage } from "./og-card";
|
||||
import { PROJECT_VIDEO_IDS } from "./project-showcase";
|
||||
|
||||
describe("readProjectOgBackground", () => {
|
||||
it("returns the recorded cover of a showcase project as a JPEG data URI", () => {
|
||||
const uri = readProjectOgBackground("nutriscan");
|
||||
expect(uri).toMatch(/^data:image\/jpeg;base64,/);
|
||||
expect((uri ?? "").length).toBeGreaterThan(5_000);
|
||||
jest.mock("node:fs", () => {
|
||||
const actual = jest.requireActual<typeof import("node:fs")>("node:fs");
|
||||
return { ...actual, statSync: jest.fn(actual.statSync) };
|
||||
});
|
||||
|
||||
const mockedStatSync = jest.mocked(statSync);
|
||||
const actualStatSync =
|
||||
jest.requireActual<typeof import("node:fs")>("node:fs").statSync;
|
||||
|
||||
afterEach(() => {
|
||||
mockedStatSync.mockImplementation(actualStatSync);
|
||||
});
|
||||
|
||||
/** Largura e altura de um JPEG, lidas do primeiro marcador de quadro (SOF). */
|
||||
function jpegSize(image: Buffer) {
|
||||
let offset = 2;
|
||||
while (offset < image.length) {
|
||||
const marker = image[offset + 1];
|
||||
const length = image.readUInt16BE(offset + 2);
|
||||
if (
|
||||
marker >= 0xc0 &&
|
||||
marker <= 0xcf &&
|
||||
marker !== 0xc4 &&
|
||||
marker !== 0xc8
|
||||
) {
|
||||
return {
|
||||
height: image.readUInt16BE(offset + 5),
|
||||
width: image.readUInt16BE(offset + 7),
|
||||
};
|
||||
}
|
||||
offset += 2 + length;
|
||||
}
|
||||
throw new Error("JPEG sem marcador de quadro");
|
||||
}
|
||||
|
||||
describe("readProjectOgImage", () => {
|
||||
it("returns the recorded cover of a showcase project as it is, in JPEG", () => {
|
||||
const image = readProjectOgImage("nutriscan");
|
||||
expect(image?.subarray(0, 2).toString("hex")).toBe("ffd8");
|
||||
expect(image?.length).toBeGreaterThan(5_000);
|
||||
});
|
||||
|
||||
it("serves every recorded cover below 150 KB and in the 1200x630 card size", () => {
|
||||
expect(OG_IMAGE_MAX_BYTES).toBe(150_000);
|
||||
for (const id of PROJECT_VIDEO_IDS) {
|
||||
const image = readProjectOgImage(id);
|
||||
expect(image).toBeDefined();
|
||||
expect(image?.length ?? Infinity).toBeLessThan(150_000);
|
||||
expect(jpegSize(image as Buffer)).toEqual({ width: 1200, height: 630 });
|
||||
}
|
||||
});
|
||||
|
||||
it("returns undefined for a cover that weighs the limit or more, so the plain card is used", () => {
|
||||
mockedStatSync.mockReturnValue({
|
||||
size: OG_IMAGE_MAX_BYTES,
|
||||
} as ReturnType<typeof statSync>);
|
||||
expect(readProjectOgImage("nutriscan")).toBeUndefined();
|
||||
|
||||
mockedStatSync.mockReturnValue({
|
||||
size: OG_IMAGE_MAX_BYTES - 1,
|
||||
} as ReturnType<typeof statSync>);
|
||||
expect(readProjectOgImage("nutriscan")).toBeDefined();
|
||||
});
|
||||
|
||||
it("returns undefined for projects without a recorded cover", () => {
|
||||
expect(readProjectOgBackground("twins-lab")).toBeUndefined();
|
||||
expect(readProjectOgBackground("../../etc/passwd")).toBeUndefined();
|
||||
expect(readProjectOgImage("twins-lab")).toBeUndefined();
|
||||
expect(readProjectOgImage("../../etc/passwd")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns undefined when the file is missing on disk", () => {
|
||||
mockedStatSync.mockImplementation(() => {
|
||||
throw new Error("ENOENT");
|
||||
});
|
||||
expect(readProjectOgImage("nutriscan")).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user