CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history
merge-queue.test.ts
Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.
| a79a9ed | 1 | /** |
| 2 | * Block E5 — Merge queue smoke tests. | |
| 3 | * | |
| 4 | * Integration paths (enqueue → process-next → merge) need a seeded test DB | |
| 5 | * + a real bare repo on disk. Here we cover: | |
| 6 | * - helper shape (types + default values) | |
| 7 | * - route-level auth guards (302 redirects to /login for write actions) | |
| 8 | * - 404 for missing repo on read path | |
| 9 | */ | |
| 10 | ||
| 11 | import { describe, it, expect } from "bun:test"; | |
| 12 | import app from "../app"; | |
| 13 | ||
| 14 | describe("merge-queue — route smoke", () => { | |
| 15 | it("GET /:owner/:repo/queue on missing repo → 404 HTML", async () => { | |
| 16 | const res = await app.request("/nobody/missing/queue"); | |
| 17 | expect(res.status).toBe(404); | |
| 18 | const body = await res.text(); | |
| 19 | expect(body.toLowerCase()).toContain("not found"); | |
| 20 | }); | |
| 21 | ||
| 22 | it("POST /:owner/:repo/pulls/1/enqueue without auth → 302 /login", async () => { | |
| 23 | const res = await app.request("/any/repo/pulls/1/enqueue", { | |
| 24 | method: "POST", | |
| 25 | }); | |
| 26 | expect(res.status).toBe(302); | |
| 27 | const loc = res.headers.get("location") || ""; | |
| 28 | expect(loc.startsWith("/login")).toBe(true); | |
| 29 | }); | |
| 30 | ||
| 31 | it("POST /:owner/:repo/queue/abc/dequeue without auth → 302 /login", async () => { | |
| 32 | const res = await app.request("/any/repo/queue/abc/dequeue", { | |
| 33 | method: "POST", | |
| 34 | }); | |
| 35 | expect(res.status).toBe(302); | |
| 36 | const loc = res.headers.get("location") || ""; | |
| 37 | expect(loc.startsWith("/login")).toBe(true); | |
| 38 | }); | |
| 39 | ||
| 40 | it("POST /:owner/:repo/queue/process-next without auth → 302 /login", async () => { | |
| 41 | const res = await app.request("/any/repo/queue/process-next", { | |
| 42 | method: "POST", | |
| 43 | }); | |
| 44 | expect(res.status).toBe(302); | |
| 45 | const loc = res.headers.get("location") || ""; | |
| 46 | expect(loc.startsWith("/login")).toBe(true); | |
| 47 | }); | |
| 48 | }); | |
| 49 | ||
| 50 | describe("merge-queue — helper exports", () => { | |
| 51 | it("exports enqueuePr, dequeueEntry, listQueue, peekHead, completeEntry", async () => { | |
| 52 | const mod = await import("../lib/merge-queue"); | |
| 53 | expect(typeof mod.enqueuePr).toBe("function"); | |
| 54 | expect(typeof mod.dequeueEntry).toBe("function"); | |
| 55 | expect(typeof mod.listQueue).toBe("function"); | |
| 56 | expect(typeof mod.peekHead).toBe("function"); | |
| 57 | expect(typeof mod.completeEntry).toBe("function"); | |
| 58 | expect(typeof mod.markHeadRunning).toBe("function"); | |
| 59 | expect(typeof mod.isQueued).toBe("function"); | |
| 60 | expect(typeof mod.queueDepth).toBe("function"); | |
| 61 | expect(typeof mod.listQueueWithPrs).toBe("function"); | |
| 62 | }); | |
| 63 | }); |