@@ -31,6 +31,8 @@ test('initial state', () => {
3131 expect ( stateHook . result . current ) . toStrictEqual ( {
3232 passcode : null ,
3333 obscureCodeEnabled : false ,
34+ failedAttempts : 0 ,
35+ lockUntil : 0 ,
3436 } ) ;
3537} ) ;
3638
@@ -64,6 +66,8 @@ test('passcode cannot be set to invalid value', () => {
6466 expect ( stateHook . result . current ) . toStrictEqual ( {
6567 passcode : null ,
6668 obscureCodeEnabled : false ,
69+ failedAttempts : 0 ,
70+ lockUntil : 0 ,
6771 } ) ;
6872} ) ;
6973
@@ -86,6 +90,8 @@ test('obscure code cannot be set when passcode is not set', () => {
8690 expect ( stateHook . result . current ) . toStrictEqual ( {
8791 passcode : null ,
8892 obscureCodeEnabled : false ,
93+ failedAttempts : 0 ,
94+ lockUntil : 0 ,
8995 } ) ;
9096} ) ;
9197
@@ -108,6 +114,8 @@ test('obscure code has expected value when enabled', () => {
108114 expect ( stateHook . result . current ) . toStrictEqual ( {
109115 passcode : '12345' ,
110116 obscureCodeEnabled : false ,
117+ failedAttempts : 0 ,
118+ lockUntil : 0 ,
111119 } ) ;
112120
113121 act ( ( ) => {
@@ -117,6 +125,8 @@ test('obscure code has expected value when enabled', () => {
117125 expect ( stateHook . result . current ) . toStrictEqual ( {
118126 passcode : '12345' ,
119127 obscureCodeEnabled : true ,
128+ failedAttempts : 0 ,
129+ lockUntil : 0 ,
120130 } ) ;
121131} ) ;
122132
@@ -140,6 +150,8 @@ test('obscure code is unset when passcode is unset', () => {
140150 expect ( stateHook . result . current ) . toStrictEqual ( {
141151 passcode : '12345' ,
142152 obscureCodeEnabled : true ,
153+ failedAttempts : 0 ,
154+ lockUntil : 0 ,
143155 } ) ;
144156
145157 act ( ( ) => {
@@ -149,5 +161,37 @@ test('obscure code is unset when passcode is unset', () => {
149161 expect ( stateHook . result . current ) . toStrictEqual ( {
150162 passcode : null ,
151163 obscureCodeEnabled : false ,
164+ failedAttempts : 0 ,
165+ lockUntil : 0 ,
152166 } ) ;
153167} ) ;
168+ test ( 'increments attempts and sets lockout' , ( ) => {
169+ const store = createSecurityStore ( ) ;
170+ const wrapper = createWrapper ( store ) ;
171+ const actionsHook = renderHook ( ( ) => useSecurityActions ( ) , { wrapper} ) ;
172+ const stateHook = renderHook ( ( ) => useSecurityState ( ) , { wrapper} ) ;
173+
174+ act ( ( ) => {
175+ actionsHook . result . current . incrementAndGetAttempts ( ) ;
176+ actionsHook . result . current . incrementAndGetAttempts ( ) ;
177+ actionsHook . result . current . setLockUntil ( 123456789 ) ;
178+ } ) ;
179+
180+ expect ( stateHook . result . current . failedAttempts ) . toBe ( 2 ) ;
181+ expect ( stateHook . result . current . lockUntil ) . toBe ( 123456789 ) ;
182+ } ) ;
183+ test ( 'resets attempts and lockout' , ( ) => {
184+ const store = createSecurityStore ( ) ;
185+ const wrapper = createWrapper ( store ) ;
186+ const actionsHook = renderHook ( ( ) => useSecurityActions ( ) , { wrapper} ) ;
187+ const stateHook = renderHook ( ( ) => useSecurityState ( ) , { wrapper} ) ;
188+
189+ act ( ( ) => {
190+ actionsHook . result . current . incrementAndGetAttempts ( ) ;
191+ actionsHook . result . current . setLockUntil ( 999999 ) ;
192+ actionsHook . result . current . resetFailedAttempts ( ) ;
193+ } ) ;
194+
195+ expect ( stateHook . result . current . failedAttempts ) . toBe ( 0 ) ;
196+ expect ( stateHook . result . current . lockUntil ) . toBe ( 0 ) ;
197+ } ) ;
0 commit comments