import * as fs from "node:fs"; import * as path from "node:path"; import * as os from "node:os"; import { SecurityAuditorAgent } from "../agents/security-auditor.js"; describe("SecurityAuditorAgent", () => { let tempDir: string; beforeEach(() => { tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "ciagent-sec-auditor-test-")); }); afterEach(() => { fs.rmSync(tempDir, { recursive: true, force: true }); }); it("finds hardcoded passwords via mechanical audit", () => { const srcDir = path.join(tempDir, "src"); fs.mkdirSync(srcDir, { recursive: true }); fs.writeFileSync(path.join(srcDir, "config.ts"), 'const password = "secret123";'); const agent = new SecurityAuditorAgent(); const findings = agent.mechanicalAudit(tempDir); expect(findings.length).toBeGreaterThan(0); expect(findings[0].stride_category).toBe("information_disclosure"); expect(findings[0].cwe).toContain("CWE-"); expect(findings[0].severity).toBe("high"); }); it("finds empty catch blocks as repudiation", () => { const srcDir = path.join(tempDir, "src"); fs.mkdirSync(srcDir, { recursive: true }); fs.writeFileSync(path.join(srcDir, "err.ts"), 'try { work(); } catch(e) {}'); const agent = new SecurityAuditorAgent(); const findings = agent.mechanicalAudit(tempDir); const repudiation = findings.filter((f) => f.stride_category === "repudiation"); expect(repudiation.length).toBeGreaterThan(0); }); it("returns empty findings for clean code", () => { const srcDir = path.join(tempDir, "src"); fs.mkdirSync(srcDir, { recursive: true }); fs.writeFileSync(path.join(srcDir, "app.ts"), 'export function main() { return 1; }'); const agent = new SecurityAuditorAgent(); const findings = agent.mechanicalAudit(tempDir); expect(findings).toHaveLength(0); }); it("applies confidence-based disposition", () => { const srcDir = path.join(tempDir, "src"); fs.mkdirSync(srcDir, { recursive: true }); fs.writeFileSync(path.join(srcDir, "api.ts"), 'const api_key = "abc123";'); const agent = new SecurityAuditorAgent(0.5); const findings = agent.mechanicalAudit(tempDir); expect(findings.some((f) => f.disposition === "flag")).toBe(true); }); it("agent name is security-auditor", () => { const agent = new SecurityAuditorAgent(); expect(agent.name).toBe("security-auditor"); }); });