transactionThresholdModal.spec.tsx 3.9 KB

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