newIssueExperienceButton.spec.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import {LocationFixture} from 'sentry-fixture/locationFixture';
  2. import {OrganizationFixture} from 'sentry-fixture/organization';
  3. import {UserFixture} from 'sentry-fixture/user';
  4. import {act, render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
  5. import ConfigStore from 'sentry/stores/configStore';
  6. import {trackAnalytics} from 'sentry/utils/analytics';
  7. import {NewIssueExperienceButton} from 'sentry/views/issueDetails/actions/newIssueExperienceButton';
  8. const mockUseNavigate = jest.fn();
  9. jest.mock('sentry/utils/useNavigate', () => ({
  10. useNavigate: () => mockUseNavigate,
  11. }));
  12. jest.mock('sentry/utils/analytics');
  13. describe('NewIssueExperienceButton', function () {
  14. const organization = OrganizationFixture({features: ['issue-details-streamline']});
  15. const user = UserFixture();
  16. user.options.prefersIssueDetailsStreamlinedUI = true;
  17. const location = LocationFixture({query: {streamline: '1'}});
  18. beforeEach(() => {
  19. ConfigStore.init();
  20. });
  21. it('does not appear by default', function () {
  22. render(
  23. <div data-test-id="test-id">
  24. <NewIssueExperienceButton />
  25. </div>
  26. );
  27. expect(screen.getByTestId('test-id')).toBeEmptyDOMElement();
  28. });
  29. it('appears when organization has flag', function () {
  30. render(
  31. <div data-test-id="test-id">
  32. <NewIssueExperienceButton />
  33. </div>,
  34. {organization}
  35. );
  36. expect(screen.getByTestId('test-id')).not.toBeEmptyDOMElement();
  37. });
  38. it('does not appear even if user prefers this UI', function () {
  39. act(() => ConfigStore.set('user', user));
  40. render(
  41. <div data-test-id="test-id">
  42. <NewIssueExperienceButton />
  43. </div>
  44. );
  45. expect(screen.getByTestId('test-id')).toBeEmptyDOMElement();
  46. });
  47. it('does not appear when query param is set', function () {
  48. render(
  49. <div data-test-id="test-id">
  50. <NewIssueExperienceButton />
  51. </div>,
  52. {router: {location}}
  53. );
  54. expect(screen.getByTestId('test-id')).toBeEmptyDOMElement();
  55. });
  56. it('triggers changes to the user config and location', async function () {
  57. const mockChangeUserSettings = MockApiClient.addMockResponse({
  58. url: '/users/me/',
  59. method: 'PUT',
  60. });
  61. render(<NewIssueExperienceButton />, {organization});
  62. const button = screen.getByRole('button', {
  63. name: 'Switch to the new issue experience',
  64. });
  65. await userEvent.click(button);
  66. // Text should change immediately
  67. expect(
  68. screen.getByRole('button', {name: 'Switch to the old issue experience'})
  69. ).toBeInTheDocument();
  70. // User option should be saved
  71. await waitFor(() => {
  72. expect(mockChangeUserSettings).toHaveBeenCalledWith(
  73. '/users/me/',
  74. expect.objectContaining({
  75. data: {
  76. options: {
  77. prefersIssueDetailsStreamlinedUI: true,
  78. },
  79. },
  80. })
  81. );
  82. });
  83. // Location should update
  84. expect(mockUseNavigate).toHaveBeenCalledWith(
  85. expect.objectContaining({query: {streamline: '1'}})
  86. );
  87. expect(trackAnalytics).toHaveBeenCalledTimes(1);
  88. // Clicking again toggles it off
  89. await userEvent.click(button);
  90. // Old text should be back
  91. expect(
  92. screen.getByRole('button', {name: 'Switch to the new issue experience'})
  93. ).toBeInTheDocument();
  94. // And save the option as false
  95. await waitFor(() => {
  96. expect(mockChangeUserSettings).toHaveBeenCalledWith(
  97. '/users/me/',
  98. expect.objectContaining({
  99. data: {
  100. options: {
  101. prefersIssueDetailsStreamlinedUI: false,
  102. },
  103. },
  104. })
  105. );
  106. });
  107. // Location should update again
  108. expect(mockUseNavigate).toHaveBeenCalledWith(
  109. expect.objectContaining({query: {streamline: '0'}})
  110. );
  111. expect(trackAnalytics).toHaveBeenCalledTimes(2);
  112. });
  113. });