44
55import 'mutationobserver-shim' ;
66import React from 'react' ;
7- import { screen , fireEvent , act } from '@testing-library/react' ;
7+ import { screen , fireEvent , act , waitFor } from '@testing-library/react' ;
88import {
99 renderWithRouter ,
1010 mockEmail ,
1111 mockAppContext ,
1212 mockSettingsContext ,
1313} from '../../../models/mocks' ;
14+ import { createMockAccount } from './mocks' ;
1415import { UnitRowSecondaryEmail } from '.' ;
1516import { Account , AppContext } from '../../../models' ;
1617import { SettingsContext } from '../../../models/contexts/SettingsContext' ;
18+ import { JwtTokenCache } from '../../../lib/cache' ;
19+ import AuthClient from 'fxa-auth-client/lib/client' ;
20+ import userEvent , { UserEvent } from '@testing-library/user-event' ;
21+
22+ const mockSessionToken = 'you-get-a-session-token' ;
23+ const mockJwt = 'and-you-get-a-jwt' ;
24+
25+ jest . mock ( '../../../lib/cache' , ( ) => ( {
26+ __esModule : true ,
27+ ...jest . requireActual ( '../../../lib/cache' ) ,
28+ sessionToken : ( ) => mockSessionToken ,
29+ } ) ) ;
1730
1831const account = {
1932 emails :
[ mockEmail ( ) , mockEmail ( '[email protected] ' , false , false ) ] , @@ -308,46 +321,81 @@ describe('UnitRowSecondaryEmail', () => {
308321 } ) ;
309322
310323 describe ( 'deleteSecondaryEmail' , ( ) => {
324+ let user : UserEvent ;
325+ const mockAuthClient = new AuthClient ( 'http://localhost:9000' ) ;
326+
327+ const setupMockAuthClient = ( ) => {
328+ mockAuthClient . mfaRequestOtp = jest
329+ . fn ( )
330+ . mockResolvedValue ( { code : 200 , errno : 0 } ) ;
331+ mockAuthClient . mfaOtpVerify = jest
332+ . fn ( )
333+ . mockResolvedValue ( { accessToken : mockJwt } ) ;
334+ } ;
335+
336+ const resetJwtCache = ( ) => {
337+ if ( JwtTokenCache . hasToken ( mockSessionToken , 'email' ) ) {
338+ JwtTokenCache . removeToken ( mockSessionToken , 'email' ) ;
339+ }
340+ } ;
341+
342+ beforeEach ( ( ) => {
343+ jest . clearAllMocks ( ) ;
344+ resetJwtCache ( ) ;
345+ setupMockAuthClient ( ) ;
346+ user = userEvent . setup ( ) ;
347+ } ) ;
348+ /**
349+ * This test case also implicitly covers that the MfaGuard is not displayed
350+ * on success, so no need for a separate test for that specific case.
351+ */
311352 it ( 'displays a success message in the AlertBar' , async ( ) => {
312- const primaryEmail = mockEmail ( '[email protected] ' ) ; 353+ JwtTokenCache . setToken ( mockSessionToken , 'email' , mockJwt ) ;
354+
313355 const emails = [
314- { ... primaryEmail } ,
356+ 315357 mockEmail ( '[email protected] ' , false , false ) , 316358 ] ;
317- const account = {
359+ const account = createMockAccount ( {
360+ deleteSecondaryEmailWithJwt : jest . fn ( ) . mockResolvedValue ( true ) ,
318361 emails,
319- deleteSecondaryEmail : jest . fn ( ) . mockResolvedValue ( true ) ,
320- } as unknown as Account ;
321- const context = mockAppContext ( { account } ) ;
362+ } ) ;
363+
364+ const appCtx = mockAppContext ( {
365+ authClient : mockAuthClient as any ,
366+ account,
367+ } ) ;
322368 const settingsContext = mockSettingsContext ( ) ;
323369 renderWithRouter (
324- < AppContext . Provider value = { context } >
370+ < AppContext . Provider value = { appCtx } >
325371 < SettingsContext . Provider value = { settingsContext } >
326372 < UnitRowSecondaryEmail />
327373 </ SettingsContext . Provider >
328374 </ AppContext . Provider >
329375 ) ;
330376
331- await act ( async ( ) => {
332- fireEvent . click ( screen . getByTestId ( 'secondary-email-delete' ) ) ;
333- } ) ;
377+ await user . click ( screen . getByTestId ( 'secondary-email-delete' ) ) ;
334378
335- expect ( settingsContext . alertBarInfo ?. success ) . toHaveBeenCalledTimes ( 1 ) ;
336- expect ( settingsContext . alertBarInfo ?. success ) . toHaveBeenCalledWith (
337- '[email protected] successfully deleted' 379+ await waitFor ( ( ) =>
380+ expect ( settingsContext . alertBarInfo ?. success ) . toHaveBeenCalledTimes ( 1 )
381+ ) ;
382+ await waitFor ( ( ) =>
383+ expect ( settingsContext . alertBarInfo ?. success ) . toHaveBeenCalledWith (
384+ '[email protected] successfully deleted' 385+ )
338386 ) ;
339387 } ) ;
340388
341389 it ( 'displays an error message in the AlertBar' , async ( ) => {
342- const emails = [
343- mockEmail ( ) ,
344- mockEmail ( '[email protected] ' , false , false ) , 345- ] ;
346- const account = {
347- emails ,
348- deleteSecondaryEmail : jest . fn ( ) . mockRejectedValue ( new Error ( ) ) ,
349- } as unknown as Account ;
350- const context = mockAppContext ( { account } ) ;
390+ JwtTokenCache . setToken ( mockSessionToken , 'email' , mockJwt ) ;
391+
392+ const account = createMockAccount ( {
393+ deleteSecondaryEmailWithJwt : jest . fn ( ) . mockRejectedValue ( new Error ( ) ) ,
394+ } ) ;
395+ const context = mockAppContext ( {
396+ authClient : mockAuthClient as any ,
397+ account ,
398+ } ) ;
351399 const settingsContext = mockSettingsContext ( ) ;
352400 renderWithRouter (
353401 < AppContext . Provider value = { context } >
@@ -362,5 +410,36 @@ describe('UnitRowSecondaryEmail', () => {
362410 } ) ;
363411 expect ( settingsContext . alertBarInfo ?. error ) . toHaveBeenCalledTimes ( 1 ) ;
364412 } ) ;
413+
414+ it ( 'displays the MFA guard if the JWT is invalid' , async ( ) => {
415+ JwtTokenCache . setToken ( mockSessionToken , 'email' , 'invalid-jwt' ) ;
416+
417+ const account = createMockAccount ( {
418+ deleteSecondaryEmailWithJwt : jest
419+ . fn ( )
420+ . mockRejectedValue ( { code : 401 , errno : 110 } ) ,
421+ } ) ;
422+
423+ const context = mockAppContext ( {
424+ authClient : mockAuthClient as any ,
425+ account,
426+ } ) ;
427+ const settingsContext = mockSettingsContext ( ) ;
428+ renderWithRouter (
429+ < AppContext . Provider value = { context } >
430+ < SettingsContext . Provider value = { settingsContext } >
431+ < UnitRowSecondaryEmail />
432+ </ SettingsContext . Provider >
433+ </ AppContext . Provider >
434+ ) ;
435+
436+ await act ( async ( ) => {
437+ fireEvent . click ( screen . getByTestId ( 'secondary-email-delete' ) ) ;
438+ } ) ;
439+
440+ expect (
441+ await screen . findByText ( 'Enter confirmation code' )
442+ ) . toBeInTheDocument ( ) ;
443+ } ) ;
365444 } ) ;
366445} ) ;
0 commit comments