@ -1,5 +1,5 @@
import React from 'react'
import React from 'react'
import { render, screen , fireEvent , waitFor , act } from '@testing-library/react'
import { act, fireEvent , render , screen , waitFor } from '@testing-library/react'
import '@testing-library/jest-dom'
import '@testing-library/jest-dom'
// Mock the service base to avoid ky import issues
// Mock the service base to avoid ky import issues
@ -47,7 +47,7 @@ const createWrapper = () => {
} ,
} ,
mutations : {
mutations : {
retry : false ,
retry : false ,
}
} ,
} ,
} ,
} )
} )
@ -68,7 +68,9 @@ describe('MFAPage Component', () => {
test ( 'renders loading state initially' , ( ) = > {
test ( 'renders loading state initially' , ( ) = > {
const { get } = require ( '@/service/base' )
const { get } = require ( '@/service/base' )
get . mockImplementation ( ( ) = > new Promise ( ( ) = > { } ) ) // Never resolves
get . mockImplementation ( ( ) = > new Promise ( ( ) = > {
// Never resolves - intentionally empty for testing loading state
} ) ) // Never resolves
const { container } = render ( < MFAPage / > , { wrapper } )
const { container } = render ( < MFAPage / > , { wrapper } )
@ -92,7 +94,7 @@ describe('MFAPage Component', () => {
const { get } = require ( '@/service/base' )
const { get } = require ( '@/service/base' )
get . mockResolvedValue ( {
get . mockResolvedValue ( {
enabled : true ,
enabled : true ,
setup_at : '2025-01-01T12:00:00'
setup_at : '2025-01-01T12:00:00' ,
} )
} )
render ( < MFAPage / > , { wrapper } )
render ( < MFAPage / > , { wrapper } )
@ -107,7 +109,7 @@ describe('MFAPage Component', () => {
get . mockResolvedValue ( { enabled : false } )
get . mockResolvedValue ( { enabled : false } )
post . mockResolvedValue ( {
post . mockResolvedValue ( {
secret : 'TEST_SECRET' ,
secret : 'TEST_SECRET' ,
qr_code : 'data:image/png;base64,test'
qr_code : 'data:image/png;base64,test' ,
} )
} )
render ( < MFAPage / > , { wrapper } )
render ( < MFAPage / > , { wrapper } )
@ -136,13 +138,14 @@ describe('MFAPage Component', () => {
if ( url . includes ( '/setup' ) && ! url . includes ( '/complete' ) ) {
if ( url . includes ( '/setup' ) && ! url . includes ( '/complete' ) ) {
return Promise . resolve ( {
return Promise . resolve ( {
secret : 'TEST_SECRET' ,
secret : 'TEST_SECRET' ,
qr_code : 'data:image/png;base64,test'
qr_code : 'data:image/png;base64,test' ,
} )
} )
} else if ( url . includes ( '/setup/complete' ) ) {
}
else if ( url . includes ( '/setup/complete' ) ) {
return Promise . resolve ( {
return Promise . resolve ( {
message : 'MFA setup successfully' ,
message : 'MFA setup successfully' ,
backup_codes : [ 'CODE1' , 'CODE2' , 'CODE3' , 'CODE4' , 'CODE5' , 'CODE6' , 'CODE7' , 'CODE8' ] ,
backup_codes : [ 'CODE1' , 'CODE2' , 'CODE3' , 'CODE4' , 'CODE5' , 'CODE6' , 'CODE7' , 'CODE8' ] ,
setup_at : '2025-01-01T12:00:00'
setup_at : '2025-01-01T12:00:00' ,
} )
} )
}
}
} )
} )
@ -190,7 +193,7 @@ describe('MFAPage Component', () => {
// Check that toast was called
// Check that toast was called
expect ( Toast . notify ) . toHaveBeenCalledWith ( {
expect ( Toast . notify ) . toHaveBeenCalledWith ( {
type : 'success' ,
type : 'success' ,
message : 'mfa.setupSuccess'
message : 'mfa.setupSuccess' ,
} )
} )
} , 15000 )
} , 15000 )
@ -203,9 +206,10 @@ describe('MFAPage Component', () => {
if ( url . includes ( '/setup' ) && ! url . includes ( '/complete' ) ) {
if ( url . includes ( '/setup' ) && ! url . includes ( '/complete' ) ) {
return Promise . resolve ( {
return Promise . resolve ( {
secret : 'TEST_SECRET' ,
secret : 'TEST_SECRET' ,
qr_code : 'data:image/png;base64,test'
qr_code : 'data:image/png;base64,test' ,
} )
} )
} else if ( url . includes ( '/setup/complete' ) ) {
}
else if ( url . includes ( '/setup/complete' ) ) {
return Promise . reject ( new Error ( 'Invalid TOTP token' ) )
return Promise . reject ( new Error ( 'Invalid TOTP token' ) )
}
}
} )
} )
@ -243,7 +247,7 @@ describe('MFAPage Component', () => {
await waitFor ( ( ) = > {
await waitFor ( ( ) = > {
expect ( Toast . notify ) . toHaveBeenCalledWith ( {
expect ( Toast . notify ) . toHaveBeenCalledWith ( {
type : 'error' ,
type : 'error' ,
message : 'mfa.invalidToken'
message : 'mfa.invalidToken' ,
} )
} )
} , { timeout : 5000 } )
} , { timeout : 5000 } )
} , 15000 )
} , 15000 )
@ -254,13 +258,13 @@ describe('MFAPage Component', () => {
get . mockResolvedValue ( {
get . mockResolvedValue ( {
enabled : true ,
enabled : true ,
setup_at : '2025-01-01T12:00:00'
setup_at : '2025-01-01T12:00:00' ,
} )
} )
post . mockImplementation ( ( url ) = > {
post . mockImplementation ( ( url ) = > {
if ( url . includes ( '/disable' ) ) {
if ( url . includes ( '/disable' ) ) {
return Promise . resolve ( {
return Promise . resolve ( {
success : true ,
success : true ,
message : 'MFA disabled successfully'
message : 'MFA disabled successfully' ,
} )
} )
}
}
} )
} )
@ -292,7 +296,7 @@ describe('MFAPage Component', () => {
await waitFor ( ( ) = > {
await waitFor ( ( ) = > {
expect ( Toast . notify ) . toHaveBeenCalledWith ( {
expect ( Toast . notify ) . toHaveBeenCalledWith ( {
type : 'success' ,
type : 'success' ,
message : 'mfa.disabledSuccessfully'
message : 'mfa.disabledSuccessfully' ,
} )
} )
} , { timeout : 5000 } )
} , { timeout : 5000 } )
} , 15000 )
} , 15000 )
@ -303,12 +307,11 @@ describe('MFAPage Component', () => {
get . mockResolvedValue ( {
get . mockResolvedValue ( {
enabled : true ,
enabled : true ,
setup_at : '2025-01-01T12:00:00'
setup_at : '2025-01-01T12:00:00' ,
} )
} )
post . mockImplementation ( ( url ) = > {
post . mockImplementation ( ( url ) = > {
if ( url . includes ( '/disable' ) ) {
if ( url . includes ( '/disable' ) )
return Promise . reject ( new Error ( 'Invalid password' ) )
return Promise . reject ( new Error ( 'Invalid password' ) )
}
} )
} )
render ( < MFAPage / > , { wrapper } )
render ( < MFAPage / > , { wrapper } )
@ -337,7 +340,7 @@ describe('MFAPage Component', () => {
await waitFor ( ( ) = > {
await waitFor ( ( ) = > {
expect ( Toast . notify ) . toHaveBeenCalledWith ( {
expect ( Toast . notify ) . toHaveBeenCalledWith ( {
type : 'error' ,
type : 'error' ,
message : 'mfa.invalidPassword'
message : 'mfa.invalidPassword' ,
} )
} )
} , { timeout : 5000 } )
} , { timeout : 5000 } )
} , 15000 )
} , 15000 )
@ -352,13 +355,14 @@ describe('MFAPage Component', () => {
if ( url . includes ( '/setup' ) && ! url . includes ( '/complete' ) ) {
if ( url . includes ( '/setup' ) && ! url . includes ( '/complete' ) ) {
return Promise . resolve ( {
return Promise . resolve ( {
secret : 'TEST_SECRET' ,
secret : 'TEST_SECRET' ,
qr_code : 'data:image/png;base64,test'
qr_code : 'data:image/png;base64,test' ,
} )
} )
} else if ( url . includes ( '/setup/complete' ) ) {
}
else if ( url . includes ( '/setup/complete' ) ) {
return Promise . resolve ( {
return Promise . resolve ( {
message : 'MFA setup successfully' ,
message : 'MFA setup successfully' ,
backup_codes : [ 'ABCD1234' , 'EFGH5678' , 'IJKL9012' , 'MNOP3456' , 'QRST7890' , 'UVWX1234' , 'YZAB5678' , 'CDEF9012' ] ,
backup_codes : [ 'ABCD1234' , 'EFGH5678' , 'IJKL9012' , 'MNOP3456' , 'QRST7890' , 'UVWX1234' , 'YZAB5678' , 'CDEF9012' ] ,
setup_at : '2025-01-01T12:00:00'
setup_at : '2025-01-01T12:00:00' ,
} )
} )
}
}
} )
} )