// fake-gitlab.mjs — minimal GitLab v4 API stand-in on an ephemeral port. // Serves exactly the two endpoints the daemon calls (daemon/gitlab.go): // GET /api/v4/user (PAT validation) // GET /api/v4/projects (member projects listing) // Projects are returned UNSORTED so the harness proves the daemon sorts by // last_activity_at. import * as http from "node:http"; export const GOOD_PAT = "glpat-e2e-0123456789abcdef"; const HTTP_OK = 200; const HTTP_UNAUTHORIZED = 401; const HTTP_NOT_FOUND = 404; export function startFakeGitLab() { const seen = { userAuths: [], projectAuths: [] }; const server = http.createServer((req, res) => { const auth = String(req.headers["private-token"] ?? ""); const send = (code, obj) => { res.writeHead(code, { "Content-Type": "application/json" }); res.end(JSON.stringify(obj)); }; if (req.url.startsWith("/api/v4/user")) { seen.userAuths.push(auth); return auth === GOOD_PAT ? send(HTTP_OK, { id: 1, username: "e2e-user", name: "E2E User" }) : send(HTTP_UNAUTHORIZED, { message: "401 Unauthorized" }); } if (req.url.startsWith("/api/v4/projects")) { seen.projectAuths.push(auth); if (auth !== GOOD_PAT) return send(HTTP_UNAUTHORIZED, { message: "401 Unauthorized" }); const base = `http://127.0.0.1:${server.address().port}`; return send(HTTP_OK, [ { path_with_namespace: "lvmh/beta", name: "beta", namespace: { path: "lvmh" }, last_activity_at: "2025-07-01T10:00:00Z", web_url: `${base}/lvmh/beta`, default_branch: "main", }, { path_with_namespace: "lvmh/alpha", name: "alpha", namespace: { path: "lvmh" }, last_activity_at: "2025-08-01T10:00:00Z", web_url: `${base}/lvmh/alpha`, default_branch: "trunk", }, ]); } return send(HTTP_NOT_FOUND, { message: "404 Not Found" }); }); return new Promise((resolve) => { server.listen(0, "127.0.0.1", () => { resolve({ url: `http://127.0.0.1:${server.address().port}`, pat: GOOD_PAT, seen, close() { server.close(); }, }); }); }); }