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

IX Bid Adapter: Removing dependency on EID Allowlist #10988

Merged
merged 1 commit into from
Feb 5, 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
25 changes: 20 additions & 5 deletions modules/ixBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const VIDEO_TIME_TO_LIVE = 3600; // 1hr
const NATIVE_TIME_TO_LIVE = 3600; // Since native can have video, use ttl same as video
const NET_REVENUE = true;
const MAX_REQUEST_LIMIT = 4;
const MAX_EID_SOURCES = 50;
const OUTSTREAM_MINIMUM_PLAYER_SIZE = [144, 144];
const PRICE_TO_DOLLAR_FACTOR = {
JPY: 1
Expand Down Expand Up @@ -111,7 +112,8 @@ export const storage = getStorageManager({ bidderCode: BIDDER_CODE });
export const FEATURE_TOGGLES = {
// Update with list of CFTs to be requested from Exchange
REQUESTED_FEATURE_TOGGLES: [
'pbjs_enable_multiformat'
'pbjs_enable_multiformat',
'pbjs_allow_all_eids'
],

featureToggles: {},
Expand Down Expand Up @@ -657,15 +659,23 @@ function getEidInfo(allEids) {
let seenSources = {};
if (isArray(allEids)) {
for (const eid of allEids) {
if (SOURCE_RTI_MAPPING.hasOwnProperty(eid.source) && deepAccess(eid, 'uids.0')) {
const isSourceMapped = SOURCE_RTI_MAPPING.hasOwnProperty(eid.source);
const allowAllEidsFeatureEnabled = FEATURE_TOGGLES.isFeatureEnabled('pbjs_allow_all_eids');
const hasUids = deepAccess(eid, 'uids.0');

if ((isSourceMapped || allowAllEidsFeatureEnabled) && hasUids) {
seenSources[eid.source] = true;
if (SOURCE_RTI_MAPPING[eid.source] != '') {

if (isSourceMapped && SOURCE_RTI_MAPPING[eid.source] !== '') {
eid.uids[0].ext = {
rtiPartner: SOURCE_RTI_MAPPING[eid.source]
};
}
delete eid.uids[0].atype;
toSend.push(eid);
if (toSend.length >= MAX_EID_SOURCES) {
break;
}
}
}
}
Expand Down Expand Up @@ -710,7 +720,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
// getting ixdiags for adunits of the video, outstream & multi format (MF) style
const fledgeEnabled = deepAccess(bidderRequest, 'fledgeEnabled')
let ixdiag = buildIXDiag(validBidRequests, fledgeEnabled);
for (var key in ixdiag) {
for (let key in ixdiag) {
r.ext.ixdiag[key] = ixdiag[key];
}

Expand Down Expand Up @@ -796,6 +806,9 @@ function addRTI(userEids, eidInfo) {
let identityInfo = window.headertag.getIdentityInfo();
if (identityInfo && typeof identityInfo === 'object') {
for (const partnerName in identityInfo) {
if (userEids.length >= MAX_EID_SOURCES) {
return
}
if (identityInfo.hasOwnProperty(partnerName)) {
let response = identityInfo[partnerName];
if (!response.responsePending && response.data && typeof response.data === 'object' &&
Expand Down Expand Up @@ -1274,6 +1287,7 @@ function buildIXDiag(validBidRequests, fledgeEnabled) {
.map(bidRequest => bidRequest.adUnitCode)
.filter((value, index, arr) => arr.indexOf(value) === index);

let allEids = deepAccess(validBidRequests, '0.userIdAsEids', [])
let ixdiag = {
mfu: 0,
bu: 0,
Expand All @@ -1286,7 +1300,8 @@ function buildIXDiag(validBidRequests, fledgeEnabled) {
userIds: _getUserIds(validBidRequests[0]),
url: window.location.href.split('?')[0],
vpd: defaultVideoPlacement,
ae: fledgeEnabled
ae: fledgeEnabled,
eidLength: allEids.length
};

// create ad unit map and collect the required diag properties
Expand Down
119 changes: 119 additions & 0 deletions test/spec/modules/ixBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,23 @@ describe('IndexexchangeAdapter', function () {

const extractPayload = function (bidRequest) { return bidRequest.data }

const generateEid = function (numEid) {
const eids = [];

for (let i = 1; i <= numEid; i++) {
const newEid = {
source: `eid_source_${i}.com`,
uids: [{
id: `uid_id_${i}`,
}]
};

eids.push(newEid);
}

return eids;
}

describe('inherited functions', function () {
it('should exists and is a function', function () {
const adapter = newBidder(spec);
Expand Down Expand Up @@ -1485,6 +1502,17 @@ describe('IndexexchangeAdapter', function () {
describe('buildRequestsUserId', function () {
let validIdentityResponse;
let validUserIdPayload;
const serverResponse = {
body: {
ext: {
pbjs_allow_all_eids: {
test: {
activated: false
}
}
}
}
};

beforeEach(function () {
window.headertag = {};
Expand All @@ -1495,6 +1523,12 @@ describe('IndexexchangeAdapter', function () {

afterEach(function () {
delete window.headertag;
serverResponse.body.ext.features = {
pbjs_allow_all_eids: {
activated: false
}
};
validIdentityResponse = {}
});

it('IX adapter reads supported user modules from Prebid and adds it to Video', function () {
Expand All @@ -1506,6 +1540,91 @@ describe('IndexexchangeAdapter', function () {
expect(payload.user.eids).to.have.deep.members(DEFAULT_USERID_PAYLOAD);
});

it('IX adapter filters eids from prebid past the maximum eid limit', function () {
serverResponse.body.ext.features = {
pbjs_allow_all_eids: {
activated: true
}
};
FEATURE_TOGGLES.setFeatureToggles(serverResponse);
const cloneValidBid = utils.deepClone(DEFAULT_VIDEO_VALID_BID);
let eid_sent_from_prebid = generateEid(55);
cloneValidBid[0].userIdAsEids = utils.deepClone(eid_sent_from_prebid);
const request = spec.buildRequests(cloneValidBid, DEFAULT_OPTION)[0];
const payload = extractPayload(request);
expect(payload.user.eids).to.have.lengthOf(50);
let eid_accepted = eid_sent_from_prebid.slice(0, 50);
expect(payload.user.eids).to.have.deep.members(eid_accepted);
expect(payload.ext.ixdiag.eidLength).to.equal(55);
});

it('IX adapter filters eids from IXL past the maximum eid limit', function () {
validIdentityResponse = {
MerkleIp: {
responsePending: false,
data: {
source: 'merkle.com',
uids: [{
id: '1234-5678-9012-3456',
ext: {
keyID: '1234-5678',
enc: 1
}
}]
}
},
LiveIntentIp: {
responsePending: false,
data: {
source: 'liveintent.com',
uids: [{
id: '1234-5678-9012-3456',
ext: {
keyID: '1234-5678',
rtiPartner: 'LDID',
enc: 1
}
}]
}
}
};
serverResponse.body.ext.features = {
pbjs_allow_all_eids: {
activated: true
}
};
FEATURE_TOGGLES.setFeatureToggles(serverResponse);
const cloneValidBid = utils.deepClone(DEFAULT_VIDEO_VALID_BID);
let eid_sent_from_prebid = generateEid(49);
cloneValidBid[0].userIdAsEids = utils.deepClone(eid_sent_from_prebid);
const request = spec.buildRequests(cloneValidBid, DEFAULT_OPTION)[0];
const payload = extractPayload(request);
expect(payload.user.eids).to.have.lengthOf(50);
eid_sent_from_prebid.push({
source: 'merkle.com',
uids: [{
id: '1234-5678-9012-3456',
ext: {
keyID: '1234-5678',
enc: 1
}
}]
})
expect(payload.user.eids).to.have.deep.members(eid_sent_from_prebid);
expect(payload.ext.ixdiag.eidLength).to.equal(49);
});

it('All incoming eids are from unsupported source with feature toggle off', function () {
FEATURE_TOGGLES.setFeatureToggles(serverResponse);
const cloneValidBid = utils.deepClone(DEFAULT_VIDEO_VALID_BID);
let eid_sent_from_prebid = generateEid(20);
cloneValidBid[0].userIdAsEids = utils.deepClone(eid_sent_from_prebid);
const request = spec.buildRequests(cloneValidBid, DEFAULT_OPTION)[0];
const payload = extractPayload(request);
expect(payload.user.eids).to.be.undefined
expect(payload.ext.ixdiag.eidLength).to.equal(20);
});

it('We continue to send in IXL identity info and Prebid takes precedence over IXL', function () {
validIdentityResponse = {
AdserverOrgIp: {
Expand Down