/* @vitest-environment node */ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; vi.mock("@/lib/auth/session", () => ({ getSession: vi.fn(), })); import { getSession } from "@/lib/auth/session"; import { GET, dynamic } from "./route.js"; describe("GET /api/files", () => { let tmpRoot; const originalNasRoot = process.env.NAS_ROOT_PATH; beforeEach(async () => { vi.clearAllMocks(); tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), "api-files-")); process.env.NAS_ROOT_PATH = tmpRoot; const dir = path.join(tmpRoot, "NL01", "2024", "10", "23"); await fs.mkdir(dir, { recursive: true }); await fs.writeFile(path.join(dir, "test.pdf"), "dummy-pdf-content"); }); afterEach(async () => { process.env.NAS_ROOT_PATH = originalNasRoot; if (tmpRoot) await fs.rm(tmpRoot, { recursive: true, force: true }); }); it('exports dynamic="force-dynamic" (RHL-006)', () => { expect(dynamic).toBe("force-dynamic"); }); it("returns 401 when unauthenticated", async () => { getSession.mockResolvedValue(null); const req = new Request( "http://localhost/api/files?branch=NL01&year=2024&month=10&day=23" ); const res = await GET(req); expect(res.status).toBe(401); expect(await res.json()).toEqual({ error: { message: "Unauthorized", code: "AUTH_UNAUTHENTICATED" }, }); }); it("returns 403 when branch user accesses a different branch", async () => { getSession.mockResolvedValue({ role: "branch", branchId: "NL01", userId: "u1", }); const req = new Request( "http://localhost/api/files?branch=NL02&year=2024&month=10&day=23" ); const res = await GET(req); expect(res.status).toBe(403); expect(await res.json()).toEqual({ error: { message: "Forbidden", code: "AUTH_FORBIDDEN_BRANCH" }, }); }); it("returns files for a valid query when allowed", async () => { getSession.mockResolvedValue({ role: "branch", branchId: "NL01", userId: "u1", }); const req = new Request( "http://localhost/api/files?branch=NL01&year=2024&month=10&day=23" ); const res = await GET(req); expect(res.status).toBe(200); const body = await res.json(); expect(body.branch).toBe("NL01"); expect(body.files).toHaveLength(1); expect(body.files[0]).toMatchObject({ name: "test.pdf", relativePath: "NL01/2024/10/23/test.pdf", }); }); it("returns 400 when query params are missing (authenticated)", async () => { getSession.mockResolvedValue({ role: "admin", branchId: null, userId: "u2", }); const req = new Request("http://localhost/api/files"); const res = await GET(req); expect(res.status).toBe(400); const body = await res.json(); expect(body).toEqual({ error: { message: "Missing required query parameter(s)", code: "VALIDATION_MISSING_QUERY", details: { params: ["branch", "year", "month", "day"] }, }, }); }); it("returns 404 when the day folder does not exist (authorized)", async () => { getSession.mockResolvedValue({ role: "admin", branchId: null, userId: "u2", }); const req = new Request( "http://localhost/api/files?branch=NL01&year=2024&month=10&day=99" ); const res = await GET(req); expect(res.status).toBe(404); expect(await res.json()).toEqual({ error: { message: "Not found", code: "FS_NOT_FOUND", details: { branch: "NL01", year: "2024", month: "10", day: "99" }, }, }); }); });