Skip to content

Commit

Permalink
permutiveRtd : transform integers to strings (prebid#11910)
Browse files Browse the repository at this point in the history
* fix(permutiveRtd): transform integers to strings

* docs(permutiveRtd): update jsdoc to match function signatures

* docs(permutiveRtd): fix ordering of jsdoc comments
  • Loading branch information
AntonioGargaro authored and DecayConstant committed Jul 18, 2024
1 parent 9571b26 commit fa9dafa
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 30 deletions.
94 changes: 72 additions & 22 deletions modules/permutiveRtdProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ export function getModuleConfig(customModuleConfig) {
/**
* Sets ortb2 config for ac bidders
* @param {Object} bidderOrtb2 - The ortb2 object for the all bidders
* @param {Object} customModuleConfig - Publisher config for module
* @param {Object} moduleConfig - Publisher config for module
* @param {Object} segmentData - Segment data grouped by bidder or type
*/
export function setBidderRtb (bidderOrtb2, moduleConfig, segmentData) {
const acBidders = deepAccess(moduleConfig, 'params.acBidders')
Expand Down Expand Up @@ -129,13 +130,13 @@ export function setBidderRtb (bidderOrtb2, moduleConfig, segmentData) {

/**
* Updates `user.data` object in existing bidder config with Permutive segments
* @param string bidder - The bidder
* @param {string} bidder - The bidder identifier
* @param {Object} currConfig - Current bidder config
* @param {Object[]} transformationConfigs - array of objects with `id` and `config` properties, used to determine
* the transformations on user data to include the ORTB2 object
* @param {string[]} segmentIDs - Permutive segment IDs
* @param {string[]} sspSegmentIDs - Permutive SSP segment IDs
* @param {Object} topics - Privacy Sandbox Topics, keyed by IAB taxonomy version (600, 601, etc.)
* @param {Object[]} transformationConfigs - array of objects with `id` and `config` properties, used to determine
* the transformations on user data to include the ORTB2 object
* @param {Object} segmentData - The segments available for targeting
* @return {Object} Merged ortb2 object
*/
Expand Down Expand Up @@ -270,7 +271,7 @@ function setSegments (reqBidsConfigObj, moduleConfig, segmentData) {
*/
function makeSafe (fn) {
try {
fn()
return fn()
} catch (e) {
logError(e)
}
Expand Down Expand Up @@ -310,23 +311,71 @@ export function isPermutiveOnPage () {
* @param {number} maxSegs - Maximum number of segments to be included
* @return {Object}
*/
export function getSegments (maxSegs) {
const legacySegs = readSegments('_psegs', []).map(Number).filter(seg => seg >= 1000000).map(String)
const _ppam = readSegments('_ppam', [])
const _pcrprs = readSegments('_pcrprs', [])

export function getSegments(maxSegs) {
const segments = {
ac: [..._pcrprs, ..._ppam, ...legacySegs],
ix: readSegments('_pindexs', []),
rubicon: readSegments('_prubicons', []),
appnexus: readSegments('_papns', []),
gam: readSegments('_pdfps', []),
ssp: readSegments('_pssps', {
cohorts: [],
ssps: []
ac:
makeSafe(() => {
const legacySegs =
makeSafe(() =>
readSegments('_psegs', [])
.map(Number)
.filter((seg) => seg >= 1000000)
.map(String),
) || [];
const _ppam = makeSafe(() => readSegments('_ppam', []).map(String)) || [];
const _pcrprs = makeSafe(() => readSegments('_pcrprs', []).map(String)) || [];

return [..._pcrprs, ..._ppam, ...legacySegs];
}) || [],

ix:
makeSafe(() => {
const _pindexs = readSegments('_pindexs', []);
return _pindexs.map(String);
}) || [],

rubicon:
makeSafe(() => {
const _prubicons = readSegments('_prubicons', []);
return _prubicons.map(String);
}) || [],

appnexus:
makeSafe(() => {
const _papns = readSegments('_papns', []);
return _papns.map(String);
}) || [],

gam:
makeSafe(() => {
const _pdfps = readSegments('_pdfps', []);
return _pdfps.map(String);
}) || [],

ssp: makeSafe(() => {
const _pssps = readSegments('_pssps', {
cohorts: [],
ssps: [],
});

return {
cohorts: makeSafe(() => _pssps.cohorts.map(String)) || [],
ssps: makeSafe(() => _pssps.ssps.map(String)) || [],
};
}),
topics: readSegments('_ppsts', {}),
}

topics:
makeSafe(() => {
const _ppsts = readSegments('_ppsts', {});

const topics = {};
for (const [k, value] of Object.entries(_ppsts)) {
topics[k] = makeSafe(() => value.map(String)) || [];
}

return topics;
}) || {},
};

for (const bidder in segments) {
if (bidder === 'ssp') {
Expand All @@ -342,7 +391,8 @@ export function getSegments (maxSegs) {
}
}

return segments
logger.logInfo(`Read segments`, segments)
return segments;
}

/**
Expand Down Expand Up @@ -393,7 +443,7 @@ function iabSegmentId(permutiveSegmentId, iabIds) {
* Pull the latest configuration and cohort information and update accordingly.
*
* @param reqBidsConfigObj - Bidder provided config for request
* @param customModuleConfig - Publisher provide config
* @param moduleConfig - Publisher provided config
*/
export function readAndSetCohorts(reqBidsConfigObj, moduleConfig) {
const segmentData = getSegments(deepAccess(moduleConfig, 'params.maxSegs'))
Expand Down
50 changes: 42 additions & 8 deletions test/spec/modules/permutiveRtdProvider_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,9 @@ describe('permutiveRtdProvider', function () {
_psegs: [],
_ppam: [],
_pcrprs: [],
_pssps: { ssps: [], cohorts: [] }
_pindexs: [],
_pssps: { ssps: [], cohorts: [] },
_ppsts: {},
})

setBidderRtb(bidderConfig, moduleConfig, segmentsData)
Expand Down Expand Up @@ -568,6 +570,7 @@ describe('permutiveRtdProvider', function () {
const data = transformedTargeting()
expect(getSegments(250)).to.deep.equal(data)
})

it('should enforce max segments', function () {
const max = 1
const segments = getSegments(max)
Expand All @@ -584,6 +587,26 @@ describe('permutiveRtdProvider', function () {
}
}
})

it('should coerce numbers to strings', function () {
setLocalStorage({ _prubicons: [1, 2, 3], _pssps: { ssps: ['foo', 'bar'], cohorts: [4, 5, 6] } })

const segments = getSegments(200)

expect(segments.rubicon).to.deep.equal(['1', '2', '3'])
expect(segments.ssp.ssps).to.deep.equal(['foo', 'bar'])
expect(segments.ssp.cohorts).to.deep.equal(['4', '5', '6'])
})

it('should return empty values on unexpected format', function () {
setLocalStorage({ _prubicons: 'a string instead?', _pssps: 123 })

const segments = getSegments(200)

expect(segments.rubicon).to.deep.equal([])
expect(segments.ssp.ssps).to.deep.equal([])
expect(segments.ssp.cohorts).to.deep.equal([])
})
})

describe('Existing key-value targeting', function () {
Expand Down Expand Up @@ -703,14 +726,25 @@ function getConfig () {
}

function transformedTargeting (data = getTargetingData()) {
const topics = (() => {
const topics = {}
for (const topic in data._ppsts) {
topics[topic] = data._ppsts[topic].map(String)
}
return topics
})()

return {
ac: [...data._pcrprs, ...data._ppam, ...data._psegs.filter(seg => seg >= 1000000)],
appnexus: data._papns,
ix: data._pindexs,
rubicon: data._prubicons,
gam: data._pdfps,
ssp: data._pssps,
topics: data._ppsts,
ac: [...data._pcrprs, ...data._ppam, ...data._psegs.filter(seg => seg >= 1000000)].map(String),
appnexus: data._papns.map(String),
ix: data._pindexs.map(String),
rubicon: data._prubicons.map(String),
gam: data._pdfps.map(String),
ssp: {
ssps: data._pssps.ssps.map(String),
cohorts: data._pssps.cohorts.map(String)
},
topics,
}
}

Expand Down

0 comments on commit fa9dafa

Please sign in to comment.