pr_01m47d15m3e54sn21z27rpy5n9/apps/web/app/lib/repo-lifecycle.test.ts

95 lines3,853 bytesCodeBlame

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.

Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import {
5 confirmsName,
6 daysUntil,
7 filterCounts,
8 filterRepos,
9 longDate,
10 parseFilter,
11 renamedBranchPath,
12 summariseBulk,
13 tidyName,
14} from "./repo-lifecycle.ts";
15
16test("the typed name confirms only the full name, in any case", () => {
17 assert.equal(confirmsName("acme/web", "acme/web"), true);
18 assert.equal(confirmsName(" ACME/Web ", "acme/web"), true);
19 assert.equal(confirmsName("web", "acme/web"), false);
20 assert.equal(confirmsName("", "acme/web"), false);
21 assert.equal(confirmsName(null, "acme/web"), false);
22});
23
24const repos = [
25 { name: "web", description: "The site", topics: ["astro"], isPrivate: false, archivedAt: null },
26 { name: "api", description: "Rust service", topics: ["rust", "cli"], isPrivate: true, archivedAt: null },
27 { name: "old-site", description: null, topics: [], isPrivate: false, archivedAt: "2026-01-01T00:00:00Z" },
28];
29
30test("filters by visibility and archived", () => {
31 assert.deepEqual(filterRepos(repos, "all", "").map((r) => r.name), ["web", "api", "old-site"]);
32 assert.deepEqual(filterRepos(repos, "public", "").map((r) => r.name), ["web", "old-site"]);
33 assert.deepEqual(filterRepos(repos, "private", "").map((r) => r.name), ["api"]);
34 assert.deepEqual(filterRepos(repos, "archived", "").map((r) => r.name), ["old-site"]);
35});
36
37test("search matches every word in name, description or topics", () => {
38 assert.deepEqual(filterRepos(repos, "all", "rust").map((r) => r.name), ["api"]);
39 assert.deepEqual(filterRepos(repos, "all", "SITE").map((r) => r.name), ["web", "old-site"]);
40 assert.deepEqual(filterRepos(repos, "all", "site astro").map((r) => r.name), ["web"]);
41 assert.deepEqual(filterRepos(repos, "private", "site").map((r) => r.name), []);
42});
43
44test("counts each filter", () => {
45 assert.deepEqual(filterCounts(repos), { all: 3, public: 2, private: 1, archived: 1 });
46});
47
48test("an unknown filter is all", () => {
49 assert.equal(parseFilter("archived"), "archived");
50 assert.equal(parseFilter("nope"), "all");
51 assert.equal(parseFilter(null), "all");
52});
53
54test("a bulk action is summed up, with each failure and why", () => {
55 assert.deepEqual(
56 summariseBulk(
57 [
58 { name: "web", ok: true },
59 { name: "api", ok: false, error: "Only owners can archive a repository." },
60 { name: "cli", ok: true },
61 ],
62 "archived",
63 ),
64 {
65 message: "2 repositories archived. 1 repository could not be.",
66 failures: ["api: Only owners can archive a repository."],
67 },
68 );
69 assert.equal(summariseBulk([{ name: "web", ok: true }], "unarchived").message, "1 repository unarchived.");
70 assert.equal(summariseBulk([], "archived").message, "Nothing was selected.");
71});
72
73test("a renamed branch keeps the rest of the address", () => {
74 assert.equal(renamedBranchPath("/acme/web/tree/master/src/lib", "?x=1", "main"), "/acme/web/tree/main/src/lib?x=1");
75 assert.equal(renamedBranchPath("/acme/web/blob/old/README.md", "", "feature/new"), "/acme/web/blob/feature%2Fnew/README.md");
76 assert.equal(renamedBranchPath("/acme/web/tree/master", "", "main"), "/acme/web/tree/main");
77 assert.equal(renamedBranchPath("/acme/web/commits", "", "main"), null);
78});
79
80test("days until a date, never negative", () => {
81 const now = Date.parse("2026-10-05T12:00:00Z");
82 assert.equal(daysUntil("2026-11-04T12:00:00Z", now), 30);
83 assert.equal(daysUntil("2026-10-05T13:00:00Z", now), 1);
84 assert.equal(daysUntil("2026-10-01T00:00:00Z", now), 0);
85 assert.equal(daysUntil("not a date", now), 0);
86});
87
88test("dates read the same everywhere", () => {
89 assert.equal(longDate("2026-11-04T23:30:00Z"), "4 November 2026");
90 assert.equal(longDate("nope"), "nope");
91});
92
93test("names are tidied, not judged", () => {
94 assert.equal(tidyName(" my new site "), "my-new-site");
95});