70 lines
2.7 KiB
JavaScript
70 lines
2.7 KiB
JavaScript
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import assert from "node:assert/strict";
|
|
import { afterEach, describe, it } from "vitest";
|
|
import { createFeatureManifest, parseArgs, writeFeatureManifest } from "./create-feature-manifest.mjs";
|
|
|
|
const fixtures = [];
|
|
|
|
function createRoot() {
|
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), "feature-manifest-"));
|
|
fixtures.push(root);
|
|
return root;
|
|
}
|
|
|
|
afterEach(() => {
|
|
while (fixtures.length > 0) {
|
|
fs.rmSync(fixtures.pop(), { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
describe("create-feature-manifest", () => {
|
|
it("creates an integration-aware manifest scaffold", () => {
|
|
const manifest = createFeatureManifest({
|
|
id: "customer-health",
|
|
title: "Customer Health",
|
|
classification: "plugin-candidate",
|
|
ownership: "admin-managed",
|
|
lastReviewed: "2026-05-15",
|
|
});
|
|
|
|
assert.equal(manifest.schemaVersion, "1.0");
|
|
assert.equal(manifest.id, "customer-health");
|
|
assert.equal(manifest.pruning.action, "extract-plugin");
|
|
assert.equal(manifest.integration.ownership, "admin-managed");
|
|
assert.deepEqual(Object.keys(manifest.integration.surfaces), ["adminRoutes", "tenantRoutes", "publicRoutes", "apiRoutes"]);
|
|
assert.match(manifest.integration.permissions[0], /^app\./);
|
|
assert.match(manifest.integration.auditEvents[0], /^feature\./);
|
|
assert.equal(manifest.validation.lastReviewed, "2026-05-15");
|
|
});
|
|
|
|
it("writes without overwriting existing manifests unless forced", () => {
|
|
const root = createRoot();
|
|
const args = {
|
|
id: "agent-demo",
|
|
title: "Agent Demo",
|
|
classification: "core",
|
|
ownership: "system-only",
|
|
lastReviewed: "2026-05-15",
|
|
};
|
|
|
|
const first = writeFeatureManifest(args, root);
|
|
assert.equal(path.relative(root, first.target), "docs/feature-manifests/agent-demo.json");
|
|
assert.equal(JSON.parse(fs.readFileSync(first.target, "utf8")).pruning.action, "keep");
|
|
assert.throws(() => writeFeatureManifest(args, root), /already exists/);
|
|
assert.doesNotThrow(() => writeFeatureManifest({ ...args, force: true }, root));
|
|
});
|
|
|
|
it("parses CLI flags and rejects invalid values", () => {
|
|
assert.deepEqual(parseArgs(["--id", "my-feature", "--title", "My Feature", "--force"]), {
|
|
id: "my-feature",
|
|
title: "My Feature",
|
|
force: true,
|
|
});
|
|
assert.throws(() => createFeatureManifest({ id: "Bad_ID", title: "Bad" }), /--id must match/);
|
|
assert.throws(() => createFeatureManifest({ id: "ok", title: "" }), /--title is required/);
|
|
assert.throws(() => createFeatureManifest({ id: "ok", title: "OK", classification: "legacy" }), /--classification must be/);
|
|
});
|
|
});
|