releases.test.ts

3.8 KB · raw

1import { beforeAll, describe, expect, test } from "bun:test";2import { mkdtemp, writeFile } from "node:fs/promises";3import { tmpdir } from "node:os";4import { join } from "node:path";5import { openBucket } from "../src/bucket/reader.ts";6import { type SyncTarget, syncAll } from "../src/bucket/sync.ts";7import { openMirror } from "../src/mirror/store.ts";8import { compareVersions, visibleReleases } from "../src/releases/releases.ts";9import { openKeprDb } from "../src/server/db.ts";10import { makeRepos, writeRelease } from "./fixture.ts";1112const bytes = (text: string) => new TextEncoder().encode(text);1314describe("release reading in sync", () => {15	let bucketDir: string;16	let save: string;17	let target: SyncTarget;18	const releases = () =>19		visibleReleases(target.kepr, openMirror(target.mirrorDir, "app"), "app").map((r) => r.version);20	const lastError = () =>21		(target.kepr.query("SELECT last_sync_error FROM repos").get() as { last_sync_error: string })22			.last_sync_error;2324	beforeAll(async () => {25		const repos = await makeRepos(["app"]);26		bucketDir = repos.bucketDir;27		save = repos.saves.app as string;28		const dataDir = await mkdtemp(join(tmpdir(), "kepr-releases-"));29		target = {30			bucket: openBucket({ kind: "folder", path: bucketDir }),31			kepr: openKeprDb(dataDir),32			mirrorDir: join(dataDir, "mirror"),33			tarballDir: join(dataDir, "tarballs"),34		};35		for (const version of ["1.9.0", "1.10.0", "1.2.3"]) {36			const files = [{ platform: "linux-x86_64", name: "app", bytes: bytes(version) }];37			await writeRelease(bucketDir, "app", { version, save, files }, version === "1.10.0");38		}39		await syncAll(target);40	});4142	test("reads every release.json, newest first by number", () => {43		expect(lastError()).toBeNull();44		expect(releases()).toEqual(["1.10.0", "1.9.0", "1.2.3"]);45	});4647	test("a version folder without release.json does not exist, and nothing is re-read until latest moves", async () => {48		await writeFile(join(bucketDir, "app/releases/2.0.0.tmp"), "half-written");49		const orphan = join(bucketDir, "app/releases/3.0.0/linux-x86_64");50		await Bun.write(join(orphan, "app"), "no record yet");51		await writeRelease(52			bucketDir,53			"app",54			{55				version: "1.11.0",56				save,57				files: [{ platform: "linux-x86_64", name: "app", bytes: bytes("x") }],58			},59			false,60		);61		await syncAll(target);62		expect(releases()).toEqual(["1.10.0", "1.9.0", "1.2.3"]);63		await writeFile(join(bucketDir, "app/releases/latest"), "1.11.0");64		await syncAll(target);65		expect(releases()).toEqual(["1.11.0", "1.10.0", "1.9.0", "1.2.3"]);66	});6768	test("hidden versions drop out and a notes override replaces the record's notes", () => {69		target.kepr.run(70			"INSERT INTO release_settings (repo, version, hidden, notes) VALUES ('app', '1.11.0', 1, NULL), ('app', '1.9.0', 0, 'Operator notes.')",71		);72		const shown = visibleReleases(target.kepr, openMirror(target.mirrorDir, "app"), "app");73		expect(shown.map((r) => [r.version, r.notes])).toEqual([74			["1.10.0", ""],75			["1.9.0", "Operator notes."],76			["1.2.3", ""],77		]);78		target.kepr.run("DELETE FROM release_settings");79	});8081	test("a release record that breaks §11.2 is the repo's last sync error", async () => {82		await writeRelease(bucketDir, "app", {83			version: "1.12.0",84			save,85			files: [{ platform: "plan9-mips", name: "app", bytes: bytes("x") }],86		});87		await syncAll(target);88		expect(lastError()).toContain("release record does not match");89		await writeRelease(bucketDir, "app", {90			version: "1.12.0",91			save,92			files: [{ platform: "linux-x86_64", name: "../app", bytes: bytes("x") }],93		});94		await syncAll(target);95		expect(lastError()).toContain("release record does not match");96	});97});9899test("versions compare as numbers, segment by segment", () => {100	const sorted = ["1.10.0", "1.9.9", "2", "1.9", "0.0.0", "1.10", "10.0.0"].sort(compareVersions);101	expect(sorted).toEqual(["0.0.0", "1.9", "1.9.9", "1.10", "1.10.0", "2", "10.0.0"]);102});