@benshi.ai/js-sdk
Version:
Benshi SDK
426 lines (335 loc) • 13.1 kB
text/typescript
/**
* @jest-environment jsdom
*/
import ViewableImpressionManager from "./ViewableImpressionEngine"
import { ImpressionEventType } from "./typings"
// time, in millis, to be sure that the "expect" is not called at the same time than the timeout
const delta = 100
describe('ViewableImpressionManager', () => {
it('Should trigger an impression event when a item has been detected - just one time', async () => {
let mockObserver = {
on: jest.fn(),
}
let hideCallback, showCallback;
let impressionCallback = jest.fn()
mockObserver.on.mockImplementation((event, cb) => {
if (event === 'hide') {
hideCallback = cb
} else {
showCallback = cb
}
})
const config = {
triggerInterval: 200,
keepVisibleTimeout: 100
}
const impressionManager = new ViewableImpressionManager(mockObserver as any, config)
impressionManager.on(ImpressionEventType.Impression, impressionCallback)
const itemDrugProps = {
market_id: 'ID',
name: '',
description: '',
supplier_id: `supplier-90`,
supplier_name: `name-of-the-supplier`,
producer: '',
packaging: '',
active_ingredients: ['paracetamol', '(-)-Naringenina'],
drug_form: '',
drug_strength: `${Math.floor(Math.random() * 10)}`,
atc_anatomical_group: '',
otc_or_ethical: ''
}
const eventData = {
id: '12',
currency: 'EUR',
price: 100,
quantity: 2,
stock_status: 'in_stock',
promo_id: 'testPromoId',
drug_catalog_object: JSON.stringify(itemDrugProps)
}
// emulates the ImpressionObserver
showCallback('12', eventData)
// timeout to wait for the triggerInterval
await new Promise((r) => setTimeout(r, config.triggerInterval + delta));
expect(impressionCallback).toBeCalledTimes(1)
expect(impressionCallback).toBeCalledWith({ dataset: eventData, appData: {} })
})
it('Should not trigger an impression event when a item has been detected and removed before one second', async () => {
let mockObserver = {
on: jest.fn(),
}
let hideCallback, showCallback;
let impressionCallback = jest.fn()
mockObserver.on.mockImplementation((event, cb) => {
if (event === 'hide') {
hideCallback = cb
} else {
showCallback = cb
}
})
const config = {
triggerInterval: 200,
keepVisibleTimeout: 100
}
const impressionManager = new ViewableImpressionManager(mockObserver as any, config)
impressionManager.on(ImpressionEventType.Impression, impressionCallback)
const itemDrugProps = {
market_id: 'ID',
name: '',
description: '',
supplier_id: `supplier-90`,
supplier_name: `name-of-the-supplier`,
producer: '',
packaging: '',
active_ingredients: ['paracetamol', '(-)-Naringenina'],
drug_form: '',
drug_strength: `${Math.floor(Math.random() * 10)}`,
atc_anatomical_group: '',
otc_or_ethical: ''
}
const eventData = {
dataset: {
id: '12',
currency: 'EUR',
price: 100,
quantity: 2,
stock_status: 'in_stock',
promo_id: 'testPromoId',
drug_catalog_object: JSON.stringify(itemDrugProps)
},
appData: {}
}
// emulates the ImpressionObserver
showCallback('12', eventData)
hideCallback('12')
await new Promise((r) => setTimeout(r, config.triggerInterval + 100)); // wait to be sure than the interval check has been fired
expect(impressionCallback).toBeCalledTimes(0)
})
it('Should trigger an impression event with only one item even it appears several times', async () => {
let mockObserver = {
on: jest.fn(),
}
let hideCallback, showCallback;
let impressionCallback = jest.fn()
mockObserver.on.mockImplementation((event, cb) => {
if (event === 'hide') {
hideCallback = cb
} else {
showCallback = cb
}
})
const config = {
triggerInterval: 200,
keepVisibleTimeout: 100
}
const impressionManager = new ViewableImpressionManager(mockObserver as any, config)
impressionManager.on(ImpressionEventType.Impression, impressionCallback)
const itemDrugProps = {
market_id: 'ID',
name: '',
description: '',
supplier_id: `supplier-90`,
supplier_name: `name-of-the-supplier`,
producer: '',
packaging: '',
active_ingredients: ['paracetamol', '(-)-Naringenina'],
drug_form: '',
drug_strength: `${Math.floor(Math.random() * 10)}`,
atc_anatomical_group: '',
otc_or_ethical: ''
}
const eventData = {
id: '12',
currency: 'EUR',
price: 100,
quantity: 2,
stock_status: 'in_stock',
promo_id: 'testPromoId',
drug_catalog_object: JSON.stringify(itemDrugProps)
}
// emulates the ImpressionObserver
showCallback('12', eventData)
await new Promise((r) => setTimeout(r, config.keepVisibleTimeout + delta));
hideCallback('12')
showCallback('12', eventData)
await new Promise((r) => setTimeout(r, config.keepVisibleTimeout + delta));
expect(impressionCallback).toBeCalledTimes(1)
expect(impressionCallback).toBeCalledWith({ dataset: eventData, appData: {} })
}, 10000)
it('Should trigger an impression event when it has been removed from screen but the checking interval not fired yet', async () => {
let mockObserver = {
on: jest.fn(),
}
let hideCallback, showCallback;
let impressionCallback = jest.fn()
mockObserver.on.mockImplementation((event, cb) => {
if (event === 'hide') {
hideCallback = cb
} else {
showCallback = cb
}
})
const config = {
triggerInterval: 2000,
keepVisibleTimeout: 100
}
const impressionManager = new ViewableImpressionManager(mockObserver as any, config)
impressionManager.on(ImpressionEventType.Impression, impressionCallback)
const eventData = {
id: '12',
currency: 'EUR',
price: 100,
quantity: 2,
stock_status: 'in_stock',
promo_id: 'testPromoId'
}
// emulates the ImpressionObserver
showCallback('12', eventData)
await new Promise((r) => setTimeout(r, config.keepVisibleTimeout + delta)); // a bit more than a second, which is the time to consider it as impression
hideCallback('12')
expect(impressionCallback).toBeCalledTimes(1)
expect(impressionCallback).toBeCalledWith({ dataset: eventData, appData: {} })
}, 10000)
it('Should trigger again same IDs after restarting', async () => {
let mockObserver = {
on: jest.fn(),
start: jest.fn(),
stop: jest.fn()
}
let hideCallback, showCallback;
let impressionCallback = jest.fn()
mockObserver.on.mockImplementation((event, cb) => {
if (event === 'hide') {
hideCallback = cb
} else {
showCallback = cb
}
})
const config = {
triggerInterval: 200,
keepVisibleTimeout: 100
}
const impressionManager = new ViewableImpressionManager(mockObserver as any, config)
impressionManager.on(ImpressionEventType.Impression, impressionCallback)
impressionManager.start('aaa', 'bb', 'searchId-1')
const eventData = {
id: '12',
currency: 'EUR',
price: 100,
quantity: 2,
stock_status: 'in_stock',
promo_id: 'testPromoId'
}
// emulates the ImpressionObserver
showCallback('12', eventData)
await new Promise((r) => setTimeout(r, config.keepVisibleTimeout + delta));
impressionManager.restart('searchId-2')
showCallback('12', { dataset: eventData, appData: {} })
await new Promise((r) => setTimeout(r, config.triggerInterval + delta));
expect(impressionCallback).toBeCalledTimes(2)
})
it('Should trigger pending events when stopping', async () => {
let mockObserver = {
on: jest.fn(),
stop: () => { }
}
let hideCallback, showCallback;
let impressionCallback = jest.fn()
mockObserver.on.mockImplementation((event, cb) => {
if (event === 'hide') {
hideCallback = cb
} else {
showCallback = cb
}
})
const config = {
triggerInterval: 2000, // big trigger interval to make sure that the stop function is called before timeout
keepVisibleTimeout: 100
}
const impressionManager = new ViewableImpressionManager(mockObserver as any, config)
impressionManager.on(ImpressionEventType.Impression, impressionCallback)
const eventData = {
id: '12',
currency: 'EUR',
price: 100,
quantity: 2,
stock_status: 'in_stock',
promo_id: 'testPromoId'
}
// emulates the ImpressionObserver
showCallback('12', eventData)
await new Promise((r) => setTimeout(r, config.keepVisibleTimeout + delta)); // a bit more than a second, which is the time to consider it as impression
impressionManager.stop()
expect(impressionCallback).toBeCalledTimes(1)
expect(impressionCallback).toBeCalledWith({ dataset: eventData, appData: {} })
})
it('Should not trigger pending events when stopping if they have not been enough time in screen', async () => {
let mockObserver = {
on: jest.fn(),
stop: () => { }
}
let hideCallback, showCallback;
let impressionCallback = jest.fn()
mockObserver.on.mockImplementation((event, cb) => {
if (event === 'hide') {
hideCallback = cb
} else {
showCallback = cb
}
})
const config = {
triggerInterval: 2000, // big trigger interval to make sure that the stop function is called before timeout
keepVisibleTimeout: 100
}
const impressionManager = new ViewableImpressionManager(mockObserver as any, config)
impressionManager.on(ImpressionEventType.Impression, impressionCallback)
const eventData = {
id: '12',
currency: 'EUR',
price: 100,
quantity: 2,
stock_status: 'in_stock',
promo_id: 'testPromoId'
}
// emulates the ImpressionObserver
showCallback('12', eventData)
impressionManager.stop()
expect(impressionCallback).toBeCalledTimes(0)
})
it('Should trigger an impression event when a item is detected without drug properties', async () => {
let mockObserver = {
on: jest.fn(),
}
let hideCallback, showCallback;
let impressionCallback = jest.fn()
mockObserver.on.mockImplementation((event, cb) => {
if (event === 'hide') {
hideCallback = cb
} else {
showCallback = cb
}
})
const config = {
triggerInterval: 200,
keepVisibleTimeout: 100
}
const impressionManager = new ViewableImpressionManager(mockObserver as any, config)
impressionManager.on(ImpressionEventType.Impression, impressionCallback)
const eventData = {
id: '12',
currency: 'EUR',
price: 100,
quantity: 2,
stock_status: 'in_stock',
promo_id: 'testPromoId',
drug_catalog_object: {}
}
// emulates the ImpressionObserver
showCallback('12', eventData)
// timeout to wait for the triggerInterval
await new Promise((r) => setTimeout(r, config.triggerInterval + delta));
expect(impressionCallback).toBeCalledTimes(1)
expect(impressionCallback).toBeCalledWith({dataset: eventData, appData: {}})
})
})