metricsDataSwitcher.spec.tsx 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. import {ProjectFixture} from 'sentry-fixture/project';
  2. import {addMetricsDataMock} from 'sentry-test/performance/addMetricsDataMock';
  3. import {initializeData} from 'sentry-test/performance/initializePerformanceData';
  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 {generatePerformanceEventView} from 'sentry/views/performance/data';
  8. import {PerformanceLanding} from 'sentry/views/performance/landing';
  9. function WrappedComponent({
  10. data,
  11. withStaticFilters = true,
  12. }: {
  13. data: any;
  14. withStaticFilters?: boolean;
  15. }) {
  16. const eventView = generatePerformanceEventView(
  17. data.router.location,
  18. data.projects,
  19. {
  20. withStaticFilters,
  21. },
  22. data.organization
  23. );
  24. return (
  25. <MetricsCardinalityProvider
  26. location={data.router.location}
  27. organization={data.organization}
  28. >
  29. <PerformanceLanding
  30. router={data.router}
  31. organization={data.organization}
  32. location={data.router.location}
  33. eventView={eventView}
  34. projects={data.projects}
  35. selection={eventView.getPageFilters()}
  36. onboardingProject={undefined}
  37. handleSearch={() => {}}
  38. handleTrendsClick={() => {}}
  39. setError={() => {}}
  40. withStaticFilters={withStaticFilters}
  41. />
  42. </MetricsCardinalityProvider>
  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: '/organizations/org-slug/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 = ProjectFixture();
  117. const data = initializeData({
  118. project: project.id,
  119. projects: [project],
  120. features,
  121. });
  122. wrapper = render(<WrappedComponent data={data} />, {organization: data.organization});
  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 = ProjectFixture();
  128. const data = initializeData({
  129. project: project.id,
  130. projects: [project],
  131. features,
  132. });
  133. wrapper = render(<WrappedComponent data={data} />, {organization: data.organization});
  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 = ProjectFixture();
  143. const data = initializeData({
  144. project: project.id,
  145. projects: [project],
  146. features,
  147. });
  148. wrapper = render(<WrappedComponent data={data} />, {organization: data.organization});
  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 = ProjectFixture();
  158. const data = initializeData({
  159. project: project.id,
  160. projects: [project],
  161. features,
  162. });
  163. wrapper = render(<WrappedComponent data={data} />, {organization: data.organization});
  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 = ProjectFixture({id: '1'});
  177. const project2 = ProjectFixture({id: '2'});
  178. const data = initializeData({
  179. project: '-1',
  180. projects: [project, project2],
  181. features,
  182. });
  183. wrapper = render(<WrappedComponent data={data} />, {organization: data.organization});
  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 = ProjectFixture({id: '1'});
  197. const project2 = ProjectFixture({id: '2'});
  198. const data = initializeData({
  199. project: '-1',
  200. projects: [project, project2],
  201. features,
  202. });
  203. wrapper = render(<WrappedComponent data={data} />, {organization: data.organization});
  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 = ProjectFixture();
  216. const data = initializeData({
  217. project: project.id,
  218. projects: [project],
  219. features,
  220. });
  221. wrapper = render(<WrappedComponent data={data} />, {organization: data.organization});
  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 project = ProjectFixture({platform: 'javascript-react'});
  234. const data = initializeData({
  235. project: project.id,
  236. projects: [project],
  237. features,
  238. });
  239. wrapper = render(<WrappedComponent data={data} />, {organization: data.organization});
  240. expect(await screen.findByTestId('transaction-search-bar')).toBeInTheDocument();
  241. expect(
  242. await screen.findByTestId('landing-mep-alert-unnamed-discover-or-set')
  243. ).toBeInTheDocument();
  244. });
  245. it('renders with feature flag and partial other(unparam) transactions', async function () {
  246. addMetricsDataMock({
  247. metricsCount: 100,
  248. nullCount: 0,
  249. unparamCount: 1,
  250. });
  251. const project = ProjectFixture();
  252. const data = initializeData({
  253. project: project.id,
  254. projects: [project],
  255. features,
  256. });
  257. wrapper = render(<WrappedComponent data={data} />, {organization: data.organization});
  258. expect(await screen.findByTestId('transaction-search-bar')).toBeInTheDocument();
  259. expect(
  260. await screen.findByTestId('landing-mep-alert-unnamed-discover')
  261. ).toBeInTheDocument();
  262. });
  263. });