Skip to content

Commit d79483b

Browse files
robertrmartinezbretg
authored andcommitted
Rubi Analytics handles > 1 bidResponse per bidRequest (#4224)
1 parent 0274410 commit d79483b

File tree

2 files changed

+70
-12
lines changed

2 files changed

+70
-12
lines changed

modules/rubiconAnalyticsAdapter.js

+20-12
Original file line numberDiff line numberDiff line change
@@ -209,18 +209,26 @@ function sendMessage(auctionId, bidWonId) {
209209
);
210210
}
211211

212-
export function parseBidResponse(bid) {
212+
function getBidPrice(bid) {
213+
if (typeof bid.currency === 'string' && bid.currency.toUpperCase() === 'USD') {
214+
return Number(bid.cpm);
215+
}
216+
// use currency conversion function if present
217+
if (typeof bid.getCpmInNewCurrency === 'function') {
218+
return Number(bid.getCpmInNewCurrency('USD'));
219+
}
220+
utils.logWarn('Rubicon Analytics Adapter: Could not determine the bidPriceUSD of the bid ', bid);
221+
}
222+
223+
export function parseBidResponse(bid, previousBidResponse) {
224+
// The current bidResponse for this matching requestId/bidRequestId
225+
let responsePrice = getBidPrice(bid)
226+
// we need to compare it with the previous one (if there was one)
227+
if (previousBidResponse && previousBidResponse.bidPriceUSD > responsePrice) {
228+
return previousBidResponse;
229+
}
213230
return utils.pick(bid, [
214-
'bidPriceUSD', () => {
215-
if (typeof bid.currency === 'string' && bid.currency.toUpperCase() === 'USD') {
216-
return Number(bid.cpm);
217-
}
218-
// use currency conversion function if present
219-
if (typeof bid.getCpmInNewCurrency === 'function') {
220-
return Number(bid.getCpmInNewCurrency('USD'));
221-
}
222-
utils.logWarn('Rubicon Analytics Adapter: Could not determine the bidPriceUSD of the bid ', bid);
223-
},
231+
'bidPriceUSD', () => responsePrice,
224232
'dealId',
225233
'status',
226234
'mediaType',
@@ -405,7 +413,7 @@ let rubiconAdapter = Object.assign({}, baseAdapter, {
405413
};
406414
}
407415
bid.clientLatencyMillis = Date.now() - cache.auctions[args.auctionId].timestamp;
408-
bid.bidResponse = parseBidResponse(args);
416+
bid.bidResponse = parseBidResponse(args, bid.bidResponse);
409417
break;
410418
case BIDDER_DONE:
411419
args.bids.forEach(bid => {

test/spec/modules/rubiconAnalyticsAdapter_spec.js

+50
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,56 @@ describe('rubicon analytics adapter', function () {
657657
expect(message).to.deep.equal(ANALYTICS_MESSAGE);
658658
});
659659

660+
it('should pick the highest cpm bid if more than one bid per bidRequestId', function () {
661+
// Only want one bid request in our mock auction
662+
let bidRequested = utils.deepClone(MOCK.BID_REQUESTED);
663+
bidRequested.bids.shift();
664+
let auctionInit = utils.deepClone(MOCK.AUCTION_INIT);
665+
auctionInit.adUnits.shift();
666+
667+
// clone the mock bidResponse and duplicate
668+
let duplicateResponse1 = utils.deepClone(BID2);
669+
duplicateResponse1.cpm = 1.0;
670+
duplicateResponse1.adserverTargeting.hb_pb = '1.0';
671+
duplicateResponse1.adserverTargeting.hb_adid = '1111';
672+
let duplicateResponse2 = utils.deepClone(BID2);
673+
duplicateResponse2.cpm = 5.5;
674+
duplicateResponse2.adserverTargeting.hb_pb = '5.5';
675+
duplicateResponse2.adserverTargeting.hb_adid = '5555';
676+
let duplicateResponse3 = utils.deepClone(BID2);
677+
duplicateResponse3.cpm = 0.1;
678+
duplicateResponse3.adserverTargeting.hb_pb = '0.1';
679+
duplicateResponse3.adserverTargeting.hb_adid = '3333';
680+
681+
const setTargeting = {
682+
[duplicateResponse2.adUnitCode]: duplicateResponse2.adserverTargeting
683+
};
684+
685+
const bidWon = Object.assign({}, duplicateResponse2, {
686+
'status': 'rendered'
687+
});
688+
689+
// spoof the auction with just our duplicates
690+
events.emit(AUCTION_INIT, auctionInit);
691+
events.emit(BID_REQUESTED, bidRequested);
692+
events.emit(BID_RESPONSE, duplicateResponse1);
693+
events.emit(BID_RESPONSE, duplicateResponse2);
694+
events.emit(BID_RESPONSE, duplicateResponse3);
695+
events.emit(AUCTION_END, MOCK.AUCTION_END);
696+
events.emit(SET_TARGETING, setTargeting);
697+
events.emit(BID_WON, bidWon);
698+
699+
let message = JSON.parse(requests[0].requestBody);
700+
validate(message);
701+
expect(message.auctions[0].adUnits[0].bids[0].bidResponse.bidPriceUSD).to.equal(5.5);
702+
expect(message.auctions[0].adUnits[0].adserverTargeting.hb_pb).to.equal('5.5');
703+
expect(message.auctions[0].adUnits[0].adserverTargeting.hb_adid).to.equal('5555');
704+
expect(message.bidsWon.length).to.equal(1);
705+
expect(message.bidsWon[0].bidResponse.bidPriceUSD).to.equal(5.5);
706+
expect(message.bidsWon[0].adserverTargeting.hb_pb).to.equal('5.5');
707+
expect(message.bidsWon[0].adserverTargeting.hb_adid).to.equal('5555');
708+
});
709+
660710
it('should send batched message without BID_WON if necessary and further BID_WON events individually', function () {
661711
events.emit(AUCTION_INIT, MOCK.AUCTION_INIT);
662712
events.emit(BID_REQUESTED, MOCK.BID_REQUESTED);

0 commit comments

Comments
 (0)