import { describe, it, expect } from "vitest"; import { runSecretScan, type ScanDeps } from "../../tools/runScan"; const token = () => ["glpat", "-", "Zz9Yy8Xx7Ww6Vv5Uu4Tt"].join(""); function deps(files: Record, over: Partial = {}): ScanDeps { return { listTracked: () => Object.keys(files), readFile: (p) => { if (!(p in files)) throw Object.assign(new Error("ENOENT"), { code: "ENOENT" }); return files[p] as string; }, fileSize: (p) => (files[p] ?? "").length, ...over, }; } describe("runSecretScan", () => { it("exits 0 and says so when nothing is found", () => { const r = runSecretScan({ cwd: "/r" }, deps({ "a.ts": "const a = 1;" })); expect(r).toMatchObject({ exitCode: 0, output: "no secrets found", findings: [] }); }); it("exits 1 and reports file, line and rule without the secret", () => { const secret = token(); const r = runSecretScan({ cwd: "/r" }, deps({ "x/.env": `A=1\nT=${secret}\n`, "ok.md": "fine" })); expect(r.exitCode).toBe(1); expect(r.output).toContain("x/.env:2"); expect(r.output).toContain("gitlab-token"); expect(r.output).not.toContain(secret); }); it("does not read files that are not worth scanning", () => { const read: string[] = []; runSecretScan({ cwd: "/r" }, deps({ "node_modules/a.js": "x", "logo.png": "x", "src/a.ts": "x" }, { readFile: (p) => (read.push(p), "x") })); expect(read).toEqual(["src/a.ts"]); }); it("skips and names files over the size limit", () => { const r = runSecretScan({ cwd: "/r", maxBytes: 10 }, deps({ "big.txt": "x".repeat(50), "s.txt": "ok" })); expect(r.exitCode).toBe(0); expect(r.skipped).toEqual(["big.txt (too large)"]); expect(r.output).toContain("skipped: big.txt (too large)"); }); it("skips a tracked file that cannot be read instead of crashing", () => { const r = runSecretScan({ cwd: "/r" }, deps({ "gone.txt": "x" }, { readFile: () => { throw new Error("EACCES"); } })); expect(r.exitCode).toBe(0); expect(r.skipped).toEqual(["gone.txt (unreadable)"]); }); it("scans only the paths it is given when there are any", () => { const read: string[] = []; runSecretScan({ cwd: "/r", paths: ["b.ts"] }, deps({ "a.ts": "x", "b.ts": "y" }, { readFile: (p) => (read.push(p), "z") })); expect(read).toEqual(["b.ts"]); }); it("exits 2 when the tracked files cannot be listed", () => { const r = runSecretScan({ cwd: "/r" }, deps({}, { listTracked: () => { throw new Error("not a git repository"); } })); expect(r.exitCode).toBe(2); expect(r.output).toBe("cannot list tracked files: not a git repository"); }); });