import type { Database } from "bun:sqlite"; import { beforeAll, describe, expect, test } from "bun:test"; import { mkdir, mkdtemp, unlink, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import type { Hono } from "hono"; import { openBucket } from "../src/bucket/reader.ts"; import { syncAll } from "../src/bucket/sync.ts"; import { openMirror } from "../src/mirror/store.ts"; import { createApp } from "../src/server/app.ts"; import { openKeprDb } from "../src/server/db.ts"; import { makeRepos } from "./fixture.ts"; let app: Hono; let kepr: Database; let dataDir: string; let alphaSaves: { id: string; message: string; is_checkpoint: boolean }[]; let vaultSave: string; const body = async (path: string) => (await app.request(path)).text(); // alpha (public): a save, a checkpoint holding a draft no real save keeps, then a second save. // vault (private): one save whose message, category, language and ID must never show. beforeAll(async () => { const repos = await makeRepos(["alpha", "vault"]); const root = join(repos.bucketDir, ".."); await writeFile(join(root, "work/alpha/draft.txt"), "a draft only a checkpoint holds\n"); repos.koh("alpha", "checkpoint", "checkpoint message never shown"); await unlink(join(root, "work/alpha/draft.txt")); await writeFile(join(root, "work/alpha/README.md"), "# alpha\n\nThe alpha project, grown.\n"); await writeFile(join(root, "work/alpha/main.ts"), "export const a = 1;\n"); repos.koh("alpha", "save", "grow alpha"); // HEAD is a checkpoint adding a new language: none of it may reach a public stat. await writeFile(join(root, "work/alpha/tool.py"), "print(1)\n"); repos.koh("alpha", "checkpoint", "checkpoint at head adds python"); repos.koh("alpha", "offer"); await writeFile(join(root, "work/vault/main.zig"), "const x = 1;\n"); repos.koh("vault", "save", "vault message"); alphaSaves = JSON.parse(repos.koh("alpha", "view", "--json")).saves; vaultSave = JSON.parse(repos.koh("vault", "view", "--json")).head_id; dataDir = await mkdtemp(join(tmpdir(), "kepr-front-")); kepr = openKeprDb(dataDir); const bucket = openBucket({ kind: "folder", path: repos.bucketDir }); await syncAll({ bucket, kepr, mirrorDir: join(dataDir, "mirror"), }); kepr.run("UPDATE repos SET public = 1, category = 'tools' WHERE name = 'alpha'"); kepr.run("UPDATE repos SET category = 'secretcat' WHERE name = 'vault'"); for (const [key, value] of [ ["handle", "ada"], ["tagline", "A library of small tools."], ["bio", "Writes small tools."], ["location", "Lisbon"], ["link", "https://ada.example"], ["building_since", "may 2026"], ]) { kepr.query("INSERT INTO settings (key, value) VALUES (?, ?)").run(key, value); } kepr.run( `INSERT INTO issues (repo, number, title, body, type, filed_at, hidden) VALUES ('alpha', 1, 'a', 'b', 'bug', 1, 0), ('alpha', 2, 'c', 'd', 'bug', 1, 1), ('vault', 1, 'e', 'f', 'bug', 1, 0)`, ); kepr.run( `INSERT INTO downloads (repo, version, platform, count) VALUES ('alpha', '1.0.0', 'linux-x86_64', 7), ('alpha', '0.9.0', 'linux-x86_64', 100), ('vault', '1.0.0', 'linux-x86_64', 1000)`, ); kepr.run("INSERT INTO release_settings (repo, version, hidden) VALUES ('alpha', '0.9.0', 1)"); app = createApp( { domain: "kepr.example", dataDir, adminPasswordHash: "$argon2id$x", bucket: { kind: "folder", path: repos.bucketDir }, }, kepr, ); }); const checkpoints = () => alphaSaves.filter((save) => save.is_checkpoint).map((save) => save.id); const realSaves = () => alphaSaves.filter((save) => !save.is_checkpoint); describe("front page", () => { test("counts distinct objects of public repos' real saves only", async () => { // alpha's real saves hold .kohignore, two READMEs and main.ts; its mirror also holds the // draft and tool.py only checkpoints kept, and the private repo's objects are elsewhere. const mirror = openMirror(join(dataDir, "mirror"), "alpha"); expect(mirror.query("SELECT COUNT(*) AS n FROM objects").get()).toEqual({ n: 6 }); expect(await body("/")).toContain("The library knows
4 things."); }); test("the ticker, cloud and cards show public saves, never checkpoints or private repos", async () => { const html = await body("/"); expect(html).toContain('