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

Quantcast Bid Adapter: uses video mediatypes to read OpenRTB parameters #6932

Merged
merged 4 commits into from
Jun 8, 2021
Merged
Show file tree
Hide file tree
Changes from 3 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
38 changes: 14 additions & 24 deletions modules/quantcastBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const DEFAULT_BID_FLOOR = 0.0000000001;
const QUANTCAST_VENDOR_ID = '11';
// Check other required purposes on server
const PURPOSE_DATA_COLLECT = '1';
const VIDEO_PROPS_TO_REMOVE = ['context', 'playerSize'];

export const QUANTCAST_DOMAIN = 'qcx.quantserve.com';
export const QUANTCAST_TEST_DOMAIN = 's2s-canary.quantserve.com';
Expand All @@ -24,31 +25,20 @@ export const QUANTCAST_FPA = '__qca';
export const storage = getStorageManager(QUANTCAST_VENDOR_ID, BIDDER_CODE);

function makeVideoImp(bid) {
const video = {};
if (bid.params.video) {
video['mimes'] = bid.params.video.mimes;
video['minduration'] = bid.params.video.minduration;
video['maxduration'] = bid.params.video.maxduration;
video['protocols'] = bid.params.video.protocols;
video['startdelay'] = bid.params.video.startdelay;
video['linearity'] = bid.params.video.linearity;
video['battr'] = bid.params.video.battr;
video['maxbitrate'] = bid.params.video.maxbitrate;
video['playbackmethod'] = bid.params.video.playbackmethod;
video['delivery'] = bid.params.video.delivery;
video['placement'] = bid.params.video.placement;
video['api'] = bid.params.video.api;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not keep this block so either place populates it? I think this is why your tests are failing

if (bid.mediaTypes.video.mimes) {
video['mimes'] = bid.mediaTypes.video.mimes;
const videoInMediaType = utils.deepAccess(bid, 'mediaTypes.video') || {};
const videoInParams = utils.deepAccess(bid, 'params.video') || {};
const video = Object.assign({}, videoInParams, videoInMediaType);

if (video.playerSize) {
video.w = video.playerSize[0];
video.h = video.playerSize[1];
}
if (utils.isArray(bid.mediaTypes.video.playerSize[0])) {
video['w'] = bid.mediaTypes.video.playerSize[0][0];
video['h'] = bid.mediaTypes.video.playerSize[0][1];
} else {
video['w'] = bid.mediaTypes.video.playerSize[0];
video['h'] = bid.mediaTypes.video.playerSize[1];
for (const prop of VIDEO_PROPS_TO_REMOVE) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a bit of a nit-pick - would it make more sense to have an allow list of properties rather than a block list? otherwise the video object on mediaTypes or params could introduce new properties and we wouldn't filter them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

if (video.hasOwnProperty(prop)) {
delete video[prop];
}
}

return {
video: video,
placementCode: bid.placementCode,
Expand Down Expand Up @@ -270,9 +260,9 @@ export const spec = {
if (dealId !== undefined && dealId) {
result['dealId'] = dealId;
}
result.meta = {};

if (meta !== undefined && meta.advertiserDomains && utils.isArray(meta.advertiserDomains)) {
result.meta = {};
result.meta.advertiserDomains = meta.advertiserDomains;
}

Expand Down
83 changes: 75 additions & 8 deletions test/spec/modules/quantcastBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,15 @@ describe('Quantcast adapter', function () {
storage.setCookie('__qca', '', 'Thu, 01 Jan 1970 00:00:00 GMT');
});

function setupVideoBidRequest(videoParams) {
function setupVideoBidRequest(videoParams, mediaTypesParams) {
bidRequest.params = {
publisherId: 'test-publisher', // REQUIRED - Publisher ID provided by Quantcast
// Video object as specified in OpenRTB 2.5
video: videoParams
};
bidRequest['mediaTypes'] = {
video: {
context: 'instream',
playerSize: [600, 300]
if (mediaTypesParams) {
bidRequest['mediaTypes'] = {
video: mediaTypesParams
}
}
};
Expand Down Expand Up @@ -175,6 +174,69 @@ describe('Quantcast adapter', function () {
delivery: [1], // optional
placement: 1, // optional
api: [2, 3] // optional
}, {
context: 'instream',
playerSize: [600, 300]
});

const requests = qcSpec.buildRequests([bidRequest], bidderRequest);
const expectedVideoBidRequest = {
publisherId: QUANTCAST_TEST_PUBLISHER,
requestId: '2f7b179d443f14',
imp: [
{
video: {
mimes: ['video/mp4'],
minduration: 3,
maxduration: 5,
protocols: [3],
startdelay: 1,
linearity: 1,
battr: [1, 2],
maxbitrate: 10,
playbackmethod: [1],
delivery: [1],
placement: 1,
api: [2, 3],
w: 600,
h: 300
},
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,
uspSignal: 0,
coppa: 0,
prebidJsVersion: '$prebid.version$',
fpa: ''
};

expect(requests[0].data).to.equal(JSON.stringify(expectedVideoBidRequest));
});

it('sends video bid requests containing all the required parameters from mediaTypes', function() {
setupVideoBidRequest(null, {
mimes: ['video/mp4'], // required
minduration: 3, // optional
maxduration: 5, // optional
protocols: [3], // optional
startdelay: 1, // optional
linearity: 1, // optinal
battr: [1, 2], // optional
maxbitrate: 10, // optional
playbackmethod: [1], // optional
delivery: [1], // optional
placement: 1, // optional
api: [2, 3], // optional
context: 'instream',
playerSize: [600, 300]
});

const requests = qcSpec.buildRequests([bidRequest], bidderRequest);
Expand Down Expand Up @@ -222,6 +284,9 @@ describe('Quantcast adapter', function () {
it('overrides video parameters with parameters from adunit', function() {
setupVideoBidRequest({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test looks good as is, it has two different values for mimes and you're testing the ad unit wins.

mimes: ['video/mp4']
}, {
context: 'instream',
playerSize: [600, 300]
});
bidRequest.mediaTypes.video.mimes = ['video/webm'];

Expand Down Expand Up @@ -257,7 +322,10 @@ describe('Quantcast adapter', function () {
});

it('sends video bid request when no video parameters are given', function () {
setupVideoBidRequest(null);
setupVideoBidRequest(null, {
context: 'instream',
playerSize: [600, 300]
});

const requests = qcSpec.buildRequests([bidRequest], bidderRequest);
const expectedVideoBidRequest = {
Expand Down Expand Up @@ -766,8 +834,7 @@ describe('Quantcast adapter', function () {
creativeId: undefined,
ad: undefined,
netRevenue: QUANTCAST_NET_REVENUE,
currency: 'USD',
meta: {}
currency: 'USD'
};
const interpretedResponse = qcSpec.interpretResponse(videoResponse);

Expand Down