listContent.spec.tsx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. import {OrganizationFixture} from 'sentry-fixture/organization';
  2. import {render, screen, waitFor} from 'sentry-test/reactTestingLibrary';
  3. import useDeadRageSelectors from 'sentry/utils/replays/hooks/useDeadRageSelectors';
  4. import {
  5. useHaveSelectedProjectsSentAnyReplayEvents,
  6. useReplayOnboardingSidebarPanel,
  7. } from 'sentry/utils/replays/hooks/useReplayOnboarding';
  8. import useProjectSdkNeedsUpdate from 'sentry/utils/useProjectSdkNeedsUpdate';
  9. import useAllMobileProj from 'sentry/views/replays/detail/useAllMobileProj';
  10. import ListPage from 'sentry/views/replays/list/listContent';
  11. jest.mock('sentry/utils/replays/hooks/useDeadRageSelectors');
  12. jest.mock('sentry/utils/replays/hooks/useReplayOnboarding');
  13. jest.mock('sentry/utils/replays/hooks/useReplayPageview');
  14. jest.mock('sentry/utils/useProjectSdkNeedsUpdate');
  15. jest.mock('sentry/views/replays/detail/useAllMobileProj');
  16. const mockUseDeadRageSelectors = jest.mocked(useDeadRageSelectors);
  17. mockUseDeadRageSelectors.mockReturnValue({
  18. isLoading: false,
  19. isError: false,
  20. data: [],
  21. pageLinks: undefined,
  22. });
  23. const mockUseHaveSelectedProjectsSentAnyReplayEvents = jest.mocked(
  24. useHaveSelectedProjectsSentAnyReplayEvents
  25. );
  26. const mockUseProjectSdkNeedsUpdate = jest.mocked(useProjectSdkNeedsUpdate);
  27. const mockUseReplayOnboardingSidebarPanel = jest.mocked(useReplayOnboardingSidebarPanel);
  28. mockUseReplayOnboardingSidebarPanel.mockReturnValue({activateSidebar: jest.fn()});
  29. const mockUseAllMobileProj = jest.mocked(useAllMobileProj);
  30. mockUseAllMobileProj.mockReturnValue({allMobileProj: false});
  31. const AM1_FEATURES = [];
  32. const AM2_FEATURES = ['session-replay'];
  33. function getMockOrganizationFixture({features}: {features: string[]}) {
  34. const mockOrg = OrganizationFixture({
  35. features,
  36. access: [],
  37. });
  38. return mockOrg;
  39. }
  40. describe('ReplayList', () => {
  41. let mockFetchReplayListRequest;
  42. beforeEach(() => {
  43. mockUseHaveSelectedProjectsSentAnyReplayEvents.mockClear();
  44. mockUseProjectSdkNeedsUpdate.mockClear();
  45. mockUseDeadRageSelectors.mockClear();
  46. // mockUseAllMobileProj.mockClear();
  47. MockApiClient.clearMockResponses();
  48. MockApiClient.addMockResponse({
  49. url: '/organizations/org-slug/tags/',
  50. body: [],
  51. });
  52. mockFetchReplayListRequest = MockApiClient.addMockResponse({
  53. url: `/organizations/org-slug/replays/`,
  54. body: {},
  55. });
  56. // Request made by SearchQueryBuilder:
  57. MockApiClient.addMockResponse({
  58. url: '/organizations/org-slug/recent-searches/',
  59. method: 'GET',
  60. body: [],
  61. });
  62. });
  63. it('should render the onboarding panel when the org is on AM1', async () => {
  64. const mockOrg = getMockOrganizationFixture({features: AM1_FEATURES});
  65. mockUseHaveSelectedProjectsSentAnyReplayEvents.mockReturnValue({
  66. fetching: false,
  67. hasSentOneReplay: false,
  68. });
  69. mockUseProjectSdkNeedsUpdate.mockReturnValue({
  70. isError: false,
  71. isFetching: false,
  72. needsUpdate: false,
  73. });
  74. render(<ListPage />, {
  75. organization: mockOrg,
  76. });
  77. await waitFor(() =>
  78. expect(screen.getByText('Get to the root cause faster')).toBeInTheDocument()
  79. );
  80. expect(mockFetchReplayListRequest).not.toHaveBeenCalled();
  81. });
  82. it('should render the onboarding panel when the org is on AM1 and has sent some replays', async () => {
  83. const mockOrg = getMockOrganizationFixture({features: AM1_FEATURES});
  84. mockUseHaveSelectedProjectsSentAnyReplayEvents.mockReturnValue({
  85. fetching: false,
  86. hasSentOneReplay: true,
  87. });
  88. mockUseProjectSdkNeedsUpdate.mockReturnValue({
  89. isError: false,
  90. isFetching: false,
  91. needsUpdate: false,
  92. });
  93. render(<ListPage />, {
  94. organization: mockOrg,
  95. });
  96. await waitFor(() =>
  97. expect(screen.getByText('Get to the root cause faster')).toBeInTheDocument()
  98. );
  99. expect(mockFetchReplayListRequest).not.toHaveBeenCalled();
  100. });
  101. it('should render the onboarding panel when the org is on AM2 and has never sent a replay', async () => {
  102. const mockOrg = getMockOrganizationFixture({features: AM2_FEATURES});
  103. mockUseHaveSelectedProjectsSentAnyReplayEvents.mockReturnValue({
  104. fetching: false,
  105. hasSentOneReplay: false,
  106. });
  107. mockUseProjectSdkNeedsUpdate.mockReturnValue({
  108. isError: false,
  109. isFetching: false,
  110. needsUpdate: false,
  111. });
  112. render(<ListPage />, {
  113. organization: mockOrg,
  114. });
  115. await waitFor(() =>
  116. expect(screen.getByText('Get to the root cause faster')).toBeInTheDocument()
  117. );
  118. expect(mockFetchReplayListRequest).not.toHaveBeenCalled();
  119. });
  120. it('should render the rage-click sdk update banner when the org is AM2, has sent replays, but the sdk version is low', async () => {
  121. const mockOrg = getMockOrganizationFixture({features: AM2_FEATURES});
  122. mockUseHaveSelectedProjectsSentAnyReplayEvents.mockReturnValue({
  123. fetching: false,
  124. hasSentOneReplay: true,
  125. });
  126. mockUseProjectSdkNeedsUpdate.mockReturnValue({
  127. isError: false,
  128. isFetching: false,
  129. needsUpdate: true,
  130. });
  131. render(<ListPage />, {
  132. organization: mockOrg,
  133. });
  134. await waitFor(() => {
  135. expect(screen.getByText('Introducing Rage and Dead Clicks')).toBeInTheDocument();
  136. expect(screen.queryByTestId('replay-table')).toBeInTheDocument();
  137. });
  138. expect(mockFetchReplayListRequest).toHaveBeenCalled();
  139. });
  140. it('should fetch the replay table when the org is on AM2, has sent some replays, and has a newer SDK version', async () => {
  141. const mockOrg = getMockOrganizationFixture({features: AM2_FEATURES});
  142. mockUseHaveSelectedProjectsSentAnyReplayEvents.mockReturnValue({
  143. fetching: false,
  144. hasSentOneReplay: true,
  145. });
  146. mockUseProjectSdkNeedsUpdate.mockReturnValue({
  147. isError: false,
  148. isFetching: false,
  149. needsUpdate: false,
  150. });
  151. render(<ListPage />, {
  152. organization: mockOrg,
  153. });
  154. await waitFor(() => expect(screen.queryAllByTestId('replay-table')).toHaveLength(1));
  155. expect(mockFetchReplayListRequest).toHaveBeenCalled();
  156. });
  157. });