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.

125 linesCodeBlameRaw
1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import { linkPathOf, refContext, refRoute, refSitePath, routeFor, sessionRoute, sitePathOf, targetRoute } from "./links.ts";
5
6test("a g1t:// link names a site path, as on the desktop", () => {
7 assert.equal(sitePathOf("g1t://acme/-/chat/dm/chn_1"), "/acme/-/chat/dm/chn_1");
8 assert.equal(sitePathOf("g1t:///acme/rocket/pull/3?tab=files"), "/acme/rocket/pull/3?tab=files");
9 assert.equal(sitePathOf("https://g1t.sh/acme"), null);
10});
11
12test("an https link to the site names the same path as a g1t:// one", () => {
13 assert.equal(linkPathOf("https://g1t.sh/acme/-/work/12"), "/acme/-/work/12");
14 assert.equal(linkPathOf("g1t://acme/-/work/12"), "/acme/-/work/12");
15 assert.equal(linkPathOf("https://g1t.sh/acme/-/work?repo=web#top"), "/acme/-/work?repo=web");
16 assert.equal(linkPathOf("https://g1t.sh"), "/");
17 assert.equal(linkPathOf("mailto:someone@example.com"), null);
18});
19
20test("Chat's pages open the app's Chat", () => {
21 assert.equal(routeFor("/acme/-/chat"), "/chat?workspace=acme");
22 assert.equal(routeFor("/acme/-/chat/general"), "/chat/general?workspace=acme");
23 assert.equal(routeFor("/acme/-/chat/dm/chn_1"), "/chat/chn_1?workspace=acme");
24 assert.equal(routeFor("/acme/-/chat/browse"), null);
25});
26
27test("Work's pages open the app's Work", () => {
28 assert.equal(routeFor("/acme/-/work"), "/work?workspace=acme");
29 assert.equal(routeFor("/acme/-/work/12"), "/work/12?workspace=acme");
30 assert.equal(routeFor(linkPathOf("g1t://acme/-/work/12")!), "/work/12?workspace=acme");
31 assert.equal(routeFor(linkPathOf("https://g1t.sh/acme/-/work/12")!), "/work/12?workspace=acme");
32 assert.equal(routeFor("/acme/-/work/new"), "/work/new?workspace=acme");
33 // The list keeps the filters the site's does, and drops anything else.
34 assert.equal(routeFor("/acme/-/work?repo=web&label=bug&page=3"), "/work?workspace=acme&label=bug&repo=web");
35 assert.equal(routeFor("/acme/-/work/labels"), null);
36 assert.equal(routeFor("/acme/-/work/milestones/2"), null);
37 assert.equal(routeFor("/acme/-/work/12/edit"), null);
38});
39
40test("Work's board opens Work on its board", () => {
41 assert.equal(routeFor("/acme/-/work/board"), "/work?workspace=acme&view=board");
42 assert.equal(routeFor(linkPathOf("g1t://acme/-/work/board")!), "/work?workspace=acme&view=board");
43 assert.equal(routeFor("/acme/-/work/board/x"), null);
44});
45
46test("Sessions and a session open the app's Sessions", () => {
47 assert.equal(routeFor(linkPathOf("g1t://acme/-/sessions")!), "/work/sessions?workspace=acme");
48 assert.equal(routeFor(linkPathOf("https://g1t.sh/acme/-/sessions")!), "/work/sessions?workspace=acme");
49 assert.equal(routeFor(linkPathOf("g1t://acme/-/sessions/ses_01abc")!), "/work/sessions/ses_01abc?workspace=acme");
50 assert.equal(routeFor(linkPathOf("https://g1t.sh/acme/-/sessions/ses_01abc")!), "/work/sessions/ses_01abc?workspace=acme");
51 // The list keeps the filters the site's does, and drops anything else.
52 assert.equal(routeFor("/acme/-/sessions?state=live&repo=web&page=2"), "/work/sessions?workspace=acme&state=live&repo=web");
53 assert.equal(routeFor("/acme/-/sessions/ses_1/entries"), null);
54});
55
56test("a session opens its page, or its pull request's for g1t's agent and a recorded one", () => {
57 assert.equal(sessionRoute({ kind: "harness", id: "ses_1", repo: "acme/web", pull: 3 }, "acme", true), "/work/sessions/ses_1?workspace=acme");
58 assert.equal(sessionRoute({ kind: "hosted", id: "ses_2", repo: "acme/web", pull: null }, "acme", false), "/work/sessions/ses_2?workspace=acme");
59 assert.equal(sessionRoute({ kind: "agent", id: "run_1", repo: "acme/web", pull: 3 }, "acme", true), "/code/acme/web/pull/3");
60 assert.equal(sessionRoute({ kind: "recorded", id: "pr_1", repo: "acme/web", pull: 3 }, "acme", false), "/open?path=%2Facme%2Fweb%2Fpull%2F3%2Fsession");
61 assert.equal(sessionRoute({ kind: "recorded", id: "pr_1", repo: "acme/web", pull: null }, "acme", true), null);
62});
63
64test("an old link to an issue asks g1t what its number names in its repository", () => {
65 assert.equal(routeFor("/acme/rocket/issues/12"), "/ref?repo=acme%2Frocket&number=12");
66 assert.equal(routeFor(linkPathOf("https://g1t.sh/acme/rocket/issues/12")!), "/ref?repo=acme%2Frocket&number=12");
67 assert.equal(routeFor("/acme/rocket/issues"), "/work?workspace=acme&repo=rocket");
68 assert.equal(routeFor("/acme/rocket/issues/new"), "/work/new?workspace=acme&repo=rocket");
69 assert.equal(routeFor("/acme/rocket/issues/12/edit"), null);
70});
71
72test("Code's pages open the app's Code", () => {
73 assert.equal(routeFor("/acme/rocket"), "/code/acme/rocket");
74 assert.equal(routeFor("/acme/rocket/pull/14"), "/code/acme/rocket/pull/14");
75 assert.equal(routeFor("/acme/-/overview"), "/code?workspace=acme");
76 assert.equal(routeFor("/acme/rocket/pull/14/files"), null);
77 assert.equal(routeFor("/acme/rocket/sessions"), null);
78});
79
80test("#N is read where it was written, owner/name#N in that repository, workspace#N in that workspace", () => {
81 const here = { workspace: "acme" };
82 assert.deepEqual(refContext(null, here), { workspace: "acme" });
83 assert.deepEqual(refContext(null, { repo: "acme/web" }), { repo: "acme/web" });
84 assert.deepEqual(refContext("acme/api", here), { repo: "acme/api" });
85 assert.deepEqual(refContext("globex", here), { workspace: "globex" });
86 assert.equal(refRoute({ workspace: "acme" }, 7), "/ref?workspace=acme&number=7");
87 assert.equal(refRoute({ repo: "acme/web" }, 7), "/ref?repo=acme%2Fweb&number=7");
88});
89
90test("what a reference names opens its screen, and the site reads one the app cannot", () => {
91 assert.equal(targetRoute({ kind: "work_item", workspace: "acme", number: 31, item_id: "wki_1" }), "/work/31?workspace=acme");
92 assert.equal(targetRoute({ kind: "pull", repo: "acme/web", number: 9 }), "/code/acme/web/pull/9");
93 assert.equal(targetRoute({ kind: "pull", repo: "nonsense", number: 9 }), null);
94 assert.equal(targetRoute({ kind: "none" }), null);
95 assert.equal(refSitePath({ repo: "acme/web" }, 9), "/acme/web/issues/9");
96 assert.equal(refSitePath({ workspace: "acme" }, 9), "/acme/-/work/9");
97});
98
99test("old links to Agents, Customize and the Marketplace open Home", () => {
100 assert.equal(routeFor("/acme/-/agents"), "/home?workspace=acme");
101 assert.equal(routeFor("/acme/-/agents/skills"), "/home?workspace=acme");
102 assert.equal(routeFor("/acme/-/agents/skills/pdf"), "/home?workspace=acme");
103 assert.equal(routeFor("/acme/-/customize"), "/home?workspace=acme");
104 assert.equal(routeFor("/acme/-/customize/plugins/pdf%40anthropic-agent-skills"), "/home?workspace=acme");
105 assert.equal(routeFor("/acme/-/marketplace/integrations"), "/home?workspace=acme");
106});
107
108test("the integrations directory stays on the site", () => {
109 assert.equal(routeFor("/acme/-/integrations"), null);
110 assert.equal(routeFor("/acme/-/integrations/github"), null);
111});
112
113test("the app's sign-in comes back to its own screen, and the site's own pages stay on the site", () => {
114 assert.equal(routeFor("/oauth/callback?code=c&state=s"), "/oauth/callback?code=c&state=s");
115 assert.equal(routeFor("/settings/tokens"), null);
116 assert.equal(routeFor("/"), "/");
117});
118
119test("a connect link points the app at a g1t", () => {
120 assert.equal(routeFor("/connect?server=https%3A%2F%2Fg1t.example.com"), "/connect?server=https%3A%2F%2Fg1t.example.com");
121 assert.equal(sitePathOf("g1t://connect?server=https%3A%2F%2Fg1t.example.com"), "/connect?server=https%3A%2F%2Fg1t.example.com");
122 // A workspace named connect is still a workspace.
123 assert.equal(routeFor("/connect/-/chat"), "/chat?workspace=connect");
124 assert.equal(routeFor("/connect/web"), "/code/connect/web");
125});