Skip to content

Commit

Permalink
Fix for #4047 (#4063)
Browse files Browse the repository at this point in the history
* Changed isBidRequestValid to reject bid requests missing required parameters.

* Filter outstream video bid requests.

* Improved detection of different media types. Ignore all media types except instream video and banner.

* Added test to confirm behaviour with multi-format request.

* Removed unnecessary change to bid sizes.

* Removed unused imports and tests.

* Added log message for unsupported media types.
  • Loading branch information
dpapworth-qc authored and jsnellbaker committed Aug 9, 2019
1 parent 6d9f85e commit ecd3815
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 65 deletions.
34 changes: 17 additions & 17 deletions modules/quantcastBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
},

/**
Expand All @@ -112,12 +102,22 @@ 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 => {
let bidRequestsList = [];

bids.forEach(bid => {
let imp;
const videoContext = utils.deepAccess(bid, 'mediaTypes.video.context');
if (videoContext === 'instream') {
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
utils.logInfo(`${BIDDER_CODE}: No supported mediaTypes found in ${JSON.stringify(bid.mediaTypes)}`);
return;
}
} else {
// Parse as banner by default
imp = makeBannerImp(bid);
}

Expand All @@ -143,11 +143,11 @@ export const spec = {
: QUANTCAST_DOMAIN;
const url = `${QUANTCAST_PROTOCOL}://${qcDomain}:${QUANTCAST_PORT}/qchb`;

return {
bidRequestsList.push({
data,
method: 'POST',
url
};
});
});

return bidRequestsList;
Expand Down
131 changes: 83 additions & 48 deletions test/spec/modules/quantcastBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -13,11 +11,11 @@ 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);
let bidRequest;
let bidderRequest;

beforeEach(function () {
bidRequest = {
Expand All @@ -32,6 +30,13 @@ describe('Quantcast adapter', function () {
},
sizes: [[300, 250]]
};

bidderRequest = {
refererInfo: {
referer: 'http://example.com/hello.html',
canonicalUrl: 'http://example.com/hello.html'
}
};
});

function setupVideoBidRequest() {
Expand Down Expand Up @@ -68,27 +73,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);
});
});

Expand Down Expand Up @@ -131,13 +134,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,
Expand Down Expand Up @@ -168,13 +164,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,
Expand Down Expand Up @@ -213,6 +202,69 @@ 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('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 () {
Expand Down Expand Up @@ -354,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();
// });
// });
});

0 comments on commit ecd3815

Please sign in to comment.