projectPerformance.spec.jsx 4.6 KB

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