useReplaysCount.spec.tsx 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. import {reactHooks} from 'sentry-test/reactTestingLibrary';
  2. import {useLocation} from 'sentry/utils/useLocation';
  3. import useReplaysCount from './useReplaysCount';
  4. jest.mock('sentry/utils/useLocation');
  5. describe('useReplaysCount', () => {
  6. const MockUseLocation = useLocation as jest.MockedFunction<typeof useLocation>;
  7. const mockGroupIds = ['123', '456'];
  8. const mockReplayIds = ['abc', 'def'];
  9. const mockTransactionNames = ['/home', '/profile'];
  10. MockUseLocation.mockReturnValue({
  11. pathname: '',
  12. search: '',
  13. query: {},
  14. hash: '',
  15. state: undefined,
  16. action: 'PUSH',
  17. key: '',
  18. });
  19. const organization = TestStubs.Organization({
  20. features: ['session-replay'],
  21. });
  22. it('should throw if none of groupIds, replayIds, transactionNames is provided', () => {
  23. const {result} = reactHooks.renderHook(useReplaysCount, {
  24. initialProps: {
  25. organization,
  26. },
  27. });
  28. expect(result.error).toBeTruthy();
  29. });
  30. it('should throw if more than one of groupIds, replayIds, transactionNames are provided', () => {
  31. const {result: result1} = reactHooks.renderHook(useReplaysCount, {
  32. initialProps: {
  33. organization,
  34. groupIds: [],
  35. transactionNames: [],
  36. },
  37. });
  38. expect(result1.error).toBeTruthy();
  39. const {result: result2} = reactHooks.renderHook(useReplaysCount, {
  40. initialProps: {
  41. organization,
  42. groupIds: [],
  43. replayIds: [],
  44. },
  45. });
  46. expect(result2.error).toBeTruthy();
  47. const {result: result3} = reactHooks.renderHook(useReplaysCount, {
  48. initialProps: {
  49. organization,
  50. replayIds: [],
  51. transactionNames: [],
  52. },
  53. });
  54. expect(result3.error).toBeTruthy();
  55. });
  56. it('should query for groupIds', async () => {
  57. const replayCountRequest = MockApiClient.addMockResponse({
  58. url: `/organizations/${organization.slug}/replay-count/`,
  59. method: 'GET',
  60. body: {},
  61. });
  62. const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
  63. initialProps: {
  64. organization,
  65. groupIds: mockGroupIds,
  66. },
  67. });
  68. expect(result.current).toEqual({});
  69. expect(replayCountRequest).toHaveBeenCalledWith(
  70. '/organizations/org-slug/replay-count/',
  71. expect.objectContaining({
  72. query: {
  73. query: `issue.id:[${mockGroupIds.join(',')}]`,
  74. statsPeriod: '14d',
  75. project: -1,
  76. },
  77. })
  78. );
  79. await waitForNextUpdate();
  80. });
  81. it('should return the count of each groupId, or zero if not included in the response', async () => {
  82. const replayCountRequest = MockApiClient.addMockResponse({
  83. url: `/organizations/${organization.slug}/replay-count/`,
  84. method: 'GET',
  85. body: {
  86. 123: 42,
  87. },
  88. });
  89. const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
  90. initialProps: {
  91. organization,
  92. groupIds: mockGroupIds,
  93. },
  94. });
  95. expect(result.current).toEqual({});
  96. expect(replayCountRequest).toHaveBeenCalled();
  97. await waitForNextUpdate();
  98. expect(result.current).toEqual({
  99. '123': 42,
  100. '456': 0,
  101. });
  102. });
  103. it('should request the count for a group only once', async () => {
  104. const replayCountRequest = MockApiClient.addMockResponse({
  105. url: `/organizations/${organization.slug}/replay-count/`,
  106. method: 'GET',
  107. body: {},
  108. });
  109. const {result, rerender, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
  110. initialProps: {
  111. organization,
  112. groupIds: mockGroupIds,
  113. },
  114. });
  115. await waitForNextUpdate();
  116. expect(replayCountRequest).toHaveBeenCalledTimes(1);
  117. expect(replayCountRequest).toHaveBeenCalledWith(
  118. '/organizations/org-slug/replay-count/',
  119. expect.objectContaining({
  120. query: {
  121. query: `issue.id:[123,456]`,
  122. statsPeriod: '14d',
  123. project: -1,
  124. },
  125. })
  126. );
  127. expect(result.current).toEqual({
  128. 123: 0,
  129. 456: 0,
  130. });
  131. rerender({
  132. organization,
  133. groupIds: [...mockGroupIds, '789'],
  134. });
  135. await waitForNextUpdate();
  136. expect(replayCountRequest).toHaveBeenCalledTimes(2);
  137. expect(replayCountRequest).toHaveBeenCalledWith(
  138. '/organizations/org-slug/replay-count/',
  139. expect.objectContaining({
  140. query: {
  141. query: `issue.id:[789]`,
  142. statsPeriod: '14d',
  143. project: -1,
  144. },
  145. })
  146. );
  147. expect(result.current).toEqual({
  148. 123: 0,
  149. 456: 0,
  150. 789: 0,
  151. });
  152. });
  153. it('should not request anything if there are no new ids to query', async () => {
  154. const replayCountRequest = MockApiClient.addMockResponse({
  155. url: `/organizations/${organization.slug}/replay-count/`,
  156. method: 'GET',
  157. body: {},
  158. });
  159. const {result, rerender, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
  160. initialProps: {
  161. organization,
  162. groupIds: mockGroupIds,
  163. },
  164. });
  165. await waitForNextUpdate();
  166. expect(replayCountRequest).toHaveBeenCalledTimes(1);
  167. expect(replayCountRequest).toHaveBeenCalledWith(
  168. '/organizations/org-slug/replay-count/',
  169. expect.objectContaining({
  170. query: {
  171. query: `issue.id:[123,456]`,
  172. statsPeriod: '14d',
  173. project: -1,
  174. },
  175. })
  176. );
  177. expect(result.current).toEqual({
  178. 123: 0,
  179. 456: 0,
  180. });
  181. rerender({
  182. organization,
  183. groupIds: mockGroupIds,
  184. });
  185. expect(replayCountRequest).toHaveBeenCalledTimes(1);
  186. expect(result.current).toEqual({
  187. 123: 0,
  188. 456: 0,
  189. });
  190. });
  191. it('should query for replayId', async () => {
  192. const replayCountRequest = MockApiClient.addMockResponse({
  193. url: `/organizations/${organization.slug}/replay-count/`,
  194. method: 'GET',
  195. body: {},
  196. });
  197. const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
  198. initialProps: {
  199. organization,
  200. replayIds: mockReplayIds,
  201. },
  202. });
  203. expect(result.current).toEqual({});
  204. expect(replayCountRequest).toHaveBeenCalledWith(
  205. '/organizations/org-slug/replay-count/',
  206. expect.objectContaining({
  207. query: {
  208. query: `replay_id:[abc,def]`,
  209. statsPeriod: '14d',
  210. project: -1,
  211. },
  212. })
  213. );
  214. await waitForNextUpdate();
  215. });
  216. it('should return the count of each replayId, or zero if not included in the response', async () => {
  217. const countRequest = MockApiClient.addMockResponse({
  218. url: `/organizations/${organization.slug}/replay-count/`,
  219. method: 'GET',
  220. body: {
  221. abc: 42,
  222. },
  223. });
  224. const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
  225. initialProps: {
  226. organization,
  227. replayIds: mockReplayIds,
  228. },
  229. });
  230. expect(result.current).toEqual({});
  231. expect(countRequest).toHaveBeenCalled();
  232. await waitForNextUpdate();
  233. expect(result.current).toEqual({
  234. abc: 42,
  235. def: 0,
  236. });
  237. });
  238. it('should query for transactionNames', async () => {
  239. const replayCountRequest = MockApiClient.addMockResponse({
  240. url: `/organizations/${organization.slug}/replay-count/`,
  241. method: 'GET',
  242. body: {},
  243. });
  244. const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
  245. initialProps: {
  246. organization,
  247. transactionNames: mockTransactionNames,
  248. },
  249. });
  250. expect(result.current).toEqual({});
  251. expect(replayCountRequest).toHaveBeenCalledWith(
  252. '/organizations/org-slug/replay-count/',
  253. expect.objectContaining({
  254. query: {
  255. query: `transaction:["/home","/profile"]`,
  256. statsPeriod: '14d',
  257. project: -1,
  258. },
  259. })
  260. );
  261. await waitForNextUpdate();
  262. });
  263. it('should return the count of each transactionName, or zero if not included in the response', async () => {
  264. const countRequest = MockApiClient.addMockResponse({
  265. url: `/organizations/${organization.slug}/replay-count/`,
  266. method: 'GET',
  267. body: {
  268. '/home': 42,
  269. },
  270. });
  271. const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
  272. initialProps: {
  273. organization,
  274. transactionNames: mockTransactionNames,
  275. },
  276. });
  277. expect(result.current).toEqual({});
  278. expect(countRequest).toHaveBeenCalled();
  279. await waitForNextUpdate();
  280. expect(result.current).toEqual({
  281. '/home': 42,
  282. '/profile': 0,
  283. });
  284. });
  285. });