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

ozone adapter - minor fix to add w/h to video requests #3953

Merged
merged 3 commits into from
Jul 19, 2019
Merged
Show file tree
Hide file tree
Changes from all 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
91 changes: 82 additions & 9 deletions modules/ozoneBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const OZONEURI = 'https://elb.the-ozone-project.com/openrtb2/auction';
const OZONECOOKIESYNC = 'https://elb.the-ozone-project.com/static/load-cookie.html';
const OZONE_RENDERER_URL = 'https://prebid.the-ozone-project.com/ozone-renderer.js';

const OZONEVERSION = '2.1.1';
const OZONEVERSION = '2.1.2';

export const spec = {
code: BIDDER_CODE,
Expand Down Expand Up @@ -65,11 +65,11 @@ export const spec = {
}
if (bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(VIDEO)) {
if (!bid.mediaTypes.video.hasOwnProperty('context')) {
utils.logInfo('OZONE: [WARNING] No context key/value in bid. Rejecting bid: ', ozoneBidRequest);
utils.logInfo('OZONE: [WARNING] No context key/value in bid. Rejecting bid: ', bid);
return false;
}
if (bid.mediaTypes.video.context !== 'outstream') {
utils.logInfo('OZONE: [WARNING] Only outstream video is supported. Rejecting bid: ', ozoneBidRequest);
utils.logInfo('OZONE: [WARNING] Only outstream video is supported. Rejecting bid: ', bid);
return false;
}
}
Expand Down Expand Up @@ -134,10 +134,24 @@ export const spec = {
arrBannerSizes = ozoneBidRequest.mediaTypes[BANNER].sizes; /* Note - if there is a sizes element in the config root it will be pushed into here */
utils.logInfo('OZONE: setting banner size from the mediaTypes.banner element for bidId ' + obj.id + ': ', arrBannerSizes);
}
// Video integration is not complete yet
if (ozoneBidRequest.mediaTypes.hasOwnProperty(VIDEO)) {
obj.video = ozoneBidRequest.mediaTypes[VIDEO];
utils.logInfo('OZONE: setting video object from the mediaTypes.video element: ' + obj.id + ':', obj.video);
// we need to duplicate some of the video values
let wh = getWidthAndHeightFromVideoObject(obj.video);
utils.logInfo('OZONE: setting video object from the mediaTypes.video element: ' + obj.id + ':', obj.video, 'wh=', wh);
if (wh && typeof wh === 'object') {
obj.video.w = wh['w'];
obj.video.h = wh['h'];
if (playerSizeIsNestedArray(obj.video)) { // this should never happen; it was in the original spec for this change though.
utils.logInfo('OZONE: setting obj.video.format to be an array of objects');
obj.video.format = [wh];
} else {
utils.logInfo('OZONE: setting obj.video.format to be an object');
obj.video.format = wh;
}
} else {
utils.logInfo('OZONE: cannot set w, h & format values for video; the config is not right');
}
}
// Native integration is not complete yet
if (ozoneBidRequest.mediaTypes.hasOwnProperty(NATIVE)) {
Expand Down Expand Up @@ -319,7 +333,7 @@ export function checkDeepArray(Arr) {
}
export function defaultSize(thebidObj) {
if (!thebidObj) {
utils.logInfo('defaultSize received empty bid obj! going to return fixed default size');
utils.logInfo('OZONE: defaultSize received empty bid obj! going to return fixed default size');
return {
'defaultHeight': 250,
'defaultWidth': 300
Expand Down Expand Up @@ -389,14 +403,14 @@ export function getRoundedBid(price, mediaType) {
let theConfigObject = getGranularityObject(mediaType, mediaTypeGranularity, strBuckets, objBuckets);
let theConfigKey = getGranularityKeyName(mediaType, mediaTypeGranularity, strBuckets);

utils.logInfo('getRoundedBid. price:', price, 'mediaType:', mediaType, 'configkey:', theConfigKey, 'configObject:', theConfigObject, 'mediaTypeGranularity:', mediaTypeGranularity, 'strBuckets:', strBuckets);
utils.logInfo('OZONE: getRoundedBid. price:', price, 'mediaType:', mediaType, 'configkey:', theConfigKey, 'configObject:', theConfigObject, 'mediaTypeGranularity:', mediaTypeGranularity, 'strBuckets:', strBuckets);

let priceStringsObj = getPriceBucketString(
price,
theConfigObject,
config.getConfig('currency.granularityMultiplier')
);
utils.logInfo('priceStringsObj', priceStringsObj);
utils.logInfo('OZONE: priceStringsObj', priceStringsObj);
// by default, without any custom granularity set, you get granularity name : 'medium'
let granularityNamePriceStringsKeyMapping = {
'medium': 'med',
Expand Down Expand Up @@ -526,9 +540,68 @@ function outstreamRender(bid) {
function toFlatArray(obj) {
let ret = [];
Object.keys(obj).forEach(function(key) { if (obj[key]) { ret.push(parseInt(key)); } });
utils.logInfo('toFlatArray:', obj, 'returning', ret);
utils.logInfo('OZONE: toFlatArray:', obj, 'returning', ret);
return ret;
}

/**
*
* @param objVideo will be like {"playerSize":[640,480],"mimes":["video/mp4"],"context":"outstream"} or POSSIBLY {"playerSize":[[640,480]],"mimes":["video/mp4"],"context":"outstream"}
* @return object {w,h} or null
*/
export function getWidthAndHeightFromVideoObject(objVideo) {
let playerSize = getPlayerSizeFromObject(objVideo);
if (!playerSize) {
return null;
}
if (playerSize[0] && typeof playerSize[0] === 'object') {
utils.logInfo('OZONE: getWidthAndHeightFromVideoObject found nested array inside playerSize.', playerSize[0]);
playerSize = playerSize[0];
if (typeof playerSize[0] !== 'number' && typeof playerSize[0] !== 'string') {
utils.logInfo('OZONE: getWidthAndHeightFromVideoObject found non-number/string type inside the INNER array in playerSize. This is totally wrong - cannot continue.', playerSize[0]);
return null;
}
}
if (playerSize.length !== 2) {
utils.logInfo('OZONE: getWidthAndHeightFromVideoObject found playerSize with length of ' + playerSize.length + '. This is totally wrong - cannot continue.');
return null;
}
return ({'w': playerSize[0], 'h': playerSize[1]});
}

/**
* @param objVideo will be like {"playerSize":[640,480],"mimes":["video/mp4"],"context":"outstream"} or POSSIBLY {"playerSize":[[640,480]],"mimes":["video/mp4"],"context":"outstream"}
* @return object {w,h} or null
*/
export function playerSizeIsNestedArray(objVideo) {
let playerSize = getPlayerSizeFromObject(objVideo);
if (!playerSize) {
return null;
}
if (playerSize.length < 1) {
return null;
}
return (playerSize[0] && typeof playerSize[0] === 'object');
}

/**
* Common functionality when looking at a video object, to get the playerSize
* @param objVideo
* @returns {*}
*/
function getPlayerSizeFromObject(objVideo) {
utils.logInfo('OZONE: getPlayerSizeFromObject received object', objVideo);
if (!objVideo.hasOwnProperty('playerSize')) {
utils.logError('OZONE: getPlayerSizeFromObject FAILED: no playerSize in video object', objVideo);
return null;
}
let playerSize = objVideo.playerSize;
if (typeof playerSize !== 'object') {
utils.logError('OZONE: getPlayerSizeFromObject FAILED: playerSize is not an object/array', objVideo);
return null;
}
return playerSize;
}

registerBidder(spec);
utils.logInfo('OZONE: ozoneBidAdapter ended');
89 changes: 85 additions & 4 deletions test/spec/modules/ozoneBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from 'chai';
import { spec } from 'modules/ozoneBidAdapter';
import { spec, getWidthAndHeightFromVideoObject, playerSizeIsNestedArray, defaultSize } from 'modules/ozoneBidAdapter';
import { config } from 'src/config';
import {Renderer} from '../../../src/Renderer';
const OZONEURI = 'https://elb.the-ozone-project.com/openrtb2/auction';
Expand Down Expand Up @@ -74,7 +74,7 @@ var validBidRequestsWithNonBannerMediaTypesAndValidOutstreamVideo = [
bidderRequestId: '1c1586b27a1b5c8',
crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'},
params: { publisherId: '9876abcd12-3', customData: {'gender': 'bart', 'age': 'low'}, lotameData: {'Profile': {'tpid': 'c8ef27a0d4ba771a81159f0d2e792db4', 'Audiences': {'Audience': [{'id': '99999', 'abbr': 'sports'}, {'id': '88888', 'abbr': 'movie'}, {'id': '77777', 'abbr': 'blogger'}], 'ThirdPartyAudience': [{'id': '123', 'name': 'Automobiles'}, {'id': '456', 'name': 'Ages: 30-39'}]}}}, placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, video: {skippable: true, playback_method: ['auto_play_sound_off'], targetDiv: 'some-different-div-id-to-my-adunitcode'} } ] },
mediaTypes: {video: {mimes: ['video/mp4'], 'context': 'outstream'}, native: {info: 'dummy data'}},
mediaTypes: {video: {mimes: ['video/mp4'], 'context': 'outstream', 'sizes': [640, 480]}, native: {info: 'dummy data'}},
transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
}
];
Expand Down Expand Up @@ -664,7 +664,7 @@ describe('ozone Adapter', function () {
params: {
'placementId': '1234567890',
'publisherId': '9876abcd12-3',
'lotameData': 'this should be an object',
'lotameData': {},
siteId: '1234567890'
},
mediaTypes: {
Expand All @@ -678,6 +678,24 @@ describe('ozone Adapter', function () {
expect(spec.isBidRequestValid(xBadVideoContext)).to.equal(false);
});

var xBadVideoContext2 = {
bidder: BIDDER_CODE,
params: {
'placementId': '1234567890',
'publisherId': '9876abcd12-3',
'lotameData': {},
siteId: '1234567890'
},
mediaTypes: {
video: {
mimes: ['video/mp4']}
}
};

it('should not validate video without context attribute', function () {
expect(spec.isBidRequestValid(xBadVideoContext2)).to.equal(false);
});

let validVideoBidReq = {
bidder: BIDDER_CODE,
params: {
Expand All @@ -692,7 +710,7 @@ describe('ozone Adapter', function () {
}
};

it('should not validate video instream being sent', function () {
it('should validate video outstream being sent', function () {
expect(spec.isBidRequestValid(validVideoBidReq)).to.equal(true);
});
});
Expand Down Expand Up @@ -908,4 +926,67 @@ describe('ozone Adapter', function () {
expect(result).to.be.empty;
});
});

describe('video object utils', function () {
it('should find width & height from video object', function () {
let obj = {'playerSize': [640, 480], 'mimes': ['video/mp4'], 'context': 'outstream'};
const result = getWidthAndHeightFromVideoObject(obj);
expect(result.w).to.equal(640);
expect(result.h).to.equal(480);
});
it('should find null from bad video object', function () {
let obj = {'playerSize': [], 'mimes': ['video/mp4'], 'context': 'outstream'};
const result = getWidthAndHeightFromVideoObject(obj);
expect(result).to.be.null;
});
it('should find null from bad video object2', function () {
let obj = {'mimes': ['video/mp4'], 'context': 'outstream'};
const result = getWidthAndHeightFromVideoObject(obj);
expect(result).to.be.null;
});
it('should find null from bad video object3', function () {
let obj = {'playerSize': 'should be an array', 'mimes': ['video/mp4'], 'context': 'outstream'};
const result = getWidthAndHeightFromVideoObject(obj);
expect(result).to.be.null;
});
it('should find that player size is nested', function () {
let obj = {'playerSize': [[640, 480]], 'mimes': ['video/mp4'], 'context': 'outstream'};
const result = getWidthAndHeightFromVideoObject(obj);
expect(result.w).to.equal(640);
expect(result.h).to.equal(480);
});
it('should fail if player size is 2 x nested', function () {
let obj = {'playerSize': [[[640, 480]]], 'mimes': ['video/mp4'], 'context': 'outstream'};
const result = getWidthAndHeightFromVideoObject(obj);
expect(result).to.be.null;
});
it('should find that player size is nested', function () {
let obj = {'playerSize': [[640, 480]], 'mimes': ['video/mp4'], 'context': 'outstream'};
const result = playerSizeIsNestedArray(obj);
expect(result).to.be.true;
});
it('should find null from bad video object', function () {
let obj = {'playerSize': [], 'mimes': ['video/mp4'], 'context': 'outstream'};
const result = playerSizeIsNestedArray(obj);
expect(result).to.be.null;
});
it('should find null from bad video object2', function () {
let obj = {'mimes': ['video/mp4'], 'context': 'outstream'};
const result = playerSizeIsNestedArray(obj);
expect(result).to.be.null;
});
it('should find null from bad video object3', function () {
let obj = {'playerSize': 'should be an array', 'mimes': ['video/mp4'], 'context': 'outstream'};
const result = playerSizeIsNestedArray(obj);
expect(result).to.be.null;
});
});
describe('default size', function () {
it('should should return default sizes if no obj is sent', function () {
let obj = '';
const result = defaultSize(obj);
expect(result.defaultHeight).to.equal(250);
expect(result.defaultWidth).to.equal(300);
});
});
});