1import { asMock } from '../../../__tests__/asMock'; 2import { promptAsync } from '../../../utils/prompts'; 3import { ApiV2Error } from '../../rest/client'; 4import { showLoginPromptAsync } from '../actions'; 5import { retryUsernamePasswordAuthWithOTPAsync, UserSecondFactorDeviceMethod } from '../otp'; 6import { loginAsync } from '../user'; 7 8jest.mock('../../../log'); 9jest.mock('../../../utils/prompts'); 10jest.mock('../../rest/client', () => { 11 const { ApiV2Error } = jest.requireActual('../../rest/client'); 12 return { 13 ApiV2Error, 14 }; 15}); 16jest.mock('../otp'); 17jest.mock('../user'); 18 19beforeEach(() => { 20 asMock(promptAsync).mockClear(); 21 asMock(promptAsync).mockImplementation(() => { 22 throw new Error('Should not be called'); 23 }); 24 25 asMock(loginAsync).mockClear(); 26}); 27 28describe(showLoginPromptAsync, () => { 29 it('prompts for OTP when 2FA is enabled', async () => { 30 asMock(promptAsync) 31 .mockImplementationOnce(async () => ({ username: 'hello', password: 'world' })) 32 .mockImplementationOnce(async () => ({ otp: '123456' })) 33 .mockImplementation(() => { 34 throw new Error("shouldn't happen"); 35 }); 36 asMock(loginAsync) 37 .mockImplementationOnce(async () => { 38 throw new ApiV2Error({ 39 message: 'An OTP is required', 40 code: 'ONE_TIME_PASSWORD_REQUIRED', 41 metadata: { 42 secondFactorDevices: [ 43 { 44 id: 'p0', 45 is_primary: true, 46 method: UserSecondFactorDeviceMethod.SMS, 47 sms_phone_number: 'testphone', 48 }, 49 ], 50 smsAutomaticallySent: true, 51 }, 52 }); 53 }) 54 .mockImplementation(async () => {}); 55 56 await showLoginPromptAsync(); 57 58 expect(retryUsernamePasswordAuthWithOTPAsync).toHaveBeenCalledWith('hello', 'world', { 59 secondFactorDevices: [ 60 { 61 id: 'p0', 62 is_primary: true, 63 method: UserSecondFactorDeviceMethod.SMS, 64 sms_phone_number: 'testphone', 65 }, 66 ], 67 smsAutomaticallySent: true, 68 }); 69 }); 70 71 it('does not prompt if all required credentials are provided', async () => { 72 asMock(promptAsync).mockImplementation(() => { 73 throw new Error("shouldn't happen"); 74 }); 75 asMock(loginAsync).mockImplementation(async () => {}); 76 77 await showLoginPromptAsync({ username: 'hello', password: 'world' }); 78 }); 79}); 80