sourceMapDebug.spec.tsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  2. import {textWithMarkupMatcher} from 'sentry-test/utils';
  3. import {Event, ExceptionValue} from 'sentry/types';
  4. import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
  5. import {SourceMapDebug} from './sourceMapDebug';
  6. import {
  7. getUniqueFilesFromException,
  8. SourceMapDebugError,
  9. SourceMapProcessingIssueType,
  10. } from './useSourceMapDebug';
  11. jest.mock('sentry/utils/analytics/trackAdvancedAnalyticsEvent');
  12. describe('SourceMapDebug', () => {
  13. const organization = TestStubs.Organization({});
  14. const project = TestStubs.Project();
  15. const eventId = '1ec1bd65b0b1484b97162087a652421b';
  16. const exceptionValues: ExceptionValue[] = [
  17. {
  18. type: 'TypeError',
  19. value: "Cannot read properties of undefined (reading 'map')",
  20. mechanism: {
  21. type: 'generic',
  22. handled: true,
  23. },
  24. threadId: null,
  25. module: null,
  26. stacktrace: {
  27. frames: [
  28. {
  29. filename: './app/views/organizationStats/teamInsights/controls.tsx',
  30. absPath: 'webpack:///./app/views/organizationStats/teamInsights/controls.tsx',
  31. module: 'app/views/organizationStats/teamInsights/controls',
  32. package: null,
  33. platform: null,
  34. instructionAddr: null,
  35. symbolAddr: null,
  36. function: 'TeamStatsControls',
  37. rawFunction: null,
  38. symbol: null,
  39. context: [],
  40. lineNo: 53,
  41. colNo: 25,
  42. inApp: true,
  43. trust: null,
  44. errors: null,
  45. vars: null,
  46. minGroupingLevel: 0,
  47. },
  48. ],
  49. framesOmitted: null,
  50. registers: null,
  51. hasSystemFrames: true,
  52. },
  53. rawStacktrace: {} as any,
  54. },
  55. ];
  56. const url = `/projects/${organization.slug}/${project.slug}/events/${eventId}/source-map-debug/`;
  57. const sdkName = 'sentry.javascript.browser';
  58. const debugFrames = getUniqueFilesFromException(exceptionValues, {
  59. orgSlug: organization.slug,
  60. projectSlug: project.slug,
  61. eventId,
  62. });
  63. const event: Event = {
  64. ...TestStubs.Event(),
  65. id: eventId,
  66. sdk: {
  67. name: sdkName,
  68. },
  69. } as Event;
  70. it('should use unqiue in app frames', () => {
  71. expect(debugFrames).toHaveLength(1);
  72. expect(debugFrames[0].filename).toBe(
  73. './app/views/organizationStats/teamInsights/controls.tsx'
  74. );
  75. });
  76. it('should show message for MISSING_RELEASE', async () => {
  77. MockApiClient.addMockResponse({
  78. url,
  79. body: {
  80. errors: [
  81. {
  82. type: SourceMapProcessingIssueType.MISSING_RELEASE,
  83. message: '',
  84. data: null,
  85. },
  86. ],
  87. },
  88. match: [MockApiClient.matchQuery({exception_idx: '0', frame_idx: '0'})],
  89. });
  90. render(<SourceMapDebug debugFrames={debugFrames} event={event} />, {
  91. organization,
  92. });
  93. expect(
  94. await screen.findByText(
  95. "We've encountered 1 problem un-minifying your applications source code!"
  96. )
  97. ).toBeInTheDocument();
  98. // Step 1
  99. expect(screen.getByText('Event missing Release tag')).toBeInTheDocument();
  100. expect(screen.getByRole('link', {name: 'Read Guide'})).toHaveAttribute(
  101. 'href',
  102. 'https://docs.sentry.io/platforms/javascript/sourcemaps/#uploading-source-maps-to-sentry'
  103. );
  104. });
  105. it('should fill message with data for PARTIAL_MATCH', async () => {
  106. const error: SourceMapDebugError = {
  107. type: SourceMapProcessingIssueType.PARTIAL_MATCH,
  108. message: '',
  109. data: {
  110. absPath: 'insertPath',
  111. partialMatchPath: 'matchedSourcemapPath',
  112. urlPrefix: 'urlPrefix',
  113. },
  114. };
  115. MockApiClient.addMockResponse({
  116. url,
  117. body: {errors: [error]},
  118. match: [MockApiClient.matchQuery({exception_idx: '0', frame_idx: '0'})],
  119. });
  120. render(<SourceMapDebug debugFrames={debugFrames} event={event} />, {
  121. organization,
  122. });
  123. expect(
  124. await screen.findByText(
  125. "We've encountered 1 problem un-minifying your applications source code!"
  126. )
  127. ).toBeInTheDocument();
  128. expect(
  129. screen.getByText('Partial Absolute Path Match', {exact: false})
  130. ).toBeInTheDocument();
  131. expect(screen.getByRole('link', {name: 'Read Guide'})).toHaveAttribute(
  132. 'href',
  133. 'https://docs.sentry.io/platforms/javascript/sourcemaps/troubleshooting_js/#verify-artifact-names-match-stack-trace-frames'
  134. );
  135. });
  136. it('should expand URL_NOT_VALID description and emit an analytics event', async () => {
  137. const error: SourceMapDebugError = {
  138. type: SourceMapProcessingIssueType.URL_NOT_VALID,
  139. message: '',
  140. data: {absPath: 'absValue'},
  141. };
  142. MockApiClient.addMockResponse({
  143. url,
  144. body: {errors: [error]},
  145. });
  146. render(<SourceMapDebug debugFrames={debugFrames} event={event} />, {
  147. organization,
  148. });
  149. expect(
  150. await screen.findByText(
  151. "We've encountered 1 problem un-minifying your applications source code!"
  152. )
  153. ).toBeInTheDocument();
  154. const expandedMessage =
  155. 'The abs_path of the stack frame is absValue which is not a valid URL. Read our docs for troubleshooting help.';
  156. expect(
  157. screen.queryByText(textWithMarkupMatcher(expandedMessage))
  158. ).not.toBeInTheDocument();
  159. userEvent.click(screen.getByRole('button', {name: 'Expand'}));
  160. expect(trackAdvancedAnalyticsEvent).toHaveBeenCalledTimes(1);
  161. expect(screen.getByText(textWithMarkupMatcher(expandedMessage))).toBeInTheDocument();
  162. expect(screen.getByRole('link', {name: 'Read Guide'})).toHaveAttribute(
  163. 'href',
  164. 'https://docs.sentry.io/platforms/javascript/sourcemaps/troubleshooting_js/#verify-artifact-names-match-stack-trace-frames'
  165. );
  166. });
  167. });