diff --git a/modules/pulsepointBidAdapter.js b/modules/pulsepointBidAdapter.js index cbe37e66cd7..d3655906cf0 100644 --- a/modules/pulsepointBidAdapter.js +++ b/modules/pulsepointBidAdapter.js @@ -133,8 +133,8 @@ function bidResponseAvailable(request, response) { bid.height = idToBidMap[id].h; } else { bid.ad = idToBidMap[id].adm; - bid.width = idToImpMap[id].banner.w; - bid.height = idToImpMap[id].banner.h; + bid.width = idToBidMap[id].w || idToImpMap[id].banner.w; + bid.height = idToBidMap[id].h || idToImpMap[id].banner.h; } bids.push(bid); } @@ -161,14 +161,30 @@ function impression(slot) { * Produces an OpenRTB Banner object for the slot given. */ function banner(slot) { - const size = adSize(slot); + const sizes = parseSizes(slot); + const size = adSize(slot, sizes); return (slot.nativeParams || slot.params.video) ? null : { w: size[0], h: size[1], battr: slot.params.battr, + format: sizes }; } +/** + * Produce openrtb format objects based on the sizes configured for the slot. + */ +function parseSizes(slot) { + const sizes = utils.deepAccess(slot, 'mediaTypes.banner.sizes'); + if (sizes && utils.isArray(sizes)) { + return sizes.filter(sz => utils.isArray(sz) && sz.length === 2).map(sz => ({ + w: sz[0], + h: sz[1] + })); + } + return null; +} + /** * Produces an OpenRTB Video object for the slot given */ @@ -372,12 +388,14 @@ function parse(rawResponse) { /** * Determines the AdSize for the slot. */ -function adSize(slot) { +function adSize(slot, sizes) { if (slot.params.cf) { const size = slot.params.cf.toUpperCase().split('X'); const width = parseInt(slot.params.cw || size[0], 10); const height = parseInt(slot.params.ch || size[1], 10); return [width, height]; + } else if (sizes && sizes.length > 0) { + return [sizes[0].w, sizes[0].h]; } return [1, 1]; } diff --git a/test/spec/modules/pulsepointBidAdapter_spec.js b/test/spec/modules/pulsepointBidAdapter_spec.js index ea81aa5d962..4b21856b68e 100644 --- a/test/spec/modules/pulsepointBidAdapter_spec.js +++ b/test/spec/modules/pulsepointBidAdapter_spec.js @@ -6,6 +6,11 @@ import {deepClone} from 'src/utils.js'; describe('PulsePoint Adapter Tests', function () { const slotConfigs = [{ placementCode: '/DfpAccount1/slot1', + mediaTypes: { + banner: { + sizes: [[728, 90], [160, 600]] + } + }, bidId: 'bid12345', params: { cp: 'p10000', @@ -655,4 +660,45 @@ describe('PulsePoint Adapter Tests', function () { userVerify(ortbRequest.user.ext.eids[4], 'parrable.com', 'parrable_id234'); userVerify(ortbRequest.user.ext.eids[5], 'liveintent.com', 'liveintent_id123'); }); + it('Verify multiple adsizes', function () { + const bidRequests = deepClone(slotConfigs); + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request).to.be.not.null; + expect(request.data).to.be.not.null; + const ortbRequest = request.data; + expect(ortbRequest.imp).to.have.lengthOf(2); + // first impression has multi sizes + expect(ortbRequest.imp[0].banner).to.not.be.null; + expect(ortbRequest.imp[0].banner.w).to.equal(300); + expect(ortbRequest.imp[0].banner.h).to.equal(250); + expect(ortbRequest.imp[0].banner.format).to.not.be.null; + expect(ortbRequest.imp[0].banner.format).to.have.lengthOf(2); + expect(ortbRequest.imp[0].banner.format[0].w).to.equal(728); + expect(ortbRequest.imp[0].banner.format[0].h).to.equal(90); + expect(ortbRequest.imp[0].banner.format[1].w).to.equal(160); + expect(ortbRequest.imp[0].banner.format[1].h).to.equal(600); + // slot 2 + expect(ortbRequest.imp[1].banner).to.not.be.null; + expect(ortbRequest.imp[1].banner.w).to.equal(728); + expect(ortbRequest.imp[1].banner.h).to.equal(90); + expect(ortbRequest.imp[1].banner.format).to.be.null; + // adsize on response + const ortbResponse = { + seatbid: [{ + bid: [{ + impid: ortbRequest.imp[0].id, + price: 1.25, + adm: 'This is an Ad', + crid: 'Creative#123', + w: 728, + h: 90 + }] + }] + }; + const bids = spec.interpretResponse({ body: ortbResponse }, request); + expect(bids).to.have.lengthOf(1); + const bid = bids[0]; + expect(bid.width).to.equal(728); + expect(bid.height).to.equal(90); + }); });