From 0dfa61743859ae9fab4ea8eb663e9ae6c4d3f0d8 Mon Sep 17 00:00:00 2001 From: dpapworth-qc Date: Mon, 5 Aug 2019 14:52:59 +0100 Subject: [PATCH 1/7] Changed isBidRequestValid to reject bid requests missing required parameters. --- modules/quantcastBidAdapter.js | 12 +-------- test/spec/modules/quantcastBidAdapter_spec.js | 26 +++++++++---------- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/modules/quantcastBidAdapter.js b/modules/quantcastBidAdapter.js index 64cec7e231a..68cd97393dc 100644 --- a/modules/quantcastBidAdapter.js +++ b/modules/quantcastBidAdapter.js @@ -83,17 +83,7 @@ export const spec = { * @return boolean `true` is this is a valid bid, and `false` otherwise */ isBidRequestValid(bid) { - if (!bid) { - return false; - } - - const videoMediaType = utils.deepAccess(bid, 'mediaTypes.video'); - const context = utils.deepAccess(bid, 'mediaTypes.video.context'); - if (videoMediaType && context == 'outstream') { - return false; - } - - return true; + return !!bid.params.publisherId; }, /** diff --git a/test/spec/modules/quantcastBidAdapter_spec.js b/test/spec/modules/quantcastBidAdapter_spec.js index 662641de17b..caa1c1a1309 100644 --- a/test/spec/modules/quantcastBidAdapter_spec.js +++ b/test/spec/modules/quantcastBidAdapter_spec.js @@ -68,27 +68,25 @@ describe('Quantcast adapter', function () { }); describe('`isBidRequestValid`', function () { - it('should return `false` when bid is not passed', function () { - expect(qcSpec.isBidRequestValid()).to.equal(false); - }); - - it('should return `false` when bid is for outstream video', function () { + it('should return `true` when bid has publisherId', function () { const bidRequest = { - mediaType: 'video', - mediaTypes: { - video: { - context: 'outstream' - } + bidder: 'quantcast', + params: { + publisherId: 'my_publisher_id' } }; - expect(qcSpec.isBidRequestValid(bidRequest)).to.equal(false); + expect(qcSpec.isBidRequestValid(bidRequest)).to.equal(true); }); - it('should return `true` when bid contains required params', function () { - const bidRequest = { mediaType: 'banner' }; + it('should return `false` when bid has no publisherId', function () { + const bidRequest = { + bidder: 'quantcast', + params: { + } + }; - expect(qcSpec.isBidRequestValid(bidRequest)).to.equal(true); + expect(qcSpec.isBidRequestValid(bidRequest)).to.equal(false); }); }); From 7ff6d85294435a889c0ff118d94e0cdd18527d13 Mon Sep 17 00:00:00 2001 From: dpapworth-qc Date: Mon, 5 Aug 2019 15:00:18 +0100 Subject: [PATCH 2/7] Filter outstream video bid requests. --- modules/quantcastBidAdapter.js | 8 +++-- test/spec/modules/quantcastBidAdapter_spec.js | 35 +++++++++++-------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/modules/quantcastBidAdapter.js b/modules/quantcastBidAdapter.js index 68cd97393dc..302c80a564e 100644 --- a/modules/quantcastBidAdapter.js +++ b/modules/quantcastBidAdapter.js @@ -102,10 +102,12 @@ export const spec = { const page = utils.deepAccess(bidderRequest, 'refererInfo.canonicalUrl') || config.getConfig('pageUrl') || utils.deepAccess(window, 'location.href'); const domain = getDomain(page); - const bidRequestsList = bids.map(bid => { + const bidRequestsList = bids.filter(bid => { + // Filter outstream video + return utils.deepAccess(bid, 'mediaTypes.video.context') !== 'outstream'; + }).map(bid => { let imp; - const videoContext = utils.deepAccess(bid, 'mediaTypes.video.context'); - if (videoContext === 'instream') { + if (utils.deepAccess(bid, 'mediaTypes.video')) { imp = makeVideoImp(bid); } else { imp = makeBannerImp(bid); diff --git a/test/spec/modules/quantcastBidAdapter_spec.js b/test/spec/modules/quantcastBidAdapter_spec.js index caa1c1a1309..10b523dc56d 100644 --- a/test/spec/modules/quantcastBidAdapter_spec.js +++ b/test/spec/modules/quantcastBidAdapter_spec.js @@ -18,6 +18,7 @@ import * as ajax from 'src/ajax'; describe('Quantcast adapter', function () { const quantcastAdapter = newBidder(qcSpec); let bidRequest; + let bidderRequest; beforeEach(function () { bidRequest = { @@ -32,6 +33,13 @@ describe('Quantcast adapter', function () { }, sizes: [[300, 250]] }; + + bidderRequest = { + refererInfo: { + referer: 'http://example.com/hello.html', + canonicalUrl: 'http://example.com/hello.html' + } + }; }); function setupVideoBidRequest() { @@ -129,13 +137,6 @@ describe('Quantcast adapter', function () { }); it('sends banner bid requests contains all the required parameters', function () { - const bidderRequest = { - refererInfo: { - referer: 'http://example.com/hello.html', - canonicalUrl: 'http://example.com/hello.html' - } - }; - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); const expectedBannerBidRequest = { publisherId: QUANTCAST_TEST_PUBLISHER, @@ -166,13 +167,6 @@ describe('Quantcast adapter', function () { it('sends video bid requests containing all the required parameters', function () { setupVideoBidRequest(); - const bidderRequest = { - refererInfo: { - referer: 'http://example.com/hello.html', - canonicalUrl: 'http://example.com/hello.html' - } - }; - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); const expectedVideoBidRequest = { publisherId: QUANTCAST_TEST_PUBLISHER, @@ -211,6 +205,19 @@ describe('Quantcast adapter', function () { expect(requests[0].data).to.equal(JSON.stringify(expectedVideoBidRequest)); }); + + it('ignores unsupported video bid requests', function () { + bidRequest.mediaTypes = { + video: { + context: 'outstream', + playerSize: [[550, 310]] + } + }; + + const requests = qcSpec.buildRequests([bidRequest], bidderRequest); + + expect(requests).to.be.empty; + }); }); it('propagates GDPR consent string and signal', function () { From d958e1b64b1664ad10799a558fd328652a08cb84 Mon Sep 17 00:00:00 2001 From: dpapworth-qc Date: Mon, 5 Aug 2019 17:41:39 +0100 Subject: [PATCH 3/7] Improved detection of different media types. Ignore all media types except instream video and banner. --- modules/quantcastBidAdapter.js | 42 ++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/modules/quantcastBidAdapter.js b/modules/quantcastBidAdapter.js index 302c80a564e..270faae1f1d 100644 --- a/modules/quantcastBidAdapter.js +++ b/modules/quantcastBidAdapter.js @@ -20,15 +20,22 @@ export const QUANTCAST_PORT = ? '8080' : '8443'; -function extractBidSizes(bid) { +function extractBidSizes(sizes) { const bidSizes = []; - bid.sizes.forEach(size => { + if (utils.isArray(sizes[0])) { + sizes.forEach(size => { + bidSizes.push({ + width: size[0], + height: size[1] + }); + }); + } else { bidSizes.push({ - width: size[0], - height: size[1] + width: sizes[0], + height: sizes[1] }); - }); + } return bidSizes; } @@ -53,7 +60,7 @@ function makeBannerImp(bid) { return { banner: { battr: bid.params.battr, - sizes: extractBidSizes(bid), + sizes: extractBidSizes(bid.sizes), }, placementCode: bid.placementCode, bidFloor: bid.params.bidFloor || DEFAULT_BID_FLOOR @@ -102,14 +109,21 @@ export const spec = { const page = utils.deepAccess(bidderRequest, 'refererInfo.canonicalUrl') || config.getConfig('pageUrl') || utils.deepAccess(window, 'location.href'); const domain = getDomain(page); - const bidRequestsList = bids.filter(bid => { - // Filter outstream video - return utils.deepAccess(bid, 'mediaTypes.video.context') !== 'outstream'; - }).map(bid => { + let bidRequestsList = []; + + bids.forEach(bid => { let imp; - if (utils.deepAccess(bid, 'mediaTypes.video')) { - imp = makeVideoImp(bid); + if (bid.mediaTypes) { + if (bid.mediaTypes.video && bid.mediaTypes.video.context === 'instream') { + imp = makeVideoImp(bid); + } else if (bid.mediaTypes.banner) { + imp = makeBannerImp(bid); + } else { + // Unsupported mediaType + return; + } } else { + // Parse as banner by default imp = makeBannerImp(bid); } @@ -135,11 +149,11 @@ export const spec = { : QUANTCAST_DOMAIN; const url = `${QUANTCAST_PROTOCOL}://${qcDomain}:${QUANTCAST_PORT}/qchb`; - return { + bidRequestsList.push({ data, method: 'POST', url - }; + }); }); return bidRequestsList; From 46c734c4bcccd6566e424cceeb5c21f3618a5417 Mon Sep 17 00:00:00 2001 From: dpapworth-qc Date: Mon, 5 Aug 2019 18:34:38 +0100 Subject: [PATCH 4/7] Added test to confirm behaviour with multi-format request. --- test/spec/modules/quantcastBidAdapter_spec.js | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/test/spec/modules/quantcastBidAdapter_spec.js b/test/spec/modules/quantcastBidAdapter_spec.js index 10b523dc56d..4957ecee4e5 100644 --- a/test/spec/modules/quantcastBidAdapter_spec.js +++ b/test/spec/modules/quantcastBidAdapter_spec.js @@ -218,6 +218,56 @@ describe('Quantcast adapter', function () { expect(requests).to.be.empty; }); + + it('parses multi-format bid request', function () { + bidRequest.mediaTypes = { + banner: {sizes: [[300, 250], [728, 90], [250, 250], [468, 60], [320, 50]]}, + native: { + image: {required: true, sizes: [150, 50]}, + title: {required: true, len: 80}, + sponsoredBy: {required: true}, + clickUrl: {required: true}, + privacyLink: {required: false}, + body: {required: true}, + icon: {required: true, sizes: [50, 50]} + }, + video: { + context: 'outstream', + playerSize: [[550, 310]] + } + }; + bidRequest.sizes = [[300, 250], [728, 90], [250, 250], [468, 60], [320, 50]]; + + const requests = qcSpec.buildRequests([bidRequest], bidderRequest); + const expectedBidRequest = { + publisherId: QUANTCAST_TEST_PUBLISHER, + requestId: '2f7b179d443f14', + imp: [{ + banner: { + battr: [1, 2], + sizes: [ + {width: 300, height: 250}, + {width: 728, height: 90}, + {width: 250, height: 250}, + {width: 468, height: 60}, + {width: 320, height: 50} + ] + }, + placementCode: 'div-gpt-ad-1438287399331-0', + bidFloor: 1e-10 + }], + site: { + page: 'http://example.com/hello.html', + referrer: 'http://example.com/hello.html', + domain: 'example.com' + }, + bidId: '2f7b179d443f14', + gdprSignal: 0, + prebidJsVersion: '$prebid.version$' + }; + + expect(requests[0].data).to.equal(JSON.stringify(expectedBidRequest)); + }); }); it('propagates GDPR consent string and signal', function () { From ffce7521f961cbfc031d80abc31f5f5930b7ac8e Mon Sep 17 00:00:00 2001 From: dpapworth-qc Date: Tue, 6 Aug 2019 09:21:03 +0100 Subject: [PATCH 5/7] Removed unnecessary change to bid sizes. --- modules/quantcastBidAdapter.js | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/modules/quantcastBidAdapter.js b/modules/quantcastBidAdapter.js index 270faae1f1d..5ce331f77e0 100644 --- a/modules/quantcastBidAdapter.js +++ b/modules/quantcastBidAdapter.js @@ -20,22 +20,15 @@ export const QUANTCAST_PORT = ? '8080' : '8443'; -function extractBidSizes(sizes) { +function extractBidSizes(bid) { const bidSizes = []; - if (utils.isArray(sizes[0])) { - sizes.forEach(size => { - bidSizes.push({ - width: size[0], - height: size[1] - }); - }); - } else { + bid.sizes.forEach(size => { bidSizes.push({ - width: sizes[0], - height: sizes[1] + width: size[0], + height: size[1] }); - } + }); return bidSizes; } @@ -60,7 +53,7 @@ function makeBannerImp(bid) { return { banner: { battr: bid.params.battr, - sizes: extractBidSizes(bid.sizes), + sizes: extractBidSizes(bid), }, placementCode: bid.placementCode, bidFloor: bid.params.bidFloor || DEFAULT_BID_FLOOR From 6f2a5178af70487fa2e9c6d3b3752534dd12a8d9 Mon Sep 17 00:00:00 2001 From: dpapworth-qc Date: Tue, 6 Aug 2019 14:40:46 +0100 Subject: [PATCH 6/7] Removed unused imports and tests. --- test/spec/modules/quantcastBidAdapter_spec.js | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/test/spec/modules/quantcastBidAdapter_spec.js b/test/spec/modules/quantcastBidAdapter_spec.js index 4957ecee4e5..e29a12a22be 100644 --- a/test/spec/modules/quantcastBidAdapter_spec.js +++ b/test/spec/modules/quantcastBidAdapter_spec.js @@ -1,6 +1,4 @@ -import * as utils from 'src/utils'; import { expect } from 'chai'; -import { stub, sandbox } from 'sinon'; import { QUANTCAST_DOMAIN, QUANTCAST_TEST_DOMAIN, @@ -13,7 +11,6 @@ import { } from '../../../modules/quantcastBidAdapter'; import { newBidder } from '../../../src/adapters/bidderFactory'; import { parse } from 'src/url'; -import * as ajax from 'src/ajax'; describe('Quantcast adapter', function () { const quantcastAdapter = newBidder(qcSpec); @@ -409,26 +406,9 @@ describe('Quantcast adapter', function () { body, headers: {} }; - const expectedResponse = []; const interpretedResponse = qcSpec.interpretResponse(response); expect(interpretedResponse.length).to.equal(0); }); }); - - // can't stub ajax with es6 anymore, need to fix this - // describe('`onTimeout`', function() { - // it('makes a request to the notify endpoint', function() { - // const sinonSandbox = sandbox.create(); - // const ajaxStub = sinonSandbox.stub(ajax, 'ajax').callsFake(function() {}); - // const timeoutData = { - // bidder: 'quantcast' - // }; - // qcSpec.onTimeout(timeoutData); - // const expectedUrl = `${QUANTCAST_PROTOCOL}://${QUANTCAST_DOMAIN}:${QUANTCAST_PORT}/qchb_notify?type=timeout`; - // ajaxStub.withArgs(expectedUrl, null, null).calledOnce.should.be.true; - // ajaxStub.restore(); - // sinonSandbox.restore(); - // }); - // }); }); From f8b3f3b6a48c92872cf4654a9481a45f1a52aafe Mon Sep 17 00:00:00 2001 From: dpapworth-qc Date: Thu, 8 Aug 2019 17:00:21 +0100 Subject: [PATCH 7/7] Added log message for unsupported media types. --- modules/quantcastBidAdapter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/quantcastBidAdapter.js b/modules/quantcastBidAdapter.js index 5ce331f77e0..afe95ffb832 100644 --- a/modules/quantcastBidAdapter.js +++ b/modules/quantcastBidAdapter.js @@ -113,6 +113,7 @@ export const spec = { imp = makeBannerImp(bid); } else { // Unsupported mediaType + utils.logInfo(`${BIDDER_CODE}: No supported mediaTypes found in ${JSON.stringify(bid.mediaTypes)}`); return; } } else {