diff --git a/modules/insticatorBidAdapter.js b/modules/insticatorBidAdapter.js index a18c893b5fc..193337d1503 100644 --- a/modules/insticatorBidAdapter.js +++ b/modules/insticatorBidAdapter.js @@ -68,17 +68,42 @@ function buildBanner(bidRequest) { } function buildVideo(bidRequest) { - const w = deepAccess(bidRequest, 'mediaTypes.video.w'); - const h = deepAccess(bidRequest, 'mediaTypes.video.h'); + let w = deepAccess(bidRequest, 'mediaTypes.video.w'); + let h = deepAccess(bidRequest, 'mediaTypes.video.h'); const mimes = deepAccess(bidRequest, 'mediaTypes.video.mimes'); const placement = deepAccess(bidRequest, 'mediaTypes.video.placement') || 3; + const plcmt = deepAccess(bidRequest, 'mediaTypes.video.plcmt') || undefined; + const playerSize = deepAccess(bidRequest, 'mediaTypes.video.playerSize'); + + if (!w && playerSize) { + if (Array.isArray(playerSize[0])) { + w = parseInt(playerSize[0][0], 10); + } else if (typeof playerSize[0] === 'number' && !isNaN(playerSize[0])) { + w = parseInt(playerSize[0], 10); + } + } + if (!h && playerSize) { + if (Array.isArray(playerSize[0])) { + h = parseInt(playerSize[0][1], 10); + } else if (typeof playerSize[1] === 'number' && !isNaN(playerSize[1])) { + h = parseInt(playerSize[1], 10); + } + } - return { + let videoObj = { placement, mimes, w, h, } + + if (plcmt) { + videoObj = { + ...videoObj, + plcmt + } + } + return videoObj } function buildImpression(bidRequest) { @@ -235,7 +260,11 @@ function buildBid(bid, bidderRequest) { meta.advertiserDomains = bid.adomain } - return { + let mediaType = 'banner'; + if (bid.adm && bid.adm.includes(' 0 ? {meta} : {}) }; + + if (mediaType === 'video') { + bidResponse.vastXml = bid.adm; + } + + // Inticator bid adaptor only returns `vastXml` for video bids. No VastUrl or videoCache. + if (!bidResponse.vastUrl && bidResponse.vastXml) { + bidResponse.vastUrl = 'data:text/xml;charset=utf-8;base64,' + window.btoa(bidResponse.vastXml.replace(/\\"/g, '"')); + } + + return bidResponse; } function buildBidSet(seatbid, bidderRequest) { @@ -315,9 +355,26 @@ function validateVideo(bid) { return true; } + let w = deepAccess(bid, 'mediaTypes.video.w'); + let h = deepAccess(bid, 'mediaTypes.video.h'); + const playerSize = deepAccess(bid, 'mediaTypes.video.playerSize'); + if (!w && playerSize) { + if (Array.isArray(playerSize[0])) { + w = parseInt(playerSize[0][0], 10); + } else if (typeof playerSize[0] === 'number' && !isNaN(playerSize[0])) { + w = parseInt(playerSize[0], 10); + } + } + if (!h && playerSize) { + if (Array.isArray(playerSize[0])) { + h = parseInt(playerSize[0][1], 10); + } else if (typeof playerSize[1] === 'number' && !isNaN(playerSize[1])) { + h = parseInt(playerSize[1], 10); + } + } const videoSize = [ - deepAccess(bid, 'mediaTypes.video.w'), - deepAccess(bid, 'mediaTypes.video.h'), + w, + h, ]; if ( @@ -341,6 +398,13 @@ function validateVideo(bid) { return false; } + const plcmt = deepAccess(bid, 'mediaTypes.video.plcmt'); + + if (typeof plcmt !== 'undefined' && typeof plcmt !== 'number') { + logError('insticator: video plcmt is not a number'); + return false; + } + return true; } diff --git a/test/spec/modules/insticatorBidAdapter_spec.js b/test/spec/modules/insticatorBidAdapter_spec.js index e24bcb3b455..36b6dd8fbf2 100644 --- a/test/spec/modules/insticatorBidAdapter_spec.js +++ b/test/spec/modules/insticatorBidAdapter_spec.js @@ -179,6 +179,43 @@ describe('InsticatorBidAdapter', function () { } })).to.be.false; }); + + it('should return false if video plcmt is not a number', () => { + expect(spec.isBidRequestValid({ + ...bidRequest, + ...{ + mediaTypes: { + video: { + mimes: [ + 'video/mp4', + 'video/mpeg', + ], + w: 250, + h: 300, + plcmt: 'NaN', + }, + } + } + })).to.be.false; + }); + + it('should return true if playerSize is present instead of w and h', () => { + expect(spec.isBidRequestValid({ + ...bidRequest, + ...{ + mediaTypes: { + video: { + mimes: [ + 'video/mp4', + 'video/mpeg', + ], + playerSize: [250, 300], + placement: 1, + }, + } + } + })).to.be.true; + }); }); describe('buildRequests', function () { @@ -570,4 +607,87 @@ describe('InsticatorBidAdapter', function () { expect(spec.getUserSyncs({}, [response])).to.have.length(0); }) }); + + describe('Response with video Instream', function () { + const bidRequestVid = { + method: 'POST', + url: 'https://ex.ingage.tech/v1/openrtb', + options: { + contentType: 'application/json', + withCredentials: true, + }, + data: '', + bidderRequest: { + bidderRequestId: '22edbae2733bf6', + auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', + timeout: 300, + bids: [ + { + bidder: 'insticator', + params: { + adUnitId: '1a2b3c4d5e6f1a2b3c4d' + }, + adUnitCode: 'adunit-code-1', + mediaTypes: { + video: { + mimes: [ + 'video/mp4', + 'video/mpeg', + ], + playerSize: [[250, 300]], + placement: 2, + plcmt: 2, + } + }, + bidId: 'bid1', + } + ] + } + }; + + const bidResponseVid = { + body: { + id: '22edbae2733bf6', + bidid: 'foo9876', + cur: 'USD', + seatbid: [ + { + seat: 'some-dsp', + bid: [ + { + ad: '', + impid: 'bid1', + crid: 'crid1', + price: 0.5, + w: 300, + h: 250, + adm: '', + exp: 60, + adomain: ['test1.com'], + ext: { + meta: { + test: 1 + } + }, + } + ], + }, + ] + } + }; + const bidRequestWithVideo = utils.deepClone(bidRequestVid); + + it('should have related properties for video Instream', function() { + const serverResponseWithInstream = utils.deepClone(bidResponseVid); + serverResponseWithInstream.body.seatbid[0].bid[0].vastXml = ''; + serverResponseWithInstream.body.seatbid[0].bid[0].mediaType = 'video'; + const bidResponse = spec.interpretResponse(serverResponseWithInstream, bidRequestWithVideo)[0]; + expect(bidResponse).to.have.any.keys('mediaType', 'vastXml', 'vastUrl'); + expect(bidResponse).to.have.property('mediaType', 'video'); + expect(bidResponse.width).to.equal(300); + expect(bidResponse.height).to.equal(250); + expect(bidResponse).to.have.property('vastXml', ''); + expect(bidResponse.vastUrl).to.match(/^data:text\/xml;charset=utf-8;base64,[\w+/=]+$/) + }); + }) });