import {render, screen, userEvent, within} from 'sentry-test/reactTestingLibrary'; import {textWithMarkupMatcher} from 'sentry-test/utils'; import {EventErrors} from 'sentry/components/events/eventErrors'; import { GenericSchemaErrors, JavascriptProcessingErrors, } from 'sentry/constants/eventErrors'; import {EntryType} from 'sentry/types'; describe('EventErrors', () => { const defaultProps = { project: TestStubs.Project(), event: TestStubs.Event(), isShare: false, }; beforeEach(() => { jest.resetAllMocks(); MockApiClient.clearMockResponses(); }); it('does not render anything when no errors', () => { const {container} = render(); expect(container).toBeEmptyDOMElement(); }); it('renders with errors in event', async () => { const eventWithErrors = TestStubs.Event({ errors: [ { type: 'invalid_data', data: { name: 'logentry', }, message: 'no message present', }, { type: 'invalid_data', data: { name: 'breadcrumbs.values.2.data', }, message: 'expected an object', }, ], }); render(); await userEvent.click( screen.getByText(/there were 2 problems processing this event/i) ); const errorItems = screen.getAllByTestId('event-error-item'); expect(errorItems).toHaveLength(2); expect(within(errorItems[0]).getByText('logentry')).toBeInTheDocument(); expect( within(errorItems[1]).getByText('breadcrumbs.values.2.data') ).toBeInTheDocument(); }); it('does not render hidden cocoa errors', async () => { const eventWithErrors = TestStubs.Event({ errors: [ { type: 'not_invalid_data', data: { name: 'logentry', }, message: 'no message present', }, { type: 'invalid_data', data: { name: 'contexts.trace.sampled', }, message: 'expected an object', }, ], sdk: { name: 'sentry.cocoa', version: '8.7.3', }, }); render(); await userEvent.click(screen.getByText(/there was 1 problem processing this event/i)); const errorItem = screen.getByTestId('event-error-item'); expect(errorItem).toBeInTheDocument(); expect(within(errorItem).getByText('logentry')).toBeInTheDocument(); }); it('hides source map not found error', () => { const eventWithDifferentDist = TestStubs.Event({ errors: [ { type: JavascriptProcessingErrors.JS_MISSING_SOURCE, }, ], }); render(); expect(screen.queryByText(/problem processing this event/i)).not.toBeInTheDocument(); }); it('hides event error that is hidden', () => { const eventWithUnknownError = TestStubs.Event({ errors: [ { type: GenericSchemaErrors.UNKNOWN_ERROR, }, ], }); render(); expect(screen.queryByText(/problem processing this event/i)).not.toBeInTheDocument(); }); describe('proguard errors', () => { beforeEach(() => { MockApiClient.addMockResponse({ url: `/projects/org-slug/project-slug/files/dsyms/`, body: [], }); }); const proGuardUuid = 'a59c8fcc-2f27-49f8-af9e-02661fc3e8d7'; it('displays missing mapping file with debugmeta but no event error', async () => { const eventWithDebugMeta = TestStubs.Event({ platform: 'java', entries: [ { type: EntryType.DEBUGMETA, data: { images: [{type: 'proguard', uuid: proGuardUuid}], }, }, ], }); render(); await userEvent.click( await screen.findByText(/there was 1 problem processing this event/i) ); const errorItem = screen.getByTestId('event-error-item'); expect(errorItem).toBeInTheDocument(); expect( within(errorItem).getByText('A proguard mapping file was missing.') ).toBeInTheDocument(); }); it('displays missing mapping file with debugmeta and matching event error', async () => { const eventWithDebugMeta = TestStubs.Event({ platform: 'java', entries: [ { type: EntryType.DEBUGMETA, data: { images: [{type: 'proguard', uuid: proGuardUuid}], }, }, ], errors: [ { type: 'proguard_missing_mapping', message: 'A proguard mapping file was missing.', data: {mapping_uuid: proGuardUuid}, }, ], }); render(); await userEvent.click( await screen.findByText(/there was 1 problem processing this event/i) ); const errorItem = screen.getByTestId('event-error-item'); expect(errorItem).toBeInTheDocument(); expect( within(errorItem).getByText('A proguard mapping file was missing.') ).toBeInTheDocument(); }); describe('ProGuard Plugin seems to not be correctly configured', function () { it('find minified data in the exception entry', async function () { const newEvent = TestStubs.Event({ platform: 'java', entries: [ { type: 'exception', data: { values: [ { stacktrace: { frames: [ { function: null, colNo: null, vars: {}, symbol: null, module: 'a.$a.a.a', }, ], framesOmitted: null, registers: null, hasSystemFrames: false, }, module: null, rawStacktrace: null, mechanism: null, threadId: null, value: 'Unexpected token else', type: 'SyntaxError', }, ], excOmitted: null, hasSystemFrames: false, }, }, ], }); render(); await userEvent.click( await screen.findByText(/there was 1 problem processing this event/i) ); const errorItem = screen.getByTestId('event-error-item'); expect(errorItem).toBeInTheDocument(); expect( within(errorItem).getByText( textWithMarkupMatcher( 'Some frames appear to be minified. Did you configure the Sentry Gradle Plugin?' ) ) ).toBeInTheDocument(); }); it('find minified data in the threads entry', async function () { const newEvent = TestStubs.Event({ platform: 'java', entries: [ { type: 'exception', data: { values: [ { stacktrace: { frames: [ { function: null, colNo: null, vars: {}, symbol: null, module: 'a.$a.a.a', }, ], framesOmitted: null, registers: null, hasSystemFrames: false, }, module: null, rawStacktrace: null, mechanism: null, threadId: null, value: 'Unexpected token else', type: 'SyntaxError', }, ], excOmitted: null, hasSystemFrames: false, }, }, { type: 'threads', data: { values: [ { stacktrace: { frames: [ { function: 'start', package: 'libdyld.dylib', module: 'a.$a.a.a', }, { function: 'main', package: 'iOS-Swift', module: '', }, ], }, }, ], }, }, ], }); render(); await userEvent.click( await screen.findByText(/there was 1 problem processing this event/i) ); const errorItem = screen.getByTestId('event-error-item'); expect(errorItem).toBeInTheDocument(); expect( within(errorItem).getByText( textWithMarkupMatcher( 'Some frames appear to be minified. Did you configure the Sentry Gradle Plugin?' ) ) ).toBeInTheDocument(); }); }); }); });