index.spec.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import {browserHistory} from 'react-router';
  2. import {
  3. initializeData as _initializeData,
  4. InitializeDataSettings,
  5. } from 'sentry-test/performance/initializePerformanceData';
  6. import {act, render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  7. import ProjectsStore from 'sentry/stores/projectsStore';
  8. import {MEPSettingProvider} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
  9. import TransactionEvents from 'sentry/views/performance/transactionSummary/transactionEvents';
  10. import {EVENTS_TABLE_RESPONSE_FIELDS, MOCK_EVENTS_TABLE_DATA} from './eventsTable.spec';
  11. function WrappedComponent({data}) {
  12. return (
  13. <MEPSettingProvider>
  14. <TransactionEvents
  15. organization={data.organization}
  16. location={data.router.location}
  17. />
  18. </MEPSettingProvider>
  19. );
  20. }
  21. const setupMockApiResponeses = () => {
  22. MockApiClient.addMockResponse({
  23. url: '/organizations/org-slug/events-has-measurements/',
  24. body: {measurements: false},
  25. });
  26. MockApiClient.addMockResponse({
  27. url: '/organizations/org-slug/events/',
  28. body: {
  29. data: [
  30. {
  31. 'p100()': 9500,
  32. 'p99()': 9000,
  33. 'p95()': 7000,
  34. 'p75()': 5000,
  35. 'p50()': 500,
  36. },
  37. ],
  38. meta: {
  39. fields: {
  40. 'p100()': 'duration',
  41. 'p99()': 'duration',
  42. 'p95()': 'duration',
  43. 'p75()': 'duration',
  44. 'p50()': 'duration',
  45. },
  46. },
  47. },
  48. match: [
  49. (_, options) => {
  50. return options.query?.field?.includes('p95()');
  51. },
  52. ],
  53. });
  54. MockApiClient.addMockResponse({
  55. url: '/organizations/org-slug/events/',
  56. body: {
  57. data: [
  58. {
  59. 'count()': 4000,
  60. },
  61. ],
  62. meta: {
  63. fields: {
  64. 'count()': 'integer',
  65. },
  66. },
  67. },
  68. match: [
  69. (_, options) => {
  70. return options.query?.field?.includes('count()');
  71. },
  72. ],
  73. });
  74. MockApiClient.addMockResponse({
  75. url: '/organizations/org-slug/events/',
  76. body: {
  77. data: [
  78. {
  79. 'count()': 4000,
  80. },
  81. ],
  82. meta: {
  83. fields: {
  84. 'count()': 'integer',
  85. },
  86. },
  87. },
  88. match: [(_, options) => options.query?.field?.includes('count()')],
  89. });
  90. MockApiClient.addMockResponse({
  91. url: '/organizations/org-slug/events/',
  92. body: {
  93. data: MOCK_EVENTS_TABLE_DATA,
  94. meta: {
  95. fields: EVENTS_TABLE_RESPONSE_FIELDS,
  96. },
  97. },
  98. match: [
  99. (_, options) =>
  100. options.query?.field?.includes('transaction.duration') &&
  101. !options.query?.query.includes('transaction.duration'),
  102. ],
  103. });
  104. MockApiClient.addMockResponse({
  105. url: '/organizations/org-slug/events/',
  106. body: {
  107. data: [MOCK_EVENTS_TABLE_DATA[0]],
  108. meta: {
  109. fields: EVENTS_TABLE_RESPONSE_FIELDS,
  110. },
  111. },
  112. match: [
  113. (_, options) =>
  114. options.query?.field?.includes('transaction.duration') &&
  115. options.query?.query.includes('transaction.duration:<=500'), // 500 refers to p50 value
  116. ],
  117. });
  118. };
  119. const initializeData = (settings?: InitializeDataSettings) => {
  120. settings = {
  121. features: ['performance-view'],
  122. query: {project: '1', transaction: 'transaction'},
  123. ...settings,
  124. };
  125. const data = _initializeData(settings);
  126. act(() => void ProjectsStore.loadInitialData(data.organization.projects));
  127. return data;
  128. };
  129. describe('Performance > Transaction Summary > Transaction Events > Index', () => {
  130. beforeEach(setupMockApiResponeses);
  131. afterEach(() => {
  132. MockApiClient.clearMockResponses();
  133. jest.clearAllMocks();
  134. });
  135. it('should contain all transaction events', async () => {
  136. const data = initializeData();
  137. render(<WrappedComponent data={data} />, {context: data.routerContext});
  138. expect(await screen.findByText('uhoh@example.com')).toBeInTheDocument();
  139. expect(await screen.findByText('moreuhoh@example.com')).toBeInTheDocument();
  140. });
  141. it('should filter the transaction duration if in query', async () => {
  142. const data = initializeData({
  143. query: {project: '1', transaction: 'transaction', showTransactions: 'p50'},
  144. });
  145. render(<WrappedComponent data={data} />, {context: data.routerContext});
  146. expect(await screen.findByText('uhoh@example.com')).toBeInTheDocument();
  147. expect(screen.queryByText('moreuhoh@example.com')).not.toBeInTheDocument();
  148. });
  149. it('should update transaction percentile query if selected', async () => {
  150. const data = initializeData();
  151. render(<WrappedComponent data={data} />, {context: data.routerContext});
  152. const percentileButton = await screen.findByRole('button', {
  153. name: /percentile p100/i,
  154. });
  155. await userEvent.click(percentileButton);
  156. const p50 = screen.getByRole('option', {name: 'p50'});
  157. expect(p50).toBeInTheDocument();
  158. await userEvent.click(p50);
  159. expect(browserHistory.push).toHaveBeenCalledWith(
  160. expect.objectContaining({query: expect.objectContaining({showTransactions: 'p50'})})
  161. );
  162. });
  163. });