metricsDataSwitcher.spec.tsx 9.2 KB

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