Skip to content
This repository has been archived by the owner on Feb 13, 2021. It is now read-only.

Commit

Permalink
Merge pull request prebid#38 in AOLP_ADS_JS/prebid.js from feature/PL…
Browse files Browse the repository at this point in the history
…MP-73-unit-tests-false-timed-out-bids to release/1.4.1

* commit '8dabc4fbee8f523e08262b17b791b8f8b0ac1e55':
  Updated CHANGELOG
  Refactoring of unit tests for AOL analytics #2
  Minor refactoring of unit tests for AOL analytics
  Added more unit tests for AOL analytics
  Added unit tests for AOL analytics
  Refactoring of AOL analytics
  • Loading branch information
marian-r committed Oct 24, 2016
2 parents 5e7eec4 + 8dabc4f commit af5c813
Show file tree
Hide file tree
Showing 4 changed files with 1,353 additions and 559 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
AOL Prebid 1.4.1
----------------
Refactoring of AOL analytics.
Fixed reporting of pageId parameter in AOL analytics.


AOL Prebid 1.4.0
----------------
Updated to Prebid 0.13.1
Expand Down
362 changes: 183 additions & 179 deletions src/adapters/analytics/aol.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,201 +28,205 @@ const EVENTS = {
WIN: 2
};

let adUnits = {};

let baseSchemaTemplate = template`${'protocol'}://${'host'}/hbevent/${'tagversion'}/${'network'}/${'placement'}/${'site'}/${'eventid'}/hbeventts=${'hbeventts'};cors=yes`;
let auctionSchemaTemplate = template`;pubadid=${'pubadid'};hbauctionid=${'hbauctionid'};hbwinner=${'hbwinner'};hbprice=${'hbprice'}${'hbcur'}${'pubapi'}`;
let winSchemaTemplate = template`;hbauctioneventts=${'hbauctioneventts'};pubadid=${'pubadid'};hbauctionid=${'hbauctionid'};hbwinner=${'hbwinner'};pubcpm=${'pubcpm'}`;
let bidderSchemaTemplate = template`;hbbidder=${'hbbidder'};hbbid=${'hbbid'};hbstatus=${'hbstatus'};hbtime=${'hbtime'}`;

