CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history
projects.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.
| 1e162a8 | 1 | /** |
| 2 | * Block E1 — Projects / kanban smoke tests. | |
| 3 | */ | |
| 4 | ||
| 5 | import { describe, it, expect } from "bun:test"; | |
| 6 | import app from "../app"; | |
| 7 | ||
| 8 | describe("projects — route smoke", () => { | |
| 9 | it("GET /:owner/:repo/projects on missing repo → 404", async () => { | |
| 10 | const res = await app.request("/nobody/missing/projects"); | |
| 11 | expect(res.status).toBe(404); | |
| 12 | }); | |
| 13 | ||
| 14 | it("GET /:owner/:repo/projects/new without auth → 302 /login", async () => { | |
| 15 | const res = await app.request("/any/repo/projects/new"); | |
| 16 | expect(res.status).toBe(302); | |
| 17 | expect(res.headers.get("location") || "").toMatch(/^\/login/); | |
| 18 | }); | |
| 19 | ||
| 20 | it("POST /:owner/:repo/projects without auth → 302 /login", async () => { | |
| 21 | const res = await app.request("/any/repo/projects", { | |
| 22 | method: "POST", | |
| 23 | body: new URLSearchParams({ title: "x" }), | |
| 24 | headers: { "content-type": "application/x-www-form-urlencoded" }, | |
| 25 | }); | |
| 26 | expect(res.status).toBe(302); | |
| 27 | expect(res.headers.get("location") || "").toMatch(/^\/login/); | |
| 28 | }); | |
| 29 | ||
| 30 | it("POST /:owner/:repo/projects/1/columns without auth → 302 /login", async () => { | |
| 31 | const res = await app.request("/any/repo/projects/1/columns", { | |
| 32 | method: "POST", | |
| 33 | body: new URLSearchParams({ name: "Later" }), | |
| 34 | headers: { "content-type": "application/x-www-form-urlencoded" }, | |
| 35 | }); | |
| 36 | expect(res.status).toBe(302); | |
| 37 | expect(res.headers.get("location") || "").toMatch(/^\/login/); | |
| 38 | }); | |
| 39 | ||
| 40 | it("POST /:owner/:repo/projects/1/items without auth → 302 /login", async () => { | |
| 41 | const res = await app.request("/any/repo/projects/1/items", { | |
| 42 | method: "POST", | |
| 43 | body: new URLSearchParams({ column_id: "x", title: "card" }), | |
| 44 | headers: { "content-type": "application/x-www-form-urlencoded" }, | |
| 45 | }); | |
| 46 | expect(res.status).toBe(302); | |
| 47 | expect(res.headers.get("location") || "").toMatch(/^\/login/); | |
| 48 | }); | |
| 49 | ||
| 50 | it("POST close without auth → 302 /login", async () => { | |
| 51 | const res = await app.request("/any/repo/projects/1/close", { | |
| 52 | method: "POST", | |
| 53 | }); | |
| 54 | expect(res.status).toBe(302); | |
| 55 | expect(res.headers.get("location") || "").toMatch(/^\/login/); | |
| 56 | }); | |
| 57 | }); |