recoveryOptionsModal.spec.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import styled from '@emotion/styled';
  2. import {
  3. AllAuthenticatorsFixture,
  4. AuthenticatorsFixture,
  5. } from 'sentry-fixture/authenticators';
  6. import {RouterContextFixture} from 'sentry-fixture/routerContextFixture';
  7. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  8. import {makeCloseButton} from 'sentry/components/globalModal/components';
  9. import RecoveryOptionsModal from 'sentry/components/modals/recoveryOptionsModal';
  10. describe('RecoveryOptionsModal', function () {
  11. const closeModal = jest.fn();
  12. const mockId = AuthenticatorsFixture().Recovery().authId;
  13. const routerContext = RouterContextFixture();
  14. beforeEach(function () {
  15. MockApiClient.clearMockResponses();
  16. MockApiClient.addMockResponse({
  17. url: '/users/me/authenticators/',
  18. method: 'GET',
  19. body: AllAuthenticatorsFixture(),
  20. });
  21. });
  22. function renderComponent() {
  23. const styledWrapper = styled(c => c.children);
  24. render(
  25. <RecoveryOptionsModal
  26. Body={styledWrapper()}
  27. Header={p => <span>{p.children}</span>}
  28. Footer={styledWrapper()}
  29. authenticatorName="Authenticator App"
  30. closeModal={closeModal}
  31. CloseButton={makeCloseButton(() => {})}
  32. />,
  33. {context: routerContext}
  34. );
  35. }
  36. it('can redirect to recovery codes if user skips backup phone setup', async function () {
  37. renderComponent();
  38. const skipButton = await screen.findByRole('button', {name: 'Skip this step'});
  39. expect(
  40. screen.queryByRole('button', {name: 'Get Recovery Codes'})
  41. ).not.toBeInTheDocument();
  42. // skip backup phone setup
  43. await userEvent.click(skipButton);
  44. const getCodesbutton = screen.getByRole('button', {name: 'Get Recovery Codes'});
  45. expect(getCodesbutton).toBeInTheDocument();
  46. expect(getCodesbutton).toHaveAttribute(
  47. 'href',
  48. `/settings/account/security/mfa/${mockId}/`
  49. );
  50. await userEvent.click(getCodesbutton);
  51. expect(closeModal).toHaveBeenCalled();
  52. });
  53. it('can redirect to backup phone setup', async function () {
  54. renderComponent();
  55. const backupPhoneButton = await screen.findByRole('button', {
  56. name: 'Add a Phone Number',
  57. });
  58. expect(backupPhoneButton).toBeInTheDocument();
  59. expect(backupPhoneButton).toHaveAttribute(
  60. 'href',
  61. '/settings/account/security/mfa/sms/enroll/'
  62. );
  63. await userEvent.click(backupPhoneButton);
  64. expect(closeModal).toHaveBeenCalled();
  65. });
  66. it('skips backup phone setup if text message authenticator unavailable', async function () {
  67. MockApiClient.clearMockResponses();
  68. MockApiClient.addMockResponse({
  69. url: '/users/me/authenticators/',
  70. method: 'GET',
  71. body: [AuthenticatorsFixture().Totp(), AuthenticatorsFixture().Recovery()],
  72. });
  73. renderComponent();
  74. const getCodesbutton = await screen.findByRole('button', {
  75. name: 'Get Recovery Codes',
  76. });
  77. expect(getCodesbutton).toBeInTheDocument();
  78. expect(getCodesbutton).toHaveAttribute(
  79. 'href',
  80. `/settings/account/security/mfa/${mockId}/`
  81. );
  82. expect(
  83. screen.queryByRole('button', {name: 'Skip this step'})
  84. ).not.toBeInTheDocument();
  85. expect(
  86. screen.queryByRole('button', {name: 'Add a Phone Number'})
  87. ).not.toBeInTheDocument();
  88. });
  89. it('renders the error message on API error', async () => {
  90. MockApiClient.clearMockResponses();
  91. MockApiClient.addMockResponse({
  92. url: '/users/me/authenticators/',
  93. method: 'GET',
  94. statusCode: 500,
  95. });
  96. renderComponent();
  97. const error = await screen.findByText('There was an error loading authenticators.');
  98. expect(error).toBeInTheDocument();
  99. });
  100. });