CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history
editor.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.
| 9736195 | 1 | /** |
| 2 | * Sanity tests for the web file editor route. | |
| 3 | * | |
| 4 | * Visual correctness (CodeMirror 6 syntax highlighting, CDN loading) is | |
| 5 | * manually verified. These tests cover: | |
| 6 | * | |
| 7 | * 1. Module shape — the default export is a Hono router. | |
| 8 | * 2. Auth guard — unauthenticated GET to the edit form redirects to /login | |
| 9 | * or returns an auth-related error status. | |
| 10 | * 3. The AI commit-message endpoint is still reachable (auth guard only — | |
| 11 | * full coverage in editor-ai-commit.test.ts). | |
| 12 | */ | |
| 13 | ||
| 14 | import { describe, it, expect } from "bun:test"; | |
| 15 | import type { Hono } from "hono"; | |
| 16 | ||
| 17 | describe("editor module", () => { | |
| 18 | it("exports a Hono router as the default export", async () => { | |
| 19 | // Dynamic import so test isolation is clean (no side-effects at top level) | |
| 20 | const mod = await import("../routes/editor"); | |
| 21 | const router = mod.default; | |
| 22 | // Hono routers expose .routes and .fetch | |
| 23 | expect(typeof router).toBe("object"); | |
| 24 | expect(router).not.toBeNull(); | |
| f5b9ef5 | 25 | expect(typeof (router as unknown as Hono).fetch).toBe("function"); |
| 26 | expect(Array.isArray((router as unknown as Hono).routes)).toBe(true); | |
| 9736195 | 27 | }); |
| 28 | ||
| 29 | it("registers at least one route for /:owner/:repo/edit/:ref", async () => { | |
| 30 | const mod = await import("../routes/editor"); | |
| f5b9ef5 | 31 | const router = mod.default as unknown as Hono; |
| 9736195 | 32 | const editRoutes = router.routes.filter( |
| 33 | (r) => r.path.includes("/edit/") || r.path.includes("edit") | |
| 34 | ); | |
| 35 | expect(editRoutes.length).toBeGreaterThan(0); | |
| 36 | }); | |
| 37 | }); | |
| 38 | ||
| 39 | describe("GET /:owner/:repo/edit/:ref — auth guard", () => { | |
| 40 | it("redirects or returns 401/403/404 for unauthenticated users", async () => { | |
| 41 | // We import the full app so the editor is mounted properly | |
| 42 | const { default: app } = await import("../app"); | |
| 43 | const res = await app.request( | |
| 44 | "/alice/myrepo/edit/README.md", | |
| 45 | { method: "GET", redirect: "manual" } | |
| 46 | ); | |
| 47 | // Any of these are acceptable: redirect to login, or a deny status | |
| 48 | const acceptable = [301, 302, 303, 307, 308, 401, 403, 404, 503]; | |
| 49 | expect(acceptable).toContain(res.status); | |
| 50 | if ([302, 303, 307].includes(res.status)) { | |
| 51 | const loc = res.headers.get("location") || ""; | |
| 52 | expect(loc).toContain("/login"); | |
| 53 | } | |
| 54 | }); | |
| 55 | }); |