Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions modules/bidResponseFilter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const MODULE_NAME = 'bidResponseFilter';
export const BID_CATEGORY_REJECTION_REASON = 'Category is not allowed';
export const BID_ADV_DOMAINS_REJECTION_REASON = 'Adv domain is not allowed';
export const BID_ATTR_REJECTION_REASON = 'Attr is not allowed';
export const BID_MEDIA_TYPE_REJECTION_REASON = `Media type is not allowed`;

let moduleConfig;
let enabled = false;
Expand All @@ -29,13 +30,20 @@ export function reset() {

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 bidRequest = index.getBidRequest(bid);
const battr = bidRequest?.ortb2Imp[bid.mediaType]?.battr || index.getAdUnit(bid)?.ortb2Imp[bid.mediaType]?.battr || [];

const catConfig = {enforce: true, blockUnknown: true, ...(moduleConfig?.cat || {})};
const advConfig = {enforce: true, blockUnknown: true, ...(moduleConfig?.adv || {})};
const attrConfig = {enforce: true, blockUnknown: true, ...(moduleConfig?.attr || {})};
const mediaTypesConfig = {enforce: true, blockUnknown: true, ...(moduleConfig?.mediaTypes || {})};

const { primaryCatId, secondaryCatIds = [], advertiserDomains = [], attr: metaAttr } = bid.meta || {};
const {
primaryCatId, secondaryCatIds = [],
advertiserDomains = [],
attr: metaAttr,
mediaType: metaMediaType,
} = bid.meta || {};

// checking if bid fulfills ortb2 fields rules
if ((catConfig.enforce && bcat.some(category => [primaryCatId, ...secondaryCatIds].includes(category))) ||
Expand All @@ -47,6 +55,9 @@ export function addBidResponseHook(next, adUnitCode, bid, reject, index = auctio
} else if ((attrConfig.enforce && battr.includes(metaAttr)) ||
(attrConfig.blockUnknown && !metaAttr)) {
reject(BID_ATTR_REJECTION_REASON);
} else if ((mediaTypesConfig.enforce && !Object.keys(bidRequest?.mediaTypes || {}).includes(metaMediaType)) ||
(mediaTypesConfig.blockUnknown && !metaMediaType)) {
reject(BID_MEDIA_TYPE_REJECTION_REASON);
} else {
return next(adUnitCode, bid, reject);
}
Expand Down
79 changes: 70 additions & 9 deletions test/spec/modules/bidResponseFilter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import {
BID_ADV_DOMAINS_REJECTION_REASON,
BID_ATTR_REJECTION_REASON,
BID_CATEGORY_REJECTION_REASON,
init,
MODULE_NAME
, reset} from '../../../modules/bidResponseFilter/index.js';
import {config} from '../../../src/config.js';
import {addBidResponse} from '../../../src/auction.js';
BID_MEDIA_TYPE_REJECTION_REASON,
MODULE_NAME,
reset
} from '../../../modules/bidResponseFilter/index.js';
import { addBidResponse } from '../../../src/auction.js';
import { config } from '../../../src/config.js';

describe('bidResponseFilter', () => {
let mockAuctionIndex
Expand Down Expand Up @@ -56,11 +57,19 @@ describe('bidResponseFilter', () => {
badv: [], bcat: ['BANNED_CAT1', 'BANNED_CAT2']
});

mockAuctionIndex.getBidRequest = () => ({
mediaTypes: {
banner: {}
},
ortb2Imp: {}
})

const bid = {
meta: {
advertiserDomains: ['domain1.com', 'domain2.com'],
primaryCatId: 'EXAMPLE-CAT-ID',
attr: 'attr'
attr: 'attr',
mediaType: 'banner'
}
};

Expand Down Expand Up @@ -138,10 +147,18 @@ describe('bidResponseFilter', () => {
meta: {
advertiserDomains: ['validdomain1.com', 'validdomain2.com'],
primaryCatId: 'BANNED_CAT1',
attr: 'valid_attr'
attr: 'valid_attr',
mediaType: 'banner',
}
};

mockAuctionIndex.getBidRequest = () => ({
mediaTypes: {
banner: {}
},
ortb2Imp: {}
})

mockAuctionIndex.getOrtb2 = () => ({
badv: ['domain2.com'], bcat: ['BANNED_CAT1', 'BANNED_CAT2']
});
Expand All @@ -159,18 +176,62 @@ describe('bidResponseFilter', () => {
meta: {
advertiserDomains: ['validdomain1.com', 'validdomain2.com'],
primaryCatId: undefined,
attr: 'valid_attr'
attr: 'valid_attr',
mediaType: 'banner'
}
};

mockAuctionIndex.getOrtb2 = () => ({
badv: ['domain2.com'], bcat: ['BANNED_CAT1', 'BANNED_CAT2']
});

mockAuctionIndex.getBidRequest = () => ({
mediaTypes: {
banner: {}
},
ortb2Imp: {}
})

config.setConfig({[MODULE_NAME]: {cat: {blockUnknown: false}}});

addBidResponseHook(call, 'adcode', bid, () => {
});
}, mockAuctionIndex);
sinon.assert.calledOnce(call);
});

it('should reject bid for meta.mediaType not present on adunit', () => {
const reject = sinon.stub();
const call = sinon.stub();
const bid = {
meta: {
advertiserDomains: ['validdomain1.com', 'validdomain2.com'],
primaryCatId: 'VALID_CAT',
attr: 6,
mediaType: 'audio'
},
};

mockAuctionIndex.getOrtb2 = () => ({
badv: [], bcat: []
});

mockAuctionIndex.getBidRequest = () => ({
ortb2Imp: {
banner: {
},
video: {
},
}
})

mockAuctionIndex.getBidRequest = () => ({
mediaTypes: {
banner: {},
},
ortb2Imp: {}
})

addBidResponseHook(call, 'adcode', bid, reject, mockAuctionIndex);
sinon.assert.calledWith(reject, BID_MEDIA_TYPE_REJECTION_REASON);
});
})