eventNavigation.spec.tsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import {EventFixture} from 'sentry-fixture/event';
  2. import {GroupFixture} from 'sentry-fixture/group';
  3. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  4. import {browserHistory} from 'sentry/utils/browserHistory';
  5. import * as useMedia from 'sentry/utils/useMedia';
  6. import {EventNavigation} from 'sentry/views/issueDetails/streamline/eventNavigation';
  7. describe('EventNavigation', () => {
  8. const testEvent = EventFixture({
  9. id: 'event-id',
  10. size: 7,
  11. dateCreated: '2019-03-20T00:00:00.000Z',
  12. errors: [],
  13. entries: [],
  14. tags: [
  15. {key: 'environment', value: 'dev'},
  16. {key: 'replayId', value: 'replay-id'},
  17. ],
  18. previousEventID: 'prev-event-id',
  19. nextEventID: 'next-event-id',
  20. });
  21. const defaultProps = {
  22. event: testEvent,
  23. group: GroupFixture({id: 'group-id'}),
  24. };
  25. beforeEach(() => {
  26. Object.assign(navigator, {
  27. clipboard: {writeText: jest.fn().mockResolvedValue('')},
  28. });
  29. window.open = jest.fn();
  30. MockApiClient.addMockResponse({
  31. url: `/projects/org-slug/project-slug/events/event-id/actionable-items/`,
  32. body: {
  33. errors: [],
  34. },
  35. method: 'GET',
  36. });
  37. });
  38. describe('recommended event tabs', () => {
  39. it('can navigate to the oldest event', async () => {
  40. jest.spyOn(useMedia, 'default').mockReturnValue(true);
  41. render(<EventNavigation {...defaultProps} />);
  42. await userEvent.click(screen.getByRole('tab', {name: 'First Event'}));
  43. expect(browserHistory.push).toHaveBeenCalledWith({
  44. pathname: '/organizations/org-slug/issues/group-id/events/oldest/',
  45. query: {referrer: 'oldest-event'},
  46. });
  47. });
  48. it('can navigate to the latest event', async () => {
  49. jest.spyOn(useMedia, 'default').mockReturnValue(true);
  50. render(<EventNavigation {...defaultProps} />);
  51. await userEvent.click(screen.getByRole('tab', {name: 'Last Event'}));
  52. expect(browserHistory.push).toHaveBeenCalledWith({
  53. pathname: '/organizations/org-slug/issues/group-id/events/latest/',
  54. query: {referrer: 'latest-event'},
  55. });
  56. });
  57. it('can navigate to the recommended event', async () => {
  58. jest.spyOn(useMedia, 'default').mockReturnValue(true);
  59. render(<EventNavigation {...defaultProps} />, {
  60. router: {
  61. params: {eventId: 'latest'},
  62. },
  63. });
  64. await userEvent.click(screen.getByRole('tab', {name: 'Recommended Event'}));
  65. expect(browserHistory.push).toHaveBeenCalledWith({
  66. pathname: '/organizations/org-slug/issues/group-id/events/recommended/',
  67. query: {referrer: 'recommended-event'},
  68. });
  69. });
  70. });
  71. it('can navigate next/previous events', () => {
  72. render(<EventNavigation {...defaultProps} />);
  73. expect(screen.getByLabelText(/Previous Event/)).toHaveAttribute(
  74. 'href',
  75. `/organizations/org-slug/issues/group-id/events/prev-event-id/?referrer=previous-event`
  76. );
  77. expect(screen.getByLabelText(/Next Event/)).toHaveAttribute(
  78. 'href',
  79. `/organizations/org-slug/issues/group-id/events/next-event-id/?referrer=next-event`
  80. );
  81. });
  82. it('shows jump to sections', async () => {
  83. render(<EventNavigation {...defaultProps} />);
  84. expect(await screen.findByText('Replay')).toBeInTheDocument();
  85. expect(await screen.findByText('Tags')).toBeInTheDocument();
  86. expect(await screen.findByText('Event Highlights')).toBeInTheDocument();
  87. });
  88. it('can copy event ID', async () => {
  89. render(<EventNavigation {...defaultProps} />);
  90. await userEvent.click(screen.getByText(testEvent.id));
  91. expect(navigator.clipboard.writeText).toHaveBeenCalledWith(testEvent.id);
  92. });
  93. it('shows event actions dropdown', async () => {
  94. render(<EventNavigation {...defaultProps} />);
  95. await userEvent.click(screen.getByRole('button', {name: 'Event actions'}));
  96. await userEvent.click(screen.getByRole('menuitemradio', {name: 'Copy Event ID'}));
  97. expect(navigator.clipboard.writeText).toHaveBeenCalledWith(testEvent.id);
  98. await userEvent.click(screen.getByRole('button', {name: 'Event actions'}));
  99. await userEvent.click(screen.getByRole('menuitemradio', {name: 'Copy Event Link'}));
  100. expect(navigator.clipboard.writeText).toHaveBeenCalledWith(
  101. `http://localhost/organizations/org-slug/issues/group-id/events/event-id/`
  102. );
  103. await userEvent.click(screen.getByRole('button', {name: 'Event actions'}));
  104. await userEvent.click(screen.getByRole('menuitemradio', {name: 'View JSON'}));
  105. expect(window.open).toHaveBeenCalledWith(
  106. `https://us.sentry.io/api/0/projects/org-slug/project-slug/events/event-id/json/`
  107. );
  108. });
  109. it('shows processing issue button if there is an event error', async () => {
  110. MockApiClient.addMockResponse({
  111. url: `/projects/org-slug/project-slug/events/event-id/actionable-items/`,
  112. body: {
  113. errors: [
  114. {
  115. type: 'invalid_data',
  116. data: {
  117. name: 'logentry',
  118. },
  119. message: 'no message present',
  120. },
  121. ],
  122. },
  123. method: 'GET',
  124. });
  125. render(<EventNavigation {...defaultProps} />);
  126. expect(
  127. await screen.findByRole('button', {name: 'Processing Error'})
  128. ).toBeInTheDocument();
  129. });
  130. });