Skip to content

Commit

Permalink
Generate no-bid response for ech bid request not matched by a bid (#1216
Browse files Browse the repository at this point in the history
)
  • Loading branch information
dmitriyshashkin authored and Matt Kendall committed Jun 14, 2017
1 parent 89c6300 commit 7cb6ce8
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 29 deletions.
41 changes: 18 additions & 23 deletions src/adapters/prebidServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,34 +108,12 @@ function PrebidServer() {
if (result.status === 'OK') {
if (result.bidder_status) {
result.bidder_status.forEach(bidder => {
if (bidder.no_bid || bidder.no_cookie) {
// store a "No Bid" bid response

if (!bidder.ad_unit) {
utils.getBidderRequestAllAdUnits(bidder.bidder).bids.forEach(bid => {
let bidObject = bidfactory.createBid(STATUS.NO_BID, bid);
bidObject.adUnitCode = bid.placementCode;
bidObject.bidderCode = bidder.bidder;

bidmanager.addBidResponse(bid.placementCode, bidObject);
});
} else {
let bidObject = bidfactory.createBid(STATUS.NO_BID, {
bidId: bidder.bid_id
});

bidObject.adUnitCode = bidder.ad_unit;
bidObject.bidderCode = bidder.bidder;

bidmanager.addBidResponse(bidObject.adUnitCode, bidObject);
}
}
if (bidder.no_cookie) {
// if no cookie is present then no bids were made, we don't store a bid response
queueSync({bidder: bidder.bidder, url: bidder.usersync.url, type: bidder.usersync.type});
}
});
}

if (result.bids) {
result.bids.forEach(bidObj => {
let bidRequest = utils.getBidRequest(bidObj.bid_id);
Expand All @@ -161,6 +139,23 @@ function PrebidServer() {
bidmanager.addBidResponse(bidObj.code, bidObject);
});
}

const receivedBidIds = result.bids ? result.bids.map(bidObj => bidObj.bid_id) : [];

// issue a no-bid response for every bid request that can not be matched with received bids
config.bidders.forEach(bidder => {
utils
.getBidderRequestAllAdUnits(bidder)
.bids.filter(bidRequest => !receivedBidIds.includes(bidRequest.bidId))
.forEach(bidRequest => {
let bidObject = bidfactory.createBid(STATUS.NO_BID, bidRequest);

bidObject.adUnitCode = bidRequest.placementCode;
bidObject.bidderCode = bidRequest.bidder;

bidmanager.addBidResponse(bidObject.adUnitCode, bidObject);
});
});
}
else if (result.status === 'no_cookie') {
// cookie sync
Expand Down
49 changes: 43 additions & 6 deletions test/spec/adapters/prebidServer_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,16 +144,20 @@ describe('S2S Adapter', () => {
sinon.stub(bidmanager, 'addBidResponse');
sinon.stub(utils, 'getBidderRequestAllAdUnits').returns({
bids: [{
bidId: '32167',
bidId: '123',
placementCode: 'div-gpt-ad-1460505748561-0'
}]
});
sinon.stub(utils, 'getBidRequest').returns({
bidId: '123'
});
});

afterEach(() => {
server.restore();
bidmanager.addBidResponse.restore();
utils.getBidderRequestAllAdUnits.restore();
utils.getBidRequest.restore();
});

it('registers bids', () => {
Expand All @@ -167,9 +171,10 @@ describe('S2S Adapter', () => {
const response = bidmanager.addBidResponse.firstCall.args[1];
expect(response).to.have.property('statusMessage', 'Bid available');
expect(response).to.have.property('cpm', 0.5);
expect(response).to.have.property('adId', '123');
});

it('registers no bid response when ad unit not set', () => {
it('registers no-bid response when ad unit not set', () => {
server.respondWith(JSON.stringify(RESPONSE_NO_BID_NO_UNIT));

adapter.setConfig(CONFIG);
Expand All @@ -184,10 +189,10 @@ describe('S2S Adapter', () => {
expect(response).to.have.property('statusMessage', 'Bid returned empty or error response');

const bid_request_passed = bidmanager.addBidResponse.firstCall.args[1];
expect(bid_request_passed).to.have.property('adId', '32167');
expect(bid_request_passed).to.have.property('adId', '123');
});

it('registers no bid response when server requests cookie sync', () => {
it('registers no-bid response when server requests cookie sync', () => {
server.respondWith(JSON.stringify(RESPONSE_NO_COOKIE));

adapter.setConfig(CONFIG);
Expand All @@ -202,10 +207,10 @@ describe('S2S Adapter', () => {
expect(response).to.have.property('statusMessage', 'Bid returned empty or error response');

const bid_request_passed = bidmanager.addBidResponse.firstCall.args[1];
expect(bid_request_passed).to.have.property('adId', '32167');
expect(bid_request_passed).to.have.property('adId', '123');
});

it('registers no bid response when ad unit is set', () => {
it('registers no-bid response when ad unit is set', () => {
server.respondWith(JSON.stringify(RESPONSE_NO_BID_UNIT_SET));

adapter.setConfig(CONFIG);
Expand All @@ -220,6 +225,38 @@ describe('S2S Adapter', () => {
expect(response).to.have.property('statusMessage', 'Bid returned empty or error response');
});

it('registers no-bid response when there are less bids than requests', () => {
utils.getBidderRequestAllAdUnits.restore();
sinon.stub(utils, 'getBidderRequestAllAdUnits').returns({
bids: [{
bidId: '123',
placementCode: 'div-gpt-ad-1460505748561-0'
}, {
bidId: '101111',
placementCode: 'div-gpt-ad-1460505748561-1'
}]
});

server.respondWith(JSON.stringify(RESPONSE));

adapter.setConfig(CONFIG);
adapter.callBids(REQUEST);
server.respond();

sinon.assert.calledTwice(bidmanager.addBidResponse);

expect(bidmanager.addBidResponse.firstCall.args[0]).to.equal('div-gpt-ad-1460505748561-0');
expect(bidmanager.addBidResponse.secondCall.args[0]).to.equal('div-gpt-ad-1460505748561-1');

expect(bidmanager.addBidResponse.firstCall.args[1]).to.have.property('adId', '123');
expect(bidmanager.addBidResponse.secondCall.args[1]).to.have.property('adId', '101111');

expect(bidmanager.addBidResponse.firstCall.args[1])
.to.have.property('statusMessage', 'Bid available');
expect(bidmanager.addBidResponse.secondCall.args[1])
.to.have.property('statusMessage', 'Bid returned empty or error response');
});

it('should have dealId in bidObject', () => {
server.respondWith(JSON.stringify(RESPONSE));

Expand Down

0 comments on commit 7cb6ce8

Please sign in to comment.