返回 CodeWhale
site-schema.test.ts
根目录 / web / lib / site-schema.test.ts
1 import { readFileSync } from "node:fs";
2 import { describe, expect, it } from "vitest";
3 import { DISCORD_URL, REPO_URL } from "./i18n/links";
4 import { IDENTITY_PHRASE, SITE_NAME, SITE_URL } from "./page-meta";
5 import {
6 ORGANIZATION_ID,
7 ORGANIZATION_LOGO_URL,
8 WEBSITE_ID,
9 buildSiteJsonLd,
10 } from "./site-schema";
11
12 describe("Organization and WebSite structured data", () => {
13 it("emits a stable Organization @id with logo and sameAs", () => {
14 const schema = buildSiteJsonLd("en");
15 const organization = schema["@graph"].find((node) => node["@type"] === "Organization");
16 const website = schema["@graph"].find((node) => node["@type"] === "WebSite");
17
18 expect(organization).toEqual({
19 "@type": "Organization",
20 "@id": ORGANIZATION_ID,
21 name: SITE_NAME,
22 url: SITE_URL,
23 logo: { "@type": "ImageObject", url: ORGANIZATION_LOGO_URL },
24 sameAs: [REPO_URL, DISCORD_URL],
25 });
26 expect(organization?.["@id"]).toBe("https://codewhale.net/#organization");
27 expect(website).toMatchObject({
28 "@type": "WebSite",
29 "@id": WEBSITE_ID,
30 name: SITE_NAME,
31 url: SITE_URL,
32 description: IDENTITY_PHRASE,
33 inLanguage: "en",
34 publisher: { "@id": ORGANIZATION_ID },
35 });
36 });
37
38 it("sets WebSite inLanguage from the routed locale", () => {
39 expect(buildSiteJsonLd("zh")["@graph"].find((node) => node["@type"] === "WebSite")?.inLanguage).toBe(
40 "zh",
41 );
42 expect(buildSiteJsonLd("ja")["@graph"].find((node) => node["@type"] === "WebSite")?.inLanguage).toBe(
43 "ja",
44 );
45 });
46
47 it("embeds the graph from the locale layout, not a second homepage-only tag", () => {
48 const layout = readFileSync(new URL("../app/[locale]/layout.tsx", import.meta.url), "utf8");
49 expect(layout).toContain("buildSiteJsonLd(locale)");
50 expect(layout).toContain("type=\"application/ld+json\"");
51 expect(layout).toContain("serializeJsonLd(siteJsonLd)");
52 });
53 });
54
54 lines TYPESCRIPT