Skip to content

Commit

Permalink
Updated schema to be grouped by adunit code and added client-side inc…
Browse files Browse the repository at this point in the history
…remental lift calculation.
  • Loading branch information
Jimmy Tu committed May 27, 2020
1 parent 4e68b34 commit 7035afd
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 33 deletions.
63 changes: 51 additions & 12 deletions modules/openxAnalyticsAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import includes from 'core-js/library/fn/array/includes.js';
import includes from 'core-js-pure/features/array/includes.js';
import adapter from '../src/AnalyticsAdapter.js';
import CONSTANTS from '../src/constants.json';
import adapterManager from '../src/adapterManager.js';
Expand Down Expand Up @@ -1080,24 +1080,19 @@ function buildAuctionPayload(auction) {
deviceOSType: detectOS(),
browser: detectBrowser(),
testCode: analyticsConfig.testCode,
bidRequests: buildBidRequestsPayload(adUnitCodeToBidderRequestMap),
adUnits: buildBidRequestsPayload(adUnitCodeToBidderRequestMap),
};

function buildBidRequestsPayload(adUnitCodeToBidderRequestMap) {
return utils._map(adUnitCodeToBidderRequestMap, (bidderRequestMap, adUnitCode) => {
return utils._map(bidderRequestMap, (bidderRequest) => {
let bidRequests = utils._map(bidderRequestMap, (bidderRequest) => {
let {bidder, source, bids, mediaTypes, timedOut, userId} = bidderRequest;
return {
adUnitCode,
bidder,
source,
// return an array of objects containing the module name and id
userIds: utils._map(userId, (id, module) => {
return {
module: module,
id: getUserId(module, id)};
})
.filter(({id}) => id),
userIds: buildUserIdPayload(userId),
hasBidderResponded: Object.keys(bids).length > 0,
availableAdSizes: getMediaTypeSizes(mediaTypes),
availableMediaTypes: getMediaTypes(mediaTypes),
Expand All @@ -1122,7 +1117,7 @@ function buildAuctionPayload(auction) {
latency,
winner,
rendered,
renderTime,
renderTime
} = bidderBidResponse;

return {
Expand All @@ -1141,14 +1136,58 @@ function buildAuctionPayload(auction) {
ts,
rendered,
renderTime,
meta,
meta
}
})
}
})
});

return {
code: adUnitCode,
incrementalLiftMicroCpmUSD: calculateIncrementalLift(bidRequests),
bidRequests
};

function buildUserIdPayload(userId) {
return utils._map(userId, (id, module) => {
return {
module: module,
id: getUserId(module, id)
};
})
.filter(({id}) => id)
}
}).flat();
}

function calculateIncrementalLift(bidRequests) {
let bidResponses = bidRequests.flatMap(bidRequest => bidRequest.bidResponses);
let [winningBidResponses, losingBidResponses] = partitionByWinningResponses(bidResponses);
let loserWithHigestCpm;


if(winningBidResponses.length === 0) {
return 0;
}

loserWithHigestCpm = losingBidResponses.reduce((bidResponseWithHighestCpm, bidResponse) => {
if(!bidResponseWithHighestCpm){
return bidResponse
} else {
return bidResponse.microCpm > bidResponseWithHighestCpm.microCpm ? bidResponse : bidResponseWithHighestCpm;
}
}, {microCpm: 0});

return (winningBidResponses[0].microCpm - loserWithHigestCpm.microCpm);

function partitionByWinningResponses(bidResponses){
return bidResponses.reduce(([winners, losers], bidResponse) => {
bidResponse.winner ? winners.push(bidResponse) : losers.push(bidResponse);
return [winners, losers];
}, [[],[]]);
}
}

