// Covers §24's Downloads section: counts per UTC day, the last 30 days per repo or across all, // each repo's totals, the most downloaded files, and dropping days older than 400. import { afterAll, beforeAll, describe, expect, setSystemTime, test } from "bun:test"; import { Browser, type Instance, instance } from "./browser.ts"; import { makeRepos, writeRelease } from "./fixture.ts"; describe("download analytics (§24)", () => { let inst: Instance; let operator: Browser; const at = (iso: string) => setSystemTime(new Date(iso)); const download = (repo: string, platform: string) => inst.app.request(`/${repo}/releases/1.0.0/${platform}`); const page = async (query = "") => (await operator.get(`/admin/downloads${query}`)).text(); beforeAll(async () => { at("2026-09-30T12:00:00Z"); const repos = await makeRepos(["app", "tools"]); for (const repo of ["app", "tools"]) { await writeRelease(repos.bucketDir, repo, { version: "1.0.0", save: repos.saves[repo] as string, files: [ { platform: "linux-x86_64", name: repo, bytes: new Uint8Array([1]) }, { platform: "macos-aarch64", name: repo, bytes: new Uint8Array([2]) }, ], }); } inst = await instance(repos.bucketDir); operator = new Browser(inst.app); await operator.signIn(); for (const repo of ["app", "tools"]) await operator.post(`/admin/repos/${repo}`, { public: "1" }); at("2025-08-01T12:00:00Z"); await download("app", "linux-x86_64"); at("2026-09-28T23:59:00Z"); await download("app", "linux-x86_64"); await download("app", "macos-aarch64"); at("2026-09-30T00:01:00Z"); await download("app", "linux-x86_64"); await download("tools", "linux-x86_64"); }); afterAll(() => setSystemTime()); test("each download counts toward its repo's UTC day, and days past 400 are dropped", () => { const days = inst.kepr .query("SELECT repo, day, count FROM download_days ORDER BY day, repo") .all(); expect(days).toEqual([ { repo: "app", day: "2026-09-28", count: 2 }, { repo: "app", day: "2026-09-30", count: 1 }, { repo: "tools", day: "2026-09-30", count: 1 }, ]); }); test("the section shows 30 days, each repo's totals and the top files", async () => { const html = await page(); expect(html).toContain('\s*]*>4 downloads · 3 in 30 days<\/span>/); expect(html.indexOf("app 1.0.0 linux-x86_64")).toBeLessThan( html.indexOf("tools 1.0.0 linux-x86_64"), ); }); test("one repo narrows the days, and an unknown one narrows nothing", async () => { const tools = await page("?repo=tools"); expect(tools).toContain('