Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prebid 9: Deprecate native sendTargetingKeys/types, validate asset IDs #11481

Merged
merged 3 commits into from
May 15, 2024
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
21 changes: 21 additions & 0 deletions src/prebid.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,17 +138,38 @@ function validateVideoMediaType(adUnit) {
}

function validateNativeMediaType(adUnit) {
function err(msg) {
logError(`Error in adUnit "${adUnit.code}": ${msg}. Removing native request from ad unit`, adUnit);
delete validatedAdUnit.mediaTypes.native;
return validatedAdUnit;
}
function checkDeprecated(onDeprecated) {
for (const key of ['sendTargetingKeys', 'types']) {
if (native.hasOwnProperty(key)) {
const res = onDeprecated(key);
if (res) return res;
}
}
}
const validatedAdUnit = deepClone(adUnit);
const native = validatedAdUnit.mediaTypes.native;
// if native assets are specified in OpenRTB format, remove legacy assets and print a warn.
if (native.ortb) {
if (native.ortb.assets?.some(asset => !isNumber(asset.id) || asset.id < 0 || asset.id % 1 !== 0)) {
return err('native asset ID must be a nonnegative integer');
}
if (checkDeprecated(key => err(`ORTB native requests cannot specify "${key}"`))) {
return validatedAdUnit;
}
const legacyNativeKeys = Object.keys(NATIVE_KEYS).filter(key => NATIVE_KEYS[key].includes('hb_native_'));
const nativeKeys = Object.keys(native);
const intersection = nativeKeys.filter(nativeKey => legacyNativeKeys.includes(nativeKey));
if (intersection.length > 0) {
logError(`when using native OpenRTB format, you cannot use legacy native properties. Deleting ${intersection} keys from request.`);
intersection.forEach(legacyKey => delete validatedAdUnit.mediaTypes.native[legacyKey]);
}
} else {
checkDeprecated(key => `mediaTypes.native.${key} is deprecated, consider using native ORTB instead`, adUnit);
}
if (native.image && native.image.sizes && !Array.isArray(native.image.sizes)) {
logError('Please use an array of sizes for native.image.sizes field. Removing invalid mediaTypes.native.image.sizes property from request.');
Expand Down
67 changes: 56 additions & 11 deletions test/spec/unit/pbjs_api_spec.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,32 @@
import {
createBidReceived,
getAdServerTargeting,
getAdUnits,
getBidRequests,
getBidResponses,
getBidResponsesFromAPI,
getTargetingKeys,
getTargetingKeysBidLandscape,
getAdUnits,
createBidReceived
getTargetingKeysBidLandscape
} from 'test/fixtures/fixtures.js';
import { auctionManager, newAuctionManager } from 'src/auctionManager.js';
import { targeting, newTargeting, filters } from 'src/targeting.js';
import { config as configObj } from 'src/config.js';
import {auctionManager, newAuctionManager} from 'src/auctionManager.js';
import {filters, newTargeting, targeting} from 'src/targeting.js';
import {config as configObj} from 'src/config.js';
import * as ajaxLib from 'src/ajax.js';
import * as auctionModule from 'src/auction.js';
import { registerBidder } from 'src/adapters/bidderFactory.js';
import {resizeRemoteCreative} from 'src/secureCreatives.js';
import {resetAuctionState} from 'src/auction.js';
import {registerBidder} from 'src/adapters/bidderFactory.js';
import {find} from 'src/polyfill.js';
import * as pbjsModule from 'src/prebid.js';
import $$PREBID_GLOBAL$$ from 'src/prebid.js';
import {hook} from '../../../src/hook.js';
import {reset as resetDebugging} from '../../../src/debugging.js';
import $$PREBID_GLOBAL$$ from 'src/prebid.js';
import {resetAuctionState} from 'src/auction.js';
import {stubAuctionIndex} from '../../helpers/indexStub.js';
import {createBid} from '../../../src/bidfactory.js';
import {enrichFPD} from '../../../src/fpd/enrichment.js';
import {mockFpdEnrichments} from '../../helpers/fpd.js';
import {generateUUID} from '../../../src/utils.js';
import {getCreativeRenderer} from '../../../src/creativeRenderers.js';
import { BID_STATUS, EVENTS, GRANULARITY_OPTIONS, TARGETING_KEYS } from 'src/constants.js';
import {BID_STATUS, EVENTS, GRANULARITY_OPTIONS, TARGETING_KEYS} from 'src/constants.js';

var assert = require('chai').assert;
var expect = require('chai').expect;
Expand Down Expand Up @@ -2475,6 +2474,52 @@ describe('Unit: Prebid Module', function () {
}
});

if (FEATURES.NATIVE) {
Object.entries({
missing: {},
negative: {id: -1},
'not an integer': {id: 1.23},
NaN: {id: 'garbage'}
}).forEach(([t, props]) => {
it(`should reject native ortb when asset ID is ${t}`, () => {
const adUnit = {
code: 'au',
mediaTypes: {
native: {
ortb: {
assets: [props]
}
}
},
bids: [{bidder: 'appnexus'}]
};
$$PREBID_GLOBAL$$.requestBids({
adUnits: [adUnit]
});
expect(auctionArgs.adUnits[0].bids.length).to.equal(0);
});
});

['sendTargetingKeys', 'types'].forEach(key => {
it(`should reject native that includes both ortb and ${key}`, () => {
const adUnit = {
code: 'au',
mediaTypes: {
native: {
ortb: {},
[key]: {}
}
},
bids: [{bidder: 'appnexus'}]
};
$$PREBID_GLOBAL$$.requestBids({
adUnits: [adUnit]
});
expect(auctionArgs.adUnits[0].bids.length).to.equal(0);
})
});
}

it('should throw error message and remove adUnit if adUnit.bids is not defined correctly', function () {
const adUnits = [{
code: 'ad-unit-1',
Expand Down