header.spec.tsx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import {initializeOrg} from 'sentry-test/initializeOrg';
  2. import {render, screen, waitFor} from 'sentry-test/reactTestingLibrary';
  3. import {Organization} from 'sentry/types';
  4. import EventView from 'sentry/utils/discover/eventView';
  5. import {OrganizationContext} from 'sentry/views/organizationContext';
  6. import TransactionHeader from 'sentry/views/performance/transactionSummary/header';
  7. import Tab from 'sentry/views/performance/transactionSummary/tabs';
  8. type InitialOpts = {
  9. features?: string[];
  10. platform?: string;
  11. };
  12. function initializeData(opts?: InitialOpts) {
  13. const {features, platform} = opts ?? {};
  14. const project = TestStubs.Project({platform});
  15. const organization = TestStubs.Organization({
  16. projects: [project],
  17. features,
  18. });
  19. const initialData = initializeOrg({
  20. organization,
  21. router: {
  22. location: {
  23. query: {
  24. project: project.id,
  25. },
  26. },
  27. },
  28. project: project.id,
  29. projects: [],
  30. });
  31. const router = initialData.router;
  32. const eventView = EventView.fromSavedQuery({
  33. id: undefined,
  34. version: 2,
  35. name: '',
  36. fields: ['transaction.status'], // unused fields
  37. projects: [parseInt(project.id, 10)],
  38. });
  39. return {
  40. project,
  41. organization,
  42. router,
  43. eventView,
  44. };
  45. }
  46. function ComponentProviders({
  47. organization,
  48. children,
  49. }: {
  50. children: React.ReactNode;
  51. organization: Organization;
  52. }) {
  53. return (
  54. <OrganizationContext.Provider value={organization}>
  55. {children}
  56. </OrganizationContext.Provider>
  57. );
  58. }
  59. describe('Performance > Transaction Summary Header', function () {
  60. beforeEach(function () {
  61. MockApiClient.clearMockResponses();
  62. });
  63. it('should render web vitals tab when yes', function () {
  64. const {project, organization, router, eventView} = initializeData();
  65. MockApiClient.addMockResponse({
  66. url: '/organizations/org-slug/events-has-measurements/',
  67. body: {measurements: true},
  68. });
  69. render(
  70. <ComponentProviders organization={organization}>
  71. <TransactionHeader
  72. eventView={eventView}
  73. location={router.location}
  74. organization={organization}
  75. projects={[project]}
  76. projectId={project.id}
  77. transactionName="transaction_name"
  78. currentTab={Tab.TransactionSummary}
  79. hasWebVitals="yes"
  80. />
  81. </ComponentProviders>
  82. );
  83. expect(screen.getByRole('tab', {name: 'Web Vitals'})).toBeInTheDocument();
  84. });
  85. it('should not render web vitals tab when no', function () {
  86. const {project, organization, router, eventView} = initializeData();
  87. MockApiClient.addMockResponse({
  88. url: '/organizations/org-slug/events-has-measurements/',
  89. body: {measurements: true},
  90. });
  91. <ComponentProviders organization={organization}>
  92. <TransactionHeader
  93. eventView={eventView}
  94. location={router.location}
  95. organization={organization}
  96. projects={[project]}
  97. projectId={project.id}
  98. transactionName="transaction_name"
  99. currentTab={Tab.TransactionSummary}
  100. hasWebVitals="no"
  101. />
  102. </ComponentProviders>;
  103. expect(screen.queryByRole('tab', {name: 'Web Vitals'})).not.toBeInTheDocument();
  104. });
  105. it('should render web vitals tab when maybe and is frontend platform', function () {
  106. const {project, organization, router, eventView} = initializeData({
  107. platform: 'javascript',
  108. });
  109. MockApiClient.addMockResponse({
  110. url: '/organizations/org-slug/events-has-measurements/',
  111. body: {measurements: true},
  112. });
  113. render(
  114. <ComponentProviders organization={organization}>
  115. <TransactionHeader
  116. eventView={eventView}
  117. location={router.location}
  118. organization={organization}
  119. projects={[project]}
  120. projectId={project.id}
  121. transactionName="transaction_name"
  122. currentTab={Tab.TransactionSummary}
  123. hasWebVitals="maybe"
  124. />
  125. </ComponentProviders>
  126. );
  127. expect(screen.getByRole('tab', {name: 'Web Vitals'})).toBeInTheDocument();
  128. });
  129. it('should render web vitals tab when maybe and has measurements', async function () {
  130. const {project, organization, router, eventView} = initializeData();
  131. const eventHasMeasurementsMock = MockApiClient.addMockResponse({
  132. url: '/organizations/org-slug/events-has-measurements/',
  133. body: {measurements: true},
  134. });
  135. render(
  136. <ComponentProviders organization={organization}>
  137. <TransactionHeader
  138. eventView={eventView}
  139. location={router.location}
  140. organization={organization}
  141. projects={[project]}
  142. projectId={project.id}
  143. transactionName="transaction_name"
  144. currentTab={Tab.TransactionSummary}
  145. hasWebVitals="maybe"
  146. />
  147. </ComponentProviders>
  148. );
  149. await waitFor(() => expect(eventHasMeasurementsMock).toHaveBeenCalled());
  150. expect(screen.getByRole('tab', {name: 'Web Vitals'})).toBeInTheDocument();
  151. });
  152. it('should not render web vitals tab when maybe and has no measurements', async function () {
  153. const {project, organization, router, eventView} = initializeData();
  154. const eventHasMeasurementsMock = MockApiClient.addMockResponse({
  155. url: '/organizations/org-slug/events-has-measurements/',
  156. body: {measurements: false},
  157. });
  158. render(
  159. <ComponentProviders organization={organization}>
  160. <TransactionHeader
  161. eventView={eventView}
  162. location={router.location}
  163. organization={organization}
  164. projects={[project]}
  165. projectId={project.id}
  166. transactionName="transaction_name"
  167. currentTab={Tab.TransactionSummary}
  168. hasWebVitals="maybe"
  169. />
  170. </ComponentProviders>
  171. );
  172. await waitFor(() => expect(eventHasMeasurementsMock).toHaveBeenCalled());
  173. expect(screen.queryByRole('tab', {name: 'Web Vitals'})).not.toBeInTheDocument();
  174. });
  175. it('should render spans tab with feature', function () {
  176. const {project, organization, router, eventView} = initializeData({
  177. features: ['performance-suspect-spans-view'],
  178. });
  179. MockApiClient.addMockResponse({
  180. url: '/organizations/org-slug/events-has-measurements/',
  181. body: {measurements: true},
  182. });
  183. render(
  184. <ComponentProviders organization={organization}>
  185. <TransactionHeader
  186. eventView={eventView}
  187. location={router.location}
  188. organization={organization}
  189. projects={[project]}
  190. projectId={project.id}
  191. transactionName="transaction_name"
  192. currentTab={Tab.TransactionSummary}
  193. hasWebVitals="yes"
  194. />
  195. </ComponentProviders>
  196. );
  197. expect(screen.getByRole('tab', {name: 'Spans'})).toBeInTheDocument();
  198. });
  199. });