metricsDataSwitcher.spec.tsx 8.9 KB

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