UNPKG

@causalfoundry/js-sdk

Version:

Causal Foundry WEB SDK (JS/TS)

322 lines (260 loc) 8.94 kB
import CfSender from './CfSender' import { ContentBlock, NavigationTypes } from '../modules/Navigation/typings'; import { AppAction } from '../modules/Navigation/typings'; import {AppInfoObject, DeviceInfoObject, EventMainObject} from "./typings"; jest.useFakeTimers(); jest.spyOn(global, 'setInterval'); const numberOfRetries = 3 const senderOptions = { flushInterval: 10000, flushMaxRetries: numberOfRetries, baseUrl: 'www.base.url', ingestPath: '/ingestPath', allowAnonymousUsers: false, nudgeFetchPath: '/nudgePath', catalogPath: '/catalog', activateNudgeMechanism: true, selfManagedNudges: false, cacheEventsInLocalstorage: true, cacheEventsKey: 'cfLog', debug: true, pauseSDK: false } const deviceObject: DeviceInfoObject = { id: 'device_id', brand: "testBrand", model: "testBrand", os: 'linux', os_ver: 'linux', } const appObject: AppInfoObject = { id: "websiteURL", min_sdk_version: 21, target_sdk_version: 31, version: "1.0.3 (3)", version_code: 3, version_name: "1.0.3", } describe('CfSender', () => { it('Should send one event when flushing explicity', () => { const mockCfNetwork = { send: jest.fn( () => new Promise(r => r([]) )), get: jest.fn() } const notificationSpy = jest.spyOn(mockCfNetwork, 'send') const cfSender = new CfSender(mockCfNetwork, senderOptions) const event = { ol: true, ts: "2022-01-12T07:36:28Z", type: NavigationTypes.App, ctx: { action: AppAction.Open, start_time : 200 } }; cfSender.add("userId", "deviceId", event) cfSender.flush() // [0][1] -> first call, parameter 1 expect(notificationSpy).toBeCalledWith( expect.anything(), {data: expect.arrayContaining([ expect.objectContaining({ ts: "2022-01-12T07:36:28Z" }) ]) } ) }) it('Should send one event when setting forceSend = true', () => { const mockCfNetwork = { send: jest.fn( () => new Promise(r => r([]) )), get: jest.fn() } const notificationSpy = jest.spyOn(mockCfNetwork, 'send') const cfSender = new CfSender(mockCfNetwork, senderOptions) const event = { ol: true, ts: "2022-01-12T07:36:28Z", type: NavigationTypes.App, ctx: { action: AppAction.Open, start_time : 200 } }; cfSender.add("userId", "deviceId", event, true) // [0][1] -> first call, parameter 1 expect(notificationSpy).toBeCalledWith( expect.anything(), {data: expect.arrayContaining([ expect.objectContaining({ ts: "2022-01-12T07:36:28Z" }) ]) } ) }) it('Should NOT send the event immediately when not forced', () => { const mockCfNetwork = { send: jest.fn( () => new Promise(r => r([]) )), get: jest.fn() } const networkSendSpy = jest.spyOn(mockCfNetwork, 'send') const cfSender = new CfSender(mockCfNetwork, senderOptions) const event = { ol: true, ts: "2022-01-12T07:36:28Z", type: NavigationTypes.App, ctx: { action: AppAction.Open, start_time : 112 } }; cfSender.add("userId", "deviceId", event, false) // [0][1] -> first call, parameter 1 expect(networkSendSpy).toBeCalledTimes(0) }) it('Should not sent the event after reaching the maximum number of retries', async() => { const mockCfNetwork = { send: jest .fn() .mockRejectedValueOnce(new Error('Async error')) .mockRejectedValueOnce(new Error('Async error')) .mockRejectedValueOnce(new Error('Async error')) .mockResolvedValueOnce('first call'), get: jest.fn() } const notificationSpy = jest.spyOn(mockCfNetwork, 'send') const cfSender = new CfSender(mockCfNetwork, senderOptions) const event = { ol: true, ts: "2022-01-12T07:36:28Z", type: NavigationTypes.App, ctx: { action: AppAction.Open, start_time : 133 } }; cfSender.add("userId", "deviceId", event) await cfSender.flush() await cfSender.flush() await cfSender.flush() await cfSender.flush() await cfSender.flush() await cfSender.flush() await cfSender.flush() expect(notificationSpy).toBeCalledTimes(numberOfRetries + 1) }) it('Should release the queue when flushing explicity', async () => { const mockCfNetwork = { send: jest.fn(() => Promise.resolve()), get: jest.fn() } const notificationSpy = jest.spyOn(mockCfNetwork, 'send') const cfSender = new CfSender(mockCfNetwork, senderOptions) const event = { ol: true, ts: "2022-01-12T07:36:28Z", type: NavigationTypes.App, ctx: { action: AppAction.Open, start_time : 131 } }; const eventMainObject: EventMainObject = { s_id: 'userId_0_0', u_id: 'u_id', app_info: appObject, d_info: deviceObject, sdk: `jsXCF/`, up: 90, dn: 100, data: [event] } cfSender.add("userId", "deviceId", event) await cfSender.flush() await cfSender.flush() // first "flush" will call it, but second one not, because the list // is already empty expect(notificationSpy).toHaveBeenCalledTimes(1) }) it('Should enqueue event when there is a network error', async () => { const mockCfNetwork = { send: jest .fn() .mockRejectedValueOnce(new Error('Async error')) .mockResolvedValueOnce('first call'), get: jest.fn() } const notificationSpy = jest.spyOn(mockCfNetwork, 'send') const cfSender = new CfSender(mockCfNetwork, senderOptions) const event = { ol: true, ts: "2022-01-12T07:36:28Z", type: NavigationTypes.App, ctx: { action: AppAction.Open, start_time : 131 } }; const eventMainObject: EventMainObject = { s_id: 'userId_0_0', u_id: 'u_id', app_info: appObject, d_info: deviceObject, sdk: `jsXCF/`, up: 90, dn: 100, data: [event] } cfSender.add("userId", "deviceId", event) await cfSender.flush() await cfSender.flush() expect(notificationSpy).lastCalledWith( expect.anything(), { data: expect.arrayContaining([ expect.objectContaining({ ts: "2022-01-12T07:36:28Z" }) ]) } ) }) it('Should send all events receive from last flushing explicity - explicit flush', async () => { const mockCfNetwork = { send: jest.fn(() => Promise.resolve()), get: jest.fn() } const notificationSpy = jest.spyOn(mockCfNetwork, 'send') const cfSender = new CfSender(mockCfNetwork, senderOptions) const event = { ol: true, ts: "2022-01-12T07:36:28Z", type: NavigationTypes.App, ctx: { action: AppAction.Open, start_time : 122 } }; const eventMainObject: EventMainObject = { s_id: 'userId_0_0', u_id: 'u_id', app_info: appObject, d_info: deviceObject, sdk: `jsXCF/`, up: 90, dn: 100, data: [event] } cfSender.add("userId", "deviceId", event) cfSender.add("userId", "deviceId", event) cfSender.add("userId", "deviceId", event) await cfSender.flush() expect(notificationSpy).toHaveBeenCalledWith( expect.anything(), { data: expect.arrayContaining([ expect.objectContaining({ ts: "2022-01-12T07:36:28Z" }), expect.objectContaining({ ts: "2022-01-12T07:36:29Z" }), expect.objectContaining({ ts: "2022-01-12T07:36:30Z" }), ]) } ) }) })