diff --git a/src/auction.js b/src/auction.js index f5f7e3a9eec..f37fead883b 100644 --- a/src/auction.js +++ b/src/auction.js @@ -48,7 +48,7 @@ * @property {function(): void} callBids - sends requests to all adapters for bids */ -import { uniques, timestamp, adUnitsFilter, delayExecution, getBidderRequest } from './utils'; +import { uniques, flatten, timestamp, adUnitsFilter, delayExecution, getBidderRequest } from './utils'; import { getPriceBucketString } from './cpmBucketManager'; import { NATIVE_KEYS } from './native'; import { getCacheUrl, store } from './videoCache'; @@ -88,7 +88,7 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels}) let _bidderRequests = []; let _bidsReceived = []; let _auctionStart; - let _auctionId = utils.getUniqueIdentifierStr(); + let _auctionId = utils.generateUUID(); let _auctionStatus; let _callback = callback; let _timer; @@ -132,28 +132,14 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels}) if (timedOut) { utils.logMessage(`Auction ${_auctionId} timedOut`); - const timedOutBidders = getTimedOutBidders(); + const timedOutBidders = getTimedOutBids(_bidderRequests, _bidsReceived); if (timedOutBidders.length) { - events.emit(CONSTANTS.EVENTS.BID_TIMEOUT, { timedOutBidders, auctionId: _auctionId }); + events.emit(CONSTANTS.EVENTS.BID_TIMEOUT, timedOutBidders); } } } } - function getTimedOutBidders() { - return _bidderRequests - .map((bidSet) => { - return bidSet.bidderCode; - }) - .filter(uniques) - .filter(bidder => _bidsReceived - .map((bid) => { - return bid.bidder; - }) - .filter(uniques) - .indexOf(bidder) < 0); - }; - function done(bidRequestId) { var innerBidRequestId = bidRequestId; return delayExecution(function() { @@ -458,3 +444,41 @@ function groupByPlacement(bidsByPlacement, bid) { bidsByPlacement[bid.adUnitCode].bids.push(bid); return bidsByPlacement; } + +/** + * Returns a list of bids that we haven't received a response yet + * @param {BidRequest[]} bidderRequests List of bids requested for auction instance + * @param {BidReceived[]} bidsReceived List of bids received for auction instance + * + * @typedef {Object} TimedOutBid + * @property {string} bidId The id representing the bid + * @property {string} bidder The string name of the bidder + * @property {string} adUnitCode The code used to uniquely identify the ad unit on the publisher's page + * @property {string} auctionId The id representing the auction + * + * @return {Array} List of bids that Prebid hasn't received a response for + */ +function getTimedOutBids(bidderRequests, bidsReceived) { + const bidRequestedCodes = bidderRequests + .map(bid => bid.bidderCode) + .filter(uniques); + + const bidReceivedCodes = bidsReceived + .map(bid => bid.bidder) + .filter(uniques); + + const timedOutBidderCodes = bidRequestedCodes + .filter(bidder => !bidReceivedCodes.includes(bidder)); + + const timedOutBids = bidderRequests + .map(bid => (bid.bids || []).filter(bid => timedOutBidderCodes.includes(bid.bidder))) + .reduce(flatten, []) + .map(bid => ({ + bidId: bid.bidId, + bidder: bid.bidder, + adUnitCode: bid.adUnitCode, + auctionId: bid.auctionId, + })); + + return timedOutBids; +} diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index 613074e59f9..223752d2e57 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -850,7 +850,7 @@ describe('Unit: Prebid Module', function () { }; $$PREBID_GLOBAL$$.requestBids(requestObj); - let re = new RegExp('^Auction [0-9A-Za-z]+ timedOut$'); + let re = new RegExp('^Auction [a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12} timedOut$'); clock.tick(requestObj.timeout - 1); assert.ok(logMessageSpy.neverCalledWith(sinon.match(re)), 'executeCallback not called');