import assert from "node:assert/strict"; import { test } from "node:test"; import { createServer } from "node:http"; // A pull request's merge check (novox/hq to-be 45 §9): each new head announced once, and the verdict set // where the pull request shows it — an error never as a success. test("each open pull request's new head is announced once, and nothing closed or merged", async () => { const { headsToAnnounce } = await import("../pulls.ts"); const pulls = [ { number: 1, title: "a", state: "open", merged: false, head_sha: "aaa", html_url: "" }, { number: 2, title: "b", state: "open", merged: false, head_sha: "bbb", html_url: "" }, { number: 3, title: "c", state: "closed", merged: true, head_sha: "ccc", html_url: "" }, { number: 4, title: "d", state: "open", merged: false, html_url: "" }, ]; const announced = { "novox/mesh-catalog#1": "aaa", "novox/mesh-catalog#2": "old" }; assert.deepEqual(headsToAnnounce("novox/mesh-catalog", pulls, announced).map((p) => p.number), [2], "only a head not announced, of a pull request that is open"); }); test("a verdict is the head commit's status; an error is the forge's error, never a success", async () => { const { statusFor, commentFor, CHECK_CONTEXT } = await import("../pulls.ts"); const base = { owner: "novox", repo: "mesh-catalog", number: 7, commit: "0123456789abcdef", id: "build-1", on: "laptop" }; assert.equal(statusFor({ ...base, verdict: "pass", summary: "every machine composes" }).state, "success"); assert.equal(statusFor({ ...base, verdict: "warning", summary: "a merge rebuilds 14 module(s)" }).state, "warning"); assert.equal(statusFor({ ...base, verdict: "fail", summary: "x" }).state, "failure"); assert.equal(statusFor({ ...base, verdict: "error", summary: "the check could not run" }).state, "error"); assert.equal(statusFor({ ...base, verdict: "", summary: "" }).state, "error", "no verdict is no pass"); const long = statusFor({ ...base, verdict: "fail", summary: "y".repeat(500) }); assert.ok(long.description.length <= 140 && long.context === CHECK_CONTEXT); assert.equal(commentFor({ ...base, verdict: "pass", summary: "fine" }), null, "a pass leaves no comment"); const said = commentFor({ ...base, verdict: "fail", summary: "lemurs refused", report: "fails:\n - ```x```" }) ?? ""; assert.match(said, /Merge check: FAIL/); assert.match(said, /01234567/); assert.match(said, /builds --log build-1/); assert.ok(!said.slice(said.indexOf("```") + 3, said.lastIndexOf("```")).includes("```"), "the report cannot close its own block"); }); test("a commit status is set on the commit, under the merge check's context", async () => { const { GiteaClient } = await import("../client.ts"); let seen: { path: string; body: any } | null = null; const server = createServer((req, res) => { let raw = ""; req.on("data", (c) => (raw += c)); req.on("end", () => { seen = { path: `${req.method} ${req.url}`, body: JSON.parse(raw) }; res.statusCode = 201; res.end("{}"); }); }); await new Promise((r) => server.listen(0, r)); const port = (server.address() as any).port; const client = new GiteaClient(`http://127.0.0.1:${port}`, "t"); await client.setCommitStatus("novox", "mesh-catalog", "abc123", { state: "failure", context: "mesh/merge-gate", description: "x" }); server.close(); assert.equal(seen!.path, "POST /api/v1/repos/novox/mesh-catalog/statuses/abc123"); assert.equal(seen!.body.state, "failure"); assert.equal(seen!.body.context, "mesh/merge-gate"); });