transactionThresholdModal.spec.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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(screen.getByRole('spinbutton'));
  68. await userEvent.type(screen.getByRole('spinbutton'), '1000{enter}');
  69. await userEvent.click(screen.getByTestId('apply-threshold'));
  70. expect(postTransactionThresholdMock).toHaveBeenCalledWith(
  71. '/organizations/org-slug/project-transaction-threshold-override/',
  72. expect.objectContaining({
  73. data: {metric: 'lcp', threshold: '1000', transaction: 'transaction/threshold'},
  74. })
  75. );
  76. });
  77. it('can update metric', async function () {
  78. mountModal(eventView, organization, onApply);
  79. await selectEvent.select(
  80. screen.getByText('Largest Contentful Paint'),
  81. 'Transaction Duration'
  82. );
  83. await userEvent.click(screen.getByTestId('apply-threshold'));
  84. expect(postTransactionThresholdMock).toHaveBeenCalledWith(
  85. '/organizations/org-slug/project-transaction-threshold-override/',
  86. expect.objectContaining({
  87. data: {
  88. metric: 'duration',
  89. threshold: 400,
  90. transaction: 'transaction/threshold',
  91. },
  92. })
  93. );
  94. });
  95. it('can clear metrics', async function () {
  96. mountModal(eventView, organization, onApply);
  97. const deleteTransactionThresholdMock = MockApiClient.addMockResponse({
  98. url: '/organizations/org-slug/project-transaction-threshold-override/',
  99. method: 'DELETE',
  100. });
  101. const getProjectThresholdMock = MockApiClient.addMockResponse({
  102. url: '/projects/org-slug/project-slug/transaction-threshold/configure/',
  103. method: 'GET',
  104. body: {
  105. threshold: '200',
  106. metric: 'duration',
  107. },
  108. });
  109. await userEvent.click(screen.getByTestId('reset-all'));
  110. expect(deleteTransactionThresholdMock).toHaveBeenCalledTimes(1);
  111. // Replace with project fallback
  112. await waitFor(() => {
  113. expect(getProjectThresholdMock).toHaveBeenCalledTimes(1);
  114. });
  115. });
  116. });