From 2dedab6b7f67b1c77009ef4e8feaba4c32c4a57d Mon Sep 17 00:00:00 2001 From: pm-nitin-shirsat Date: Wed, 12 Oct 2022 11:21:17 +0530 Subject: [PATCH 01/13] Implement functionality for deal priority --- modules/pubmaticBidAdapter.js | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 7f346b1c7b0..11163d4ac43 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -1,10 +1,11 @@ -import { logWarn, _each, isBoolean, isStr, isArray, inIframe, mergeDeep, deepAccess, isNumber, deepSetValue, logInfo, logError, deepClone, convertTypes, uniques } from '../src/utils.js'; +import { getBidRequest, logWarn, _each, isBoolean, isStr, isArray, inIframe, mergeDeep, deepAccess, isNumber, deepSetValue, logInfo, logError, deepClone, convertTypes, uniques } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO, NATIVE } from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; +import { BANNER, VIDEO, NATIVE, ADPOD } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; import { Renderer } from '../src/Renderer.js'; import { bidderSettings } from '../src/bidderSettings.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { INSTREAM } from '../src/video.js'; const BIDDER_CODE = 'pubmatic'; const LOG_WARN_PREFIX = 'PubMatic: '; @@ -953,6 +954,29 @@ function _assignRenderer(newBid, request) { } } +/** + * In case of adpod video context, assign prebiddealpriority to the dealtier property of adpod-video bid, + * so that adpod module can set the hb_pb_cat_dur targetting key. + * @param {*} newBid + * @param {*} bid + * @param {*} request + * @returns + */ +export function assignDealTier(newBid, bid, request) { + if (!bid?.ext?.prebiddealpriority) return; + const bidRequest = getBidRequest(newBid.requestId, [request.bidderRequest]); + const videoObj = deepAccess(bidRequest, 'mediaTypes.video'); + if (videoObj?.context != ADPOD) return; + + const duration = bid?.ext?.video?.duration || videoObj?.maxduration; + // if (!duration) return; + newBid.video = { + context: ADPOD, + durationSeconds: duration, + dealTier: bid.ext.prebiddealpriority + }; +} + function isNonEmptyArray(test) { if (isArray(test) === true) { if (test.length > 0) { @@ -1265,6 +1289,7 @@ export const spec = { newBid.height = bid.hasOwnProperty('h') ? bid.h : req.video.h; newBid.vastXml = bid.adm; _assignRenderer(newBid, request); + assignDealTier(newBid, bid, request); break; case NATIVE: _parseNativeResponse(bid, newBid); From afae8882289465cd29e5f7e53ef7b2b716f648be Mon Sep 17 00:00:00 2001 From: pm-nitin-shirsat Date: Wed, 12 Oct 2022 14:31:01 +0530 Subject: [PATCH 02/13] Update test cases --- modules/pubmaticBidAdapter.js | 1 - test/spec/modules/pubmaticBidAdapter_spec.js | 63 ++++++++++++++++++-- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 11163d4ac43..02198042474 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -5,7 +5,6 @@ import { config } from '../src/config.js'; import { Renderer } from '../src/Renderer.js'; import { bidderSettings } from '../src/bidderSettings.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; -import { INSTREAM } from '../src/video.js'; const BIDDER_CODE = 'pubmatic'; const LOG_WARN_PREFIX = 'PubMatic: '; diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 3f341fd259f..f554d57290d 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {spec, checkVideoPlacement, _getDomainFromURL} from 'modules/pubmaticBidAdapter.js'; +import { expect } from 'chai'; +import { spec, checkVideoPlacement, _getDomainFromURL, assignDealTier } from 'modules/pubmaticBidAdapter.js'; import * as utils from 'src/utils.js'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; import { createEidsArray } from 'modules/userId/eids.js'; import { bidderSettings } from 'src/bidderSettings.js'; const constants = require('src/constants.json'); @@ -4063,9 +4063,64 @@ describe('PubMatic adapter', function () { expect(data.imp[0]['video']['h']).to.equal(videoBidRequests[0].mediaTypes.video.playerSize[1]); expect(data.imp[0]['video']['battr']).to.equal(undefined); }); + + describe('Assign Deal Tier (i.e. prebidDealPriority)', function () { + let videoSeatBid, request, newBid; + // let data = JSON.parse(request.data); + beforeEach(function () { + videoSeatBid = videoBidResponse.body.seatbid[0].bid[0]; + // const adpodValidOutstreamBidRequest = validOutstreamBidRequest.bids[0].mediaTypes.video.context = 'adpod'; + request = spec.buildRequests(bidRequests, validOutstreamBidRequest); + newBid = { + requestId: '47acc48ad47af5' + }; + videoSeatBid.ext = videoSeatBid.ext || {}; + videoSeatBid.ext.video = videoSeatBid.ext.video || {}; + // videoBidRequests[0].mediaTypes.video = videoBidRequests[0].mediaTypes.video || {}; + }); + + it('should not assign video object if deal priority is missing', function () { + assignDealTier(newBid, videoSeatBid, request); + expect(newBid.video).to.equal(undefined); + expect(newBid.video).to.not.exist; + }); + + it('should not assign video object if context is not a adpod', function () { + videoSeatBid.ext.prebiddealpriority = 5; + assignDealTier(newBid, videoSeatBid, request); + expect(newBid.video).to.equal(undefined); + expect(newBid.video).to.not.exist; + }); + + describe('when video deal tier object is present', function () { + beforeEach(function () { + videoSeatBid.ext.prebiddealpriority = 5; + request.bidderRequest.bids[0].mediaTypes.video = { + ...request.bidderRequest.bids[0].mediaTypes.video, + context: 'adpod', + maxduration: 50 + }; + }); + + it('should set video deal tier object, when maxduration is present in ext', function () { + assignDealTier(newBid, videoSeatBid, request); + expect(newBid.video.durationSeconds).to.equal(50); + expect(newBid.video.context).to.equal('adpod'); + expect(newBid.video.dealTier).to.equal(5); + }); + + it('should set video deal tier object, when duration is present in ext', function () { + videoSeatBid.ext.video.duration = 20; + assignDealTier(newBid, videoSeatBid, request); + expect(newBid.video.durationSeconds).to.equal(20); + expect(newBid.video.context).to.equal('adpod'); + expect(newBid.video.dealTier).to.equal(5); + }); + }); + }); }); - describe('Marketplace params', function() { + describe('Marketplace params', function () { let sandbox, utilsMock, newBidRequests, newBidResponses; beforeEach(() => { utilsMock = sinon.mock(utils); From 9447e84c683e36351258e450b4475690fac0d5eb Mon Sep 17 00:00:00 2001 From: Chris Huie Date: Thu, 13 Oct 2022 08:11:59 -0700 Subject: [PATCH 03/13] kick off test manually --- test/spec/modules/pubmaticBidAdapter_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index f554d57290d..13b4e31b5c7 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -4137,7 +4137,7 @@ describe('PubMatic adapter', function () { sandbox.restore(); }) - it('Should add bidder code as groupm for marketplace groupm response', function () { + it('Should add bidder code as groupm for marketplace groupm response ', function () { let request = spec.buildRequests(newBidRequests, { auctionId: 'new-auction-id' }); From ade41d32c92adea9f6015a59b3cbf9fdfe253272 Mon Sep 17 00:00:00 2001 From: Nitin Shirsat Date: Wed, 3 May 2023 17:23:17 +0530 Subject: [PATCH 04/13] Added support of GPP to PubMatic adapter --- modules/pubmaticBidAdapter.js | 17 ++- test/spec/modules/pubmaticBidAdapter_spec.js | 119 +++++++++++++++++++ 2 files changed, 135 insertions(+), 1 deletion(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index edfee7a0b6d..92be54d5149 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -1175,6 +1175,15 @@ export const spec = { deepSetValue(payload, 'regs.ext.us_privacy', bidderRequest.uspConsent); } + // Attaching GPP Consent Params + if (bidderRequest?.gppConsent?.gppString) { + deepSetValue(payload, 'regs.gpp', bidderRequest.gppConsent.gppString); + deepSetValue(payload, 'regs.gpp_sid', bidderRequest.gppConsent.applicableSections); + } else if (bidderRequest?.ortb2?.regs?.gpp) { + deepSetValue(payload, 'regs.gpp', bidderRequest.ortb2.regs.gpp); + deepSetValue(payload, 'regs.gpp_sid', bidderRequest.ortb2.regs.gpp_sid); + } + // coppa compliance if (config.getConfig('coppa') === true) { deepSetValue(payload, 'regs.coppa', 1); @@ -1333,7 +1342,7 @@ export const spec = { /** * Register User Sync. */ - getUserSyncs: (syncOptions, responses, gdprConsent, uspConsent) => { + getUserSyncs: (syncOptions, responses, gdprConsent, uspConsent, gppConsent) => { let syncurl = '' + publisherId; // Attaching GDPR Consent Params in UserSync url @@ -1347,6 +1356,12 @@ export const spec = { syncurl += '&us_privacy=' + encodeURIComponent(uspConsent); } + // GPP Consent + if (gppConsent?.gppString && gppConsent?.applicableSections?.length) { + syncurl += '&gpp=' + encodeURIComponent(gppConsent.gppString); + syncurl += '&gpp_sid=' + encodeURIComponent(gppConsent?.applicableSections); + } + // coppa compliance if (config.getConfig('coppa') === true) { syncurl += '&coppa=1'; diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 3198fe406e7..845bfe939ca 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -3040,6 +3040,76 @@ describe('PubMatic adapter', function () { expect(data.imp[0]['video']['h']).to.equal(videoBidRequests[0].mediaTypes.video.playerSize[1]); }); } + + describe('GPP', function() { + it('Request params check with GPP Consent', function () { + let bidRequest = { + gppConsent: { + 'gppString': 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN', + 'fullGppData': { + 'sectionId': 3, + 'gppVersion': 1, + 'sectionList': [ + 5, + 7 + ], + 'applicableSections': [ + 5 + ], + 'gppString': 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN', + 'pingData': { + 'cmpStatus': 'loaded', + 'gppVersion': '1.0', + 'cmpDisplayStatus': 'visible', + 'supportedAPIs': [ + 'tcfca', + 'usnat', + 'usca', + 'usva', + 'usco', + 'usut', + 'usct' + ], + 'cmpId': 31 + }, + 'eventName': 'sectionChange' + }, + 'applicableSections': [ + 5 + ], + 'apiVersion': 1 + } + }; + let request = spec.buildRequests(bidRequests, bidRequest); + let data = JSON.parse(request.data); + expect(data.regs.gpp).to.equal('DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN'); + expect(data.regs.gpp_sid[0]).to.equal(5); + }); + + it('Request params check without GPP Consent', function () { + let bidRequest = {}; + let request = spec.buildRequests(bidRequests, bidRequest); + let data = JSON.parse(request.data); + expect(data.regs).to.equal(undefined); + }); + + it('Request params check with GPP Consent read from ortb2', function () { + let bidRequest = { + ortb2: { + regs: { + 'gpp': 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN', + 'gpp_sid': [ + 5 + ] + } + } + }; + let request = spec.buildRequests(bidRequests, bidRequest); + let data = JSON.parse(request.data); + expect(data.regs.gpp).to.equal('DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN'); + expect(data.regs.gpp_sid[0]).to.equal(5); + }); + }); }); it('Request params dctr check', function () { @@ -3950,6 +4020,55 @@ describe('PubMatic adapter', function () { type: 'image', url: `${syncurl_image}&gdpr=1&gdpr_consent=foo&us_privacy=1NYN&coppa=1` }]); }); + + describe('GPP', function() { + it('should return userSync url without Gpp consent if gppConsent is undefined', () => { + const result = spec.getUserSyncs({iframeEnabled: true}, undefined, undefined, undefined, undefined); + expect(result).to.deep.equal([{ + type: 'iframe', url: `${syncurl_iframe}` + }]); + }); + + it('should return userSync url without Gpp consent if gppConsent.gppString is undefined', () => { + const gppConsent = { applicableSections: ['5'] }; + const result = spec.getUserSyncs({iframeEnabled: true}, undefined, undefined, undefined, gppConsent); + expect(result).to.deep.equal([{ + type: 'iframe', url: `${syncurl_iframe}` + }]); + }); + + it('should return userSync url without Gpp consent if gppConsent.applicableSections is undefined', () => { + const gppConsent = { gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN' }; + const result = spec.getUserSyncs({iframeEnabled: true}, undefined, undefined, undefined, gppConsent); + expect(result).to.deep.equal([{ + type: 'iframe', url: `${syncurl_iframe}` + }]); + }); + + it('should return userSync url without Gpp consent if gppConsent.applicableSections is an empty array', () => { + const gppConsent = { gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN', applicableSections: [] }; + const result = spec.getUserSyncs({iframeEnabled: true}, undefined, undefined, undefined, gppConsent); + expect(result).to.deep.equal([{ + type: 'iframe', url: `${syncurl_iframe}` + }]); + }); + + it('should concatenate gppString and applicableSections values in the returned userSync iframe url', () => { + const gppConsent = { gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN', applicableSections: [5] }; + const result = spec.getUserSyncs({iframeEnabled: true}, undefined, undefined, undefined, gppConsent); + expect(result).to.deep.equal([{ + type: 'iframe', url: `${syncurl_iframe}&gpp=${encodeURIComponent(gppConsent.gppString)}&gpp_sid=${encodeURIComponent(gppConsent.applicableSections)}` + }]); + }); + + it('should concatenate gppString and applicableSections values in the returned userSync image url', () => { + const gppConsent = { gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN', applicableSections: [5] }; + const result = spec.getUserSyncs({iframeEnabled: false}, undefined, undefined, undefined, gppConsent); + expect(result).to.deep.equal([{ + type: 'image', url: `${syncurl_image}&gpp=${encodeURIComponent(gppConsent.gppString)}&gpp_sid=${encodeURIComponent(gppConsent.applicableSections)}` + }]); + }); + }); }); if (FEATURES.VIDEO) { From 92846e994e294cd4a0a6c8a1fdec14c0bd3cb159 Mon Sep 17 00:00:00 2001 From: Nitin Shirsat Date: Fri, 30 Jun 2023 12:34:54 +0530 Subject: [PATCH 05/13] gpp_sid in user syncs supposed to encode as a string, not an array --- modules/pubmaticBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index e5ee9d8ac52..ce0da73f751 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -1378,7 +1378,7 @@ export const spec = { // GPP Consent if (gppConsent?.gppString && gppConsent?.applicableSections?.length) { syncurl += '&gpp=' + encodeURIComponent(gppConsent.gppString); - syncurl += '&gpp_sid=' + encodeURIComponent(gppConsent?.applicableSections); + syncurl += '&gpp_sid=' + encodeURIComponent(gppConsent?.applicableSections?.join(',')); } // coppa compliance From f92818add4758e8f509cccb8020574d345f7ff17 Mon Sep 17 00:00:00 2001 From: Nitin Shirsat Date: Wed, 5 Jul 2023 18:11:07 +0530 Subject: [PATCH 06/13] Remove extra space --- test/spec/modules/pubmaticBidAdapter_spec.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index ea6deecfb21..b4db81201a9 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -3126,8 +3126,7 @@ describe('PubMatic adapter', function () { expect(data.regs.gpp_sid[0]).to.equal(5); }); }); - - + describe('Fledge', function() { it('should not send imp.ext.ae when FLEDGE is disabled, ', function () { let bidRequest = Object.assign([], bidRequests); From fcb0dde5327b8bc789b31f8d42f318c8154b8ab0 Mon Sep 17 00:00:00 2001 From: Nitin Shirsat Date: Wed, 5 Jul 2023 18:14:41 +0530 Subject: [PATCH 07/13] Remove trailing spaces --- test/spec/modules/pubmaticBidAdapter_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index b4db81201a9..53f5e12aa6d 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -3126,7 +3126,7 @@ describe('PubMatic adapter', function () { expect(data.regs.gpp_sid[0]).to.equal(5); }); }); - + describe('Fledge', function() { it('should not send imp.ext.ae when FLEDGE is disabled, ', function () { let bidRequest = Object.assign([], bidRequests); From 70b6e36a399f5dbaef0c6a68307d1b62787cf625 Mon Sep 17 00:00:00 2001 From: Nitin Shirsat Date: Thu, 23 May 2024 18:46:44 +0530 Subject: [PATCH 08/13] Remove the placement parameter and update test cases accordingly, Add plcmt parameter. --- modules/pubmaticBidAdapter.js | 8 ++++---- test/spec/modules/pubmaticBidAdapter_spec.js | 18 ++++++++---------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 7ff86c5c46f..a383d4cc779 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -25,7 +25,7 @@ const DEFAULT_HEIGHT = 0; const PREBID_NATIVE_HELP_LINK = 'http://prebid.org/dev-docs/show-native-ads.html'; const PUBLICATION = 'pubmatic'; // Your publication on Blue Billywig, potentially with environment (e.g. publication.bbvms.com or publication.test.bbvms.com) const RENDERER_URL = 'https://pubmatic.bbvms.com/r/'.concat('$RENDERER', '.js'); // URL of the renderer application -const MSG_VIDEO_PLACEMENT_MISSING = 'Video.Placement param missing'; +const MSG_VIDEO_PLCMT_MISSING = 'Video.plcmt param missing'; const CUSTOM_PARAMS = { 'kadpageurl': '', // Custom page url @@ -56,7 +56,7 @@ const VIDEO_CUSTOM_PARAMS = { 'h': DATA_TYPES.NUMBER, 'battr': DATA_TYPES.ARRAY, 'linearity': DATA_TYPES.NUMBER, - 'placement': DATA_TYPES.NUMBER, + // 'placement': DATA_TYPES.NUMBER, 'plcmt': DATA_TYPES.NUMBER, 'minbitrate': DATA_TYPES.NUMBER, 'maxbitrate': DATA_TYPES.NUMBER, @@ -560,8 +560,8 @@ function _createBannerRequest(bid) { export function checkVideoPlacement(videoData, adUnitCode) { // Check for video.placement property. If property is missing display log message. - if (FEATURES.VIDEO && !deepAccess(videoData, 'placement')) { - logWarn(MSG_VIDEO_PLACEMENT_MISSING + ' for ' + adUnitCode); + if (FEATURES.VIDEO && !deepAccess(videoData, 'plcmt')) { + logWarn(MSG_VIDEO_PLCMT_MISSING + ' for ' + adUnitCode); }; } diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index ebda4b1767d..45fe67245ce 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -116,7 +116,7 @@ describe('PubMatic adapter', function () { protocols: [2, 3], battr: [13, 14], linearity: 1, - placement: 2, + // plcmt: 2, plcmt: 1, minbitrate: 10, maxbitrate: 10 @@ -169,7 +169,7 @@ describe('PubMatic adapter', function () { h: 480, battr: [13, 14], linearity: 1, - placement: 2, + // plcmt: 2, plcmt: 1, minbitrate: 100, maxbitrate: 4096 @@ -394,7 +394,7 @@ describe('PubMatic adapter', function () { h: 480, battr: [13, 14], linearity: 1, - placement: 2, + // plcmt: 2, plcmt: 1, minbitrate: 100, maxbitrate: 4096 @@ -522,7 +522,7 @@ describe('PubMatic adapter', function () { h: 480, battr: [13, 14], linearity: 1, - placement: 2, + // plcmt: 2, plcmt: 1, minbitrate: 100, maxbitrate: 4096 @@ -593,7 +593,7 @@ describe('PubMatic adapter', function () { h: 480, battr: [13, 14], linearity: 1, - placement: 2, + // plcmt: 2, plcmt: 1, minbitrate: 100, maxbitrate: 4096 @@ -2564,7 +2564,6 @@ describe('PubMatic adapter', function () { expect(data.imp[1]['video']['battr'][1]).to.equal(multipleMediaRequests[1].params.video['battr'][1]); expect(data.imp[1]['video']['linearity']).to.equal(multipleMediaRequests[1].params.video['linearity']); - expect(data.imp[1]['video']['placement']).to.equal(multipleMediaRequests[1].params.video['placement']); expect(data.imp[1]['video']['plcmt']).to.equal(multipleMediaRequests[1].params.video['plcmt']); expect(data.imp[1]['video']['minbitrate']).to.equal(multipleMediaRequests[1].params.video['minbitrate']); expect(data.imp[1]['video']['maxbitrate']).to.equal(multipleMediaRequests[1].params.video['maxbitrate']); @@ -2860,7 +2859,6 @@ describe('PubMatic adapter', function () { expect(data.imp[0]['video']['battr'][1]).to.equal(videoBidRequests[0].params.video['battr'][1]); expect(data.imp[0]['video']['linearity']).to.equal(videoBidRequests[0].params.video['linearity']); - expect(data.imp[0]['video']['placement']).to.equal(videoBidRequests[0].params.video['placement']); expect(data.imp[0]['video']['plcmt']).to.equal(videoBidRequests[0].params.video['plcmt']); expect(data.imp[0]['video']['minbitrate']).to.equal(videoBidRequests[0].params.video['minbitrate']); expect(data.imp[0]['video']['maxbitrate']).to.equal(videoBidRequests[0].params.video['maxbitrate']); @@ -4044,10 +4042,10 @@ describe('PubMatic adapter', function () { }); if (FEATURES.VIDEO) { - describe('Checking for Video.Placement property', function() { + describe('Checking for Video.plcmt property', function() { let sandbox, utilsMock; const adUnit = 'Div1'; - const msg_placement_missing = 'Video.Placement param missing for Div1'; + const msg_placement_missing = 'Video.plcmt param missing for Div1'; let videoData = { battr: [6, 7], skipafter: 15, @@ -4076,7 +4074,7 @@ describe('PubMatic adapter', function () { sinon.assert.calledWith(utils.logWarn, msg_placement_missing); }) it('shoud not log Video.Placement param missing', function() { - videoData['placement'] = 1; + videoData['plcmt'] = 1; checkVideoPlacement(videoData, adUnit); sinon.assert.neverCalledWith(utils.logWarn, msg_placement_missing); }) From a3667c1bb9379cc8bdf1de2c333c56d5bc214ff2 Mon Sep 17 00:00:00 2001 From: Nitin Shirsat Date: Fri, 24 May 2024 12:19:40 +0530 Subject: [PATCH 09/13] Supporting placement parameter and logging warning message, for the plcmt parameter, if it is missing. --- modules/pubmaticBidAdapter.js | 2 +- test/spec/modules/pubmaticBidAdapter_spec.js | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index a383d4cc779..593e80db4c9 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -56,7 +56,7 @@ const VIDEO_CUSTOM_PARAMS = { 'h': DATA_TYPES.NUMBER, 'battr': DATA_TYPES.ARRAY, 'linearity': DATA_TYPES.NUMBER, - // 'placement': DATA_TYPES.NUMBER, + 'placement': DATA_TYPES.NUMBER, 'plcmt': DATA_TYPES.NUMBER, 'minbitrate': DATA_TYPES.NUMBER, 'maxbitrate': DATA_TYPES.NUMBER, diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 45fe67245ce..729ccd439dc 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -116,6 +116,7 @@ describe('PubMatic adapter', function () { protocols: [2, 3], battr: [13, 14], linearity: 1, + placement: 2, // plcmt: 2, plcmt: 1, minbitrate: 10, @@ -169,6 +170,7 @@ describe('PubMatic adapter', function () { h: 480, battr: [13, 14], linearity: 1, + placement: 2, // plcmt: 2, plcmt: 1, minbitrate: 100, @@ -394,6 +396,7 @@ describe('PubMatic adapter', function () { h: 480, battr: [13, 14], linearity: 1, + placement: 2, // plcmt: 2, plcmt: 1, minbitrate: 100, @@ -522,6 +525,7 @@ describe('PubMatic adapter', function () { h: 480, battr: [13, 14], linearity: 1, + placement: 2, // plcmt: 2, plcmt: 1, minbitrate: 100, @@ -593,6 +597,7 @@ describe('PubMatic adapter', function () { h: 480, battr: [13, 14], linearity: 1, + placement: 2, // plcmt: 2, plcmt: 1, minbitrate: 100, @@ -2564,6 +2569,7 @@ describe('PubMatic adapter', function () { expect(data.imp[1]['video']['battr'][1]).to.equal(multipleMediaRequests[1].params.video['battr'][1]); expect(data.imp[1]['video']['linearity']).to.equal(multipleMediaRequests[1].params.video['linearity']); + expect(data.imp[1]['video']['placement']).to.equal(multipleMediaRequests[1].params.video['placement']); expect(data.imp[1]['video']['plcmt']).to.equal(multipleMediaRequests[1].params.video['plcmt']); expect(data.imp[1]['video']['minbitrate']).to.equal(multipleMediaRequests[1].params.video['minbitrate']); expect(data.imp[1]['video']['maxbitrate']).to.equal(multipleMediaRequests[1].params.video['maxbitrate']); @@ -2859,6 +2865,7 @@ describe('PubMatic adapter', function () { expect(data.imp[0]['video']['battr'][1]).to.equal(videoBidRequests[0].params.video['battr'][1]); expect(data.imp[0]['video']['linearity']).to.equal(videoBidRequests[0].params.video['linearity']); + expect(data.imp[0]['video']['placement']).to.equal(videoBidRequests[0].params.video['placement']); expect(data.imp[0]['video']['plcmt']).to.equal(videoBidRequests[0].params.video['plcmt']); expect(data.imp[0]['video']['minbitrate']).to.equal(videoBidRequests[0].params.video['minbitrate']); expect(data.imp[0]['video']['maxbitrate']).to.equal(videoBidRequests[0].params.video['maxbitrate']); @@ -4069,11 +4076,11 @@ describe('PubMatic adapter', function () { sandbox.restore(); }) - it('should log Video.Placement param missing', function() { + it('should log Video.plcmt param missing', function() { checkVideoPlacement(videoData, adUnit); sinon.assert.calledWith(utils.logWarn, msg_placement_missing); }) - it('shoud not log Video.Placement param missing', function() { + it('shoud not log Video.plcmt param missing', function() { videoData['plcmt'] = 1; checkVideoPlacement(videoData, adUnit); sinon.assert.neverCalledWith(utils.logWarn, msg_placement_missing); From 484c69146d1e327f3e071d1ba8ef90d3c36f7ba0 Mon Sep 17 00:00:00 2001 From: Nitin Shirsat Date: Tue, 28 May 2024 11:11:39 +0530 Subject: [PATCH 10/13] Remove commented code --- test/spec/modules/pubmaticBidAdapter_spec.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 729ccd439dc..9f0526e3a97 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -117,7 +117,6 @@ describe('PubMatic adapter', function () { battr: [13, 14], linearity: 1, placement: 2, - // plcmt: 2, plcmt: 1, minbitrate: 10, maxbitrate: 10 @@ -171,7 +170,6 @@ describe('PubMatic adapter', function () { battr: [13, 14], linearity: 1, placement: 2, - // plcmt: 2, plcmt: 1, minbitrate: 100, maxbitrate: 4096 @@ -397,7 +395,6 @@ describe('PubMatic adapter', function () { battr: [13, 14], linearity: 1, placement: 2, - // plcmt: 2, plcmt: 1, minbitrate: 100, maxbitrate: 4096 @@ -526,7 +523,6 @@ describe('PubMatic adapter', function () { battr: [13, 14], linearity: 1, placement: 2, - // plcmt: 2, plcmt: 1, minbitrate: 100, maxbitrate: 4096 @@ -598,7 +594,6 @@ describe('PubMatic adapter', function () { battr: [13, 14], linearity: 1, placement: 2, - // plcmt: 2, plcmt: 1, minbitrate: 100, maxbitrate: 4096 From 14db919e976ffa248a86b05f1611525fd06e02ce Mon Sep 17 00:00:00 2001 From: Nitin Shirsat Date: Fri, 31 May 2024 10:52:17 +0530 Subject: [PATCH 11/13] Added plcmt in the pubmaticBidAdapter.md file --- modules/pubmaticBidAdapter.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/pubmaticBidAdapter.md b/modules/pubmaticBidAdapter.md index baf58177505..e472b30a916 100644 --- a/modules/pubmaticBidAdapter.md +++ b/modules/pubmaticBidAdapter.md @@ -70,6 +70,7 @@ var adVideoAdUnits = [ protocols: [ 2, 3 ], // optional battr: [ 13, 14 ], // optional linearity: 1, // optional + plcmt: 1, // optional placement: 2, // optional minbitrate: 10, // optional maxbitrate: 10 // optional @@ -169,6 +170,7 @@ var adUnits = [ protocols: [ 2, 3 ], // optional battr: [ 13, 14 ], // optional linearity: 1, // optional + plcmt: 1, // optional placement: 2, // optional minbitrate: 10, // optional maxbitrate: 10 // optional From 6cfb9be2c942a79ca0da692794b6055343aa426e Mon Sep 17 00:00:00 2001 From: Nitin Shirsat Date: Mon, 1 Jul 2024 12:24:36 +0530 Subject: [PATCH 12/13] Adding support for Banner battr object --- modules/pubmaticBidAdapter.js | 12 ++++++ test/spec/modules/pubmaticBidAdapter_spec.js | 40 ++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 5add3fb9be1..9ffe36de5bd 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -68,6 +68,10 @@ const NATIVE_ASSET_IMAGE_TYPE = { 'IMAGE': 3 } +const BANNER_CUSTOM_PARAMS = { + 'battr': DATA_TYPES.ARRAY +} + const NET_REVENUE = true; const dealChannelValues = { 1: 'PMP', @@ -551,6 +555,14 @@ function _createBannerRequest(bid) { } bannerObj.pos = 0; bannerObj.topframe = inIframe() ? 0 : 1; + + // Adding Banner custom params + for (let key in BANNER_CUSTOM_PARAMS) { + let bannerCustomParams = bid.mediaTypes.banner; + if (bannerCustomParams.hasOwnProperty(key)) { + bannerObj[key] = _checkParamDataType(key, bannerCustomParams[key], BANNER_CUSTOM_PARAMS[key]); + } + } } else { logWarn(LOG_WARN_PREFIX + 'Error: mediaTypes.banner.size missing for adunit: ' + bid.params.adUnit + '. Ignoring the banner impression in the adunit.'); bannerObj = UNDEFINED; diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 7d42f407448..ac595f3b596 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -4084,6 +4084,46 @@ describe('PubMatic adapter', function () { }) }); } + + describe('Banner Request param battr checking', function() { + it('should add battr params to bannerObj if present in mediaTypes.banner', function() { + let originalBidRequests = utils.deepClone(bidRequests); + let bannerObj = utils.deepClone(originalBidRequests[0].mediaTypes.banner); + originalBidRequests[0].mediaTypes.banner = Object.assign(bannerObj, { + battr: [1, 2] + }); + + const req = spec.buildRequests(originalBidRequests, { + auctionId: 'new-auction-id' + }); + let data = JSON.parse(req.data); + expect(data.imp[0]['banner']['battr']).to.exist.and.to.be.an('array'); + expect(data.imp[0]['banner']['battr'][0]).to.equal(originalBidRequests[0].mediaTypes.banner['battr'][0]); + expect(data.imp[0]['banner']['battr'][1]).to.equal(originalBidRequests[0].mediaTypes.banner['battr'][1]); + }); + + it('should not add battr params to bannerObj if not present in mediaTypes.banner', function() { + const req = spec.buildRequests(bidRequests, { + auctionId: 'new-auction-id' + }); + let data = JSON.parse(req.data); + expect(data.imp[0]['banner']['battr']).to.equal(undefined); + }); + + it('should not add battr params if _checkParamDataType returns undefined (Mismatch data type)', function() { + let originalBidRequests = utils.deepClone(bidRequests); + let bannerObj = utils.deepClone(originalBidRequests[0].mediaTypes.banner); + originalBidRequests[0].mediaTypes.banner = Object.assign(bannerObj, { + battr: 1 + }); + + const req = spec.buildRequests(originalBidRequests, { + auctionId: 'new-auction-id' + }); + let data = JSON.parse(req.data); + expect(data.imp[0]['banner']['battr']).to.equal(undefined); + }); + }); }); if (FEATURES.VIDEO) { From cb85e20197980719efcfd7849222b4c6fc058b67 Mon Sep 17 00:00:00 2001 From: Nitin Shirsat Date: Thu, 4 Jul 2024 11:32:55 +0530 Subject: [PATCH 13/13] reading battr from ortb2Imp.banner --- modules/pubmaticBidAdapter.js | 2 +- test/spec/modules/pubmaticBidAdapter_spec.js | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 9ffe36de5bd..85018a73a54 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -557,8 +557,8 @@ function _createBannerRequest(bid) { bannerObj.topframe = inIframe() ? 0 : 1; // Adding Banner custom params + const bannerCustomParams = {...deepAccess(bid, 'ortb2Imp.banner')}; for (let key in BANNER_CUSTOM_PARAMS) { - let bannerCustomParams = bid.mediaTypes.banner; if (bannerCustomParams.hasOwnProperty(key)) { bannerObj[key] = _checkParamDataType(key, bannerCustomParams[key], BANNER_CUSTOM_PARAMS[key]); } diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index ac595f3b596..82715ac518a 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -4086,10 +4086,10 @@ describe('PubMatic adapter', function () { } describe('Banner Request param battr checking', function() { - it('should add battr params to bannerObj if present in mediaTypes.banner', function() { + it('should add battr params to bannerObj if present in ortb2Imp.banner', function() { let originalBidRequests = utils.deepClone(bidRequests); - let bannerObj = utils.deepClone(originalBidRequests[0].mediaTypes.banner); - originalBidRequests[0].mediaTypes.banner = Object.assign(bannerObj, { + let bannerObj = utils.deepClone(originalBidRequests[0].ortb2Imp.banner); + originalBidRequests[0].ortb2Imp.banner = Object.assign(bannerObj, { battr: [1, 2] }); @@ -4098,11 +4098,11 @@ describe('PubMatic adapter', function () { }); let data = JSON.parse(req.data); expect(data.imp[0]['banner']['battr']).to.exist.and.to.be.an('array'); - expect(data.imp[0]['banner']['battr'][0]).to.equal(originalBidRequests[0].mediaTypes.banner['battr'][0]); - expect(data.imp[0]['banner']['battr'][1]).to.equal(originalBidRequests[0].mediaTypes.banner['battr'][1]); + expect(data.imp[0]['banner']['battr'][0]).to.equal(originalBidRequests[0].ortb2Imp.banner['battr'][0]); + expect(data.imp[0]['banner']['battr'][1]).to.equal(originalBidRequests[0].ortb2Imp.banner['battr'][1]); }); - it('should not add battr params to bannerObj if not present in mediaTypes.banner', function() { + it('should not add battr params to bannerObj if not present in ortb2Imp.banner', function() { const req = spec.buildRequests(bidRequests, { auctionId: 'new-auction-id' }); @@ -4112,8 +4112,8 @@ describe('PubMatic adapter', function () { it('should not add battr params if _checkParamDataType returns undefined (Mismatch data type)', function() { let originalBidRequests = utils.deepClone(bidRequests); - let bannerObj = utils.deepClone(originalBidRequests[0].mediaTypes.banner); - originalBidRequests[0].mediaTypes.banner = Object.assign(bannerObj, { + let bannerObj = utils.deepClone(originalBidRequests[0].ortb2Imp.banner); + originalBidRequests[0].ortb2Imp.banner = Object.assign(bannerObj, { battr: 1 });