// scenarios/gitlab.mjs — PAT connect against the fake GitLab (started by the // driver before daemon boot; its URL is in GITLAB_BASE_URL), project mapping, // status, and the PAT-leak guarantee. import { rest } from "../lib.mjs"; export async function run(ctx) { const { r, base, token, gitlab } = ctx; const connect = await rest(base, token, "/api/gitlab/connect", { method: "POST", body: { token: gitlab.pat }, }); r.check( "POST /api/gitlab/connect → 200 {username}", connect.status === 200 && connect.json?.username === "e2e-user", `got ${connect.status} ${connect.text}`, ); r.check( "daemon validated PAT against fake /api/v4/user", gitlab.seen.userAuths.length === 1 && gitlab.seen.userAuths[0] === gitlab.pat, JSON.stringify(gitlab.seen.userAuths), ); const status = await rest(base, token, "/api/gitlab/status"); r.check( "status shows connected with username + baseUrl", status.json?.connected === true && status.json?.username === "e2e-user" && status.json?.baseUrl === gitlab.url, JSON.stringify(status.json), ); const repos = await rest(base, token, "/api/gitlab/repos"); r.check( "repos mapped to protocol shape", Array.isArray(repos.json) && repos.json.length === 2 && repos.json.every((p) => typeof p.path === "string" && typeof p.name === "string" && typeof p.namespace === "string" && typeof p.lastActivityAt === "string" && typeof p.webUrl === "string" && typeof p.defaultBranch === "string"), JSON.stringify(repos.json ?? null), ); r.check( "repos sorted by lastActivityAt desc (daemon-side sort)", repos.json?.[0]?.path === "lvmh/alpha" && repos.json?.[1]?.path === "lvmh/beta" && repos.json?.[0]?.defaultBranch === "trunk", JSON.stringify((repos.json ?? []).map((p) => p.path)), ); const leaky = [connect.text, status.text, repos.text].filter((t) => t.includes(gitlab.pat)); r.check("PAT never appears in any daemon response", leaky.length === 0, `leaked in ${leaky.length} response(s)`); const badConnect = await rest(base, token, "/api/gitlab/connect", { method: "POST", body: { token: "glpat-wrong" }, }); r.check("connect with bad PAT → error status", badConnect.status >= 400, `got ${badConnect.status}`); const statusAfter = await rest(base, token, "/api/gitlab/status"); r.check( "failed connect does not clobber the stored PAT", statusAfter.json?.connected === true && statusAfter.json?.username === "e2e-user", JSON.stringify(statusAfter.json), ); }