import assert from "node:assert/strict"; import { createHash } from "node:crypto"; import { mkdir, mkdtemp, readFile, rm, stat, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import test from "node:test"; import { createRuntimeAssetManifest, deployRuntimeAssetPlan, readRuntimeAssetManifest, serializeRuntimeAssetManifest, } from "../../scripts/lib/runtime-assets.mjs"; test("committed P0-A runtime manifest covers the frozen first-version binary assets", () => { const manifest = readRuntimeAssetManifest("config/runtime-assets-manifest.json"); assert.deepEqual(manifest.counts, { dynamic_fonts: 7, dynamic_images: 8, font_panel_items: 11, static_stickers: 1407, }); assert.equal(manifest.entries.length, 1433); assert.doesNotMatch(serializeRuntimeAssetManifest(manifest), /[A-Za-z]:[\\/]/); }); test("runtime asset deployment creates verified hardlinks and a path-free manifest", async (t) => { const root = await mkdtemp(join(tmpdir(), "dada-runtime-assets-")); t.after(() => rm(root, { force: true, recursive: true })); const sourceRoot = join(root, "source"); const assetRoot = join(root, "assets"); const sourcePath = join(sourceRoot, "sticker.png"); const bytes = Buffer.from("runtime asset fixture"); await mkdir(sourceRoot); await writeFile(sourcePath, bytes); const entry = { assetId: "STK001", mimeType: "image/png", relativePath: "p0a-static-v1/STK001.png", resourceVersion: "p0a-static-v1", rootRef: "p0a_runtime_assets", sha256: createHash("sha256").update(bytes).digest("hex"), }; const manifest = createRuntimeAssetManifest({ counts: { dynamic_fonts: 0, dynamic_images: 0, font_panel_items: 0, static_stickers: 1 }, entries: [entry], }); await deployRuntimeAssetPlan({ assetRoot, manifest, resources: [{ entry, sourcePath }] }); const targetPath = join(assetRoot, entry.relativePath); const [sourceStat, targetStat] = await Promise.all([stat(sourcePath), stat(targetPath)]); assert.equal(sourceStat.ino, targetStat.ino); assert.deepEqual(await readFile(targetPath), bytes); const writtenManifest = await readFile(join(assetRoot, "manifest.json"), "utf8"); assert.deepEqual(JSON.parse(writtenManifest), manifest); assert.doesNotMatch(writtenManifest, /[A-Za-z]:[\\/]/); }); test("runtime asset deployment refuses a mismatched existing target", async (t) => { const root = await mkdtemp(join(tmpdir(), "dada-runtime-assets-conflict-")); t.after(() => rm(root, { force: true, recursive: true })); const sourcePath = join(root, "source.png"); const assetRoot = join(root, "assets"); const targetPath = join(assetRoot, "p0a-static-v1", "STK001.png"); await mkdir(join(assetRoot, "p0a-static-v1"), { recursive: true }); await writeFile(sourcePath, "expected"); await writeFile(targetPath, "unexpected"); const entry = { assetId: "STK001", mimeType: "image/png", relativePath: "p0a-static-v1/STK001.png", resourceVersion: "p0a-static-v1", rootRef: "p0a_runtime_assets", sha256: createHash("sha256").update("expected").digest("hex"), }; const manifest = createRuntimeAssetManifest({ counts: { dynamic_fonts: 0, dynamic_images: 0, font_panel_items: 0, static_stickers: 1 }, entries: [entry], }); assert.throws( () => deployRuntimeAssetPlan({ assetRoot, manifest, resources: [{ entry, sourcePath }] }), /asset_target_conflict/, ); });