From a28ac0195ae5a85be8b0f5b2a27d052335056352 Mon Sep 17 00:00:00 2001 From: Lemma Dev <54662130+lemmadev@users.noreply.github.com> Date: Fri, 2 Apr 2021 16:39:05 +0530 Subject: [PATCH] Lemma Bid Adapter: accepting the floor to use the getFloor function (#6497) * lemmaBidAdapter.js Added lemma bid adapter file * lemmaBidAdapter.md Added lemma bid adapter md file * lemmaBidAdapter_spec.js Added lemma bid adapter test spec file * Update lemmaBidAdapter.js Fixed automated code review alert comparison between inconvertible types * Update lemmaBidAdapter.js Fixed review changes * Update lemmaBidAdapter.md Correct parameter value. * Update lemmaBidAdapter.js Lemma Bid Adapter - v3.0 compliance * Update lemmaBidAdapter_spec.js Lemma Bid Adapter - v3.0 compliance * Update lemmaBidAdapter.md Lemma Bid Adapter - v3.0 compliance * Update lemmaBidAdapter.js Added user sync support into bid adapter. * updated include modules file extension. updated include modules js file extension. * Update lemmaBidAdapter_spec.js Added unit test for user sync feature. * Update lemmaBidAdapter.js Fixed format error. * Update lemmaBidAdapter_spec.js Fixed format error and typo error. * Set mediaType key value into bid object Set mediaType key value into the bid object. * Update lemmaBidAdapter.js remove duplicate function * Update lemmaBidAdapter.js Remove non supported code. * Update lemmaBidAdapter_spec.js Remove GDPR test cases. * Update lemmaBidAdapter.js Made changes for accepting the floor to use the getFloor function * Update lemmaBidAdapter.js correct undefined keyword name. * Update lemmaBidAdapter_spec.js Added test coverage floor value * Update lemmaBidAdapter.js Remove trailing spaces on lines 379 and 381. * Update lemmaBidAdapter_spec.js Added getFloor function test case changes, Please review it. * Update lemmaBidAdapter_spec.js * Update lemmaBidAdapter.js * Update lemmaBidAdapter.js Fixed lint issue. * Update lemmaBidAdapter_spec.js Fixed test cases. * Update lemmaBidAdapter_spec.js Made suggested changes. Please review it. Co-authored-by: Abhijit Mane --- modules/lemmaBidAdapter.js | 28 ++++++++- test/spec/modules/lemmaBidAdapter_spec.js | 75 +++++++++++++++++++++++ 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/modules/lemmaBidAdapter.js b/modules/lemmaBidAdapter.js index 926761e5ab2..c7440743d2c 100644 --- a/modules/lemmaBidAdapter.js +++ b/modules/lemmaBidAdapter.js @@ -84,6 +84,30 @@ function _initConf(refererInfo) { return conf; } +function _setFloor(impObj, bid) { + let bidFloor = -1; + // get lowest floor from floorModule + if (typeof bid.getFloor === 'function') { + [BANNER, VIDEO].forEach(mediaType => { + if (impObj.hasOwnProperty(mediaType)) { + let floorInfo = bid.getFloor({ currency: impObj.bidfloorcur, mediaType: mediaType, size: '*' }); + if (typeof floorInfo === 'object' && floorInfo.currency === impObj.bidfloorcur && !isNaN(parseInt(floorInfo.floor))) { + let mediaTypeFloor = parseFloat(floorInfo.floor); + bidFloor = (bidFloor == -1 ? mediaTypeFloor : Math.min(mediaTypeFloor, bidFloor)) + } + } + }); + } + // get highest from impObj.bidfllor and floor from floor module + // as we are using Math.max, it is ok if we have not got any floor from floorModule, then value of bidFloor will be -1 + if (impObj.bidfloor) { + bidFloor = Math.max(bidFloor, impObj.bidfloor) + } + + // assign value only if bidFloor is > 0 + impObj.bidfloor = ((!isNaN(bidFloor) && bidFloor > 0) ? bidFloor : undefined); +} + function parseRTBResponse(request, response) { var bidResponses = []; try { @@ -352,11 +376,9 @@ function _getImpressionObject(bid) { secure: window.location.protocol === 'https:' ? 1 : 0, bidfloorcur: params.currency ? params.currency : DEFAULT_CURRENCY }; - if (params.bidFloor) { impression.bidfloor = params.bidFloor; } - if (bid.hasOwnProperty('mediaTypes')) { for (mediaTypes in bid.mediaTypes) { switch (mediaTypes) { @@ -392,7 +414,7 @@ function _getImpressionObject(bid) { } impression.banner = bObj; } - + _setFloor(impression, bid); return impression.hasOwnProperty(BANNER) || impression.hasOwnProperty(VIDEO) ? impression : undefined; } diff --git a/test/spec/modules/lemmaBidAdapter_spec.js b/test/spec/modules/lemmaBidAdapter_spec.js index a22f5650e50..a3a70a39731 100644 --- a/test/spec/modules/lemmaBidAdapter_spec.js +++ b/test/spec/modules/lemmaBidAdapter_spec.js @@ -23,6 +23,7 @@ describe('lemmaBidAdapter', function() { pubId: 1001, adunitId: 1, currency: 'AUD', + bidFloor: 1.3, geo: { lat: '12.3', lon: '23.7', @@ -46,6 +47,7 @@ describe('lemmaBidAdapter', function() { params: { pubId: 1001, adunitId: 1, + bidFloor: 1.3, video: { mimes: ['video/mp4', 'video/x-flv'], skippable: true, @@ -161,6 +163,7 @@ describe('lemmaBidAdapter', function() { expect(data.site.publisher.id).to.equal(bidRequests[0].params.pubId.toString()); // publisher Id expect(data.imp[0].tagid).to.equal('1'); // tagid expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency); + expect(data.imp[0].bidfloor).to.equal(bidRequests[0].params.bidFloor); }); it('Request params check without mediaTypes object', function() { var bidRequests = [{ @@ -192,6 +195,7 @@ describe('lemmaBidAdapter', function() { expect(data.site.publisher.id).to.equal(bidRequests[0].params.pubId.toString()); // publisher Id expect(data.imp[0].tagid).to.equal(undefined); // tagid expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency); + expect(data.imp[0].bidfloor).to.equal(bidRequests[0].params.bidFloor); }); it('Request params multi size format object check', function() { var bidRequests = [{ @@ -309,6 +313,77 @@ describe('lemmaBidAdapter', function() { expect(data.imp[0]['video']['w']).to.equal(videoBidRequests[0].mediaTypes.video.playerSize[0]); expect(data.imp[0]['video']['h']).to.equal(videoBidRequests[0].mediaTypes.video.playerSize[1]); }); + describe('setting imp.floor using floorModule', function() { + /* + Use the minimum value among floor from floorModule per mediaType + If params.bidFloor is set then take max(floor, min(floors from floorModule)) + set imp.bidfloor only if it is more than 0 + */ + + let newRequest; + let floorModuleTestData; + let getFloor = function(req) { + return floorModuleTestData[req.mediaType]; + }; + + beforeEach(() => { + floorModuleTestData = { + 'banner': { + 'currency': 'AUD', + 'floor': 1.50 + }, + 'video': { + 'currency': 'AUD', + 'floor': 2.00 + } + }; + newRequest = utils.deepClone(bidRequests); + newRequest[0].getFloor = getFloor; + }); + + it('bidfloor should be undefined if calculation is <= 0', function() { + floorModuleTestData.banner.floor = 0; // lowest of them all + newRequest[0].params.bidFloor = undefined; + let request = spec.buildRequests(newRequest); + let data = JSON.parse(request.data); + data = data.imp[0]; + expect(data.bidfloor).to.equal(undefined); + }); + + it('ignore floormodule o/p if floor is not number', function() { + floorModuleTestData.banner.floor = 'INR'; + newRequest[0].params.bidFloor = undefined; + let request = spec.buildRequests(newRequest); + let data = JSON.parse(request.data); + data = data.imp[0]; + expect(data.bidfloor).to.equal(undefined); // video will be lowest now + }); + + it('ignore floormodule o/p if currency is not matched', function() { + floorModuleTestData.banner.currency = 'INR'; + newRequest[0].params.bidFloor = undefined; + let request = spec.buildRequests(newRequest); + let data = JSON.parse(request.data); + data = data.imp[0]; + expect(data.bidfloor).to.equal(undefined); // video will be lowest now + }); + + it('bidFloor is not passed, use minimum from floorModule', function() { + newRequest[0].params.bidFloor = undefined; + let request = spec.buildRequests(newRequest); + let data = JSON.parse(request.data); + data = data.imp[0]; + expect(data.bidfloor).to.equal(1.5); + }); + + it('bidFloor is passed as 1, use min of floorModule as it is highest', function() { + newRequest[0].params.bidFloor = '1.0';// yes, we want it as a string + let request = spec.buildRequests(newRequest); + let data = JSON.parse(request.data); + data = data.imp[0]; + expect(data.bidfloor).to.equal(1.5); + }); + }); describe('Response checking', function() { it('should check for valid response values', function() { var request = spec.buildRequests(bidRequests);