index.spec.tsx 6.6 KB

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