useReplaysForRegressionIssue.spec.tsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import {Location} from 'history';
  2. import {EventFixture} from 'sentry-fixture/event';
  3. import {GroupFixture} from 'sentry-fixture/group';
  4. import {OrganizationFixture} from 'sentry-fixture/organization';
  5. import {reactHooks} from 'sentry-test/reactTestingLibrary';
  6. import {EventOccurrence, IssueCategory} from 'sentry/types';
  7. import {useLocation} from 'sentry/utils/useLocation';
  8. import useReplaysForRegressionIssue from 'sentry/views/issueDetails/groupReplays/useReplaysForRegressionIssue';
  9. jest.mock('sentry/utils/useLocation');
  10. describe('useReplaysForRegressionIssue', () => {
  11. const location: Location = {
  12. pathname: '',
  13. search: '',
  14. query: {},
  15. hash: '',
  16. state: undefined,
  17. action: 'PUSH',
  18. key: '',
  19. };
  20. jest.mocked(useLocation).mockReturnValue(location);
  21. const organization = OrganizationFixture({
  22. features: ['session-replay'],
  23. });
  24. const mockEvent = {
  25. ...EventFixture(),
  26. occurrence: {
  27. evidenceDisplay: {} as EventOccurrence['evidenceDisplay'],
  28. detectionTime: 'mock-detection-time',
  29. eventId: 'eventId',
  30. fingerprint: ['fingerprint'],
  31. id: 'id',
  32. issueTitle: 'Transaction Duration Regression',
  33. subtitle: 'Increased from 20.64ms to 36.24ms (P95)',
  34. resourceId: '',
  35. type: 1017,
  36. evidenceData: {
  37. transaction: 'mock-transaction',
  38. aggregateRange2: 100,
  39. breakpoint: Date.now() / 1000, // The breakpoint is stored in seconds
  40. },
  41. },
  42. };
  43. it('should fetch a list of replay ids', async () => {
  44. const MOCK_GROUP = GroupFixture({issueCategory: IssueCategory.PERFORMANCE});
  45. MockApiClient.addMockResponse({
  46. url: `/organizations/${organization.slug}/replay-count/`,
  47. method: 'GET',
  48. body: {
  49. ['mock-transaction']: ['replay42', 'replay256'],
  50. },
  51. });
  52. const {result, waitForNextUpdate} = reactHooks.renderHook(
  53. useReplaysForRegressionIssue,
  54. {
  55. initialProps: {
  56. group: MOCK_GROUP,
  57. location,
  58. organization,
  59. event: mockEvent,
  60. },
  61. }
  62. );
  63. expect(result.current).toEqual({
  64. eventView: null,
  65. fetchError: undefined,
  66. pageLinks: null,
  67. });
  68. await waitForNextUpdate();
  69. expect(result.current).toEqual({
  70. eventView: expect.objectContaining({
  71. query: 'id:[replay42,replay256]',
  72. }),
  73. fetchError: undefined,
  74. pageLinks: null,
  75. });
  76. });
  77. it('should return an empty EventView when there are no replay_ids returned from the count endpoint', async () => {
  78. const MOCK_GROUP = GroupFixture({issueCategory: IssueCategory.PERFORMANCE});
  79. MockApiClient.addMockResponse({
  80. url: `/organizations/${organization.slug}/replay-count/`,
  81. method: 'GET',
  82. body: {},
  83. });
  84. const {result, waitForNextUpdate} = reactHooks.renderHook(
  85. useReplaysForRegressionIssue,
  86. {
  87. initialProps: {
  88. group: MOCK_GROUP,
  89. location,
  90. organization,
  91. event: mockEvent,
  92. },
  93. }
  94. );
  95. expect(result.current).toEqual({
  96. eventView: null,
  97. fetchError: undefined,
  98. pageLinks: null,
  99. });
  100. await waitForNextUpdate();
  101. expect(result.current).toEqual({
  102. eventView: expect.objectContaining({
  103. query: 'id:[]',
  104. }),
  105. fetchError: undefined,
  106. pageLinks: null,
  107. });
  108. });
  109. it('queries using start and end date strings if passed in', async () => {
  110. const MOCK_GROUP = GroupFixture({issueCategory: IssueCategory.PERFORMANCE});
  111. const replayCountRequest = MockApiClient.addMockResponse({
  112. url: `/organizations/${organization.slug}/replay-count/`,
  113. method: 'GET',
  114. body: {
  115. ['mock_transaction']: ['replay42', 'replay256'],
  116. },
  117. });
  118. const {waitForNextUpdate} = reactHooks.renderHook(useReplaysForRegressionIssue, {
  119. initialProps: {
  120. group: MOCK_GROUP,
  121. location,
  122. organization,
  123. event: mockEvent,
  124. },
  125. });
  126. expect(replayCountRequest).toHaveBeenCalledWith(
  127. '/organizations/org-slug/replay-count/',
  128. expect.objectContaining({
  129. query: expect.objectContaining({
  130. start: new Date(
  131. mockEvent.occurrence.evidenceData.breakpoint * 1000
  132. ).toISOString(),
  133. end: new Date().toISOString(),
  134. }),
  135. })
  136. );
  137. await waitForNextUpdate();
  138. });
  139. it('queries the transaction name with event type and duration filters', async () => {
  140. const MOCK_GROUP = GroupFixture({issueCategory: IssueCategory.PERFORMANCE});
  141. const replayCountRequest = MockApiClient.addMockResponse({
  142. url: `/organizations/${organization.slug}/replay-count/`,
  143. method: 'GET',
  144. body: {
  145. ['mock_transaction']: ['replay42', 'replay256'],
  146. },
  147. });
  148. const {waitForNextUpdate} = reactHooks.renderHook(useReplaysForRegressionIssue, {
  149. initialProps: {
  150. group: MOCK_GROUP,
  151. location,
  152. organization,
  153. event: mockEvent,
  154. },
  155. });
  156. expect(replayCountRequest).toHaveBeenCalledWith(
  157. '/organizations/org-slug/replay-count/',
  158. expect.objectContaining({
  159. query: expect.objectContaining({
  160. query:
  161. 'event.type:transaction transaction:["mock-transaction"] transaction.duration:>=50ms',
  162. }),
  163. })
  164. );
  165. await waitForNextUpdate();
  166. });
  167. });