44import request from 'supertest' ;
55import path from 'path' ;
66import _ from 'lodash' ;
7+ import { jest } from '@jest/globals' ;
78
89import { bootstrap } from '../../../lib/app.js' ;
910import mongooseService from '../../../lib/services/mongoose.js' ;
@@ -29,6 +30,7 @@ describe('Auth integration tests:', () => {
2930 agent = request . agent ( init . app ) ;
3031 } catch ( err ) {
3132 console . log ( err ) ;
33+ expect ( err ) . toBeFalsy ( ) ;
3234 }
3335 } ) ;
3436
@@ -235,6 +237,22 @@ describe('Auth integration tests:', () => {
235237 }
236238 } ) ;
237239
240+ test ( 'should reject login with correct email but wrong password' , async ( ) => {
241+ try {
242+ const result = await agent
243+ . post ( '/api/auth/signin' )
244+ . send ( {
245+ email : credentials [ 0 ] . email ,
246+ password : 'WrongPassword!123' ,
247+ } )
248+ . expect ( 401 ) ;
249+ expect ( result . error . text ) . toBe ( 'Unauthorized' ) ;
250+ } catch ( err ) {
251+ console . log ( err ) ;
252+ expect ( err ) . toBeFalsy ( ) ;
253+ }
254+ } ) ;
255+
238256 test ( 'forgot password request for non-existent email should return 400' , async ( ) => {
239257 try {
240258 const result = await agent
@@ -431,12 +449,189 @@ describe('Auth integration tests:', () => {
431449 } ) ;
432450 } ) ;
433451
452+ describe ( 'OAuth profile and service branches' , ( ) => {
453+ let AuthController ;
454+ const oauthUsers = [ ] ;
455+
456+ beforeAll ( async ( ) => {
457+ AuthController = ( await import ( path . resolve ( './modules/auth/controllers/auth.controller.js' ) ) ) . default ;
458+ // clean up any leftover users from a previously failed run
459+ for ( const email of [ 'noprovider@auth-test.com' , 'oauthprofile@test.com' , 'oauthfind@test.com' ] ) {
460+ try {
461+ const existing = await UserService . getBrut ( { email } ) ;
462+ if ( existing ) await UserService . remove ( existing ) ;
463+ } catch ( _ ) { /* cleanup – ignore errors */ }
464+ }
465+ } ) ;
466+
467+ test ( 'should create user with default provider when none is specified' , async ( ) => {
468+ const result = await UserService . create ( {
469+ firstName : 'No' ,
470+ lastName : 'Provider' ,
471+ email : 'noprovider@auth-test.com' ,
472+ password : 'P@ss!W0rd123' ,
473+ roles : [ 'user' ] ,
474+ // provider intentionally omitted to trigger the default branch
475+ } ) ;
476+ expect ( result . provider ) . toBe ( 'local' ) ;
477+ oauthUsers . push ( result ) ;
478+ } ) ;
479+
480+ test ( 'should create an OAuth user without password via checkOAuthUserProfile' , async ( ) => {
481+ const profil = {
482+ firstName : 'OAuth' ,
483+ lastName : 'Test' ,
484+ email : 'oauthprofile@test.com' ,
485+ avatar : '' ,
486+ providerData : { id : 'google-fake-id-999' } ,
487+ } ;
488+ const mockRes = { status ( ) { return this ; } , json ( ) { } , cookie ( ) { return this ; } } ;
489+ const result = await AuthController . checkOAuthUserProfile ( profil , 'id' , 'google' , mockRes ) ;
490+ expect ( result ) . toBeDefined ( ) ;
491+ expect ( result . id ) . toBeDefined ( ) ;
492+ expect ( result . email ) . toBe ( profil . email ) ;
493+ oauthUsers . push ( result ) ;
494+ } ) ;
495+
496+ test ( 'should find an existing OAuth user via checkOAuthUserProfile' , async ( ) => {
497+ // Create an OAuth user directly first
498+ const createdUser = await UserService . create ( {
499+ firstName : 'OAuth' ,
500+ lastName : 'Find' ,
501+ email : 'oauthfind@test.com' ,
502+ provider : 'google' ,
503+ providerData : { id : 'google-find-id-777' } ,
504+ roles : [ 'user' ] ,
505+ } ) ;
506+
507+ const profil = {
508+ firstName : 'OAuth' ,
509+ lastName : 'Find' ,
510+ email : 'oauthfind@test.com' ,
511+ avatar : '' ,
512+ providerData : { id : 'google-find-id-777' } ,
513+ } ;
514+ const mockRes = { status ( ) { return this ; } , json ( ) { } , cookie ( ) { return this ; } } ;
515+ // Second call — should find the existing user (search.length === 1 branch)
516+ const found = await AuthController . checkOAuthUserProfile ( profil , 'id' , 'google' , mockRes ) ;
517+ expect ( found ) . toBeDefined ( ) ;
518+
519+ // cleanup
520+ try {
521+ await UserService . remove ( createdUser ) ;
522+ } catch ( _ ) { /* cleanup – ignore errors */ }
523+ } ) ;
524+
525+ afterAll ( async ( ) => {
526+ for ( const u of oauthUsers ) {
527+ try {
528+ await UserService . remove ( u ) ;
529+ } catch ( _ ) { /* cleanup – ignore errors */ }
530+ }
531+ } ) ;
532+ } ) ;
533+
534+ describe ( 'Password reset endpoint' , ( ) => {
535+ beforeEach ( async ( ) => {
536+ credentials = [
537+ {
538+ email : 'resetpwd@test.com' ,
539+ password : 'W@os.jsI$Aw3$0m3' ,
540+ } ,
541+ ] ;
542+ _user = {
543+ firstName : 'Reset' ,
544+ lastName : 'User' ,
545+ email : credentials [ 0 ] . email ,
546+ password : credentials [ 0 ] . password ,
547+ provider : 'local' ,
548+ } ;
549+ try {
550+ const result = await agent . post ( '/api/auth/signup' ) . send ( _user ) . expect ( 200 ) ;
551+ user = result . body . user ;
552+ } catch ( err ) {
553+ console . log ( err ) ;
554+ expect ( err ) . toBeFalsy ( ) ;
555+ }
556+ } ) ;
557+
558+ test ( 'should return 400 when token or password fields are missing' , async ( ) => {
559+ try {
560+ const result = await agent . post ( '/api/auth/reset' ) . send ( { newPassword : 'NewP@ss123' } ) . expect ( 400 ) ;
561+ expect ( result . body . message ) . toBe ( 'Bad Request' ) ;
562+ expect ( result . body . description ) . toBe ( 'Password or Token fields must not be blank' ) ;
563+ } catch ( err ) {
564+ console . log ( err ) ;
565+ expect ( err ) . toBeFalsy ( ) ;
566+ }
567+ } ) ;
568+
569+ test ( 'should return 400 when reset token is invalid or not found' , async ( ) => {
570+ try {
571+ const result = await agent . post ( '/api/auth/reset' ) . send ( { token : 'invalid-token-xyz' , newPassword : 'NewP@ss!Word123' } ) . expect ( 400 ) ;
572+ expect ( result . body . message ) . toBe ( 'Bad Request' ) ;
573+ expect ( result . body . description ) . toBe ( 'Password reset token is invalid or has expired.' ) ;
574+ } catch ( err ) {
575+ console . log ( err ) ;
576+ expect ( err ) . toBeFalsy ( ) ;
577+ }
578+ } ) ;
579+
580+ test ( 'should successfully reset password with a valid token' , async ( ) => {
581+ // Trigger forgot to generate a reset token (email send fails in test env, which is expected)
582+ try {
583+ await agent . post ( '/api/auth/forgot' ) . send ( { email : credentials [ 0 ] . email } ) . expect ( 400 ) ;
584+ } catch ( err ) {
585+ console . log ( err ) ;
586+ expect ( err ) . toBeFalsy ( ) ;
587+ }
588+
589+ // Fetch the token directly via UserService
590+ let resetToken ;
591+ try {
592+ const userWithToken = await UserService . getBrut ( { email : credentials [ 0 ] . email } ) ;
593+ resetToken = userWithToken . resetPasswordToken ;
594+ expect ( resetToken ) . toBeDefined ( ) ;
595+ } catch ( err ) {
596+ console . log ( err ) ;
597+ expect ( err ) . toBeFalsy ( ) ;
598+ }
599+
600+ // Reset password with the valid token
601+ try {
602+ const result = await agent . post ( '/api/auth/reset' ) . send ( { token : resetToken , newPassword : 'NewP@ss!Word123' } ) . expect ( 200 ) ;
603+ expect ( result . body . message ) . toBe ( 'Password changed successfully' ) ;
604+ expect ( result . body . user ) . toBeDefined ( ) ;
605+ } catch ( err ) {
606+ console . log ( err ) ;
607+ expect ( err ) . toBeFalsy ( ) ;
608+ }
609+ } ) ;
610+
611+ afterEach ( async ( ) => {
612+ try {
613+ await UserService . remove ( user ) ;
614+ } catch ( err ) {
615+ console . log ( err ) ;
616+ }
617+ } ) ;
618+ } ) ;
619+
620+ describe ( 'Error paths' , ( ) => {
621+ test ( 'should redirect to invalid when validateResetToken getBrut throws' , async ( ) => {
622+ jest . spyOn ( UserService , 'getBrut' ) . mockRejectedValueOnce ( new Error ( 'DB error' ) ) ;
623+ const result = await agent . get ( '/api/auth/reset/sometoken' ) . expect ( 302 ) ;
624+ expect ( result . headers . location ) . toBe ( '/api/password/reset/invalid' ) ;
625+ } ) ;
626+ } ) ;
627+
434628 // Mongoose disconnect
435629 afterAll ( async ( ) => {
436630 try {
437631 await mongooseService . disconnect ( ) ;
438632 } catch ( err ) {
439633 console . log ( err ) ;
634+ expect ( err ) . toBeFalsy ( ) ;
440635 }
441636 } ) ;
442637} ) ;
0 commit comments