useSpanMetricsSeries.spec.tsx 5.2 KB

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