Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Merge commit authors and hovercards: commits show their accounts, every name opens a card (repos 0016) | 1 | import assert from "node:assert/strict"; |
| 2 | import { test } from "node:test"; | |
| 3 | ||
| 4 | import type { Contributors, Profile, ProfileWorkspace, RepoPath, Result, Viewer } from "@g1t/contracts"; | |
| 5 | ||
| 6 | import { type CardSources, buildCard, cardHref, committedLabel, committedWithin, parseRepo } from "./hovercard.ts"; | |
| 7 | ||
| 8 | const NOW = Date.parse("2026-10-08T12:00:00Z"); | |
| 9 | const DAY = 86_400_000; | |
| 10 | ||
| 11 | const ada: Profile = { | |
| 12 | username: "ada", | |
| 13 | name: "Ada Lovelace", | |
| 14 | bio: "Engines.", | |
| 15 | location: "London", | |
| 16 | website: "https://ada.example", | |
| 17 | pronouns: "she/her", | |
| Merge leftovers: plan activity filtered in the query, pushes counted by account, ghost during the deletion window, profile time zones (identity 0039) | 18 | timezone: "Europe/London", |
| Merge commit authors and hovercards: commits show their accounts, every name opens a card (repos 0016) | 19 | avatar: "cafe", |
| 20 | createdAt: "2026-01-01T00:00:00Z", | |
| 21 | }; | |
| 22 | ||
| 23 | const me: Viewer = { id: "usr_me", username: "me", kind: "user", verified: true } as Viewer; | |
| 24 | ||
| 25 | /** | |
| 26 | * Stand-ins for identity and repos that behave as they do: workspaces are | |
| 27 | * shown only when the viewer shares them, or when ada has a public project | |
| 28 | * there; the repository answers only viewers who may read it. | |
| 29 | */ | |
| 30 | function sources(over: Partial<CardSources> = {}): CardSources & { asked: { viewer: Viewer; publicIn: string[] }[] } { | |
| 31 | const asked: { viewer: Viewer; publicIn: string[] }[] = []; | |
| 32 | const memberships: ProfileWorkspace[] = [ | |
| 33 | { slug: "acme", name: "Acme", avatar: null }, | |
| 34 | { slug: "secret-lab", name: "Secret Lab", avatar: null }, | |
| 35 | ]; | |
| 36 | return { | |
| 37 | asked, | |
| 38 | profile: async (username) => (username === "ada" ? ada : null), | |
| 39 | accountId: async (username) => (username === "ada" ? "usr_ada" : null), | |
| 40 | publicNamespaces: async () => ["acme"], | |
| 41 | profileWorkspaces: async (_username, viewer, publicIn) => { | |
| 42 | asked.push({ viewer, publicIn }); | |
| 43 | // secret-lab is private: only someone who belongs to it sees it. | |
| 44 | return memberships.filter((one) => publicIn.includes(one.slug) || (viewer?.username === "insider" && one.slug === "secret-lab")); | |
| 45 | }, | |
| 46 | contributors: async (path: RepoPath, viewer: Viewer): Promise<Result<Contributors>> => { | |
| 47 | if (path.name === "private" && viewer?.username !== "insider") { | |
| 48 | return { ok: false, error: { code: "not_found", message: "Repository not found." } } as Result<Contributors>; | |
| 49 | } | |
| 50 | return { | |
| 51 | ok: true, | |
| 52 | value: { | |
| 53 | head: "h", | |
| 54 | commit: "h", | |
| 55 | computedAt: null, | |
| 56 | pending: false, | |
| 57 | partial: false, | |
| 58 | total: 1, | |
| 59 | commits: 3, | |
| 60 | weeks: [], | |
| 61 | contributors: [{ kind: "user", name: "ada", username: "ada", avatar: "cafe", commits: 3, firstAt: "2026-09-01T00:00:00Z", lastAt: new Date(NOW - 3 * DAY).toISOString(), weeks: [] }], | |
| 62 | }, | |
| 63 | }; | |
| 64 | }, | |
| 65 | ...over, | |
| 66 | }; | |
| 67 | } | |
| 68 | ||
| 69 | test("the card is the public profile, signed out too", async () => { | |
| 70 | const card = await buildCard("Ada", null, null, sources(), NOW); | |
| 71 | assert.ok(card && card.kind === "user"); | |
| 72 | assert.equal(card.username, "ada"); | |
| 73 | assert.equal(card.name, "Ada Lovelace"); | |
| 74 | assert.equal(card.pronouns, "she/her"); | |
| 75 | assert.equal(card.bio, "Engines."); | |
| 76 | assert.equal(card.location, "London"); | |
| 77 | assert.equal(card.avatar, "cafe"); | |
| 78 | assert.equal(card.committed, null, "no repository, nothing about commits"); | |
| 79 | // Never an address. | |
| 80 | assert.ok(!JSON.stringify(card).includes("@")); | |
| 81 | }); | |
| 82 | ||
| 83 | test("a private workspace is hidden from someone outside it", async () => { | |
| 84 | const outside = sources(); | |
| 85 | const outsider = await buildCard("ada", me, null, outside, NOW); | |
| 86 | assert.deepEqual(outsider?.kind === "user" && outsider.workspaces.map((one) => one.slug), ["acme"]); | |
| 87 | // The viewer is passed through, for identity to decide. | |
| 88 | assert.equal(outside.asked[0]!.viewer, me); | |
| 89 | assert.deepEqual(outside.asked[0]!.publicIn, ["acme"]); | |
| 90 | const insider = await buildCard("ada", { ...me, username: "insider" } as Viewer, null, sources(), NOW); | |
| 91 | assert.deepEqual(insider?.kind === "user" && insider.workspaces.map((one) => one.slug), ["acme", "secret-lab"]); | |
| 92 | }); | |
| 93 | ||
| 94 | test("commits to a repository show only to those who may read it", async () => { | |
| 95 | const open = await buildCard("ada", null, { namespace: "acme", name: "web" }, sources(), NOW); | |
| 96 | assert.equal(open?.kind === "user" && open.committed, "week"); | |
| 97 | const hidden = await buildCard("ada", me, { namespace: "acme", name: "private" }, sources(), NOW); | |
| 98 | assert.equal(hidden?.kind === "user" && hidden.committed, null); | |
| 99 | }); | |
| 100 | ||
| Merge leftovers: plan activity filtered in the query, pushes counted by account, ghost during the deletion window, profile time zones (identity 0039) | 101 | test("the card carries the time zone a profile gives, and none when it gives none", async () => { |
| 102 | const card = await buildCard("ada", me, null, sources(), NOW); | |
| 103 | assert.equal(card?.kind === "user" && card.timezone, "Europe/London"); | |
| 104 | const without = await buildCard("ada", me, null, sources({ profile: async () => ({ ...ada, timezone: null }) }), NOW); | |
| 105 | assert.equal(without?.kind === "user" && without.timezone, null); | |
| 106 | }); | |
| 107 | ||
| Merge commit authors and hovercards: commits show their accounts, every name opens a card (repos 0016) | 108 | test("a failing service leaves its part out, not the card", async () => { |
| 109 | const card = await buildCard( | |
| 110 | "ada", | |
| 111 | me, | |
| 112 | { namespace: "acme", name: "web" }, | |
| 113 | sources({ profileWorkspaces: async () => Promise.reject(new Error("down")), contributors: async () => Promise.reject(new Error("down")) }), | |
| 114 | NOW, | |
| 115 | ); | |
| 116 | assert.ok(card && card.kind === "user"); | |
| 117 | assert.deepEqual(card.workspaces, []); | |
| 118 | assert.equal(card.committed, null); | |
| 119 | }); | |
| 120 | ||
| 121 | test("g1t has its own card; ghost and strangers have none", async () => { | |
| 122 | assert.deepEqual(await buildCard("g1t", null, null, sources(), NOW), { kind: "g1t", username: "g1t" }); | |
| 123 | assert.equal(await buildCard("ghost", me, null, sources(), NOW), null); | |
| 124 | assert.equal(await buildCard("nobody", me, null, sources(), NOW), null); | |
| 125 | assert.equal(await buildCard("../etc", me, null, sources(), NOW), null); | |
| 126 | }); | |
| 127 | ||
| 128 | test("workspaces past three are counted", async () => { | |
| 129 | const many = Array.from({ length: 5 }, (_, index) => ({ slug: `w${index}`, name: `W${index}`, avatar: null })); | |
| 130 | const card = await buildCard("ada", me, null, sources({ profileWorkspaces: async () => many }), NOW); | |
| 131 | assert.ok(card && card.kind === "user"); | |
| 132 | assert.equal(card.workspaces.length, 3); | |
| 133 | assert.equal(card.more_workspaces, 2); | |
| 134 | }); | |
| 135 | ||
| 136 | test("how recently, in the words the card uses", () => { | |
| 137 | assert.equal(committedWithin(new Date(NOW - 2 * 3_600_000).toISOString(), NOW), "day"); | |
| 138 | assert.equal(committedWithin(new Date(NOW - 6 * DAY).toISOString(), NOW), "week"); | |
| 139 | assert.equal(committedWithin(new Date(NOW - 20 * DAY).toISOString(), NOW), "month"); | |
| 140 | assert.equal(committedWithin(new Date(NOW - 60 * DAY).toISOString(), NOW), null); | |
| 141 | assert.equal(committedWithin(null, NOW), null); | |
| 142 | assert.equal(committedLabel("week"), "Committed to this repository in the past week"); | |
| 143 | }); | |
| 144 | ||
| 145 | test("the card's address and its repository", () => { | |
| 146 | assert.equal(cardHref("Ada", "acme/web"), "/-/hovercard/user/ada?repo=acme%2Fweb"); | |
| 147 | assert.equal(cardHref("ada", null), "/-/hovercard/user/ada"); | |
| 148 | assert.deepEqual(parseRepo("acme/web"), { namespace: "acme", name: "web" }); | |
| 149 | assert.equal(parseRepo("acme"), null); | |
| 150 | assert.equal(parseRepo("../x/y"), null); | |
| 151 | }); |
This file's history is long; its oldest lines are credited to the oldest commit read.