test.web/presentation/renderers/schema.renderer.test.ts

test.web/presentation/renderers/schema.renderer.test.ts is a file in Codebase Testing. 320 lines of code and 0 definitions.

import "@banes-lab/web/presentation/records/grammar.record.ts";
import { AUTHOR_GITHUB, AUTHOR_PROFILE, SITE_URL, pagePath, tabLink } from "@banes-lab/web/core/assets/link.assets.ts";
import {
    AUTHOR_HANDLE,
    COMPANY_CITY,
    COMPANY_COUNTRY,
    COMPANY_FOUNDED,
    COMPANY_NAME,
    COMPANY_NUMBER,
    COMPANY_OWNER,
    COMPANY_POSTAL_CODE,
    COMPANY_STREET,
} from "@banes-lab/web/configuration/strings/company.strings.ts";
import { GRAMMAR_PAGE, HOME_PAGE } from "@banes-lab/web/core/ids/page.ids.ts";
import { describe, expect, it } from "vitest";
import {
    recordSchemaOf,
    schemaOf,
    sectionSchemaOf,
    sourceSchemaOf,
} from "@banes-lab/web/presentation/renderers/schema.renderer.ts";
import { GRAMMAR_TABS } from "@banes-lab/web/core/generated/grammar.page.generated.ts";
import { instantOf } from "@banes-lab/web/core/factories/schema.factory.ts";
import { loadPage } from "@banes-lab/web/domain/registries/page.registry.ts";
import { sectionHead } from "@banes-lab/web/presentation/renderers/page.renderer.ts";

const GRAMMAR = await loadPage(GRAMMAR_PAGE);
const TITLE = "Grammar — Bane's Lab";
const DESCRIPTION = "The grammar.";
const CRUMBS_FOR_TAB = 3;
const DATES = { modified: "2026-10-07", published: "2026-09-30" };

const typesOf = function typesOf(graph: readonly Readonly<Record<string, unknown>>[]): string[] {
    return graph.map((entity) => String(entity["@type"]));
};

describe("sourceSchemaOf", () => {
    const subject = {
        alternates: { json: "/json/source/tree/a.ts", markdown: "/source/tree/a.ts.md" },
        description: "a.ts is a file in Site.",
        language: "typescript",
        license: "CC-BY-SA-4.0",
        name: "a.ts",
        path: "/anatomy/tree/file-a-ts",
        repository: "https://code.x.test/a.ts",
        tabPath: "/anatomy/tree",
        tabTitle: "Site",
        title: "Site · a.ts · Bane's Lab",
        trail: [
            { label: "Site", path: "/anatomy/tree" },
            { label: "core", path: "/anatomy/tree/folder-core" },
        ],
    };

    it("trails the breadcrumb through the tab and every folder above the page", () => {
        const page = sourceSchemaOf(subject)["@graph"].at(-1);
        const items: unknown = Reflect.get(Object(page?.["breadcrumb"]), "itemListElement");
        const names = Array.isArray(items) ? items.map((item: unknown) => Reflect.get(Object(item), "name")) : [];
        expect(names).toStrictEqual(["Home", "Site", "core", "a.ts"]);
    });

    it("names the page's source code with its language, repository, license and tree", () => {
        const page = sourceSchemaOf(subject)["@graph"].at(-1);
        expect(page?.["@type"]).toBe("WebPage");
        expect(page?.["url"]).toBe(SITE_URL + subject.path);
        expect(page?.["mainEntity"]).toStrictEqual({
            "@type": "SoftwareSourceCode",
            codeRepository: subject.repository,
            isPartOf: { "@id": SITE_URL + subject.tabPath },
            license: subject.license,
            name: subject.name,
            programmingLanguage: subject.language,
        });
    });

    it("leaves out what a folder or an unlicensed tree does not have", () => {
        const page = sourceSchemaOf({ ...subject, language: null, license: null, repository: null })["@graph"].at(-1);
        expect(page?.["mainEntity"]).toStrictEqual({
            "@type": "SoftwareSourceCode",
            isPartOf: { "@id": SITE_URL + subject.tabPath },
            name: subject.name,
        });
    });
});

