useReplaysForRegressionIssue.spec.tsx 5.3 KB

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