metricsDataSwitcher.spec.tsx 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. import {addMetricsDataMock} from 'sentry-test/performance/addMetricsDataMock';
  2. import {initializeData} from 'sentry-test/performance/initializePerformanceData';
  3. import {makeTestQueryClient} from 'sentry-test/queryClient';
  4. import {act, render, screen} from 'sentry-test/reactTestingLibrary';
  5. import TeamStore from 'sentry/stores/teamStore';
  6. import {MetricsCardinalityProvider} from 'sentry/utils/performance/contexts/metricsCardinality';
  7. import {QueryClientProvider} from 'sentry/utils/queryClient';
  8. import {OrganizationContext} from 'sentry/views/organizationContext';
  9. import {generatePerformanceEventView} from 'sentry/views/performance/data';
  10. import {PerformanceLanding} from 'sentry/views/performance/landing';
  11. function WrappedComponent({data, withStaticFilters = true}) {
  12. const eventView = generatePerformanceEventView(
  13. data.router.location,
  14. data.projects,
  15. {
  16. withStaticFilters,
  17. },
  18. data.organization
  19. );
  20. return (
  21. <QueryClientProvider client={makeTestQueryClient()}>
  22. <OrganizationContext.Provider value={data.organization}>
  23. <MetricsCardinalityProvider
  24. location={data.router.location}
  25. organization={data.organization}
  26. >
  27. <PerformanceLanding
  28. router={data.router}
  29. organization={data.organization}
  30. location={data.router.location}
  31. eventView={eventView}
  32. projects={data.projects}
  33. selection={eventView.getPageFilters()}
  34. onboardingProject={undefined}
  35. handleSearch={() => {}}
  36. handleTrendsClick={() => {}}
  37. setError={() => {}}
  38. withStaticFilters={withStaticFilters}
  39. />
  40. </MetricsCardinalityProvider>
  41. </OrganizationContext.Provider>
  42. </QueryClientProvider>
  43. );
  44. }
  45. const features = [
  46. 'performance-transaction-name-only-search',
  47. 'organizations:performance-transaction-name-only-search',
  48. ];
  49. describe('Performance > Landing > MetricsDataSwitcher', function () {
  50. let wrapper: any;
  51. act(() => void TeamStore.loadInitialData([], false, null));
  52. beforeEach(function () {
  53. jest.spyOn(console, 'error').mockImplementation(jest.fn());
  54. MockApiClient.addMockResponse({
  55. url: '/organizations/org-slug/sdk-updates/',
  56. body: [],
  57. });
  58. MockApiClient.addMockResponse({
  59. url: '/prompts-activity/',
  60. body: {},
  61. });
  62. MockApiClient.addMockResponse({
  63. url: '/organizations/org-slug/projects/',
  64. body: [],
  65. });
  66. MockApiClient.addMockResponse({
  67. method: 'GET',
  68. url: `/organizations/org-slug/key-transactions-list/`,
  69. body: [],
  70. });
  71. MockApiClient.addMockResponse({
  72. method: 'GET',
  73. url: `/organizations/org-slug/legacy-key-transactions-count/`,
  74. body: [],
  75. });
  76. MockApiClient.addMockResponse({
  77. method: 'GET',
  78. url: `/organizations/org-slug/events-stats/`,
  79. body: [],
  80. });
  81. MockApiClient.addMockResponse({
  82. method: 'GET',
  83. url: `/organizations/org-slug/events-trends-stats/`,
  84. body: [],
  85. });
  86. MockApiClient.addMockResponse({
  87. method: 'GET',
  88. url: `/organizations/org-slug/events-histogram/`,
  89. body: [],
  90. });
  91. MockApiClient.addMockResponse({
  92. method: 'GET',
  93. url: `/organizations/org-slug/eventsv2/`,
  94. body: {
  95. meta: {
  96. id: 'string',
  97. },
  98. data: [
  99. {
  100. id: '1234',
  101. },
  102. ],
  103. },
  104. });
  105. });
  106. afterEach(function () {
  107. MockApiClient.clearMockResponses();
  108. jest.restoreAllMocks();
  109. if (wrapper) {
  110. wrapper.unmount();
  111. wrapper = undefined;
  112. }
  113. });
  114. it('renders basic UI elements', function () {
  115. addMetricsDataMock();
  116. const project = TestStubs.Project();
  117. const data = initializeData({
  118. project: project.id,
  119. projects: [project],
  120. features,
  121. });
  122. wrapper = render(<WrappedComponent data={data} />, data.routerContext);
  123. expect(screen.getByTestId('performance-landing-v3')).toBeInTheDocument();
  124. });
  125. it('renders with feature flag and all metric data', async function () {
  126. addMetricsDataMock();
  127. const project = TestStubs.Project();
  128. const data = initializeData({
  129. project: project.id,
  130. projects: [project],
  131. features,
  132. });
  133. wrapper = render(<WrappedComponent data={data} />, data.routerContext);
  134. expect(await screen.findByTestId('transaction-search-bar')).toBeInTheDocument();
  135. });
  136. it('renders with feature flag and checking dynamic sampled projects exist', async function () {
  137. addMetricsDataMock({
  138. metricsCount: 100,
  139. nullCount: 0,
  140. unparamCount: 0,
  141. });
  142. const project = TestStubs.Project();
  143. const data = initializeData({
  144. project: project.id,
  145. projects: [project],
  146. features,
  147. });
  148. wrapper = render(<WrappedComponent data={data} />, data.routerContext);
  149. expect(await screen.findByTestId('transaction-search-bar')).toBeInTheDocument();
  150. });
  151. it('renders with feature flag and any incompatible data', async function () {
  152. addMetricsDataMock({
  153. metricsCount: 100,
  154. nullCount: 1,
  155. unparamCount: 0,
  156. });
  157. const project = TestStubs.Project();
  158. const data = initializeData({
  159. project: project.id,
  160. projects: [project],
  161. features,
  162. });
  163. wrapper = render(<WrappedComponent data={data} />, data.routerContext);
  164. expect(await screen.findByTestId('transaction-search-bar')).toBeInTheDocument();
  165. expect(
  166. await screen.findByTestId('landing-mep-alert-single-project-incompatible')
  167. ).toBeInTheDocument();
  168. });
  169. it('renders with feature flag and any incompatible transactions on multiple projects with at least one compatible project', async function () {
  170. addMetricsDataMock({
  171. metricsCount: 100,
  172. nullCount: 1,
  173. unparamCount: 0,
  174. compatibleProjects: [1],
  175. });
  176. const project = TestStubs.Project({id: 1});
  177. const project2 = TestStubs.Project({id: 2});
  178. const data = initializeData({
  179. project: '-1',
  180. projects: [project, project2],
  181. features,
  182. });
  183. wrapper = render(<WrappedComponent data={data} />, data.routerContext);
  184. expect(await screen.findByTestId('transaction-search-bar')).toBeInTheDocument();
  185. expect(
  186. await screen.findByTestId('landing-mep-alert-multi-project-incompatible')
  187. ).toBeInTheDocument();
  188. });
  189. it('renders with feature flag and any incompatible transactions on multiple projects with no compatible project', async function () {
  190. addMetricsDataMock({
  191. metricsCount: 100,
  192. nullCount: 1,
  193. unparamCount: 0,
  194. compatibleProjects: [],
  195. });
  196. const project = TestStubs.Project({id: 1});
  197. const project2 = TestStubs.Project({id: 2});
  198. const data = initializeData({
  199. project: '-1',
  200. projects: [project, project2],
  201. features,
  202. });
  203. wrapper = render(<WrappedComponent data={data} />, data.routerContext);
  204. expect(await screen.findByTestId('transaction-search-bar')).toBeInTheDocument();
  205. expect(
  206. await screen.findByTestId('landing-mep-alert-multi-project-all-incompatible')
  207. ).toBeInTheDocument();
  208. });
  209. it('renders with feature flag and all other(unparam) transactions', async function () {
  210. addMetricsDataMock({
  211. metricsCount: 100,
  212. nullCount: 0,
  213. unparamCount: 100,
  214. });
  215. const project = TestStubs.Project();
  216. const data = initializeData({
  217. project: project.id,
  218. projects: [project],
  219. features,
  220. });
  221. wrapper = render(<WrappedComponent data={data} />, data.routerContext);
  222. expect(await screen.findByTestId('transaction-search-bar')).toBeInTheDocument();
  223. expect(
  224. await screen.findByTestId('landing-mep-alert-unnamed-discover')
  225. ).toBeInTheDocument();
  226. });
  227. it('renders with feature flag and partial other(unparam) transactions and platform with docs', async function () {
  228. addMetricsDataMock({
  229. metricsCount: 100,
  230. nullCount: 0,
  231. unparamCount: 1,
  232. });
  233. const platformWithDocs = 'javascript.react';
  234. const project = TestStubs.Project({platform: platformWithDocs});
  235. const data = initializeData({
  236. project: project.id,
  237. projects: [project],
  238. features,
  239. });
  240. wrapper = render(<WrappedComponent data={data} />, data.routerContext);
  241. expect(await screen.findByTestId('transaction-search-bar')).toBeInTheDocument();
  242. expect(
  243. await screen.findByTestId('landing-mep-alert-unnamed-discover-or-set')
  244. ).toBeInTheDocument();
  245. });
  246. it('renders with feature flag and partial other(unparam) transactions', async function () {
  247. addMetricsDataMock({
  248. metricsCount: 100,
  249. nullCount: 0,
  250. unparamCount: 1,
  251. });
  252. const project = TestStubs.Project();
  253. const data = initializeData({
  254. project: project.id,
  255. projects: [project],
  256. features,
  257. });
  258. wrapper = render(<WrappedComponent data={data} />, data.routerContext);
  259. expect(await screen.findByTestId('transaction-search-bar')).toBeInTheDocument();
  260. expect(
  261. await screen.findByTestId('landing-mep-alert-unnamed-discover')
  262. ).toBeInTheDocument();
  263. });
  264. });