@@ -530,6 +530,115 @@ describe('Concurrency queue test', () => {
530530 } )
531531 . catch ( done )
532532 } )
533+
534+ it ( 'should not refresh token when error_code is 294 (2FA required) with 401 status' , done => {
535+ let refreshTokenCallCount = 0
536+ const refreshTokenStub = sinon . stub ( ) . callsFake ( ( ) => {
537+ refreshTokenCallCount ++
538+ return Promise . resolve ( { authorization : 'Bearer new_token' } )
539+ } )
540+
541+ const axiosWithRefresh = client ( {
542+ baseURL : `${ host } :${ port } ` ,
543+ authorization : 'Bearer <token_value>' ,
544+ refreshToken : refreshTokenStub
545+ } )
546+
547+ const mock = new MockAdapter ( axiosWithRefresh . axiosInstance )
548+ mock . onGet ( '/test2fa' ) . reply ( 401 , {
549+ error_message : 'Please login using the Two-Factor verification Token' ,
550+ error_code : 294 ,
551+ errors : [ ] ,
552+ statusCode : 401 ,
553+ tfa_type : 'totp_authenticator'
554+ } )
555+
556+ axiosWithRefresh . axiosInstance . get ( '/test2fa' )
557+ . then ( ( ) => {
558+ done ( new Error ( 'Expected error was not thrown' ) )
559+ } )
560+ . catch ( ( error ) => {
561+ // Verify refreshToken was NOT called
562+ expect ( refreshTokenCallCount ) . to . equal ( 0 )
563+ expect ( refreshTokenStub . called ) . to . equal ( false )
564+
565+ // Verify the raw error response has error_code 294
566+ expect ( error . response . status ) . to . equal ( 401 )
567+ expect ( error . response . data . error_code ) . to . equal ( 294 )
568+ expect ( error . response . data . error_message ) . to . include ( 'Two-Factor verification' )
569+ expect ( error . response . data . tfa_type ) . to . equal ( 'totp_authenticator' )
570+ done ( )
571+ } )
572+ . catch ( done )
573+ } )
574+
575+ it ( 'should refresh token when 401 status without error_code 294' , done => {
576+ const axios2 = client ( {
577+ baseURL : `${ host } :${ port } `
578+ } )
579+ const axios = client ( {
580+ baseURL : `${ host } :${ port } ` ,
581+ authorization : 'Bearer <token_value>' ,
582+ refreshToken : ( ) => {
583+ return new Promise ( ( resolve , reject ) => {
584+ return axios2 . login ( ) . then ( ( res ) => {
585+ resolve ( { authorization : res . token } )
586+ } ) . catch ( ( error ) => {
587+ reject ( error )
588+ } )
589+ } )
590+ }
591+ } )
592+
593+ // First request will fail with 401, trigger refresh, then succeed
594+ axios . axiosInstance . get ( '/unauthorized' )
595+ . then ( ( response ) => {
596+ // Should succeed after token refresh
597+ expect ( response . data . randomInteger ) . to . equal ( 123 )
598+ done ( )
599+ } )
600+ . catch ( done )
601+ } )
602+
603+ it ( 'should preserve error_code 294 when present with 401 status' , done => {
604+ const refreshTokenStub = sinon . stub ( )
605+ refreshTokenStub . returns ( Promise . resolve ( { authorization : 'Bearer new_token' } ) )
606+
607+ const axiosWithRefresh = client ( {
608+ baseURL : `${ host } :${ port } ` ,
609+ authorization : 'Bearer <token_value>' ,
610+ refreshToken : refreshTokenStub
611+ } )
612+
613+ const mock = new MockAdapter ( axiosWithRefresh . axiosInstance )
614+ mock . onGet ( '/test2fa294' ) . reply ( 401 , {
615+ error_message : 'Please login using the Two-Factor verification Token' ,
616+ error_code : 294 ,
617+ errors : [ ] ,
618+ statusCode : 401 ,
619+ tfa_type : 'totp_authenticator'
620+ } )
621+
622+ axiosWithRefresh . axiosInstance . get ( '/test2fa294' )
623+ . then ( ( ) => {
624+ done ( new Error ( 'Expected error was not thrown' ) )
625+ } )
626+ . catch ( ( error ) => {
627+ // Verify refreshToken was NOT called
628+ expect ( refreshTokenStub . called ) . to . equal ( false )
629+
630+ // Verify the raw error response preserves error_code 294
631+ expect ( error . response . status ) . to . equal ( 401 )
632+ expect ( error . response . data . error_code ) . to . equal ( 294 )
633+ expect ( error . response . data . error_message ) . to . include ( 'Two-Factor verification' )
634+ expect ( error . response . data . tfa_type ) . to . equal ( 'totp_authenticator' )
635+
636+ // The key test: error_code 294 should be preserved in response.data
637+ // This ensures our fix in concurrency-queue.js is working (no token refresh attempted)
638+ done ( )
639+ } )
640+ . catch ( done )
641+ } )
533642} )
534643
535644function makeConcurrencyQueue ( config ) {
0 commit comments