diff --git a/packages/core/test/lib/hint.test.ts b/packages/core/test/lib/hint.test.ts new file mode 100644 index 000000000000..03b755a63c71 --- /dev/null +++ b/packages/core/test/lib/hint.test.ts @@ -0,0 +1,96 @@ +import { captureEvent, configureScope } from '@sentry/hub'; +import { getGlobalObject } from '@sentry/utils'; + +import { initAndBind } from '../../src/sdk'; +import { getDefaultTestClientOptions, TestClient } from '../mocks/client'; +import { AddAttachmentTestIntegration } from '../mocks/integration'; + +const PUBLIC_DSN = 'https://username@domain/123'; +const sendEvent = jest.spyOn(TestClient.prototype, 'sendEvent'); + +describe('Hint', () => { + beforeEach(() => { + TestClient.sendEventCalled = undefined; + TestClient.instance = undefined; + }); + + afterEach(() => { + jest.clearAllMocks(); + delete getGlobalObject().__SENTRY__; + }); + + describe('attachments', () => { + test('can be mutated in beforeSend', () => { + expect.assertions(1); + + const options = getDefaultTestClientOptions({ + dsn: PUBLIC_DSN, + beforeSend: (event, hint) => { + hint.attachments = [...(hint.attachments || []), { filename: 'another.file', data: 'more text' }]; + return event; + }, + }); + + const client = new TestClient(options); + client.captureEvent({}); + + const [, hint] = sendEvent.mock.calls[0]; + expect(hint).toEqual({ attachments: [{ filename: 'another.file', data: 'more text' }] }); + }); + + test('gets passed through to beforeSend and can be further mutated', () => { + expect.assertions(1); + + const options = getDefaultTestClientOptions({ + dsn: PUBLIC_DSN, + beforeSend: (event, hint) => { + hint.attachments = [...(hint.attachments || []), { filename: 'another.file', data: 'more text' }]; + return event; + }, + }); + + const client = new TestClient(options); + client.captureEvent({}, { attachments: [{ filename: 'some-file.txt', data: 'Hello' }] }); + + const [, hint] = sendEvent.mock.calls[0]; + expect(hint).toEqual({ + attachments: [ + { filename: 'some-file.txt', data: 'Hello' }, + { filename: 'another.file', data: 'more text' }, + ], + }); + }); + + test('can be mutated by an integration via event processor', () => { + expect.assertions(1); + + const options = getDefaultTestClientOptions({ + dsn: PUBLIC_DSN, + integrations: [new AddAttachmentTestIntegration()], + }); + + initAndBind(TestClient, options); + captureEvent({}); + + const [, hint] = sendEvent.mock.calls[0]; + expect(hint?.attachments).toEqual([{ filename: 'integration.file', data: 'great content!' }]); + }); + + test('get copied from scope to hint', () => { + expect.assertions(1); + + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); + initAndBind(TestClient, options); + + configureScope(scope => scope.addAttachment({ filename: 'scope.file', data: 'great content!' })); + + captureEvent({}, { attachments: [{ filename: 'some-file.txt', data: 'Hello' }] }); + + const [, hint] = sendEvent.mock.calls[0]; + expect(hint?.attachments).toEqual([ + { filename: 'some-file.txt', data: 'Hello' }, + { filename: 'scope.file', data: 'great content!' }, + ]); + }); + }); +}); diff --git a/packages/core/test/mocks/integration.ts b/packages/core/test/mocks/integration.ts index 2e192fb12227..868446665949 100644 --- a/packages/core/test/mocks/integration.ts +++ b/packages/core/test/mocks/integration.ts @@ -22,3 +22,16 @@ export class TestIntegration implements Integration { }); } } + +export class AddAttachmentTestIntegration implements Integration { + public static id: string = 'AddAttachmentTestIntegration'; + + public name: string = 'AddAttachmentTestIntegration'; + + public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void): void { + addGlobalEventProcessor((event, hint) => { + hint.attachments = [...(hint.attachments || []), { filename: 'integration.file', data: 'great content!' }]; + return event; + }); + } +}