From 7c0c732805b0a43e8ef0559386f2d93ac9c00817 Mon Sep 17 00:00:00 2001 From: Anand Venkatraman Date: Tue, 10 Dec 2019 21:26:39 -0500 Subject: [PATCH] PulsePoint: CCPA and new UserId partner integration (#4565) * ET-1691: Pulsepoint Analytics adapter for Prebid. (#1) * ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter * ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter * ET-1691: cleanup * ET-1691: minor * ET-1691: revert package.json change * Adding bidRequest to bidFactory.createBid method as per https://github.com/prebid/Prebid.js/issues/509 * ET-1765: Adding support for additional params in PulsePoint adapter (#2) * ET-1850: Fixing https://github.com/prebid/Prebid.js/issues/866 * Minor fix * Adding mandatory parameters to Bid * PulsePoint: CCPA and new user id partner integration * Review comment --- modules/pulsepointBidAdapter.js | 53 +++++++++++++--- .../spec/modules/pulsepointBidAdapter_spec.js | 62 +++++++++++++++++-- 2 files changed, 100 insertions(+), 15 deletions(-) diff --git a/modules/pulsepointBidAdapter.js b/modules/pulsepointBidAdapter.js index c3fd1fa5eaf..b898618673e 100644 --- a/modules/pulsepointBidAdapter.js +++ b/modules/pulsepointBidAdapter.js @@ -397,9 +397,31 @@ function user(bidRequest, bidderRequest) { if (bidRequest.userId) { ext.eids = []; addExternalUserId(ext.eids, bidRequest.userId.pubcid, 'pubcommon'); - addExternalUserId(ext.eids, bidRequest.userId.tdid, 'ttdid'); - addExternalUserId(ext.eids, utils.deepAccess(bidRequest.userId.digitrustid, 'data.id'), 'digitrust'); - addExternalUserId(ext.eids, bidRequest.userId.id5id, 'id5id'); + addExternalUserId(ext.eids, bidRequest.userId.britepoolid, 'britepool.com'); + addExternalUserId(ext.eids, bidRequest.userId.criteoId, 'criteo'); + addExternalUserId(ext.eids, bidRequest.userId.idl_env, 'identityLink'); + addExternalUserId(ext.eids, bidRequest.userId.id5id, 'id5-sync.com'); + addExternalUserId(ext.eids, bidRequest.userId.parrableid, 'parrable.com'); + // liveintent + if (bidRequest.userId.lipb && bidRequest.userId.lipb.lipbid) { + addExternalUserId(ext.eids, bidRequest.userId.lipb.lipbid, 'liveintent.com'); + } + // TTD + addExternalUserId(ext.eids, bidRequest.userId.tdid, 'adserver.org', { + rtiPartner: 'TDID' + }); + // digitrust + const digitrustResponse = bidRequest.userId.digitrustid; + if (digitrustResponse && digitrustResponse.data) { + var digitrust = {}; + if (digitrustResponse.data.id) { + digitrust.id = digitrustResponse.data.id; + } + if (digitrustResponse.data.keyv) { + digitrust.keyv = digitrustResponse.data.keyv; + } + ext.digitrust = digitrust; + } } } return { ext }; @@ -408,13 +430,15 @@ function user(bidRequest, bidderRequest) { /** * Produces external userid object in ortb 3.0 model. */ -function addExternalUserId(eids, value, source) { - if (value) { +function addExternalUserId(eids, id, source, uidExt) { + if (id) { + var uid = { id }; + if (uidExt) { + uid.ext = uidExt; + } eids.push({ source, - uids: [{ - id: value - }] + uids: [ uid ] }); } } @@ -423,8 +447,17 @@ function addExternalUserId(eids, value, source) { * Produces the regulations ortb object */ function regs(bidderRequest) { - if (bidderRequest && bidderRequest.gdprConsent) { - return { ext: { gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0 } }; + if (bidderRequest.gdprConsent || bidderRequest.uspConsent) { + var ext = {}; + // GDPR applies attribute (actual consent value is in user object) + if (bidderRequest.gdprConsent) { + ext.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; + } + // CCPA + if (bidderRequest.uspConsent) { + ext.us_privacy = bidderRequest.uspConsent; + } + return { ext }; } return null; } diff --git a/test/spec/modules/pulsepointBidAdapter_spec.js b/test/spec/modules/pulsepointBidAdapter_spec.js index b62b799c8a0..6ab05a0a001 100644 --- a/test/spec/modules/pulsepointBidAdapter_spec.js +++ b/test/spec/modules/pulsepointBidAdapter_spec.js @@ -431,6 +431,20 @@ describe('PulsePoint Adapter Tests', function () { expect(ortbRequest.regs.ext.gdpr).to.equal(1); }); + it('Verify CCPA', function () { + const bidderRequestUSPrivacy = { + uspConsent: '1YYY' + }; + const request = spec.buildRequests(slotConfigs, Object.assign({}, bidderRequest, bidderRequestUSPrivacy)); + expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid'); + expect(request.method).to.equal('POST'); + const ortbRequest = request.data; + // regs object + expect(ortbRequest.regs).to.not.equal(null); + expect(ortbRequest.regs.ext).to.not.equal(null); + expect(ortbRequest.regs.ext.us_privacy).to.equal('1YYY'); + }); + it('Verify Video request', function () { const request = spec.buildRequests(videoSlotConfig, bidderRequest); expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid'); @@ -592,15 +606,53 @@ describe('PulsePoint Adapter Tests', function () { expect(ortbRequest.user).to.not.be.undefined; expect(ortbRequest.user.ext).to.not.be.undefined; expect(ortbRequest.user.ext.eids).to.not.be.undefined; - expect(ortbRequest.user.ext.eids).to.have.lengthOf(3); + expect(ortbRequest.user.ext.eids).to.have.lengthOf(2); expect(ortbRequest.user.ext.eids[0].source).to.equal('pubcommon'); expect(ortbRequest.user.ext.eids[0].uids).to.have.lengthOf(1); expect(ortbRequest.user.ext.eids[0].uids[0].id).to.equal('userid_pubcid'); - expect(ortbRequest.user.ext.eids[1].source).to.equal('ttdid'); + expect(ortbRequest.user.ext.eids[1].source).to.equal('adserver.org'); expect(ortbRequest.user.ext.eids[1].uids).to.have.lengthOf(1); expect(ortbRequest.user.ext.eids[1].uids[0].id).to.equal('userid_ttd'); - expect(ortbRequest.user.ext.eids[2].source).to.equal('digitrust'); - expect(ortbRequest.user.ext.eids[2].uids).to.have.lengthOf(1); - expect(ortbRequest.user.ext.eids[2].uids[0].id).to.equal('userid_digitrust'); + expect(ortbRequest.user.ext.eids[1].uids[0].ext).to.not.be.null; + expect(ortbRequest.user.ext.eids[1].uids[0].ext.rtiPartner).to.equal('TDID'); + expect(ortbRequest.user.ext.digitrust).to.not.be.null; + expect(ortbRequest.user.ext.digitrust.id).to.equal('userid_digitrust'); + expect(ortbRequest.user.ext.digitrust.keyv).to.equal(4); + }); + it('Verify new external user id partners', function () { + const bidRequests = deepClone(slotConfigs); + bidRequests[0].userId = { + britepoolid: 'britepool_id123', + criteoId: 'criteo_id234', + idl_env: 'idl_id123', + id5id: 'id5id_234', + parrableid: 'parrable_id234', + lipb: { + lipbid: 'liveintent_id123' + } + }; + const userVerify = function(obj, source, id) { + expect(obj).to.deep.equal({ + source, + uids: [{ + id + }] + }); + }; + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request).to.be.not.null; + const ortbRequest = request.data; + expect(request.data).to.be.not.null; + // user object + expect(ortbRequest.user).to.not.be.undefined; + expect(ortbRequest.user.ext).to.not.be.undefined; + expect(ortbRequest.user.ext.eids).to.not.be.undefined; + expect(ortbRequest.user.ext.eids).to.have.lengthOf(6); + userVerify(ortbRequest.user.ext.eids[0], 'britepool.com', 'britepool_id123'); + userVerify(ortbRequest.user.ext.eids[1], 'criteo', 'criteo_id234'); + userVerify(ortbRequest.user.ext.eids[2], 'identityLink', 'idl_id123'); + userVerify(ortbRequest.user.ext.eids[3], 'id5-sync.com', 'id5id_234'); + userVerify(ortbRequest.user.ext.eids[4], 'parrable.com', 'parrable_id234'); + userVerify(ortbRequest.user.ext.eids[5], 'liveintent.com', 'liveintent_id123'); }); });