Skip to content

Commit

Permalink
Pbjs Core: add new API to return the highest unused bid for a given a…
Browse files Browse the repository at this point in the history
…dunit (#6342)

* feat: add new API to return the highest unused bid for a given adunit code

* feat: add unit tests for new API
  • Loading branch information
woggle23 authored and idettman committed May 21, 2021
1 parent 3e709ad commit a883da5
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 2 deletions.
8 changes: 8 additions & 0 deletions src/auctionManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*
* @property {function(): Array} getBidsRequested - returns consolidated bid requests
* @property {function(): Array} getBidsReceived - returns consolidated bid received
* @property {function(): Array} getAllBidsForAdUnitCode - returns consolidated bid received for a given adUnit
* @property {function(): Array} getAdUnits - returns consolidated adUnits
* @property {function(): Array} getAdUnitCodes - returns consolidated adUnitCodes
* @property {function(): Object} createAuction - creates auction instance and stores it for future reference
Expand Down Expand Up @@ -66,6 +67,13 @@ export function newAuctionManager() {
.filter(bid => bid);
};

auctionManager.getAllBidsForAdUnitCode = function(adUnitCode) {
return _auctions.map((auction) => {
return auction.getBidsReceived();
}).reduce(flatten, [])
.filter(bid => bid && bid.adUnitCode === adUnitCode)
};

auctionManager.getAdUnits = function() {
return _auctions.map(auction => auction.getAdUnits())
.reduce(flatten, []);
Expand Down
22 changes: 20 additions & 2 deletions src/prebid.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/** @module pbjs */

import { getGlobal } from './prebidGlobal.js';
import { adUnitsFilter, flatten, isArrayOfNums, isGptPubadsDefined, uniques } from './utils.js';
import { adUnitsFilter, flatten, getHighestCpm, isArrayOfNums, isGptPubadsDefined, uniques } from './utils.js';
import { listenMessagesFromCreative } from './secureCreatives.js';
import { userSync } from './userSync.js';
import { config } from './config.js';
import { auctionManager } from './auctionManager.js';
import { targeting } from './targeting.js';
import { filters, targeting } from './targeting.js';
import { hook } from './hook.js';
import { sessionLoader } from './debugging.js';
import includes from 'core-js-pure/features/array/includes.js';
Expand Down Expand Up @@ -222,6 +222,24 @@ $$PREBID_GLOBAL$$.getAdserverTargetingForAdUnitCodeStr = function (adunitCode) {
}
};

/**
* This function returns the query string targeting parameters available at this moment for a given ad unit. Note that some bidder's response may not have been received if you call this function too quickly after the requests are sent.
* @param adUnitCode {string} adUnitCode to get the bid responses for
* @alias module:pbjs.getHighestUnusedBidResponseForAdUnitCode
* @returns {Object} returnObj return bid
*/
$$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode = function (adunitCode) {
if (adunitCode) {
const bid = auctionManager.getAllBidsForAdUnitCode(adunitCode)
.filter(filters.isUnusedBid)
.filter(filters.isBidNotExpired)

return bid.length ? bid.reduce(getHighestCpm) : {}
} else {
utils.logMessage('Need to call getHighestUnusedBidResponseForAdUnitCode with adunitCode');
}
};

/**
* This function returns the query string targeting parameters available at this moment for a given ad unit. Note that some bidder's response may not have been received if you call this function too quickly after the requests are sent.
* @param adUnitCode {string} adUnitCode to get the bid responses for
Expand Down
4 changes: 4 additions & 0 deletions test/spec/api_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,9 @@ describe('Publisher API', function () {
it('should have function $$PREBID_GLOBAL$$.getAllWinningBids', function () {
assert.isFunction($$PREBID_GLOBAL$$.getAllWinningBids);
});

it('should have function $$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode', function () {
assert.isFunction($$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode);
});
});
});
52 changes: 52 additions & 0 deletions test/spec/unit/pbjs_api_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2611,6 +2611,58 @@ describe('Unit: Prebid Module', function () {
});
});

describe('getHighestUnusedBidResponseForAdUnitCode', () => {
afterEach(() => {
resetAuction();
})

it('returns an empty object if there is no bid for the given adUnitCode', () => {
const highestBid = $$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode('stallone');
expect(highestBid).to.deep.equal({});
})

it('returns undefined if adUnitCode is provided', () => {
const highestBid = $$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode();
expect(highestBid).to.be.undefined;
})

it('should ignore bids that have already been used (\'rendered\')', () => {
const _bidsReceived = getBidResponses().slice(0, 3);
_bidsReceived[0].cpm = 11
_bidsReceived[1].cpm = 13
_bidsReceived[2].cpm = 12

_bidsReceived.forEach((bid) => {
bid.adUnitCode = '/19968336/header-bid-tag-0';
});

auction.getBidsReceived = function() { return _bidsReceived };
const highestBid1 = $$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode('/19968336/header-bid-tag-0');
expect(highestBid1).to.deep.equal(_bidsReceived[1])
_bidsReceived[1].status = CONSTANTS.BID_STATUS.RENDERED
const highestBid2 = $$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode('/19968336/header-bid-tag-0');
expect(highestBid2).to.deep.equal(_bidsReceived[2])
})

it('should ignore expired bids', () => {
const _bidsReceived = getBidResponses().slice(0, 3);
_bidsReceived[0].cpm = 11
_bidsReceived[1].cpm = 13
_bidsReceived[2].cpm = 12

_bidsReceived.forEach((bid) => {
bid.adUnitCode = '/19968336/header-bid-tag-0';
});

auction.getBidsReceived = function() { return _bidsReceived };

bidExpiryStub.restore();
bidExpiryStub = sinon.stub(filters, 'isBidNotExpired').callsFake((bid) => bid.cpm !== 13);
const highestBid = $$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode('/19968336/header-bid-tag-0');
expect(highestBid).to.deep.equal(_bidsReceived[2])
})
})

describe('getHighestCpm', () => {
after(() => {
resetAuction();
Expand Down

0 comments on commit a883da5

Please sign in to comment.