From af00abed25759fc314bdefb44a3d9979e721f869 Mon Sep 17 00:00:00 2001 From: Krystof Woldrich Date: Mon, 19 Feb 2024 12:09:45 +0100 Subject: [PATCH 1/2] fix(client): Option `enabled: false` ensures no events are sent --- src/js/client.ts | 2 +- test/client.test.ts | 80 ++++++++++++++++++++++++++++++++++++++++++++- test/testutils.ts | 9 ++++- 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/src/js/client.ts b/src/js/client.ts index c896939295..107c925add 100644 --- a/src/js/client.ts +++ b/src/js/client.ts @@ -134,7 +134,7 @@ export class ReactNativeClient extends BaseClient { } let shouldClearOutcomesBuffer = true; - if (this._transport && this._dsn) { + if (this._isEnabled() && this._transport && this._dsn) { this.emit('beforeEnvelope', envelope); this._transport.send(envelope).then(null, reason => { diff --git a/test/client.test.ts b/test/client.test.ts index 0a710f5dc6..3596f5c3ae 100644 --- a/test/client.test.ts +++ b/test/client.test.ts @@ -1,5 +1,5 @@ import { defaultStackParser } from '@sentry/browser'; -import type { Envelope, Event, Outcome, Transport } from '@sentry/types'; +import type { Envelope, Event, MetricInstance, Outcome, Transport } from '@sentry/types'; import { rejectedSyncPromise, SentryError } from '@sentry/utils'; import * as RN from 'react-native'; @@ -11,6 +11,7 @@ import { NativeTransport } from '../src/js/transports/native'; import { SDK_NAME, SDK_PACKAGE_NAME, SDK_VERSION } from '../src/js/version'; import { NATIVE } from '../src/js/wrapper'; import { + createMockTransport, envelopeHeader, envelopeItemHeader, envelopeItemPayload, @@ -147,6 +148,83 @@ describe('Tests ReactNativeClient', () => { }); }); + describe('enabled option', () => { + test('captureMessage does not call transport when enabled false', () => { + const mockTransport = createMockTransport(); + const client = createDisabledClientWith(mockTransport); + + client.captureMessage('This message will never be sent because the client is disabled.'); + + expect(mockTransport.send).not.toBeCalled(); + }); + + test('captureException does not call transport when enabled false', () => { + const mockTransport = createMockTransport(); + const client = createDisabledClientWith(mockTransport); + + client.captureException(new Error('This exception will never be sent because the client is disabled.')); + + expect(mockTransport.send).not.toBeCalled(); + }); + + test('captureEvent does not call transport when enabled false', () => { + const mockTransport = createMockTransport(); + const client = createDisabledClientWith(mockTransport); + + client.captureEvent({ + message: 'This event will never be sent because the client is disabled.', + }); + + expect(mockTransport.send).not.toBeCalled(); + }); + + test('captureSession does not call transport when enabled false', () => { + const mockTransport = createMockTransport(); + const client = createDisabledClientWith(mockTransport); + + client.captureSession(getMockSession()); + + expect(mockTransport.send).not.toBeCalled(); + }); + + test('captureUserFeedback does not call transport when enabled false', () => { + const mockTransport = createMockTransport(); + const client = createDisabledClientWith(mockTransport); + + client.captureUserFeedback(getMockUserFeedback()); + + expect(mockTransport.send).not.toBeCalled(); + }); + + test('captureAggregateMetrics does not call transport when enabled false', () => { + const mockTransport = createMockTransport(); + const client = createDisabledClientWith(mockTransport); + + client.captureAggregateMetrics([ + { + // https://github.com/getsentry/sentry-javascript/blob/a7097d9ba2a74b2cb323da0ef22988a383782ffb/packages/core/test/lib/metrics/aggregator.test.ts#L115 + metric: { _value: 1 } as unknown as MetricInstance, + metricType: 'c', + name: 'requests', + tags: {}, + timestamp: expect.any(Number), + unit: 'none', + }, + ]); + + expect(mockTransport.send).not.toBeCalled(); + }); + + function createDisabledClientWith(transport: Transport) { + return new ReactNativeClient({ + ...DEFAULT_OPTIONS, + dsn: EXAMPLE_DSN, + enabled: false, + transport: () => transport, + }); + } + }); + describe('onReady', () => { test('calls onReady callback with true if Native SDK is initialized', done => { new ReactNativeClient( diff --git a/test/testutils.ts b/test/testutils.ts index 5e2ec0f682..256257b31e 100644 --- a/test/testutils.ts +++ b/test/testutils.ts @@ -1,5 +1,5 @@ import { Transaction } from '@sentry/core'; -import type { Session, UserFeedback } from '@sentry/types'; +import type { Session, Transport, UserFeedback } from '@sentry/types'; import { rejectedSyncPromise } from '@sentry/utils'; import { getBlankTransactionContext } from '../src/js/tracing/utils'; @@ -66,3 +66,10 @@ export const getSyncPromiseRejectOnFirstCall = (reason: unknown } }); }; + +export const createMockTransport = (): MockInterface => { + return { + send: jest.fn().mockResolvedValue(undefined), + flush: jest.fn().mockResolvedValue(true), + }; +}; From e4afee2eca4b61459f5f430165c5372c3a9373bf Mon Sep 17 00:00:00 2001 From: Krystof Woldrich Date: Mon, 19 Feb 2024 12:16:10 +0100 Subject: [PATCH 2/2] add changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 672fafcaad..7776c52fa2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Fixes + +- Option `enabled: false` ensures no events are sent ([#3606](https://github.com/getsentry/sentry-react-native/pull/3606)) + ### Dependencies - Bump Cocoa SDK from v8.17.1 to v8.20.0 ([#3476](https://github.com/getsentry/sentry-react-native/pull/3476))