mk9-prebid
Version:
Header Bidding Management Library
303 lines (269 loc) • 8.8 kB
JavaScript
import analyticsAdapter, { ExpiringQueue, getUmtSource, storage } from 'modules/staqAnalyticsAdapter.js';
import { expect } from 'chai';
import adapterManager from 'src/adapterManager.js';
import CONSTANTS from 'src/constants.json';
const events = require('../../../src/events');
const DIRECT = {
source: '(direct)',
medium: '(direct)',
campaign: '(direct)'
};
const REFERRER = {
source: 'lander.com',
medium: '(referral)',
campaign: '(referral)',
content: '/lander.html'
};
const GOOGLE_ORGANIC = {
source: 'google',
medium: '(organic)',
campaign: '(organic)'
};
const CAMPAIGN = {
source: 'adkernel',
medium: 'email',
campaign: 'new_campaign',
c1: '1',
c2: '2',
c3: '3',
c4: '4',
c5: '5'
};
describe('', function() {
let sandbox;
before(function() {
sandbox = sinon.sandbox.create();
});
after(function() {
sandbox.restore();
analyticsAdapter.disableAnalytics();
});
describe('UTM source parser', function() {
let stubSetItem;
let stubGetItem;
before(function() {
stubSetItem = sandbox.stub(storage, 'setItem');
stubGetItem = sandbox.stub(storage, 'getItem');
});
afterEach(function() {
sandbox.reset();
});
it('should parse first direct visit as (direct)', function() {
stubGetItem.withArgs('adk_dpt_analytics').returns(undefined);
stubSetItem.returns(undefined);
let source = getUmtSource('https://example.com');
expect(source).to.be.eql(DIRECT);
});
it('should parse visit from google as organic', function() {
stubGetItem.withArgs('adk_dpt_analytics').returns(undefined);
stubSetItem.returns(undefined);
let source = getUmtSource('https://example.com', 'https://www.google.com/search?q=pikachu');
expect(source).to.be.eql(GOOGLE_ORGANIC);
});
it('should parse referral visit', function() {
stubGetItem.withArgs('adk_dpt_analytics').returns(undefined);
stubSetItem.returns(undefined);
let source = getUmtSource('https://example.com', 'https://lander.com/lander.html');
expect(source).to.be.eql(REFERRER);
});
it('should parse referral visit from same domain as direct', function() {
stubGetItem.withArgs('adk_dpt_analytics').returns(undefined);
stubSetItem.returns(undefined);
let source = getUmtSource('https://lander.com/news.html', 'https://lander.com/lander.html');
expect(source).to.be.eql(DIRECT);
});
it('should parse campaign visit', function() {
stubGetItem.withArgs('adk_dpt_analytics').returns(undefined);
stubSetItem.returns(undefined);
let source = getUmtSource('https://lander.com/index.html?utm_campaign=new_campaign&utm_source=adkernel&utm_medium=email&utm_c1=1&utm_c2=2&utm_c3=3&utm_c4=4&utm_c5=5');
expect(source).to.be.eql(CAMPAIGN);
});
});
describe('ExpiringQueue', function() {
let timer;
before(function() {
timer = sandbox.useFakeTimers(0);
});
after(function() {
timer.restore();
});
it('should notify after timeout period', (done) => {
let queue = new ExpiringQueue(() => {
let elements = queue.popAll();
expect(elements).to.be.eql([1, 2, 3, 4]);
elements = queue.popAll();
expect(elements).to.have.lengthOf(0);
expect(Date.now()).to.be.equal(200);
done();
}, 100);
queue.push(1);
setTimeout(() => {
queue.push([2, 3]);
timer.tick(50);
}, 50);
setTimeout(() => {
queue.push([4]);
timer.tick(100);
}, 100);
timer.tick(50);
});
});
const REQUEST = {
bidderCode: 'AppNexus',
bidderName: 'AppNexus',
auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f',
bidderRequestId: '1a6fc81528d0f6',
bids: [{
bidder: 'AppNexus',
params: {},
adUnitCode: 'container-1',
transactionId: 'de90df62-7fd0-4fbc-8787-92d133a7dc06',
sizes: [
[300, 250]
],
bidId: '208750227436c1',
bidderRequestId: '1a6fc81528d0f6',
auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f'
}],
auctionStart: 1509369418387,
timeout: 3000,
start: 1509369418389
};
const RESPONSE = {
bidderCode: 'AppNexus',
width: 300,
height: 250,
statusMessage: 'Bid available',
adId: '208750227436c1',
mediaType: 'banner',
cpm: 0.015,
ad: '<!-- tag goes here -->',
auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f',
responseTimestamp: 1509369418832,
requestTimestamp: 1509369418389,
bidder: 'AppNexus',
adUnitCode: 'container-1',
timeToRespond: 443,
size: '300x250'
};
const bidTimeoutArgsV1 = [{
bidId: '2baa51527bd015',
bidderCode: 'AppNexus',
adUnitCode: 'container-1',
auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f'
},
{
bidId: '6fe3b4c2c23092',
bidderCode: 'AppNexus',
adUnitCode: 'container-2',
auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f'
}];
describe('Analytics adapter', function() {
let ajaxStub;
let timer;
before(function() {
ajaxStub = sandbox.stub(analyticsAdapter, 'ajaxCall');
timer = sandbox.useFakeTimers(0);
});
beforeEach(function() {
sandbox.stub(events, 'getEvents').callsFake(() => {
return []
});
});
afterEach(function() {
events.getEvents.restore();
});
it('should be configurable', function() {
adapterManager.registerAnalyticsAdapter({
code: 'staq',
adapter: analyticsAdapter
});
adapterManager.enableAnalytics({
provider: 'staq',
options: {
connId: 777,
queueTimeout: 1000,
url: 'https://localhost/prebid'
}
});
expect(analyticsAdapter.context).to.have.property('connectionId', 777);
});
it('should handle auction init event', function() {
events.emit(CONSTANTS.EVENTS.AUCTION_INIT, { config: {}, timeout: 3000 });
const ev = analyticsAdapter.context.queue.peekAll();
expect(ev).to.have.length(1);
expect(ev[0]).to.be.eql({ event: 'auctionInit', auctionId: undefined });
});
it('should handle bid request event', function() {
events.emit(CONSTANTS.EVENTS.BID_REQUESTED, REQUEST);
const ev = analyticsAdapter.context.queue.peekAll();
expect(ev).to.have.length(2);
expect(ev[1]).to.be.eql({
adUnitCode: 'container-1',
auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f',
event: 'bidRequested',
adapter: 'AppNexus',
bidderName: 'AppNexus'
});
});
it('should handle bid response event', function() {
events.emit(CONSTANTS.EVENTS.BID_RESPONSE, RESPONSE);
const ev = analyticsAdapter.context.queue.peekAll();
expect(ev).to.have.length(3);
expect(ev[2]).to.be.eql({
adId: '208750227436c1',
event: 'bidResponse',
adapter: 'AppNexus',
bidderName: 'AppNexus',
auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f',
adUnitCode: 'container-1',
cpm: 0.015,
timeToRespond: 0.443,
height: 250,
width: 300,
bidWon: false,
});
});
it('should handle timeouts properly', function() {
events.emit(CONSTANTS.EVENTS.BID_TIMEOUT, bidTimeoutArgsV1);
const ev = analyticsAdapter.context.queue.peekAll();
expect(ev).to.have.length(5); // remember, we added 2 timeout events
expect(ev[3]).to.be.eql({
adapter: 'AppNexus',
auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f',
bidderName: 'AppNexus',
event: 'adapterTimedOut'
})
});
it('should handle winning bid', function() {
events.emit(CONSTANTS.EVENTS.BID_WON, RESPONSE);
const ev = analyticsAdapter.context.queue.peekAll();
expect(ev).to.have.length(6);
expect(ev[5]).to.be.eql({
auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f',
adId: '208750227436c1',
event: 'bidWon',
adapter: 'AppNexus',
bidderName: 'AppNexus',
adUnitCode: 'container-1',
cpm: 0.015,
height: 250,
width: 300,
bidWon: true,
});
});
it('should handle auction end event', function() {
timer.tick(447);
events.emit(CONSTANTS.EVENTS.AUCTION_END, RESPONSE);
let ev = analyticsAdapter.context.queue.peekAll();
expect(ev).to.have.length(0);
expect(ajaxStub.calledOnce).to.be.equal(true);
let firstCallArgs0 = ajaxStub.firstCall.args[0];
ev = JSON.parse(firstCallArgs0);
const ev6 = ev['events'][6];
expect(ev['connId']).to.be.eql(777);
expect(ev6.auctionId).to.be.eql('5018eb39-f900-4370-b71e-3bb5b48d324f');
expect(ev6.event).to.be.eql('auctionEnd');
});
});
});