downloads.test.ts

2.9 KB · raw

1// Covers §24's Downloads section: counts per UTC day, the last 30 days per repo or across all,2// each repo's totals, the most downloaded files, and dropping days older than 400.34import { afterAll, beforeAll, describe, expect, setSystemTime, test } from "bun:test";5import { Browser, type Instance, instance } from "./browser.ts";6import { makeRepos, writeRelease } from "./fixture.ts";78describe("download analytics (§24)", () => {9	let inst: Instance;10	let operator: Browser;11	const at = (iso: string) => setSystemTime(new Date(iso));12	const download = (repo: string, platform: string) =>13		inst.app.request(`/${repo}/releases/1.0.0/${platform}`);14	const page = async (query = "") => (await operator.get(`/admin/downloads${query}`)).text();1516	beforeAll(async () => {17		at("2026-09-30T12:00:00Z");18		const repos = await makeRepos(["app", "tools"]);19		for (const repo of ["app", "tools"]) {20			await writeRelease(repos.bucketDir, repo, {21				version: "1.0.0",22				save: repos.saves[repo] as string,23				files: [24					{ platform: "linux-x86_64", name: repo, bytes: new Uint8Array([1]) },25					{ platform: "macos-aarch64", name: repo, bytes: new Uint8Array([2]) },26				],27			});28		}29		inst = await instance(repos.bucketDir);30		operator = new Browser(inst.app);31		await operator.signIn();32		for (const repo of ["app", "tools"])33			await operator.post(`/admin/repos/${repo}`, { public: "1" });34		at("2025-08-01T12:00:00Z");35		await download("app", "linux-x86_64");36		at("2026-09-28T23:59:00Z");37		await download("app", "linux-x86_64");38		await download("app", "macos-aarch64");39		at("2026-09-30T00:01:00Z");40		await download("app", "linux-x86_64");41		await download("tools", "linux-x86_64");42	});43	afterAll(() => setSystemTime());4445	test("each download counts toward its repo's UTC day, and days past 400 are dropped", () => {46		const days = inst.kepr47			.query("SELECT repo, day, count FROM download_days ORDER BY day, repo")48			.all();49		expect(days).toEqual([50			{ repo: "app", day: "2026-09-28", count: 2 },51			{ repo: "app", day: "2026-09-30", count: 1 },52			{ repo: "tools", day: "2026-09-30", count: 1 },53		]);54	});5556	test("the section shows 30 days, each repo's totals and the top files", async () => {57		const html = await page();58		expect(html).toContain('<meter min="0" max="2" value="2"');59		expect(html).toContain("2026-09-28");60		expect(html).not.toContain("2026-08-31");61		expect(html).toContain("2026-09-01");62		expect(html).toMatch(/app<\/a>\s*<span[^>]*>4 downloads · 3 in 30 days<\/span>/);63		expect(html.indexOf("app 1.0.0 linux-x86_64")).toBeLessThan(64			html.indexOf("tools 1.0.0 linux-x86_64"),65		);66	});6768	test("one repo narrows the days, and an unknown one narrows nothing", async () => {69		const tools = await page("?repo=tools");70		expect(tools).toContain('<meter min="0" max="1" value="1"');71		expect(tools).not.toContain('value="2"');72		expect(await page("?repo=nowhere")).toContain('<meter min="0" max="2" value="2"');73	});74});