|
|
@@ -0,0 +1,171 @@
|
|
|
+import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
|
+
|
|
|
+// 1) Mocks
|
|
|
+
|
|
|
+vi.mock("@/lib/db", () => ({
|
|
|
+ default: vi.fn(),
|
|
|
+}));
|
|
|
+
|
|
|
+vi.mock("@/models/user", () => ({
|
|
|
+ default: {
|
|
|
+ findOne: vi.fn(),
|
|
|
+ },
|
|
|
+}));
|
|
|
+
|
|
|
+vi.mock("@/lib/auth/session", () => ({
|
|
|
+ createSession: vi.fn(),
|
|
|
+}));
|
|
|
+
|
|
|
+vi.mock("bcryptjs", () => {
|
|
|
+ const compare = vi.fn();
|
|
|
+ return {
|
|
|
+ default: { compare },
|
|
|
+ compare,
|
|
|
+ };
|
|
|
+});
|
|
|
+
|
|
|
+// 2) Imports NACH den Mocks
|
|
|
+
|
|
|
+import dbConnect from "@/lib/db";
|
|
|
+import User from "@/models/user";
|
|
|
+import { createSession } from "@/lib/auth/session";
|
|
|
+import { compare as bcryptCompare } from "bcryptjs";
|
|
|
+import { POST } from "./route";
|
|
|
+
|
|
|
+function createRequestStub(body) {
|
|
|
+ return {
|
|
|
+ async json() {
|
|
|
+ return body;
|
|
|
+ },
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+describe("POST /api/auth/login", () => {
|
|
|
+ beforeEach(() => {
|
|
|
+ vi.clearAllMocks();
|
|
|
+ dbConnect.mockResolvedValue(undefined);
|
|
|
+ });
|
|
|
+
|
|
|
+ it("logs in successfully with correct credentials", async () => {
|
|
|
+ const user = {
|
|
|
+ _id: "507f1f77bcf86cd799439011",
|
|
|
+ username: "branchuser",
|
|
|
+ passwordHash: "hashed-password",
|
|
|
+ role: "branch",
|
|
|
+ branchId: "NL01",
|
|
|
+ };
|
|
|
+
|
|
|
+ User.findOne.mockReturnValue({
|
|
|
+ exec: vi.fn().mockResolvedValue(user),
|
|
|
+ });
|
|
|
+
|
|
|
+ bcryptCompare.mockResolvedValue(true);
|
|
|
+
|
|
|
+ const request = createRequestStub({
|
|
|
+ username: "BranchUser", // mixed case, should be normalized
|
|
|
+ password: "secret-password",
|
|
|
+ });
|
|
|
+
|
|
|
+ const response = await POST(request);
|
|
|
+ const json = await response.json();
|
|
|
+
|
|
|
+ expect(response.status).toBe(200);
|
|
|
+ expect(json).toEqual({ ok: true });
|
|
|
+
|
|
|
+ expect(dbConnect).toHaveBeenCalledTimes(1);
|
|
|
+ expect(User.findOne).toHaveBeenCalledWith({ username: "branchuser" });
|
|
|
+
|
|
|
+ expect(bcryptCompare).toHaveBeenCalledWith(
|
|
|
+ "secret-password",
|
|
|
+ "hashed-password"
|
|
|
+ );
|
|
|
+
|
|
|
+ expect(createSession).toHaveBeenCalledWith({
|
|
|
+ userId: "507f1f77bcf86cd799439011",
|
|
|
+ role: "branch",
|
|
|
+ branchId: "NL01",
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ it("returns 401 when user does not exist", async () => {
|
|
|
+ User.findOne.mockReturnValue({
|
|
|
+ exec: vi.fn().mockResolvedValue(null),
|
|
|
+ });
|
|
|
+
|
|
|
+ const request = createRequestStub({
|
|
|
+ username: "unknownuser",
|
|
|
+ password: "some-password",
|
|
|
+ });
|
|
|
+
|
|
|
+ const response = await POST(request);
|
|
|
+ const json = await response.json();
|
|
|
+
|
|
|
+ expect(response.status).toBe(401);
|
|
|
+ expect(json).toEqual({ error: "Invalid credentials" });
|
|
|
+
|
|
|
+ expect(createSession).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+
|
|
|
+ it("returns 401 when password is incorrect", async () => {
|
|
|
+ const user = {
|
|
|
+ _id: "507f1f77bcf86cd799439012",
|
|
|
+ username: "branchuser",
|
|
|
+ passwordHash: "hashed-password",
|
|
|
+ role: "branch",
|
|
|
+ branchId: "NL02",
|
|
|
+ };
|
|
|
+
|
|
|
+ User.findOne.mockReturnValue({
|
|
|
+ exec: vi.fn().mockResolvedValue(user),
|
|
|
+ });
|
|
|
+
|
|
|
+ bcryptCompare.mockResolvedValue(false);
|
|
|
+
|
|
|
+ const request = createRequestStub({
|
|
|
+ username: "branchuser",
|
|
|
+ password: "wrong-password",
|
|
|
+ });
|
|
|
+
|
|
|
+ const response = await POST(request);
|
|
|
+ const json = await response.json();
|
|
|
+
|
|
|
+ expect(response.status).toBe(401);
|
|
|
+ expect(json).toEqual({ error: "Invalid credentials" });
|
|
|
+
|
|
|
+ expect(createSession).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+
|
|
|
+ it("returns 400 when username or password is missing", async () => {
|
|
|
+ const request = createRequestStub({
|
|
|
+ username: "only-username",
|
|
|
+ });
|
|
|
+
|
|
|
+ const response = await POST(request);
|
|
|
+ const json = await response.json();
|
|
|
+
|
|
|
+ expect(response.status).toBe(400);
|
|
|
+ expect(json).toEqual({ error: "Missing username or password" });
|
|
|
+
|
|
|
+ expect(User.findOne).not.toHaveBeenCalled();
|
|
|
+ expect(createSession).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+
|
|
|
+ it("returns 500 when an unexpected error occurs", async () => {
|
|
|
+ User.findOne.mockImplementation(() => {
|
|
|
+ throw new Error("DB failure");
|
|
|
+ });
|
|
|
+
|
|
|
+ const request = createRequestStub({
|
|
|
+ username: "branchuser",
|
|
|
+ password: "secret-password",
|
|
|
+ });
|
|
|
+
|
|
|
+ const response = await POST(request);
|
|
|
+ const json = await response.json();
|
|
|
+
|
|
|
+ expect(response.status).toBe(500);
|
|
|
+ expect(json).toEqual({ error: "Internal server error" });
|
|
|
+
|
|
|
+ expect(createSession).not.toHaveBeenCalled();
|
|
|
+ });
|
|
|
+});
|