Files
osmWorkflow/scripts/test-native-road-package.js

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.");