UNPKG

@gitlab/application-sdk-browser

Version:

Client side Browser SDK for GitLab Application services

384 lines (327 loc) 10.4 kB
import { newTracker, trackSelfDescribingEvent, trackPageView, setUserId, addGlobalContexts, disableAnonymousTracking, enableActivityTracking, setCustomUrl, setReferrerUrl, } from '@snowplow/browser-tracker'; import { doNotTrackEnabled } from '../src/utils/doNotTrack'; import { glClientSDK } from '../src/main'; import { DEFAULT_PAGEPING_OPTIONS, DEFAULT_TRACKER_ID, SCHEMAS, } from '../src/utils/constants'; import { asMock } from './utils/asMock'; import { trackError } from '@snowplow/browser-plugin-error-tracking'; import { GitLabClientSDKType } from '../src/types'; jest.mock('../src/utils/doNotTrack', () => ({ doNotTrackEnabled: jest.fn(), })); jest.mock('@snowplow/browser-tracker', () => ({ ...jest.requireActual('@snowplow/browser-tracker'), newTracker: jest.fn(), enableActivityTracking: jest.fn(), trackSelfDescribingEvent: jest.fn(), trackPageView: jest.fn(), setUserId: jest.fn(), addGlobalContexts: jest.fn(), disableAnonymousTracking: jest.fn(), setCustomUrl: jest.fn(), setReferrerUrl: jest.fn(), })); jest.mock('@snowplow/browser-plugin-error-tracking', () => ({ ...jest.requireActual('@snowplow/browser-plugin-error-tracking'), trackError: jest.fn(), })); describe('GlClient', () => { let glClient: GitLabClientSDKType; beforeAll(() => { Object.defineProperty(document, 'cookie', { get: jest.fn().mockImplementation(() => { return ''; }), set: jest.fn().mockImplementation(() => {}), }); }); describe.each` name | func | funcValue ${'DNT'} | ${doNotTrackEnabled} | ${true} `('with tracking disabled by $name', ({ func, funcValue }) => { beforeEach(() => { func.mockReturnValue(funcValue); glClient = glClientSDK({ appId: '123', host: 'collector.gitlab.com', }); }); it('basic setup initialises GlClientSDK', () => { expect(glClient).toBeDefined(); }); describe('track', () => { it('does not call Snowplow', () => { glClient.track('testEvent'); expect(trackSelfDescribingEvent).not.toHaveBeenCalled(); }); }); describe('page', () => { it('does not call Snowplow', () => { glClient.page(); expect(trackSelfDescribingEvent).not.toHaveBeenCalled(); }); }); describe('identify', () => { it('does not call Snowplow', () => { glClient.identify('1'); expect(setUserId).not.toHaveBeenCalled(); expect(addGlobalContexts).not.toHaveBeenCalled(); }); }); }); describe('with tracking enabled', () => { beforeEach(() => { asMock(doNotTrackEnabled).mockReturnValue(false); glClient = glClientSDK({ appId: '123', host: 'collector.gitlab.com', }); }); it('basic setup initialises GlClientSDK', () => { expect(glClient).toBeDefined(); }); describe('track', () => { it('call will send off Snowplow Call', () => { const eventAttributes = { key: 'value' }; const eventName = 'custom_event'; glClient.track(eventName, eventAttributes); expect(trackSelfDescribingEvent).toHaveBeenCalledWith({ event: { schema: SCHEMAS.CUSTOM_EVENT, data: { name: eventName, props: { ...eventAttributes }, }, }, }); }); }); describe('pagePingTracking', () => { it('call will enableActivityTracking with default options if set to true', () => { glClient = glClientSDK({ appId: '123', host: 'collector.gitlab.com', pagePingTracking: true, }); expect(enableActivityTracking).toHaveBeenCalledWith( DEFAULT_PAGEPING_OPTIONS ); }); it('call will disableActivityTracking if set to false', () => { jest.resetAllMocks(); glClient = glClientSDK({ appId: '123', host: 'collector.gitlab.com', pagePingTracking: false, }); expect(enableActivityTracking).not.toHaveBeenCalled(); }); it('call will enableActivityTracking with custom options if set to an object', () => { const customOptions = { minimumVisitLength: 10, heartbeatDelay: 5 }; glClient = glClientSDK({ appId: '123', host: 'collector.gitlab.com', pagePingTracking: customOptions, }); expect(enableActivityTracking).toHaveBeenCalledWith(customOptions); }); it('call will enableActivityTracking with default options if not passed', () => { glClient = glClientSDK({ appId: '123', host: 'collector.gitlab.com', }); expect(enableActivityTracking).toHaveBeenCalledWith( DEFAULT_PAGEPING_OPTIONS ); }); }); describe('page', () => { it('call will send off snowplow page Track Call', () => { glClient.page(); expect(trackPageView).toHaveBeenCalled(); }); }); describe('identify', () => { it('call will send off Jitsu id Call', () => { const USER_ID = '12345'; const USER_ATTRIBUTES = { userId: USER_ID, }; glClient.identify(USER_ID, USER_ATTRIBUTES); expect(setUserId).toHaveBeenCalledWith(USER_ID); expect(addGlobalContexts).toHaveBeenCalledWith([ { schema: SCHEMAS.USER_CONTEXT, data: USER_ATTRIBUTES, }, ]); }); }); }); describe('with tracking enabled', () => { beforeEach(() => { asMock(doNotTrackEnabled).mockReturnValue(false); glClient = glClientSDK({ appId: '123', host: 'collector.gitlab.com', }); }); describe('track', () => { it('call will send off Snowplow Call', () => { const eventAttributes = { key: 'value' }; const eventName = 'custom_event'; glClient.track(eventName, eventAttributes); expect(trackSelfDescribingEvent).toHaveBeenCalledWith({ event: { schema: SCHEMAS.CUSTOM_EVENT, data: { name: eventName, props: { ...eventAttributes }, }, }, }); }); }); describe('addCookieConsent', () => { it('will call disableAnonymousTracking', () => { glClient.addCookieConsent(); expect(disableAnonymousTracking).toHaveBeenCalledWith({ stateStorageStrategy: 'cookieAndLocalStorage', }); }); }); }); describe('stateStorageStrategy', () => { beforeAll(() => { asMock(doNotTrackEnabled).mockReturnValue(false); }); it.each` hasCookieConsent | value ${true} | ${undefined} ${false} | ${'none'} `( 'sets stateStorageStrategy as `none` when set to `$hasCookieConsent`', ({ hasCookieConsent, value }) => { glClient = glClientSDK({ appId: '123', host: 'collector.gitlab.com', hasCookieConsent, }); expect(newTracker).toHaveBeenCalledWith( DEFAULT_TRACKER_ID, 'collector.gitlab.com', hasCookieConsent ? expect.not.objectContaining({ stateStorageStrategy: value, }) : expect.objectContaining({ stateStorageStrategy: value, }) ); } ); }); }); describe('trackError', () => { it('should not be called when tracking is disabled', () => { asMock(doNotTrackEnabled).mockReturnValue(true); const glClient = glClientSDK({ appId: '123', host: 'collector.gitlab.com', }); glClient.trackError({ message: 'Error occured' }); expect(trackError).not.toHaveBeenCalled(); }); it('should not be called when error tracking plugin is disabled', () => { asMock(doNotTrackEnabled).mockReturnValue(false); const glClient = glClientSDK({ appId: '123', host: 'collector.gitlab.com', plugins: { errorTracking: false, }, }); glClient.trackError({ message: 'Error occured' }); expect(trackError).not.toHaveBeenCalled(); }); it('should be called when error tracking plugin is enabled and tracking is enabled', () => { asMock(doNotTrackEnabled).mockReturnValue(false); const glClient = glClientSDK({ appId: '123', host: 'collector.gitlab.com', }); glClient.trackError({ message: 'Error occured' }); expect(trackError).toHaveBeenCalledWith({ message: 'Error occured', }); }); }); describe('configuration checks', () => { let spiedWarn: any; beforeAll(() => { asMock(doNotTrackEnabled).mockReturnValue(false); spiedWarn = jest.spyOn(console, 'warn'); spiedWarn.mockImplementation(() => {}); }); afterAll(() => { spiedWarn.mockRestore(); }); afterEach(() => { spiedWarn.mockClear(); }); it('creates console warning if no tracking ID was provided', () => { // @ts-ignore glClientSDK(); expect(spiedWarn).toHaveBeenCalled(); expect(spiedWarn.mock.calls[0][0]).toContain( 'GitLab: No appId was provided' ); }); it('creates console warning if no host was provided', () => { // @ts-ignore glClientSDK({ appId: '123', }); expect(spiedWarn).toHaveBeenCalled(); expect(spiedWarn.mock.calls[0][0]).toContain( 'GitLab: No host was provided' ); }); }); describe('setCustomUrl', () => { it('should call the setCustomUrl method from Snowplow with the provided URL', () => { const customUrl = 'https://example.com'; asMock(doNotTrackEnabled).mockReturnValue(false); const glClient = glClientSDK({ appId: '123', host: 'collector.gitlab.com', }); glClient.setCustomUrl(customUrl); expect(setCustomUrl).toHaveBeenCalledWith(customUrl); }); }); describe('setReferrerUrl', () => { it('should call the setReferrerUrl method from Snowplow with the provided URL', () => { const referrerUrl = 'https://referrer.com'; asMock(doNotTrackEnabled).mockReturnValue(false); const glClient = glClientSDK({ appId: '123', host: 'collector.gitlab.com', }); glClient.setReferrerUrl(referrerUrl); expect(setReferrerUrl).toHaveBeenCalledWith(referrerUrl); }); });