describe("recordSchemaOf", () => {
    const subject = {
        aliases: [],
        alternates: { json: "/json/records/lexicon/cache", markdown: "/records/lexicon/cache.md" },
        code: "CACHE",
        collection: { label: "Lexicon", path: "/ontology/lexicon" },
        description: "A store that answers again without the work.",
        facts: [],
        kind: "term",
        layer: null,
        name: "Cache",
        path: "/records/lexicon/cache",
        placement: null,
        relations: [],
        section: null,
        summary: "A store that answers again without the work.",
        title: "Cache (CACHE) — Lexicon — Bane's Lab",
    };

    it("names the record as a defined term in its collection's term set, under a three-crumb trail", () => {
        const page = recordSchemaOf(subject)["@graph"].at(-1);
        expect(page?.["url"]).toBe(SITE_URL + subject.path);
        expect(page?.["mainEntity"]).toStrictEqual({
            "@type": "DefinedTerm",
            description: subject.summary,
            inDefinedTermSet: { "@type": "DefinedTermSet", name: "Lexicon", url: `${SITE_URL}/ontology/lexicon` },
            name: "Cache",
            termCode: "CACHE",
            url: SITE_URL + subject.path,
        });
        const crumbs = page?.["breadcrumb"];
        expect(JSON.stringify(crumbs)).toContain("Lexicon");
    });

    it("leaves out the code and summary a record does not have", () => {
        const page = recordSchemaOf({ ...subject, code: null, summary: null })["@graph"].at(-1);
        const entity = page?.["mainEntity"];
        expect(JSON.stringify(entity)).not.toContain("termCode");
        expect(JSON.stringify(entity)).not.toContain("description");
    });
});

const SECTION_SUBJECT = {
    alternates: { json: "/json/ontology/lexicon/core", markdown: "/ontology/lexicon/core.md" },
    description: "The 2 records of the Core section in Lexicon.",
    name: "Core",
    parts: [],
    path: "/ontology/lexicon/core",
    seed: {
        intro: null,
        kind: null,
        name: "Core",
        page: "ontology",
        part: 1,
        parts: 1,
        records: 2,
        rows: [0, 2] as const,
        section: "core",
        tab: "lexicon",
        tabPath: "/ontology/lexicon",
        tabTitle: "Lexicon",
    },
    title: "Core — Lexicon — Bane's Lab",
};

describe("sectionSchemaOf and sectionHead", () => {
    it("names a section page's rows as an item list under its tab, and indexes it under its own path", () => {
        const page = sectionSchemaOf(SECTION_SUBJECT)["@graph"].at(-1);
        expect(page?.["mainEntity"]).toStrictEqual({ "@type": "ItemList", name: "Core", numberOfItems: 2 });
        expect(JSON.stringify(page?.["breadcrumb"])).toContain("Lexicon");
        const head = sectionHead(SECTION_SUBJECT);
        expect([head.path, head.title, head.robots]).toStrictEqual([SECTION_SUBJECT.path, SECTION_SUBJECT.title, "index, follow"]);
    });
});

