@@ -49,12 +49,17 @@ describe("<ForgotPassword>", () => {
49
49
} ) ;
50
50
} ;
51
51
52
- const clickButton = async ( label : string ) : Promise < void > => {
52
+ const click = async ( element : Element ) : Promise < void > => {
53
53
await act ( async ( ) => {
54
- await userEvent . click ( screen . getByText ( label ) , { delay : null } ) ;
54
+ await userEvent . click ( element , { delay : null } ) ;
55
55
} ) ;
56
56
} ;
57
57
58
+ const waitForDialog = async ( ) : Promise < void > => {
59
+ await flushPromisesWithFakeTimers ( ) ;
60
+ await flushPromisesWithFakeTimers ( ) ;
61
+ } ;
62
+
58
63
const itShouldCloseTheDialogAndShowThePasswordInput = ( ) : void => {
59
64
it ( "should close the dialog and show the password input" , ( ) => {
60
65
expect ( screen . queryByText ( "Verify your email to continue" ) ) . not . toBeInTheDocument ( ) ;
@@ -121,17 +126,17 @@ describe("<ForgotPassword>", () => {
121
126
} ) ;
122
127
} ) ;
123
128
124
- describe ( "when clicking »Sign in instead«" , ( ) => {
129
+ describe ( "and clicking »Sign in instead«" , ( ) => {
125
130
beforeEach ( async ( ) => {
126
- await clickButton ( "Sign in instead" ) ;
131
+ await click ( screen . getByText ( "Sign in instead" ) ) ;
127
132
} ) ;
128
133
129
134
it ( "should call onLoginClick()" , ( ) => {
130
135
expect ( onLoginClick ) . toHaveBeenCalled ( ) ;
131
136
} ) ;
132
137
} ) ;
133
138
134
- describe ( "when entering a non-email value" , ( ) => {
139
+ describe ( "and entering a non-email value" , ( ) => {
135
140
beforeEach ( async ( ) => {
136
141
await typeIntoField ( "Email address" , "not en email" ) ;
137
142
} ) ;
@@ -141,27 +146,27 @@ describe("<ForgotPassword>", () => {
141
146
} ) ;
142
147
} ) ;
143
148
144
- describe ( "when submitting an unknown email" , ( ) => {
149
+ describe ( "and submitting an unknown email" , ( ) => {
145
150
beforeEach ( async ( ) => {
146
151
await typeIntoField ( "Email address" , testEmail ) ;
147
152
mocked ( client ) . requestPasswordEmailToken . mockRejectedValue ( {
148
153
errcode : "M_THREEPID_NOT_FOUND" ,
149
154
} ) ;
150
- await clickButton ( "Send email" ) ;
155
+ await click ( screen . getByText ( "Send email" ) ) ;
151
156
} ) ;
152
157
153
158
it ( "should show an email not found message" , ( ) => {
154
159
expect ( screen . getByText ( "This email address was not found" ) ) . toBeInTheDocument ( ) ;
155
160
} ) ;
156
161
} ) ;
157
162
158
- describe ( "when a connection error occurs" , ( ) => {
163
+ describe ( "and a connection error occurs" , ( ) => {
159
164
beforeEach ( async ( ) => {
160
165
await typeIntoField ( "Email address" , testEmail ) ;
161
166
mocked ( client ) . requestPasswordEmailToken . mockRejectedValue ( {
162
167
name : "ConnectionError" ,
163
168
} ) ;
164
- await clickButton ( "Send email" ) ;
169
+ await click ( screen . getByText ( "Send email" ) ) ;
165
170
} ) ;
166
171
167
172
it ( "should show an info about that" , ( ) => {
@@ -174,7 +179,7 @@ describe("<ForgotPassword>", () => {
174
179
} ) ;
175
180
} ) ;
176
181
177
- describe ( "when the server liveness check fails" , ( ) => {
182
+ describe ( "and the server liveness check fails" , ( ) => {
178
183
beforeEach ( async ( ) => {
179
184
await typeIntoField ( "Email address" , testEmail ) ;
180
185
mocked ( AutoDiscoveryUtils . validateServerConfigWithStaticUrls ) . mockRejectedValue ( { } ) ;
@@ -183,21 +188,21 @@ describe("<ForgotPassword>", () => {
183
188
serverIsAlive : false ,
184
189
serverDeadError : "server down" ,
185
190
} ) ;
186
- await clickButton ( "Send email" ) ;
191
+ await click ( screen . getByText ( "Send email" ) ) ;
187
192
} ) ;
188
193
189
194
it ( "should show the server error" , ( ) => {
190
195
expect ( screen . queryByText ( "server down" ) ) . toBeInTheDocument ( ) ;
191
196
} ) ;
192
197
} ) ;
193
198
194
- describe ( "when submitting an known email" , ( ) => {
199
+ describe ( "and submitting an known email" , ( ) => {
195
200
beforeEach ( async ( ) => {
196
201
await typeIntoField ( "Email address" , testEmail ) ;
197
202
mocked ( client ) . requestPasswordEmailToken . mockResolvedValue ( {
198
203
sid : testSid ,
199
204
} ) ;
200
- await clickButton ( "Send email" ) ;
205
+ await click ( screen . getByText ( "Send email" ) ) ;
201
206
} ) ;
202
207
203
208
it ( "should send the mail and show the check email view" , ( ) => {
@@ -210,19 +215,19 @@ describe("<ForgotPassword>", () => {
210
215
expect ( screen . getByText ( testEmail ) ) . toBeInTheDocument ( ) ;
211
216
} ) ;
212
217
213
- describe ( "when clicking re -enter email" , ( ) => {
218
+ describe ( "and clicking »Re -enter email address« " , ( ) => {
214
219
beforeEach ( async ( ) => {
215
- await clickButton ( "Re-enter email address" ) ;
220
+ await click ( screen . getByText ( "Re-enter email address" ) ) ;
216
221
} ) ;
217
222
218
223
it ( "go back to the email input" , ( ) => {
219
224
expect ( screen . queryByText ( "Enter your email to reset password" ) ) . toBeInTheDocument ( ) ;
220
225
} ) ;
221
226
} ) ;
222
227
223
- describe ( "when clicking resend email " , ( ) => {
228
+ describe ( "and clicking »Resend« " , ( ) => {
224
229
beforeEach ( async ( ) => {
225
- await userEvent . click ( screen . getByText ( "Resend" ) , { delay : null } ) ;
230
+ await click ( screen . getByText ( "Resend" ) ) ;
226
231
// the message is shown after some time
227
232
jest . advanceTimersByTime ( 500 ) ;
228
233
} ) ;
@@ -237,16 +242,16 @@ describe("<ForgotPassword>", () => {
237
242
} ) ;
238
243
} ) ;
239
244
240
- describe ( "when clicking next " , ( ) => {
245
+ describe ( "and clicking »Next« " , ( ) => {
241
246
beforeEach ( async ( ) => {
242
- await clickButton ( "Next" ) ;
247
+ await click ( screen . getByText ( "Next" ) ) ;
243
248
} ) ;
244
249
245
250
it ( "should show the password input view" , ( ) => {
246
251
expect ( screen . getByText ( "Reset your password" ) ) . toBeInTheDocument ( ) ;
247
252
} ) ;
248
253
249
- describe ( "when entering different passwords" , ( ) => {
254
+ describe ( "and entering different passwords" , ( ) => {
250
255
beforeEach ( async ( ) => {
251
256
await typeIntoField ( "New Password" , testPassword ) ;
252
257
await typeIntoField ( "Confirm new password" , testPassword + "asd" ) ;
@@ -257,7 +262,7 @@ describe("<ForgotPassword>", () => {
257
262
} ) ;
258
263
} ) ;
259
264
260
- describe ( "when entering a new password" , ( ) => {
265
+ describe ( "and entering a new password" , ( ) => {
261
266
beforeEach ( async ( ) => {
262
267
mocked ( client . setPassword ) . mockRejectedValue ( { httpStatus : 401 } ) ;
263
268
await typeIntoField ( "New Password" , testPassword ) ;
@@ -273,7 +278,7 @@ describe("<ForgotPassword>", () => {
273
278
retry_after_ms : ( 13 * 60 + 37 ) * 1000 ,
274
279
} ,
275
280
} ) ;
276
- await clickButton ( "Reset password" ) ;
281
+ await click ( screen . getByText ( "Reset password" ) ) ;
277
282
} ) ;
278
283
279
284
it ( "should show the rate limit error message" , ( ) => {
@@ -316,10 +321,8 @@ describe("<ForgotPassword>", () => {
316
321
317
322
describe ( "and submitting it" , ( ) => {
318
323
beforeEach ( async ( ) => {
319
- await clickButton ( "Reset password" ) ;
320
- // double flush promises for the modal to appear
321
- await flushPromisesWithFakeTimers ( ) ;
322
- await flushPromisesWithFakeTimers ( ) ;
324
+ await click ( screen . getByText ( "Reset password" ) ) ;
325
+ await waitForDialog ( ) ;
323
326
} ) ;
324
327
325
328
it ( "should send the new password and show the click validation link dialog" , ( ) => {
@@ -347,33 +350,25 @@ describe("<ForgotPassword>", () => {
347
350
await act ( async ( ) => {
348
351
await userEvent . click ( screen . getByTestId ( "dialog-background" ) , { delay : null } ) ;
349
352
} ) ;
350
- // double flush promises for the modal to disappear
351
- await flushPromisesWithFakeTimers ( ) ;
352
- await flushPromisesWithFakeTimers ( ) ;
353
+ await waitForDialog ( ) ;
353
354
} ) ;
354
355
355
356
itShouldCloseTheDialogAndShowThePasswordInput ( ) ;
356
357
} ) ;
357
358
358
359
describe ( "and dismissing the dialog" , ( ) => {
359
360
beforeEach ( async ( ) => {
360
- await act ( async ( ) => {
361
- await userEvent . click ( screen . getByLabelText ( "Close dialog" ) , { delay : null } ) ;
362
- } ) ;
363
- // double flush promises for the modal to disappear
364
- await flushPromisesWithFakeTimers ( ) ;
365
- await flushPromisesWithFakeTimers ( ) ;
361
+ await click ( screen . getByLabelText ( "Close dialog" ) ) ;
362
+ await waitForDialog ( ) ;
366
363
} ) ;
367
364
368
365
itShouldCloseTheDialogAndShowThePasswordInput ( ) ;
369
366
} ) ;
370
367
371
- describe ( "when clicking re -enter email" , ( ) => {
368
+ describe ( "and clicking »Re -enter email address« " , ( ) => {
372
369
beforeEach ( async ( ) => {
373
- await clickButton ( "Re-enter email address" ) ;
374
- // double flush promises for the modal to disappear
375
- await flushPromisesWithFakeTimers ( ) ;
376
- await flushPromisesWithFakeTimers ( ) ;
370
+ await click ( screen . getByText ( "Re-enter email address" ) ) ;
371
+ await waitForDialog ( ) ;
377
372
} ) ;
378
373
379
374
it ( "should close the dialog and go back to the email input" , ( ) => {
@@ -382,7 +377,7 @@ describe("<ForgotPassword>", () => {
382
377
} ) ;
383
378
} ) ;
384
379
385
- describe ( "when validating the link from the mail" , ( ) => {
380
+ describe ( "and validating the link from the mail" , ( ) => {
386
381
beforeEach ( async ( ) => {
387
382
mocked ( client . setPassword ) . mockResolvedValue ( { } ) ;
388
383
// be sure the next set password attempt was sent
@@ -400,6 +395,42 @@ describe("<ForgotPassword>", () => {
400
395
} ) ;
401
396
} ) ;
402
397
} ) ;
398
+
399
+ describe ( "and clicking »Sign out of all devices« and »Reset password«" , ( ) => {
400
+ beforeEach ( async ( ) => {
401
+ await click ( screen . getByText ( "Sign out of all devices" ) ) ;
402
+ await click ( screen . getByText ( "Reset password" ) ) ;
403
+ await waitForDialog ( ) ;
404
+ } ) ;
405
+
406
+ it ( "should show the sign out warning dialog" , async ( ) => {
407
+ expect (
408
+ screen . getByText (
409
+ "Signing out your devices will delete the message encryption keys stored on them, making encrypted chat history unreadable." ,
410
+ ) ,
411
+ ) . toBeInTheDocument ( ) ;
412
+
413
+ // confirm dialog
414
+ await click ( screen . getByText ( "Continue" ) ) ;
415
+
416
+ // expect setPassword with logoutDevices = true
417
+ expect ( client . setPassword ) . toHaveBeenCalledWith (
418
+ {
419
+ type : "m.login.email.identity" ,
420
+ threepid_creds : {
421
+ client_secret : expect . any ( String ) ,
422
+ sid : testSid ,
423
+ } ,
424
+ threepidCreds : {
425
+ client_secret : expect . any ( String ) ,
426
+ sid : testSid ,
427
+ } ,
428
+ } ,
429
+ testPassword ,
430
+ true ,
431
+ ) ;
432
+ } ) ;
433
+ } ) ;
403
434
} ) ;
404
435
} ) ;
405
436
} ) ;
0 commit comments