1- import { describe , it , expect , beforeAll } from '@jest/globals'
1+ import { describe , it , expect , beforeAll , afterAll } from '@jest/globals'
22import axios from 'axios'
3+ import mongoose from 'mongoose'
4+ import crypto from 'crypto'
35import { env } from '../../../../constant/env.constant'
46import UserUtils from '../user.utils'
5- import mongoose from 'mongoose'
7+ import User from '../user.model'
8+
9+ const API_URL = env . BACKEND_URL
610
711describe ( 'User Registration Tests' , ( ) => {
812 let userExists = false
@@ -38,7 +42,7 @@ describe('User Registration Tests', () => {
3842 }
3943
4044 try {
41- const res = await axios . post ( `${ env . BACKEND_URL } /auth/signup` , {
45+ const res = await axios . post ( `${ API_URL } /auth/signup` , {
4246 firstName : 'Test User' ,
4347 birthPlace : 'Test City' ,
4448 location : 'Test Country' ,
@@ -72,7 +76,7 @@ describe('User Registration Tests', () => {
7276 }
7377
7478 try {
75- const res = await axios . post ( `${ env . BACKEND_URL } /auth/signup` , {
79+ const res = await axios . post ( `${ API_URL } /auth/signup` , {
7680 firstName : 'Duplicate User' ,
7781 birthPlace : 'Duplicate City' ,
7882 location : 'Duplicate Country' ,
@@ -90,3 +94,286 @@ describe('User Registration Tests', () => {
9094 }
9195 } , 10000 )
9296} )
97+
98+ describe ( 'Password Validation Tests' , ( ) => {
99+ const validUserData = {
100+ firstName : 'Password Test' ,
101+ birthPlace : 'Test City' ,
102+ location : 'Test Country' ,
103+ email : `pwtest_${ Date . now ( ) } @example.com` ,
104+ }
105+
106+ it ( 'should reject password without uppercase letter' , async ( ) => {
107+ try {
108+ await axios . post ( `${ API_URL } /auth/signup` , {
109+ ...validUserData ,
110+ email : `test_noupper_${ Date . now ( ) } @example.com` ,
111+ password : 'test@1234' , // No uppercase
112+ } )
113+ throw new Error ( 'Should have rejected password without uppercase' )
114+ } catch ( error : any ) {
115+ expect ( error . response ) . toBeDefined ( )
116+ expect ( error . response . status ) . toBe ( 400 )
117+ }
118+ } , 10000 )
119+
120+ it ( 'should reject password without lowercase letter' , async ( ) => {
121+ try {
122+ await axios . post ( `${ API_URL } /auth/signup` , {
123+ ...validUserData ,
124+ email : `test_nolower_${ Date . now ( ) } @example.com` ,
125+ password : 'TEST@1234' , // No lowercase
126+ } )
127+ throw new Error ( 'Should have rejected password without lowercase' )
128+ } catch ( error : any ) {
129+ expect ( error . response ) . toBeDefined ( )
130+ expect ( error . response . status ) . toBe ( 400 )
131+ }
132+ } , 10000 )
133+
134+ it ( 'should reject password without number' , async ( ) => {
135+ try {
136+ await axios . post ( `${ API_URL } /auth/signup` , {
137+ ...validUserData ,
138+ email : `test_nonum_${ Date . now ( ) } @example.com` ,
139+ password : 'Test@test' , // No number
140+ } )
141+ throw new Error ( 'Should have rejected password without number' )
142+ } catch ( error : any ) {
143+ expect ( error . response ) . toBeDefined ( )
144+ expect ( error . response . status ) . toBe ( 400 )
145+ }
146+ } , 10000 )
147+
148+ it ( 'should reject password without special character' , async ( ) => {
149+ try {
150+ await axios . post ( `${ API_URL } /auth/signup` , {
151+ ...validUserData ,
152+ email : `test_nospecial_${ Date . now ( ) } @example.com` ,
153+ password : 'Test12345' , // No special char
154+ } )
155+ throw new Error ( 'Should have rejected password without special character' )
156+ } catch ( error : any ) {
157+ expect ( error . response ) . toBeDefined ( )
158+ expect ( error . response . status ) . toBe ( 400 )
159+ }
160+ } , 10000 )
161+
162+ it ( 'should reject password shorter than 8 characters' , async ( ) => {
163+ try {
164+ await axios . post ( `${ API_URL } /auth/signup` , {
165+ ...validUserData ,
166+ email : `test_short_${ Date . now ( ) } @example.com` ,
167+ password : 'Te@1' , // Too short
168+ } )
169+ throw new Error ( 'Should have rejected short password' )
170+ } catch ( error : any ) {
171+ expect ( error . response ) . toBeDefined ( )
172+ expect ( error . response . status ) . toBe ( 400 )
173+ }
174+ } , 10000 )
175+ } )
176+
177+ describe ( 'Input Validation Edge Cases' , ( ) => {
178+ const baseUserData = {
179+ firstName : 'Edge Case Test' ,
180+ birthPlace : 'Test City' ,
181+ location : 'Test Country' ,
182+ password : 'ValidPass@123' ,
183+ }
184+
185+ it ( 'should reject empty firstName' , async ( ) => {
186+ try {
187+ await axios . post ( `${ API_URL } /auth/signup` , {
188+ ...baseUserData ,
189+ firstName : '' ,
190+ email : `test_nofname_${ Date . now ( ) } @example.com` ,
191+ } )
192+ throw new Error ( 'Should have rejected empty firstName' )
193+ } catch ( error : any ) {
194+ expect ( error . response ) . toBeDefined ( )
195+ expect ( error . response . status ) . toBe ( 400 )
196+ }
197+ } , 10000 )
198+
199+ it ( 'should reject invalid email format' , async ( ) => {
200+ try {
201+ await axios . post ( `${ API_URL } /auth/signup` , {
202+ ...baseUserData ,
203+ email : 'invalid-email-format' ,
204+ } )
205+ throw new Error ( 'Should have rejected invalid email' )
206+ } catch ( error : any ) {
207+ expect ( error . response ) . toBeDefined ( )
208+ expect ( error . response . status ) . toBe ( 400 )
209+ }
210+ } , 10000 )
211+
212+ it ( 'should reject empty birthPlace' , async ( ) => {
213+ try {
214+ await axios . post ( `${ API_URL } /auth/signup` , {
215+ ...baseUserData ,
216+ birthPlace : '' ,
217+ email : `test_nobirth_${ Date . now ( ) } @example.com` ,
218+ } )
219+ throw new Error ( 'Should have rejected empty birthPlace' )
220+ } catch ( error : any ) {
221+ expect ( error . response ) . toBeDefined ( )
222+ expect ( error . response . status ) . toBe ( 400 )
223+ }
224+ } , 10000 )
225+
226+ it ( 'should reject empty location' , async ( ) => {
227+ try {
228+ await axios . post ( `${ API_URL } /auth/signup` , {
229+ ...baseUserData ,
230+ location : '' ,
231+ email : `test_noloc_${ Date . now ( ) } @example.com` ,
232+ } )
233+ throw new Error ( 'Should have rejected empty location' )
234+ } catch ( error : any ) {
235+ expect ( error . response ) . toBeDefined ( )
236+ expect ( error . response . status ) . toBe ( 400 )
237+ }
238+ } , 10000 )
239+
240+ it ( 'should accept valid portfolioUrl' , async ( ) => {
241+ const uniqueEmail = `test_portfolio_${ Date . now ( ) } @example.com`
242+ try {
243+ const res = await axios . post ( `${ API_URL } /auth/signup` , {
244+ ...baseUserData ,
245+ email : uniqueEmail ,
246+ portfolioUrl : 'https://portfolio.example.com' ,
247+ } )
248+ expect ( res . status ) . toBe ( 201 )
249+ } catch ( error : any ) {
250+ if ( error . response ?. status !== 409 ) {
251+ throw error
252+ }
253+ }
254+ } , 10000 )
255+
256+ it ( 'should reject bio longer than 50 characters' , async ( ) => {
257+ try {
258+ await axios . post ( `${ API_URL } /auth/signup` , {
259+ ...baseUserData ,
260+ email : `test_longbio_${ Date . now ( ) } @example.com` ,
261+ bio : 'A' . repeat ( 51 ) , // 51 characters
262+ } )
263+ throw new Error ( 'Should have rejected long bio' )
264+ } catch ( error : any ) {
265+ expect ( error . response ) . toBeDefined ( )
266+ expect ( error . response . status ) . toBe ( 400 )
267+ }
268+ } , 10000 )
269+ } )
270+
271+ describe ( 'Login Endpoint Tests' , ( ) => {
272+ const loginTestEmail = env . YOUR_EMAIL || 'test@example.com'
273+ const validPassword = 'Test@1234'
274+
275+ it ( 'should successfully login with valid credentials' , async ( ) => {
276+ try {
277+ const res = await axios . post ( `${ API_URL } /user/login` , {
278+ email : loginTestEmail ,
279+ password : validPassword ,
280+ } )
281+
282+ expect ( res . status ) . toBe ( 200 )
283+ expect ( res . data ) . toBeDefined ( )
284+ expect ( res . data . message ) . toBeDefined ( )
285+ } catch ( error : any ) {
286+ if ( error . response ?. status === 401 || error . response ?. status === 404 ) {
287+ console . log ( 'Test user not found, skipping login success test' )
288+ expect ( true ) . toBe ( true )
289+ } else {
290+ throw error
291+ }
292+ }
293+ } , 10000 )
294+
295+ it ( 'should reject login with wrong password' , async ( ) => {
296+ try {
297+ await axios . post ( `${ API_URL } /user/login` , {
298+ email : loginTestEmail ,
299+ password : 'WrongPassword@123' ,
300+ } )
301+ throw new Error ( 'Should have rejected wrong password' )
302+ } catch ( error : any ) {
303+ expect ( error . response ) . toBeDefined ( )
304+ expect ( [ 401 , 404 ] ) . toContain ( error . response . status )
305+ }
306+ } , 10000 )
307+
308+ it ( 'should reject login with non-existent email' , async ( ) => {
309+ try {
310+ await axios . post ( `${ API_URL } /user/login` , {
311+ email : 'nonexistent_user_12345@example.com' ,
312+ password : 'SomePassword@123' ,
313+ } )
314+ throw new Error ( 'Should have rejected non-existent email' )
315+ } catch ( error : any ) {
316+ expect ( error . response ) . toBeDefined ( )
317+ expect ( [ 401 , 404 ] ) . toContain ( error . response . status )
318+ }
319+ } , 10000 )
320+ } )
321+
322+ describe ( 'Password Reset Tests' , ( ) => {
323+ const testEmail = env . YOUR_EMAIL || 'test@example.com'
324+ // Generate a token we can control
325+ const rawToken = 'test-reset-token-123'
326+ const hashedToken = crypto . createHash ( 'sha256' ) . update ( rawToken ) . digest ( 'hex' )
327+
328+ it ( 'should send reset email (forgot password)' , async ( ) => {
329+ const res = await axios . post ( `${ API_URL } /auth/forgot-password` , {
330+ email : testEmail ,
331+ } )
332+
333+ expect ( res . status ) . toBe ( 200 )
334+ expect ( res . data . message ) . toMatch ( / r e s e t l i n k h a s b e e n s e n t / i)
335+ } )
336+
337+ it ( 'should successfully reset password with valid token' , async ( ) => {
338+ // 1. Setup: Manually inject token into DB for the test user
339+ const user = await User . findOne ( { email : testEmail } )
340+ if ( ! user ) throw new Error ( 'Test user not found' )
341+
342+ user . resetPasswordToken = hashedToken
343+ user . resetPasswordExpire = new Date ( Date . now ( ) + 10 * 60 * 1000 ) // 10 mins from now
344+ await user . save ( )
345+
346+ // 2. Call Reset Password Endpoint with RAW token
347+ const newPassword = 'NewSecurePassword123!'
348+ const res = await axios . post ( `${ API_URL } /auth/reset-password/${ rawToken } ` , {
349+ password : newPassword ,
350+ } )
351+
352+ expect ( res . status ) . toBe ( 200 )
353+ expect ( res . data . message ) . toMatch ( / p a s s w o r d r e s e t s u c c e s s f u l l y / i)
354+
355+ // 3. Verify Login with New Password works
356+ const loginRes = await axios . post ( `${ API_URL } /user/login` , {
357+ email : testEmail ,
358+ password : newPassword ,
359+ } )
360+ expect ( loginRes . status ) . toBe ( 200 )
361+ } )
362+
363+ it ( 'should fail reset with invalid token' , async ( ) => {
364+ try {
365+ await axios . post ( `${ API_URL } /auth/reset-password/invalid-token` , {
366+ password : 'NewPassword123!' ,
367+ } )
368+ throw new Error ( 'Should have failed' )
369+ } catch ( error : any ) {
370+ expect ( error . response . status ) . toBe ( 500 ) // or 400 depending on implementation
371+ // Checking for "Invalid token" message we just added
372+ expect ( error . response . data . message ) . toMatch ( / I n v a l i d t o k e n / i)
373+ }
374+ } )
375+ } )
376+
377+ afterAll ( async ( ) => {
378+ await mongoose . connection . close ( )
379+ } )
0 commit comments