describe("schemaOf", () => {
    it("always carries the organization, the person, the site and the page, linked by id", () => {
        const graph = schemaOf({ description: DESCRIPTION, path: pagePath(HOME_PAGE), title: TITLE })["@graph"];
        expect(typesOf(graph)).toStrictEqual(["Organization", "Person", "WebSite", "WebPage"]);
        const [organization, person, , page] = graph;
        expect(organization?.["name"]).toBe(COMPANY_NAME);
        expect(organization?.["sameAs"]).toStrictEqual([AUTHOR_GITHUB, AUTHOR_PROFILE]);
        expect(organization?.["vatID"]).toBe(COMPANY_COUNTRY + COMPANY_NUMBER.split(".").join(""));
        expect(organization?.["foundingDate"]).toBe(COMPANY_FOUNDED);
        expect(organization?.["address"]).toStrictEqual({
            "@type": "PostalAddress",
            addressCountry: COMPANY_COUNTRY,
            addressLocality: COMPANY_CITY,
            postalCode: COMPANY_POSTAL_CODE,
            streetAddress: COMPANY_STREET,
        });
        expect(organization?.["iso6523Code"]).toBe(`0208:${COMPANY_NUMBER.split(".").join("")}`);
        expect(organization?.["numberOfEmployees"]).toStrictEqual({ "@type": "QuantitativeValue", value: 1 });
        expect([person?.["name"], person?.["alternateName"]]).toStrictEqual([COMPANY_OWNER, AUTHOR_HANDLE]);
        expect(typeof person?.["description"]).toBe("string");
        expect(page?.["url"]).toBe(SITE_URL + pagePath(HOME_PAGE));
        expect(page?.["breadcrumb"]).toBeUndefined();
    });

    it("adds a breadcrumb trail and the page's own entities for a registered page and its tab", () => {
        const grammar = GRAMMAR;
        const [, second] = GRAMMAR_TABS;
        if (grammar === undefined || second === undefined) {
            throw new Error(GRAMMAR_PAGE);
        }
        const path = tabLink(GRAMMAR_PAGE, second.id);
        const graph = schemaOf({ definition: grammar, description: DESCRIPTION, path, tab: second, title: TITLE })[
            "@graph"
        ];
        expect(typesOf(graph)).toContain("CreativeWork");
        const page = graph.find((entity) => entity["@type"] === "WebPage");
        const trail: unknown = page?.["breadcrumb"];
        expect(typeof trail === "object" && trail !== null && "itemListElement" in trail).toBe(true);
        const items: unknown = typeof trail === "object" && trail !== null ? Reflect.get(trail, "itemListElement") : [];
        expect(Array.isArray(items) ? items.length : 0).toBe(CRUMBS_FOR_TAB);
    });

    it("lists the tab's sections as parts of the page, each at its own fragment", () => {
        const grammar = GRAMMAR;
        const [, second] = GRAMMAR_TABS;
        if (grammar === undefined || second === undefined) {
            throw new Error(GRAMMAR_PAGE);
        }
        const path = tabLink(GRAMMAR_PAGE, second.id);
        const graph = schemaOf({ definition: grammar, description: DESCRIPTION, path, tab: second, title: TITLE })[
            "@graph"
        ];
        const parts: unknown = graph.find((entity) => entity["@type"] === "WebPage")?.["hasPart"];
        expect(parts).toStrictEqual(
            second.sections.map((section) => ({
                "@id": `${SITE_URL}${path}#${section.id}`,
                "@type": "WebPageElement",
                encoding: [
                    {
                        "@type": "MediaObject",
                        contentUrl: `${SITE_URL}/json/${GRAMMAR_PAGE}/${second.id}/${section.id}`,
                        encodingFormat: "application/json",
                    },
                    {
                        "@type": "MediaObject",
                        contentUrl: `${SITE_URL}${path}/${section.id}.md`,
                        encodingFormat: "text/markdown",
                    },
                ],
                name: section.title,
                url: `${SITE_URL}${path}#${section.id}`,
            })),
        );
    });

    it("dates the page and names a teaching tab as a dated tech article under its tab and page title", () => {
        const grammar = GRAMMAR;
        const [, second] = GRAMMAR_TABS;
        if (grammar === undefined || second === undefined) {
            throw new Error(GRAMMAR_PAGE);
        }
        const banner = { alt: "a", source: "/static/card.gif", stills: ["/static/wide.png", "/static/square.png"] };
        const path = tabLink(GRAMMAR_PAGE, second.id);
        const graph = schemaOf({
            banner,
            dates: DATES,
            definition: grammar,
            description: DESCRIPTION,
            path,
            tab: second,
            title: TITLE,
        })["@graph"];
        const page = graph.find((entity) => entity["@type"] === "WebPage");
        expect([page?.["datePublished"], page?.["dateModified"]]).toStrictEqual([
            instantOf(DATES.published),
            instantOf(DATES.modified),
        ]);
        expect(page?.["mainEntity"]).toStrictEqual({
            "@type": "TechArticle",
            author: { "@id": `${SITE_URL}/#person` },
            dateModified: instantOf(DATES.modified),
            datePublished: instantOf(DATES.published),
            headline: `${second.label} — ${grammar.title}`,
            image: [`${SITE_URL}/static/wide.png`, `${SITE_URL}/static/square.png`],
            inLanguage: "en",
            publisher: { "@id": `${SITE_URL}/#organization` },
        });
    });

    it("names no article on a page that does not declare one or has no banner, and no date it was not given", () => {
        const grammar = GRAMMAR;
        if (grammar === undefined) {
            throw new Error(GRAMMAR_PAGE);
        }
        const path = pagePath(GRAMMAR_PAGE);
        const banner = { alt: "a", source: "/static/card.gif", stills: [] };
        const plain = schemaOf({ banner, definition: { ...grammar, article: false }, description: DESCRIPTION, path, title: TITLE });
        const bare = schemaOf({ definition: grammar, description: DESCRIPTION, path, title: TITLE });
        for (const graph of [plain["@graph"], bare["@graph"]]) {
            const page = graph.find((entity) => entity["@type"] === "WebPage");
            expect([page?.["mainEntity"], page?.["datePublished"], page?.["dateModified"]]).toStrictEqual([
                undefined,
                undefined,
                undefined,
            ]);
        }
    });

    it("names a profile page as a ProfilePage whose main entity is the site's person", () => {
        const grammar = GRAMMAR;
        if (grammar === undefined) {
            throw new Error(GRAMMAR_PAGE);
        }
        const definition = { ...grammar, article: false, profile: true };
        const graph = schemaOf({ definition, description: DESCRIPTION, path: pagePath(GRAMMAR_PAGE), title: TITLE })[
            "@graph"
        ];
        const page = graph.find((entity) => entity["url"] === SITE_URL + pagePath(GRAMMAR_PAGE));
        expect([page?.["@type"], page?.["mainEntity"]]).toStrictEqual(["ProfilePage", { "@id": `${SITE_URL}/#person` }]);
        const person = graph.find((entity) => entity["@type"] === "Person");
        expect(person?.["url"]).toBe(`${SITE_URL}/about`);
    });

    it("dates a page's dataset with the page's modified day, and leaves its other entities as they are", () => {
        const grammar = GRAMMAR;
        if (grammar === undefined) {
            throw new Error(GRAMMAR_PAGE);
        }
        const definition = { ...grammar, entities: [{ "@type": "Dataset", name: "d" }, { "@type": "CreativeWork" }] };
        const path = pagePath(GRAMMAR_PAGE);
        const graph = schemaOf({ dates: DATES, definition, description: DESCRIPTION, path, title: TITLE })["@graph"];
        expect(graph.slice(-2)).toStrictEqual([
            { "@type": "Dataset", dateModified: instantOf(DATES.modified), name: "d" },
            { "@type": "CreativeWork" },
        ]);
        const undated = schemaOf({ definition, description: DESCRIPTION, path, title: TITLE })["@graph"];
        expect(undated.at(-2)).toStrictEqual({ "@type": "Dataset", name: "d" });
    });

    it("names the page's JSON payload, its Markdown version and its catalog index", () => {
        const grammar = GRAMMAR;
        if (grammar === undefined) {
            throw new Error(GRAMMAR_PAGE);
        }
        const path = pagePath(GRAMMAR_PAGE);
        const graph = schemaOf({ definition: grammar, description: DESCRIPTION, path, title: TITLE })["@graph"];
        const encoding: unknown = graph.find((entity) => entity["@type"] === "WebPage")?.["encoding"];
        const urls: unknown[] = Array.isArray(encoding)
            ? encoding.map((item: unknown) =>
                  typeof item === "object" && item !== null && "contentUrl" in item ? item.contentUrl : undefined,
              )
            : [];
        expect(urls).toStrictEqual([
            `${SITE_URL}/json/${GRAMMAR_PAGE}`,
            `${SITE_URL}${path}.md`,
            `${SITE_URL}/json/api/pages/${GRAMMAR_PAGE}`,
        ]);
    });
});