diff --git a/modules/insticatorBidAdapter.js b/modules/insticatorBidAdapter.js index c967f530e75..4d069cc91a6 100644 --- a/modules/insticatorBidAdapter.js +++ b/modules/insticatorBidAdapter.js @@ -1,5 +1,5 @@ import {config} from '../src/config.js'; -import {BANNER} from '../src/mediaTypes.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {deepAccess, generateUUID, logError, isArray} from '../src/utils.js'; import {getStorageManager} from '../src/storageManager.js'; @@ -48,14 +48,9 @@ function setUserId(userId) { } } -function buildImpression(bidRequest) { +function buildBanner(bidRequest) { const format = []; - const ext = { - insticator: { - adUnitId: bidRequest.params.adUnitId, - }, - } - + const pos = deepAccess(bidRequest, 'mediaTypes.banner.pos'); const sizes = deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes; @@ -66,27 +61,47 @@ function buildImpression(bidRequest) { }); } - const gpid = deepAccess(bidRequest, 'ortb2Imp.ext.gpid'); - - if (gpid) { - ext.gpid = gpid; + return { + format, + pos, } +} - const instl = deepAccess(bidRequest, 'ortb2Imp.instl') - const secure = location.protocol === 'https:' ? 1 : 0; - const pos = deepAccess(bidRequest, 'mediaTypes.banner.pos'); +function buildVideo(bidRequest) { + const w = deepAccess(bidRequest, 'mediaTypes.video.w'); + const h = deepAccess(bidRequest, 'mediaTypes.video.h'); + const mimes = deepAccess(bidRequest, 'mediaTypes.video.mimes'); return { + mimes, + w, + h, + } +} + +function buildImpression(bidRequest) { + const imp = { id: bidRequest.bidId, tagid: bidRequest.adUnitCode, - instl, - secure, - banner: { - format, - pos, + instl: deepAccess(bidRequest, 'ortb2Imp.instl'), + secure: location.protocol === 'https:' ? 1 : 0, + ext: { + gpid: deepAccess(bidRequest, 'ortb2Imp.ext.gpid'), + insticator: { + adUnitId: bidRequest.params.adUnitId, + }, }, - ext, - }; + } + + if (deepAccess(bidRequest, 'mediaTypes.banner')) { + imp.banner = buildBanner(bidRequest); + } + + if (deepAccess(bidRequest, 'mediaTypes.video')) { + imp.video = buildVideo(bidRequest); + } + + return imp; } function buildDevice() { @@ -252,31 +267,83 @@ function validateSizes(sizes) { ); } -export const spec = { - code: BIDDER_CODE, - gvlid: GVLID, - supportedMediaTypes: [BANNER], +function validateAdUnitId(bid) { + if (!bid.params.adUnitId) { + logError('insticator: missing adUnitId bid parameter'); + return false; + } - isBidRequestValid: function (bid) { - if (!bid.params.adUnitId) { - logError('insticator: missing adUnitId bid parameter'); - return false; - } + return true; +} - if (!(BANNER in bid.mediaTypes)) { - logError('insticator: expected banner in mediaTypes'); - return false; - } +function validateMediaType(bid) { + if (!(BANNER in bid.mediaTypes || VIDEO in bid.mediaTypes)) { + logError('insticator: expected banner or video in mediaTypes'); + return false; + } - if ( - !validateSizes(bid.sizes) && - !validateSizes(bid.mediaTypes.banner.sizes) - ) { - logError('insticator: banner sizes not specified or invalid'); - return false; - } + return true; +} +function validateBanner(bid) { + const banner = deepAccess(bid, 'mediaTypes.banner'); + + if (banner === undefined) { return true; + } + + if ( + !validateSizes(bid.sizes) && + !validateSizes(bid.mediaTypes.banner.sizes) + ) { + logError('insticator: banner sizes not specified or invalid'); + return false; + } + + return true; +} + +function validateVideo(bid) { + const video = deepAccess(bid, 'mediaTypes.video'); + + if (video === undefined) { + return true; + } + + const videoSize = [ + deepAccess(bid, 'mediaTypes.video.w'), + deepAccess(bid, 'mediaTypes.video.h'), + ]; + + if ( + !validateSize(videoSize) + ) { + logError('insticator: video size not specified or invalid'); + return false; + } + + const mimes = deepAccess(bid, 'mediaTypes.video.mimes'); + + if (!Array.isArray(mimes) || mimes.length === 0) { + logError('insticator: mimes not specified'); + return false; + } + + return true; +} + +export const spec = { + code: BIDDER_CODE, + gvlid: GVLID, + supportedMediaTypes: [ BANNER, VIDEO ], + + isBidRequestValid: function (bid) { + return ( + validateAdUnitId(bid) && + validateMediaType(bid) && + validateBanner(bid) && + validateVideo(bid) + ); }, buildRequests: function (validBidRequests, bidderRequest) { diff --git a/test/spec/modules/insticatorBidAdapter_spec.js b/test/spec/modules/insticatorBidAdapter_spec.js index 03e034f060a..211addaf626 100644 --- a/test/spec/modules/insticatorBidAdapter_spec.js +++ b/test/spec/modules/insticatorBidAdapter_spec.js @@ -27,7 +27,15 @@ describe('InsticatorBidAdapter', function () { banner: { sizes: [[300, 250], [300, 600]], pos: 4, - } + }, + video: { + mimes: [ + 'video/mp4', + 'video/mpeg', + ], + w: 250, + h: 300, + }, }, bidId: '30b31c1838de1e', ortb2Imp: { @@ -116,6 +124,35 @@ describe('InsticatorBidAdapter', function () { bidRequest.mediaTypes.banner.sizes = [[300, 250], [300, 600]]; expect(spec.isBidRequestValid({ ...bidRequest, ...{ sizes: {} } })).to.be.true; }); + + it('should return true if there is video and video sizes', () => { + expect(spec.isBidRequestValid({ + ...bidRequest, + ...{ + mediaTypes: { + video: { + mimes: [ + 'video/mp4', + 'video/mpeg', + ], + w: 250, + h: 300, + }, + } + } + })).to.be.true; + }); + + it('should return false if there is no video sizes', () => { + expect(spec.isBidRequestValid({ + ...bidRequest, + ...{ + mediaTypes: { + video: {}, + } + } + })).to.be.false; + }); }); describe('buildRequests', function () { @@ -240,6 +277,14 @@ describe('InsticatorBidAdapter', function () { { w: 300, h: 600 }, ] }, + video: { + mimes: [ + 'video/mp4', + 'video/mpeg', + ], + h: 300, + w: 250, + }, ext: { gpid: bidRequest.ortb2Imp.ext.gpid, insticator: {