Skip to content

Commit

Permalink
Altering logic to determine if is video bid or not + update tests (#3263
Browse files Browse the repository at this point in the history
)

* Altering logic to determine if is video bid or not + update tests

* Browser compatible int check

* Spelling error fix (deprecated)

* fixing suggestion by isaac
  • Loading branch information
Robert Ray Martinez III authored and harpere committed Nov 6, 2018
1 parent 3b541a3 commit 4153788
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 42 deletions.
78 changes: 50 additions & 28 deletions modules/rubiconBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export const spec = {
name: bidRequest.adUnitCode,
width: size[0],
height: size[1],
size_id: utils.deepAccess(bidRequest, `mediaTypes.${VIDEO}.context`) === 'outstream' ? 203 : params.video.size_id
size_id: determineRubiconVideoSizeId(bidRequest)
};

if (params.video) {
Expand Down Expand Up @@ -573,12 +573,12 @@ function mapSizes(sizes) {

/**
* Test if bid has mediaType or mediaTypes set for video.
* note: 'mediaType' has been deprecated, however support will remain for a transitional period
* Also makes sure the video object is present in the rubicon bidder params
* @param {BidRequest} bidRequest
* @returns {boolean}
*/
export function hasVideoMediaType(bidRequest) {
if (typeof utils.deepAccess(bidRequest, 'params.video') === 'undefined' && Array.isArray(utils.deepAccess(bidRequest, 'params.sizes'))) {
if (typeof utils.deepAccess(bidRequest, 'params.video') !== 'object') {
return false;
}
return (bidRequest.mediaType === VIDEO || typeof utils.deepAccess(bidRequest, `mediaTypes.${VIDEO}`) !== 'undefined');
Expand All @@ -591,43 +591,54 @@ export function hasVideoMediaType(bidRequest) {
* @returns {string|undefined} Returns 'video' or 'banner' if resolves to a type, or undefined otherwise (invalid).
*/
function bidType(bid, log = false) {
let validVideo;
// Is it considered video ad unit by rubicon
if (hasVideoMediaType(bid)) {
validVideo = true;

if (utils.deepAccess(bid, `mediaTypes.${VIDEO}.context`) === 'instream' || bid.mediaType === VIDEO) {
if (typeof utils.deepAccess(bid, 'params.video.size_id') === 'undefined') {
// legacy mediaType or the new mediaTypes
// this is the preffered "new" way to define mediaTypes
if (typeof utils.deepAccess(bid, `mediaTypes.${VIDEO}`) !== 'undefined') {
// We require either context as instream or outstream
if (['outstream', 'instream'].indexOf(utils.deepAccess(bid, `mediaTypes.${VIDEO}.context`)) === -1) {
if (log) {
utils.logError('Rubicon bid adapter Error: size id is missing for instream video request.');
utils.logError('Rubicon bid adapter requires mediaTypes.video.context to be one of outstream or instream');
}
validVideo = false;
return;
}
} else { // Otherwise its the legacy way where mediaType == 'video'
if (log) {
utils.logWarn('Rubicon video bid requested using legacy `adUnit.mediaType = `video``\nThis is deprecated\nPlease move towards the PBJS standard using mediaTypes object!');
}
} else if (utils.deepAccess(bid, `mediaTypes.${VIDEO}.context`) === 'outstream') {
if (utils.deepAccess(bid, 'params.video.size_id') !== 203) {
if (isNaN(parseInt(utils.deepAccess(bid, 'params.video.size_id')))) {
if (log) {
utils.logWarn('Rubicon bid adapter Warning: outstream video is sending invalid size id, converting size id to 203.');
utils.logError('Rubicon bid adapter needs params.video.size_id to be declared and an integer in order to process a legacy video request using mediaType == video');
}
return;
}
} else {
}
// we require playerWidth and playerHeight to come from one of params.playerWidth/playerHeight or mediaTypes.video.playerSize or adUnit.sizes
if (parseSizes(bid, 'video').length < 2) {
if (log) {
utils.logError('Rubicon bid adapter Error: no instream or outstream context defined in mediaTypes.');
utils.logError('Rubicon bid adapter could not determine the playerSize of the video\nplayerWidth and playerHeight are inferred from one of params.playerWidth/playerHeight or mediaTypes.video.playerSize or adUnit.sizes, in that order');
}
validVideo = false;
return;
}
if (validVideo) {
if (typeof utils.deepAccess(bid, `mediaTypes.${BANNER}`) !== 'undefined') {
if (log) {
utils.logWarn('Rubicon bid adapter Warning: video and banner requested for same adUnit, continuing with video request, multi-format request is not supported by rubicon yet.');
}

if (log) {
utils.logMessage('Rubicon bid adapter making video request for adUnit', bid.adUnitCode);
}
return 'video';
} else {
// we require banner sizes to come from one of params.sizes or mediaTypes.banner.sizes or adUnit.sizes, in that order
// if we cannot determine them, we reject it!
if (parseSizes(bid, 'banner').length === 0) {
if (log) {
utils.logError('Rubicon bid adapter could not determine the sizes for a banner request\nThey are inferred from one of params.sizes or mediaTypes.banner.sizes or adUnit.sizes, in that order');
}
return 'video';
} else if (typeof utils.deepAccess(bid, `mediaTypes.${BANNER}`) === 'undefined') {
return undefined;
return;
}
}
if (parseSizes(bid, 'banner').length > 0) {
if (log && validVideo === false) {
utils.logWarn('Rubicon bid adapter Warning: invalid video requested for adUnit, continuing with banner request.');

// everything looks good for banner so lets do it
if (log) {
utils.logMessage('Rubicon bid adapter making banner request for adUnit', bid.adUnitCode);
}
return 'banner';
}
Expand Down Expand Up @@ -656,6 +667,17 @@ export function masSizeOrdering(sizes) {
});
}

export function determineRubiconVideoSizeId(bid) {
// If we have size_id in the bid then use it
let rubiconSizeId = parseInt(utils.deepAccess(bid, 'params.video.size_id'));
if (!isNaN(rubiconSizeId)) {
return rubiconSizeId;
}
// otherwise 203 for outstream and 201 for instream
// When this function is used we know it has to be one of outstream or instream
return utils.deepAccess(bid, `mediaTypes.${VIDEO}.context`) === 'outstream' ? 203 : 201;
}

var hasSynced = false;

export function resetUserSync() {
Expand Down
67 changes: 53 additions & 14 deletions test/spec/modules/rubiconBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1312,29 +1312,37 @@ describe('the rubicon adapter', function () {
expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
});

it('should not validate bid request when a invalid video object and no banner object is passed in', function () {
createVideoBidderRequestNoVideo();
it('should not validate bid request when a params.video object is present but no context instream or outstream is passed in', function () {
let bid = bidderRequest.bids[0];
bid.mediaTypes = {
video: {}
}
bid.params.video = {};

sandbox.stub(Date, 'now').callsFake(() =>
bidderRequest.auctionStart + 100
);

const bidRequestCopy = clone(bidderRequest.bids[0]);
expect(spec.isBidRequestValid(bidRequestCopy)).to.equal(false);

bidRequestCopy.params.video = {};
bidRequestCopy.params.video = {sizeId: 201};
expect(spec.isBidRequestValid(bidRequestCopy)).to.equal(false);

bidRequestCopy.params.video = undefined;
bidRequestCopy.mediaTypes.video = {context: undefined};
expect(spec.isBidRequestValid(bidRequestCopy)).to.equal(false);

bidRequestCopy.params.video = 123;
bidRequestCopy.mediaTypes.video = {context: ''};
expect(spec.isBidRequestValid(bidRequestCopy)).to.equal(false);

bidRequestCopy.params.video = {size_id: undefined};
bidRequestCopy.mediaTypes.video = {context: 'random'};
expect(spec.isBidRequestValid(bidRequestCopy)).to.equal(false);

delete bidRequestCopy.params.video;
expect(spec.isBidRequestValid(bidRequestCopy)).to.equal(false);
bidRequestCopy.mediaTypes.video = {context: 'instream'};
expect(spec.isBidRequestValid(bidRequestCopy)).to.equal(true);

bidRequestCopy.mediaTypes.video = {context: 'outstream'};
expect(spec.isBidRequestValid(bidRequestCopy)).to.equal(true);
});

it('should not validate bid request when an invalid video object is passed in with legacy config mediaType', function () {
Expand All @@ -1344,19 +1352,20 @@ describe('the rubicon adapter', function () {
);

const bidderRequestCopy = clone(bidderRequest);
expect(spec.isBidRequestValid(bidderRequestCopy.bids[0])).to.equal(false);

bidderRequestCopy.bids[0].params.video = {};
expect(spec.isBidRequestValid(bidderRequestCopy.bids[0])).to.equal(false);

bidderRequestCopy.bids[0].params.video = undefined;
bidderRequestCopy.bids[0].params.video = {size_id: undefined};
expect(spec.isBidRequestValid(bidderRequestCopy.bids[0])).to.equal(false);

bidderRequestCopy.bids[0].params.video = NaN;
bidderRequestCopy.bids[0].params.video = {size_id: 'size'};
expect(spec.isBidRequestValid(bidderRequestCopy.bids[0])).to.equal(false);

delete bidderRequestCopy.bids[0].params.video;
expect(spec.isBidRequestValid(bidderRequestCopy.bids[0])).to.equal(false);
bidderRequestCopy.bids[0].params.video = {size_id: '201'};
expect(spec.isBidRequestValid(bidderRequestCopy.bids[0])).to.equal(true);

bidderRequestCopy.bids[0].params.video = {size_id: 201};
expect(spec.isBidRequestValid(bidderRequestCopy.bids[0])).to.equal(true);
});

it('bid request is valid when video context is outstream', function () {
Expand All @@ -1372,6 +1381,36 @@ describe('the rubicon adapter', function () {
expect(request.data.slots[0].size_id).to.equal(203);
});

it('should send banner request when outstream or instream video included but no rubicon video obect is present', function () {
let bid = bidderRequest.bids[0];
// add banner and video mediaTypes
bidderRequest.mediaTypes = {
banner: {
sizes: [[300, 250]]
},
video: {
context: 'outstream'
}
};
// no video object in rubicon params, so we should see one call made for banner

sandbox.stub(Date, 'now').callsFake(() =>
bidderRequest.auctionStart + 100
);

let requests = spec.buildRequests(bidderRequest.bids, bidderRequest);

expect(requests.length).to.equal(1);
expect(requests[0].url).to.equal(FASTLANE_ENDPOINT);

bidderRequest.mediaTypes.video.context = 'instream';

requests = spec.buildRequests(bidderRequest.bids, bidderRequest);

expect(requests.length).to.equal(1);
expect(requests[0].url).to.equal(FASTLANE_ENDPOINT);
});

it('should send request as banner when invalid video bid in multiple mediaType bidRequest', function () {
createVideoBidderRequestNoVideo();

Expand Down

0 comments on commit 4153788

Please sign in to comment.