v0.2.0: Git-native architecture (#1)

This commit was merged in pull request #1.
This commit is contained in:
2026-05-29 12:59:45 +00:00
parent 9cf5c000d9
commit 6e637e4af0
50 changed files with 5852 additions and 135 deletions
+91
View File
@@ -0,0 +1,91 @@
import * as fs from "node:fs";
import * as path from "node:path";
import * as os from "node:os";
import { SecurityVerification } from "../verification/security.js";
describe("SecurityVerification", () => {
let tempDir: string;
beforeEach(() => {
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "ci-security-test-"));
});
afterEach(() => {
fs.rmSync(tempDir, { recursive: true, force: true });
});
it("passes when no security threats detected", async () => {
const srcDir = path.join(tempDir, "src");
fs.mkdirSync(srcDir, { recursive: true });
fs.writeFileSync(path.join(srcDir, "app.ts"), "export function main() { return 1; }");
fs.writeFileSync(path.join(tempDir, ".gitignore"), "node_modules\n.env\n");
const verifier = new SecurityVerification();
const result = await verifier.verify(tempDir, 1);
expect(result.layer).toBe(3);
expect(result.name).toBe("Security");
const highThreatsCheck = result.checks.find((c) => c.name.includes("High severity"));
expect(highThreatsCheck?.status).toBe("pass");
});
it("detects hardcoded passwords as high severity", async () => {
const srcDir = path.join(tempDir, "src");
fs.mkdirSync(srcDir, { recursive: true });
fs.writeFileSync(path.join(srcDir, "config.ts"), 'const password = "supersecret123";');
fs.writeFileSync(path.join(tempDir, ".gitignore"), "node_modules\n.env\n");
const verifier = new SecurityVerification();
const result = await verifier.verify(tempDir, 1);
const highCheck = result.checks.find((c) => c.name.includes("High severity"));
expect(highCheck?.status).toBe("fail");
});
it("detects hardcoded API keys", async () => {
const srcDir = path.join(tempDir, "src");
fs.mkdirSync(srcDir, { recursive: true });
fs.writeFileSync(path.join(srcDir, "api.ts"), 'const api_key = "abc123def456";');
fs.writeFileSync(path.join(tempDir, ".gitignore"), "node_modules\n.env\n");
const verifier = new SecurityVerification();
const result = await verifier.verify(tempDir, 1);
const highCheck = result.checks.find((c) => c.name.includes("High severity"));
expect(highCheck?.status).toBe("fail");
});
it("detects eval() usage", async () => {
const srcDir = path.join(tempDir, "src");
fs.mkdirSync(srcDir, { recursive: true });
fs.writeFileSync(path.join(srcDir, "eval.ts"), 'function run(code: string) { eval(code); }');
fs.writeFileSync(path.join(tempDir, ".gitignore"), "node_modules\n.env\n");
const verifier = new SecurityVerification();
const result = await verifier.verify(tempDir, 1);
const highCheck = result.checks.find((c) => c.name.includes("High severity"));
expect(highCheck?.status).toBe("fail");
});
it("warns about missing .gitignore patterns", async () => {
const srcDir = path.join(tempDir, "src");
fs.mkdirSync(srcDir, { recursive: true });
fs.writeFileSync(path.join(srcDir, "app.ts"), "export function main() { return 1; }");
fs.writeFileSync(path.join(tempDir, ".gitignore"), "node_modules\n");
const verifier = new SecurityVerification();
const result = await verifier.verify(tempDir, 1);
const gitignoreCheck = result.checks.find((c) => c.name.includes(".gitignore"));
expect(gitignoreCheck?.status).toBe("warning");
});
it("skips checks when no src/ directory", async () => {
const verifier = new SecurityVerification();
const result = await verifier.verify(tempDir, 1);
const lowCheck = result.checks.find((c) => c.name.includes("Low severity"));
expect(lowCheck?.status).toBe("pass");
});
});