CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history
api.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.
| fc1817a | 1 | import { describe, it, expect, beforeAll, afterAll } from "bun:test"; |
| 2 | import { join } from "path"; | |
| 3 | import { rm, mkdir } from "fs/promises"; | |
| 4 | import app from "../app"; | |
| 5 | ||
| 6 | const TEST_REPOS = join(import.meta.dir, "../../.test-repos-api"); | |
| 7 | ||
| 8 | beforeAll(async () => { | |
| 9 | process.env.GIT_REPOS_PATH = TEST_REPOS; | |
| 10 | process.env.DATABASE_URL = process.env.DATABASE_URL || ""; | |
| 11 | await mkdir(TEST_REPOS, { recursive: true }); | |
| 12 | }); | |
| 13 | ||
| 14 | afterAll(async () => { | |
| 15 | await rm(TEST_REPOS, { recursive: true, force: true }); | |
| 16 | }); | |
| 17 | ||
| 18 | describe("API routes", () => { | |
| 19 | it("GET / returns home page", async () => { | |
| 20 | const res = await app.request("/"); | |
| 21 | expect(res.status).toBe(200); | |
| 22 | const text = await res.text(); | |
| 23 | expect(text).toContain("gluecron"); | |
| 24 | }); | |
| 25 | ||
| 63807e5 | 26 | it("GET /api/repos/:owner/:name returns 404 or 503, never 500", async () => { |
| fc1817a | 27 | const res = await app.request("/api/repos/nobody/nothing"); |
| 63807e5 | 28 | // Without DB: 503 (db unreachable). With DB + missing repo: 404. |
| 29 | // API must degrade gracefully — 500 is NOT acceptable. | |
| 30 | expect([404, 503]).toContain(res.status); | |
| fc1817a | 31 | }); |
| 32 | ||
| 63807e5 | 33 | it("POST /api/repos returns 400 without required fields, never 500", async () => { |
| fc1817a | 34 | const res = await app.request("/api/repos", { |
| 35 | method: "POST", | |
| 36 | headers: { "Content-Type": "application/json" }, | |
| 37 | body: JSON.stringify({}), | |
| 38 | }); | |
| 63807e5 | 39 | // Validation happens before DB access — always 400. |
| 40 | expect(res.status).toBe(400); | |
| 41 | }); | |
| 42 | ||
| 43 | it("GET /api/users/:u/repos returns 404 or 503, never 500", async () => { | |
| 44 | const res = await app.request("/api/users/nobody/repos"); | |
| 45 | expect([404, 503]).toContain(res.status); | |
| fc1817a | 46 | }); |
| 47 | }); | |
| 48 | ||
| 49 | describe("Git HTTP routes", () => { | |
| 50 | it("returns 400 for invalid service", async () => { | |
| 51 | const res = await app.request("/test/repo.git/info/refs?service=invalid"); | |
| 52 | expect(res.status).toBe(400); | |
| 53 | }); | |
| 54 | ||
| 55 | it("returns 404 for non-existent repo", async () => { | |
| 56 | const res = await app.request( | |
| 57 | "/nobody/nothing.git/info/refs?service=git-upload-pack" | |
| 58 | ); | |
| 59 | expect(res.status).toBe(404); | |
| 60 | }); | |
| 61 | }); |