51 lines
3.3 KiB
JavaScript
51 lines
3.3 KiB
JavaScript
#!/usr/bin/env node
|
|
"use strict";
|
|
|
|
const assert = require("assert");
|
|
const fs = require("fs");
|
|
const os = require("os");
|
|
const path = require("path");
|
|
const { zipSync } = require("fflate");
|
|
const { importNativeRoadPackage } = require("./lib/native-road-package");
|
|
|
|
const temp = fs.mkdtempSync(path.join(os.tmpdir(), "native-road-package-"));
|
|
const area = { id: "fixture", nativeRoadPackage: "", outputs: { pipelineDir: path.join(temp, "pipeline") } };
|
|
const layers = ["road_surface", "connectors"];
|
|
const manifest = { contract: "native-road-package/v1.1", areaId: "fixture", layers: [
|
|
{ source: "road_surface", role: "surface", materialLayer: "road_surface" },
|
|
{ source: "connectors", role: "semantic" },
|
|
] };
|
|
function validEntries() {
|
|
return {
|
|
"manifest.json": Buffer.from(JSON.stringify(manifest)),
|
|
"compiled.json": Buffer.from("{}"), "diagnostics.json": Buffer.from("{}"), "comparison.json": Buffer.from("{}"),
|
|
"traffic-signal-assemblies.json": Buffer.from("{}"), "traffic-signals.json": Buffer.from("{}"),
|
|
...Object.fromEntries(layers.map((layer) => [`layers/${layer}.geojson`, Buffer.from('{"type":"FeatureCollection","features":[]}')])),
|
|
};
|
|
}
|
|
function write(name, entries = validEntries()) { const file = path.join(temp, name); fs.writeFileSync(file, zipSync(entries)); area.nativeRoadPackage = file; return file; }
|
|
write("valid.zip");
|
|
const first = importNativeRoadPackage(area);
|
|
assert.equal(first.manifest.areaId, "fixture");
|
|
assert.equal(Object.keys(first.records).length, 8);
|
|
assert.ok(first.rootDir.includes(first.zipRecord.sha256));
|
|
assert.equal(importNativeRoadPackage(area).rootDir, first.rootDir);
|
|
assert.throws(() => { area.nativeRoadPackage = path.join(temp, "missing.zip"); importNativeRoadPackage(area); }, /ZIP not found/);
|
|
write("corrupt.zip", { "manifest.json": Buffer.from("{") });
|
|
assert.throws(() => importNativeRoadPackage(area), /ZIP central directory|Invalid ZIP|Invalid native road manifest|Missing native road ZIP entry/);
|
|
write("nested.zip", { "nested/manifest.json": Buffer.from("{}") });
|
|
assert.throws(() => importNativeRoadPackage(area), /root-flat/);
|
|
write("traversal.zip", { "../manifest.json": Buffer.from("{}") });
|
|
assert.throws(() => importNativeRoadPackage(area), /Unsafe ZIP entry/);
|
|
const wrongContract = validEntries(); wrongContract["manifest.json"] = Buffer.from(JSON.stringify({ ...manifest, contract: "v1" })); write("contract.zip", wrongContract);
|
|
assert.throws(() => importNativeRoadPackage(area), /Unsupported native road contract/);
|
|
const wrongArea = validEntries(); wrongArea["manifest.json"] = Buffer.from(JSON.stringify({ ...manifest, areaId: "other" })); write("area.zip", wrongArea);
|
|
assert.throws(() => importNativeRoadPackage(area), /areaId mismatch/);
|
|
const mismatch = validEntries(); delete mismatch["layers/connectors.geojson"]; write("mismatch.zip", mismatch);
|
|
assert.throws(() => importNativeRoadPackage(area), /manifest\/source mismatch/);
|
|
const symlink = write("symlink.zip");
|
|
const data = fs.readFileSync(symlink); const index = data.indexOf(Buffer.from([0x50, 0x4b, 0x01, 0x02])); data.writeUInt32LE((0xa000 << 16) >>> 0, index + 38); fs.writeFileSync(symlink, data);
|
|
assert.throws(() => importNativeRoadPackage(area), /Symbolic links/);
|
|
fs.rmSync(temp, { recursive: true, force: true });
|
|
console.log("Native road ZIP package tests passed.");
|