frontendOverviewPage.spec.tsx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. import {OrganizationFixture} from 'sentry-fixture/organization';
  2. import {PageFiltersFixture} from 'sentry-fixture/pageFilters';
  3. import {ProjectFixture} from 'sentry-fixture/project';
  4. import {render, screen} from 'sentry-test/reactTestingLibrary';
  5. import {useLocation} from 'sentry/utils/useLocation';
  6. import useOrganization from 'sentry/utils/useOrganization';
  7. import usePageFilters from 'sentry/utils/usePageFilters';
  8. import useProjects from 'sentry/utils/useProjects';
  9. import {useOnboardingProject} from 'sentry/views/insights/common/queries/useOnboardingProject';
  10. import FrontendOverviewPage from 'sentry/views/insights/pages/frontend/frontendOverviewPage';
  11. jest.mock('sentry/utils/usePageFilters');
  12. jest.mock('sentry/utils/useLocation');
  13. jest.mock('sentry/utils/useOrganization');
  14. jest.mock('sentry/utils/useProjects');
  15. jest.mock('sentry/views/insights/common/queries/useOnboardingProject');
  16. const organization = OrganizationFixture({features: ['performance-view']});
  17. const pageFilterSelection = PageFiltersFixture({
  18. projects: [1, 2],
  19. datetime: {
  20. period: '14d',
  21. start: null,
  22. end: null,
  23. utc: false,
  24. },
  25. });
  26. const projects = [
  27. ProjectFixture({id: '1', platform: 'javascript-react'}),
  28. ProjectFixture({id: '2', platform: undefined}),
  29. ];
  30. let mainTableApiCall: jest.Mock;
  31. describe('FrontendOverviewPage', () => {
  32. beforeEach(() => {
  33. jest.clearAllMocks();
  34. setupMocks();
  35. });
  36. describe('data fetching', () => {
  37. it('fetches correct data with unkown + frontend platform', async () => {
  38. render(<FrontendOverviewPage />);
  39. expect(await screen.findByRole('heading', {level: 1})).toHaveTextContent(
  40. 'Frontend'
  41. );
  42. expect(mainTableApiCall).toHaveBeenCalledWith(
  43. '/organizations/org-slug/events/',
  44. expect.objectContaining({
  45. query: expect.objectContaining({
  46. query:
  47. '( transaction.op:pageload OR transaction.op:navigation OR transaction.op:ui.render OR transaction.op:interaction ) OR project.id:[1] event.type:transaction',
  48. }),
  49. })
  50. );
  51. });
  52. it('fetches correct data with unknown platform', async () => {
  53. jest.mocked(usePageFilters).mockReturnValue({
  54. isReady: true,
  55. desyncedFilters: new Set(),
  56. pinnedFilters: new Set(),
  57. shouldPersist: true,
  58. selection: {
  59. projects: [2],
  60. datetime: pageFilterSelection.datetime,
  61. environments: [],
  62. },
  63. });
  64. render(<FrontendOverviewPage />);
  65. expect(await screen.findByRole('heading', {level: 1})).toHaveTextContent(
  66. 'Frontend'
  67. );
  68. expect(mainTableApiCall).toHaveBeenCalledWith(
  69. '/organizations/org-slug/events/',
  70. expect.objectContaining({
  71. query: expect.objectContaining({
  72. query:
  73. '( transaction.op:pageload OR transaction.op:navigation OR transaction.op:ui.render OR transaction.op:interaction ) event.type:transaction',
  74. }),
  75. })
  76. );
  77. });
  78. });
  79. });
  80. const setupMocks = () => {
  81. mainTableApiCall = MockApiClient.addMockResponse({
  82. url: '/organizations/org-slug/events/',
  83. body: {
  84. data: [],
  85. meta: {
  86. fields: {
  87. 'transaction.op': 'string',
  88. transaction: 'string',
  89. project: 'string',
  90. team_key_transaction: 'boolean',
  91. 'p95(transaction.duration)': 'duration',
  92. 'p75(transaction.duration)': 'duration',
  93. 'tpm()': 'rate',
  94. 'p50(transaction.duration)': 'duration',
  95. 'user_misery()': 'number',
  96. 'count_unique(user)': 'integer',
  97. 'count_miserable(user)': 'integer',
  98. },
  99. units: {
  100. 'transaction.op': null,
  101. transaction: null,
  102. project: null,
  103. team_key_transaction: null,
  104. 'p95(transaction.duration)': 'millisecond',
  105. 'p75(transaction.duration)': 'millisecond',
  106. 'tpm()': '1/minute',
  107. 'p50(transaction.duration)': 'millisecond',
  108. 'user_misery()': null,
  109. 'count_unique(user)': null,
  110. 'count_miserable(user)': null,
  111. },
  112. isMetricsData: true,
  113. isMetricsExtractedData: false,
  114. tips: {},
  115. datasetReason: 'unchanged',
  116. dataset: 'metrics',
  117. },
  118. },
  119. match: [MockApiClient.matchQuery({referrer: 'api.performance.landing-table'})],
  120. });
  121. mainTableApiCall = MockApiClient.addMockResponse({
  122. url: '/organizations/org-slug/events/',
  123. body: {
  124. data: [],
  125. },
  126. });
  127. MockApiClient.addMockResponse({
  128. url: '/organizations/org-slug/events-stats/',
  129. body: {
  130. data: [],
  131. meta: {
  132. fields: {
  133. 'transaction.op': 'string',
  134. transaction: 'string',
  135. project: 'string',
  136. team_key_transaction: 'boolean',
  137. 'p95(transaction.duration)': 'duration',
  138. 'p75(transaction.duration)': 'duration',
  139. 'tpm()': 'rate',
  140. 'p50(transaction.duration)': 'duration',
  141. 'user_misery()': 'number',
  142. 'count_unique(user)': 'integer',
  143. 'count_miserable(user)': 'integer',
  144. },
  145. units: {
  146. 'transaction.op': null,
  147. transaction: null,
  148. project: null,
  149. team_key_transaction: null,
  150. 'p95(transaction.duration)': 'millisecond',
  151. 'p75(transaction.duration)': 'millisecond',
  152. 'tpm()': '1/minute',
  153. 'p50(transaction.duration)': 'millisecond',
  154. 'user_misery()': null,
  155. 'count_unique(user)': null,
  156. 'count_miserable(user)': null,
  157. },
  158. isMetricsData: true,
  159. isMetricsExtractedData: false,
  160. tips: {},
  161. datasetReason: 'unchanged',
  162. dataset: 'metrics',
  163. },
  164. },
  165. });
  166. MockApiClient.addMockResponse({
  167. url: '/organizations/org-slug/events-histogram/',
  168. body: {data: [], meta: []},
  169. });
  170. MockApiClient.addMockResponse({
  171. url: '/organizations/org-slug/key-transactions-list/',
  172. body: [],
  173. });
  174. jest.mocked(useLocation).mockReturnValue({
  175. pathname: '/insights/backend/http/',
  176. search: '',
  177. query: {statsPeriod: '10d', 'span.domain': 'git', project: '1'},
  178. hash: '',
  179. state: undefined,
  180. action: 'PUSH',
  181. key: '',
  182. });
  183. jest.mocked(useOrganization).mockReturnValue(organization);
  184. jest.mocked(usePageFilters).mockReturnValue({
  185. isReady: true,
  186. desyncedFilters: new Set(),
  187. pinnedFilters: new Set(),
  188. shouldPersist: true,
  189. selection: pageFilterSelection,
  190. });
  191. jest.mocked(useProjects).mockReturnValue({
  192. projects,
  193. fetchError: null,
  194. hasMore: false,
  195. initiallyLoaded: true,
  196. onSearch: () => Promise.resolve(),
  197. reloadProjects: jest.fn(),
  198. placeholders: [],
  199. fetching: false,
  200. });
  201. jest.mocked(useOnboardingProject).mockReturnValue(undefined);
  202. };