UNPKG

@cyclonedx/cdxgen

Version:

Creates CycloneDX Software Bill of Materials (SBOM) from source or container image

107 lines (100 loc) 4.2 kB
import { assert, describe, it } from "poku"; import { collectAiOversight } from "./aiOversightCollector.js"; import { collectAiProvenance } from "./aiProvenanceCollector.js"; // Integration tests that run the AI provenance/oversight collectors against the // cdxgen repository itself (process.cwd() when poku executes). The repo commits // AI-assistant config files (AGENTS.md, .github/copilot-instructions.md), so // code-authorship detection is deterministic regardless of git history depth or // network access. Oversight is asserted only for structural validity because it // depends on git-ai notes / forge data that may be absent in CI. const REPO_DIR = process.cwd(); describe("AI provenance collector (cdxgen repo)", () => { it("detects AI authorship from committed config files", () => { const result = collectAiProvenance(REPO_DIR); assert.strictEqual( result.detected, true, "AI provenance should be detected", ); assert.ok(Array.isArray(result.tools), "tools should be an array"); assert.ok( result.tools.length > 0, "at least one AI tool should be detected", ); assert.ok( result.tools.includes("github-copilot"), "github-copilot should be detected from .github/copilot-instructions.md", ); assert.ok( ["low", "medium", "high"].includes(result.band), `confidence band should be a known value, got ${result.band}`, ); }); it("emits well-formed cdx:ai:codegen properties", () => { const result = collectAiProvenance(REPO_DIR); const byName = new Map(result.properties.map((p) => [p.name, p.value])); assert.strictEqual(byName.get("cdx:ai:codegen:detected"), "true"); const confidence = Number.parseFloat( byName.get("cdx:ai:codegen:confidence"), ); assert.ok( confidence > 0 && confidence <= 0.99, `confidence should be within (0, 0.99], got ${confidence}`, ); assert.ok( byName.has("cdx:ai:codegen:tools"), "tools property should be present", ); // The evidence blob must be a valid, non-empty JSON array of signals. const evidence = byName.get("cdx:ai:codegen:evidence:json"); assert.ok(evidence, "evidence:json property should be present"); const signals = JSON.parse(evidence); assert.ok(Array.isArray(signals) && signals.length > 0); for (const sig of signals) { assert.ok(sig.channel && sig.tool, "each signal has a channel and tool"); } }); it("computes structurally valid oversight results (git-only)", async () => { // Force git-only mode so the test never depends on forge network access. const prevGh = process.env.GITHUB_TOKEN; const prevGl = process.env.GITLAB_TOKEN; delete process.env.GITHUB_TOKEN; delete process.env.GITLAB_TOKEN; try { const result = await collectAiOversight(REPO_DIR); assert.ok( ["strong", "moderate", "weak"].includes(result.band), `band should be a known value, got ${result.band}`, ); assert.ok( typeof result.score === "number" && result.score >= 0 && result.score <= 1, "score should be within [0, 1]", ); // When AI commits are found, review-dependent metrics must be honest // (unavailable) in git-only mode and properties must be well-formed. if (result.properties.length > 0) { const byName = new Map(result.properties.map((p) => [p.name, p.value])); assert.strictEqual( byName.get("cdx:ai:oversight:reviewCoverage"), "unavailable", "review coverage must be unavailable without forge data", ); const dataSources = byName.get("cdx:ai:oversight:dataSources") || ""; assert.ok( dataSources.split(",").includes("git"), "git must be listed as a data source", ); assert.ok( !dataSources.includes("github-api") && !dataSources.includes("gitlab-api"), "no forge data sources in git-only mode", ); } } finally { if (prevGh !== undefined) process.env.GITHUB_TOKEN = prevGh; if (prevGl !== undefined) process.env.GITLAB_TOKEN = prevGl; } }); });