UNPKG

@benshi.ai/js-sdk

Version:

Benshi SDK

345 lines (285 loc) 10.2 kB
import BsSender from './BsSender' 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', currencyPath: '/currencyPath', nudgeFetchPath: '/nudgePath', catalogPath: '/catalog', activateNudgeMechanism: true, cacheEventsInLocalstorage: true, cacheEventsKey: 'bslog', debug: true } 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('BsSender', () => { it('Should send one event when flushing explicity', () => { const mockBsNetwork = { send: jest.fn( () => new Promise(r => r([]) )), get: jest.fn() } const notificationSpy = jest.spyOn(mockBsNetwork, 'send') const bsSender = new BsSender(mockBsNetwork, senderOptions) const event = { block: ContentBlock.Core, ol: true, ts: "2022-01-12T07:36:28Z", type: NavigationTypes.App, props: { action: AppAction.Open, start_time : 200 } }; bsSender.add("userId", "deviceId", event) bsSender.flush() // [0][1] -> first call, parameter 1 expect(notificationSpy).toBeCalledWith( expect.anything(), { data: expect.arrayContaining([ expect.objectContaining({ ts: "2022-01-12T07:36:28Z" }) ]), app_info : expect.anything(), d_info : expect.anything(), dn : expect.anything(), up : expect.anything(), sdk : expect.anything(), u_id : expect.anything(), s_id : expect.anything(), } ) }) it('Should send one event when setting forceSend = true', () => { const mockBsNetwork = { send: jest.fn( () => new Promise(r => r([]) )), get: jest.fn() } const notificationSpy = jest.spyOn(mockBsNetwork, 'send') const bsSender = new BsSender(mockBsNetwork, senderOptions) const event = { block: ContentBlock.Core, ol: true, ts: "2022-01-12T07:36:28Z", type: NavigationTypes.App, props: { action: AppAction.Open, start_time : 112 } }; bsSender.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" }) ]), app_info : expect.anything(), d_info : expect.anything(), dn : expect.anything(), up : expect.anything(), sdk : expect.anything(), u_id : expect.anything(), s_id : expect.anything(), } ) }) it('Should NOT send the event immediately when not forced', () => { const mockBsNetwork = { send: jest.fn( () => new Promise(r => r([]) )), get: jest.fn() } const networkSendSpy = jest.spyOn(mockBsNetwork, 'send') const bsSender = new BsSender(mockBsNetwork, senderOptions) const event = { block: ContentBlock.Core, ol: true, ts: "2022-01-12T07:36:28Z", type: NavigationTypes.App, props: { action: AppAction.Open, start_time : 112 } }; bsSender.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 mockBsNetwork = { 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(mockBsNetwork, 'send') const bsSender = new BsSender(mockBsNetwork, senderOptions) const event = { block: ContentBlock.Core, ol: true, ts: "2022-01-12T07:36:28Z", type: NavigationTypes.App, props: { action: AppAction.Open, start_time : 133 } }; bsSender.add("userId", "deviceId", event) await bsSender.flush() await bsSender.flush() await bsSender.flush() await bsSender.flush() await bsSender.flush() await bsSender.flush() await bsSender.flush() await bsSender.flush() expect(notificationSpy).toBeCalledTimes(numberOfRetries + 1) }) it('Should release the queue when flushing explicity', async () => { const mockBsNetwork = { send: jest.fn(() => Promise.resolve()), get: jest.fn() } const notificationSpy = jest.spyOn(mockBsNetwork, 'send') const bsSender = new BsSender(mockBsNetwork, senderOptions) const event = { block: ContentBlock.Core, ol: true, ts: "2022-01-12T07:36:28Z", type: NavigationTypes.App, props: { action: AppAction.Open, start_time : 131 } }; bsSender.add("userId", "deviceId", event) await bsSender.flush() await bsSender.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 mockBsNetwork = { send: jest .fn() .mockRejectedValueOnce(new Error('Async error')) .mockResolvedValueOnce('first call'), get: jest.fn() } const notificationSpy = jest.spyOn(mockBsNetwork, 'send') const bsSender = new BsSender(mockBsNetwork, senderOptions) const event = { block: ContentBlock.Core, ol: true, ts: "2022-01-12T07:36:28Z", type: NavigationTypes.App, props: { action: AppAction.Open, start_time : 131 } }; bsSender.add("userId", "deviceId", event) await bsSender.flush() await bsSender.flush() expect(notificationSpy).lastCalledWith( expect.anything(), { data: expect.arrayContaining([ expect.objectContaining({ ts: "2022-01-12T07:36:28Z" }) ]), app_info : expect.anything(), d_info : expect.anything(), dn : expect.anything(), up : expect.anything(), sdk : expect.anything(), u_id : expect.anything(), s_id : expect.anything(), } ) }) it('Should send all events receive from last flushing explicity - explicit flush', async () => { const mockBsNetwork = { send: jest.fn(() => Promise.resolve()), get: jest.fn() } const notificationSpy = jest.spyOn(mockBsNetwork, 'send') const bsSender = new BsSender(mockBsNetwork, senderOptions) const event1 = { block: ContentBlock.Core, ol: true, ts: "2022-01-12T07:36:28Z", type: NavigationTypes.App, props: { action: AppAction.Open, start_time : 122 } }; const event2 = { block: ContentBlock.Core, ol: true, ts: "2022-01-12T07:36:29Z", type: NavigationTypes.App, props: { action: AppAction.Open, start_time : 122 } }; const event3 = { block: ContentBlock.Core, ol: true, ts: "2022-01-12T07:36:30Z", type: NavigationTypes.App, props: { action: AppAction.Open, start_time : 122 } }; bsSender.add("userId", "deviceId", event1) bsSender.add("userId", "deviceId", event2) bsSender.add("userId", "deviceId", event3) await bsSender.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" }), ]), app_info : expect.anything(), d_info : expect.anything(), dn : expect.anything(), up : expect.anything(), sdk : expect.anything(), u_id : expect.anything(), s_id : expect.anything(), } ) }) })