route.test.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import { describe, it, expect, vi, beforeEach } from "vitest";
  2. // 1) Mocks
  3. vi.mock("@/lib/db", () => ({
  4. default: vi.fn(),
  5. }));
  6. vi.mock("@/models/user", () => ({
  7. default: {
  8. findOne: vi.fn(),
  9. },
  10. }));
  11. vi.mock("@/lib/auth/session", () => ({
  12. createSession: vi.fn(),
  13. }));
  14. vi.mock("bcryptjs", () => {
  15. const compare = vi.fn();
  16. return {
  17. default: { compare },
  18. compare,
  19. };
  20. });
  21. // 2) Imports NACH den Mocks
  22. import dbConnect from "@/lib/db";
  23. import User from "@/models/user";
  24. import { createSession } from "@/lib/auth/session";
  25. import { compare as bcryptCompare } from "bcryptjs";
  26. import { POST } from "./route";
  27. function createRequestStub(body) {
  28. return {
  29. async json() {
  30. return body;
  31. },
  32. };
  33. }
  34. describe("POST /api/auth/login", () => {
  35. beforeEach(() => {
  36. vi.clearAllMocks();
  37. dbConnect.mockResolvedValue(undefined);
  38. });
  39. it("logs in successfully with correct credentials", async () => {
  40. const user = {
  41. _id: "507f1f77bcf86cd799439011",
  42. username: "branchuser",
  43. passwordHash: "hashed-password",
  44. role: "branch",
  45. branchId: "NL01",
  46. };
  47. User.findOne.mockReturnValue({
  48. exec: vi.fn().mockResolvedValue(user),
  49. });
  50. bcryptCompare.mockResolvedValue(true);
  51. const request = createRequestStub({
  52. username: "BranchUser", // mixed case, should be normalized
  53. password: "secret-password",
  54. });
  55. const response = await POST(request);
  56. const json = await response.json();
  57. expect(response.status).toBe(200);
  58. expect(json).toEqual({ ok: true });
  59. expect(dbConnect).toHaveBeenCalledTimes(1);
  60. expect(User.findOne).toHaveBeenCalledWith({ username: "branchuser" });
  61. expect(bcryptCompare).toHaveBeenCalledWith(
  62. "secret-password",
  63. "hashed-password"
  64. );
  65. expect(createSession).toHaveBeenCalledWith({
  66. userId: "507f1f77bcf86cd799439011",
  67. role: "branch",
  68. branchId: "NL01",
  69. });
  70. });
  71. it("returns 401 when user does not exist", async () => {
  72. User.findOne.mockReturnValue({
  73. exec: vi.fn().mockResolvedValue(null),
  74. });
  75. const request = createRequestStub({
  76. username: "unknownuser",
  77. password: "some-password",
  78. });
  79. const response = await POST(request);
  80. const json = await response.json();
  81. expect(response.status).toBe(401);
  82. expect(json).toEqual({ error: "Invalid credentials" });
  83. expect(createSession).not.toHaveBeenCalled();
  84. });
  85. it("returns 401 when password is incorrect", async () => {
  86. const user = {
  87. _id: "507f1f77bcf86cd799439012",
  88. username: "branchuser",
  89. passwordHash: "hashed-password",
  90. role: "branch",
  91. branchId: "NL02",
  92. };
  93. User.findOne.mockReturnValue({
  94. exec: vi.fn().mockResolvedValue(user),
  95. });
  96. bcryptCompare.mockResolvedValue(false);
  97. const request = createRequestStub({
  98. username: "branchuser",
  99. password: "wrong-password",
  100. });
  101. const response = await POST(request);
  102. const json = await response.json();
  103. expect(response.status).toBe(401);
  104. expect(json).toEqual({ error: "Invalid credentials" });
  105. expect(createSession).not.toHaveBeenCalled();
  106. });
  107. it("returns 400 when username or password is missing", async () => {
  108. const request = createRequestStub({
  109. username: "only-username",
  110. });
  111. const response = await POST(request);
  112. const json = await response.json();
  113. expect(response.status).toBe(400);
  114. expect(json).toEqual({ error: "Missing username or password" });
  115. expect(User.findOne).not.toHaveBeenCalled();
  116. expect(createSession).not.toHaveBeenCalled();
  117. });
  118. it("returns 500 when an unexpected error occurs", async () => {
  119. User.findOne.mockImplementation(() => {
  120. throw new Error("DB failure");
  121. });
  122. const request = createRequestStub({
  123. username: "branchuser",
  124. password: "secret-password",
  125. });
  126. const response = await POST(request);
  127. const json = await response.json();
  128. expect(response.status).toBe(500);
  129. expect(json).toEqual({ error: "Internal server error" });
  130. expect(createSession).not.toHaveBeenCalled();
  131. });
  132. });