import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { NextRequest } from "next/server"; import { proxy } from "./proxy"; const request = (path: string, cookie = "mega_session=token") => new NextRequest(`http://app.test${path}`, { headers: cookie ? { cookie } : {} }); beforeEach(() => { vi.stubEnv("AUTH_MODE", "users"); vi.stubEnv("NEXT_PUBLIC_POCKETBASE_URL", "http://pb.test"); vi.stubGlobal("fetch", vi.fn(async () => Response.json({ record: { id: "u1", email: "u@example.test", role: "site_user", sites: ["site1"], is_active: true, } }))); }); afterEach(() => { vi.unstubAllGlobals(); vi.unstubAllEnvs(); }); describe("login proxy", () => { it("rejects an anonymous data request", async () => { expect((await proxy(request("/api/sites", ""))).status).toBe(401); }); it("allows clock users into operational pages and APIs", async () => { vi.stubGlobal("fetch", vi.fn(async () => Response.json({ record: { id: "u1", email: "u@example.test", role: "clock_only", sites: ["site1"], is_active: true, } }))); expect((await proxy(request("/api/sites"))).status).toBe(200); expect((await proxy(request("/api/clock/scan"))).status).toBe(200); }); it("blocks a site user from user administration and unknown APIs", async () => { expect((await proxy(request("/api/admin/users/another-user"))).status).toBe(403); expect((await proxy(request("/api/unknown"))).status).toBe(403); }); it("allows site managers into user creation but blocks clock users", async () => { expect((await proxy(request("/api/admin/users"))).status).toBe(200); expect((await proxy(request("/dashboard/settings/users"))).status).toBe(200); vi.stubGlobal("fetch", vi.fn(async () => Response.json({ record: { id: "u1", email: "u@example.test", role: "clock_only", sites: ["site1"], is_active: true, } }))); expect((await proxy(request("/api/admin/users"))).status).toBe(403); }); it("redirects a first-time user before rendering dashboard data", async () => { vi.stubGlobal("fetch", vi.fn(async () => Response.json({ record: { id: "u1", email: "u@example.test", role: "site_user", sites: ["site1"], is_active: true, must_change_password: true, } }))); const response = await proxy(request("/dashboard")); expect(response.status).toBe(307); expect(response.headers.get("location")).toBe("http://app.test/change-password"); }); it("preserves machine routes without a user cookie", async () => { expect((await proxy(request("/api/purchase-orders/ingest", ""))).status).toBe(200); expect(fetch).not.toHaveBeenCalled(); }); });