68 lines
2.8 KiB
TypeScript
68 lines
2.8 KiB
TypeScript
import { createHash } from "node:crypto";
|
|
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join, resolve } from "node:path";
|
|
|
|
import { afterEach, describe, expect, it } from "vitest";
|
|
|
|
import { loadConfiguredRuntimeAssets } from "../../apps/api/src/runtime-assets.js";
|
|
|
|
const temporaryDirectories: string[] = [];
|
|
|
|
afterEach(() => {
|
|
for (const directory of temporaryDirectories.splice(0)) {
|
|
if (resolve(directory).startsWith(resolve(tmpdir()))) rmSync(directory, { force: true, recursive: true });
|
|
}
|
|
});
|
|
|
|
function fixture() {
|
|
const base = mkdtempSync(join(tmpdir(), "dada-postv1-assets-"));
|
|
temporaryDirectories.push(base);
|
|
const assetRoot = join(base, "assets");
|
|
const dataRoot = join(base, "data");
|
|
const configFile = join(base, "instance.json");
|
|
const trustedManifestPath = join(base, "trusted-manifest.json");
|
|
const bytes = Buffer.from("synthetic sticker 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 = {
|
|
counts: { dynamic_fonts: 0, dynamic_images: 0, font_panel_items: 0, static_stickers: 1 },
|
|
entries: [entry],
|
|
root_ref: "p0a_runtime_assets",
|
|
schema_version: "DadaRuntimeAssets/v1",
|
|
source: "external_read_only",
|
|
};
|
|
mkdirSync(join(assetRoot, "p0a-static-v1"), { recursive: true });
|
|
writeFileSync(join(assetRoot, entry.relativePath), bytes);
|
|
writeFileSync(join(assetRoot, "manifest.json"), `${JSON.stringify(manifest, null, 2)}\n`);
|
|
writeFileSync(trustedManifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
writeFileSync(configFile, JSON.stringify({ asset_root: assetRoot }));
|
|
return { assetRoot, configFile, dataRoot, trustedManifestPath };
|
|
}
|
|
|
|
describe("POSTV1-06 portable runtime assets", () => {
|
|
it("activates a validated external asset root without exposing its path", () => {
|
|
const input = fixture();
|
|
const loaded = loadConfiguredRuntimeAssets(input);
|
|
|
|
expect(loaded.state).toMatchObject({ configured: true, pause_reason: null, status: "active" });
|
|
expect(loaded.publicAssets?.read("p0a-static-v1", "STK001")?.bytes.toString()).toBe("synthetic sticker bytes");
|
|
expect(JSON.stringify(loaded.state)).not.toContain(input.assetRoot);
|
|
});
|
|
|
|
it("rejects a changed external manifest and leaves unrelated API features available", () => {
|
|
const input = fixture();
|
|
writeFileSync(join(input.assetRoot, "manifest.json"), "{}\n");
|
|
const loaded = loadConfiguredRuntimeAssets(input);
|
|
|
|
expect(loaded.publicAssets).toBeUndefined();
|
|
expect(loaded.state).toMatchObject({ configured: true, pause_reason: "asset_manifest_invalid", status: "unavailable" });
|
|
});
|
|
});
|