import assert from "node:assert/strict"; import { mkdir, mkdtemp, readFile, readdir, rm, writeFile } from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import test from "node:test"; import { KeyManager } from "../dist/services/key-manager.js"; import { RepoCounterService } from "../dist/services/repo-counter.js"; async function createHarness(options = {}) { const root = await mkdtemp(path.join(os.tmpdir(), "loc-via-git-test-")); const fixture = path.join(root, "fixture"); const bin = path.join(root, "bin"); const cloneLog = path.join(root, "clone-log"); await mkdir(fixture, { recursive: true }); await mkdir(bin); await writeFile(path.join(bin, "git"), `#!/usr/bin/env node import { appendFileSync, cpSync } from "node:fs"; const args = process.argv.slice(2); const command = args.includes("clone") ? "clone" : args.includes("rev-parse") ? "rev-parse" : "other"; if (command === "clone") { appendFileSync(process.env.LOC_TEST_CLONE_LOG, "clone\\n"); if (process.env.LOC_TEST_HANG === "1") setInterval(() => {}, 1000); cpSync(process.env.LOC_TEST_FIXTURE, args.at(-1), { recursive: true }); } else if (command === "rev-parse") { process.stdout.write("fixture-commit\\n"); } `, { mode: 0o755 }); const config = { allowedGitHosts: ["example.test"], apiKey: "", cacheSweepIntervalMs: 60_000, cacheTtlMs: 60_000, cloneTimeoutMs: 100, defaultSshKeyName: "", generateSshKeyIfMissing: false, maxConcurrentScans: 2, maxFilesPerScan: 100, maxFileSizeBytes: 1024 * 1024, maxScanBytes: 1024 * 1024, port: 3000, rateLimitMax: 30, rateLimitWindowMs: 60_000, sshKeysDir: path.join(root, "keys"), tempRoot: path.join(root, "tmp"), trustProxy: false, ...options }; const originalPath = process.env.PATH; process.env.PATH = `${bin}:${originalPath}`; process.env.LOC_TEST_FIXTURE = fixture; process.env.LOC_TEST_CLONE_LOG = cloneLog; const keyManager = new KeyManager(config); const service = new RepoCounterService(config, keyManager); await keyManager.initialize(); await service.initialize(); return { cloneLog, config, fixture, root, service, async cleanup() { process.env.PATH = originalPath; delete process.env.LOC_TEST_FIXTURE; delete process.env.LOC_TEST_CLONE_LOG; delete process.env.LOC_TEST_HANG; await rm(root, { recursive: true, force: true }); } }; } test("scans fixture repositories, caches duplicate work, and cleans clone directories", async () => { const harness = await createHarness(); try { await writeFile(path.join(harness.fixture, "main.ts"), "const value = 1;\n\nexport { value };\n"); await mkdir(path.join(harness.fixture, "dist")); await writeFile(path.join(harness.fixture, "dist", "bundle.min.js"), "ignored\n"); const request = { repo: "https://example.test/demo.git", ref: null, sshKey: null }; const [first, second] = await Promise.all([harness.service.count(request), harness.service.count(request)]); const third = await harness.service.count(request); assert.equal(first.commit, "fixture-commit"); assert.equal(second.lineCount, 2); assert.equal(third.cached, true); assert.equal((await readFile(harness.cloneLog, "utf8")).trim().split("\n").length, 1); assert.deepEqual(await readdir(harness.config.tempRoot), []); } finally { await harness.cleanup(); } }); test("rejects oversized files and still removes the temporary clone", async () => { const harness = await createHarness({ maxFileSizeBytes: 10 }); try { await writeFile(path.join(harness.fixture, "large.ts"), "export const value = 123;\n"); await assert.rejects( harness.service.count({ repo: "https://example.test/demo.git", ref: null, sshKey: null }), { statusCode: 413 } ); assert.deepEqual(await readdir(harness.config.tempRoot), []); } finally { await harness.cleanup(); } }); test("times out stalled clones and rejects unsupported repository URLs", async () => { const harness = await createHarness({ cloneTimeoutMs: 50 }); try { process.env.LOC_TEST_HANG = "1"; await assert.rejects( harness.service.count({ repo: "https://example.test/demo.git", ref: null, sshKey: null }), { statusCode: 504 } ); await assert.rejects( harness.service.count({ repo: "file:///private/repo", ref: null, sshKey: null }), { statusCode: 400 } ); } finally { await harness.cleanup(); } });