diff --git a/modules/rtbhouseBidAdapter.js b/modules/rtbhouseBidAdapter.js index 6b8fe05e8bb..036bdfaebeb 100644 --- a/modules/rtbhouseBidAdapter.js +++ b/modules/rtbhouseBidAdapter.js @@ -7,6 +7,7 @@ const BIDDER_CODE = 'rtbhouse'; const REGIONS = ['prebid-eu', 'prebid-us', 'prebid-asia']; const ENDPOINT_URL = 'creativecdn.com/bidder/prebid/bids'; const DEFAULT_CURRENCY_ARR = ['USD']; // NOTE - USD is the only supported currency right now; Hardcoded for bids +const SUPPORTED_MEDIA_TYPES = [BANNER, NATIVE]; const TTL = 55; // Codes defined by OpenRTB Native Ads 1.1 specification @@ -34,7 +35,7 @@ export const OPENRTB = { export const spec = { code: BIDDER_CODE, - supportedMediaTypes: [BANNER, NATIVE], + supportedMediaTypes: SUPPORTED_MEDIA_TYPES, isBidRequestValid: function (bid) { return !!(includes(REGIONS, bid.params.region) && bid.params.publisherId); @@ -55,6 +56,23 @@ export const spec = { request.regs = {ext: {gdpr: gdpr}}; request.user = {ext: {consent: consentStr}}; } + if (validBidRequests[0].schain) { + const schain = mapSchain(validBidRequests[0].schain); + if (schain) { + request.ext = { + schain: schain, + } + } + } + + if (validBidRequests[0].userIdAsEids) { + const eids = { eids: validBidRequests[0].userIdAsEids }; + if (request.user && request.user.ext) { + request.user.ext = { ...request.user.ext, ...eids }; + } else { + request.user = {ext: eids}; + } + } return { method: 'POST', @@ -85,6 +103,22 @@ export const spec = { }; registerBidder(spec); +/** + * @param {object} slot Ad Unit Params by Prebid + * @returns {int} floor by imp type + */ +function applyFloor(slot) { + const floors = []; + if (typeof slot.getFloor === 'function') { + Object.keys(slot.mediaTypes).forEach(type => { + if (includes(SUPPORTED_MEDIA_TYPES, type)) { + floors.push(slot.getFloor({ currency: DEFAULT_CURRENCY_ARR[0], mediaType: type, size: slot.sizes || '*' }).floor); + } + }); + } + return floors.length > 0 ? Math.max(...floors) : parseFloat(slot.params.bidfloor); +} + /** * @param {object} slot Ad Unit Params by Prebid * @returns {object} Imp by OpenRTB 2.5 ยง3.2.4 @@ -97,9 +131,9 @@ function mapImpression(slot) { tagid: slot.adUnitCode.toString() }; - const bidfloor = parseFloat(slot.params.bidfloor); + const bidfloor = applyFloor(slot); if (bidfloor) { - imp.bidfloor = bidfloor + imp.bidfloor = bidfloor; } return imp; @@ -151,12 +185,7 @@ function mapSource(slot) { const source = { tid: slot.transactionId, }; - const schain = mapSchain(slot.schain); - if (schain) { - source.ext = { - schain: schain - } - } + return source; } diff --git a/test/spec/modules/rtbhouseBidAdapter_spec.js b/test/spec/modules/rtbhouseBidAdapter_spec.js index 77dfff35c4a..d6bee26d73b 100644 --- a/test/spec/modules/rtbhouseBidAdapter_spec.js +++ b/test/spec/modules/rtbhouseBidAdapter_spec.js @@ -51,38 +51,7 @@ describe('RTBHouseAdapter', () => { }); describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': 'rtbhouse', - 'params': { - 'publisherId': 'PREBID_TEST', - 'region': 'prebid-eu', - 'test': 1 - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]], - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'transactionId': 'example-transaction-id', - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'directseller.com', - 'sid': '00001', - 'rid': 'BidRequest1', - 'hp': 1 - } - ] - } - } - ]; + let bidRequests; const bidderRequest = { 'refererInfo': { 'numIframes': 0, @@ -92,6 +61,41 @@ describe('RTBHouseAdapter', () => { } }; + beforeEach(() => { + bidRequests = [ + { + 'bidder': 'rtbhouse', + 'params': { + 'publisherId': 'PREBID_TEST', + 'region': 'prebid-eu', + 'test': 1 + }, + 'adUnitCode': 'adunit-code', + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250], [300, 600]], + } + }, + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + 'transactionId': 'example-transaction-id', + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'directseller.com', + 'sid': '00001', + 'rid': 'BidRequest1', + 'hp': 1 + } + ] + } + } + ]; + }); + it('should build test param into the request', () => { let builtTestRequest = spec.buildRequests(bidRequests, bidderRequest).data; expect(JSON.parse(builtTestRequest).test).to.equal(1); @@ -177,6 +181,23 @@ describe('RTBHouseAdapter', () => { expect(data.source.tid).to.equal('example-transaction-id'); }); + it('should include bidfloor from floor module if avaiable', () => { + const bidRequest = Object.assign([], bidRequests); + bidRequest[0].getFloor = () => ({floor: 1.22}); + const request = spec.buildRequests(bidRequest, bidderRequest); + const data = JSON.parse(request.data); + expect(data.imp[0].bidfloor).to.equal(1.22) + }); + + it('should use bidfloor from floor module if both floor module and bid floor avaiable', () => { + const bidRequest = Object.assign([], bidRequests); + bidRequest[0].getFloor = () => ({floor: 1.22}); + bidRequest[0].params.bidfloor = 0.01; + const request = spec.buildRequests(bidRequest, bidderRequest); + const data = JSON.parse(request.data); + expect(data.imp[0].bidfloor).to.equal(1.22) + }); + it('should include bidfloor in request if available', () => { const bidRequest = Object.assign([], bidRequests); bidRequest[0].params.bidfloor = 0.01; @@ -185,11 +206,11 @@ describe('RTBHouseAdapter', () => { expect(data.imp[0].bidfloor).to.equal(0.01) }); - it('should include source.ext.schain in request', () => { + it('should include schain in request', () => { const bidRequest = Object.assign([], bidRequests); const request = spec.buildRequests(bidRequest, bidderRequest); const data = JSON.parse(request.data); - expect(data.source.ext.schain).to.deep.equal({ + expect(data.ext.schain).to.deep.equal({ 'ver': '1.0', 'complete': 1, 'nodes': [ @@ -203,6 +224,13 @@ describe('RTBHouseAdapter', () => { }); }); + it('should include source.tid in request', () => { + const bidRequest = Object.assign([], bidRequests); + const request = spec.buildRequests(bidRequest, bidderRequest); + const data = JSON.parse(request.data); + expect(data.source).to.have.deep.property('tid'); + }); + it('should not include invalid schain', () => { const bidRequest = Object.assign([], bidRequests); bidRequest[0].schain = {