import { readFile } from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { describe, expect, it } from "vitest"; import { parseSha256File, parseVerifyModulePackageArguments, readModulePackagePlatform, } from "../src/cli/verify-module-package.js"; const repositoryRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", ".."); const digest = "ab".repeat(32); describe("verify-module-package arguments", () => { it("takes an archive and, optionally, a digest and an extraction directory", () => { expect(parseVerifyModulePackageArguments(["example-0.1.0-any.tar.gz"])).toEqual({ archivePath: "example-0.1.0-any.tar.gz", }); expect( parseVerifyModulePackageArguments([ "x.tar.gz", "--sha256", digest.toUpperCase(), "--extract-to", "/staging/example", ]), ).toEqual({ archivePath: "x.tar.gz", expectedSha256: digest, extractTo: "/staging/example" }); expect( parseVerifyModulePackageArguments(["x.tar.gz", "--sha256-file", "x.tar.gz.sha256"]), ).toEqual({ archivePath: "x.tar.gz", sha256File: "x.tar.gz.sha256" }); }); it.each([ ["no archive", []], ["two archives", ["a.tar.gz", "b.tar.gz"]], ["an unknown option", ["a.tar.gz", "--force"]], ["both digest options", ["a.tar.gz", "--sha256", digest, "--sha256-file", "a.sha256"]], ["a malformed digest", ["a.tar.gz", "--sha256", "abc"]], ["an option without its value", ["a.tar.gz", "--extract-to"]], ])("refuses %s", (_label, argv) => { expect(() => parseVerifyModulePackageArguments(argv)).toThrow(); }); }); describe("verify-module-package digest files", () => { it("reads the sha256sum format, ignoring the recorded file name", () => { expect(parseSha256File(`${digest} example-0.1.0-any.tar.gz\n`)).toBe(digest); expect(parseSha256File(`${digest.toUpperCase()} *renamed.tar.gz\n`)).toBe(digest); }); it.each([ "", "not-a-digest x.tar.gz\n", `${digest}\n${digest} second\n`, ])("refuses %j", (contents) => { expect(() => parseSha256File(contents)).toThrow(); }); }); describe("verify-module-package platform facts", () => { it("reads this platform's versions and its transitional database runtime from the repository", async () => { const root = JSON.parse(await readFile(path.join(repositoryRoot, "package.json"), "utf8")); const core = JSON.parse( await readFile(path.join(repositoryRoot, "core", "package.json"), "utf8"), ); const sdk = JSON.parse( await readFile(path.join(repositoryRoot, "packages", "module-sdk", "package.json"), "utf8"), ); await expect(readModulePackagePlatform(repositoryRoot)).resolves.toEqual({ databaseRuntime: { "drizzle-orm": core.dependencies["drizzle-orm"] }, moduleSdkVersion: sdk.version, platformVersion: root.version, }); }); });