From 998623cc418c5ef9ac9a981deca24685151fc35b Mon Sep 17 00:00:00 2001 From: Henry Tang Date: Wed, 28 Aug 2019 14:37:28 -0400 Subject: [PATCH 01/12] add datablocks Analytics and Bidder Adapters --- modules/datablocksAnalyticsAdapter.js | 19 ++ modules/datablocksAnalyticsAdapter.md | 23 ++ modules/datablocksBidAdapter.js | 264 ++++++++++++++++++ modules/datablocksBidAdapter.md | 54 ++++ .../spec/modules/datablocksBidAdapter_spec.js | 230 +++++++++++++++ 5 files changed, 590 insertions(+) create mode 100644 modules/datablocksAnalyticsAdapter.js create mode 100644 modules/datablocksAnalyticsAdapter.md create mode 100644 modules/datablocksBidAdapter.js create mode 100644 modules/datablocksBidAdapter.md create mode 100644 test/spec/modules/datablocksBidAdapter_spec.js diff --git a/modules/datablocksAnalyticsAdapter.js b/modules/datablocksAnalyticsAdapter.js new file mode 100644 index 00000000000..76dd490180b --- /dev/null +++ b/modules/datablocksAnalyticsAdapter.js @@ -0,0 +1,19 @@ +/** + * Analytics Adapter for Datablocks + */ + +import adapter from '../src/AnalyticsAdapter'; +import adapterManager from '../src/adapterManager'; + +var datablocksAdapter = adapter({ + global: 'datablocksAnalytics', + handler: 'on', + analyticsType: 'bundle' +}); + +adapterManager.registerAnalyticsAdapter({ + adapter: datablocksAdapter, + code: 'datablocks' +}); + +export default datablocksAdapter; diff --git a/modules/datablocksAnalyticsAdapter.md b/modules/datablocksAnalyticsAdapter.md new file mode 100644 index 00000000000..01d0f6ddd32 --- /dev/null +++ b/modules/datablocksAnalyticsAdapter.md @@ -0,0 +1,23 @@ +# Overview + +Module Name: Datablocks Analytics Adapter +Module Type: Datablocks Adapter +Maintainer: support@datablocks.net + +# Description + +Analytics adapter for Datablocks.net. Contact support@datablocks.net for information. + +# Test Parameters + +``` +{ + provider: 'datablocks', + options: { + publisherId: 12345, + sourceId: 12356, + host: 'datablocks.net' + + } +} +``` \ No newline at end of file diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js new file mode 100644 index 00000000000..7035cb3124b --- /dev/null +++ b/modules/datablocksBidAdapter.js @@ -0,0 +1,264 @@ +import * as utils from 'src/utils'; +import { registerBidder } from 'src/adapters/bidderFactory'; +import { BANNER, NATIVE } from '../src/mediaTypes'; +import { parse as parseUrl } from '../src/url'; +const NATIVE_MAP = { + 'body': 2, + 'body2': 10, + 'price': 6, + 'displayUrl': 11, + 'cta': 12 +}; +const NATIVE_IMAGE = [{ + id: 'title_1', + required: 1, + title: { + len: 140 + } +}, { + id: 'image_1', + required: 1, + img: { type: 3 } +}, { + id: 'sponsoredBy_1', + required: 1, + data: { + type: 11 + } +}, { + id: 'body_1', + required: 0, + data: { + type: 2 + } +}, { + id: 'icon_1', + required: 0, + img: { type: 1 } +}, { + id: 'cta_1', + required: 0, + data: { + type: 12 + } +}]; + +export const spec = { + supportedMediaTypes: [BANNER, NATIVE], + code: 'datablocks', + isBidRequestValid: function(bid) { + return !!(bid.params.host && bid.params.sourceId && + bid.mediaTypes && (bid.mediaTypes.banner || bid.mediaTypes.native)); + }, + buildRequests: function(validBidRequests, bidderRequest) { + if (!validBidRequests.length) { return []; } + + let imps = {}; + let site = {}; + let device = {}; + let refurl = parseUrl(bidderRequest.referrer); + let requests = []; + + validBidRequests.forEach(bidRequest => { + let imp = { + id: bidRequest.bidId, + tagid: bidRequest.adUnitCode, + secure: window.location.protocol == 'https:' + } + + if (utils.deepAccess(bidRequest, `mediaTypes.banner`)) { + let sizes = bidRequest.mediaTypes.banner.sizes; + if (sizes.length == 1) { + imp.banner = { + w: sizes[0][0], + h: sizes[0][1] + } + } else if (sizes.length > 1) { + imp.banner = { + format: sizes.map(size => ({ w: size[0], h: size[1] })) + }; + } else { + return; + } + } else if (utils.deepAccess(bidRequest, 'mediaTypes.native')) { + let nativeImp = bidRequest.mediaTypes.native; + + if (nativeImp.type) { + let nativeAssets = []; + switch (nativeImp.type) { + case 'image': + nativeAssets = NATIVE_IMAGE; + break; + default: + return; + } + imp.native = JSON.stringify({ assets: nativeAssets }); + } else { + let nativeAssets = []; + let nativeKeys = Object.keys(nativeImp); + nativeKeys.forEach((nativeKey, index) => { + let required = !!nativeImp[nativeKey].required; + switch (nativeKey) { + case 'title': + nativeAssets.push({ + id: 'title_' + index, + required: required, + title: { + len: nativeImp[nativeKey].len || 140 + } + }); + break; + case 'body': // desc + case 'body2': // desc2 + case 'price': + case 'display_url': + let data = { + id: nativeKey + '_' + index, + required: required, + data: { + type: NATIVE_MAP[nativeKey] + } + } + if (nativeImp[nativeKey].data && nativeImp[nativeKey].data.len) { data.data.len = nativeImp[nativeKey].data.len; } + + nativeAssets.push(data); + break; + case 'image': + if (nativeImp[nativeKey].sizes && nativeImp[nativeKey].sizes.length) { + nativeAssets.push({ + id: 'image_' + index, + required: required, + image: { + type: 3, + w: nativeImp[nativeKey].sizes[0], + h: nativeImp[nativeKey].sizes[1] + } + }) + } + } + }); + imp.native = JSON.stringify({ assets: nativeAssets }); + } + } + let host = bidRequest.params.host; + let sourceId = bidRequest.params.sourceId; + let preLoadParam = window.DATABLOCKS && window.DATABLOCKS.getFetchId && typeof window.DATABLOCKS.getFetchId == 'function' && window.DATABLOCKS.getFetchId(); + imps[host] = imps[host] || {}; + let hostImp = imps[host][preLoadParam || sourceId] = imps[host][preLoadParam || sourceId] || { imps: [] }; + hostImp.imps.push(imp); + hostImp.subid = hostImp.imps.subid || bidRequest.params.subid || 'blank'; + hostImp.path = preLoadParam ? 'prebid' : 'search'; + hostImp.preLoadParam = preLoadParam ? 'preid' : 'sid'; + hostImp.protocol = '//'; + }); + + // Generate Site obj + site.domain = refurl.hostname; + site.page = refurl.protocol + '://' + refurl.hostname + refurl.pathname; + if (self === top && document.referrer) { + site.ref = document.referrer; + } + let keywords = document.getElementsByTagName('meta')['keywords']; + if (keywords && keywords.content) { + site.keywords = keywords.content; + } + + // Generate Device obj. + device.ip = 'peer'; + device.ua = window.navigator.userAgent; + device.js = 1; + device.language = ((navigator.language || navigator.userLanguage || '').split('-'))[0] || 'en'; + + RtbRequest(device, site, imps).forEach(formatted => { + requests.push({ + method: 'POST', + url: formatted.url, + data: formatted.body, + options: { + withCredentials: false + } + }) + }); + + return requests; + + function RtbRequest(device, site, imps) { + let collection = []; + Object.keys(imps).forEach(host => { + let sourceIds = imps[host]; + Object.keys(sourceIds).forEach(sourceId => { + let impObj = sourceIds[sourceId]; + collection.push({ + url: `${impObj.protocol}${host}/${impObj.path}/?${impObj.preLoadParam}=${sourceId}`, + body: { + id: bidderRequest.auctionId, + imp: impObj.imps, + site: Object.assign({ id: impObj.subid || 'blank' }, site), + device: Object.assign({}, device) + } + }) + }) + }) + + return collection; + } + }, + interpretResponse: function(serverResponse, bidRequest) { + if (!serverResponse || !serverResponse.body || !serverResponse.body.seatbid) { + return []; + } + let body = serverResponse.body; + + let bids = body.seatbid + .map(seatbid => seatbid.bid) + .reduce((memo, bid) => memo.concat(bid), []); + let req = bidRequest.data; + let reqImps = req.imp; + + return bids.map(rtbBid => { + let imp = reqImps.find(imp => imp.id == rtbBid.impid); + let br = { + requestId: rtbBid.impid, + cpm: rtbBid.price, + creativeId: rtbBid.crid, + currency: rtbBid.currency || 'USD', + netRevenue: true, + ttl: 360 + }; + if (imp.banner) { + br.mediaType = BANNER; + br.width = rtbBid.w; + br.height = rtbBid.h; + br.ad = rtbBid.adm; + } else if (imp.native) { + br.mediaType = NATIVE; + const nativeResponse = JSON.parse(rtbBid.adm); + const { assets, link, imptrackers, jstrackers } = nativeResponse.native; + const result = { + clickUrl: link.url, + clickTrackers: link.clicktrackers || undefined, + impressionTrackers: imptrackers || undefined, + javascriptTrackers: jstrackers ? [jstrackers] : undefined + }; + assets.forEach(asset => { + let assetType = asset.id.split('_')[0]; + switch (assetType) { + case 'title': + result.title = asset.title.text; + break; + case 'image': + result.image = asset.img.url; + break; + default: + result[assetType] = asset.data.value; + break; + } + }) + br.native = result; + } + return br; + }); + } + +}; +registerBidder(spec); diff --git a/modules/datablocksBidAdapter.md b/modules/datablocksBidAdapter.md new file mode 100644 index 00000000000..3d7fc9d8350 --- /dev/null +++ b/modules/datablocksBidAdapter.md @@ -0,0 +1,54 @@ +# Overview + +``` +Module Name: Datablocks Bidder Adapter +Module Type: Bidder Adapter +Maintainer: support@datablocks.net +``` + +# Description + +Connects to Datablocks Version 5 Platform +Banner Native and + + +# Test Parameters +``` + var adUnits = [ + { + code: 'banner-div', + sizes: [[300, 250]], + mediaType:{ + banner: { + sizes: [300,250] + } + }, + bids: [ + { + bidder: 'datablocks', + params: { + sourceId: 12345, + host: 'v5demo.datablocks.net' + } + } + ] + }, { + code: 'native-div', + bids: [ + { + bidder: 'datablocks', + mediaType : { + native: { + title:{required:true}, + body:{required:true} + } + }, + params: { + sourceId: 12345, + host: 'v5demo.datablocks.net' + } + } + ] + } + ]; +``` \ No newline at end of file diff --git a/test/spec/modules/datablocksBidAdapter_spec.js b/test/spec/modules/datablocksBidAdapter_spec.js new file mode 100644 index 00000000000..6d0713a45b7 --- /dev/null +++ b/test/spec/modules/datablocksBidAdapter_spec.js @@ -0,0 +1,230 @@ +import { expect } from 'chai'; +import { spec } from '../../../modules/datablocksBidAdapter'; + +let bid = { + bidId: '2dd581a2b6281d', + bidder: 'datablocks', + bidderRequestId: '145e1d6a7837c9', + params: { + sourceId: 7560, + host: 'v5demo.datablocks.net' + }, + adUnitCode: '/19968336/header-bid-tag-0', + auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', + mediaTypes: { + banner: { + sizes: [ + [300, 250] + ] + } + }, + sizes: [ + [300, 250] + ], + transactionId: '1ccbee15-f6f6-46ce-8998-58fe5542e8e1' +}; + +let nativeBid = { + adUnitCode: '/19968336/header-bid-tag-0', + auctionId: '160c78a4-f808-410f-b682-d8728f3a79ee', + bidId: '332045ee374a99', + bidder: 'datablocks', + bidderRequestId: '15d9012765e36c', + mediaTypes: { + native: { + body: { + required: true + }, + title: { + required: true + } + } + }, + nativeParams: { + body: { + required: true + }, + title: { + required: true + } + }, + params: { + sourceId: 7560, + host: 'v5demo.datablocks.net' + }, + transactionId: '0a4e9788-4def-4b94-bc25-564d7cac99f6' +} + +const bidderRequest = { + auctionId: '8bfef1be-d3ac-4d18-8859-754c7b4cf017', + auctionStart: Date.now(), + biddeCode: 'datablocks', + bidderRequestId: '10c47a5fc3c41', + bids: [bid, nativeBid], + refererInfo: { + numIframes: 0, + reachedTop: true, + referer: 'http://v5demo.datablocks.net/test', + stack: ['http://v5demo.datablocks.net/test'] + }, + start: Date.now(), + timeout: 10000 +}; + +let resObject = { + body: { + id: '10c47a5fc3c41', + bidid: '166895245-28-11347-1', + seatbid: [{ + seat: '7560', + bid: [{ + id: '1090738570', + impid: '2966b257c81d27', + price: 24.000000, + adm: 'RON', + cid: '55', + adid: '177654', + crid: '177656', + cat: [], + api: [], + w: 300, + h: 250 + }, { + id: '1090738570', + impid: '15d9012765e36c', + price: 24.000000, + adm: '{"native":{"ver":"1.2","assets":[{"id":"title_1","required":1,"title":{"text":"Example Title"}},{"id":"body_0","required":1,"data":{"value":"Example Body"}}],"link":{"url":"http://click.example.com/c/264597/?fcid=29699699045816"},"imptrackers":["http://impression.example.com/i/264597/?fcid=29699699045816"]}}', + cid: '132145', + adid: '154321', + crid: '177432', + cat: [], + api: [] + }] + }], + cur: 'USD', + ext: {} + } +}; +let bidRequest = { + method: 'POST', + url: '//v5demo.datablocks.net/search/?sid=7560', + options: { + withCredentials: false + }, + data: { + device: { + ip: 'peer', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) Ap…ML, like Gecko) Chrome/73.0.3683.86 Safari/537.36', + js: 1, + language: 'en' + }, + id: '10c47a5fc3c41', + imp: [{ + banner: { w: 300, h: 250 }, + id: '2966b257c81d27', + secure: false, + tagid: '/19968336/header-bid-tag-0' + }, { + id: '15d9012765e36c', + native: '{"assets":[{"id":"title_0","required":true,"title":{"len":140}},{"id":"body_1","required":true,"data":{"type":2}}]}', + secure: false, + tagid: '/19968336/header-bid-tag-0' + }], + site: { + domain: '', + id: 'blank', + page: 'http://v5demo.datablocks.net/test' + } + } +} + +describe('DatablocksAdapter', function() { + describe('isBidRequestValid', function() { + it('Should return true when sourceId and Host are set', function() { + expect(spec.isBidRequestValid(bid)).to.be.true; + }); + it('Should return false when host/sourceId is not set', function() { + let moddedBid = Object.assign({}, bid); + delete moddedBid.params.sourceId; + delete moddedBid.params.host; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + }); + + describe('buildRequests', function() { + let requests = spec.buildRequests([bid], bidderRequest); + it('Creates an array of request objects', function() { + expect(requests).to.be.an('array').that.is.not.empty; + }); + + requests.forEach(request => { + expect(request).to.exist; + it('Returns POST method', function() { + expect(request.method).to.exist; + expect(request.method).to.equal('POST'); + }); + it('Returns valid URL', function() { + expect(request.url).to.exist; + expect(request.url).to.equal('//v5demo.datablocks.net/search/?sid=7560'); + }); + + it('Should be a valid openRTB request', function() { + let data = request.data; + expect(data).to.be.an('object'); + expect(data).to.have.all.keys('device', 'imp', 'site', 'id'); + expect(data.id).to.be.a('string'); + + let imps = data['imp']; + imps.forEach((imp, index) => { + let curBid = bidderRequest.bids[index]; + expect(imp).to.have.all.keys('banner', 'id', 'secure', 'tagid'); + expect(imp.banner).to.be.a('object'); + expect(imp.id).to.be.a('string'); + expect(imp.id).to.equal(curBid.bidId); + expect(imp.tagid).to.be.a('string'); + expect(imp.tagid).to.equal(curBid.adUnitCode); + expect(imp.secure).to.equal(false); + }) + + expect(data.device.ip).to.equal('peer'); + }); + }) + + it('Returns empty data if no valid requests are passed', function() { + let request = spec.buildRequests([]); + expect(request).to.be.an('array').that.is.empty; + }); + }); + describe('interpretResponse', function() { + let serverResponses = spec.interpretResponse(resObject, bidRequest); + it('Returns an array of valid server responses if response object is valid', function() { + expect(serverResponses).to.be.an('array').that.is.not.empty; + for (let i = 0; i < serverResponses.length; i++) { + let dataItem = serverResponses[i]; + expect(Object.keys(dataItem)).to.include('cpm', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'mediaType', 'requestId'); + expect(dataItem.requestId).to.be.a('string'); + expect(dataItem.cpm).to.be.a('number'); + expect(dataItem.ttl).to.be.a('number'); + expect(dataItem.creativeId).to.be.a('string'); + expect(dataItem.netRevenue).to.be.a('boolean'); + expect(dataItem.currency).to.be.a('string'); + expect(dataItem.mediaType).to.be.a('string'); + + if (dataItem.mediaType == 'banner') { + expect(dataItem.ad).to.be.a('string'); + expect(dataItem.width).to.be.a('number'); + expect(dataItem.height).to.be.a('number'); + } else if (dataItem.mediaType == 'native') { + expect(dataItem.native.title).to.be.a('string'); + expect(dataItem.native.body).to.be.a('string'); + expect(dataItem.native.clickUrl).to.be.a('string'); + } + } + it('Returns an empty array if invalid response is passed', function() { + serverResponses = spec.interpretResponse('invalid_response'); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + }); + }); +}); From 56f6164a71cdacc595792be8977fefad685ecab3 Mon Sep 17 00:00:00 2001 From: Henry Tang Date: Wed, 28 Aug 2019 14:50:49 -0400 Subject: [PATCH 02/12] remove preload param --- modules/datablocksBidAdapter.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js index 7035cb3124b..c5528b279cf 100644 --- a/modules/datablocksBidAdapter.js +++ b/modules/datablocksBidAdapter.js @@ -142,13 +142,12 @@ export const spec = { } let host = bidRequest.params.host; let sourceId = bidRequest.params.sourceId; - let preLoadParam = window.DATABLOCKS && window.DATABLOCKS.getFetchId && typeof window.DATABLOCKS.getFetchId == 'function' && window.DATABLOCKS.getFetchId(); imps[host] = imps[host] || {}; - let hostImp = imps[host][preLoadParam || sourceId] = imps[host][preLoadParam || sourceId] || { imps: [] }; + let hostImp = imps[host][sourceId] = imps[host][sourceId] || { imps: [] }; hostImp.imps.push(imp); hostImp.subid = hostImp.imps.subid || bidRequest.params.subid || 'blank'; - hostImp.path = preLoadParam ? 'prebid' : 'search'; - hostImp.preLoadParam = preLoadParam ? 'preid' : 'sid'; + hostImp.path = 'search'; + hostImp.idParam = 'sid'; hostImp.protocol = '//'; }); @@ -189,7 +188,7 @@ export const spec = { Object.keys(sourceIds).forEach(sourceId => { let impObj = sourceIds[sourceId]; collection.push({ - url: `${impObj.protocol}${host}/${impObj.path}/?${impObj.preLoadParam}=${sourceId}`, + url: `${impObj.protocol}${host}/${impObj.path}/?${impObj.idLoadParam}=${sourceId}`, body: { id: bidderRequest.auctionId, imp: impObj.imps, From 22222bcfcaaf5f1fdc94d002dfcc4ef44e0e581a Mon Sep 17 00:00:00 2001 From: Henry Tang Date: Wed, 28 Aug 2019 15:49:33 -0400 Subject: [PATCH 03/12] remove preloadid --- modules/datablocksBidAdapter.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js index c5528b279cf..27239fd4717 100644 --- a/modules/datablocksBidAdapter.js +++ b/modules/datablocksBidAdapter.js @@ -1,5 +1,5 @@ -import * as utils from 'src/utils'; -import { registerBidder } from 'src/adapters/bidderFactory'; +import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory'; import { BANNER, NATIVE } from '../src/mediaTypes'; import { parse as parseUrl } from '../src/url'; const NATIVE_MAP = { @@ -188,7 +188,7 @@ export const spec = { Object.keys(sourceIds).forEach(sourceId => { let impObj = sourceIds[sourceId]; collection.push({ - url: `${impObj.protocol}${host}/${impObj.path}/?${impObj.idLoadParam}=${sourceId}`, + url: `${impObj.protocol}${host}/${impObj.path}/?${impObj.idParam}=${sourceId}`, body: { id: bidderRequest.auctionId, imp: impObj.imps, From de6839ca2257532bf485e11fa597a17095d4213c Mon Sep 17 00:00:00 2001 From: Henry Tang Date: Thu, 29 Aug 2019 15:05:16 -0400 Subject: [PATCH 04/12] better coverage of tests --- .../spec/modules/datablocksBidAdapter_spec.js | 64 +++++++++++++++++-- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/test/spec/modules/datablocksBidAdapter_spec.js b/test/spec/modules/datablocksBidAdapter_spec.js index 6d0713a45b7..bb89c63ee92 100644 --- a/test/spec/modules/datablocksBidAdapter_spec.js +++ b/test/spec/modules/datablocksBidAdapter_spec.js @@ -24,6 +24,25 @@ let bid = { transactionId: '1ccbee15-f6f6-46ce-8998-58fe5542e8e1' }; +let bid2 = { + bidId: '2dd581a2b624324g', + bidder: 'datablocks', + bidderRequestId: '145e1d6a7837543', + params: { + sourceId: 7560, + host: 'v5demo.datablocks.net' + }, + adUnitCode: '/19968336/header-bid-tag-0', + auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', + mediaTypes: { + banner: { + sizes: + [728, 90] + } + }, + transactionId: '1ccbee15-f6f6-46ce-8998-58fe55425432' +}; + let nativeBid = { adUnitCode: '/19968336/header-bid-tag-0', auctionId: '160c78a4-f808-410f-b682-d8728f3a79ee', @@ -37,6 +56,9 @@ let nativeBid = { }, title: { required: true + }, + image: { + required: true } } }, @@ -46,6 +68,9 @@ let nativeBid = { }, title: { required: true + }, + image: { + required: true } }, params: { @@ -60,7 +85,7 @@ const bidderRequest = { auctionStart: Date.now(), biddeCode: 'datablocks', bidderRequestId: '10c47a5fc3c41', - bids: [bid, nativeBid], + bids: [bid, bid2, nativeBid], refererInfo: { numIframes: 0, reachedTop: true, @@ -89,11 +114,23 @@ let resObject = { api: [], w: 300, h: 250 + }, { + id: '1090738571', + impid: '2966b257c81d28', + price: 24.000000, + adm: 'RON', + cid: '55', + adid: '177654', + crid: '177656', + cat: [], + api: [], + w: 728, + h: 90 }, { id: '1090738570', impid: '15d9012765e36c', price: 24.000000, - adm: '{"native":{"ver":"1.2","assets":[{"id":"title_1","required":1,"title":{"text":"Example Title"}},{"id":"body_0","required":1,"data":{"value":"Example Body"}}],"link":{"url":"http://click.example.com/c/264597/?fcid=29699699045816"},"imptrackers":["http://impression.example.com/i/264597/?fcid=29699699045816"]}}', + adm: '{"native":{"ver":"1.2","assets":[{"id":"title_1","required":1,"title":{"text":"Example Title"}},{"id":"body_0","required":1,"data":{"value":"Example Body"}},{"id":"image_1","required":1,"img":{"url":"http://example.image.com/"}}],"link":{"url":"http://click.example.com/c/264597/?fcid=29699699045816"},"imptrackers":["http://impression.example.com/i/264597/?fcid=29699699045816"]}}', cid: '132145', adid: '154321', crid: '177432', @@ -124,9 +161,14 @@ let bidRequest = { id: '2966b257c81d27', secure: false, tagid: '/19968336/header-bid-tag-0' + }, { + banner: { w: 728, h: 90 }, + id: '2966b257c81d28', + secure: false, + tagid: '/19968336/header-bid-tag-0' }, { id: '15d9012765e36c', - native: '{"assets":[{"id":"title_0","required":true,"title":{"len":140}},{"id":"body_1","required":true,"data":{"type":2}}]}', + native: '{"assets":[{"id":"title_0","required":true,"title":{"len":140}},{"id":"body_1","required":true,"data":{"type":2}},{"id":"image_1","img":{"w":728,"h":90,"type":3}}]}', secure: false, tagid: '/19968336/header-bid-tag-0' }], @@ -152,7 +194,7 @@ describe('DatablocksAdapter', function() { }); describe('buildRequests', function() { - let requests = spec.buildRequests([bid], bidderRequest); + let requests = spec.buildRequests([bid,bid2,nativeBid], bidderRequest); it('Creates an array of request objects', function() { expect(requests).to.be.an('array').that.is.not.empty; }); @@ -177,8 +219,18 @@ describe('DatablocksAdapter', function() { let imps = data['imp']; imps.forEach((imp, index) => { let curBid = bidderRequest.bids[index]; - expect(imp).to.have.all.keys('banner', 'id', 'secure', 'tagid'); - expect(imp.banner).to.be.a('object'); + if (imp.banner ) { + expect(imp).to.have.all.keys('banner','id', 'secure', 'tagid'); + expect(imp.banner).to.be.a('object'); + } else if ( imp.native ) { + expect(imp).to.have.all.keys('native','id', 'secure', 'tagid'); + expect(imp.native).to.be.a('string'); + let native = JSON.parse(imp.native); + expect(native).to.be.a('object'); + } else { + expect(true).to.equal(false); + } + expect(imp.id).to.be.a('string'); expect(imp.id).to.equal(curBid.bidId); expect(imp.tagid).to.be.a('string'); From e3ddd33e318f984b0f998eb37a9174ba29438a20 Mon Sep 17 00:00:00 2001 From: Henry Tang Date: Thu, 29 Aug 2019 15:15:16 -0400 Subject: [PATCH 05/12] better coverage --- test/spec/modules/datablocksBidAdapter_spec.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/spec/modules/datablocksBidAdapter_spec.js b/test/spec/modules/datablocksBidAdapter_spec.js index bb89c63ee92..42c1b3f6292 100644 --- a/test/spec/modules/datablocksBidAdapter_spec.js +++ b/test/spec/modules/datablocksBidAdapter_spec.js @@ -64,13 +64,17 @@ let nativeBid = { }, nativeParams: { body: { - required: true + required: true, + data:{ + len:250 + } }, title: { required: true }, image: { - required: true + required: true, + sizes:[728,90] } }, params: { From e032c38508d1ddd228ad861104afe16bf3084137 Mon Sep 17 00:00:00 2001 From: Jon Apgar <5638966+jonapgar@users.noreply.github.com> Date: Thu, 29 Aug 2019 15:30:31 -0400 Subject: [PATCH 06/12] IE doesn't support array.find --- modules/datablocksBidAdapter.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js index 27239fd4717..6a84ec3a6f8 100644 --- a/modules/datablocksBidAdapter.js +++ b/modules/datablocksBidAdapter.js @@ -215,7 +215,14 @@ export const spec = { let reqImps = req.imp; return bids.map(rtbBid => { - let imp = reqImps.find(imp => imp.id == rtbBid.impid); + let imp; + for (let i in reqImps) { + let testImp = reqImps[i] + if (testImp.id == rtbBid.impid) { + imp = testImp; + break; + } + } let br = { requestId: rtbBid.impid, cpm: rtbBid.price, @@ -224,7 +231,9 @@ export const spec = { netRevenue: true, ttl: 360 }; - if (imp.banner) { + if (!imp) { + return br; + } else if (imp.banner) { br.mediaType = BANNER; br.width = rtbBid.w; br.height = rtbBid.h; From ade690a574b784cb72716e7be9af2806eb7c528a Mon Sep 17 00:00:00 2001 From: Henry Tang Date: Thu, 29 Aug 2019 15:40:31 -0400 Subject: [PATCH 07/12] lint test --- test/spec/modules/datablocksBidAdapter_spec.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/spec/modules/datablocksBidAdapter_spec.js b/test/spec/modules/datablocksBidAdapter_spec.js index 42c1b3f6292..8e28560473f 100644 --- a/test/spec/modules/datablocksBidAdapter_spec.js +++ b/test/spec/modules/datablocksBidAdapter_spec.js @@ -65,8 +65,8 @@ let nativeBid = { nativeParams: { body: { required: true, - data:{ - len:250 + data: { + len: 250 } }, title: { @@ -74,7 +74,7 @@ let nativeBid = { }, image: { required: true, - sizes:[728,90] + sizes: [728, 90] } }, params: { @@ -198,7 +198,7 @@ describe('DatablocksAdapter', function() { }); describe('buildRequests', function() { - let requests = spec.buildRequests([bid,bid2,nativeBid], bidderRequest); + let requests = spec.buildRequests([bid, bid2, nativeBid], bidderRequest); it('Creates an array of request objects', function() { expect(requests).to.be.an('array').that.is.not.empty; }); @@ -223,11 +223,11 @@ describe('DatablocksAdapter', function() { let imps = data['imp']; imps.forEach((imp, index) => { let curBid = bidderRequest.bids[index]; - if (imp.banner ) { - expect(imp).to.have.all.keys('banner','id', 'secure', 'tagid'); + if (imp.banner) { + expect(imp).to.have.all.keys('banner', 'id', 'secure', 'tagid'); expect(imp.banner).to.be.a('object'); - } else if ( imp.native ) { - expect(imp).to.have.all.keys('native','id', 'secure', 'tagid'); + } else if (imp.native) { + expect(imp).to.have.all.keys('native', 'id', 'secure', 'tagid'); expect(imp.native).to.be.a('string'); let native = JSON.parse(imp.native); expect(native).to.be.a('object'); From 477ef093d3fd1c91ad3b02bb544e70ff7f90d578 Mon Sep 17 00:00:00 2001 From: Henry Tang Date: Tue, 3 Sep 2019 09:41:30 -0400 Subject: [PATCH 08/12] update example host --- modules/datablocksAnalyticsAdapter.md | 2 +- modules/datablocksBidAdapter.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/datablocksAnalyticsAdapter.md b/modules/datablocksAnalyticsAdapter.md index 01d0f6ddd32..07f65da6e2c 100644 --- a/modules/datablocksAnalyticsAdapter.md +++ b/modules/datablocksAnalyticsAdapter.md @@ -16,7 +16,7 @@ Analytics adapter for Datablocks.net. Contact support@datablocks.net for informa options: { publisherId: 12345, sourceId: 12356, - host: 'datablocks.net' + host: 'prebid.datablocks.net' } } diff --git a/modules/datablocksBidAdapter.md b/modules/datablocksBidAdapter.md index 3d7fc9d8350..a341f1fd2ea 100644 --- a/modules/datablocksBidAdapter.md +++ b/modules/datablocksBidAdapter.md @@ -28,7 +28,7 @@ Banner Native and bidder: 'datablocks', params: { sourceId: 12345, - host: 'v5demo.datablocks.net' + host: 'prebid.datablocks.net' } } ] @@ -45,7 +45,7 @@ Banner Native and }, params: { sourceId: 12345, - host: 'v5demo.datablocks.net' + host: 'prebid.datablocks.net' } } ] From 4cac192821e1a2fac08cd644b2ba8e6ec7c68ed2 Mon Sep 17 00:00:00 2001 From: Henry Tang Date: Wed, 4 Sep 2019 16:51:35 -0400 Subject: [PATCH 09/12] native asset id should be integer --- modules/datablocksBidAdapter.js | 55 ++++++++++++------- modules/datablocksBidAdapter.md | 14 ++--- .../spec/modules/datablocksBidAdapter_spec.js | 19 ++++--- 3 files changed, 51 insertions(+), 37 deletions(-) diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js index 6a84ec3a6f8..aa427c6eae1 100644 --- a/modules/datablocksBidAdapter.js +++ b/modules/datablocksBidAdapter.js @@ -10,33 +10,33 @@ const NATIVE_MAP = { 'cta': 12 }; const NATIVE_IMAGE = [{ - id: 'title_1', + id: 1, required: 1, title: { len: 140 } }, { - id: 'image_1', + id: 2, required: 1, img: { type: 3 } }, { - id: 'sponsoredBy_1', + id: 3, required: 1, data: { type: 11 } }, { - id: 'body_1', + id: 4, required: 0, data: { type: 2 } }, { - id: 'icon_1', + id: 5, required: 0, img: { type: 1 } }, { - id: 'cta_1', + id: 6, required: 0, data: { type: 12 @@ -98,10 +98,11 @@ export const spec = { let nativeKeys = Object.keys(nativeImp); nativeKeys.forEach((nativeKey, index) => { let required = !!nativeImp[nativeKey].required; + let assetId = index + 1; switch (nativeKey) { case 'title': nativeAssets.push({ - id: 'title_' + index, + id: assetId, required: required, title: { len: nativeImp[nativeKey].len || 140 @@ -113,7 +114,7 @@ export const spec = { case 'price': case 'display_url': let data = { - id: nativeKey + '_' + index, + id: assetId, required: required, data: { type: NATIVE_MAP[nativeKey] @@ -126,7 +127,7 @@ export const spec = { case 'image': if (nativeImp[nativeKey].sizes && nativeImp[nativeKey].sizes.length) { nativeAssets.push({ - id: 'image_' + index, + id: assetId, required: required, image: { type: 3, @@ -137,7 +138,9 @@ export const spec = { } } }); - imp.native = JSON.stringify({ assets: nativeAssets }); + imp.native = { + request: JSON.stringify({native: {assets: nativeAssets}}) + }; } } let host = bidRequest.params.host; @@ -240,6 +243,21 @@ export const spec = { br.ad = rtbBid.adm; } else if (imp.native) { br.mediaType = NATIVE; + + let reverseNativeMap = {}; + let nativeKeys = Object.keys(NATIVE_MAP); + nativeKeys.forEach(k => { + reverseNativeMap[NATIVE_MAP[k]] = k; + }); + + let idMap = {}; + let nativeReq = JSON.parse(imp.native.request); + if (nativeReq.native && nativeReq.native.assets) { + nativeReq.native.assets.forEach(asset => { + if (asset.data) { idMap[asset.id] = reverseNativeMap[asset.data.type]; } + }) + } + const nativeResponse = JSON.parse(rtbBid.adm); const { assets, link, imptrackers, jstrackers } = nativeResponse.native; const result = { @@ -249,17 +267,12 @@ export const spec = { javascriptTrackers: jstrackers ? [jstrackers] : undefined }; assets.forEach(asset => { - let assetType = asset.id.split('_')[0]; - switch (assetType) { - case 'title': - result.title = asset.title.text; - break; - case 'image': - result.image = asset.img.url; - break; - default: - result[assetType] = asset.data.value; - break; + if (asset.title) { + result.title = asset.title.text; + } else if (asset.img) { + result.image = asset.img.url; + } else if (idMap[asset.id]) { + result[idMap[asset.id]] = asset.data.value; } }) br.native = result; diff --git a/modules/datablocksBidAdapter.md b/modules/datablocksBidAdapter.md index a341f1fd2ea..7562eee5704 100644 --- a/modules/datablocksBidAdapter.md +++ b/modules/datablocksBidAdapter.md @@ -18,7 +18,7 @@ Banner Native and { code: 'banner-div', sizes: [[300, 250]], - mediaType:{ + mediaTypes:{ banner: { sizes: [300,250] } @@ -34,15 +34,15 @@ Banner Native and ] }, { code: 'native-div', + mediaTypes : { + native: { + title:{required:true}, + body:{required:true} + } + }, bids: [ { bidder: 'datablocks', - mediaType : { - native: { - title:{required:true}, - body:{required:true} - } - }, params: { sourceId: 12345, host: 'prebid.datablocks.net' diff --git a/test/spec/modules/datablocksBidAdapter_spec.js b/test/spec/modules/datablocksBidAdapter_spec.js index 8e28560473f..07989b86535 100644 --- a/test/spec/modules/datablocksBidAdapter_spec.js +++ b/test/spec/modules/datablocksBidAdapter_spec.js @@ -51,10 +51,10 @@ let nativeBid = { bidderRequestId: '15d9012765e36c', mediaTypes: { native: { - body: { + title: { required: true }, - title: { + body: { required: true }, image: { @@ -63,15 +63,15 @@ let nativeBid = { } }, nativeParams: { + title: { + required: true + }, body: { required: true, data: { len: 250 } }, - title: { - required: true - }, image: { required: true, sizes: [728, 90] @@ -134,7 +134,7 @@ let resObject = { id: '1090738570', impid: '15d9012765e36c', price: 24.000000, - adm: '{"native":{"ver":"1.2","assets":[{"id":"title_1","required":1,"title":{"text":"Example Title"}},{"id":"body_0","required":1,"data":{"value":"Example Body"}},{"id":"image_1","required":1,"img":{"url":"http://example.image.com/"}}],"link":{"url":"http://click.example.com/c/264597/?fcid=29699699045816"},"imptrackers":["http://impression.example.com/i/264597/?fcid=29699699045816"]}}', + adm: '{"native":{"ver":"1.2","assets":[{"id":1,"required":1,"title":{"text":"Example Title"}},{"id":2,"required":1,"data":{"value":"Example Body"}},{"id":3,"required":1,"img":{"url":"http://example.image.com/"}}],"link":{"url":"http://click.example.com/c/264597/?fcid=29699699045816"},"imptrackers":["http://impression.example.com/i/264597/?fcid=29699699045816"]}}', cid: '132145', adid: '154321', crid: '177432', @@ -172,7 +172,7 @@ let bidRequest = { tagid: '/19968336/header-bid-tag-0' }, { id: '15d9012765e36c', - native: '{"assets":[{"id":"title_0","required":true,"title":{"len":140}},{"id":"body_1","required":true,"data":{"type":2}},{"id":"image_1","img":{"w":728,"h":90,"type":3}}]}', + native: {request: '{"native":{"assets":[{"id":"1","required":true,"title":{"len":140}},{"id":"2","required":true,"data":{"type":2}},{"id":"3","img":{"w":728,"h":90,"type":3}}]}}'}, secure: false, tagid: '/19968336/header-bid-tag-0' }], @@ -228,8 +228,9 @@ describe('DatablocksAdapter', function() { expect(imp.banner).to.be.a('object'); } else if (imp.native) { expect(imp).to.have.all.keys('native', 'id', 'secure', 'tagid'); - expect(imp.native).to.be.a('string'); - let native = JSON.parse(imp.native); + expect(imp.native).to.have.all.keys('request'); + expect(imp.native.request).to.be.a('string'); + let native = JSON.parse(imp.native.request); expect(native).to.be.a('object'); } else { expect(true).to.equal(false); From c64e93a087c630e01642897dae7c2af1a61036e8 Mon Sep 17 00:00:00 2001 From: Henry Tang Date: Mon, 16 Sep 2019 15:24:44 -0400 Subject: [PATCH 10/12] add datablocks Video --- modules/datablocksBidAdapter.js | 52 +++++++++++++++++-- modules/datablocksBidAdapter.md | 21 +++++++- .../spec/modules/datablocksBidAdapter_spec.js | 51 +++++++++++++++++- 3 files changed, 117 insertions(+), 7 deletions(-) diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js index aa427c6eae1..4ae4a826f18 100644 --- a/modules/datablocksBidAdapter.js +++ b/modules/datablocksBidAdapter.js @@ -1,6 +1,6 @@ import * as utils from '../src/utils'; import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, NATIVE } from '../src/mediaTypes'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; import { parse as parseUrl } from '../src/url'; const NATIVE_MAP = { 'body': 2, @@ -43,12 +43,17 @@ const NATIVE_IMAGE = [{ } }]; +const VIDEO_PARAMS = ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', + 'placement', 'linearity', 'skip', 'skipmin', 'skipafter', 'sequence', 'battr', 'maxextended', + 'minbitrate', 'maxbitrate', 'boxingallowed', 'playbackmethod', 'playbackend', 'delivery', + 'pos', 'companionad', 'api', 'companiontype', 'ext']; + export const spec = { - supportedMediaTypes: [BANNER, NATIVE], + supportedMediaTypes: [BANNER, NATIVE, VIDEO], code: 'datablocks', isBidRequestValid: function(bid) { return !!(bid.params.host && bid.params.sourceId && - bid.mediaTypes && (bid.mediaTypes.banner || bid.mediaTypes.native)); + bid.mediaTypes && (bid.mediaTypes.banner || bid.mediaTypes.native || bid.mediaTypes.video)); }, buildRequests: function(validBidRequests, bidderRequest) { if (!validBidRequests.length) { return []; } @@ -142,6 +147,41 @@ export const spec = { request: JSON.stringify({native: {assets: nativeAssets}}) }; } + } else if (utils.deepAccess(bidRequest, 'mediaTypes.video')) { + let video = bidRequest.mediaTypes.video; + let sizes = video.playerSize || bidRequest.sizes; + if (sizes.length && Array.isArray(sizes[0])) { + imp.video = { + w: sizes[0][0], + h: sizes[0][1] + }; + } else if (sizes.length && Number.isInteger(sizes[0])) { + imp.video = { + w: sizes[0], + h: sizes[1] + }; + } + + if (video.durationRangeSec) { + if (Array.isArray(video.durationRangeSec)) { + if (video.durationRangeSec.length == 1) { + imp.video.maxduration = video.durationRangeSec[0]; + } else if (video.durationRangeSec.length == 2) { + imp.video.minduration = video.durationRangeSec[0]; + imp.video.maxduration = video.durationRangeSec[1]; + } + } else { + imp.video.maxduration = video.durationRangeSec; + } + } + + if (bidRequest.params.video) { + Object.keys(bidRequest.params.video).forEach(k => { + if (VIDEO_PARAMS.indexOf(k) > -1) { + imp.video[k] = bidRequest.params.video[k]; + } + }) + } } let host = bidRequest.params.host; let sourceId = bidRequest.params.sourceId; @@ -181,7 +221,6 @@ export const spec = { } }) }); - return requests; function RtbRequest(device, site, imps) { @@ -276,6 +315,11 @@ export const spec = { } }) br.native = result; + } else if (imp.video) { + br.mediaType = VIDEO; + br.width = rtbBid.w; + br.height = rtbBid.h; + if (rtbBid.adm) { br.vastXml = rtbBid.adm; } else if (rtbBid.nurl) { br.vastUrl = rtbBid.nurl; } } return br; }); diff --git a/modules/datablocksBidAdapter.md b/modules/datablocksBidAdapter.md index 7562eee5704..e30cd361974 100644 --- a/modules/datablocksBidAdapter.md +++ b/modules/datablocksBidAdapter.md @@ -9,7 +9,7 @@ Maintainer: support@datablocks.net # Description Connects to Datablocks Version 5 Platform -Banner Native and +Banner Native and Video # Test Parameters @@ -47,6 +47,25 @@ Banner Native and sourceId: 12345, host: 'prebid.datablocks.net' } + }, { + code: 'video-div', + mediaTypes : { + video: { + playerSize:[500,400], + durationRangeSec:[15,30], + context: "linear" + } + }, + bids: [ + { + bidder: 'datablocks', + params: { + sourceId: 12345, + host: 'prebid.datablocks.net', + video: { + mimes:["video/flv"] + } + } } ] } diff --git a/test/spec/modules/datablocksBidAdapter_spec.js b/test/spec/modules/datablocksBidAdapter_spec.js index 07989b86535..ca0676ff42b 100644 --- a/test/spec/modules/datablocksBidAdapter_spec.js +++ b/test/spec/modules/datablocksBidAdapter_spec.js @@ -84,12 +84,35 @@ let nativeBid = { transactionId: '0a4e9788-4def-4b94-bc25-564d7cac99f6' } +let videoBid = { + adUnitCode: '/19968336/header-bid-tag-0', + auctionId: '160c78a4-f808-410f-b682-d8728f3a79e1', + bidId: '332045ee374b99', + bidder: 'datablocks', + bidderRequestId: '15d9012765e36d', + mediaTypes: { + video: { + context: 'instream', + playerSize: [501, 400], + durationRangeSec: [15, 60] + } + }, + params: { + sourceId: 7560, + host: 'v5demo.datablocks.net', + video:{ + minduration:14 + } + }, + transactionId: '0a4e9788-4def-4b94-bc25-564d7cac99f7' +} + const bidderRequest = { auctionId: '8bfef1be-d3ac-4d18-8859-754c7b4cf017', auctionStart: Date.now(), biddeCode: 'datablocks', bidderRequestId: '10c47a5fc3c41', - bids: [bid, bid2, nativeBid], + bids: [bid, bid2, nativeBid, videoBid], refererInfo: { numIframes: 0, reachedTop: true, @@ -140,6 +163,18 @@ let resObject = { crid: '177432', cat: [], api: [] + }, { + id: '1090738575', + impid: '15d9012765e36f', + price: 25.000000, + cid: '12345', + adid: '12345', + crid: '123456', + nurl: 'http://click.v5demo.datablocks.net/m//?fcid=435235435432', + cat: [], + api: [], + w: 500, + h: 400 }] }], cur: 'USD', @@ -175,6 +210,11 @@ let bidRequest = { native: {request: '{"native":{"assets":[{"id":"1","required":true,"title":{"len":140}},{"id":"2","required":true,"data":{"type":2}},{"id":"3","img":{"w":728,"h":90,"type":3}}]}}'}, secure: false, tagid: '/19968336/header-bid-tag-0' + }, { + id: '15d9012765e36f', + video: {w: 500, h: 400, minduration: 15, maxduration: 60}, + secure: false, + tagid: '/19968336/header-bid-tag-0' }], site: { domain: '', @@ -198,7 +238,7 @@ describe('DatablocksAdapter', function() { }); describe('buildRequests', function() { - let requests = spec.buildRequests([bid, bid2, nativeBid], bidderRequest); + let requests = spec.buildRequests([bid, bid2, nativeBid, videoBid], bidderRequest); it('Creates an array of request objects', function() { expect(requests).to.be.an('array').that.is.not.empty; }); @@ -232,6 +272,9 @@ describe('DatablocksAdapter', function() { expect(imp.native.request).to.be.a('string'); let native = JSON.parse(imp.native.request); expect(native).to.be.a('object'); + } else if (imp.video) { + expect(imp).to.have.all.keys('video', 'id', 'secure', 'tagid'); + expect(imp.video).to.have.all.keys('w', 'h', 'minduration', 'maxduration') } else { expect(true).to.equal(false); } @@ -276,6 +319,10 @@ describe('DatablocksAdapter', function() { expect(dataItem.native.title).to.be.a('string'); expect(dataItem.native.body).to.be.a('string'); expect(dataItem.native.clickUrl).to.be.a('string'); + } else if (dataItem.mediaType == 'video') { + expect(dataItem.vastUrl).to.be.a('string'); + expect(dataItem.width).to.be.a('number'); + expect(dataItem.height).to.be.a('number'); } } it('Returns an empty array if invalid response is passed', function() { From af9649e95e00488fe7ad7b579de3eaaddb91460e Mon Sep 17 00:00:00 2001 From: Henry Tang Date: Mon, 16 Sep 2019 15:49:47 -0400 Subject: [PATCH 11/12] remove isInteger --- modules/datablocksBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js index 4ae4a826f18..e1ff5105acb 100644 --- a/modules/datablocksBidAdapter.js +++ b/modules/datablocksBidAdapter.js @@ -155,7 +155,7 @@ export const spec = { w: sizes[0][0], h: sizes[0][1] }; - } else if (sizes.length && Number.isInteger(sizes[0])) { + } else if (sizes.length && sizes.length == 2 && !Array.isArray(sizes[0])) { imp.video = { w: sizes[0], h: sizes[1] From d095d19716606c624b719c23cc6a50d11177a2d9 Mon Sep 17 00:00:00 2001 From: Henry Tang Date: Mon, 16 Sep 2019 15:52:33 -0400 Subject: [PATCH 12/12] skip if empty --- modules/datablocksBidAdapter.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js index e1ff5105acb..3e9bf219c75 100644 --- a/modules/datablocksBidAdapter.js +++ b/modules/datablocksBidAdapter.js @@ -149,17 +149,19 @@ export const spec = { } } else if (utils.deepAccess(bidRequest, 'mediaTypes.video')) { let video = bidRequest.mediaTypes.video; - let sizes = video.playerSize || bidRequest.sizes; + let sizes = video.playerSize || bidRequest.sizes || []; if (sizes.length && Array.isArray(sizes[0])) { imp.video = { w: sizes[0][0], h: sizes[0][1] }; - } else if (sizes.length && sizes.length == 2 && !Array.isArray(sizes[0])) { + } else if (sizes.length == 2 && !Array.isArray(sizes[0])) { imp.video = { w: sizes[0], h: sizes[1] }; + } else { + return; } if (video.durationRangeSec) {