useTraceMeta.spec.tsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import {QueryClientProvider} from '@tanstack/react-query';
  2. import {OrganizationFixture} from 'sentry-fixture/organization';
  3. import {makeTestQueryClient} from 'sentry-test/queryClient';
  4. import {renderHook, waitFor} from 'sentry-test/reactTestingLibrary';
  5. import * as useOrganization from 'sentry/utils/useOrganization';
  6. import type {ReplayTrace} from 'sentry/views/replays/detail/trace/useReplayTraces';
  7. import {useTraceMeta} from './useTraceMeta';
  8. const organization = OrganizationFixture();
  9. const queryClient = makeTestQueryClient();
  10. const mockedReplayTraces: ReplayTrace[] = [
  11. {
  12. traceSlug: 'slug1',
  13. timestamp: 1,
  14. },
  15. {
  16. traceSlug: 'slug2',
  17. timestamp: 2,
  18. },
  19. {
  20. traceSlug: 'slug3',
  21. timestamp: 3,
  22. },
  23. ];
  24. describe('useTraceMeta', () => {
  25. beforeEach(function () {
  26. queryClient.clear();
  27. jest.clearAllMocks();
  28. jest.spyOn(useOrganization, 'default').mockReturnValue(organization);
  29. });
  30. it('Returns merged meta results', async () => {
  31. MockApiClient.addMockResponse({
  32. method: 'GET',
  33. url: '/organizations/org-slug/events-trace-meta/slug1/',
  34. body: {
  35. errors: 1,
  36. performance_issues: 1,
  37. projects: 1,
  38. transactions: 1,
  39. transaction_child_count_map: [{'transaction.id': '1', count: 1}],
  40. },
  41. });
  42. MockApiClient.addMockResponse({
  43. method: 'GET',
  44. url: '/organizations/org-slug/events-trace-meta/slug2/',
  45. body: {
  46. errors: 1,
  47. performance_issues: 1,
  48. projects: 1,
  49. transactions: 1,
  50. transaction_child_count_map: [{'transaction.id': '2', count: 2}],
  51. },
  52. });
  53. MockApiClient.addMockResponse({
  54. method: 'GET',
  55. url: '/organizations/org-slug/events-trace-meta/slug3/',
  56. body: {
  57. errors: 1,
  58. performance_issues: 1,
  59. projects: 1,
  60. transactions: 1,
  61. transaction_child_count_map: [],
  62. },
  63. });
  64. const wrapper = ({children}: {children: React.ReactNode}) => (
  65. <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  66. );
  67. const {result} = renderHook(() => useTraceMeta(mockedReplayTraces), {wrapper});
  68. expect(result.current).toEqual({
  69. data: undefined,
  70. errors: [],
  71. status: 'pending',
  72. });
  73. await waitFor(() => expect(result.current.status === 'success').toBe(true));
  74. expect(result.current).toEqual({
  75. data: {
  76. errors: 3,
  77. performance_issues: 3,
  78. projects: 1,
  79. transactions: 3,
  80. transactiontoSpanChildrenCount: {
  81. '1': 1,
  82. '2': 2,
  83. },
  84. },
  85. errors: [],
  86. status: 'success',
  87. });
  88. });
  89. it('Collects errors from rejected api calls', async () => {
  90. const mockRequest1 = MockApiClient.addMockResponse({
  91. method: 'GET',
  92. url: '/organizations/org-slug/events-trace-meta/slug1/',
  93. statusCode: 400,
  94. });
  95. const mockRequest2 = MockApiClient.addMockResponse({
  96. method: 'GET',
  97. url: '/organizations/org-slug/events-trace-meta/slug2/',
  98. statusCode: 400,
  99. });
  100. const mockRequest3 = MockApiClient.addMockResponse({
  101. method: 'GET',
  102. url: '/organizations/org-slug/events-trace-meta/slug3/',
  103. statusCode: 400,
  104. });
  105. const wrapper = ({children}: {children: React.ReactNode}) => (
  106. <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  107. );
  108. const {result} = renderHook(() => useTraceMeta(mockedReplayTraces), {wrapper});
  109. expect(result.current).toEqual({
  110. data: undefined,
  111. errors: [],
  112. status: 'pending',
  113. });
  114. await waitFor(() => expect(result.current.status === 'pending').toBe(false));
  115. expect(result.current).toEqual({
  116. data: {
  117. errors: 0,
  118. performance_issues: 0,
  119. projects: 0,
  120. transactions: 0,
  121. transactiontoSpanChildrenCount: {},
  122. },
  123. errors: [expect.any(Error), expect.any(Error), expect.any(Error)],
  124. status: 'error',
  125. });
  126. expect(mockRequest1).toHaveBeenCalled();
  127. expect(mockRequest2).toHaveBeenCalled();
  128. expect(mockRequest3).toHaveBeenCalled();
  129. });
  130. it('Accumulates metaResults and collects errors from rejected api calls', async () => {
  131. const mockRequest1 = MockApiClient.addMockResponse({
  132. method: 'GET',
  133. url: '/organizations/org-slug/events-trace-meta/slug1/',
  134. statusCode: 400,
  135. });
  136. const mockRequest2 = MockApiClient.addMockResponse({
  137. method: 'GET',
  138. url: '/organizations/org-slug/events-trace-meta/slug2/',
  139. body: {
  140. errors: 1,
  141. performance_issues: 1,
  142. projects: 1,
  143. transactions: 1,
  144. transaction_child_count_map: [],
  145. },
  146. });
  147. const mockRequest3 = MockApiClient.addMockResponse({
  148. method: 'GET',
  149. url: '/organizations/org-slug/events-trace-meta/slug3/',
  150. body: {
  151. errors: 1,
  152. performance_issues: 1,
  153. projects: 1,
  154. transactions: 1,
  155. transaction_child_count_map: [],
  156. },
  157. });
  158. const wrapper = ({children}: {children: React.ReactNode}) => (
  159. <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  160. );
  161. const {result} = renderHook(() => useTraceMeta(mockedReplayTraces), {wrapper});
  162. expect(result.current).toEqual({
  163. data: undefined,
  164. errors: [],
  165. status: 'pending',
  166. });
  167. await waitFor(() => expect(result.current.status === 'pending').toBe(false));
  168. expect(result.current).toEqual({
  169. data: {
  170. errors: 2,
  171. performance_issues: 2,
  172. projects: 1,
  173. transactions: 2,
  174. transactiontoSpanChildrenCount: {},
  175. },
  176. errors: [expect.any(Error)],
  177. status: 'success',
  178. });
  179. expect(mockRequest1).toHaveBeenCalledTimes(1);
  180. expect(mockRequest2).toHaveBeenCalledTimes(1);
  181. expect(mockRequest3).toHaveBeenCalledTimes(1);
  182. });
  183. });