index.spec.tsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. import {InjectedRouter} from 'react-router';
  2. import {Location} from 'history';
  3. import {initializeOrg} from 'sentry-test/initializeOrg';
  4. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  5. import GlobalModal from 'sentry/components/globalModal';
  6. import {Organization} from 'sentry/types';
  7. import {OrganizationContext} from 'sentry/views/organizationContext';
  8. import {RouteContext} from 'sentry/views/routeContext';
  9. import OrganizationSecurityAndPrivacy from 'sentry/views/settings/organizationSecurityAndPrivacy';
  10. function ComponentProviders({
  11. router,
  12. location,
  13. organization,
  14. children,
  15. }: {
  16. children: React.ReactNode;
  17. location: Location;
  18. organization: Organization;
  19. router: InjectedRouter;
  20. }) {
  21. MockApiClient.addMockResponse({
  22. url: `/organizations/${organization.slug}/auth-provider/`,
  23. method: 'GET',
  24. body: {},
  25. });
  26. return (
  27. <OrganizationContext.Provider value={organization}>
  28. <RouteContext.Provider
  29. value={{
  30. router,
  31. location,
  32. params: {},
  33. routes: [],
  34. }}
  35. >
  36. {children}
  37. </RouteContext.Provider>
  38. </OrganizationContext.Provider>
  39. );
  40. }
  41. describe('OrganizationSecurityAndPrivacy', function () {
  42. it('shows require2fa switch', async function () {
  43. const {organization, router} = initializeOrg();
  44. render(
  45. <ComponentProviders
  46. organization={organization}
  47. router={router}
  48. location={router.location}
  49. >
  50. <OrganizationSecurityAndPrivacy />
  51. </ComponentProviders>
  52. );
  53. expect(
  54. await screen.findByRole('checkbox', {
  55. name: 'Enable to require and enforce two-factor authentication for all members',
  56. })
  57. ).toBeInTheDocument();
  58. });
  59. it('returns to "off" if switch enable fails (e.g. API error)', async function () {
  60. const {organization, router} = initializeOrg();
  61. MockApiClient.addMockResponse({
  62. url: `/organizations/${organization.slug}/`,
  63. method: 'PUT',
  64. statusCode: 500,
  65. });
  66. render(
  67. <ComponentProviders
  68. organization={organization}
  69. router={router}
  70. location={router.location}
  71. >
  72. <GlobalModal />
  73. <OrganizationSecurityAndPrivacy />
  74. </ComponentProviders>
  75. );
  76. userEvent.click(
  77. await screen.findByRole('checkbox', {
  78. name: 'Enable to require and enforce two-factor authentication for all members',
  79. })
  80. );
  81. // Hide console.error for this test
  82. jest.spyOn(console, 'error').mockImplementation(() => {});
  83. // Confirm but has API failure
  84. userEvent.click(screen.getByRole('button', {name: 'Confirm'}));
  85. expect(
  86. await screen.findByRole('checkbox', {
  87. name: 'Enable to require and enforce two-factor authentication for all members',
  88. })
  89. ).not.toBeChecked();
  90. });
  91. it('renders join request switch', async function () {
  92. const {organization, router} = initializeOrg();
  93. render(
  94. <ComponentProviders
  95. organization={organization}
  96. router={router}
  97. location={router.location}
  98. >
  99. <OrganizationSecurityAndPrivacy />
  100. </ComponentProviders>
  101. );
  102. expect(
  103. await screen.findByRole('checkbox', {
  104. name: 'Enable to allow users to request to join your organization',
  105. })
  106. ).toBeInTheDocument();
  107. });
  108. it('enables require2fa but cancels confirm modal', async function () {
  109. const {organization, router} = initializeOrg();
  110. const mock = MockApiClient.addMockResponse({
  111. url: `/organizations/${organization.slug}/`,
  112. method: 'PUT',
  113. });
  114. render(
  115. <ComponentProviders
  116. organization={organization}
  117. router={router}
  118. location={router.location}
  119. >
  120. <GlobalModal />
  121. <OrganizationSecurityAndPrivacy />
  122. </ComponentProviders>
  123. );
  124. userEvent.click(
  125. await screen.findByRole('checkbox', {
  126. name: 'Enable to require and enforce two-factor authentication for all members',
  127. })
  128. );
  129. // Cancel
  130. userEvent.click(screen.getByRole('button', {name: 'Cancel'}));
  131. expect(
  132. screen.getByRole('checkbox', {
  133. name: 'Enable to require and enforce two-factor authentication for all members',
  134. })
  135. ).not.toBeChecked();
  136. expect(mock).not.toHaveBeenCalled();
  137. });
  138. it('enables require2fa with confirm modal', async function () {
  139. const {organization, router} = initializeOrg();
  140. const mock = MockApiClient.addMockResponse({
  141. url: `/organizations/${organization.slug}/`,
  142. method: 'PUT',
  143. });
  144. render(
  145. <ComponentProviders
  146. organization={organization}
  147. router={router}
  148. location={router.location}
  149. >
  150. <GlobalModal />
  151. <OrganizationSecurityAndPrivacy />
  152. </ComponentProviders>
  153. );
  154. userEvent.click(
  155. await screen.findByRole('checkbox', {
  156. name: 'Enable to require and enforce two-factor authentication for all members',
  157. })
  158. );
  159. userEvent.click(screen.getByRole('button', {name: 'Confirm'}));
  160. expect(
  161. screen.getByRole('checkbox', {
  162. name: 'Enable to require and enforce two-factor authentication for all members',
  163. })
  164. ).toBeChecked();
  165. expect(mock).toHaveBeenCalledWith(
  166. '/organizations/org-slug/',
  167. expect.objectContaining({
  168. method: 'PUT',
  169. data: {
  170. require2FA: true,
  171. },
  172. })
  173. );
  174. });
  175. });