stackTracePreview.spec.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
  2. import {EventError} from 'sentry/types';
  3. import {EntryType, Event, ExceptionType, ExceptionValue, Frame} from 'sentry/types/event';
  4. import useApi from 'sentry/utils/useApi';
  5. import {StackTracePreview} from './stackTracePreview';
  6. const makeEvent = (event: Partial<Event> = {}): Event => {
  7. const evt: Event = {
  8. ...TestStubs.Event(),
  9. ...event,
  10. };
  11. return evt;
  12. };
  13. jest.mock('sentry/utils/useApi');
  14. describe('StackTracePreview', () => {
  15. it('fetches from projects when eventId and projectSlug are provided', async () => {
  16. const api = new MockApiClient();
  17. const spy = jest
  18. .spyOn(api, 'requestPromise')
  19. .mockResolvedValue(makeEvent({id: 'event_id', entries: []}));
  20. // @ts-ignore useApi is mocked
  21. useApi.mockReturnValue(api);
  22. render(
  23. <StackTracePreview issueId="issue" eventId="event_id" projectSlug="project_slug">
  24. Preview Trigger
  25. </StackTracePreview>
  26. );
  27. userEvent.hover(screen.getByText(/Preview Trigger/));
  28. await waitFor(() => {
  29. expect(spy.mock.calls[0][0]).toBe(
  30. `/projects/org-slug/project_slug/events/event_id/`
  31. );
  32. });
  33. });
  34. it('fetches from issues when issueId when eventId and projectSlug are not provided', async () => {
  35. const api = new MockApiClient();
  36. const spy = jest
  37. .spyOn(api, 'requestPromise')
  38. .mockResolvedValue(makeEvent({id: 'event_id', entries: []}));
  39. // @ts-ignore useApi is mocked
  40. useApi.mockReturnValue(api);
  41. render(<StackTracePreview issueId="issue">Preview Trigger</StackTracePreview>);
  42. userEvent.hover(screen.getByText(/Preview Trigger/));
  43. await waitFor(() => {
  44. expect(spy.mock.calls[0][0]).toBe(
  45. `/issues/issue/events/latest/?collapse=stacktraceOnly`
  46. );
  47. });
  48. });
  49. it('renders error message', async () => {
  50. const api = new MockApiClient();
  51. jest
  52. .spyOn(api, 'requestPromise')
  53. .mockRejectedValue(makeEvent({id: 'event_id', entries: []}));
  54. // @ts-ignore useApi is mocked
  55. useApi.mockReturnValue(api);
  56. render(<StackTracePreview issueId="issue">Preview Trigger</StackTracePreview>);
  57. userEvent.hover(screen.getByText(/Preview Trigger/));
  58. expect(await screen.findByText(/Failed to load stack trace/)).toBeInTheDocument();
  59. });
  60. it('warns about no stacktrace', async () => {
  61. const api = new MockApiClient();
  62. jest
  63. .spyOn(api, 'requestPromise')
  64. .mockResolvedValue(makeEvent({id: 'event_id', entries: []}));
  65. // @ts-ignore useApi is mocked
  66. useApi.mockReturnValue(api);
  67. render(<StackTracePreview issueId="issue">Preview Trigger</StackTracePreview>);
  68. userEvent.hover(screen.getByText(/Preview Trigger/));
  69. expect(
  70. await screen.findByText(/There is no stack trace available for this issue./)
  71. ).toBeInTheDocument();
  72. });
  73. it.each([
  74. ['stack-trace-content', []],
  75. ['stack-trace-content-v2', ['grouping-stacktrace-ui']],
  76. ])('renders %s', async (component, features) => {
  77. const api = new MockApiClient();
  78. const frame: Frame = {
  79. colNo: 0,
  80. filename: 'file.js',
  81. function: 'throwError',
  82. lineNo: 0,
  83. absPath: null,
  84. context: [],
  85. errors: null,
  86. inApp: false,
  87. instructionAddr: null,
  88. module: null,
  89. package: null,
  90. platform: null,
  91. rawFunction: null,
  92. symbol: null,
  93. symbolAddr: null,
  94. trust: undefined,
  95. vars: null,
  96. };
  97. const thread: ExceptionValue = {
  98. stacktrace: {
  99. hasSystemFrames: false,
  100. registers: {},
  101. framesOmitted: 0,
  102. frames: [frame],
  103. },
  104. mechanism: null,
  105. module: null,
  106. rawStacktrace: null,
  107. threadId: null,
  108. type: '',
  109. value: '',
  110. };
  111. const exceptionValue: ExceptionType = {
  112. values: [thread],
  113. excOmitted: undefined,
  114. hasSystemFrames: false,
  115. };
  116. const errorEvent: EventError = {
  117. id: 'event_id',
  118. entries: [
  119. {
  120. type: EntryType.EXCEPTION,
  121. data: exceptionValue,
  122. },
  123. ],
  124. } as EventError;
  125. jest.spyOn(api, 'requestPromise').mockResolvedValue(makeEvent(errorEvent));
  126. // @ts-ignore useApi is mocked
  127. useApi.mockReturnValue(api);
  128. render(<StackTracePreview issueId="issue">Preview Trigger</StackTracePreview>, {
  129. organization: {features},
  130. });
  131. userEvent.hover(screen.getByText(/Preview Trigger/));
  132. expect(await screen.findByTestId(component)).toBeInTheDocument();
  133. });
  134. });