From a60d6679b355c37bc6d3ad8bcaf5b2155163f005 Mon Sep 17 00:00:00 2001 From: pm-nitin-shirsat <107102698+pm-nitin-shirsat@users.noreply.github.com> Date: Thu, 21 Nov 2024 20:58:50 +0530 Subject: [PATCH] PubMatic Bid Adapter : support for InBannerVideo (IBV) Field in Bid Response with meta.mediaType (#12484) Support for InBannerVideo (IBV) Field in Bid Response with meta.mediaType --- modules/pubmaticBidAdapter.js | 23 ++++- test/spec/modules/pubmaticBidAdapter_spec.js | 88 +++++++++++++++++++- 2 files changed, 105 insertions(+), 6 deletions(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index a03091f1f4a..79a68a9b87b 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -859,6 +859,18 @@ function _handleEids(payload, validBidRequests) { } } +// Setting IBV & meta.mediaType field into the bid response +export function setIBVField(bid, newBid) { + if (bid?.ext?.ibv) { + newBid.ext = newBid.ext || {}; + newBid.ext['ibv'] = bid.ext.ibv; + + // Overriding the mediaType field in meta with the `video` value if bid.ext.ibv is present + newBid.meta = newBid.meta || {}; + newBid.meta.mediaType = VIDEO; + } +} + function _checkMediaType(bid, newBid) { // Create a regex here to check the strings if (bid.ext && bid.ext['bidtype'] != undefined) { @@ -1008,7 +1020,7 @@ function isNonEmptyArray(test) { * @param {*} bid : bids */ export function prepareMetaObject(br, bid, seat) { - br.meta = {}; + br.meta = br.meta || {}; if (bid.ext && bid.ext.dspid) { br.meta.networkId = bid.ext.dspid; @@ -1047,6 +1059,11 @@ export function prepareMetaObject(br, bid, seat) { if (bid.ext && bid.ext.dsa && Object.keys(bid.ext.dsa).length) { br.meta.dsa = bid.ext.dsa; } + + // Initializing meta.mediaType field to the actual bidType returned by the bidder + if (br.mediaType) { + br.meta.mediaType = br.mediaType; + } } export const spec = { @@ -1401,12 +1418,12 @@ export const spec = { } }); } + prepareMetaObject(newBid, bid, seatbidder.seat); + setIBVField(bid, newBid); if (bid.ext && bid.ext.deal_channel) { newBid['dealChannel'] = dealChannelValues[bid.ext.deal_channel] || null; } - prepareMetaObject(newBid, bid, seatbidder.seat); - // adserverTargeting if (seatbidder.ext && seatbidder.ext.buyid) { newBid.adserverTargeting = { diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 71b22e25272..6489d8ef0d5 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec, checkVideoPlacement, _getDomainFromURL, assignDealTier, prepareMetaObject, getDeviceConnectionType } from 'modules/pubmaticBidAdapter.js'; +import { spec, checkVideoPlacement, _getDomainFromURL, assignDealTier, prepareMetaObject, getDeviceConnectionType, setIBVField } from 'modules/pubmaticBidAdapter.js'; import * as utils from 'src/utils.js'; import { config } from 'src/config.js'; import { createEidsArray } from 'modules/userId/eids.js'; @@ -3579,6 +3579,33 @@ describe('PubMatic adapter', function () { expect(response[0].renderer).to.not.exist; }); + it('should set ibv field in bid.ext when bid.ext.ibv exists', function() { + let request = spec.buildRequests(bidRequests, { + auctionId: 'new-auction-id' + }); + + let copyOfBidResponse = utils.deepClone(bannerBidResponse); + let bidExt = utils.deepClone(copyOfBidResponse.body.seatbid[0].bid[0].ext); + copyOfBidResponse.body.seatbid[0].bid[0].ext = Object.assign(bidExt, { + ibv: true + }); + + let response = spec.interpretResponse(copyOfBidResponse, request); + expect(response[0].ext.ibv).to.equal(true); + expect(response[0].meta.mediaType).to.equal('video'); + }); + + it('should not set ibv field when bid.ext does not exist ', function() { + let request = spec.buildRequests(bidRequests, { + auctionId: 'new-auction-id' + }); + + let response = spec.interpretResponse(bannerBidResponse, request); + expect(response[0].ext).to.not.exist; + expect(response[0].meta).to.exist; + expect(response[0].meta.mediaType).to.equal('banner'); + }); + if (FEATURES.VIDEO) { it('should check for valid video mediaType in case of multiformat request', function() { let request = spec.buildRequests(videoBidRequests, { @@ -3878,10 +3905,12 @@ describe('PubMatic adapter', function () { // dchain: 'dc', // demandSource: 'ds', // secondaryCatIds: ['secondaryCatIds'] - } + }, }; - const br = {}; + const br = { + mediaType: 'video' + }; prepareMetaObject(br, bid, null); expect(br.meta.networkId).to.equal(6); // dspid expect(br.meta.buyerId).to.equal('12'); // adid @@ -3900,6 +3929,7 @@ describe('PubMatic adapter', function () { expect(br.meta.advertiserDomains).to.be.an('array').with.length.above(0); // adomain expect(br.meta.clickUrl).to.equal('mystartab.com'); // adomain expect(br.meta.dsa).to.equal(dsa); // dsa + expect(br.meta.mediaType).to.equal('video'); // mediaType }); it('Should be empty, when ext and adomain is absent in bid object', function () { @@ -4176,6 +4206,58 @@ describe('PubMatic adapter', function () { expect(data.imp[0]['banner']['battr']).to.equal(undefined); }); }); + + describe('setIBVField', function() { + it('should set ibv field in newBid.ext when bid.ext.ibv exists', function() { + const bid = { + ext: { + ibv: true + } + }; + const newBid = {}; + setIBVField(bid, newBid); + expect(newBid.ext).to.exist; + expect(newBid.ext.ibv).to.equal(true); + expect(newBid.meta).to.exist; + expect(newBid.meta.mediaType).to.equal('video'); + }); + + it('should not set ibv field when bid.ext.ibv does not exist', function() { + const bid = { + ext: {} + }; + const newBid = {}; + setIBVField(bid, newBid); + expect(newBid.ext).to.not.exist; + expect(newBid.meta).to.not.exist; + }); + + it('should not set ibv field when bid.ext does not exist', function() { + const bid = {}; + const newBid = {}; + setIBVField(bid, newBid); + expect(newBid.ext).to.not.exist; + expect(newBid.meta).to.not.exist; + }); + + it('should preserve existing newBid.ext properties', function() { + const bid = { + ext: { + ibv: true + } + }; + const newBid = { + ext: { + existingProp: 'should remain' + } + }; + setIBVField(bid, newBid); + expect(newBid.ext.existingProp).to.equal('should remain'); + expect(newBid.ext.ibv).to.equal(true); + expect(newBid.meta).to.exist; + expect(newBid.meta.mediaType).to.equal('video'); + }); + }); }); if (FEATURES.VIDEO) {