useSpanMetricsSeries.spec.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import {ReactNode} from 'react';
  2. import {Organization} from 'sentry-fixture/organization';
  3. import {makeTestQueryClient} from 'sentry-test/queryClient';
  4. import {reactHooks} from 'sentry-test/reactTestingLibrary';
  5. import {QueryClientProvider} from 'sentry/utils/queryClient';
  6. import {useLocation} from 'sentry/utils/useLocation';
  7. import useOrganization from 'sentry/utils/useOrganization';
  8. import usePageFilters from 'sentry/utils/usePageFilters';
  9. import {useSpanMetricsSeries} from 'sentry/views/starfish/queries/useSpanMetricsSeries';
  10. jest.mock('sentry/utils/useLocation');
  11. jest.mock('sentry/utils/usePageFilters');
  12. jest.mock('sentry/utils/useOrganization');
  13. function Wrapper({children}: {children?: ReactNode}) {
  14. return (
  15. <QueryClientProvider client={makeTestQueryClient()}>{children}</QueryClientProvider>
  16. );
  17. }
  18. describe('useSpanMetricsSeries', () => {
  19. const organization = Organization();
  20. jest.mocked(usePageFilters).mockReturnValue({
  21. isReady: true,
  22. desyncedFilters: new Set(),
  23. pinnedFilters: new Set(),
  24. shouldPersist: true,
  25. selection: {
  26. datetime: {
  27. period: '10d',
  28. start: null,
  29. end: null,
  30. utc: false,
  31. },
  32. environments: [],
  33. projects: [],
  34. },
  35. });
  36. jest.mocked(useLocation).mockReturnValue({
  37. pathname: '',
  38. search: '',
  39. query: {},
  40. hash: '',
  41. state: undefined,
  42. action: 'PUSH',
  43. key: '',
  44. });
  45. jest.mocked(useOrganization).mockReturnValue(organization);
  46. it('queries for current selection', async () => {
  47. const eventsRequest = MockApiClient.addMockResponse({
  48. url: `/organizations/${organization.slug}/events-stats/`,
  49. method: 'GET',
  50. body: {
  51. 'spm()': {
  52. data: [
  53. [1699907700, [{count: 7810.2}]],
  54. [1699908000, [{count: 1216.8}]],
  55. ],
  56. },
  57. },
  58. });
  59. const {result, waitForNextUpdate} = reactHooks.renderHook(
  60. ({filters, yAxis}) => useSpanMetricsSeries(filters, yAxis),
  61. {
  62. wrapper: Wrapper,
  63. initialProps: {
  64. filters: {
  65. 'span.group': '221aa7ebd216',
  66. transaction: '/api/details',
  67. release: '0.0.1',
  68. 'resource.render_blocking_status': 'blocking' as const,
  69. },
  70. yAxis: ['spm()'],
  71. },
  72. }
  73. );
  74. expect(result.current.isLoading).toEqual(true);
  75. expect(eventsRequest).toHaveBeenCalledWith(
  76. '/organizations/org-slug/events-stats/',
  77. expect.objectContaining({
  78. method: 'GET',
  79. query: expect.objectContaining({
  80. query: `span.group:221aa7ebd216 transaction:/api/details release:0.0.1 resource.render_blocking_status:blocking`,
  81. dataset: 'spansMetrics',
  82. statsPeriod: '10d',
  83. referrer: 'span-metrics-series',
  84. interval: '30m',
  85. yAxis: 'spm()',
  86. }),
  87. })
  88. );
  89. await waitForNextUpdate();
  90. expect(result.current.isLoading).toEqual(false);
  91. expect(result.current.data).toEqual({
  92. 'spm()': {
  93. data: [
  94. {name: '2023-11-13T20:35:00+00:00', value: 7810.2},
  95. {name: '2023-11-13T20:40:00+00:00', value: 1216.8},
  96. ],
  97. seriesName: 'spm()',
  98. },
  99. });
  100. });
  101. it('adjusts interval based on the yAxis', async () => {
  102. const eventsRequest = MockApiClient.addMockResponse({
  103. url: `/organizations/${organization.slug}/events-stats/`,
  104. method: 'GET',
  105. body: {},
  106. });
  107. const {rerender, waitForNextUpdate} = reactHooks.renderHook(
  108. ({yAxis}) => useSpanMetricsSeries({}, yAxis),
  109. {
  110. wrapper: Wrapper,
  111. initialProps: {
  112. yAxis: ['avg(span.self_time)', 'spm()'],
  113. },
  114. }
  115. );
  116. expect(eventsRequest).toHaveBeenLastCalledWith(
  117. '/organizations/org-slug/events-stats/',
  118. expect.objectContaining({
  119. method: 'GET',
  120. query: expect.objectContaining({
  121. interval: '30m',
  122. yAxis: ['avg(span.self_time)', 'spm()'],
  123. }),
  124. })
  125. );
  126. rerender({
  127. yAxis: ['p95(span.self_time)', 'spm()'],
  128. });
  129. expect(eventsRequest).toHaveBeenLastCalledWith(
  130. '/organizations/org-slug/events-stats/',
  131. expect.objectContaining({
  132. method: 'GET',
  133. query: expect.objectContaining({
  134. interval: '1h',
  135. yAxis: ['p95(span.self_time)', 'spm()'],
  136. }),
  137. })
  138. );
  139. await waitForNextUpdate();
  140. });
  141. });