groupEventEntries.spec.tsx 8.6 KB

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