function getUserId(module, idOrIdObject) {
let normalizedId;

Expand Down
54 changes: 33 additions & 21 deletions test/spec/modules/openxAnalyticsAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -675,10 +675,10 @@ describe('openx analytics adapter', function() {

const bidTimeoutOpenX = {
0: {
adUnitCode: AD_UNIT_CODE,
auctionId: 'test-auction-id',
bidId: 'test-openx-request-id'
}};
adUnitCode: AD_UNIT_CODE,
auctionId: 'test-auction-id',
bidId: 'test-openx-request-id'
}};

const bidTimeoutCloseX = {
0: {
Expand Down Expand Up @@ -922,32 +922,32 @@ describe('openx analytics adapter', function() {
});

it('should track the bidder', function () {
let openxBidder = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
let closexBidder = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'closex');
let openxBidder = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
let closexBidder = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'closex');

expect(openxBidder.bidder).to.equal('openx');
expect(closexBidder.bidder).to.equal('closex');
});

it('should track the adunit code', function () {
let openxBidder = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
let closexBidder = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'closex');
let openxBidder = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
let closexBidder = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'closex');

expect(openxBidder.adUnitCode).to.equal(AD_UNIT_CODE);
expect(closexBidder.adUnitCode).to.equal(AD_UNIT_CODE);
});

it('should track the user ids', function () {
let openxBidder = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
let closexBidder = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'closex');
let openxBidder = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
let closexBidder = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'closex');

expect(openxBidder.userIds).to.deep.include({module: 'tdid', id: bidRequestedOpenX.bids[0].userId.tdid});
expect(closexBidder.userIds).to.deep.include({module: 'tdid', id: bidRequestedCloseX.bids[0].userId.tdid});
});

it('should not have responded', function () {
let openxBidder = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
let closexBidder = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'closex');
let openxBidder = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
let closexBidder = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'closex');

expect(openxBidder.hasBidderResponded).to.equal(false);
expect(closexBidder.hasBidderResponded).to.equal(false);
Expand All @@ -973,8 +973,8 @@ describe('openx analytics adapter', function() {
clock.tick(SLOT_LOAD_WAIT_TIME * 2);
auction = JSON.parse(server.requests[0].requestBody)[0];

openxBidRequest = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
closexBidRequest = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'closex');
openxBidRequest = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
closexBidRequest = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'closex');
});

afterEach(function () {
Expand Down Expand Up @@ -1008,8 +1008,8 @@ describe('openx analytics adapter', function() {
clock.tick(SLOT_LOAD_WAIT_TIME * 2);
auction = JSON.parse(server.requests[0].requestBody)[0];

openxBidResponse = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx').bidResponses[0];
closexBidResponse = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'closex').bidResponses[0];
openxBidResponse = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx').bidResponses[0];
closexBidResponse = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'closex').bidResponses[0];
});

afterEach(function () {
Expand Down Expand Up @@ -1104,14 +1104,26 @@ describe('openx analytics adapter', function() {
});

it('should track that bidder as the winner', function () {
let openxBidder = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
let openxBidder = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
expect(openxBidder.bidResponses[0]).to.contain({winner: true});
});

it('should track that bidder as the losers', function () {
let closexBidder = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'closex');
let closexBidder = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'closex');
expect(closexBidder.bidResponses[0]).to.contain({winner: false});
});

it('should calculate the incremental lift for winning bids', function () {
let openxBidderResponse = auction.adUnits[0].bidRequests
.find(bidderRequest => bidderRequest.bidder === 'openx')
.bidResponses[0];

let closexBidderResponse = auction.adUnits[0].bidRequests
.find(bidderRequest => bidderRequest.bidder === 'closex')
.bidResponses[0];

expect(auction.adUnits[0].incrementalLiftMicroCpmUSD).to.equal(openxBidderResponse.microCpm - closexBidderResponse.microCpm);
});
});

describe('when a winning bid renders', function () {
Expand Down Expand Up @@ -1145,12 +1157,12 @@ describe('openx analytics adapter', function() {
});

it('should track that winning bid rendered', function () {
let openxBidder = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
let openxBidder = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
expect(openxBidder.bidResponses[0]).to.contain({rendered: true});
});

it('should track that winning bid render time', function () {
let openxBidder = auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
let openxBidder = auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
expect(openxBidder.bidResponses[0]).to.contain({renderTime: CURRENT_TIME});
});

Expand Down Expand Up @@ -1386,7 +1398,7 @@ describe('openx analytics adapter', function() {

expect(bidWonEventInfoList.length).to.equal(1);

let openxBidder = v2Auction.bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
let openxBidder = v2Auction.adUnits[0].bidRequests.find(bidderRequest => bidderRequest.bidder === 'openx');
expect(openxBidder.bidResponses[0]).to.contain({winner: true});
});
});
Expand Down

0 comments on commit 7035afd

Please sign in to comment.