Skip to content
New issue

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

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

Already on GitHub? # to your account

UserID: allow any contents in EIDs #12651

Merged
merged 1 commit into from
Jan 14, 2025
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
35 changes: 30 additions & 5 deletions modules/userId/eids.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {deepClone, isFn, isStr} from '../../src/utils.js';
import {logError, deepClone, isFn, isStr} from '../../src/utils.js';

/**
* @typedef {import('./index.js').SubmodulePriorityMap} SubmodulePriorityMap
Expand Down Expand Up @@ -38,7 +38,10 @@ function createEidObject(userIdData, subModuleKey, eidConf) {
export function createEidsArray(bidRequestUserId, eidConfigs = EID_CONFIG) {
const allEids = {};
function collect(eid) {
const key = JSON.stringify([eid.source?.toLowerCase(), eid.ext]);
const key = JSON.stringify([
eid.source?.toLowerCase(),
...Object.keys(eid).filter(k => !['uids', 'source'].includes(k)).sort().map(k => eid[k])
]);
if (allEids.hasOwnProperty(key)) {
allEids[key].uids.push(...eid.uids);
} else {
Expand All @@ -48,8 +51,25 @@ export function createEidsArray(bidRequestUserId, eidConfigs = EID_CONFIG) {

Object.entries(bidRequestUserId).forEach(([name, values]) => {
values = Array.isArray(values) ? values : [values];
const eids = name === 'pubProvidedId' ? deepClone(values) : values.map(value => createEidObject(value, name, eidConfigs.get(name)));
eids.filter(eid => eid != null).forEach(collect);
const eidConf = eidConfigs.get(name);
let eids;
if (name === 'pubProvidedId') {
eids = deepClone(values);
} else if (typeof eidConf === 'function') {
try {
eids = eidConf(values);
if (!Array.isArray(eids)) {
eids = [eids];
}
} catch (e) {
logError(`Could not generate EID for "${name}"`, e);
}
} else {
eids = values.map(value => createEidObject(value, name, eidConf));
}
if (Array.isArray(eids)) {
eids.filter(eid => eid != null).forEach(collect);
}
})
return Object.values(allEids);
}
Expand All @@ -64,7 +84,12 @@ export function getEids(priorityMap) {
const submodule = submodules.find(mod => mod.idObj?.[key] != null);
if (submodule) {
idValues[key] = submodule.idObj[key];
eidConfigs.set(key, submodule.submodule.eids?.[key])
let eidConf = submodule.submodule.eids?.[key];
if (typeof eidConf === 'function') {
// if eid config is given as a function, append the active module configuration to its args
eidConf = ((orig) => (...args) => orig(...args, submodule.config))(eidConf);
}
eidConfigs.set(key, eidConf);
}
})
return createEidsArray(idValues, eidConfigs);
Expand Down
86 changes: 84 additions & 2 deletions test/spec/modules/userId_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -456,14 +456,35 @@ describe('User ID', function () {
{'mockId2v1': {source: 'mock2source', atype: 2, getEidExt: () => ({v: 1})}}),
createMockIdSubmodule('mockId2v2', null, null,
{'mockId2v2': {source: 'mock2source', atype: 2, getEidExt: () => ({v: 2})}}),
createMockIdSubmodule('mockId2v3', null, null, {
'mockId2v3'(ids) {
return {
source: 'mock2source',
inserter: 'ins',
ext: {v: 2},
uids: ids.map(id => ({id, atype: 2}))
}
}
}),
createMockIdSubmodule('mockId2v4', null, null, {
'mockId2v4'(ids) {
return ids.map(id => ({
uids: [{id, atype: 0}],
source: 'mock2source',
inserter: 'ins',
ext: {v: 2}
}))
}
})
]);
});

it('should group UIDs by source and ext', () => {
it('should group UIDs by everything except uid', () => {
const eids = createEidsArray({
mockId1: ['mock-1-1', 'mock-1-2'],
mockId2v1: ['mock-2-1', 'mock-2-2'],
mockId2v2: ['mock-2-1', 'mock-2-2']
mockId2v2: ['mock-2-1', 'mock-2-2'],
mockId2v3: ['mock-2-1', 'mock-2-2']
});
expect(eids).to.eql([
{
Expand Down Expand Up @@ -510,10 +531,50 @@ describe('User ID', function () {
atype: 2,
}
]
},
{
source: 'mock2source',
inserter: 'ins',
ext: {v: 2},
uids: [
{
id: 'mock-2-1',
atype: 2,
},
{
id: 'mock-2-2',
atype: 2,
}
]
}
])
});

it('should group matching EIDs regardless of entry order', () => {
const eids = createEidsArray({
mockId2v3: ['id1', 'id2'],
mockId2v4: ['id3']
});
expect(eids).to.eql([{
source: 'mock2source',
inserter: 'ins',
uids: [
{
id: 'id1',
atype: 2,
},
{
id: 'id2',
atype: 2
},
{
id: 'id3',
atype: 0
}
],
ext: {v: 2}
}])
})
it('when merging with pubCommonId, should not alter its eids', () => {
const uid = {
pubProvidedId: [
Expand Down Expand Up @@ -705,6 +766,27 @@ describe('User ID', function () {
});
});

it('pbjs.getUserIdsAsEids should pass config to eid function', async function () {
const eidFn = sinon.stub();
init(config);
setSubmoduleRegistry([createMockIdSubmodule('mockId', null, null, {
mockId: eidFn
})]);
const moduleConfig = {
name: 'mockId',
value: {mockId: 'mockIdValue'},
some: 'config'
};
config.setConfig({
userSync: {
auctionDelay: 10,
userIds: [moduleConfig]
}
});
await getGlobal().getUserIdsAsync();
sinon.assert.calledWith(eidFn, ['mockIdValue'], moduleConfig);
})

it('pbjs.getUserIdsAsEids should prioritize user ids according to config available to core', () => {
init(config);
setSubmoduleRegistry([
Expand Down
Loading