1- import { vi , describe , it , expect , beforeEach } from 'vitest'
2- import { BiometricAuthService } from '../BiometricAuthService'
3- import { AuthenticationResult , SetupResult } from '../types'
1+ import { vi , describe , it , expect , beforeEach , afterEach } from 'vitest'
42import { Capacitor } from '@capacitor/core'
53import { NativeBiometric } from '@capgo/capacitor-native-biometric'
4+ import { BiometricAuthService } from '../BiometricAuthService'
5+ import { AuthenticationResult , SetupResult } from '../types'
66
7- // Replace imports with mocks to control their behavior in tests
87vi . mock ( '@capacitor/core' , ( ) => ( {
98 Capacitor : {
109 isNativePlatform : vi . fn ( )
@@ -18,138 +17,99 @@ vi.mock('@capgo/capacitor-native-biometric', () => ({
1817 }
1918} ) )
2019
21- // Get mocked instances for type safety
22- const mockCapacitor = vi . mocked ( Capacitor )
23- const mockNativeBiometric = vi . mocked ( NativeBiometric )
24-
2520describe ( 'BiometricAuthService' , ( ) => {
26- let biometricAuth : BiometricAuthService
21+ let service : BiometricAuthService
22+ const mockCapacitor = vi . mocked ( Capacitor )
23+ const mockNativeBiometric = vi . mocked ( NativeBiometric )
2724
2825 beforeEach ( ( ) => {
29- // Create new service instance before each test for isolation
30- biometricAuth = new BiometricAuthService ( )
31- // Clear all mocks so tests don't affect each other
26+ service = new BiometricAuthService ( )
3227 vi . clearAllMocks ( )
28+ vi . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } )
3329 } )
3430
35- describe ( 'User tries to authenticate with biometrics on mobile device' , ( ) => {
36- beforeEach ( ( ) => {
37- // Simulate that we're on mobile platform (Android/iOS)
38- mockCapacitor . isNativePlatform . mockReturnValue ( true )
31+ afterEach ( ( ) => {
32+ vi . restoreAllMocks ( )
33+ } )
34+
35+ describe ( 'authorizeUser' , ( ) => {
36+ it ( 'should return Failed when not on native platform' , async ( ) => {
37+ mockCapacitor . isNativePlatform . mockReturnValue ( false )
38+
39+ const result = await service . authorizeUser ( )
40+
41+ expect ( result ) . toBe ( AuthenticationResult . Failed )
3942 } )
4043
41- it ( 'should successfully authenticate when user provides valid biometric ' , async ( ) => {
42- // Simulate successful biometric verification (fingerprint/Face ID )
44+ it ( 'should return Success when biometric verification succeeds ' , async ( ) => {
45+ mockCapacitor . isNativePlatform . mockReturnValue ( true )
4346 mockNativeBiometric . verifyIdentity . mockResolvedValue ( undefined )
4447
45- // User clicks "Login with biometric" button
46- const result = await biometricAuth . authorizeUser ( )
48+ const result = await service . authorizeUser ( )
4749
48- // Check that verifyIdentity was called with correct parameters
50+ expect ( result ) . toBe ( AuthenticationResult . Success )
4951 expect ( mockNativeBiometric . verifyIdentity ) . toHaveBeenCalledWith ( {
5052 reason : 'Login to ADAMANT Messenger' ,
5153 title : 'Biometric Authentication'
5254 } )
53- // Expect successful authentication
54- expect ( result ) . toBe ( AuthenticationResult . Success )
5555 } )
5656
57- it ( 'should return cancel when user cancels biometric prompt ' , async ( ) => {
58- // Simulate user clicking "Cancel" in biometric dialog (must include 'cancel' in message )
59- const cancelError = new Error ( 'User cancelled biometric authentication' )
57+ it ( 'should return Cancel when user cancels authentication ' , async ( ) => {
58+ mockCapacitor . isNativePlatform . mockReturnValue ( true )
59+ const cancelError = { code : 10 , message : 'User canceled authentication' }
6060 mockNativeBiometric . verifyIdentity . mockRejectedValue ( cancelError )
6161
62- // User starts authentication but cancels it
63- const result = await biometricAuth . authorizeUser ( )
62+ const result = await service . authorizeUser ( )
6463
65- // Expect "cancel" result, not error
6664 expect ( result ) . toBe ( AuthenticationResult . Cancel )
6765 } )
6866
69- it ( 'should return failed when biometric authentication fails' , async ( ) => {
70- // Simulate unsuccessful biometric recognition (error WITHOUT 'cancel' keyword )
71- const authError = new Error ( 'Biometric authentication failed')
67+ it ( 'should return Failed when biometric verification fails' , async ( ) => {
68+ mockCapacitor . isNativePlatform . mockReturnValue ( true )
69+ const authError = { code : 11 , message : 'Authentication failed' }
7270 mockNativeBiometric . verifyIdentity . mockRejectedValue ( authError )
7371
74- // User tries to login but biometric is not recognized
75- const result = await biometricAuth . authorizeUser ( )
76-
77- // Expect failed authentication
78- expect ( result ) . toBe ( AuthenticationResult . Failed )
79- } )
80-
81- it ( 'should return failed when error does not contain cancel keyword' , async ( ) => {
82- // Simulate error that does not contain 'cancel' (should be Failed, not Cancel)
83- const nonCancelError = new Error ( 'Biometric sensor unavailable' )
84- mockNativeBiometric . verifyIdentity . mockRejectedValue ( nonCancelError )
85-
86- // User tries to authenticate but gets non-cancel error
87- const result = await biometricAuth . authorizeUser ( )
72+ const result = await service . authorizeUser ( )
8873
89- // Should return Failed (not Cancel) because error doesn't contain 'cancel'
9074 expect ( result ) . toBe ( AuthenticationResult . Failed )
9175 } )
9276 } )
9377
94- describe ( 'User tries to authenticate with biometrics in web browser' , ( ) => {
95- beforeEach ( ( ) => {
96- // Simulate that we're in web browser, not native app
78+ describe ( 'setupBiometric' , ( ) => {
79+ it ( 'should return Failed when not on native platform' , async ( ) => {
9780 mockCapacitor . isNativePlatform . mockReturnValue ( false )
98- } )
9981
100- it ( 'should return failed as biometrics not available in browser' , async ( ) => {
101- // Biometrics are not available in browser
102- const result = await biometricAuth . authorizeUser ( )
82+ const result = await service . setupBiometric ( )
10383
104- // Expect authentication to fail
105- expect ( result ) . toBe ( AuthenticationResult . Failed )
84+ expect ( result ) . toBe ( SetupResult . Failed )
10685 } )
107- } )
10886
109- describe ( 'User wants to setup biometric authentication' , ( ) => {
110- beforeEach ( ( ) => {
111- // Setup is only possible on mobile devices
87+ it ( 'should return Success when biometric is available' , async ( ) => {
11288 mockCapacitor . isNativePlatform . mockReturnValue ( true )
113- } )
114-
115- it ( 'should successfully setup when device supports biometrics' , async ( ) => {
116- // Device supports biometrics (has fingerprint sensor/Face ID)
117- mockNativeBiometric . isAvailable . mockResolvedValue ( {
118- isAvailable : true ,
119- biometryType : 1
120- } )
89+ mockNativeBiometric . isAvailable . mockResolvedValue ( { isAvailable : true } )
12190
122- // User tries to enable biometric authentication
123- const result = await biometricAuth . setupBiometric ( )
91+ const result = await service . setupBiometric ( )
12492
125- // Setup should succeed
12693 expect ( result ) . toBe ( SetupResult . Success )
12794 } )
12895
129- it ( 'should fail setup when device does not support biometrics' , async ( ) => {
130- // Device doesn't support biometrics (old device without sensors)
131- mockNativeBiometric . isAvailable . mockResolvedValue ( {
132- isAvailable : false ,
133- biometryType : 0
134- } )
96+ it ( 'should return Failed when biometric is not available' , async ( ) => {
97+ mockCapacitor . isNativePlatform . mockReturnValue ( true )
98+ mockNativeBiometric . isAvailable . mockResolvedValue ( { isAvailable : false } )
13599
136- // User tries to enable biometrics on unsupported device
137- const result = await biometricAuth . setupBiometric ( )
100+ const result = await service . setupBiometric ( )
138101
139- // Setup should fail
140102 expect ( result ) . toBe ( SetupResult . Failed )
141103 } )
142104
143- it ( 'should return cancel when user cancels biometric setup ' , async ( ) => {
144- // Simulate user cancelling during setup (includes 'cancel' keyword )
145- const cancelError = new Error ( 'cancel ' )
105+ it ( 'should return Cancel when setup is cancelled ' , async ( ) => {
106+ mockCapacitor . isNativePlatform . mockReturnValue ( true )
107+ const cancelError = new Error ( 'User cancelled setup ' )
146108 mockNativeBiometric . isAvailable . mockRejectedValue ( cancelError )
147109
148- // User starts biometric setup but cancels it
149- const result = await biometricAuth . setupBiometric ( )
110+ const result = await service . setupBiometric ( )
150111
151- // Should return Cancel for setup cancellation
152112 expect ( result ) . toBe ( SetupResult . Cancel )
153113 } )
154114 } )
155- } )
115+ } )
0 commit comments