Open History to see the last commit
1import { recognizeRemoteWith } from "@t3tools/source-control-core/shared/definition";
2import { describe, expect, it } from "vite-plus/test";
3
4import { definition } from "./definition.ts";
5
6const parse = (url: string) => definition.parseChangeRequestUrl(new URL(url));
7
8describe("GitLab change request URLs", () => {
9 it("reads a merge request on any host, nested groups and all", () => {
10 expect(parse("https://gitlab.com/t3tools/platform/t3code/-/merge_requests/42")).toEqual({
11 host: "gitlab.com",
12 repository: "t3tools/platform/t3code",
13 number: 42,
14 repositoryUrl: "https://gitlab.com/t3tools/platform/t3code",
15 });
16 expect(parse("https://code.acme.test/team/project/-/merge_requests/9")).toMatchObject({
17 host: "code.acme.test",
18 repository: "team/project",
19 number: 9,
20 });
21 });
22
23 it("keeps pull-like segments inside nested repository paths", () => {
24 expect(
25 parse("https://gitlab.example.test/group/pull/123/repo/-/merge_requests/42")?.repositoryUrl,
26 ).toBe("https://gitlab.example.test/group/pull/123/repo");
27 });
28
29 it("leaves issues and single-segment paths alone", () => {
30 expect(parse("https://gitlab.com/t3tools/t3code/-/issues/12")).toBeNull();
31 expect(parse("https://gitlab.com/t3code/-/merge_requests/12")).toBeNull();
32 });
33
34 it("recognizes only merge request URLs it can parse", () => {
35 for (const url of [
36 "https://gitlab.com/g/p?x=/-/merge_requests/5",
37 "https://gitlab.com/g/p#/-/merge_requests/5",
38 "https://gitlab.com?x=/g/p/-/merge_requests/5",
39 "https://gitlab.com#/g/p/-/merge_requests/5",
40 "https://gitlab.com/t3code/-/merge_requests/12",
41 "https://gitlab.com/g//-/merge_requests/5",
42 ]) {
43 expect(definition.isChangeRequestReference(url), url).toBe(false);
44 expect(parse(url), url).toBeNull();
45 }
46 for (const url of [
47 "https://code.acme.test/a/b/c/-/merge_requests/7?tab=diffs",
48 "http://git.internal/a/b/c/-/merge_requests/7#note_1",
49 "https://code.acme.test/a/b/c/-/merge_requests/7/diffs",
50 ]) {
51 expect(definition.isChangeRequestReference(url), url).toBe(true);
52 expect(parse(url), url).toMatchObject({ repository: "a/b/c", number: 7 });
53 }
54 });
55
56 it("builds merge request URLs below the repository", () => {
57 expect(
58 definition.changeRequestUrl({
59 host: "gitlab.com",
60 repository: "group/sub/project",
61 number: 4,
62 }),
63 ).toBe("https://gitlab.com/group/sub/project/-/merge_requests/4");
64 expect(
65 definition.changeRequestUrl({
66 host: "gitlab.internal",
67 repository: "team/app",
68 number: 5,
69 remoteUrl: "http://gitlab.internal:8080/team/app.git",
70 }),
71 ).toBe("http://gitlab.internal:8080/team/app/-/merge_requests/5");
72 expect(
73 definition.changeRequestUrl({
74 host: "gitlab.internal",
75 repository: "team/app",
76 number: 5,
77 remoteUrl: "git@gitlab.internal:team/app.git",
78 }),
79 ).toBe("https://gitlab.internal/team/app/-/merge_requests/5");
80 expect(
81 definition.changeRequestUrl({
82 host: "gitlab.com",
83 repository: "group/sub/project",
84 number: 4,
85 webUrl: "https://gitlab.com/group/sub/project",
86 }),
87 ).toBe("https://gitlab.com/group/sub/project/-/merge_requests/4");
88 });
89
90 it("links authors, bots included, to their profile on the repository's host", () => {
91 expect(definition.authorProfileUrl("TonybynMp4", "https://gitlab.com/group/sub/project")).toBe(
92 "https://gitlab.com/TonybynMp4",
93 );
94 expect(
95 definition.authorProfileUrl(
96 "project_278964_bot_89f97e2c",
97 "http://gitlab.internal:8080/team/app/-/merge_requests/5",
98 ),
99 ).toBe("http://gitlab.internal:8080/project_278964_bot_89f97e2c");
100 });
101});
102
103describe("GitLab CLI commands", () => {
104 it("recognizes shell merges and closes, including glab's `accept` alias", () => {
105 for (const command of ["glab mr merge 7 --yes", "glab mr accept 7 --yes", "glab mr close 7"]) {
106 expect(definition.changeRequestCloseCommand.test(command), command).toBe(true);
107 }
108 expect(definition.changeRequestCloseCommand.test("glab mr view 7")).toBe(false);
109 });
110});
111
112describe("GitLab remotes", () => {
113 const recognize = (url: string) => recognizeRemoteWith(definition, url);
114
115 it("keeps an HTTP port in the base URL and drops an SSH one", () => {
116 expect(recognize("https://gitlab.com:8443/group/repo.git")).toEqual({
117 kind: "gitlab",
118 name: "GitLab",
119 baseUrl: "https://gitlab.com:8443",
120 });
121 expect(recognize("ssh://git@gitlab.example.test:24/group/repo.git")).toEqual({
122 kind: "gitlab",
123 name: "GitLab Self-Hosted",
124 baseUrl: "https://gitlab.example.test",
125 });
126 expect(recognize("gitlab@gitlab.example.com:group/project.git")?.baseUrl).toBe(
127 "https://gitlab.example.com",
128 );
129 });
130
131 it("matches complete DNS labels only", () => {
132 expect(recognize("https://notgitlab.example.com/group/repo.git")).toBeNull();
133 });
134});