projectPerformance.spec.jsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  2. import * as utils from 'sentry/utils/isActiveSuperuser';
  3. import ProjectPerformance from 'sentry/views/settings/projectPerformance/projectPerformance';
  4. describe('projectPerformance', function () {
  5. const org = TestStubs.Organization({
  6. features: [
  7. 'performance-view',
  8. 'performance-issues-dev',
  9. 'project-performance-settings-admin',
  10. ],
  11. });
  12. const project = TestStubs.ProjectDetails();
  13. const configUrl = '/projects/org-slug/project-slug/transaction-threshold/configure/';
  14. let getMock, postMock, deleteMock, performanceIssuesMock;
  15. beforeEach(function () {
  16. MockApiClient.clearMockResponses();
  17. getMock = MockApiClient.addMockResponse({
  18. url: configUrl,
  19. method: 'GET',
  20. body: {
  21. id: project.id,
  22. threshold: '300',
  23. metric: 'duration',
  24. },
  25. statusCode: 200,
  26. });
  27. postMock = MockApiClient.addMockResponse({
  28. url: configUrl,
  29. method: 'POST',
  30. body: {
  31. id: project.id,
  32. threshold: '400',
  33. metric: 'lcp',
  34. },
  35. statusCode: 200,
  36. });
  37. deleteMock = MockApiClient.addMockResponse({
  38. url: configUrl,
  39. method: 'DELETE',
  40. statusCode: 200,
  41. });
  42. MockApiClient.addMockResponse({
  43. url: '/projects/org-slug/project-slug/',
  44. method: 'GET',
  45. body: {},
  46. statusCode: 200,
  47. });
  48. performanceIssuesMock = MockApiClient.addMockResponse({
  49. url: '/projects/org-slug/project-slug/performance-issues/configure/',
  50. method: 'GET',
  51. body: {},
  52. statusCode: 200,
  53. });
  54. });
  55. it('renders the fields', function () {
  56. render(
  57. <ProjectPerformance
  58. params={{orgId: org.slug, projectId: project.slug}}
  59. organization={org}
  60. project={project}
  61. />
  62. );
  63. expect(
  64. screen.getByRole('textbox', {name: 'Response Time Threshold (ms)'})
  65. ).toHaveValue('300');
  66. expect(getMock).toHaveBeenCalledTimes(1);
  67. });
  68. it('updates the field', async function () {
  69. render(
  70. <ProjectPerformance
  71. params={{orgId: org.slug, projectId: project.slug}}
  72. organization={org}
  73. project={project}
  74. />
  75. );
  76. const input = screen.getByRole('textbox', {name: 'Response Time Threshold (ms)'});
  77. await userEvent.clear(input);
  78. await userEvent.type(input, '400');
  79. await userEvent.tab();
  80. expect(postMock).toHaveBeenCalledWith(
  81. configUrl,
  82. expect.objectContaining({
  83. data: {threshold: '400'},
  84. })
  85. );
  86. expect(input).toHaveValue('400');
  87. });
  88. it('clears the data', async function () {
  89. render(
  90. <ProjectPerformance
  91. params={{orgId: org.slug, projectId: project.slug}}
  92. organization={org}
  93. project={project}
  94. />
  95. );
  96. await userEvent.click(screen.getByRole('button', {name: 'Reset All'}));
  97. expect(deleteMock).toHaveBeenCalled();
  98. });
  99. it('does not get performance issues settings without the feature flag', function () {
  100. const orgWithoutPerfIssues = TestStubs.Organization({
  101. features: ['performance-view', 'performance-issues-dev'],
  102. });
  103. render(
  104. <ProjectPerformance
  105. params={{orgId: org.slug, projectId: project.slug}}
  106. organization={orgWithoutPerfIssues}
  107. project={project}
  108. />
  109. );
  110. expect(performanceIssuesMock).not.toHaveBeenCalled();
  111. });
  112. it('renders detector threshold configuration - admin ui', async function () {
  113. jest.spyOn(utils, 'isActiveSuperuser').mockReturnValue(true);
  114. render(
  115. <ProjectPerformance
  116. params={{orgId: org.slug, projectId: project.slug}}
  117. organization={org}
  118. project={project}
  119. />,
  120. {organization: org}
  121. );
  122. expect(
  123. await screen.findByText('N+1 DB Queries Detection Enabled')
  124. ).toBeInTheDocument();
  125. expect(screen.getByText('Slow DB Queries Detection Enabled')).toBeInTheDocument();
  126. expect(screen.getByText('N+1 API Calls Detection Enabled')).toBeInTheDocument();
  127. expect(
  128. screen.getByText('Consecutive HTTP Spans Detection Enabled')
  129. ).toBeInTheDocument();
  130. expect(
  131. screen.getByText('Consecutive DB Queries Detection Enabled')
  132. ).toBeInTheDocument();
  133. expect(screen.getByText('Large HTTP Payload Detection Enabled')).toBeInTheDocument();
  134. expect(screen.getByText('DB On Main Thread Detection Enabled')).toBeInTheDocument();
  135. expect(
  136. screen.getByText('File I/O on Main Thread Detection Enabled')
  137. ).toBeInTheDocument();
  138. expect(screen.getByText('Uncompressed Assets Detection Enabled')).toBeInTheDocument();
  139. expect(
  140. screen.getByText('Large Render Blocking Asset Detection Enabled')
  141. ).toBeInTheDocument();
  142. });
  143. });