|
|
@@ -1,75 +1,119 @@
|
|
|
-// app/api/branches/[branch]/years/route.test.js
|
|
|
-import { describe, it, expect, beforeAll, afterAll } from "vitest";
|
|
|
+/* @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";
|
|
|
|
|
|
-import { GET as getYears } from "./route.js";
|
|
|
+vi.mock("@/lib/auth/session", () => ({
|
|
|
+ getSession: vi.fn(),
|
|
|
+}));
|
|
|
+
|
|
|
+import { getSession } from "@/lib/auth/session";
|
|
|
+import { GET } from "./route.js";
|
|
|
|
|
|
-let tmpRoot;
|
|
|
+describe("GET /api/branches/[branch]/years", () => {
|
|
|
+ let tmpRoot;
|
|
|
+ const originalNasRoot = process.env.NAS_ROOT_PATH;
|
|
|
|
|
|
-beforeAll(async () => {
|
|
|
- tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), "api-years-"));
|
|
|
- process.env.NAS_ROOT_PATH = tmpRoot;
|
|
|
+ beforeEach(async () => {
|
|
|
+ vi.clearAllMocks();
|
|
|
+ tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), "api-years-"));
|
|
|
+ process.env.NAS_ROOT_PATH = tmpRoot;
|
|
|
|
|
|
- // tmpRoot/NL01/2024
|
|
|
- await fs.mkdir(path.join(tmpRoot, "NL01", "2024"), {
|
|
|
- recursive: true,
|
|
|
+ // Minimal structure for NL01
|
|
|
+ await fs.mkdir(path.join(tmpRoot, "NL01", "2024"), { recursive: true });
|
|
|
});
|
|
|
-});
|
|
|
|
|
|
-afterAll(async () => {
|
|
|
- await fs.rm(tmpRoot, { recursive: true, force: true });
|
|
|
-});
|
|
|
+ afterEach(async () => {
|
|
|
+ process.env.NAS_ROOT_PATH = originalNasRoot;
|
|
|
+ if (tmpRoot) await fs.rm(tmpRoot, { recursive: true, force: true });
|
|
|
+ });
|
|
|
|
|
|
-describe("GET /api/branches/[branch]/years", () => {
|
|
|
- it("returns years for a valid branch", async () => {
|
|
|
- const req = new Request("http://localhost/api/branches/NL01/years");
|
|
|
+ it("returns 401 when unauthenticated", async () => {
|
|
|
+ getSession.mockResolvedValue(null);
|
|
|
|
|
|
- // In Next.js 16, ctx.params is a Promise the framework would resolve.
|
|
|
- // In tests we simulate that.
|
|
|
- const ctx = {
|
|
|
- params: Promise.resolve({ branch: "NL01" }),
|
|
|
- };
|
|
|
+ const res = await GET(
|
|
|
+ new Request("http://localhost/api/branches/NL01/years"),
|
|
|
+ {
|
|
|
+ params: Promise.resolve({ branch: "NL01" }),
|
|
|
+ }
|
|
|
+ );
|
|
|
|
|
|
- const res = await getYears(req, ctx);
|
|
|
- expect(res.status).toBe(200);
|
|
|
+ expect(res.status).toBe(401);
|
|
|
+ expect(await res.json()).toEqual({ error: "Unauthorized" });
|
|
|
+ });
|
|
|
|
|
|
- const body = await res.json();
|
|
|
- expect(body).toEqual({
|
|
|
- branch: "NL01",
|
|
|
- years: ["2024"],
|
|
|
+ it("returns 403 when branch user accesses a different branch", async () => {
|
|
|
+ getSession.mockResolvedValue({
|
|
|
+ role: "branch",
|
|
|
+ branchId: "NL01",
|
|
|
+ userId: "u1",
|
|
|
});
|
|
|
+
|
|
|
+ const res = await GET(
|
|
|
+ new Request("http://localhost/api/branches/NL02/years"),
|
|
|
+ {
|
|
|
+ params: Promise.resolve({ branch: "NL02" }),
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ expect(res.status).toBe(403);
|
|
|
+ expect(await res.json()).toEqual({ error: "Forbidden" });
|
|
|
});
|
|
|
|
|
|
- it("returns 400 when branch param is missing", async () => {
|
|
|
- const req = new Request("http://localhost/api/branches/UNKNOWN/years");
|
|
|
- const ctx = {
|
|
|
- params: Promise.resolve({}), // no branch
|
|
|
- };
|
|
|
+ it("returns years for a valid branch when allowed", async () => {
|
|
|
+ getSession.mockResolvedValue({
|
|
|
+ role: "branch",
|
|
|
+ branchId: "NL01",
|
|
|
+ userId: "u1",
|
|
|
+ });
|
|
|
|
|
|
- const res = await getYears(req, ctx);
|
|
|
- expect(res.status).toBe(400);
|
|
|
+ const res = await GET(
|
|
|
+ new Request("http://localhost/api/branches/NL01/years"),
|
|
|
+ {
|
|
|
+ params: Promise.resolve({ branch: "NL01" }),
|
|
|
+ }
|
|
|
+ );
|
|
|
|
|
|
+ expect(res.status).toBe(200);
|
|
|
const body = await res.json();
|
|
|
- expect(body.error).toBe("branch Parameter fehlt");
|
|
|
+ expect(body).toEqual({ branch: "NL01", years: ["2024"] });
|
|
|
});
|
|
|
|
|
|
- it("returns 500 when NAS_ROOT_PATH is invalid", async () => {
|
|
|
- const originalRoot = process.env.NAS_ROOT_PATH;
|
|
|
+ it("returns 400 when branch param is missing (authenticated)", async () => {
|
|
|
+ getSession.mockResolvedValue({
|
|
|
+ role: "admin",
|
|
|
+ branchId: null,
|
|
|
+ userId: "u2",
|
|
|
+ });
|
|
|
+
|
|
|
+ const res = await GET(new Request("http://localhost/api/branches//years"), {
|
|
|
+ params: Promise.resolve({ branch: undefined }),
|
|
|
+ });
|
|
|
+
|
|
|
+ expect(res.status).toBe(400);
|
|
|
+ expect(await res.json()).toEqual({ error: "branch Parameter fehlt" });
|
|
|
+ });
|
|
|
+
|
|
|
+ it("returns 500 when NAS_ROOT_PATH is invalid (authenticated)", async () => {
|
|
|
+ getSession.mockResolvedValue({
|
|
|
+ role: "admin",
|
|
|
+ branchId: null,
|
|
|
+ userId: "u2",
|
|
|
+ });
|
|
|
+
|
|
|
process.env.NAS_ROOT_PATH = path.join(tmpRoot, "does-not-exist");
|
|
|
|
|
|
- const req = new Request("http://localhost/api/branches/NL01/years");
|
|
|
- const ctx = {
|
|
|
- params: Promise.resolve({ branch: "NL01" }),
|
|
|
- };
|
|
|
+ const res = await GET(
|
|
|
+ new Request("http://localhost/api/branches/NL01/years"),
|
|
|
+ {
|
|
|
+ params: Promise.resolve({ branch: "NL01" }),
|
|
|
+ }
|
|
|
+ );
|
|
|
|
|
|
- const res = await getYears(req, ctx);
|
|
|
expect(res.status).toBe(500);
|
|
|
-
|
|
|
const body = await res.json();
|
|
|
expect(body.error).toContain("Fehler beim Lesen der Jahre:");
|
|
|
-
|
|
|
- process.env.NAS_ROOT_PATH = originalRoot;
|
|
|
});
|
|
|
});
|