index.spec.tsx 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import {Fragment} from 'react';
  2. import {initializeOrg} from 'sentry-test/initializeOrg';
  3. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  4. import {textWithMarkupMatcher} from 'sentry-test/utils';
  5. import GlobalModal from 'sentry/components/globalModal';
  6. import ModalStore from 'sentry/stores/modalStore';
  7. import {DataScrubbing} from 'sentry/views/settings/components/dataScrubbing';
  8. const relayPiiConfig = JSON.stringify(TestStubs.DataScrubbingRelayPiiConfig());
  9. describe('Data Scrubbing', function () {
  10. beforeEach(() => {
  11. ModalStore.reset();
  12. });
  13. describe('Organization level', function () {
  14. const {organization} = initializeOrg();
  15. const additionalContext = 'These rules can be configured for each project.';
  16. const endpoint = `organization/${organization.slug}/`;
  17. it('default render', function () {
  18. render(
  19. <DataScrubbing
  20. additionalContext={additionalContext}
  21. endpoint={endpoint}
  22. relayPiiConfig={relayPiiConfig}
  23. organization={organization}
  24. onSubmitSuccess={jest.fn()}
  25. />
  26. );
  27. // Header
  28. expect(screen.getByText('Advanced Data Scrubbing')).toBeInTheDocument();
  29. // Alert
  30. expect(
  31. screen.getByText(
  32. textWithMarkupMatcher(
  33. `${additionalContext} The new rules will only apply to upcoming events. For more details, see full documentation on data scrubbing.`
  34. )
  35. )
  36. ).toBeInTheDocument();
  37. expect(
  38. screen.getByRole('link', {name: 'full documentation on data scrubbing'})
  39. ).toHaveAttribute(
  40. 'href',
  41. `https://docs.sentry.io/product/data-management-settings/scrubbing/advanced-datascrubbing/`
  42. );
  43. // Body
  44. expect(screen.getAllByRole('button', {name: 'Edit Rule'})).toHaveLength(3);
  45. // Actions
  46. expect(screen.getByRole('button', {name: 'Read Docs'})).toHaveAttribute(
  47. 'href',
  48. `https://docs.sentry.io/product/data-management-settings/scrubbing/advanced-datascrubbing/`
  49. );
  50. expect(screen.getByRole('button', {name: 'Add Rule'})).toBeEnabled();
  51. });
  52. it('render empty state', function () {
  53. render(
  54. <DataScrubbing
  55. endpoint={endpoint}
  56. relayPiiConfig={undefined}
  57. organization={organization}
  58. onSubmitSuccess={jest.fn()}
  59. />
  60. );
  61. expect(screen.getByText('You have no data scrubbing rules')).toBeInTheDocument();
  62. });
  63. it('render disabled actions', function () {
  64. render(
  65. <DataScrubbing
  66. additionalContext={additionalContext}
  67. endpoint={endpoint}
  68. relayPiiConfig={relayPiiConfig}
  69. organization={organization}
  70. onSubmitSuccess={jest.fn()}
  71. disabled
  72. />
  73. );
  74. // Read Docs is the only enabled action
  75. expect(screen.getByRole('button', {name: 'Read Docs'})).toBeEnabled();
  76. expect(screen.getByRole('button', {name: 'Add Rule'})).toBeDisabled();
  77. for (const index in JSON.parse(relayPiiConfig).rules) {
  78. expect(screen.getAllByRole('button', {name: 'Edit Rule'})[index]).toBeDisabled();
  79. expect(
  80. screen.getAllByRole('button', {name: 'Delete Rule'})[index]
  81. ).toBeDisabled();
  82. }
  83. });
  84. });
  85. describe('Project level', function () {
  86. it('default render', function () {
  87. const {organization, project} = initializeOrg();
  88. render(
  89. <DataScrubbing
  90. endpoint={`/projects/${organization.slug}/foo/`}
  91. relayPiiConfig={relayPiiConfig}
  92. organization={organization}
  93. onSubmitSuccess={jest.fn()}
  94. project={project}
  95. />
  96. );
  97. // Header
  98. expect(
  99. screen.getByText('There are no data scrubbing rules at the organization level')
  100. ).toBeInTheDocument();
  101. });
  102. it('OrganizationRules has content', function () {
  103. const {organization, project} = initializeOrg({
  104. organization: {
  105. relayPiiConfig,
  106. },
  107. });
  108. render(
  109. <DataScrubbing
  110. endpoint={`/projects/${organization.slug}/foo/`}
  111. relayPiiConfig={relayPiiConfig}
  112. organization={organization}
  113. onSubmitSuccess={jest.fn()}
  114. project={project}
  115. />,
  116. {organization}
  117. );
  118. // Organization Rules
  119. expect(screen.getByText('Organization Rules')).toBeInTheDocument();
  120. });
  121. it('Delete rule successfully', async function () {
  122. const {organization, project} = initializeOrg();
  123. render(
  124. <Fragment>
  125. <GlobalModal />
  126. <DataScrubbing
  127. endpoint={`/projects/${organization.slug}/foo/`}
  128. project={project}
  129. relayPiiConfig={relayPiiConfig}
  130. disabled={false}
  131. organization={organization}
  132. onSubmitSuccess={jest.fn()}
  133. />
  134. </Fragment>
  135. );
  136. await userEvent.click(screen.getAllByLabelText('Delete Rule')[0]);
  137. expect(
  138. await screen.findByText('Are you sure you wish to delete this rule?')
  139. ).toBeInTheDocument();
  140. });
  141. it('Open Add Rule Modal', async function () {
  142. const {organization, project} = initializeOrg();
  143. render(
  144. <Fragment>
  145. <GlobalModal />
  146. <DataScrubbing
  147. endpoint={`/projects/${organization.slug}/foo/`}
  148. project={project}
  149. relayPiiConfig={relayPiiConfig}
  150. disabled={false}
  151. organization={organization}
  152. onSubmitSuccess={jest.fn()}
  153. />
  154. </Fragment>
  155. );
  156. await userEvent.click(screen.getByRole('button', {name: 'Add Rule'}));
  157. expect(
  158. await screen.findByText('Add an advanced data scrubbing rule')
  159. ).toBeInTheDocument();
  160. });
  161. it('Open Edit Rule Modal', async function () {
  162. const {organization, router, project} = initializeOrg();
  163. render(
  164. <Fragment>
  165. <GlobalModal />
  166. <DataScrubbing
  167. endpoint={`/projects/${organization.slug}/foo/`}
  168. project={project}
  169. relayPiiConfig={relayPiiConfig}
  170. disabled={false}
  171. organization={organization}
  172. onSubmitSuccess={jest.fn()}
  173. />
  174. </Fragment>,
  175. {router}
  176. );
  177. await userEvent.click(screen.getAllByRole('button', {name: 'Edit Rule'})[0]);
  178. // Verify the router to open the modal was called
  179. expect(router.push).toHaveBeenCalledWith(
  180. expect.objectContaining({
  181. pathname: `/settings/${organization.slug}/projects/${project.slug}/security-and-privacy/advanced-data-scrubbing/0/`,
  182. })
  183. );
  184. });
  185. });
  186. });