import { randomUUID } from "node:crypto"; import { existsSync } from "node:fs"; import { mkdir, rm, statfs } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { describe, expect, it } from "vitest"; // --------------------------------------------------------------------------- // Unit tests for workspace capacity check (L4) // --------------------------------------------------------------------------- describe("Workspace capacity circuit breaker", () => { /** * We test the logic inline since the checkWorkspaceCapacity function * is not exported. We replicate the core logic here to verify behavior. */ it("skips check when workspace directory does not exist", async () => { const nonExistentPath = join(tmpdir(), `workspace-test-${randomUUID()}`); // The function should not throw if the directory doesn't exist expect(existsSync(nonExistentPath)).toBe(false); }); it("statfs returns valid disk space info for existing directories", async () => { const testDir = join(tmpdir(), `workspace-test-${randomUUID()}`); await mkdir(testDir, { recursive: true }); try { const stats = await statfs(testDir); const freeBytes = stats.bavail * stats.bsize; const freeGB = freeBytes / 1024 ** 3; // The temp directory should have at least some free space expect(freeGB).toBeGreaterThan(0); expect(stats.bavail).toBeGreaterThan(0); expect(stats.bsize).toBeGreaterThan(0); } finally { await rm(testDir, { recursive: true, force: true }); } }); it("correctly calculates GB from statfs values", () => { // Simulate statfs output: 1GB free const mockStats = { bavail: 262144, // blocks available bsize: 4096, // block size }; const freeBytes = mockStats.bavail * mockStats.bsize; const freeGB = freeBytes / 1024 ** 3; // 262144 * 4096 = 1073741824 bytes = 1 GB expect(freeGB).toBe(1); }); it("triggers cleanup threshold at < 1GB free", () => { const freeGB = 0.8; expect(freeGB < 1).toBe(true); }); it("rejects processing at < 0.5GB free", () => { const freeGB = 0.3; const shouldReject = freeGB < 0.5; expect(shouldReject).toBe(true); }); it("allows processing at >= 0.5GB free after cleanup", () => { const freeGB = 0.7; const shouldReject = freeGB < 0.5; expect(shouldReject).toBe(false); }); }); // --------------------------------------------------------------------------- // Unit tests for upload rate limit config presence (M13) // --------------------------------------------------------------------------- describe("Upload route rate limit configuration", () => { it("rate limit config object matches expected shape", () => { // Verify the config object shape used on upload routes const uploadRateLimit = { max: 10, timeWindow: "1 minute" }; expect(uploadRateLimit.max).toBe(10); expect(uploadRateLimit.timeWindow).toBe("1 minute"); }); it("rate limit config has reasonable bounds", () => { const max = 10; // Should be positive and not too high expect(max).toBeGreaterThan(0); expect(max).toBeLessThanOrEqual(100); }); }); // --------------------------------------------------------------------------- // Unit tests for per-user storage quota logic (L3) // --------------------------------------------------------------------------- describe("Per-user storage quota logic", () => { it("calculates quota correctly for MB to bytes conversion", () => { const maxMB = 5000; const limitBytes = maxMB * 1024 * 1024; expect(limitBytes).toBe(5242880000); }); it("identifies exceeded quota", () => { const usedBytes = 5300 * 1024 * 1024; // 5300 MB const limitBytes = 5000 * 1024 * 1024; // 5000 MB expect(usedBytes >= limitBytes).toBe(true); }); it("allows upload within quota", () => { const usedBytes = 3000 * 1024 * 1024; // 3000 MB const limitBytes = 5000 * 1024 * 1024; // 5000 MB expect(usedBytes >= limitBytes).toBe(false); }); it("skips quota check when limit is 0 (unlimited)", () => { const maxStoragePerUserMB = 0; const shouldSkip = maxStoragePerUserMB <= 0; expect(shouldSkip).toBe(true); }); it("formats the error message correctly", () => { const usedBytes = 5300 * 1024 * 1024; const maxMB = 5000; const message = `Storage quota exceeded. Used ${(usedBytes / (1024 * 1024)).toFixed(1)}MB of ${maxMB}MB`; expect(message).toBe("Storage quota exceeded. Used 5300.0MB of 5000MB"); }); });