diff --git a/modules/synacormediaBidAdapter.js b/modules/synacormediaBidAdapter.js index 7694f5d838e..96616bb6a48 100644 --- a/modules/synacormediaBidAdapter.js +++ b/modules/synacormediaBidAdapter.js @@ -1,6 +1,6 @@ 'use strict'; -import { getAdUnitSizes, logWarn, deepSetValue } from '../src/utils.js'; +import { getAdUnitSizes, logWarn, deepSetValue, isFn, isPlainObject } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; import includes from 'core-js-pure/features/array/includes.js'; @@ -67,11 +67,7 @@ export const spec = { } else { seatId = bid.params.seatId; } - const tagIdOrplacementId = bid.params.tagId || bid.params.placementId; - const bidFloor = bid.params.bidfloor ? parseFloat(bid.params.bidfloor) : null; - if (isNaN(bidFloor)) { - logWarn(`Synacormedia: there is an invalid bid floor: ${bid.params.bidfloor}`); - } + const tagIdOrPlacementId = bid.params.tagId || bid.params.placementId; let pos = parseInt(bid.params.pos, 10); if (isNaN(pos)) { logWarn(`Synacormedia: there is an invalid POS: ${bid.params.pos}`); @@ -83,9 +79,9 @@ export const spec = { let imps = []; if (videoOrBannerKey === 'banner') { - imps = this.buildBannerImpressions(adSizes, bid, tagIdOrplacementId, pos, bidFloor, videoOrBannerKey); + imps = this.buildBannerImpressions(adSizes, bid, tagIdOrPlacementId, pos, videoOrBannerKey); } else if (videoOrBannerKey === 'video') { - imps = this.buildVideoImpressions(adSizes, bid, tagIdOrplacementId, pos, bidFloor, videoOrBannerKey); + imps = this.buildVideoImpressions(adSizes, bid, tagIdOrPlacementId, pos, videoOrBannerKey); } if (imps.length > 0) { imps.forEach(i => openRtbBidRequest.imp.push(i)); @@ -128,7 +124,7 @@ export const spec = { return eids; }, - buildBannerImpressions: function (adSizes, bid, tagIdOrPlacementId, pos, bidFloor, videoOrBannerKey) { + buildBannerImpressions: function (adSizes, bid, tagIdOrPlacementId, pos, videoOrBannerKey) { let format = []; let imps = []; adSizes.forEach((size, i) => { @@ -151,6 +147,10 @@ export const spec = { }, tagid: tagIdOrPlacementId, }; + const bidFloor = getBidFloor(bid, 'banner', '*'); + if (isNaN(bidFloor)) { + logWarn(`Synacormedia: there is an invalid bid floor: ${bid.params.bidfloor}`); + } if (bidFloor !== null && !isNaN(bidFloor)) { imp.bidfloor = bidFloor; } @@ -159,7 +159,7 @@ export const spec = { return imps; }, - buildVideoImpressions: function(adSizes, bid, tagIdOrPlacementId, pos, bidFloor, videoOrBannerKey) { + buildVideoImpressions: function(adSizes, bid, tagIdOrPlacementId, pos, videoOrBannerKey) { let imps = []; adSizes.forEach((size, i) => { if (!size || size.length != 2) { @@ -171,6 +171,11 @@ export const spec = { id: `${videoOrBannerKey.substring(0, 1)}${bid.bidId}-${size0}x${size1}`, tagid: tagIdOrPlacementId }; + const bidFloor = getBidFloor(bid, 'video', size); + if (isNaN(bidFloor)) { + logWarn(`Synacormedia: there is an invalid bid floor: ${bid.params.bidfloor}`); + } + if (bidFloor !== null && !isNaN(bidFloor)) { imp.bidfloor = bidFloor; } @@ -287,4 +292,20 @@ export const spec = { } }; +function getBidFloor(bid, mediaType, size) { + if (!isFn(bid.getFloor)) { + return bid.params.bidfloor ? parseFloat(bid.params.bidfloor) : null; + } + let floor = bid.getFloor({ + currency: 'USD', + mediaType, + size + }); + + if (isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === 'USD') { + return floor.floor; + } + return null; +} + registerBidder(spec); diff --git a/test/spec/modules/synacormediaBidAdapter_spec.js b/test/spec/modules/synacormediaBidAdapter_spec.js index 5f3633ec311..c053771c296 100644 --- a/test/spec/modules/synacormediaBidAdapter_spec.js +++ b/test/spec/modules/synacormediaBidAdapter_spec.js @@ -1231,4 +1231,74 @@ describe('synacormediaBidAdapter ', function () { expect(usersyncs).to.be.an('array').that.is.empty; }); }); + + describe('Bid Requests with price module should use if available', function () { + let validVideoBidRequest = { + bidder: 'synacormedia', + params: { + bidfloor: '0.50', + seatId: 'prebid', + placementId: 'demo1', + pos: 1, + video: {} + }, + renderer: { + url: '../syncOutstreamPlayer.js' + }, + mediaTypes: { + video: { + playerSize: [[300, 250]], + context: 'outstream' + } + }, + adUnitCode: 'div-1', + transactionId: '0869f34e-090b-4b20-84ee-46ff41405a39', + sizes: [[300, 250]], + bidId: '22b3a2268d9f0e', + bidderRequestId: '1d195910597e13', + auctionId: '3375d336-2aea-4ee7-804c-6d26b621ad20', + src: 'client', + bidRequestsCount: 1, + bidderRequestsCount: 1, + bidderWinsCount: 0 + }; + + let validBannerBidRequest = { + bidId: '9876abcd', + sizes: [[300, 250]], + params: { + bidfloor: '0.50', + seatId: 'prebid', + placementId: '1234', + } + }; + + let bidderRequest = { + refererInfo: { + referer: 'http://localhost:9999/' + }, + bidderCode: 'synacormedia', + auctionId: 'f8a75621-d672-4cbb-9275-3db7d74fb110' + }; + + it('should return valid bidfloor using price module for banner/video impression', function () { + let bannerRequest = spec.buildRequests([validBannerBidRequest], bidderRequest); + let videoRequest = spec.buildRequests([validVideoBidRequest], bidderRequest); + + expect(bannerRequest.data.imp[0].bidfloor).to.equal(0.5); + expect(videoRequest.data.imp[0].bidfloor).to.equal(0.5); + + let priceModuleFloor = 3; + let floorResponse = { currency: 'USD', floor: priceModuleFloor }; + + validBannerBidRequest.getFloor = () => { return floorResponse; }; + validVideoBidRequest.getFloor = () => { return floorResponse; }; + + bannerRequest = spec.buildRequests([validBannerBidRequest], bidderRequest); + videoRequest = spec.buildRequests([validVideoBidRequest], bidderRequest); + + expect(bannerRequest.data.imp[0].bidfloor).to.equal(priceModuleFloor); + expect(videoRequest.data.imp[0].bidfloor).to.equal(priceModuleFloor); + }); + }); });