transactionThresholdModal.spec.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import selectEvent from 'react-select-event';
  2. import {Organization} from 'sentry-fixture/organization';
  3. import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
  4. import {
  5. makeClosableHeader,
  6. makeCloseButton,
  7. ModalBody,
  8. ModalFooter,
  9. } from 'sentry/components/globalModal/components';
  10. import ProjectsStore from 'sentry/stores/projectsStore';
  11. import {Organization as TOrganization} from 'sentry/types';
  12. import EventView from 'sentry/utils/discover/eventView';
  13. import TransactionThresholdModal, {
  14. TransactionThresholdMetric,
  15. } from 'sentry/views/performance/transactionSummary/transactionThresholdModal';
  16. function mountModal(
  17. eventView: EventView,
  18. organization: TOrganization,
  19. onApply: React.ComponentProps<typeof TransactionThresholdModal>['onApply']
  20. ) {
  21. render(
  22. <TransactionThresholdModal
  23. Body={ModalBody}
  24. closeModal={jest.fn()}
  25. CloseButton={makeCloseButton(jest.fn())}
  26. Header={makeClosableHeader(jest.fn())}
  27. Footer={ModalFooter}
  28. eventView={eventView}
  29. organization={organization}
  30. transactionName="transaction/threshold"
  31. transactionThreshold={400}
  32. transactionThresholdMetric={TransactionThresholdMetric.LARGEST_CONTENTFUL_PAINT}
  33. onApply={onApply}
  34. />
  35. );
  36. }
  37. describe('TransactionThresholdModal', function () {
  38. const organization = Organization({features: ['performance-view']});
  39. const project = TestStubs.Project();
  40. const eventView = EventView.fromSavedQuery({
  41. id: '1',
  42. version: 2,
  43. name: 'my query',
  44. fields: ['count()'],
  45. orderby: '-count',
  46. query: '',
  47. projects: [project.id],
  48. start: '2019-10-01T00:00:00',
  49. end: '2019-10-02T00:00:00',
  50. environment: [],
  51. });
  52. const onApply = jest.fn();
  53. let postTransactionThresholdMock;
  54. beforeEach(function () {
  55. MockApiClient.clearMockResponses();
  56. ProjectsStore.loadInitialData([project]);
  57. postTransactionThresholdMock = MockApiClient.addMockResponse({
  58. url: '/organizations/org-slug/project-transaction-threshold-override/',
  59. method: 'POST',
  60. body: {
  61. data: [],
  62. },
  63. });
  64. });
  65. it('can update threshold', async function () {
  66. mountModal(eventView, organization, onApply);
  67. await userEvent.clear(await screen.findByRole('spinbutton'));
  68. await userEvent.type(screen.getByRole('spinbutton'), '1000{enter}');
  69. await userEvent.click(screen.getByTestId('apply-threshold'));
  70. await waitFor(() => {
  71. expect(postTransactionThresholdMock).toHaveBeenCalledWith(
  72. '/organizations/org-slug/project-transaction-threshold-override/',
  73. expect.objectContaining({
  74. data: {metric: 'lcp', threshold: '1000', transaction: 'transaction/threshold'},
  75. })
  76. );
  77. });
  78. });
  79. it('can update metric', async function () {
  80. mountModal(eventView, organization, onApply);
  81. await selectEvent.select(
  82. await screen.findByText('Largest Contentful Paint'),
  83. 'Transaction Duration'
  84. );
  85. await userEvent.click(screen.getByTestId('apply-threshold'));
  86. await waitFor(() => {
  87. expect(postTransactionThresholdMock).toHaveBeenCalledWith(
  88. '/organizations/org-slug/project-transaction-threshold-override/',
  89. expect.objectContaining({
  90. data: {
  91. metric: 'duration',
  92. threshold: 400,
  93. transaction: 'transaction/threshold',
  94. },
  95. })
  96. );
  97. });
  98. });
  99. it('can clear metrics', async function () {
  100. mountModal(eventView, organization, onApply);
  101. const deleteTransactionThresholdMock = MockApiClient.addMockResponse({
  102. url: '/organizations/org-slug/project-transaction-threshold-override/',
  103. method: 'DELETE',
  104. });
  105. const getProjectThresholdMock = MockApiClient.addMockResponse({
  106. url: '/projects/org-slug/project-slug/transaction-threshold/configure/',
  107. method: 'GET',
  108. body: {
  109. threshold: '200',
  110. metric: 'duration',
  111. },
  112. });
  113. await userEvent.click(await screen.findByTestId('reset-all'));
  114. expect(deleteTransactionThresholdMock).toHaveBeenCalledTimes(1);
  115. // Replace with project fallback
  116. await waitFor(() => {
  117. expect(getProjectThresholdMock).toHaveBeenCalledTimes(1);
  118. });
  119. });
  120. });