import { describe, it, expect } from "vitest"; import { encodeOgPayload, repoCard, issueCard, pullCard, profileCard, stringCard, commitCard, fileCard, tagCard, pipelineCard } from "#lib/seo/og.ts"; const decode = (url: string) => JSON.parse( Buffer.from(new URL(url).searchParams.get("payload")!, "base64url").toString("utf-8") ); describe("og card URL generation", () => { it("generates repository OG card URL with clean payload", () => { const url = repoCard( { name: "core", ownerHandle: "tangled.org", ownerDid: "did:plc:123" }, { stars: 42, pulls: 5, issues: 12 }, "https://ogre.tangled.network", [{ color: "#3178c6", percentage: 100 }], "https://next.tangled.org" ); expect(url).toContain("https://ogre.tangled.network/card?payload="); const payloadParam = new URL(url).searchParams.get("payload")!; const decoded = JSON.parse(Buffer.from(payloadParam, "base64url").toString("utf-8")); expect(decoded.avatarUrl).toBe( "https://next.tangled.org/avatar/did%3Aplc%3A123?size=256&format=jpeg" ); expect(decoded.languages).toEqual([{ color: "#3178c6", percentage: 100 }]); expect(decoded.stars).toBe(42); }); it("generates issue OG card URL", () => { const url = issueCard( { name: "core", ownerHandle: "tangled.org" }, { title: "fix critical bug", issueNumber: "3lbqxyz", state: "open", createdAt: "2026-03-01T00:00:00Z", author: { handle: "alice.tangled.org", did: "did:plc:alice" } }, "https://ogre.tangled.network", "https://next.tangled.org" ); expect(url).toContain("https://ogre.tangled.network/card?payload="); const payloadParam = new URL(url).searchParams.get("payload")!; const decoded = JSON.parse(Buffer.from(payloadParam, "base64url").toString("utf-8")); expect(decoded.authorAvatarUrl).toBe( "https://next.tangled.org/avatar/did%3Aplc%3Aalice?size=256&format=jpeg" ); }); it("generates pull request OG card URL", () => { const url = pullCard( { name: "core", ownerHandle: "tangled.org" }, { title: "add new feature", rkey: "3lbqabc", state: "open", createdAt: "2026-03-01T00:00:00Z", author: { handle: "bob.tangled.org", did: "did:plc:bob" }, versions: [{}] }, 3, undefined, "https://ogre.tangled.network", "https://next.tangled.org" ); expect(url).toContain("https://ogre.tangled.network/card?payload="); const payloadParam = new URL(url).searchParams.get("payload")!; const decoded = JSON.parse(Buffer.from(payloadParam, "base64url").toString("utf-8")); expect(decoded.authorAvatarUrl).toBe( "https://next.tangled.org/avatar/did%3Aplc%3Abob?size=256&format=jpeg" ); }); it("sends the rounds and the latest round's diff stats on a pull card", () => { const url = pullCard( { name: "core", ownerHandle: "tangled.org" }, { rkey: "87", createdAt: "2026-03-01T00:00:00Z", versions: [{}, {}, {}] }, 0, { insertions: 860, deletions: 7, files_changed: 11 }, "https://ogre.tangled.network" ); const decoded = decode(url); expect(decoded.rounds).toBe(3); expect(decoded.filesChanged).toBe(11); expect(decoded.additions).toBe(860); expect(decoded.deletions).toBe(7); }); it("leaves the stats and rounds off a pull card that has neither", () => { const decoded = decode( pullCard( { name: "core", ownerHandle: "tangled.org" }, { rkey: "87", createdAt: "2026-03-01T00:00:00Z", versions: [] }, 0, undefined, "https://ogre.tangled.network" ) ); expect(decoded).not.toHaveProperty("rounds"); expect(decoded).not.toHaveProperty("filesChanged"); expect(decoded).not.toHaveProperty("additions"); expect(decoded).not.toHaveProperty("deletions"); }); it("omits empty and null properties from encoded payload", () => { const payload = encodeOgPayload({ type: "repository", repoName: "test", ownerHandle: "alice" }); const decoded = JSON.parse(Buffer.from(payload, "base64url").toString("utf-8")); expect(decoded).toEqual({ type: "repository", repoName: "test", ownerHandle: "alice" }); expect(decoded.stars).toBeUndefined(); expect(decoded.languages).toBeUndefined(); }); it("generates profile OG card URL with six months of activity, oldest first", () => { const month = (monthsAgo: number, commits: number) => ({ monthsAgo, commits, commitRepos: [], repos: [], issues: [], pulls: [] }); const url = profileCard( { did: "did:plc:alice", handle: "alice.tangled.org" }, { description: " hello " }, { followers: 3, repos: 2, stars: 1 }, { months: [month(0, 7), month(4, 2)], truncated: false }, "https://ogre.tangled.network", "https://next.tangled.org" ); const decoded = decode(url); expect(decoded.type).toBe("profile"); expect(decoded.description).toBe("hello"); expect(decoded.activity).toEqual([0, 2, 0, 0, 0, 7]); expect(decoded.avatarUrl).toBe( "https://next.tangled.org/avatar/did%3Aplc%3Aalice?size=256&format=jpeg" ); }); it("generates string OG card URL with a trimmed preview", () => { const url = stringCard( { ownerHandle: "alice.tangled.org", filename: "mirror.sh", contents: Array.from({ length: 20 }, (_, i) => `\tline ${i}`).join("\n"), lineCount: 20, createdAt: "2026-03-01T00:00:00Z" }, "https://ogre.tangled.network" ); const decoded = decode(url); expect(decoded.preview).toHaveLength(9); expect(decoded.preview[0]).toBe(" line 0"); expect(decoded.lineCount).toBe(20); }); it("generates commit OG card URL, falling back to the git author name", () => { const url = commitCard( { name: "core", ownerHandle: "tangled.org" }, { subject: "fix things", shortHash: "4fd9171f", authorName: "Alice", authorWhen: "2026-03-01T00:00:00Z" }, { insertions: 10, deletions: 2, files_changed: 1 }, "https://ogre.tangled.network" ); const decoded = decode(url); expect(decoded.authorHandle).toBe("Alice"); expect(decoded.additions).toBe(10); expect(decoded.filesChanged).toBe(1); }); it("generates file OG card URL without null blob fields", () => { const url = fileCard( { name: "core", ownerHandle: "tangled.org" }, { path: "appview/pulls/sidebar.go", ref: "master", lines: null, sizeLabel: null }, "https://ogre.tangled.network" ); const decoded = decode(url); expect(decoded.path).toBe("appview/pulls/sidebar.go"); expect(decoded.lineCount).toBeUndefined(); expect(decoded.sizeLabel).toBeUndefined(); }); it("generates tag OG card URL", () => { const url = tagCard( { name: "core", ownerHandle: "tangled.org" }, { name: "v1.9.0", message: "release\n", taggerName: "Alice", when: "2026-03-01T00:00:00Z" }, "https://ogre.tangled.network" ); const decoded = decode(url); expect(decoded.name).toBe("v1.9.0"); expect(decoded.message).toBe("release"); expect(decoded.createdAt).toBe("2026-03-01T00:00:00Z"); }); it("generates pipeline OG card URL with the trigger mapped to the card shape", () => { const url = pipelineCard( { name: "core", ownerHandle: "tangled.org" }, { sha: "4fd9171f00000000000000000000000000000000", createdAt: "2026-03-01T00:00:00Z", trigger: { kind: "pull_request", targetRef: "master", sourceLabel: "feature" } }, { name: "build", status: "failed", duration: 41000 }, "https://ogre.tangled.network" ); const decoded = decode(url); expect(decoded.trigger).toEqual({ kind: "pull_request", ref: "master", source: "feature" }); expect(decoded.shortHash).toBe("4fd9171f"); expect(decoded.durationMs).toBe(41000); }); it("uses custom baseUrl when provided", () => { const url = repoCard( { name: "core", ownerHandle: "tangled.org" }, null, "https://ogre-dev.tangled.network" ); expect(url).toContain("https://ogre-dev.tangled.network/card?payload="); }); });