index.spec.tsx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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. ...initializeOrg(),
  105. organization: {
  106. ...initializeOrg().organization,
  107. relayPiiConfig,
  108. },
  109. });
  110. render(
  111. <DataScrubbing
  112. endpoint={`/projects/${organization.slug}/foo/`}
  113. relayPiiConfig={relayPiiConfig}
  114. organization={organization}
  115. onSubmitSuccess={jest.fn()}
  116. project={project}
  117. />,
  118. {organization}
  119. );
  120. // Organization Rules
  121. expect(screen.getByText('Organization Rules')).toBeInTheDocument();
  122. });
  123. it('Delete rule successfully', async function () {
  124. const {organization, project} = initializeOrg();
  125. render(
  126. <Fragment>
  127. <GlobalModal />
  128. <DataScrubbing
  129. endpoint={`/projects/${organization.slug}/foo/`}
  130. project={project}
  131. relayPiiConfig={relayPiiConfig}
  132. disabled={false}
  133. organization={organization}
  134. onSubmitSuccess={jest.fn()}
  135. />
  136. </Fragment>
  137. );
  138. await userEvent.click(screen.getAllByLabelText('Delete Rule')[0]);
  139. expect(
  140. await screen.findByText('Are you sure you wish to delete this rule?')
  141. ).toBeInTheDocument();
  142. });
  143. it('Open Add Rule Modal', async function () {
  144. const {organization, project} = initializeOrg();
  145. render(
  146. <Fragment>
  147. <GlobalModal />
  148. <DataScrubbing
  149. endpoint={`/projects/${organization.slug}/foo/`}
  150. project={project}
  151. relayPiiConfig={relayPiiConfig}
  152. disabled={false}
  153. organization={organization}
  154. onSubmitSuccess={jest.fn()}
  155. />
  156. </Fragment>
  157. );
  158. await userEvent.click(screen.getByRole('button', {name: 'Add Rule'}));
  159. expect(
  160. await screen.findByText('Add an advanced data scrubbing rule')
  161. ).toBeInTheDocument();
  162. });
  163. it('Open Edit Rule Modal', async function () {
  164. const {organization, router, project} = initializeOrg();
  165. render(
  166. <Fragment>
  167. <GlobalModal />
  168. <DataScrubbing
  169. endpoint={`/projects/${organization.slug}/foo/`}
  170. project={project}
  171. relayPiiConfig={relayPiiConfig}
  172. disabled={false}
  173. organization={organization}
  174. onSubmitSuccess={jest.fn()}
  175. />
  176. </Fragment>,
  177. {router}
  178. );
  179. await userEvent.click(screen.getAllByRole('button', {name: 'Edit Rule'})[0]);
  180. // Verify the router to open the modal was called
  181. expect(router.push).toHaveBeenCalledWith(
  182. expect.objectContaining({
  183. pathname: `/settings/${organization.slug}/projects/${project.slug}/security-and-privacy/advanced-data-scrubbing/0/`,
  184. })
  185. );
  186. });
  187. });
  188. });