87 lines
3.2 KiB
JavaScript
87 lines
3.2 KiB
JavaScript
"use strict";
|
|
|
|
const test = require("node:test");
|
|
const assert = require("node:assert/strict");
|
|
const { createHash } = require("node:crypto");
|
|
const { mkdtemp, readFile, rm } = require("node:fs/promises");
|
|
const os = require("node:os");
|
|
const path = require("node:path");
|
|
const { inflateRawSync } = require("node:zlib");
|
|
const {
|
|
ARCHIVE_FILES,
|
|
normalizeVersion,
|
|
packageExtension
|
|
} = require("../scripts/package-extension.js");
|
|
|
|
function readZipEntries(archive) {
|
|
const entries = new Map();
|
|
let offset = 0;
|
|
|
|
while (archive.readUInt32LE(offset) === 0x04034b50) {
|
|
const method = archive.readUInt16LE(offset + 8);
|
|
const compressedSize = archive.readUInt32LE(offset + 18);
|
|
const nameLength = archive.readUInt16LE(offset + 26);
|
|
const extraLength = archive.readUInt16LE(offset + 28);
|
|
const nameStart = offset + 30;
|
|
const dataStart = nameStart + nameLength + extraLength;
|
|
const name = archive.subarray(nameStart, nameStart + nameLength).toString("utf8");
|
|
const compressed = archive.subarray(dataStart, dataStart + compressedSize);
|
|
|
|
assert.equal(method, 8, `${name} should use DEFLATE compression`);
|
|
entries.set(name, inflateRawSync(compressed));
|
|
offset = dataStart + compressedSize;
|
|
}
|
|
|
|
assert.equal(archive.readUInt32LE(offset), 0x02014b50, "central directory is present");
|
|
return entries;
|
|
}
|
|
|
|
test("normalizes release tags and rejects versions Firefox cannot publish", () => {
|
|
assert.equal(normalizeVersion("1.2.3"), "1.2.3");
|
|
assert.equal(normalizeVersion("v2.0"), "2.0");
|
|
assert.equal(normalizeVersion("V3"), "3");
|
|
|
|
for (const version of ["", "v", "1.2.3.4.5", "1.02", "1.0-beta", "1000000000"]) {
|
|
assert.throws(() => normalizeVersion(version), /Invalid Mozilla extension version|required/);
|
|
}
|
|
});
|
|
|
|
test("builds a deterministic unsigned XPI with the release version and runtime files only", async (context) => {
|
|
const rootDirectory = path.resolve(__dirname, "..");
|
|
const firstOutput = await mkdtemp(path.join(os.tmpdir(), "glagolify-package-"));
|
|
const secondOutput = await mkdtemp(path.join(os.tmpdir(), "glagolify-package-"));
|
|
context.after(async () => {
|
|
await Promise.all([
|
|
rm(firstOutput, { recursive: true, force: true }),
|
|
rm(secondOutput, { recursive: true, force: true })
|
|
]);
|
|
});
|
|
|
|
const first = await packageExtension({
|
|
rootDirectory,
|
|
outputDirectory: firstOutput,
|
|
version: "v9.8.7"
|
|
});
|
|
const second = await packageExtension({
|
|
rootDirectory,
|
|
outputDirectory: secondOutput,
|
|
version: "9.8.7"
|
|
});
|
|
const firstArchive = await readFile(first.archivePath);
|
|
const secondArchive = await readFile(second.archivePath);
|
|
const entries = readZipEntries(firstArchive);
|
|
|
|
assert.equal(first.archiveName, "glagolify-9.8.7.xpi");
|
|
assert.deepEqual([...entries.keys()], [...ARCHIVE_FILES]);
|
|
assert.equal(JSON.parse(entries.get("manifest.json")).version, "9.8.7");
|
|
assert.equal(entries.has("package.json"), false);
|
|
assert.equal(entries.has("tests/package-extension.test.js"), false);
|
|
assert.deepEqual(firstArchive, secondArchive);
|
|
|
|
const digest = createHash("sha256").update(firstArchive).digest("hex");
|
|
assert.equal(
|
|
await readFile(first.checksumPath, "utf8"),
|
|
`${digest} glagolify-9.8.7.xpi\n`
|
|
);
|
|
});
|