metricsRequest.spec.tsx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. import {render, waitFor} from 'sentry-test/reactTestingLibrary';
  2. import MetricsRequest from 'sentry/utils/metrics/metricsRequest';
  3. import {transformMetricsResponseToSeries} from 'sentry/utils/metrics/transformMetricsResponseToSeries';
  4. jest.mock('sentry/utils/metrics/transformMetricsResponseToSeries', () => ({
  5. transformMetricsResponseToSeries: jest.fn().mockReturnValue([]),
  6. }));
  7. describe('MetricsRequest', () => {
  8. const project = TestStubs.Project();
  9. const organization = TestStubs.Organization();
  10. const childrenMock = jest.fn(() => null);
  11. const props = {
  12. api: new MockApiClient(),
  13. orgSlug: organization.slug,
  14. field: ['fieldA'],
  15. project: [project.id],
  16. environment: ['prod'],
  17. statsPeriod: '14d',
  18. query: 'abc',
  19. groupBy: ['status'],
  20. orderBy: 'fieldA',
  21. limit: 3,
  22. };
  23. let metricsMock;
  24. beforeEach(() => {
  25. metricsMock = MockApiClient.addMockResponse({
  26. method: 'GET',
  27. url: `/organizations/org-slug/metrics/data/`,
  28. body: {intervals: [], groups: []},
  29. });
  30. childrenMock.mockClear();
  31. });
  32. it('makes request and passes correct render props', async () => {
  33. render(<MetricsRequest {...props}>{childrenMock}</MetricsRequest>);
  34. expect(childrenMock).toHaveBeenNthCalledWith(1, {
  35. errored: false,
  36. error: null,
  37. loading: true,
  38. reloading: false,
  39. response: null,
  40. responsePrevious: null,
  41. tableData: undefined,
  42. pageLinks: null,
  43. });
  44. expect(metricsMock).toHaveBeenCalledTimes(1);
  45. expect(metricsMock).toHaveBeenCalledWith(
  46. expect.anything(),
  47. expect.objectContaining({
  48. query: {
  49. environment: ['prod'],
  50. field: ['fieldA'],
  51. groupBy: ['status'],
  52. interval: '1h',
  53. per_page: 3,
  54. orderBy: 'fieldA',
  55. project: ['2'],
  56. query: 'abc',
  57. statsPeriod: '14d',
  58. },
  59. })
  60. );
  61. await waitFor(() =>
  62. expect(childrenMock).toHaveBeenLastCalledWith({
  63. errored: false,
  64. error: null,
  65. loading: false,
  66. reloading: false,
  67. response: {groups: [], intervals: []},
  68. responsePrevious: null,
  69. tableData: undefined,
  70. pageLinks: null,
  71. })
  72. );
  73. });
  74. it('does not make request if isDisabled', () => {
  75. render(
  76. <MetricsRequest {...props} isDisabled>
  77. {childrenMock}
  78. </MetricsRequest>
  79. );
  80. expect(metricsMock).toHaveBeenCalledTimes(0);
  81. expect(childrenMock).toHaveBeenCalledTimes(1);
  82. expect(childrenMock).toHaveBeenCalledWith({
  83. errored: false,
  84. error: null,
  85. loading: false,
  86. reloading: false,
  87. response: null,
  88. responsePrevious: null,
  89. tableData: undefined,
  90. pageLinks: null,
  91. });
  92. });
  93. it('refetches when props change', () => {
  94. const {rerender} = render(<MetricsRequest {...props}>{childrenMock}</MetricsRequest>);
  95. expect(metricsMock).toHaveBeenCalledTimes(1);
  96. rerender(
  97. <MetricsRequest {...props} field={['fieldB']}>
  98. {childrenMock}
  99. </MetricsRequest>
  100. );
  101. expect(metricsMock).toHaveBeenCalledTimes(2);
  102. expect(metricsMock).toHaveBeenLastCalledWith(
  103. expect.anything(),
  104. expect.objectContaining({
  105. query: expect.objectContaining({field: ['fieldB']}),
  106. })
  107. );
  108. });
  109. it('does not refetch when ignored props change', () => {
  110. const {rerender} = render(<MetricsRequest {...props}>{childrenMock}</MetricsRequest>);
  111. const differentChildrenMock = jest.fn(() => 'lorem ipsum');
  112. rerender(<MetricsRequest {...props}>{differentChildrenMock}</MetricsRequest>);
  113. expect(metricsMock).toHaveBeenCalledTimes(1);
  114. });
  115. it('make two requests if includePrevious is enabled', async () => {
  116. render(
  117. <MetricsRequest {...props} includePrevious>
  118. {childrenMock}
  119. </MetricsRequest>
  120. );
  121. expect(childrenMock).toHaveBeenNthCalledWith(1, {
  122. errored: false,
  123. error: null,
  124. loading: true,
  125. reloading: false,
  126. response: null,
  127. responsePrevious: null,
  128. tableData: undefined,
  129. pageLinks: null,
  130. });
  131. expect(metricsMock).toHaveBeenCalledTimes(2);
  132. expect(metricsMock).toHaveBeenNthCalledWith(
  133. 1,
  134. expect.anything(),
  135. expect.objectContaining({
  136. query: {
  137. environment: ['prod'],
  138. field: ['fieldA'],
  139. groupBy: ['status'],
  140. interval: '1h',
  141. per_page: 3,
  142. orderBy: 'fieldA',
  143. project: ['2'],
  144. query: 'abc',
  145. statsPeriod: '14d',
  146. },
  147. })
  148. );
  149. expect(metricsMock).toHaveBeenLastCalledWith(
  150. expect.anything(),
  151. expect.objectContaining({
  152. query: {
  153. project: ['2'],
  154. environment: ['prod'],
  155. field: ['fieldA'],
  156. query: 'abc',
  157. groupBy: ['status'],
  158. orderBy: 'fieldA',
  159. per_page: 3,
  160. interval: '1h',
  161. statsPeriodStart: '28d',
  162. statsPeriodEnd: '14d',
  163. },
  164. })
  165. );
  166. await waitFor(() =>
  167. expect(childrenMock).toHaveBeenLastCalledWith({
  168. errored: false,
  169. error: null,
  170. loading: false,
  171. reloading: false,
  172. response: {groups: [], intervals: []},
  173. responsePrevious: {groups: [], intervals: []},
  174. tableData: undefined,
  175. pageLinks: null,
  176. })
  177. );
  178. });
  179. it('make one request with absolute date', () => {
  180. render(
  181. <MetricsRequest
  182. {...props}
  183. statsPeriod=""
  184. start="Wed Dec 01 2021 01:00:00 GMT+0100 (Central European Standard Time)"
  185. end="Fri Dec 17 2021 00:59:59 GMT+0100 (Central European Standard Time)"
  186. includePrevious
  187. >
  188. {childrenMock}
  189. </MetricsRequest>
  190. );
  191. expect(childrenMock).toHaveBeenNthCalledWith(1, {
  192. errored: false,
  193. error: null,
  194. loading: true,
  195. reloading: false,
  196. response: null,
  197. responsePrevious: null,
  198. tableData: undefined,
  199. pageLinks: null,
  200. });
  201. // if start and end are provided, it will not perform a request to fetch previous data
  202. expect(metricsMock).toHaveBeenCalledTimes(1);
  203. expect(metricsMock).toHaveBeenCalledWith(
  204. expect.anything(),
  205. expect.objectContaining({
  206. query: {
  207. end: '2021-12-17T00:59:59.000',
  208. environment: ['prod'],
  209. field: ['fieldA'],
  210. groupBy: ['status'],
  211. interval: '1h',
  212. per_page: 3,
  213. orderBy: 'fieldA',
  214. project: ['2'],
  215. query: 'abc',
  216. start: '2021-12-01T01:00:00.000',
  217. },
  218. })
  219. );
  220. });
  221. it('includes series data', () => {
  222. render(
  223. <MetricsRequest {...props} includeSeriesData includePrevious>
  224. {childrenMock}
  225. </MetricsRequest>
  226. );
  227. expect(metricsMock).toHaveBeenCalledTimes(2);
  228. expect(childrenMock).toHaveBeenLastCalledWith({
  229. error: null,
  230. errored: false,
  231. loading: true,
  232. pageLinks: null,
  233. reloading: false,
  234. response: null,
  235. responsePrevious: null,
  236. seriesData: [],
  237. seriesDataPrevious: [],
  238. tableData: undefined,
  239. });
  240. expect(transformMetricsResponseToSeries).toHaveBeenCalledWith(null);
  241. });
  242. });