Skip to content

Commit

Permalink
Automatad Analytics Adapter : expose queue as a global object (prebid…
Browse files Browse the repository at this point in the history
…#11203)

* fix: added fix for automatadAnalytics

* fix: add s3 upload for atmtd

* fix: add upload to s3

* fix: removed changes to gulp file and package.json

* fix: added build command to gulp

* fix: removed extra line from gulpfile

* restored original gulp file

* fix: minor fix to condition

* fix: removed unnecessary condition

* fix: removed linting error

* Get build check to re run

---------

Co-authored-by: Shashank <=>
  • Loading branch information
shashankatd authored Mar 13, 2024
1 parent c9faa28 commit b68759d
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 37 deletions.
53 changes: 31 additions & 22 deletions modules/automatadAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { config } from '../src/config.js'
const ADAPTER_CODE = 'automatadAnalytics'
const trialCountMilsMapping = [1500, 3000, 5000, 10000];

var isLoggingEnabled; var queuePointer = 0; var retryCount = 0; var timer = null; var __atmtdAnalyticsQueue = [];
var isLoggingEnabled; var queuePointer = 0; var retryCount = 0; var timer = null; var __atmtdAnalyticsQueue = []; var qBeingUsed; var qTraversalComplete;

const prettyLog = (level, text, isGroup = false, cb = () => {}) => {
if (self.isLoggingEnabled === undefined) {
Expand Down Expand Up @@ -134,6 +134,9 @@ const processEvents = () => {
if (trialCountMilsMapping[self.retryCount]) self.prettyLog('warn', `Adapter failed to process event as aggregator has not loaded. Retrying in ${trialCountMilsMapping[self.retryCount]}ms ...`);
setTimeout(self.processEvents, trialCountMilsMapping[self.retryCount])
self.retryCount = self.retryCount + 1
} else {
self.qBeingUsed = false
self.qTraversalComplete = true
}
}

Expand All @@ -142,22 +145,18 @@ const addGPTHandlers = () => {
googletag.cmd = googletag.cmd || []
googletag.cmd.push(() => {
googletag.pubads().addEventListener('slotRenderEnded', (event) => {
if (window.atmtdAnalytics && window.atmtdAnalytics.slotRenderEndedGPTHandler) {
if (window.__atmtdAggregatorFirstAuctionInitialized === true) {
window.atmtdAnalytics.slotRenderEndedGPTHandler(event)
return;
}
if (window.atmtdAnalytics && window.atmtdAnalytics.slotRenderEndedGPTHandler && !self.qBeingUsed) {
window.atmtdAnalytics.slotRenderEndedGPTHandler(event)
return;
}
self.__atmtdAnalyticsQueue.push(['slotRenderEnded', event])
self.prettyLog(`warn`, `Aggregator not initialised at auctionInit, exiting slotRenderEnded handler and pushing to que instead`)
})

googletag.pubads().addEventListener('impressionViewable', (event) => {
if (window.atmtdAnalytics && window.atmtdAnalytics.impressionViewableHandler) {
if (window.__atmtdAggregatorFirstAuctionInitialized === true) {
window.atmtdAnalytics.impressionViewableHandler(event)
return;
}
if (window.atmtdAnalytics && window.atmtdAnalytics.impressionViewableHandler && !self.qBeingUsed) {
window.atmtdAnalytics.impressionViewableHandler(event)
return;
}
self.__atmtdAnalyticsQueue.push(['impressionViewable', event])
self.prettyLog(`warn`, `Aggregator not initialised at auctionInit, exiting impressionViewable handler and pushing to que instead`)
Expand All @@ -167,6 +166,7 @@ const addGPTHandlers = () => {

const initializeQueue = () => {
self.__atmtdAnalyticsQueue.push = (args) => {
self.qBeingUsed = true
Array.prototype.push.apply(self.__atmtdAnalyticsQueue, [args]);
if (timer) {
clearTimeout(timer);
Expand Down Expand Up @@ -196,9 +196,10 @@ let atmtdAdapter = Object.assign({}, baseAdapter, {
},

track({eventType, args}) {
const shouldNotPushToQueue = !self.qBeingUsed
switch (eventType) {
case CONSTANTS.EVENTS.AUCTION_INIT:
if (window.atmtdAnalytics && window.atmtdAnalytics.auctionInitHandler) {
if (window.atmtdAnalytics && window.atmtdAnalytics.auctionInitHandler && shouldNotPushToQueue) {
self.prettyLog('status', 'Aggregator loaded, initialising auction through handlers');
window.atmtdAnalytics.auctionInitHandler(args);
} else {
Expand All @@ -207,63 +208,63 @@ let atmtdAdapter = Object.assign({}, baseAdapter, {
}
break;
case CONSTANTS.EVENTS.BID_REQUESTED:
if (window.atmtdAnalytics && window.atmtdAnalytics.bidRequestedHandler) {
if (window.atmtdAnalytics && window.atmtdAnalytics.bidRequestedHandler && shouldNotPushToQueue) {
window.atmtdAnalytics.bidRequestedHandler(args);
} else {
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
self.__atmtdAnalyticsQueue.push([eventType, args])
}
break;
case CONSTANTS.EVENTS.BID_REJECTED:
if (window.atmtdAnalytics && window.atmtdAnalytics.bidRejectedHandler) {
if (window.atmtdAnalytics && window.atmtdAnalytics.bidRejectedHandler && shouldNotPushToQueue) {
window.atmtdAnalytics.bidRejectedHandler(args);
} else {
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
self.__atmtdAnalyticsQueue.push([eventType, args])
}
break;
case CONSTANTS.EVENTS.BID_RESPONSE:
if (window.atmtdAnalytics && window.atmtdAnalytics.bidResponseHandler) {
if (window.atmtdAnalytics && window.atmtdAnalytics.bidResponseHandler && shouldNotPushToQueue) {
window.atmtdAnalytics.bidResponseHandler(args);
} else {
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
self.__atmtdAnalyticsQueue.push([eventType, args])
}
break;
case CONSTANTS.EVENTS.BIDDER_DONE:
if (window.atmtdAnalytics && window.atmtdAnalytics.bidderDoneHandler) {
if (window.atmtdAnalytics && window.atmtdAnalytics.bidderDoneHandler && shouldNotPushToQueue) {
window.atmtdAnalytics.bidderDoneHandler(args);
} else {
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
self.__atmtdAnalyticsQueue.push([eventType, args])
}
break;
case CONSTANTS.EVENTS.BID_WON:
if (window.atmtdAnalytics && window.atmtdAnalytics.bidWonHandler) {
if (window.atmtdAnalytics && window.atmtdAnalytics.bidWonHandler && shouldNotPushToQueue) {
window.atmtdAnalytics.bidWonHandler(args);
} else {
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
self.__atmtdAnalyticsQueue.push([eventType, args])
}
break;
case CONSTANTS.EVENTS.NO_BID:
if (window.atmtdAnalytics && window.atmtdAnalytics.noBidHandler) {
if (window.atmtdAnalytics && window.atmtdAnalytics.noBidHandler && shouldNotPushToQueue) {
window.atmtdAnalytics.noBidHandler(args);
} else {
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
self.__atmtdAnalyticsQueue.push([eventType, args])
}
break;
case CONSTANTS.EVENTS.AUCTION_DEBUG:
if (window.atmtdAnalytics && window.atmtdAnalytics.auctionDebugHandler) {
if (window.atmtdAnalytics && window.atmtdAnalytics.auctionDebugHandler && shouldNotPushToQueue) {
window.atmtdAnalytics.auctionDebugHandler(args);
} else {
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
self.__atmtdAnalyticsQueue.push([eventType, args])
}
break;
case CONSTANTS.EVENTS.BID_TIMEOUT:
if (window.atmtdAnalytics && window.atmtdAnalytics.bidderTimeoutHandler) {
if (window.atmtdAnalytics && window.atmtdAnalytics.bidderTimeoutHandler && shouldNotPushToQueue) {
window.atmtdAnalytics.bidderTimeoutHandler(args);
} else {
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
Expand Down Expand Up @@ -304,7 +305,7 @@ atmtdAdapter.enableAnalytics = function (configuration) {
atmtdAdapter.originEnableAnalytics(configuration)
};

/// /////////// ADAPTER REGISTRATION //////////////
/// /////////// ADAPTER REGISTRATION /////////////

adapterManager.registerAnalyticsAdapter({
adapter: atmtdAdapter,
Expand All @@ -319,7 +320,15 @@ export var self = {
prettyLog,
queuePointer,
retryCount,
isLoggingEnabled
isLoggingEnabled,
qBeingUsed,
qTraversalComplete
}

window.__atmtdAnalyticsGlobalObject = {
q: self.__atmtdAnalyticsQueue,
qBeingUsed: self.qBeingUsed,
qTraversalComplete: self.qTraversalComplete
}

export default atmtdAdapter;
117 changes: 102 additions & 15 deletions test/spec/modules/automatadAnalyticsAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ import spec, {self as exports} from 'modules/automatadAnalyticsAdapter.js';
import CONSTANTS from 'src/constants.json';
import { expect } from 'chai';

const obj = {
auctionInitHandler: (args) => {},
bidResponseHandler: (args) => {},
bidderDoneHandler: (args) => {},
bidWonHandler: (args) => {},
noBidHandler: (args) => {},
auctionDebugHandler: (args) => {},
bidderTimeoutHandler: (args) => {},
bidRequestedHandler: (args) => {},
bidRejectedHandler: (args) => {}
}

const {
AUCTION_DEBUG,
BID_REQUESTED,
Expand Down Expand Up @@ -117,20 +129,10 @@ describe('Automatad Analytics Adapter', () => {
describe('Behaviour of the adapter when the sdk has loaded', () => {
before(() => {
spec.enableAnalytics(CONFIG_WITH_DEBUG);
const obj = {
auctionInitHandler: (args) => {},
bidResponseHandler: (args) => {},
bidderDoneHandler: (args) => {},
bidWonHandler: (args) => {},
noBidHandler: (args) => {},
auctionDebugHandler: (args) => {},
bidderTimeoutHandler: (args) => {},
bidRequestedHandler: (args) => {},
bidRejectedHandler: (args) => {}
}

global.window.atmtdAnalytics = obj

exports.qBeingUsed = false
exports.qTraversalComplete = undefined
Object.keys(obj).forEach((fn) => sandbox.spy(global.window.atmtdAnalytics, fn))
})
beforeEach(() => {
Expand All @@ -143,8 +145,12 @@ describe('Automatad Analytics Adapter', () => {
sandbox.restore();
});
after(() => {
const handlers = global.window.atmtdAnalytics
Object.keys(handlers).forEach((handler) => global.window.atmtdAnalytics[handler].reset())
global.window.atmtdAnalytics = undefined;
spec.disableAnalytics();
exports.qBeingUsed = false
exports.qTraversalComplete = undefined
})

it('Should call the auctionInitHandler when the auction init event is fired', () => {
Expand Down Expand Up @@ -298,6 +304,85 @@ describe('Automatad Analytics Adapter', () => {
});
});

describe('Behaviour of the adapter when the SDK has loaded midway', () => {
before(() => {
spec.enableAnalytics(CONFIG_WITH_DEBUG);
})
beforeEach(() => {
sandbox = sinon.createSandbox();

global.window.atmtdAnalytics = undefined

exports.qBeingUsed = undefined
exports.qTraversalComplete = undefined
exports.queuePointer = 0
exports.retryCount = 0
exports.__atmtdAnalyticsQueue.length = 0

clock = sandbox.useFakeTimers();

sandbox.spy(exports.__atmtdAnalyticsQueue, 'push')
});
afterEach(() => {
sandbox.restore();
});
after(() => {
spec.disableAnalytics();
})

it('Should push to the que when the auctionInit event is fired and push to the que even after SDK has loaded after auctionInit event', () => {
events.emit(BID_RESPONSE, {type: BID_RESPONSE})
expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true)
expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(1)
expect(exports.__atmtdAnalyticsQueue[0]).to.have.lengthOf(2)
expect(exports.__atmtdAnalyticsQueue[0][0]).to.equal(BID_RESPONSE)
expect(exports.__atmtdAnalyticsQueue[0][1].type).to.equal(BID_RESPONSE)
expect(exports.qBeingUsed).to.equal(true)
expect(exports.qTraversalComplete).to.equal(undefined)
global.window.atmtdAnalytics = obj
events.emit(BID_RESPONSE, {type: BID_RESPONSE})
expect(exports.__atmtdAnalyticsQueue.push.calledTwice).to.equal(true)
expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(2)
expect(exports.__atmtdAnalyticsQueue[1]).to.have.lengthOf(2)
expect(exports.__atmtdAnalyticsQueue[1][0]).to.equal(BID_RESPONSE)
expect(exports.__atmtdAnalyticsQueue[1][1].type).to.equal(BID_RESPONSE)
expect(exports.qBeingUsed).to.equal(true)
expect(exports.qTraversalComplete).to.equal(undefined)
});

it('Should push to the que when the auctionInit event is fired and push to the analytics adapter handler after the que is processed', () => {
expect(exports.qBeingUsed).to.equal(undefined)
events.emit(AUCTION_INIT, {type: AUCTION_INIT})
global.window.atmtdAnalytics = {...obj}
const handlers = global.window.atmtdAnalytics
Object.keys(handlers).forEach((handler) => global.window.atmtdAnalytics[handler].reset())
expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true)
expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(1)
expect(exports.__atmtdAnalyticsQueue[0]).to.have.lengthOf(2)
expect(exports.__atmtdAnalyticsQueue[0][0]).to.equal(AUCTION_INIT)
expect(exports.__atmtdAnalyticsQueue[0][1].type).to.equal(AUCTION_INIT)
expect(exports.qBeingUsed).to.equal(true)
expect(exports.qTraversalComplete).to.equal(undefined)
expect(global.window.atmtdAnalytics.auctionInitHandler.callCount).to.equal(0)
clock.tick(2000)
expect(exports.qBeingUsed).to.equal(true)
expect(exports.qTraversalComplete).to.equal(undefined)
events.emit(NO_BID, {type: NO_BID})
expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(2)
expect(exports.__atmtdAnalyticsQueue.push.calledTwice).to.equal(true)
clock.tick(1500)
expect(exports.qBeingUsed).to.equal(false)
expect(exports.qTraversalComplete).to.equal(true)
events.emit(BID_RESPONSE, {type: BID_RESPONSE})
expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(2)
expect(exports.__atmtdAnalyticsQueue.push.calledTwice).to.equal(true)
expect(exports.__atmtdAnalyticsQueue.push.calledThrice).to.equal(false)
expect(global.window.atmtdAnalytics.auctionInitHandler.calledOnce).to.equal(true)
expect(global.window.atmtdAnalytics.noBidHandler.calledOnce).to.equal(true)
expect(global.window.atmtdAnalytics.bidResponseHandler.calledOnce).to.equal(true)
});
});

describe('Process Events from Que when SDK still has not loaded', () => {
before(() => {
spec.enableAnalytics({
Expand All @@ -312,6 +397,8 @@ describe('Automatad Analytics Adapter', () => {
sandbox.stub(exports.__atmtdAnalyticsQueue, 'push').callsFake((args) => {
Array.prototype.push.apply(exports.__atmtdAnalyticsQueue, [args]);
})
exports.queuePointer = 0;
exports.retryCount = 0;
})
beforeEach(() => {
sandbox = sinon.createSandbox();
Expand All @@ -326,7 +413,6 @@ describe('Automatad Analytics Adapter', () => {
sandbox.restore();
exports.queuePointer = 0;
exports.retryCount = 0;
exports.__atmtdAnalyticsQueue = []
spec.disableAnalytics();
})

Expand Down Expand Up @@ -437,7 +523,6 @@ describe('Automatad Analytics Adapter', () => {
}
});
sandbox = sinon.createSandbox();
sandbox.reset()
const obj = {
auctionInitHandler: (args) => {},
bidResponseHandler: (args) => {},
Expand Down Expand Up @@ -473,8 +558,10 @@ describe('Automatad Analytics Adapter', () => {
['impressionViewable', {type: 'impressionViewable'}]
]
});
after(() => {
afterEach(() => {
sandbox.restore();
})
after(() => {
spec.disableAnalytics();
})

Expand Down

0 comments on commit b68759d

Please sign in to comment.