Files
chlova/orchestrator/test/artifact-writer.test.ts
T
Kantin-Petit d1255b926b feat: ArtifactWriter auto-extension (artefact + doc) (v0.25.0)
Écrit un asset auto-créé (workflow/outil) + sa doc générée depuis le
gabarit, chemins sanitizés (anti-traversée), semver validé. 5 tests
(dépôt temp). Le dépôt fait foi avant tout passage en need-review.

Palier de risque : reversible (écriture fichier locale, sans commit ni exécution).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 06:32:49 +02:00

61 lines
1.9 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach } from "vitest";
import { mkdtemp, rm, readFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import {
slugify,
artifactRelPath,
docRelPath,
writeArtifact,
type AssetDraft,
} from "../src/autoext/artifact-writer.js";
const draft = (over: Partial<AssetDraft> = {}): AssetDraft => ({
type: "workflow-n8n",
name: "Backup Nextcloud",
version: "1.0.0",
riskTier: "privileged",
summary: "Sauvegarde quotidienne.",
content: '{"name":"x"}',
...over,
});
let root: string;
beforeEach(async () => {
root = await mkdtemp(join(tmpdir(), "chlova-"));
});
afterEach(async () => {
await rm(root, { recursive: true, force: true });
});
describe("slugify & chemins", () => {
it("slugifie un nom accentué", () => {
expect(slugify("Sauvegarde Été #2")).toBe("sauvegarde-ete-2");
});
it("refuse un nom vide", () => {
expect(() => slugify(" ")).toThrow();
});
it("chemins par type", () => {
expect(artifactRelPath(draft())).toBe("workflows-n8n/backup-nextcloud.v1.0.0.json");
expect(artifactRelPath(draft({ type: "tool" }))).toBe("tools/backup-nextcloud.v1.0.0.json");
expect(docRelPath(draft())).toBe("docs/assets/workflow-n8n-backup-nextcloud.md");
});
});
describe("writeArtifact", () => {
it("écrit artefact + doc", async () => {
const { artifactPath, docPath } = await writeArtifact(root, draft());
expect(await readFile(join(root, artifactPath), "utf8")).toBe('{"name":"x"}');
const doc = await readFile(join(root, docPath), "utf8");
expect(doc).toContain("Backup Nextcloud");
expect(doc).toContain("v1.0.0");
expect(doc).toContain("bloqué"); // privilégié → bloqué
});
it("refuse une version non semver", async () => {
await expect(writeArtifact(root, draft({ version: "1.0" }))).rejects.toThrow(/semver/);
});
});