Skip to content

Commit

Permalink
Add disabled option
Browse files Browse the repository at this point in the history
  • Loading branch information
silesky committed Nov 8, 2023
1 parent 008a019 commit 6a23d0b
Show file tree
Hide file tree
Showing 9 changed files with 789 additions and 657 deletions.
5 changes: 5 additions & 0 deletions .changeset/unlucky-kids-invite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@segment/analytics-next': patch
---

Add 'disable' boolean option to allow for disabling Segment in a testing environment.
2 changes: 1 addition & 1 deletion packages/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"size-limit": [
{
"path": "dist/umd/index.js",
"limit": "29 KB"
"limit": "29.5 KB"
}
],
"dependencies": {
Expand Down
43 changes: 41 additions & 2 deletions packages/browser/src/browser/__tests__/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
highEntropyTestData,
lowEntropyTestData,
} from '../../test-helpers/fixtures/client-hints'
import { getGlobalAnalytics } from '../..'
import { getGlobalAnalytics, NullAnalytics } from '../..'

let fetchCalls: ReturnType<typeof parseFetchCall>[] = []

Expand Down Expand Up @@ -94,11 +94,11 @@ const amplitudeWriteKey = 'bar'

beforeEach(() => {
setGlobalCDNUrl(undefined as any)
fetchCalls = []
})

describe('Initialization', () => {
beforeEach(async () => {
fetchCalls = []
jest.resetAllMocks()
jest.resetModules()
})
Expand Down Expand Up @@ -1209,4 +1209,43 @@ describe('Options', () => {
expect(integrationEvent.timestamp()).toBeInstanceOf(Date)
})
})

describe('disable', () => {
/**
* Note: other tests in null-analytics.test.ts cover the NullAnalytics class (including persistence)
*/
it('should return a null version of analytics / context', async () => {
const [analytics, context] = await AnalyticsBrowser.load(
{
writeKey,
},
{ disable: true }
)
expect(context).toBeInstanceOf(Context)
expect(analytics).toBeInstanceOf(NullAnalytics)
expect(analytics.initialized).toBe(true)
})

it('should not fetch cdn settings or dispatch events', async () => {
const [analytics] = await AnalyticsBrowser.load(
{
writeKey,
},
{ disable: true }
)
await analytics.track('foo')
expect(fetchCalls.length).toBe(0)
})

it('should only accept a boolean value', async () => {
const [analytics] = await AnalyticsBrowser.load(
{
writeKey,
},
// @ts-ignore
{ disable: 'true' }
)
expect(analytics).not.toBeInstanceOf(NullAnalytics)
})
})
})
20 changes: 19 additions & 1 deletion packages/browser/src/browser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { getProcessEnv } from '../lib/get-process-env'
import { getCDN, setGlobalCDNUrl } from '../lib/parse-cdn'

import { fetch } from '../lib/fetch'
import { Analytics, AnalyticsSettings, InitOptions } from '../core/analytics'
import {
Analytics,
AnalyticsSettings,
NullAnalytics,
InitOptions,
} from '../core/analytics'
import { Context } from '../core/context'
import { Plan } from '../core/events'
import { Plugin } from '../core/plugin'
Expand Down Expand Up @@ -300,6 +305,11 @@ async function loadAnalytics(
options: InitOptions = {},
preInitBuffer: PreInitMethodCallBuffer
): Promise<[Analytics, Context]> {
// return no-op analytics instance if disabled
if (options.disable === true) {
return [new NullAnalytics(), Context.system()]
}

if (options.globalAnalyticsKey)
setGlobalAnalyticsKey(options.globalAnalyticsKey)
// this is an ugly side-effect, but it's for the benefits of the plugins that get their cdn via getCDN()
Expand All @@ -313,6 +323,14 @@ async function loadAnalytics(
legacySettings = options.updateCDNSettings(legacySettings)
}

// if options.disable is a function, we allow user to disable analytics based on CDN Settings
if (typeof options.disable === 'function') {
const disabled = await options.disable(legacySettings)
if (disabled) {
return [new NullAnalytics(), Context.system()]
}
}

const retryQueue: boolean =
legacySettings.integrations['Segment.io']?.retryQueue ?? true

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { getAjsBrowserStorage } from '../../../test-helpers/browser-storage'
import { Analytics } from '../analytics'
import { NullAnalytics } from '../null-analytics'

describe(NullAnalytics, () => {
it('should return an instance of Analytics / NullAnalytics', () => {
const analytics = new NullAnalytics()
expect(analytics).toBeInstanceOf(Analytics)
expect(analytics).toBeInstanceOf(NullAnalytics)
})

it('should have initialized set to true', () => {
const analytics = new NullAnalytics()
expect(analytics.initialized).toBe(true)
})

it('should have no plugins', async () => {
const analytics = new NullAnalytics()
expect(analytics.queue.plugins).toHaveLength(0)
})
it('should dispatch events', async () => {
const analytics = new NullAnalytics()
const ctx = await analytics.track('foo')
expect(ctx.event.event).toBe('foo')
})

it('should have disableClientPersistence set to true', () => {
const analytics = new NullAnalytics()
expect(analytics.options.disableClientPersistence).toBe(true)
})

it('integration: should not touch cookies or localStorage', async () => {
const analytics = new NullAnalytics()
await analytics.track('foo')
const storage = getAjsBrowserStorage()
expect(Object.values(storage).every((v) => !v)).toBe(true)
})
})
Loading

0 comments on commit 6a23d0b

Please sign in to comment.