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=");
});
});