Skip to content

Commit

Permalink
refactor mediatype validation functions to minimize mutation of aduni…
Browse files Browse the repository at this point in the history
…t object
  • Loading branch information
Fawke committed Jul 13, 2020
1 parent 2a7cb6f commit 47cd120
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 46 deletions.
89 changes: 51 additions & 38 deletions src/prebid.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,50 +83,58 @@ function validateSizes(sizes, targLength) {
}

function validateBannerMediaType(adUnit) {
const banner = adUnit.mediaTypes.banner;
const validatedAdUnit = utils.deepClone(adUnit);
const banner = validatedAdUnit.mediaTypes.banner;
const bannerSizes = validateSizes(banner.sizes);
if (bannerSizes.length > 0) {
banner.sizes = bannerSizes;
// Deprecation Warning: This property will be deprecated in next release in favor of adUnit.mediaTypes.banner.sizes
adUnit.sizes = bannerSizes;
validatedAdUnit.sizes = bannerSizes;
} else {
utils.logError('Detected a mediaTypes.banner object without a proper sizes field. Please ensure the sizes are listed like: [[300, 250], ...]. Removing invalid mediaTypes.banner object from request.');
delete adUnit.mediaTypes.banner
delete validatedAdUnit.mediaTypes.banner
}
return validatedAdUnit;
}

