dataScrubbing.spec.tsx 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. import {mountWithTheme} from 'sentry-test/enzyme';
  2. import {addSuccessMessage} from 'sentry/actionCreators/indicator';
  3. import {openModal} from 'sentry/actionCreators/modal';
  4. import DataScrubbing from 'sentry/views/settings/components/dataScrubbing';
  5. import {ProjectId} from 'sentry/views/settings/components/dataScrubbing/types';
  6. jest.mock('sentry/actionCreators/modal');
  7. const relayPiiConfig = TestStubs.DataScrubbingRelayPiiConfig();
  8. const stringRelayPiiConfig = JSON.stringify(relayPiiConfig);
  9. const organizationSlug = 'sentry';
  10. const handleUpdateOrganization = jest.fn();
  11. const additionalContext = 'These rules can be configured for each project.';
  12. jest.mock('sentry/actionCreators/indicator');
  13. function getOrganization(piiConfig?: string) {
  14. return TestStubs.Organization(
  15. piiConfig ? {id: '123', relayPiiConfig: piiConfig} : {id: '123'}
  16. );
  17. }
  18. function renderComponent({
  19. disabled,
  20. projectId,
  21. endpoint,
  22. ...props
  23. }: Partial<Omit<DataScrubbing<ProjectId>['props'], 'endpoint'>> &
  24. Pick<DataScrubbing<ProjectId>['props'], 'endpoint'>) {
  25. const organization = props.organization ?? getOrganization();
  26. if (projectId) {
  27. return mountWithTheme(
  28. <DataScrubbing
  29. additionalContext={additionalContext}
  30. endpoint={endpoint}
  31. projectId={projectId}
  32. relayPiiConfig={stringRelayPiiConfig}
  33. disabled={disabled}
  34. organization={organization}
  35. onSubmitSuccess={handleUpdateOrganization}
  36. />
  37. );
  38. }
  39. return mountWithTheme(
  40. <DataScrubbing
  41. additionalContext={additionalContext}
  42. endpoint={endpoint}
  43. relayPiiConfig={stringRelayPiiConfig}
  44. disabled={disabled}
  45. organization={organization}
  46. onSubmitSuccess={handleUpdateOrganization}
  47. />
  48. );
  49. }
  50. describe('Data Scrubbing', () => {
  51. describe('Organization level', () => {
  52. const endpoint = `organization/${organizationSlug}/`;
  53. it('default render', () => {
  54. const wrapper = renderComponent({disabled: false, endpoint});
  55. // PanelHeader
  56. expect(wrapper.find('PanelHeader').text()).toEqual('Advanced Data Scrubbing');
  57. // PanelAlert
  58. const panelAlert = wrapper.find('PanelAlert');
  59. expect(panelAlert.text()).toEqual(
  60. `${additionalContext} The new rules will only apply to upcoming events. For more details, see full documentation on data scrubbing.`
  61. );
  62. const readDocsLink = panelAlert.find('a');
  63. expect(readDocsLink.text()).toEqual('full documentation on data scrubbing');
  64. expect(readDocsLink.prop('href')).toEqual(
  65. 'https://docs.sentry.io/product/data-management-settings/scrubbing/advanced-datascrubbing/'
  66. );
  67. // PanelBody
  68. const panelBody = wrapper.find('PanelBody');
  69. expect(panelBody).toHaveLength(1);
  70. expect(panelBody.find('ListItem')).toHaveLength(3);
  71. // OrganizationRules
  72. const organizationRules = panelBody.find('OrganizationRules');
  73. expect(organizationRules).toHaveLength(0);
  74. // PanelAction
  75. const actionButtons = wrapper.find('PanelAction').find('Button');
  76. expect(actionButtons).toHaveLength(2);
  77. expect(actionButtons.at(0).text()).toEqual('Read Docs');
  78. expect(actionButtons.at(1).text()).toEqual('Add Rule');
  79. expect(actionButtons.at(1).prop('disabled')).toEqual(false);
  80. });
  81. it('render disabled', () => {
  82. const wrapper = renderComponent({disabled: true, endpoint});
  83. // PanelBody
  84. const panelBody = wrapper.find('PanelBody');
  85. expect(panelBody).toHaveLength(1);
  86. expect(panelBody.find('List').prop('isDisabled')).toEqual(true);
  87. // PanelAction
  88. const actionButtons = wrapper.find('PanelAction').find('StyledButton');
  89. expect(actionButtons).toHaveLength(2);
  90. expect(actionButtons.at(0).prop('disabled')).toEqual(false);
  91. expect(actionButtons.at(1).prop('disabled')).toEqual(true);
  92. });
  93. });
  94. describe('Project level', () => {
  95. const projectId = 'foo';
  96. const endpoint = `/projects/${organizationSlug}/${projectId}/`;
  97. it('default render', () => {
  98. const wrapper = renderComponent({
  99. disabled: false,
  100. projectId,
  101. endpoint,
  102. });
  103. // PanelHeader
  104. expect(wrapper.find('PanelHeader').text()).toEqual('Advanced Data Scrubbing');
  105. // PanelAlert
  106. const panelAlert = wrapper.find('PanelAlert');
  107. expect(panelAlert.text()).toEqual(
  108. `${additionalContext} The new rules will only apply to upcoming events. For more details, see full documentation on data scrubbing.`
  109. );
  110. const readDocsLink = panelAlert.find('a');
  111. expect(readDocsLink.text()).toEqual('full documentation on data scrubbing');
  112. expect(readDocsLink.prop('href')).toEqual(
  113. 'https://docs.sentry.io/product/data-management-settings/scrubbing/advanced-datascrubbing/'
  114. );
  115. // PanelBody
  116. const panelBody = wrapper.find('PanelBody');
  117. expect(panelBody).toHaveLength(1);
  118. expect(panelBody.find('ListItem')).toHaveLength(3);
  119. // OrganizationRules
  120. const organizationRules = panelBody.find('OrganizationRules');
  121. expect(organizationRules).toHaveLength(1);
  122. expect(organizationRules.text()).toEqual(
  123. 'There are no data scrubbing rules at the organization level'
  124. );
  125. // PanelAction
  126. const actionButtons = wrapper.find('PanelAction').find('Button');
  127. expect(actionButtons).toHaveLength(2);
  128. expect(actionButtons.at(0).text()).toEqual('Read Docs');
  129. expect(actionButtons.at(1).text()).toEqual('Add Rule');
  130. expect(actionButtons.at(1).prop('disabled')).toEqual(false);
  131. });
  132. it('render disabled', () => {
  133. const wrapper = renderComponent({disabled: true, endpoint});
  134. // PanelBody
  135. const panelBody = wrapper.find('PanelBody');
  136. expect(panelBody).toHaveLength(1);
  137. expect(panelBody.find('List').prop('isDisabled')).toEqual(true);
  138. // PanelAction
  139. const actionButtons = wrapper.find('PanelAction').find('StyledButton');
  140. expect(actionButtons).toHaveLength(2);
  141. expect(actionButtons.at(0).prop('disabled')).toEqual(false);
  142. expect(actionButtons.at(1).prop('disabled')).toEqual(true);
  143. });
  144. it('OrganizationRules has content', () => {
  145. const wrapper = renderComponent({
  146. disabled: false,
  147. organization: getOrganization(stringRelayPiiConfig),
  148. projectId,
  149. endpoint,
  150. });
  151. // OrganizationRules
  152. const organizationRules = wrapper.find('OrganizationRules');
  153. expect(organizationRules).toHaveLength(1);
  154. expect(organizationRules.find('Header').text()).toEqual('Organization Rules');
  155. const listItems = organizationRules.find('ListItem');
  156. expect(listItems).toHaveLength(3);
  157. expect(listItems.at(0).find('[role="button"]')).toHaveLength(0);
  158. });
  159. it('Delete rule successfully', async () => {
  160. const mockDelete = MockApiClient.addMockResponse({
  161. url: endpoint,
  162. method: 'PUT',
  163. body: getOrganization(
  164. JSON.stringify({...relayPiiConfig, rules: {0: relayPiiConfig.rules[0]}})
  165. ),
  166. });
  167. const wrapper = renderComponent({
  168. disabled: false,
  169. projectId,
  170. endpoint,
  171. });
  172. const listItems = wrapper.find('ListItem');
  173. const deleteButton = listItems.at(0).find('[aria-label="Delete Rule"]').hostNodes();
  174. deleteButton.simulate('click');
  175. expect(mockDelete).toHaveBeenCalled();
  176. await tick();
  177. wrapper.update();
  178. expect(wrapper.find('ListItem')).toHaveLength(1);
  179. expect(addSuccessMessage).toHaveBeenCalled();
  180. });
  181. it('Open Add Rule Modal', () => {
  182. const wrapper = renderComponent({
  183. disabled: false,
  184. projectId,
  185. endpoint,
  186. });
  187. const addbutton = wrapper
  188. .find('PanelAction')
  189. .find('[aria-label="Add Rule"]')
  190. .hostNodes();
  191. addbutton.simulate('click');
  192. expect(openModal).toHaveBeenCalled();
  193. });
  194. it('Open Edit Rule Modal', () => {
  195. const wrapper = renderComponent({
  196. disabled: false,
  197. projectId,
  198. endpoint,
  199. });
  200. const editButton = wrapper
  201. .find('PanelBody')
  202. .find('[aria-label="Edit Rule"]')
  203. .hostNodes();
  204. editButton.at(0).simulate('click');
  205. expect(openModal).toHaveBeenCalled();
  206. });
  207. });
  208. });