diff --git a/modules/bidResponseFilter/index.js b/modules/bidResponseFilter/index.js index 3f79ea5ba57..3ace8108d2b 100644 --- a/modules/bidResponseFilter/index.js +++ b/modules/bidResponseFilter/index.js @@ -1,3 +1,4 @@ +import { auctionManager } from '../../src/auctionManager.js'; import { config } from '../../src/config.js'; import { getHook } from '../../src/hook.js'; @@ -10,8 +11,9 @@ function init() { getHook('addBidResponse').before(addBidResponseHook); }; -export function addBidResponseHook(next, adUnitCode, bid, reject) { - const { bcat = [], badv = [], battr = [] } = config.getAnyConfig('ortb2') || {}; +export function addBidResponseHook(next, adUnitCode, bid, reject, index = auctionManager.index) { + const {bcat = [], badv = []} = index.getOrtb2(bid) || {}; + const battr = index.getBidRequest(bid)?.ortb2Imp[bid.mediaType]?.battr || index.getAdUnit(bid)?.ortb2Imp[bid.mediaType]?.battr || []; const moduleConfig = config.getConfig(MODULE_NAME); const catConfig = {enforce: true, blockUnknown: true, ...(moduleConfig?.cat || {})}; diff --git a/src/prebid.js b/src/prebid.js index c92ab8f5a89..e843467bfed 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -100,6 +100,16 @@ function validateSizes(sizes, targLength) { return cleanSizes; } +function setBattrForAdUnit(adUnit, mediaType) { + const battr = adUnit.ortb2Imp?.[mediaType]?.battr || adUnit.mediaType?.[mediaType]?.battr; + if (adUnit.ortb2Imp?.[mediaType] && battr) { + adUnit.ortb2Imp[mediaType].battr = battr; + } + if (adUnit.mediaTypes?.[mediaType] && battr) { + adUnit.mediaTypes[mediaType].battr = battr; + } +} + function validateBannerMediaType(adUnit) { const validatedAdUnit = deepClone(adUnit); const banner = validatedAdUnit.mediaTypes.banner; @@ -112,6 +122,7 @@ function validateBannerMediaType(adUnit) { logError('Detected a mediaTypes.banner object without a proper sizes field. Please ensure the sizes are listed like: [[300, 250], ...]. Removing invalid mediaTypes.banner object from request.'); delete validatedAdUnit.mediaTypes.banner } + setBattrForAdUnit(validatedAdUnit, 'banner'); return validatedAdUnit; } @@ -135,6 +146,7 @@ function validateVideoMediaType(adUnit) { } } validateOrtbVideoFields(validatedAdUnit); + setBattrForAdUnit(validatedAdUnit, 'video'); return validatedAdUnit; } @@ -184,6 +196,7 @@ function validateNativeMediaType(adUnit) { logError('Please use an array of sizes for native.icon.sizes field. Removing invalid mediaTypes.native.icon.sizes property from request.'); delete validatedAdUnit.mediaTypes.native.icon.sizes; } + setBattrForAdUnit(validatedAdUnit, 'native'); return validatedAdUnit; } diff --git a/test/spec/modules/bidResponseFilter_spec.js b/test/spec/modules/bidResponseFilter_spec.js index 13368cf69fb..3990cd3feb3 100644 --- a/test/spec/modules/bidResponseFilter_spec.js +++ b/test/spec/modules/bidResponseFilter_spec.js @@ -2,12 +2,22 @@ import { BID_ADV_DOMAINS_REJECTION_REASON, BID_ATTR_REJECTION_REASON, BID_CATEGO import { config } from '../../../src/config'; describe('bidResponseFilter', () => { - afterEach(() => { + let mockAuctionIndex + beforeEach(() => { config.resetConfig(); + mockAuctionIndex = { + getBidRequest: () => {}, + getAdUnit: () => {} + }; }); it('should pass the bid after successful ortb2 rules validation', () => { const call = sinon.stub(); + + mockAuctionIndex.getOrtb2 = () => ({ + badv: [], bcat: ['BANNED_CAT1', 'BANNED_CAT2'] + }); + const bid = { meta: { advertiserDomains: ['domain1.com', 'domain2.com'], @@ -15,11 +25,8 @@ describe('bidResponseFilter', () => { attr: 'attr' } }; - config.setConfig({ortb2: { - badv: [], bcat: ['BANNED_CAT1', 'BANNED_CAT2'], battr: 'BANNED_ATTR' - }}); - addBidResponseHook(call, 'adcode', bid, () => {}); + addBidResponseHook(call, 'adcode', bid, () => {}, mockAuctionIndex); sinon.assert.calledOnce(call); }); @@ -33,11 +40,11 @@ describe('bidResponseFilter', () => { attr: 'attr' } }; - config.setConfig({ortb2: { - badv: [], bcat: ['BANNED_CAT1', 'BANNED_CAT2'], battr: 'BANNED_ATTR' - }}); + mockAuctionIndex.getOrtb2 = () => ({ + badv: [], bcat: ['BANNED_CAT1', 'BANNED_CAT2'] + }); - addBidResponseHook(call, 'adcode', bid, reject); + addBidResponseHook(call, 'adcode', bid, reject, mockAuctionIndex); sinon.assert.calledWith(reject, BID_CATEGORY_REJECTION_REASON); }); @@ -51,11 +58,11 @@ describe('bidResponseFilter', () => { attr: 'attr' } }; - config.setConfig({ortb2: { - badv: ['domain2.com'], bcat: ['BANNED_CAT1', 'BANNED_CAT2'], battr: 'BANNED_ATTR' - }}); + mockAuctionIndex.getOrtb2 = () => ({ + badv: ['domain2.com'], bcat: ['BANNED_CAT1', 'BANNED_CAT2'] + }); - addBidResponseHook(call, 'adcode', bid, rejection); + addBidResponseHook(call, 'adcode', bid, rejection, mockAuctionIndex); sinon.assert.calledWith(rejection, BID_ADV_DOMAINS_REJECTION_REASON); }); @@ -67,13 +74,22 @@ describe('bidResponseFilter', () => { advertiserDomains: ['validdomain1.com', 'validdomain2.com'], primaryCatId: 'VALID_CAT', attr: 'BANNED_ATTR' - } + }, + mediaType: 'video' }; - config.setConfig({ortb2: { - badv: ['domain2.com'], bcat: ['BANNED_CAT1', 'BANNED_CAT2'], battr: 'BANNED_ATTR' - }}); + mockAuctionIndex.getOrtb2 = () => ({ + badv: ['domain2.com'], bcat: ['BANNED_CAT1', 'BANNED_CAT2'] + }); - addBidResponseHook(call, 'adcode', bid, reject); + mockAuctionIndex.getBidRequest = () => ({ + ortb2Imp: { + video: { + battr: 'BANNED_ATTR' + } + } + }) + + addBidResponseHook(call, 'adcode', bid, reject, mockAuctionIndex); sinon.assert.calledWith(reject, BID_ATTR_REJECTION_REASON); }); @@ -86,13 +102,14 @@ describe('bidResponseFilter', () => { attr: 'valid_attr' } }; - config.setConfig({ortb2: { - badv: ['domain2.com'], bcat: ['BANNED_CAT1', 'BANNED_CAT2'], battr: 'BANNED_ATTR' - }}); + + mockAuctionIndex.getOrtb2 = () => ({ + badv: ['domain2.com'], bcat: ['BANNED_CAT1', 'BANNED_CAT2'] + }); config.setConfig({[MODULE_NAME]: {cat: {enforce: false}}}); - addBidResponseHook(call, 'adcode', bid, () => {}); + addBidResponseHook(call, 'adcode', bid, () => {}, mockAuctionIndex); sinon.assert.calledOnce(call); }); @@ -105,9 +122,10 @@ describe('bidResponseFilter', () => { attr: 'valid_attr' } }; - config.setConfig({ortb2: { - badv: ['domain2.com'], bcat: ['BANNED_CAT1', 'BANNED_CAT2'], battr: 'BANNED_ATTR' - }}); + + mockAuctionIndex.getOrtb2 = () => ({ + badv: ['domain2.com'], bcat: ['BANNED_CAT1', 'BANNED_CAT2'] + }); config.setConfig({[MODULE_NAME]: {cat: {blockUnknown: false}}});