1+ import { jest } from '@jest/globals' ;
2+
3+ // Mock Next.js modules
4+ jest . mock ( 'next/server' , ( ) => ( {
5+ NextResponse : {
6+ json : jest . fn ( ( data , options ) => {
7+ return {
8+ data,
9+ status : options ?. status || 200 ,
10+ headers : new Map ( ) ,
11+ } ;
12+ } ) ,
13+ redirect : jest . fn ( ) ,
14+ next : jest . fn ( ) ,
15+ } ,
16+ } ) ) ;
17+
18+ jest . mock ( '@/db/drizzle' , ( ) => ( {
19+ db : {
20+ query : {
21+ users : {
22+ findFirst : jest . fn ( ) ,
23+ } ,
24+ } ,
25+ } ,
26+ } ) ) ;
27+
28+ jest . mock ( '@/lib/password' , ( ) => ( {
29+ verifyPassword : jest . fn ( ) ,
30+ } ) ) ;
31+
32+ jest . mock ( '@/lib/server/session' , ( ) => ( {
33+ generateSessionToken : jest . fn ( ) . mockReturnValue ( 'mock-session-token' ) ,
34+ createSession : jest . fn ( ) . mockResolvedValue ( {
35+ token : 'mock-session-token' ,
36+ expiresAt : new Date ( Date . now ( ) + 86400000 )
37+ } ) ,
38+ } ) ) ;
39+
40+ jest . mock ( '@/lib/server/cookies' , ( ) => ( {
41+ setSessionTokenCookie : jest . fn ( ) ,
42+ } ) ) ;
43+
44+ import { NextResponse } from 'next/server' ;
45+ import { db } from '@/db/drizzle' ;
46+ import { verifyPassword } from '@/lib/password' ;
47+ import { generateSessionToken , createSession } from '@/lib/server/session' ;
48+ import { setSessionTokenCookie } from '@/lib/server/cookies' ;
49+ import { POST } from '@/app/api/auth/login/route' ;
50+
51+ describe ( 'POST /api/login' , ( ) => {
52+ beforeEach ( ( ) => {
53+ jest . clearAllMocks ( ) ;
54+ } ) ;
55+
56+ it ( 'should return user data on valid credentials' , async ( ) => {
57+ // Mock user data
58+ const mockUser = {
59+ id : '1' ,
60+ 61+ name : 'Test User' ,
62+ hashedPassword : 'hashed_password' ,
63+ } ;
64+
65+ // Set up mocks
66+ ( db . query . users . findFirst as jest . Mock ) . mockResolvedValue ( mockUser ) ;
67+ ( verifyPassword as jest . Mock ) . mockResolvedValue ( true ) ;
68+
69+ // Create mock request
70+ const request = {
71+ json : jest . fn ( ) . mockResolvedValue ( {
72+ 73+ password : 'password123' ,
74+ } ) ,
75+ } as unknown as Request ;
76+
77+ // Call the handler
78+ const response = await POST ( request ) ;
79+
80+ // Assertions
81+ expect ( db . query . users . findFirst ) . toHaveBeenCalled ( ) ;
82+ expect ( verifyPassword ) . toHaveBeenCalledWith ( 'hashed_password' , 'password123' ) ;
83+ expect ( generateSessionToken ) . toHaveBeenCalled ( ) ;
84+ expect ( createSession ) . toHaveBeenCalled ( ) ;
85+ expect ( setSessionTokenCookie ) . toHaveBeenCalled ( ) ;
86+
87+ expect ( response . data ) . toEqual ( {
88+ _id : '1' ,
89+ 90+ name : 'Test User' ,
91+ } ) ;
92+ } ) ;
93+
94+ it ( 'should return 401 if user not found' , async ( ) => {
95+ // Set up mocks
96+ ( db . query . users . findFirst as jest . Mock ) . mockResolvedValue ( null ) ;
97+
98+ // Create mock request
99+ const request = {
100+ json : jest . fn ( ) . mockResolvedValue ( {
101+ 102+ password : 'password123' ,
103+ } ) ,
104+ } as unknown as Request ;
105+
106+ // Call the handler
107+ const response = await POST ( request ) ;
108+
109+ // Assertions
110+ expect ( response . status ) . toBe ( 401 ) ;
111+ expect ( response . data ) . toEqual ( { error : 'Invalid credentials' } ) ;
112+ } ) ;
113+
114+ it ( 'should return 401 on invalid password' , async ( ) => {
115+ // Mock user data
116+ const mockUser = {
117+ id : '1' ,
118+ 119+ name : 'Test User' ,
120+ hashedPassword : 'hashed_password' ,
121+ } ;
122+
123+ // Set up mocks
124+ ( db . query . users . findFirst as jest . Mock ) . mockResolvedValue ( mockUser ) ;
125+ ( verifyPassword as jest . Mock ) . mockResolvedValue ( false ) ;
126+
127+ // Create mock request
128+ const request = {
129+ json : jest . fn ( ) . mockResolvedValue ( {
130+ 131+ password : 'wrong_password' ,
132+ } ) ,
133+ } as unknown as Request ;
134+
135+ // Call the handler
136+ const response = await POST ( request ) ;
137+
138+ // Assertions
139+ expect ( verifyPassword ) . toHaveBeenCalled ( ) ;
140+ expect ( response . status ) . toBe ( 401 ) ;
141+ expect ( response . data ) . toEqual ( { error : 'Invalid credentials' } ) ;
142+ } ) ;
143+
144+ it ( 'should return 400 on invalid request' , async ( ) => {
145+ // Create mock request that throws an error when trying to parse JSON
146+ const request = {
147+ json : jest . fn ( ) . mockRejectedValue ( new Error ( 'Invalid JSON' ) ) ,
148+ } as unknown as Request ;
149+
150+ // Call the handler
151+ const response = await POST ( request ) ;
152+
153+ // Assertions
154+ expect ( response . status ) . toBe ( 400 ) ;
155+ expect ( response . data ) . toEqual ( { error : 'Invalid request' } ) ;
156+ } ) ;
157+ } ) ;
0 commit comments