import styled from '@emotion/styled'; import { AllAuthenticatorsFixture, AuthenticatorsFixture, } from 'sentry-fixture/authenticators'; import {RouterContextFixture} from 'sentry-fixture/routerContextFixture'; import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary'; import {makeCloseButton} from 'sentry/components/globalModal/components'; import RecoveryOptionsModal from 'sentry/components/modals/recoveryOptionsModal'; describe('RecoveryOptionsModal', function () { const closeModal = jest.fn(); const mockId = AuthenticatorsFixture().Recovery().authId; const routerContext = RouterContextFixture(); beforeEach(function () { MockApiClient.clearMockResponses(); MockApiClient.addMockResponse({ url: '/users/me/authenticators/', method: 'GET', body: AllAuthenticatorsFixture(), }); }); function renderComponent() { const styledWrapper = styled(c => c.children); render( {p.children}} Footer={styledWrapper()} authenticatorName="Authenticator App" closeModal={closeModal} CloseButton={makeCloseButton(() => {})} />, {context: routerContext} ); } it('can redirect to recovery codes if user skips backup phone setup', async function () { renderComponent(); const skipButton = await screen.findByRole('button', {name: 'Skip this step'}); expect( screen.queryByRole('button', {name: 'Get Recovery Codes'}) ).not.toBeInTheDocument(); // skip backup phone setup await userEvent.click(skipButton); const getCodesbutton = screen.getByRole('button', {name: 'Get Recovery Codes'}); expect(getCodesbutton).toBeInTheDocument(); expect(getCodesbutton).toHaveAttribute( 'href', `/settings/account/security/mfa/${mockId}/` ); await userEvent.click(getCodesbutton); expect(closeModal).toHaveBeenCalled(); }); it('can redirect to backup phone setup', async function () { renderComponent(); const backupPhoneButton = await screen.findByRole('button', { name: 'Add a Phone Number', }); expect(backupPhoneButton).toBeInTheDocument(); expect(backupPhoneButton).toHaveAttribute( 'href', '/settings/account/security/mfa/sms/enroll/' ); await userEvent.click(backupPhoneButton); expect(closeModal).toHaveBeenCalled(); }); it('skips backup phone setup if text message authenticator unavailable', async function () { MockApiClient.clearMockResponses(); MockApiClient.addMockResponse({ url: '/users/me/authenticators/', method: 'GET', body: [AuthenticatorsFixture().Totp(), AuthenticatorsFixture().Recovery()], }); renderComponent(); const getCodesbutton = await screen.findByRole('button', { name: 'Get Recovery Codes', }); expect(getCodesbutton).toBeInTheDocument(); expect(getCodesbutton).toHaveAttribute( 'href', `/settings/account/security/mfa/${mockId}/` ); expect( screen.queryByRole('button', {name: 'Skip this step'}) ).not.toBeInTheDocument(); expect( screen.queryByRole('button', {name: 'Add a Phone Number'}) ).not.toBeInTheDocument(); }); it('renders the error message on API error', async () => { MockApiClient.clearMockResponses(); MockApiClient.addMockResponse({ url: '/users/me/authenticators/', method: 'GET', statusCode: 500, }); renderComponent(); const error = await screen.findByText('There was an error loading authenticators.'); expect(error).toBeInTheDocument(); }); });