Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

117 linesCodeBlameRaw
1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import {
5 MAX_CHANGES,
6 WATCH_MS,
7 byRepo,
8 byWorkspace,
9 cleanChange,
10 cleanRepoId,
11 cleanRepoPath,
12 cleanWorkspace,
13 cleanWorkspaceChange,
14 named,
15 stillWatching,
16 topicWorkspace,
17 watchUntil,
18 workspaceTopic,
19} from "./watch.ts";
20
21const AT = "2026-10-11T10:00:00Z";
22
23test("a change keeps only what a change carries", () => {
24 const change = cleanChange({
25 repo_id: "rep_1",
26 kind: "git.push",
27 ref: "refs/heads/main",
28 sha: "abc123",
29 commits: 3,
30 at: AT,
31 title: "a secret title",
32 body: "and its body",
33 });
34 assert.deepEqual(change, { repo_id: "rep_1", kind: "git.push", ref: "refs/heads/main", sha: "abc123", commits: 3, at: AT });
35});
36
37test("what is not a change is dropped", () => {
38 assert.equal(cleanChange(null), null);
39 assert.equal(cleanChange("git.push"), null);
40 assert.equal(cleanChange({ kind: "git.push", at: AT }), null);
41 assert.equal(cleanChange({ repo_id: "rep 1", kind: "git.push", at: AT }), null);
42 assert.equal(cleanChange({ repo_id: "rep_1", kind: "<script>", at: AT }), null);
43 // A field of the wrong shape goes; the change stays.
44 assert.deepEqual(cleanChange({ repo_id: "rep_1", kind: "pull.updated", number: -1, sha: "not a sha", run: "run 9", at: AT }), {
45 repo_id: "rep_1",
46 kind: "pull.updated",
47 at: AT,
48 });
49 assert.deepEqual(cleanChange({ repo_id: "rep_1", kind: "run.updated", run: "run_9", number: 4, at: AT }), {
50 repo_id: "rep_1",
51 kind: "run.updated",
52 run: "run_9",
53 number: 4,
54 at: AT,
55 });
56});
57
58test("changes go to their repositories in the order they came", () => {
59 const grouped = byRepo([
60 { repo_id: "rep_1", kind: "pull.opened", number: 1, at: AT },
61 { repo_id: "rep_2", kind: "work_item.opened", number: 2, at: AT },
62 { repo_id: "rep_1", kind: "pull.updated", number: 1, at: AT },
63 { nonsense: true },
64 ]);
65 assert.deepEqual([...grouped.keys()], ["rep_1", "rep_2"]);
66 assert.deepEqual(
67 grouped.get("rep_1")!.map((change) => change.kind),
68 ["pull.opened", "pull.updated"],
69 );
70 assert.equal(byRepo("nope").size, 0);
71 const many = Array.from({ length: MAX_CHANGES + 10 }, (_, n) => ({ repo_id: "rep_1", kind: "pull.updated", number: n, at: AT }));
72 assert.equal(byRepo(many).get("rep_1")!.length, MAX_CHANGES);
73});
74
75test("each watcher hears the repository by the name it asked for", () => {
76 const changes = [{ repo_id: "rep_1", kind: "git.push", at: AT }];
77 assert.deepEqual(named(changes, "acme/rocket"), [{ repo_id: "rep_1", kind: "git.push", at: AT, repo: "acme/rocket" }]);
78 assert.equal(Object.hasOwn(changes[0]!, "repo"), false, "the topic's own list is left as it was");
79});
80
81test("repository ids and paths are checked", () => {
82 assert.equal(cleanRepoId("rep_01J9"), "rep_01J9");
83 assert.equal(cleanRepoId("../x"), null);
84 assert.equal(cleanRepoPath("acme/rocket.js"), "acme/rocket.js");
85 assert.equal(cleanRepoPath("acme"), null);
86 assert.equal(cleanRepoPath("acme/rocket/extra"), null);
87});
88
89test("a watch lasts its time and no longer", () => {
90 const now = Date.parse(AT);
91 const until = watchUntil(now);
92 assert.equal(until, now + WATCH_MS);
93 assert.equal(stillWatching(until, now + WATCH_MS - 1), true);
94 assert.equal(stillWatching(until, now + WATCH_MS), false);
95 assert.equal(stillWatching(null, now), false);
96});
97
98test("a workspace's changes keep only what one carries, by workspace", () => {
99 const grouped = byWorkspace([
100 { workspace: "Acme", kind: "work_item.updated", number: 40, at: AT, title: "a secret title" },
101 { workspace: "acme", kind: "comment.created", number: 40, at: AT },
102 { workspace: "globex", kind: "work.claimed", at: AT },
103 { workspace: "not a slug!", kind: "work_item.updated", at: AT },
104 { workspace: "acme", kind: "<script>", at: AT },
105 ]);
106 assert.deepEqual([...grouped.keys()], ["acme", "globex"]);
107 assert.deepEqual(grouped.get("acme"), [
108 { workspace: "acme", kind: "work_item.updated", number: 40, at: AT },
109 { workspace: "acme", kind: "comment.created", number: 40, at: AT },
110 ]);
111 assert.equal(cleanWorkspaceChange(null), null);
112 assert.equal(cleanWorkspace(" Acme "), "acme");
113 // Its topic sits beside the repositories', and never takes a repository's id.
114 assert.equal(topicWorkspace(workspaceTopic("acme")), "acme");
115 assert.equal(topicWorkspace("rep_1"), null);
116 assert.equal(cleanRepoId(workspaceTopic("acme")), null);
117});