function validateVideoMediaType(adUnit) {
const video = adUnit.mediaTypes.video;
let tarPlayerSizeLen = (typeof video.playerSize[0] === 'number') ? 2 : 1;

const videoSizes = validateSizes(video.playerSize, tarPlayerSizeLen);
if (videoSizes.length > 0) {
if (tarPlayerSizeLen === 2) {
utils.logInfo('Transforming video.playerSize from [640,480] to [[640,480]] so it\'s in the proper format.');
const validatedAdUnit = utils.deepClone(adUnit);
const video = validatedAdUnit.mediaTypes.video;
if (video.playerSize) {
let tarPlayerSizeLen = (typeof video.playerSize[0] === 'number') ? 2 : 1;

const videoSizes = validateSizes(video.playerSize, tarPlayerSizeLen);
if (videoSizes.length > 0) {
if (tarPlayerSizeLen === 2) {
utils.logInfo('Transforming video.playerSize from [640,480] to [[640,480]] so it\'s in the proper format.');
}
video.playerSize = videoSizes;
// Deprecation Warning: This property will be deprecated in next release in favor of adUnit.mediaTypes.video.playerSize
validatedAdUnit.sizes = videoSizes;
} else {
utils.logError('Detected incorrect configuration of mediaTypes.video.playerSize. Please specify only one set of dimensions in a format like: [[640, 480]]. Removing invalid mediaTypes.video.playerSize property from request.');
delete validatedAdUnit.mediaTypes.video.playerSize;
}
video.playerSize = videoSizes;
// Deprecation Warning: This property will be deprecated in next release in favor of adUnit.mediaTypes.video.playerSize
adUnit.sizes = videoSizes;
} else {
utils.logError('Detected incorrect configuration of mediaTypes.video.playerSize. Please specify only one set of dimensions in a format like: [[640, 480]]. Removing invalid mediaTypes.video.playerSize property from request.');
delete adUnit.mediaTypes.video.playerSize;
}
return validatedAdUnit;
}

function validateNativeMediaType(adUnit) {
const native = adUnit.mediaTypes.native;
const validatedAdUnit = utils.deepClone(adUnit);
const native = validatedAdUnit.mediaTypes.native;
if (native.image && native.image.sizes && !Array.isArray(native.image.sizes)) {
utils.logError('Please use an array of sizes for native.image.sizes field. Removing invalid mediaTypes.native.image.sizes property from request.');
delete adUnit.mediaTypes.native.image.sizes;
delete validatedAdUnit.mediaTypes.native.image.sizes;
}
if (native.image && native.image.aspect_ratios && !Array.isArray(native.image.aspect_ratios)) {
utils.logError('Please use an array of sizes for native.image.aspect_ratios field. Removing invalid mediaTypes.native.image.aspect_ratios property from request.');
delete adUnit.mediaTypes.native.image.aspect_ratios;
delete validatedAdUnit.mediaTypes.native.image.aspect_ratios;
}
if (native.icon && native.icon.sizes && !Array.isArray(native.icon.sizes)) {
utils.logError('Please use an array of sizes for native.icon.sizes field. Removing invalid mediaTypes.native.icon.sizes property from request.');
delete adUnit.mediaTypes.native.icon.sizes;
delete validatedAdUnit.mediaTypes.native.icon.sizes;
}
return validatedAdUnit;
}

export const adUnitSetupChecks = {
Expand All @@ -137,29 +145,34 @@ export const adUnitSetupChecks = {
};

export const checkAdUnitSetup = hook('sync', function (adUnits) {
return adUnits.filter(adUnit => {
const validatedAdUnits = [];

adUnits.forEach(adUnit => {
const mediaTypes = adUnit.mediaTypes;
let validatedBanner, validatedVideo, validatedNative;
if (!mediaTypes || Object.keys(mediaTypes).length === 0) {
utils.logError(`Detected adUnit.code '${adUnit.code}' did not have a 'mediaTypes' object defined. This is a required field for the auction, so this adUnit has been removed.`);
return false;
return;
}

if (mediaTypes.banner) {
validateBannerMediaType(adUnit);
validatedBanner = validateBannerMediaType(adUnit);
}

if (mediaTypes.video) {
const video = mediaTypes.video;
if (video.playerSize) {
validateVideoMediaType(adUnit);
}
validatedVideo = validatedBanner ? validateVideoMediaType(validatedBanner) : validateVideoMediaType(adUnit);
}

if (mediaTypes.native) {
validateNativeMediaType(adUnit);
validatedNative = validatedVideo ? validateNativeMediaType(validatedVideo) : validatedBanner ? validateNativeMediaType(validatedBanner) : validateNativeMediaType(adUnit);
}
return true;

const validatedAdUnit = Object.assign({}, validatedBanner, validatedVideo, validatedNative);

validatedAdUnits.push(validatedAdUnit);
});

return validatedAdUnits;
}, 'checkAdUnitSetup');

/// ///////////////////////////////
Expand Down Expand Up @@ -192,7 +205,7 @@ $$PREBID_GLOBAL$$.getAdserverTargetingForAdUnitCodeStr = function (adunitCode) {
* @alias module:pbjs.getAdserverTargetingForAdUnitCode
* @returns {Object} returnObj return bids
*/
$$PREBID_GLOBAL$$.getAdserverTargetingForAdUnitCode = function(adUnitCode) {
$$PREBID_GLOBAL$$.getAdserverTargetingForAdUnitCode = function (adUnitCode) {
return $$PREBID_GLOBAL$$.getAdserverTargeting(adUnitCode)[adUnitCode];
};

Expand Down Expand Up @@ -300,7 +313,7 @@ $$PREBID_GLOBAL$$.setTargetingForGPTAsync = function (adUnit, customSlotMatching
* @param {(string|string[])} adUnitCode adUnitCode or array of adUnitCodes
* @alias module:pbjs.setTargetingForAst
*/
$$PREBID_GLOBAL$$.setTargetingForAst = function(adUnitCodes) {
$$PREBID_GLOBAL$$.setTargetingForAst = function (adUnitCodes) {
utils.logInfo('Invoking $$PREBID_GLOBAL$$.setTargetingForAn', arguments);
if (!targeting.isApntagDefined()) {
utils.logError('window.apntag is not defined on the page');
Expand Down Expand Up @@ -448,6 +461,8 @@ $$PREBID_GLOBAL$$.requestBids = hook('async', function ({ bidsBackHandler, timeo

utils.logInfo('Invoking $$PREBID_GLOBAL$$.requestBids', arguments);

adUnits = checkAdUnitSetup(adUnits);

if (adUnitCodes && adUnitCodes.length) {
// if specific adUnitCodes supplied filter adUnits for those codes
adUnits = adUnits.filter(unit => includes(adUnitCodes, unit.code));
Expand All @@ -456,8 +471,6 @@ $$PREBID_GLOBAL$$.requestBids = hook('async', function ({ bidsBackHandler, timeo
adUnitCodes = adUnits && adUnits.map(unit => unit.code);
}

adUnits = checkAdUnitSetup(adUnits);

/*
* for a given adunit which supports a set of mediaTypes
* and a given bidder which supports a set of mediaTypes
Expand All @@ -466,7 +479,7 @@ $$PREBID_GLOBAL$$.requestBids = hook('async', function ({ bidsBackHandler, timeo
*/
adUnits.forEach(adUnit => {
// get the adunit's mediaTypes, defaulting to banner if mediaTypes isn't present
const adUnitMediaTypes = Object.keys(adUnit.mediaTypes || {'banner': 'banner'});
const adUnitMediaTypes = Object.keys(adUnit.mediaTypes || { 'banner': 'banner' });

// get the bidder's mediaTypes
const allBidders = adUnit.bids.map(bid => bid.bidder);
Expand Down Expand Up @@ -512,7 +525,7 @@ $$PREBID_GLOBAL$$.requestBids = hook('async', function ({ bidsBackHandler, timeo
return;
}

const auction = auctionManager.createAuction({adUnits, adUnitCodes, callback: bidsBackHandler, cbTimeout, labels, auctionId});
const auction = auctionManager.createAuction({ adUnits, adUnitCodes, callback: bidsBackHandler, cbTimeout, labels, auctionId });

let adUnitsLen = adUnits.length;
if (adUnitsLen > 15) {
Expand Down Expand Up @@ -843,7 +856,7 @@ $$PREBID_GLOBAL$$.que.push(() => listenMessagesFromCreative());
* the Prebid script has been fully loaded.
* @alias module:pbjs.cmd.push
*/
$$PREBID_GLOBAL$$.cmd.push = function(command) {
$$PREBID_GLOBAL$$.cmd.push = function (command) {
if (typeof command === 'function') {
try {
command.call();
Expand All @@ -858,7 +871,7 @@ $$PREBID_GLOBAL$$.cmd.push = function(command) {
$$PREBID_GLOBAL$$.que.push = $$PREBID_GLOBAL$$.cmd.push;

function processQueue(queue) {
queue.forEach(function(cmd) {
queue.forEach(function (cmd) {
if (typeof cmd.called === 'undefined') {
try {
cmd.call();
Expand All @@ -873,7 +886,7 @@ function processQueue(queue) {
/**
* @alias module:pbjs.processQueue
*/
$$PREBID_GLOBAL$$.processQueue = function() {
$$PREBID_GLOBAL$$.processQueue = function () {
hook.ready();
processQueue($$PREBID_GLOBAL$$.que);
processQueue($$PREBID_GLOBAL$$.cmd);
Expand Down
9 changes: 1 addition & 8 deletions test/spec/unit/pbjs_api_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1770,8 +1770,6 @@ describe('Unit: Prebid Module', function () {
});

describe('multiformat requests', function () {
let spyCallBids;
let createAuctionStub;
let adUnits;

beforeEach(function () {
Expand All @@ -1791,14 +1789,10 @@ describe('Unit: Prebid Module', function () {
}];
adUnitCodes = ['adUnit-code'];
configObj.setConfig({maxRequestsPerOrigin: Number.MAX_SAFE_INTEGER || 99999999});
let auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: function() {}, cbTimeout: timeout});
spyCallBids = sinon.spy(adapterManager, 'callBids');
createAuctionStub = sinon.stub(auctionModule, 'newAuction');
createAuctionStub.returns(auction);
sinon.spy(adapterManager, 'callBids');
})

afterEach(function () {
auctionModule.newAuction.restore();
adapterManager.callBids.restore();
});

Expand All @@ -1821,7 +1815,6 @@ describe('Unit: Prebid Module', function () {

const spyArgs = adapterManager.callBids.getCall(0);
const biddersCalled = spyArgs.args[0][0].bids;

// only appnexus supports native
expect(biddersCalled.length).to.equal(1);
});
Expand Down

0 comments on commit 47cd120

Please sign in to comment.