@@ -36,6 +36,9 @@ describe('AuthController', () => {
3636 verifyGoogleMobileToken : jest . fn ( ) ,
3737 verifyGitHubMobileToken : jest . fn ( ) ,
3838 createOAuthSession : jest . fn ( ) ,
39+ createExchangeToken : jest . fn ( ) ,
40+ validateExchangeToken : jest . fn ( ) ,
41+ confirmPassword : jest . fn ( ) ,
3942 oauthCompletionStep1 : jest . fn ( ) ,
4043 oauthCompletionStep2 : jest . fn ( ) ,
4144 } ,
@@ -653,37 +656,36 @@ describe('AuthController', () => {
653656 const mock_req = { user : { id : 'user123' } } as any ;
654657 const mock_res = { redirect : jest . fn ( ) , cookie : jest . fn ( ) } as any ;
655658
656- const mock_tokens = {
657- access_token : 'access123' ,
658- refresh_token : 'refresh123' ,
659- } ;
659+ const mock_exchange_token = 'exchange_token_123' ;
660660
661- mock_auth_service . generateTokens . mockResolvedValue ( mock_tokens as any ) ;
662- const mock_set_cookie = jest . fn ( ) ;
663- controller [ 'httpOnlyRefreshToken' ] = mock_set_cookie ;
661+ mock_auth_service . createExchangeToken . mockResolvedValue ( mock_exchange_token ) ;
664662
665663 await controller . googleLoginCallback ( mock_req , mock_res ) ;
666664
667665 // eslint-disable-next-line @typescript-eslint/unbound-method
668- expect ( mock_auth_service . generateTokens ) . toHaveBeenCalledWith ( 'user123' ) ;
669-
670- expect ( mock_set_cookie ) . toHaveBeenCalledWith ( mock_res , mock_tokens . refresh_token ) ;
666+ expect ( mock_auth_service . createExchangeToken ) . toHaveBeenCalledWith ( {
667+ user_id : 'user123' ,
668+ type : 'auth' ,
669+ } ) ;
671670
672671 expect ( mock_res . redirect ) . toHaveBeenCalledWith (
673- `${ mock_frontend_url } /auth/success?token =${ mock_tokens . access_token } `
672+ `${ mock_frontend_url } /auth/success?exchange_token =${ encodeURIComponent ( mock_exchange_token ) } &provider=google `
674673 ) ;
675674 } ) ;
676675
677- it ( 'should redirect to error page if generateTokens throws' , async ( ) => {
676+ it ( 'should redirect to error page if createExchangeToken throws' , async ( ) => {
678677 const mock_req = { user : { id : 'user123' } } as any ;
679678 const mock_res = { redirect : jest . fn ( ) } as any ;
680679
681- mock_auth_service . generateTokens . mockRejectedValue ( new Error ( 'OAuth failed' ) ) ;
680+ mock_auth_service . createExchangeToken . mockRejectedValue ( new Error ( 'OAuth failed' ) ) ;
682681
683682 await controller . googleLoginCallback ( mock_req , mock_res ) ;
684683
685684 // eslint-disable-next-line @typescript-eslint/unbound-method
686- expect ( mock_auth_service . generateTokens ) . toHaveBeenCalledWith ( 'user123' ) ;
685+ expect ( mock_auth_service . createExchangeToken ) . toHaveBeenCalledWith ( {
686+ user_id : 'user123' ,
687+ type : 'auth' ,
688+ } ) ;
687689
688690 expect ( mock_res . redirect ) . toHaveBeenCalledWith (
689691 `${ mock_frontend_url } /auth/error?message=Authentication%20failed`
@@ -702,37 +704,36 @@ describe('AuthController', () => {
702704 const mock_req = { user : { id : 'user123' } } as any ;
703705 const mock_res = { redirect : jest . fn ( ) , cookie : jest . fn ( ) } as any ;
704706
705- const mock_tokens = {
706- access_token : 'access123' ,
707- refresh_token : 'refresh123' ,
708- } ;
707+ const mock_exchange_token = 'exchange_token_123' ;
709708
710- mock_auth_service . generateTokens . mockResolvedValue ( mock_tokens as any ) ;
711- const mock_set_cookie = jest . fn ( ) ;
712- controller [ 'httpOnlyRefreshToken' ] = mock_set_cookie ;
709+ mock_auth_service . createExchangeToken . mockResolvedValue ( mock_exchange_token ) ;
713710
714711 await controller . facebookLoginCallback ( mock_req , mock_res ) ;
715712
716713 // eslint-disable-next-line @typescript-eslint/unbound-method
717- expect ( mock_auth_service . generateTokens ) . toHaveBeenCalledWith ( 'user123' ) ;
718-
719- expect ( mock_set_cookie ) . toHaveBeenCalledWith ( mock_res , mock_tokens . refresh_token ) ;
714+ expect ( mock_auth_service . createExchangeToken ) . toHaveBeenCalledWith ( {
715+ user_id : 'user123' ,
716+ type : 'auth' ,
717+ } ) ;
720718
721719 expect ( mock_res . redirect ) . toHaveBeenCalledWith (
722- `${ mock_frontend_url } /auth/success?token =${ mock_tokens . access_token } `
720+ `${ mock_frontend_url } /auth/success?exchange_token =${ encodeURIComponent ( mock_exchange_token ) } &provider=facebook `
723721 ) ;
724722 } ) ;
725723
726- it ( 'should redirect to error page if generateTokens throws' , async ( ) => {
724+ it ( 'should redirect to error page if createExchangeToken throws' , async ( ) => {
727725 const mock_req = { user : { id : 'user123' } } as any ;
728726 const mock_res = { redirect : jest . fn ( ) , cookie : jest . fn ( ) } as any ;
729727
730- mock_auth_service . generateTokens . mockRejectedValue ( new Error ( 'OAuth failed' ) ) ;
728+ mock_auth_service . createExchangeToken . mockRejectedValue ( new Error ( 'OAuth failed' ) ) ;
731729
732730 await controller . facebookLoginCallback ( mock_req , mock_res ) ;
733731
734732 // eslint-disable-next-line @typescript-eslint/unbound-method
735- expect ( mock_auth_service . generateTokens ) . toHaveBeenCalledWith ( 'user123' ) ;
733+ expect ( mock_auth_service . createExchangeToken ) . toHaveBeenCalledWith ( {
734+ user_id : 'user123' ,
735+ type : 'auth' ,
736+ } ) ;
736737
737738 expect ( mock_res . redirect ) . toHaveBeenCalledWith (
738739 `${ mock_frontend_url } /auth/error?message=Authentication%20failed`
@@ -751,37 +752,36 @@ describe('AuthController', () => {
751752 const mock_req = { user : { id : 'user123' } } as any ;
752753 const mock_res = { redirect : jest . fn ( ) , cookie : jest . fn ( ) } as any ;
753754
754- const mock_tokens = {
755- access_token : 'access123' ,
756- refresh_token : 'refresh123' ,
757- } ;
755+ const mock_exchange_token = 'exchange_token_123' ;
758756
759- mock_auth_service . generateTokens . mockResolvedValue ( mock_tokens as any ) ;
760- const mock_set_cookie = jest . fn ( ) ;
761- controller [ 'httpOnlyRefreshToken' ] = mock_set_cookie ;
757+ mock_auth_service . createExchangeToken . mockResolvedValue ( mock_exchange_token ) ;
762758
763759 await controller . githubCallback ( mock_req , mock_res ) ;
764760
765761 // eslint-disable-next-line @typescript-eslint/unbound-method
766- expect ( mock_auth_service . generateTokens ) . toHaveBeenCalledWith ( 'user123' ) ;
767-
768- expect ( mock_set_cookie ) . toHaveBeenCalledWith ( mock_res , mock_tokens . refresh_token ) ;
762+ expect ( mock_auth_service . createExchangeToken ) . toHaveBeenCalledWith ( {
763+ user_id : 'user123' ,
764+ type : 'auth' ,
765+ } ) ;
769766
770767 expect ( mock_res . redirect ) . toHaveBeenCalledWith (
771- `${ mock_frontend_url } /auth/success?token =${ mock_tokens . access_token } `
768+ `${ mock_frontend_url } /auth/success?exchange_token =${ encodeURIComponent ( mock_exchange_token ) } &provider=github `
772769 ) ;
773770 } ) ;
774771
775- it ( 'should redirect to error page if generateTokens throws' , async ( ) => {
772+ it ( 'should redirect to error page if createExchangeToken throws' , async ( ) => {
776773 const mock_req = { user : { id : 'user123' } } as any ;
777774 const mock_res = { redirect : jest . fn ( ) , cookie : jest . fn ( ) } as any ;
778775
779- mock_auth_service . generateTokens . mockRejectedValue ( new Error ( 'OAuth failed' ) ) ;
776+ mock_auth_service . createExchangeToken . mockRejectedValue ( new Error ( 'OAuth failed' ) ) ;
780777
781778 await controller . githubCallback ( mock_req , mock_res ) ;
782779
783780 // eslint-disable-next-line @typescript-eslint/unbound-method
784- expect ( mock_auth_service . generateTokens ) . toHaveBeenCalledWith ( 'user123' ) ;
781+ expect ( mock_auth_service . createExchangeToken ) . toHaveBeenCalledWith ( {
782+ user_id : 'user123' ,
783+ type : 'auth' ,
784+ } ) ;
785785
786786 expect ( mock_res . redirect ) . toHaveBeenCalledWith (
787787 `${ mock_frontend_url } /auth/error?message=Authentication%20failed`
@@ -1243,4 +1243,85 @@ describe('AuthController', () => {
12431243 ) . rejects . toThrow ( 'Cookie error' ) ;
12441244 } ) ;
12451245 } ) ;
1246+
1247+ describe ( 'getCaptchaSiteKey' , ( ) => {
1248+ beforeEach ( ( ) => jest . clearAllMocks ( ) ) ;
1249+
1250+ it ( 'should return captcha site key' , ( ) => {
1251+ const result = controller . getCaptchaSiteKey ( ) ;
1252+
1253+ expect ( result ) . toHaveProperty ( 'siteKey' ) ;
1254+ expect ( typeof result . siteKey ) . toBe ( 'string' ) ;
1255+ } ) ;
1256+ } ) ;
1257+
1258+ describe ( 'exchangeToken' , ( ) => {
1259+ beforeEach ( ( ) => jest . clearAllMocks ( ) ) ;
1260+
1261+ it ( 'should exchange token successfully' , async ( ) => {
1262+ const mock_dto = { exchange_token : 'exchange-token' } ;
1263+ const mock_validation_result = {
1264+ user_id : 'user-1' ,
1265+ type : 'auth' as const ,
1266+ } ;
1267+ const mock_tokens = {
1268+ access_token : 'access-token' ,
1269+ refresh_token : 'refresh-token' ,
1270+ } ;
1271+
1272+ mock_auth_service . validateExchangeToken . mockResolvedValue ( mock_validation_result ) ;
1273+ mock_auth_service . generateTokens . mockResolvedValue ( mock_tokens as any ) ;
1274+ const mock_set_cookie = jest . fn ( ) ;
1275+ controller [ 'httpOnlyRefreshToken' ] = mock_set_cookie ;
1276+
1277+ const mock_response = {
1278+ cookie : jest . fn ( ) ,
1279+ json : jest . fn ( ) . mockReturnValue ( { type : 'auth' , access_token : 'access-token' } ) ,
1280+ } ;
1281+ const result = await controller . exchangeToken ( mock_dto as any , mock_response as any ) ;
1282+
1283+ expect ( mock_auth_service . validateExchangeToken ) . toHaveBeenCalledWith ( 'exchange-token' ) ;
1284+ expect ( result ) . toEqual ( { type : 'auth' , access_token : 'access-token' } ) ;
1285+ } ) ;
1286+
1287+ it ( 'should throw if exchange token is invalid' , async ( ) => {
1288+ const mock_dto = { exchange_token : 'invalid-token' } ;
1289+
1290+ mock_auth_service . validateExchangeToken . mockRejectedValue ( new Error ( 'Invalid token' ) ) ;
1291+
1292+ const mock_response = { cookie : jest . fn ( ) } ;
1293+ await expect (
1294+ controller . exchangeToken ( mock_dto as any , mock_response as any )
1295+ ) . rejects . toThrow ( 'Invalid token' ) ;
1296+ } ) ;
1297+ } ) ;
1298+
1299+ describe ( 'confirmPassword' , ( ) => {
1300+ beforeEach ( ( ) => jest . clearAllMocks ( ) ) ;
1301+
1302+ it ( 'should confirm password successfully' , async ( ) => {
1303+ const mock_dto = { password : 'correct-password' } ;
1304+ const mock_user = { id : 'user-1' } ;
1305+ const mock_result = { valid : true } ;
1306+
1307+ mock_auth_service . confirmPassword . mockResolvedValue ( mock_result as any ) ;
1308+
1309+ const result = await controller . confirmPassword ( mock_dto as any , 'user-1' ) ;
1310+
1311+ expect ( mock_auth_service . confirmPassword ) . toHaveBeenCalledWith ( mock_dto , 'user-1' ) ;
1312+ expect ( result ) . toEqual ( mock_result ) ;
1313+ } ) ;
1314+
1315+ it ( 'should throw if password is incorrect' , async ( ) => {
1316+ const mock_dto = { password : 'wrong-password' } ;
1317+
1318+ mock_auth_service . confirmPassword . mockRejectedValue (
1319+ new Error ( ERROR_MESSAGES . WRONG_PASSWORD )
1320+ ) ;
1321+
1322+ await expect ( controller . confirmPassword ( mock_dto as any , 'user-1' ) ) . rejects . toThrow (
1323+ ERROR_MESSAGES . WRONG_PASSWORD
1324+ ) ;
1325+ } ) ;
1326+ } ) ;
12461327} ) ;
0 commit comments