| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- // app/api/auth/login/route.test.js
- import { describe, it, expect, vi, beforeEach } from "vitest";
- // 1) Mocks
- vi.mock("@/lib/db", () => ({
- getDb: 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 AFTER the mocks
- import { getDb } 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();
- getDb.mockResolvedValue({}); // we only need it to "connect"
- });
- 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(getDb).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 passwordHash is missing (defensive)", async () => {
- User.findOne.mockReturnValue({
- exec: vi.fn().mockResolvedValue({
- _id: "507f1f77bcf86cd799439099",
- username: "branchuser",
- // passwordHash missing on purpose
- role: "branch",
- branchId: "NL01",
- }),
- });
- const request = createRequestStub({
- username: "branchuser",
- password: "secret-password",
- });
- const response = await POST(request);
- const json = await response.json();
- expect(response.status).toBe(401);
- expect(json).toEqual({ error: "Invalid credentials" });
- expect(bcryptCompare).not.toHaveBeenCalled();
- 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();
- });
- });
|