groupEventEntries.spec.tsx 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. import {initializeOrg} from 'sentry-test/initializeOrg';
  2. import {act, render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  3. import type {Error} from 'sentry/components/events/errors';
  4. import EventEntries from 'sentry/components/events/eventEntries';
  5. import {EntryType, Event} from 'sentry/types/event';
  6. import {OrganizationContext} from 'sentry/views/organizationContext';
  7. import {RouteContext} from 'sentry/views/routeContext';
  8. const {organization, project, router} = initializeOrg();
  9. const api = new MockApiClient();
  10. async function renderComponent(event: Event, errors?: Array<Error>) {
  11. render(
  12. <OrganizationContext.Provider value={organization}>
  13. <RouteContext.Provider
  14. value={{
  15. router,
  16. location: router.location,
  17. params: {},
  18. routes: [],
  19. }}
  20. >
  21. <EventEntries
  22. organization={organization}
  23. event={{...event, errors: errors ?? event.errors}}
  24. project={project}
  25. location={location}
  26. api={api}
  27. />
  28. </RouteContext.Provider>
  29. </OrganizationContext.Provider>
  30. );
  31. const alertSummaryInfo = await screen.findByTestId('event-error-alert');
  32. userEvent.click(alertSummaryInfo);
  33. const errorItems = await screen.findAllByTestId('event-error-item');
  34. return {alertSummaryInfo, errorItem: errorItems};
  35. }
  36. describe('GroupEventEntries', function () {
  37. const event = TestStubs.Event();
  38. beforeEach(() => {
  39. MockApiClient.addMockResponse({
  40. url: `/projects/${organization.slug}/${project.slug}/events/${event.id}/grouping-info/`,
  41. body: {},
  42. });
  43. MockApiClient.addMockResponse({
  44. url: `/projects/${organization.slug}/${project.slug}/files/dsyms/`,
  45. body: [],
  46. });
  47. });
  48. afterEach(() => {
  49. MockApiClient.clearMockResponses();
  50. });
  51. describe('EventError', function () {
  52. it('renders', async function () {
  53. const errors: Array<Error> = [
  54. {
  55. type: 'invalid_data',
  56. data: {
  57. name: 'logentry',
  58. },
  59. message: 'no message present',
  60. },
  61. {
  62. type: 'invalid_data',
  63. data: {
  64. name: 'breadcrumbs.values.2.data',
  65. },
  66. message: 'expected an object',
  67. },
  68. ];
  69. const {alertSummaryInfo, errorItem} = await renderComponent(event, errors);
  70. expect(alertSummaryInfo).toHaveTextContent(
  71. `There were ${errors.length} problems processing this event`
  72. );
  73. expect(errorItem.length).toBe(2);
  74. expect(screen.getByText(errors[0].data?.name!)).toBeInTheDocument();
  75. expect(screen.getByText(errors[1].data?.name!)).toBeInTheDocument();
  76. });
  77. describe('Proguard erros', function () {
  78. const proGuardUuid = 'a59c8fcc-2f27-49f8-af9e-02661fc3e8d7';
  79. it('Missing mapping file', async function () {
  80. const newEvent = {
  81. ...event,
  82. platform: 'java',
  83. entries: [
  84. {
  85. type: EntryType.DEBUGMETA,
  86. data: {
  87. images: [{type: 'proguard', uuid: proGuardUuid}],
  88. },
  89. },
  90. ],
  91. };
  92. await act(async () => {
  93. const {errorItem, alertSummaryInfo} = await renderComponent(newEvent);
  94. expect(alertSummaryInfo).toHaveTextContent(
  95. 'There was 1 problem processing this event'
  96. );
  97. expect(errorItem.length).toBe(1);
  98. expect(
  99. screen.getByText('A proguard mapping file was missing.')
  100. ).toBeInTheDocument();
  101. userEvent.click(screen.getByRole('button', {name: 'Expand'}));
  102. expect(await screen.findByText(proGuardUuid)).toBeInTheDocument();
  103. });
  104. });
  105. it("Don't display extra proguard errors, if the entry error of an event has an error of type 'proguard_missing_mapping'", async function () {
  106. const newEvent = {
  107. ...event,
  108. platform: 'java',
  109. entries: [
  110. {
  111. type: EntryType.DEBUGMETA,
  112. data: {
  113. images: [{type: 'proguard', uuid: proGuardUuid}],
  114. },
  115. },
  116. ],
  117. errors: [
  118. {
  119. type: 'proguard_missing_mapping',
  120. message: 'A proguard mapping file was missing.',
  121. data: {mapping_uuid: proGuardUuid},
  122. },
  123. ],
  124. };
  125. const {alertSummaryInfo, errorItem} = await renderComponent(newEvent);
  126. expect(alertSummaryInfo).toHaveTextContent(
  127. 'There was 1 problem processing this event'
  128. );
  129. expect(errorItem.length).toBe(1);
  130. expect(
  131. screen.getByText('A proguard mapping file was missing.')
  132. ).toBeInTheDocument();
  133. userEvent.click(screen.getByRole('button', {name: 'Expand'}));
  134. expect(await screen.findByText(proGuardUuid)).toBeInTheDocument();
  135. });
  136. describe('ProGuard Plugin seems to not be correctly configured', function () {
  137. it('find minified data in the exception entry', async function () {
  138. const newEvent = {
  139. ...event,
  140. platform: 'java',
  141. entries: [
  142. {
  143. type: 'exception',
  144. data: {
  145. values: [
  146. {
  147. stacktrace: {
  148. frames: [
  149. {
  150. function: null,
  151. colNo: null,
  152. vars: {},
  153. symbol: null,
  154. module: 'a.$a.a.a',
  155. },
  156. ],
  157. framesOmitted: null,
  158. registers: null,
  159. hasSystemFrames: false,
  160. },
  161. module: null,
  162. rawStacktrace: null,
  163. mechanism: null,
  164. threadId: null,
  165. value: 'Unexpected token else',
  166. type: 'SyntaxError',
  167. },
  168. ],
  169. excOmitted: null,
  170. hasSystemFrames: false,
  171. },
  172. },
  173. ],
  174. };
  175. const {alertSummaryInfo, errorItem} = await renderComponent(newEvent);
  176. expect(alertSummaryInfo).toHaveTextContent(
  177. 'There was 1 problem processing this event'
  178. );
  179. expect(errorItem.length).toBe(1);
  180. expect(
  181. screen.getByText('Some frames appear to be minified. Did you configure the')
  182. ).toBeInTheDocument();
  183. expect(
  184. screen.getByText('No additional details are available for this frame.')
  185. ).toBeInTheDocument();
  186. });
  187. it('find minified data in the threads entry', async function () {
  188. const newEvent = {
  189. ...event,
  190. platform: 'java',
  191. entries: [
  192. {
  193. type: 'exception',
  194. data: {
  195. values: [
  196. {
  197. stacktrace: {
  198. frames: [
  199. {
  200. function: null,
  201. colNo: null,
  202. vars: {},
  203. symbol: null,
  204. module: 'a.$a.a.a',
  205. },
  206. ],
  207. framesOmitted: null,
  208. registers: null,
  209. hasSystemFrames: false,
  210. },
  211. module: null,
  212. rawStacktrace: null,
  213. mechanism: null,
  214. threadId: null,
  215. value: 'Unexpected token else',
  216. type: 'SyntaxError',
  217. },
  218. ],
  219. excOmitted: null,
  220. hasSystemFrames: false,
  221. },
  222. },
  223. {
  224. type: 'threads',
  225. data: {
  226. values: [
  227. {
  228. stacktrace: {
  229. frames: [
  230. {
  231. function: 'start',
  232. package: 'libdyld.dylib',
  233. module: 'a.$a.a.a',
  234. },
  235. {
  236. function: 'main',
  237. package: 'iOS-Swift',
  238. module: '',
  239. },
  240. ],
  241. },
  242. },
  243. ],
  244. },
  245. },
  246. ],
  247. };
  248. const {alertSummaryInfo, errorItem} = await renderComponent(newEvent);
  249. expect(alertSummaryInfo).toHaveTextContent(
  250. 'There was 1 problem processing this event'
  251. );
  252. expect(errorItem.length).toBe(1);
  253. expect(
  254. screen.getByText('Some frames appear to be minified. Did you configure the')
  255. ).toBeInTheDocument();
  256. expect(screen.getByText('Sentry Gradle Plugin')).toBeInTheDocument();
  257. });
  258. });
  259. });
  260. });
  261. });