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'
4
2
import { Capacitor } from '@capacitor/core'
5
3
import { NativeBiometric } from '@capgo/capacitor-native-biometric'
4
+ import { BiometricAuthService } from '../BiometricAuthService'
5
+ import { AuthenticationResult , SetupResult } from '../types'
6
6
7
- // Replace imports with mocks to control their behavior in tests
8
7
vi . mock ( '@capacitor/core' , ( ) => ( {
9
8
Capacitor : {
10
9
isNativePlatform : vi . fn ( )
@@ -18,138 +17,99 @@ vi.mock('@capgo/capacitor-native-biometric', () => ({
18
17
}
19
18
} ) )
20
19
21
- // Get mocked instances for type safety
22
- const mockCapacitor = vi . mocked ( Capacitor )
23
- const mockNativeBiometric = vi . mocked ( NativeBiometric )
24
-
25
20
describe ( 'BiometricAuthService' , ( ) => {
26
- let biometricAuth : BiometricAuthService
21
+ let service : BiometricAuthService
22
+ const mockCapacitor = vi . mocked ( Capacitor )
23
+ const mockNativeBiometric = vi . mocked ( NativeBiometric )
27
24
28
25
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 ( )
32
27
vi . clearAllMocks ( )
28
+ vi . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } )
33
29
} )
34
30
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 )
39
42
} )
40
43
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 )
43
46
mockNativeBiometric . verifyIdentity . mockResolvedValue ( undefined )
44
47
45
- // User clicks "Login with biometric" button
46
- const result = await biometricAuth . authorizeUser ( )
48
+ const result = await service . authorizeUser ( )
47
49
48
- // Check that verifyIdentity was called with correct parameters
50
+ expect ( result ) . toBe ( AuthenticationResult . Success )
49
51
expect ( mockNativeBiometric . verifyIdentity ) . toHaveBeenCalledWith ( {
50
52
reason : 'Login to ADAMANT Messenger' ,
51
53
title : 'Biometric Authentication'
52
54
} )
53
- // Expect successful authentication
54
- expect ( result ) . toBe ( AuthenticationResult . Success )
55
55
} )
56
56
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' }
60
60
mockNativeBiometric . verifyIdentity . mockRejectedValue ( cancelError )
61
61
62
- // User starts authentication but cancels it
63
- const result = await biometricAuth . authorizeUser ( )
62
+ const result = await service . authorizeUser ( )
64
63
65
- // Expect "cancel" result, not error
66
64
expect ( result ) . toBe ( AuthenticationResult . Cancel )
67
65
} )
68
66
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' }
72
70
mockNativeBiometric . verifyIdentity . mockRejectedValue ( authError )
73
71
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 ( )
88
73
89
- // Should return Failed (not Cancel) because error doesn't contain 'cancel'
90
74
expect ( result ) . toBe ( AuthenticationResult . Failed )
91
75
} )
92
76
} )
93
77
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 ( ) => {
97
80
mockCapacitor . isNativePlatform . mockReturnValue ( false )
98
- } )
99
81
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 ( )
103
83
104
- // Expect authentication to fail
105
- expect ( result ) . toBe ( AuthenticationResult . Failed )
84
+ expect ( result ) . toBe ( SetupResult . Failed )
106
85
} )
107
- } )
108
86
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 ( ) => {
112
88
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 } )
121
90
122
- // User tries to enable biometric authentication
123
- const result = await biometricAuth . setupBiometric ( )
91
+ const result = await service . setupBiometric ( )
124
92
125
- // Setup should succeed
126
93
expect ( result ) . toBe ( SetupResult . Success )
127
94
} )
128
95
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 } )
135
99
136
- // User tries to enable biometrics on unsupported device
137
- const result = await biometricAuth . setupBiometric ( )
100
+ const result = await service . setupBiometric ( )
138
101
139
- // Setup should fail
140
102
expect ( result ) . toBe ( SetupResult . Failed )
141
103
} )
142
104
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 ' )
146
108
mockNativeBiometric . isAvailable . mockRejectedValue ( cancelError )
147
109
148
- // User starts biometric setup but cancels it
149
- const result = await biometricAuth . setupBiometric ( )
110
+ const result = await service . setupBiometric ( )
150
111
151
- // Should return Cancel for setup cancellation
152
112
expect ( result ) . toBe ( SetupResult . Cancel )
153
113
} )
154
114
} )
155
- } )
115
+ } )
0 commit comments