11import { test } from "node:test"
22import assert from "node:assert/strict"
33
4- import { github , bitbucket , codeberg , forgeForHostname } from "../forges.js"
4+ import { github , bitbucket , codeberg , gitlab , forgeForHostname } from "../forges.js"
55
66//
77// forgeForHostname
@@ -18,13 +18,16 @@ test("forgeForHostname matches codeberg.org", () => {
1818 assert . equal ( forgeForHostname ( "codeberg.org" ) , codeberg )
1919} )
2020
21+ test ( "forgeForHostname matches gitlab.com" , ( ) => {
22+ assert . equal ( forgeForHostname ( "gitlab.com" ) , gitlab )
23+ } )
24+
2125test ( "forgeForHostname matches a subdomain containing the hostname" , ( ) => {
2226 // hostnames are matched as substrings of the page hostname
2327 assert . equal ( forgeForHostname ( "www.github.com" ) , github )
2428} )
2529
2630test ( "forgeForHostname returns null for an unknown forge" , ( ) => {
27- assert . equal ( forgeForHostname ( "gitlab.com" ) , null )
2831 assert . equal ( forgeForHostname ( "example.com" ) , null )
2932} )
3033
@@ -260,3 +263,71 @@ test("codeberg.authHeader builds a token Authorization header", () => {
260263 Authorization : "token cb_secret" ,
261264 } )
262265} )
266+
267+ //
268+ // gitlab adapter (merge requests, nested namespaces, URL-encoded project path)
269+ //
270+ test ( "gitlab.parseUrl extracts the project path and filepath from a blob URL" , ( ) => {
271+ const url = new URL ( "https://gitlab.com/gitlab-org/gitlab/-/blob/master/README.md" )
272+ assert . deepEqual ( gitlab . parseUrl ( url ) , {
273+ projectPath : "gitlab-org/gitlab" ,
274+ filepath : "README.md" ,
275+ origin : "https://gitlab.com" ,
276+ } )
277+ } )
278+
279+ test ( "gitlab.parseUrl keeps nested group namespaces in the project path" , ( ) => {
280+ const url = new URL ( "https://gitlab.com/group/subgroup/widget/-/blob/main/dir/app.js" )
281+ const info = gitlab . parseUrl ( url )
282+ assert . equal ( info . projectPath , "group/subgroup/widget" )
283+ assert . equal ( info . filepath , "dir/app.js" )
284+ } )
285+
286+ test ( "gitlab.parseUrl returns null for a non-file URL" , ( ) => {
287+ assert . equal ( gitlab . parseUrl ( new URL ( "https://gitlab.com/acme/widget" ) ) , null )
288+ } )
289+
290+ test ( "gitlab.listPRsUrl builds the merge_requests endpoint with the encoded path" , ( ) => {
291+ const info = { projectPath : "group/subgroup/widget" }
292+ assert . equal (
293+ gitlab . listPRsUrl ( info ) ,
294+ "https://gitlab.com/api/v4/projects/group%2Fsubgroup%2Fwidget/merge_requests?state=opened" )
295+ } )
296+
297+ test ( "gitlab.filesUrl builds the diffs endpoint for a merge request" , ( ) => {
298+ const info = { projectPath : "acme/widget" }
299+ assert . equal (
300+ gitlab . filesUrl ( info , { iid : 42 } ) ,
301+ "https://gitlab.com/api/v4/projects/acme%2Fwidget/merge_requests/42/diffs" )
302+ } )
303+
304+ test ( "gitlab.prWebUrl builds the web URL of a merge request" , ( ) => {
305+ const info = { projectPath : "acme/widget" , origin : "https://gitlab.com" }
306+ assert . equal (
307+ gitlab . prWebUrl ( info , 42 ) ,
308+ "https://gitlab.com/acme/widget/-/merge_requests/42" )
309+ } )
310+
311+ test ( "gitlab.prNumber reads the iid off a merge request object" , ( ) => {
312+ assert . equal ( gitlab . prNumber ( { id : 999 , iid : 7 , title : "ignored" } ) , 7 )
313+ } )
314+
315+ test ( "gitlab.pullRequests returns the list response as-is" , ( ) => {
316+ const mrs = [ { iid : 1 } , { iid : 2 } ]
317+ assert . equal ( gitlab . pullRequests ( mrs ) , mrs )
318+ } )
319+
320+ test ( "gitlab.filenames maps diff entries to their new_path" , ( ) => {
321+ const files = [ { new_path : "a.js" , old_path : "a.js" } , { new_path : "dir/b.js" , old_path : "dir/b.js" } ]
322+ assert . deepEqual ( gitlab . filenames ( files ) , [ "a.js" , "dir/b.js" ] )
323+ } )
324+
325+ test ( "gitlab exposes no rate-limit endpoint" , ( ) => {
326+ assert . equal ( gitlab . rateLimit , null )
327+ } )
328+
329+ test ( "gitlab.authHeader builds a PRIVATE-TOKEN header" , ( ) => {
330+ assert . deepEqual ( gitlab . authHeader ( "gl_secret" ) , {
331+ "PRIVATE-TOKEN" : "gl_secret" ,
332+ } )
333+ } )
0 commit comments