Skip to content

Commit

Permalink
UserID: allow any contents in EIDs
Browse files Browse the repository at this point in the history
  • Loading branch information
dgirardi committed Jan 13, 2025
1 parent ea87c0e commit 5b379b4
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 7 deletions.
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

0 comments on commit 5b379b4

Please sign in to comment.