Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history

admin.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.

admin.test.tsBlame110 lines · 2 contributors
8f50ed0Claude1/**
2 * Block F3 — Admin panel smoke tests.
3 *
4 * Exercises the auth gate on every admin route + the lib exports. Doesn't
5 * mutate DB; `isSiteAdmin(null)` and `getFlag` against a non-existent key
6 * degrade gracefully and are safe to call in any environment.
7 */
8
9import { describe, it, expect } from "bun:test";
10import app from "../app";
11import {
12 isSiteAdmin,
13 KNOWN_FLAGS,
14 getFlag,
15} from "../lib/admin";
16
17describe("admin — auth gate", () => {
18 it("GET /admin without auth → 302 /login", async () => {
19 const res = await app.request("/admin");
20 expect(res.status).toBe(302);
21 expect(res.headers.get("location") || "").toContain("/login");
22 });
23
24 it("GET /admin/users without auth → 302 /login", async () => {
25 const res = await app.request("/admin/users");
26 expect(res.status).toBe(302);
27 expect(res.headers.get("location") || "").toContain("/login");
28 });
29
30 it("GET /admin/repos without auth → 302 /login", async () => {
31 const res = await app.request("/admin/repos");
32 expect(res.status).toBe(302);
33 expect(res.headers.get("location") || "").toContain("/login");
34 });
35
36 it("GET /admin/flags without auth → 302 /login", async () => {
37 const res = await app.request("/admin/flags");
38 expect(res.status).toBe(302);
39 expect(res.headers.get("location") || "").toContain("/login");
40 });
41
ad189d6ccantynz-alt42 // Regression: adminRoutes used to be mounted AFTER healthDashboardRoutes,
43 // whose generic GET /:owner/:repo/health matched :owner=admin
44 // :repo=autopilot and returned a real "repo not found" 404 -- the actual
45 // admin page was unreachable, not just unauthenticated. Found via a live
46 // production HTTP sweep. It must reach admin.tsx's own gate() (302 to
47 // login), not a repo-not-found 404.
48 it("GET /admin/autopilot/health reaches the real admin route, not the repo-health 404", async () => {
49 const res = await app.request("/admin/autopilot/health");
50 expect(res.status).toBe(302);
51 expect(res.headers.get("location") || "").toContain("/login");
52 });
53
8f50ed0Claude54 it("POST /admin/flags without auth → 302 /login", async () => {
55 const res = await app.request("/admin/flags", {
56 method: "POST",
57 body: new URLSearchParams({ registration_locked: "1" }),
58 headers: { "content-type": "application/x-www-form-urlencoded" },
59 });
60 expect(res.status).toBe(302);
61 expect(res.headers.get("location") || "").toContain("/login");
62 });
63});
64
65describe("admin — isSiteAdmin", () => {
66 it("returns false for null/undefined user", async () => {
67 expect(await isSiteAdmin(null)).toBe(false);
68 expect(await isSiteAdmin(undefined)).toBe(false);
69 expect(await isSiteAdmin("")).toBe(false);
70 });
71
72 it("returns false for non-existent user id", async () => {
73 const result = await isSiteAdmin("00000000-0000-0000-0000-000000000000");
74 expect(typeof result).toBe("boolean");
75 });
76});
77
78describe("admin — KNOWN_FLAGS", () => {
79 it("exposes registration_locked, site_banner_text, site_banner_level, read_only_mode", () => {
80 expect(KNOWN_FLAGS).toHaveProperty("registration_locked");
81 expect(KNOWN_FLAGS).toHaveProperty("site_banner_text");
82 expect(KNOWN_FLAGS).toHaveProperty("site_banner_level");
83 expect(KNOWN_FLAGS).toHaveProperty("read_only_mode");
84 });
85
86 it("defaults registration_locked to '0' (unlocked)", () => {
87 expect(KNOWN_FLAGS.registration_locked).toBe("0");
88 });
89});
90
91describe("admin — getFlag", () => {
92 it("returns null for unknown keys and never throws", async () => {
93 const v = await getFlag("nonexistent_flag_xyz");
94 expect(v === null || typeof v === "string").toBe(true);
95 });
96});
97
98describe("admin — lib exports", () => {
99 it("exports full admin surface", async () => {
100 const mod = await import("../lib/admin");
101 expect(typeof mod.isSiteAdmin).toBe("function");
102 expect(typeof mod.listSiteAdmins).toBe("function");
103 expect(typeof mod.grantSiteAdmin).toBe("function");
104 expect(typeof mod.revokeSiteAdmin).toBe("function");
105 expect(typeof mod.getFlag).toBe("function");
106 expect(typeof mod.setFlag).toBe("function");
107 expect(typeof mod.listFlags).toBe("function");
108 expect(mod.KNOWN_FLAGS).toBeDefined();
109 });
110});