From 7cb6ce84c2125e520a95153c407497e564c379c2 Mon Sep 17 00:00:00 2001 From: Dmitriy Shashkin Date: Wed, 14 Jun 2017 17:51:08 +0300 Subject: [PATCH] Generate no-bid response for ech bid request not matched by a bid (#1216) --- src/adapters/prebidServer.js | 41 +++++++++------------ test/spec/adapters/prebidServer_spec.js | 49 ++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/adapters/prebidServer.js b/src/adapters/prebidServer.js index e229da9b33f..5dc78008060 100644 --- a/src/adapters/prebidServer.js +++ b/src/adapters/prebidServer.js @@ -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); @@ -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 diff --git a/test/spec/adapters/prebidServer_spec.js b/test/spec/adapters/prebidServer_spec.js index abc3525a8f4..fe1cb7e9894 100644 --- a/test/spec/adapters/prebidServer_spec.js +++ b/test/spec/adapters/prebidServer_spec.js @@ -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', () => { @@ -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); @@ -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); @@ -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); @@ -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));