CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | /**
* Block E4 — Gists smoke tests.
*
* Full CRUD integration paths require a seeded test DB; we stick to pure
* helpers (`generateSlug`, `snapshotOf`) + public route behaviour
* (auth redirects, 404s) which exercise middleware + mounting.
*/
import { describe, it, expect } from "bun:test";
import app from "../app";
import { generateSlug, snapshotOf } from "../routes/gists";
describe("gists — generateSlug", () => {
it("returns an 8-char lowercase hex string", () => {
const s = generateSlug();
expect(s).toMatch(/^[0-9a-f]{8}$/);
});
it("returns different values across calls", () => {
const a = generateSlug();
const b = generateSlug();
expect(a).not.toBe(b);
});
});
describe("gists — snapshotOf", () => {
it("JSON-encodes filename → content map", () => {
const snap = snapshotOf([
{ filename: "a.ts", content: "export const a = 1;" },
{ filename: "b.md", content: "# hello" },
]);
const parsed = JSON.parse(snap);
expect(parsed["a.ts"]).toBe("export const a = 1;");
expect(parsed["b.md"]).toBe("# hello");
});
it("handles empty input", () => {
expect(snapshotOf([])).toBe("{}");
});
it("last duplicate filename wins", () => {
const snap = snapshotOf([
{ filename: "x", content: "first" },
{ filename: "x", content: "second" },
]);
expect(JSON.parse(snap).x).toBe("second");
});
});
describe("gists — route smoke", () => {
it("GET /gists → 200 HTML", async () => {
const res = await app.request("/gists");
expect(res.status).toBe(200);
});
it("GET /gists/new without auth → 302 /login", async () => {
const res = await app.request("/gists/new");
expect(res.status).toBe(302);
expect(res.headers.get("location") || "").toMatch(/^\/login/);
});
it("POST /gists without auth → 302 /login", async () => {
const res = await app.request("/gists", {
method: "POST",
body: new URLSearchParams({ description: "x" }),
headers: { "content-type": "application/x-www-form-urlencoded" },
});
expect(res.status).toBe(302);
expect(res.headers.get("location") || "").toMatch(/^\/login/);
});
it("GET /gists/nonexistent → 404", async () => {
const res = await app.request("/gists/ffffffff");
expect(res.status).toBe(404);
});
it("GET /gists/xxx/edit without auth → 302 /login", async () => {
const res = await app.request("/gists/abc12345/edit");
expect(res.status).toBe(302);
expect(res.headers.get("location") || "").toMatch(/^\/login/);
});
it("POST /gists/xxx/delete without auth → 302 /login", async () => {
const res = await app.request("/gists/abc12345/delete", {
method: "POST",
});
expect(res.status).toBe(302);
expect(res.headers.get("location") || "").toMatch(/^\/login/);
});
it("POST /gists/xxx/star without auth → 302 /login", async () => {
const res = await app.request("/gists/abc12345/star", {
method: "POST",
});
expect(res.status).toBe(302);
expect(res.headers.get("location") || "").toMatch(/^\/login/);
});
});
|