From 33762d1ee5abd0363e2b35fbbb07cb2d38287972 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Thu, 12 Sep 2019 16:38:12 -0700 Subject: [PATCH 1/9] added support for pubcommon, digitrust, id5id --- modules/pubmaticBidAdapter.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index facecdaa578..2ec353a2f4e 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -624,10 +624,31 @@ function _handleTTDId(eids, validBidRequests) { } } +/** + * Produces external userid object in ortb 3.0 model. + */ +function _addExternalUserId(eids, value, source, atype) { + if (value) { + eids.push({ + source, + uids: [{ + id: value, + atype + }] + }); + } +} + function _handleEids(payload, validBidRequests) { let eids = []; _handleDigitrustId(eids); _handleTTDId(eids, validBidRequests); + const bidRequest = validBidRequests[0]; + if(bidRequest && bidRequest.userId){ + _addExternalUserId(eids, bidRequest.userId.pubcid, 'pubcommon', 1); + _addExternalUserId(eids, utils.deepAccess(bidRequest.userId.digitrustid, 'data.id'), 'digitru.st', 1); + _addExternalUserId(eids, bidRequest.userId.id5id, 'id5id', 1); + } if (eids.length > 0) { payload.user.eids = eids; } From 0722354d7e62dc2237e16f8b7f469557ef388a20 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Thu, 12 Sep 2019 20:11:24 -0700 Subject: [PATCH 2/9] added support for IdentityLink --- modules/pubmaticBidAdapter.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 2ec353a2f4e..8c72367ba6e 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -644,10 +644,12 @@ function _handleEids(payload, validBidRequests) { _handleDigitrustId(eids); _handleTTDId(eids, validBidRequests); const bidRequest = validBidRequests[0]; - if(bidRequest && bidRequest.userId){ - _addExternalUserId(eids, bidRequest.userId.pubcid, 'pubcommon', 1); - _addExternalUserId(eids, utils.deepAccess(bidRequest.userId.digitrustid, 'data.id'), 'digitru.st', 1); - _addExternalUserId(eids, bidRequest.userId.id5id, 'id5id', 1); + if (bidRequest && bidRequest.userId) { + _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.pubcid`), 'pubcommon', 1); + _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.digitrustid.data.id`), 'digitru.st', 1); + _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.id5id`), 'id5id', 1); + _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.criteortus.${BIDDER_CODE}.userid`), 'criteortus', 1); + _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.idl_env`), 'identity_link_envelope', 1); } if (eids.length > 0) { payload.user.eids = eids; From f2c32c07b4a4996e1e7d59510974c07d2eec7d5e Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Fri, 13 Sep 2019 10:02:20 -0700 Subject: [PATCH 3/9] changed the source for id5 --- modules/pubmaticBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 8c72367ba6e..c768583b96c 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -647,7 +647,7 @@ function _handleEids(payload, validBidRequests) { if (bidRequest && bidRequest.userId) { _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.pubcid`), 'pubcommon', 1); _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.digitrustid.data.id`), 'digitru.st', 1); - _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.id5id`), 'id5id', 1); + _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.id5id`), 'id5-sync.com', 1); _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.criteortus.${BIDDER_CODE}.userid`), 'criteortus', 1); _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.idl_env`), 'identity_link_envelope', 1); } From eaed9874c1fc91d79118b148bbd740569e562023 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Fri, 13 Sep 2019 14:19:36 -0700 Subject: [PATCH 4/9] added unit test cases --- modules/pubmaticBidAdapter.js | 2 +- test/spec/modules/pubmaticBidAdapter_spec.js | 186 +++++++++++++++++++ 2 files changed, 187 insertions(+), 1 deletion(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index c768583b96c..a85a2c8e19c 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -628,7 +628,7 @@ function _handleTTDId(eids, validBidRequests) { * Produces external userid object in ortb 3.0 model. */ function _addExternalUserId(eids, value, source, atype) { - if (value) { + if (utils.isStr(value)) { eids.push({ source, uids: [{ diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 3de83c56213..d0d0ce8c08b 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -1476,6 +1476,192 @@ describe('PubMatic adapter', function () { }); }); + describe('UserIds from request', function() { + describe('pubcommon Id', function() { + it('send the pubcommon id if it is present', function() { + bidRequests[0].userId = {}; + bidRequests[0].userId.pubcid = 'pub_common_user_id'; + let request = spec.buildRequests(bidRequests, {}); + let data = JSON.parse(request.data); + expect(data.user.eids).to.deep.equal([{ + 'source': 'pubcommon', + 'uids': [{ + 'id': 'pub_common_user_id', + 'atype': 1 + }] + }]); + }); + + it('do not pass if not string', function() { + bidRequests[0].userId = {}; + bidRequests[0].userId.pubcid = 1; + let request = spec.buildRequests(bidRequests, {}); + let data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.pubcid = []; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.pubcid = null; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.pubcid = {}; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + }); + }); + + describe('Digitrust Id', function() { + it('send the digitrust id if it is present', function() { + bidRequests[0].userId = {}; + bidRequests[0].userId.digitrustid = {data: {id: 'digitrust_user_id'}}; + let request = spec.buildRequests(bidRequests, {}); + let data = JSON.parse(request.data); + expect(data.user.eids).to.deep.equal([{ + 'source': 'digitru.st', + 'uids': [{ + 'id': 'digitrust_user_id', + 'atype': 1 + }] + }]); + }); + + it('do not pass if not string', function() { + bidRequests[0].userId = {}; + bidRequests[0].userId.digitrustid = {data: {id: 1}}; + let request = spec.buildRequests(bidRequests, {}); + let data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.digitrustid = {data: {id: []}}; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.digitrustid = {data: {id: null}}; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.digitrustid = {data: {id: {}}}; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + }); + }); + + describe('ID5 Id', function() { + it('send the id5 id if it is present', function() { + bidRequests[0].userId = {}; + bidRequests[0].userId.id5id = 'id5-user-id'; + let request = spec.buildRequests(bidRequests, {}); + let data = JSON.parse(request.data); + expect(data.user.eids).to.deep.equal([{ + 'source': 'id5-sync.com', + 'uids': [{ + 'id': 'id5-user-id', + 'atype': 1 + }] + }]); + }); + + it('do not pass if not string', function() { + bidRequests[0].userId = {}; + bidRequests[0].userId.id5id = 1; + let request = spec.buildRequests(bidRequests, {}); + let data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.id5id = []; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.id5id = null; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.id5id = {}; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + }); + }); + + describe('CriteoRTUS Id', function() { + it('send the criteo id if it is present', function() { + bidRequests[0].userId = {}; + bidRequests[0].userId.criteortus = {pubmatic: {userid: 'criteo-rtus-user-id'}}; + let request = spec.buildRequests(bidRequests, {}); + let data = JSON.parse(request.data); + expect(data.user.eids).to.deep.equal([{ + 'source': 'criteortus', + 'uids': [{ + 'id': 'criteo-rtus-user-id', + 'atype': 1 + }] + }]); + }); + + it('do not pass if not string', function() { + bidRequests[0].userId = {}; + bidRequests[0].userId.criteortus = {appnexus: {userid: 'criteo-rtus-user-id'}}; + let request = spec.buildRequests(bidRequests, {}); + let data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.criteortus = {pubmatic: {userid: 1}}; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.criteortus = {pubmatic: {userid: []}}; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.criteortus = {pubmatic: {userid: null}}; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.criteortus = {pubmatic: {userid: {}}}; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + }); + }); + + describe('IdentityLink Id', function() { + it('send the identity-link id if it is present', function() { + bidRequests[0].userId = {}; + bidRequests[0].userId.idl_env = 'identity-link-user-id'; + let request = spec.buildRequests(bidRequests, {}); + let data = JSON.parse(request.data); + expect(data.user.eids).to.deep.equal([{ + 'source': 'identity_link_envelope', + 'uids': [{ + 'id': 'identity-link-user-id', + 'atype': 1 + }] + }]); + }); + + it('do not pass if not string', function() { + bidRequests[0].userId = {}; + bidRequests[0].userId.idl_env = 1; + let request = spec.buildRequests(bidRequests, {}); + let data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.idl_env = []; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.idl_env = null; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + bidRequests[0].userId.idl_env = {}; + request = spec.buildRequests(bidRequests, {}); + data = JSON.parse(request.data); + expect(data.user.eids).to.equal(undefined); + }); + }); + }) + it('Request params check for video ad', function () { let request = spec.buildRequests(videoBidRequests); let data = JSON.parse(request.data); From 602ee7ea83c07cf1ff83f6c000473512a9525b4c Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Mon, 16 Sep 2019 14:24:27 -0700 Subject: [PATCH 5/9] changed source param for identityLink --- modules/pubmaticBidAdapter.js | 2 +- test/spec/modules/pubmaticBidAdapter_spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index a85a2c8e19c..d1e1d072673 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -649,7 +649,7 @@ function _handleEids(payload, validBidRequests) { _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.digitrustid.data.id`), 'digitru.st', 1); _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.id5id`), 'id5-sync.com', 1); _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.criteortus.${BIDDER_CODE}.userid`), 'criteortus', 1); - _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.idl_env`), 'identity_link_envelope', 1); + _addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.idl_env`), 'liveramp.com', 1); } if (eids.length > 0) { payload.user.eids = eids; diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index d0d0ce8c08b..ababf2dcf5f 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -1632,7 +1632,7 @@ describe('PubMatic adapter', function () { let request = spec.buildRequests(bidRequests, {}); let data = JSON.parse(request.data); expect(data.user.eids).to.deep.equal([{ - 'source': 'identity_link_envelope', + 'source': 'liveramp.com', 'uids': [{ 'id': 'identity-link-user-id', 'atype': 1 From 44fcdf2a3482315b6050be3691d2aea4b0fe0ad7 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Tue, 28 Jul 2020 16:12:55 -0700 Subject: [PATCH 6/9] read content object from config and send it in site.content and app.content --- modules/pubmaticBidAdapter.js | 6 ++++++ test/spec/modules/pubmaticBidAdapter_spec.js | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 2e52fd27cf1..903904180d2 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -865,6 +865,11 @@ export const spec = { payload.site.page = conf.kadpageurl.trim() || payload.site.page.trim(); payload.site.domain = _getDomainFromURL(payload.site.page); + // add the content object from config in request + if (typeof config.getConfig('content') === 'object') { + payload.device = Object.assign(payload.site.content, config.getConfig('content')); + } + // merge the device from config.getConfig('device') if (typeof config.getConfig('device') === 'object') { payload.device = Object.assign(payload.device, config.getConfig('device')); @@ -910,6 +915,7 @@ export const spec = { // not copying domain from site as it is a derived value from page payload.app.publisher = payload.site.publisher; payload.app.ext = payload.site.ext || UNDEFINED; + payload.app.content = payload.site.content || UNDEFINED; delete payload.site; } diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 1e8ab8f9faf..befe0699fdb 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -776,6 +776,23 @@ describe('PubMatic adapter', function () { expect(data.source.ext.schain).to.deep.equal(bidRequests[0].schain); }); + it('Set content from config, set site.content', function() { + let sandbox = sinon.sandbox.create(); + const content = { + 'id': 'alpha-numeric-id' + }; + sandbox.stub(config, 'getConfig').callsFake((key) => { + var config = { + content: content + }; + return config[key]; + }); + let request = spec.buildRequests(bidRequests); + let data = JSON.parse(request.data); + expect(data.site.content).to.deep.equal({}); + sandbox.restore(); + }); + it('Merge the device info from config', function() { let sandbox = sinon.sandbox.create(); sandbox.stub(config, 'getConfig').callsFake((key) => { From d7788414048c4e6b7c1efe2fa37a240fb23f99a8 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Tue, 28 Jul 2020 17:07:16 -0700 Subject: [PATCH 7/9] do not use content object from config if content object is present in app as app.content --- modules/pubmaticBidAdapter.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 903904180d2..161a6d14a7d 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -915,7 +915,11 @@ export const spec = { // not copying domain from site as it is a derived value from page payload.app.publisher = payload.site.publisher; payload.app.ext = payload.site.ext || UNDEFINED; - payload.app.content = payload.site.content || UNDEFINED; + // We will also need to pass content object in app.content if app object is also set into the config; + // BUT do not use content object from config if content object is present in app as app.content + if (typeof payload.app.content !== 'object') { + payload.app.content = payload.site.content || UNDEFINED; + } delete payload.site; } From f226f510a213f0e9f7b00c47fc063082deba26b2 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Tue, 28 Jul 2020 23:28:31 -0700 Subject: [PATCH 8/9] fixed the test-cases --- modules/pubmaticBidAdapter.js | 2 +- test/spec/modules/pubmaticBidAdapter_spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index 161a6d14a7d..437e37de83e 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -867,7 +867,7 @@ export const spec = { // add the content object from config in request if (typeof config.getConfig('content') === 'object') { - payload.device = Object.assign(payload.site.content, config.getConfig('content')); + payload.site.content = config.getConfig('content'); } // merge the device from config.getConfig('device') diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index befe0699fdb..806aa475830 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -789,7 +789,7 @@ describe('PubMatic adapter', function () { }); let request = spec.buildRequests(bidRequests); let data = JSON.parse(request.data); - expect(data.site.content).to.deep.equal({}); + expect(data.site.content).to.deep.equal(content); sandbox.restore(); }); From 009a849a477bad82393acc65b99dd156e4cbb549 Mon Sep 17 00:00:00 2001 From: Harshad Mane Date: Wed, 29 Jul 2020 10:29:58 -0700 Subject: [PATCH 9/9] app.content related test cases --- test/spec/modules/pubmaticBidAdapter_spec.js | 56 ++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 806aa475830..11491b9c57c 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -857,6 +857,62 @@ describe('PubMatic adapter', function () { sandbox.restore(); }); + it('Set app, content from config, copy publisher and ext from site, unset site, config.content in app.content', function() { + let sandbox = sinon.sandbox.create(); + const content = { + 'id': 'alpha-numeric-id' + }; + sandbox.stub(config, 'getConfig').callsFake((key) => { + var config = { + content: content, + app: { + bundle: 'org.prebid.mobile.demoapp', + domain: 'prebid.org' + } + }; + return config[key]; + }); + let request = spec.buildRequests(bidRequests); + let data = JSON.parse(request.data); + expect(data.app.bundle).to.equal('org.prebid.mobile.demoapp'); + expect(data.app.domain).to.equal('prebid.org'); + expect(data.app.publisher.id).to.equal(bidRequests[0].params.publisherId); + expect(data.app.ext.key_val).to.exist.and.to.equal(bidRequests[0].params.dctr); + expect(data.app.content).to.deep.equal(content); + expect(data.site).to.not.exist; + sandbox.restore(); + }); + + it('Set app.content, content from config, copy publisher and ext from site, unset site, config.app.content in app.content', function() { + let sandbox = sinon.sandbox.create(); + const content = { + 'id': 'alpha-numeric-id' + }; + const appContent = { + id: 'app-content-id-2' + }; + sandbox.stub(config, 'getConfig').callsFake((key) => { + var config = { + content: content, + app: { + bundle: 'org.prebid.mobile.demoapp', + domain: 'prebid.org', + content: appContent + } + }; + return config[key]; + }); + let request = spec.buildRequests(bidRequests); + let data = JSON.parse(request.data); + expect(data.app.bundle).to.equal('org.prebid.mobile.demoapp'); + expect(data.app.domain).to.equal('prebid.org'); + expect(data.app.publisher.id).to.equal(bidRequests[0].params.publisherId); + expect(data.app.ext.key_val).to.exist.and.to.equal(bidRequests[0].params.dctr); + expect(data.app.content).to.deep.equal(appContent); + expect(data.site).to.not.exist; + sandbox.restore(); + }); + it('Request params check: without adSlot', function () { delete bidRequests[0].params.adSlot; let request = spec.buildRequests(bidRequests);