export default utils.extend(adapter({
url: '',
analyticsType
}), {
url: '',
analyticsType
}), {

enableAnalytics({
options = {
server: null // Internal use only. Use 'region' config option for AOL adapter.
enableAnalytics({
options = {
server: null // Internal use only. Use 'region' config option for AOL adapter.
}
}) {
this.server = options ? options.server : null;
this.adUnits = {};

//first send all events fired before enableAnalytics called
events.getEvents().forEach(event => {
if (!event) {
return;
}
}) {
this.server = options ? options.server : null;

//first send all events fired before enableAnalytics called
events.getEvents().forEach(event => {
if (!event) {
return;
}
this.enqueue(event);
});

events.on(AUCTION_END, args => this.enqueue({ eventType: AUCTION_END, args }));
events.on(BID_WON, args => this.enqueue({ eventType: BID_WON, args }));

this.enableAnalytics = function _enable() {
return utils.logMessage(
`AOL analytics adapter already enabled, unnecessary call to 'enableAnalytics()'.`
);
};
},

//override AnalyticsAdapter functions by supplying custom methods
track({ eventType, args }) {
switch (eventType) {
case AUCTION_END:
let adUnitsConf = $$PREBID_GLOBAL$$.adUnits;
let bidsReceived = $$PREBID_GLOBAL$$._bidsReceived;
let bidsRequested = $$PREBID_GLOBAL$$._bidsRequested;

let bidsReceivedPerBidderPerAdUnit = bidsReceived
.reduce((bidsReceivedPerBidderPerAdUnit, bid) => {
let bidsPerBidder = bidsReceivedPerBidderPerAdUnit[bid.bidder] || {};
let bidsPerBidderPerAdUnit = bidsPerBidder[bid.adUnitCode] || [];
bidsPerBidderPerAdUnit.push(bid);
bidsPerBidder[bid.adUnitCode] = bidsPerBidderPerAdUnit;
bidsReceivedPerBidderPerAdUnit[bid.bidder] = bidsPerBidder;
return bidsReceivedPerBidderPerAdUnit;
}, {});

let bidsToReport = bidsRequested
.map(bidderRequest => bidderRequest.bids
.map(bid => {
let receivedBidsForBidder = bidsReceivedPerBidderPerAdUnit[bid.bidder] || {};
let receivedBidsForBidderForAdUnit = receivedBidsForBidder[bid.placementCode] || [];
// check received bids, or mark bid as timed out if no more received bids
if (receivedBidsForBidderForAdUnit.length > 0) {
return receivedBidsForBidderForAdUnit.shift(); // remove to count timed out bids
} else {
return {
adUnitCode: bid.placementCode,
bidder: bid.bidder,
cpm: 0,
getStatusCode: () => 3, // ERROR_TIMEOUT
timeToRespond: new Date().getTime() - bidderRequest.start
};
}
})
)
.reduce((a, b) => a.concat(b), []);

bidsToReport.forEach(bid => {
const currentAdUnitCode = bid.adUnitCode;
let adUnit = adUnits[currentAdUnitCode];
if (!adUnit) {
adUnit = initAdUnit(currentAdUnitCode);
adUnit = addAolParams(adUnit, adUnitsConf, bidsReceived);
adUnits[currentAdUnitCode] = adUnit;
}
adUnit.winner = (adUnit.winner.cpm < bid.cpm) ? bid : adUnit.winner;
adUnit.bids.push(Object.assign(bid));
});

for (let code in adUnits) {
if (adUnits.hasOwnProperty(code)) {
let adUnit = adUnits[code];
if (adUnit.aolParams) {
let url = this.buildEndpoint(EVENTS.AUCTION, adUnit);
this.reportEvent(url);
}
}
}

break;

case BID_WON:
let bidWon = args;
this.enqueue(event);
});

for (let code in adUnits) {
if (adUnits.hasOwnProperty(code) && bidWon.adUnitCode === code) {
let url = this.buildEndpoint(EVENTS.WIN, adUnits[code]);
this.reportEvent(url);
}
events.on(AUCTION_END, args => this.enqueue({ eventType: AUCTION_END, args }));
events.on(BID_WON, args => this.enqueue({ eventType: BID_WON, args }));

this.enableAnalytics = function _enable() {
return utils.logMessage(
`AOL analytics adapter already enabled, unnecessary call to 'enableAnalytics()'.`
);
};
},

//override AnalyticsAdapter functions by supplying custom methods
track({ eventType, args }) {
switch (eventType) {
case AUCTION_END:
this.reportAuctionEvent({
adUnitsConfig: $$PREBID_GLOBAL$$.adUnits,
bidsReceived: $$PREBID_GLOBAL$$._bidsReceived,
bidsRequested: $$PREBID_GLOBAL$$._bidsRequested
});
break;

case BID_WON:
this.reportWinEvent({ winningBid: args });
break;
}
},

reportAuctionEvent({ adUnitsConfig, bidsRequested, bidsReceived }) {
let bidsReceivedPerBidderPerAdUnit = bidsReceived
.reduce((bidsReceivedPerBidderPerAdUnit, bid) => {
let bidsPerBidder = bidsReceivedPerBidderPerAdUnit[bid.bidder] || {};
let bidsPerBidderPerAdUnit = bidsPerBidder[bid.adUnitCode] || [];
bidsPerBidderPerAdUnit.push(bid);
bidsPerBidder[bid.adUnitCode] = bidsPerBidderPerAdUnit;
bidsReceivedPerBidderPerAdUnit[bid.bidder] = bidsPerBidder;
return bidsReceivedPerBidderPerAdUnit;
}, {});

let bidsToReport = bidsRequested
.map(bidderRequest => bidderRequest.bids
.map(bid => {
let receivedBidsForBidder = bidsReceivedPerBidderPerAdUnit[bid.bidder] || {};
let receivedBidsForBidderForAdUnit = receivedBidsForBidder[bid.placementCode] || [];
// check received bids, or mark bid as timed out if no more received bids
if (receivedBidsForBidderForAdUnit.length > 0) {
return receivedBidsForBidderForAdUnit.shift(); // remove to count timed out bids
} else {
return {
adUnitCode: bid.placementCode,
bidder: bid.bidder,
cpm: 0,
getStatusCode: () => 3, // ERROR_TIMEOUT
timeToRespond: new Date().getTime() - bidderRequest.start
};
}

break;
})
)
.reduce(utils.flatten, []);

let adUnits = this.adUnits;

bidsToReport.forEach(bid => {
const currentAdUnitCode = bid.adUnitCode;
let adUnit = adUnits[currentAdUnitCode];
if (!adUnit) {
adUnit = initAdUnit(currentAdUnitCode);
adUnit = addAolParams(adUnit, adUnitsConfig, bidsReceived);
adUnits[currentAdUnitCode] = adUnit;
}
adUnit.winner = (adUnit.winner.cpm < bid.cpm) ? bid : adUnit.winner;
adUnit.bids.push(Object.assign({}, bid));
});

},

reportEvent(url) {
ajax(url, null, null, { withCredentials: true });
},

getBaseSchema(eventId, adUnit) {
let aolParams = adUnit.aolParams;
return {
protocol: (document.location.protocol === 'https:') ? 'https' : 'http',
host: this.server || serverMap[aolParams.region] || serverMap.us,
tagversion: '3.0',
network: aolParams.network || '',
placement: aolParams.placement,
site: aolParams.pageid || 0,
eventid: eventId,
hbeventts: Math.floor(Date.now() / 1000) // Unix timestamp in seconds.
};
},

getAuctionSchema(adUnit) {
let aolParams = adUnit.aolParams;
return {
pubadid: adUnit.code,
hbauctionid: generateAuctionId(aolParams.placement),
hbwinner: adUnit.winner.bidder ? getBidderId(adUnit.winner.bidder) : 0,
hbprice: adUnit.winner.cpm || 0,
hbcur: aolParams.currencyCode ? `;hbcur=${aolParams.currencyCode}` : '',
pubapi: aolParams.pubapiId ? `;pubapi=${aolParams.pubapiId}` : ''
};
},

getWinSchema(adUnit) {
let auctionParams = adUnit.auctionParams;
return {
pubadid: adUnit.code,
hbauctioneventts: auctionParams.hbauctioneventts,
hbauctionid: auctionParams.hbauctionid,
hbwinner: getBidderId(adUnit.winner.bidder),
pubcpm: adUnit.winner.cpm
};
},

getBidderSchema(bid) {
return {
hbbidder: getBidderId(bid.bidder),
hbbid: bid.cpm || 0,
hbstatus: getStatusCode(bid),
hbtime: bid.timeToRespond || ''
};
},

buildEndpoint(event, adUnit) {
let baseSchema, url;

switch (event) {

case EVENTS.AUCTION:

baseSchema = this.getBaseSchema(EVENTS.AUCTION, adUnit);
let auctionSchema = this.getAuctionSchema(adUnit);
adUnit.auctionParams = {
hbauctioneventts: baseSchema.hbeventts,
hbauctionid: auctionSchema.hbauctionid
};
url = baseSchemaTemplate(baseSchema) + auctionSchemaTemplate(auctionSchema);
adUnit.bids.forEach(bid => {
url = url + bidderSchemaTemplate(this.getBidderSchema(bid));
});
return url;

case EVENTS.WIN:

baseSchema = this.getBaseSchema(EVENTS.WIN, adUnit);
let winSchema = this.getWinSchema(adUnit);
url = baseSchemaTemplate(baseSchema) + winSchemaTemplate(winSchema);
return url;
for (let code in adUnits) {
if (adUnits.hasOwnProperty(code)) {
let adUnit = adUnits[code];
if (adUnit.aolParams) {
this.reportEvent(EVENTS.AUCTION, adUnit);
}
}
}
},

reportWinEvent({ winningBid }) {
let adUnits = this.adUnits;
for (let code in adUnits) {
if (adUnits.hasOwnProperty(code) && winningBid.adUnitCode === code) {
this.reportEvent(EVENTS.WIN, adUnits[code]);
}
}
},

reportEvent(event, adUnit) {
let url = this.buildEventUrl(event, adUnit);
ajax(url, null, null, { withCredentials: true });
},

getBaseSchema(eventId, adUnit) {
let aolParams = adUnit.aolParams;
return {
protocol: (document.location.protocol === 'https:') ? 'https' : 'http',
host: this.server || serverMap[aolParams.region] || serverMap.us,
tagversion: '3.0',
network: aolParams.network || '',
placement: aolParams.placement,
site: aolParams.pageId || 0,
eventid: eventId,
hbeventts: Math.floor(Date.now() / 1000) // Unix timestamp in seconds.
};
},

getAuctionSchema(adUnit) {
let aolParams = adUnit.aolParams;
return {
pubadid: adUnit.code,
hbauctionid: generateAuctionId(aolParams.placement),
hbwinner: adUnit.winner.bidder ? getBidderId(adUnit.winner.bidder) : 0,
hbprice: adUnit.winner.cpm || 0,
hbcur: aolParams.currencyCode ? `;hbcur=${aolParams.currencyCode}` : '',
pubapi: aolParams.pubapiId ? `;pubapi=${aolParams.pubapiId}` : ''
};
},

getWinSchema(adUnit) {
let auctionParams = adUnit.auctionParams;
return {
pubadid: adUnit.code,
hbauctioneventts: auctionParams.hbauctioneventts,
hbauctionid: auctionParams.hbauctionid,
hbwinner: getBidderId(adUnit.winner.bidder),
pubcpm: adUnit.winner.cpm
};
},

getBidderSchema(bid) {
return {
hbbidder: getBidderId(bid.bidder),
hbbid: bid.cpm || 0,
hbstatus: getStatusCode(bid),
hbtime: bid.timeToRespond || ''
};
},

buildEventUrl(event, adUnit) {
let baseSchema, url;

switch (event) {

case EVENTS.AUCTION:

baseSchema = this.getBaseSchema(EVENTS.AUCTION, adUnit);
let auctionSchema = this.getAuctionSchema(adUnit);
adUnit.auctionParams = {
hbauctioneventts: baseSchema.hbeventts,
hbauctionid: auctionSchema.hbauctionid
};
url = baseSchemaTemplate(baseSchema) + auctionSchemaTemplate(auctionSchema);
adUnit.bids.forEach(bid => {
url = url + bidderSchemaTemplate(this.getBidderSchema(bid));
});
return url;

case EVENTS.WIN:

baseSchema = this.getBaseSchema(EVENTS.WIN, adUnit);
let winSchema = this.getWinSchema(adUnit);
url = baseSchemaTemplate(baseSchema) + winSchemaTemplate(winSchema);
return url;

});
}
}

});

function template(strings, ...keys) {
return function(...values) {
Expand Down
Loading

0 comments on commit af5c813

Please sign in to comment.