Skip to content

Commit

Permalink
Fix uncached video bids triggering callback early (#2017)
Browse files Browse the repository at this point in the history
* Mark video bid done after it's been cached

* Add tests
  • Loading branch information
matthewlane authored and jsnellbaker committed Jan 10, 2018
1 parent 3502919 commit 289cee2
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 9 deletions.
30 changes: 21 additions & 9 deletions src/auction.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,24 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels})
}

function done(bidRequestId) {
var innerBidRequestId = bidRequestId;
const innerBidRequestId = bidRequestId;
return delayExecution(function() {
let request = find(_bidderRequests, (bidRequest) => {
const request = find(_bidderRequests, (bidRequest) => {
return innerBidRequestId === bidRequest.bidderRequestId;
});
request.doneCbCallCount += 1;
// In case of mediaType video and prebidCache enabled, call bidsBackHandler after cache is stored.
if ((request.bids.filter(videoAdUnit).length == 0) || (request.bids.filter(videoAdUnit).length > 0 && !config.getConfig('cache.url'))) {

const nonVideoBid = request.bids.filter(videoAdUnit).length === 0;
const videoBid = request.bids.filter(videoAdUnit).length > 0;
const videoBidNoCache = videoBid && !config.getConfig('cache.url');
const videoBidWithCache = videoBid && config.getConfig('cache.url');

// video bids with cache enabled need to be cached first before saying they are done
if (!videoBidWithCache) {
request.doneCbCallCount += 1;
}

// in case of mediaType video and prebidCache enabled, call bidsBackHandler after cache is stored.
if (nonVideoBid || videoBidNoCache) {
bidsBackAll()
}
}, 1);
Expand Down Expand Up @@ -216,7 +226,9 @@ export const addBidResponse = createHook('asyncSeries', function(adUnitCode, bid
let bidRequests = auctionInstance.getBidRequests();
let auctionId = auctionInstance.getAuctionId();

let bidResponse = getPreparedBidForAuction({adUnitCode, bid, bidRequests, auctionId});
let bidRequest = getBidderRequest(bidRequests, bid.bidderCode, adUnitCode);
let bidResponse = getPreparedBidForAuction({adUnitCode, bid, bidRequest, auctionId});

if (bidResponse.mediaType === 'video') {
tryAddVideoBid(bidResponse);
} else {
Expand Down Expand Up @@ -247,6 +259,8 @@ export const addBidResponse = createHook('asyncSeries', function(adUnitCode, bid
if (!bid.vastUrl) {
bidResponse.vastUrl = getCacheUrl(bidResponse.videoCacheKey);
}
// only set this prop after the bid has been cached to avoid early ending auction early in bidsBackAll
bidRequest.doneCbCallCount += 1;
addBidToAuction(bidResponse);
auctionInstance.bidsBackAll();
}
Expand All @@ -261,9 +275,7 @@ export const addBidResponse = createHook('asyncSeries', function(adUnitCode, bid

// Postprocess the bids so that all the universal properties exist, no matter which bidder they came from.
// This should be called before addBidToAuction().
function getPreparedBidForAuction({adUnitCode, bid, bidRequests, auctionId}) {
let bidRequest = getBidderRequest(bidRequests, bid.bidderCode, adUnitCode);

function getPreparedBidForAuction({adUnitCode, bid, bidRequest, auctionId}) {
const start = bidRequest.start;

let bidObject = Object.assign({}, bid, {
Expand Down
29 changes: 29 additions & 0 deletions test/spec/auctionmanager_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import CONSTANTS from 'src/constants.json';
import { adjustBids } from 'src/auction';
import * as auctionModule from 'src/auction';
import { newBidder, registerBidder } from 'src/adapters/bidderFactory';
import { config } from 'src/config';
import * as store from 'src/videoCache';
import * as ajaxLib from 'src/ajax';

var assert = require('assert');
Expand Down Expand Up @@ -870,5 +872,32 @@ describe('auctionmanager.js', function () {
assert.notEqual(addedBid2.adId, bids1[0].requestId);
assert.equal(length, 1);
});

it('should run auction after video bids have been cached', () => {
sinon.stub(store, 'store').callsArgWith(1, null, [{ uuid: 123}]);
sinon.stub(config, 'getConfig').withArgs('cache.url').returns('cache-url');

const bidsCopy = [Object.assign({}, bids[0], { mediaType: 'video'})];
const bids1Copy = [Object.assign({}, bids1[0], { mediaType: 'video'})];

registerBidder(spec);
registerBidder(spec1);

spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]);
spec.isBidRequestValid.returns(true);
spec.interpretResponse.returns(bidsCopy);

spec1.buildRequests.returns([{'id': 123, 'method': 'POST'}]);
spec1.isBidRequestValid.returns(true);
spec1.interpretResponse.returns(bids1Copy);

auction.callBids();

assert.equal(auction.getBidsReceived().length, 2);
assert.equal(auction.getAuctionStatus(), 'completed');

config.getConfig.restore();
store.store.restore();
});
});
});

0 comments on commit 289cee2

Please sign in to comment.