content.spec.tsx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import type {InjectedRouter} from 'react-router';
  2. import {OrganizationFixture} from 'sentry-fixture/organization';
  3. import {ProjectFixture} from 'sentry-fixture/project';
  4. import {RouterContextFixture} from 'sentry-fixture/routerContextFixture';
  5. import {initializeOrg} from 'sentry-test/initializeOrg';
  6. import {render, screen} from 'sentry-test/reactTestingLibrary';
  7. import EventView from 'sentry/utils/discover/eventView';
  8. import {MEPSettingProvider} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
  9. import {OrganizationContext} from 'sentry/views/organizationContext';
  10. import {SpanOperationBreakdownFilter} from 'sentry/views/performance/transactionSummary/filter';
  11. import SummaryContent from 'sentry/views/performance/transactionSummary/transactionOverview/content';
  12. import {RouteContext} from 'sentry/views/routeContext';
  13. function initialize(project, query, additionalFeatures: string[] = []) {
  14. const features = ['transaction-event', 'performance-view', ...additionalFeatures];
  15. const organization = OrganizationFixture({
  16. features,
  17. projects: [project],
  18. });
  19. const initialData = initializeOrg({
  20. organization,
  21. router: {
  22. location: {
  23. query: {...query},
  24. },
  25. },
  26. projects: [],
  27. });
  28. const eventView = EventView.fromNewQueryWithLocation(
  29. {
  30. id: undefined,
  31. version: 2,
  32. name: 'test-transaction',
  33. fields: ['id', 'user.display', 'transaction.duration', 'trace', 'timestamp'],
  34. projects: [],
  35. },
  36. initialData.router.location
  37. );
  38. const spanOperationBreakdownFilter = SpanOperationBreakdownFilter.NONE;
  39. const transactionName = 'example-transaction';
  40. return {
  41. ...initialData,
  42. spanOperationBreakdownFilter,
  43. transactionName,
  44. location: initialData.router.location,
  45. eventView,
  46. };
  47. }
  48. function WrappedComponent({
  49. organization,
  50. router,
  51. ...props
  52. }: React.ComponentProps<typeof SummaryContent> & {
  53. router: InjectedRouter<Record<string, string>, any>;
  54. }) {
  55. return (
  56. <OrganizationContext.Provider value={organization}>
  57. <RouteContext.Provider value={{router, ...router}}>
  58. <MEPSettingProvider>
  59. <SummaryContent organization={organization} {...props} />
  60. </MEPSettingProvider>
  61. </RouteContext.Provider>
  62. </OrganizationContext.Provider>
  63. );
  64. }
  65. describe('Transaction Summary Content', function () {
  66. beforeEach(function () {
  67. MockApiClient.addMockResponse({
  68. method: 'GET',
  69. url: '/organizations/org-slug/prompts-activity/',
  70. body: {},
  71. });
  72. MockApiClient.addMockResponse({
  73. url: '/organizations/org-slug/sdk-updates/',
  74. body: [],
  75. });
  76. MockApiClient.addMockResponse({
  77. url: '/organizations/org-slug/events/',
  78. body: {data: [{'event.type': 'error'}], meta: {fields: {'event.type': 'string'}}},
  79. });
  80. MockApiClient.addMockResponse({
  81. url: '/organizations/org-slug/users/',
  82. body: [],
  83. });
  84. MockApiClient.addMockResponse({
  85. url: '/organizations/org-slug/issues/?limit=5&query=is%3Aunresolved%20transaction%3Aexample-transaction&sort=trends&statsPeriod=14d',
  86. body: [],
  87. });
  88. MockApiClient.addMockResponse({
  89. url: '/organizations/org-slug/events-facets/',
  90. body: [],
  91. });
  92. MockApiClient.addMockResponse({
  93. url: '/organizations/org-slug/releases/stats/',
  94. body: [],
  95. });
  96. MockApiClient.addMockResponse({
  97. url: '/organizations/org-slug/events-stats/',
  98. body: [],
  99. });
  100. MockApiClient.addMockResponse({
  101. url: '/organizations/org-slug/events-facets-performance/',
  102. body: {},
  103. });
  104. MockApiClient.addMockResponse({
  105. url: '/organizations/org-slug/events-has-measurements/',
  106. body: {measurements: false},
  107. });
  108. MockApiClient.addMockResponse({
  109. url: '/organizations/org-slug/events-spans-performance/',
  110. body: [
  111. {
  112. op: 'ui.long-task',
  113. group: 'c777169faad84eb4',
  114. description: 'Main UI thread blocked',
  115. frequency: 713,
  116. count: 9040,
  117. avgOccurrences: null,
  118. sumExclusiveTime: 1743893.9822921753,
  119. p50ExclusiveTime: null,
  120. p75ExclusiveTime: 244.9998779296875,
  121. p95ExclusiveTime: null,
  122. p99ExclusiveTime: null,
  123. },
  124. ],
  125. });
  126. MockApiClient.addMockResponse({
  127. url: `/projects/org-slug/project-slug/profiling/functions/`,
  128. body: {functions: []},
  129. });
  130. MockApiClient.addMockResponse({
  131. url: '/organizations/org-slug/dynamic-sampling/custom-rules/',
  132. body: '',
  133. });
  134. });
  135. afterEach(function () {
  136. MockApiClient.clearMockResponses();
  137. });
  138. it('performs basic rendering', async function () {
  139. const project = ProjectFixture();
  140. const {
  141. organization,
  142. location,
  143. eventView,
  144. spanOperationBreakdownFilter,
  145. transactionName,
  146. router,
  147. } = initialize(project, {});
  148. const routerContext = RouterContextFixture([{organization}]);
  149. render(
  150. <WrappedComponent
  151. location={location}
  152. organization={organization}
  153. eventView={eventView}
  154. projectId={project.id}
  155. transactionName={transactionName}
  156. isLoading={false}
  157. totalValues={null}
  158. spanOperationBreakdownFilter={spanOperationBreakdownFilter}
  159. error={null}
  160. onChangeFilter={() => {}}
  161. router={router}
  162. />,
  163. {context: routerContext}
  164. );
  165. expect(
  166. await screen.findByTestId('page-filter-environment-selector')
  167. ).toBeInTheDocument();
  168. expect(screen.getByTestId('page-filter-timerange-selector')).toBeInTheDocument();
  169. expect(screen.getByTestId('smart-search-bar')).toBeInTheDocument();
  170. expect(screen.getByTestId('transaction-summary-charts')).toBeInTheDocument();
  171. expect(screen.getByRole('heading', {name: /user misery/i})).toBeInTheDocument();
  172. expect(screen.getByRole('heading', {name: /status breakdown/i})).toBeInTheDocument();
  173. expect(screen.getByRole('heading', {name: /apdex/i})).toBeInTheDocument();
  174. expect(screen.getByTestId('apdex-summary-value')).toBeInTheDocument();
  175. expect(screen.getByRole('heading', {name: /failure rate/i})).toBeInTheDocument();
  176. expect(screen.getByTestId('failure-rate-summary-value')).toBeInTheDocument();
  177. });
  178. });