Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix uncached video bids triggering callback early #2017

Merged
merged 2 commits into from
Jan 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
});
});
});