From 05245b263f901193ec92e6f0c4b5c11aa583f801 Mon Sep 17 00:00:00 2001 From: Kajan Umakanthan Date: Wed, 21 Apr 2021 16:59:38 -0700 Subject: [PATCH 1/7] pass fpd data to r object --- modules/ixBidAdapter.js | 59 +++++++++++- test/spec/modules/ixBidAdapter_spec.js | 125 +++++++++++++++++++++++++ 2 files changed, 183 insertions(+), 1 deletion(-) diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js index 766ece90fce..642aa05dc34 100644 --- a/modules/ixBidAdapter.js +++ b/modules/ixBidAdapter.js @@ -26,6 +26,15 @@ const USER_SYNC_URL = 'https://js-sec.indexww.com/um/ixmatch.html'; const FLOOR_SOURCE = { PBJS: 'p', IX: 'x' }; // determines which eids we send and the rtiPartner field in ext + +const FIRST_PARTY_DATA = { + SITE: [ + 'id', 'name', 'domain', 'cat', 'sectioncat', 'pagecat', 'page', 'ref', 'search', 'mobile', + 'privacypolicy', 'publisher', 'content', 'keywords', 'ext' + ], + USER: ['id', 'buyeruid', 'yob', 'gender', 'keywords', 'customdata', 'geo', 'data', 'ext'] +}; + const SOURCE_RTI_MAPPING = { 'liveramp.com': 'idl', 'netid.de': 'NETID', @@ -566,6 +575,8 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { } let currentRequestSize = baseRequestSize; + let fpdRequestSize = 0; + let isFpdAdded = false; if (otherIxConfig) { // Append firstPartyData to r.site.page if firstPartyData exists. @@ -579,7 +590,18 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { } firstPartyString = firstPartyString.slice(0, -1); - r.site.page += firstPartyString; + fpdRequestSize = encodeURIComponent(firstPartyString).length; + + if (fpdRequestSize < MAX_REQUEST_SIZE) { + if ('page' in r.site) { + r.site.page += firstPartyString; + } else { + r.site.page = firstPartyString; + } + currentRequestSize += fpdRequestSize; + } else { + utils.logError('ix bidder: IX config FPD request size has exceeded maximum request size.'); + } } // Create t in payload if timeout is configured. @@ -642,6 +664,41 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { r.imp.push(...impressionObjects); } + currentRequestSize += currentImpressionSize; + + const fpd = config.getConfig('ortb2') || {}; + + if (!utils.isEmpty(fpd) && !isFpdAdded) { + r.ext.ixdiag.fpd = true; + + const site = { ...(fpd.site || fpd.context) }; + + Object.keys(site).forEach(key => { + if (FIRST_PARTY_DATA.SITE.indexOf(key) === -1) { + delete site[key]; + } + }); + + const user = { ...fpd.user }; + + Object.keys(user).forEach(key => { + if (FIRST_PARTY_DATA.USER.indexOf(key) === -1) { + delete user[key]; + } + }); + + const fpdRequestSize = encodeURIComponent(utils.parseQueryStringParameters({ ...site, ...user })).length; + + if (currentRequestSize + fpdRequestSize < MAX_REQUEST_SIZE) { + r.site = utils.mergeDeep({}, r.site, site); + r.user = utils.mergeDeep({}, r.user, user); + isFpdAdded = true; + currentRequestSize += fpdRequestSize; + } else { + utils.logError('ix bidder: FPD request size has exceeded maximum request size.'); + } + } + const isLastAdUnit = adUnitIndex === transactionIds.length - 1; if (wasAdUnitImpressionsTrimmed || isLastAdUnit) { diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js index 4c24af6c082..698ec807138 100644 --- a/test/spec/modules/ixBidAdapter_spec.js +++ b/test/spec/modules/ixBidAdapter_spec.js @@ -1232,6 +1232,131 @@ describe('IndexexchangeAdapter', function () { }); }); + describe('First party data', function () { + afterEach(function () { + config.setConfig({ + ortb2: {} + }); + }); + + it('should not set ixdiag.fpd value if not defined', function () { + const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0]; + const r = JSON.parse(request.data.r); + + expect(r.ext.ixdiag.fpd).to.be.undefined; + }); + + it('should set ixdiag.fpd value if it exists using fpd', function () { + config.setConfig({ + fpd: { + site: { + data: { + pageType: 'article' + } + } + } + }); + + const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0]; + const r = JSON.parse(request.data.r); + + expect(r.ext.ixdiag.fpd).to.exist; + }); + + it('should set ixdiag.fpd value if it exists using ortb2', function () { + config.setConfig({ + ortb2: { + site: { + ext: { + data: { + pageType: 'article' + } + } + } + } + }); + + const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0]; + const r = JSON.parse(request.data.r); + + expect(r.ext.ixdiag.fpd).to.exist; + }); + + it('should not send information that is not part of openRTB spec v2.5 using fpd', function () { + config.setConfig({ + fpd: { + site: { + keywords: 'power tools, drills', + search: 'drill', + testProperty: 'test_string' + }, + user: { + keywords: ['a'], + testProperty: 'test_string' + } + } + }); + + const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0]; + const r = JSON.parse(request.data.r); + + expect(r.site.keywords).to.exist; + expect(r.site.search).to.exist; + expect(r.site.testProperty).to.be.undefined; + expect(r.user.keywords).to.exist; + expect(r.user.testProperty).to.be.undefined; + }); + + it('should not send information that is not part of openRTB spec v2.5 using ortb2', function () { + config.setConfig({ + ortb2: { + site: { + keywords: 'power tools, drills', + search: 'drill', + testProperty: 'test_string' + }, + user: { + keywords: ['a'], + testProperty: 'test_string' + } + } + }); + + const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0]; + const r = JSON.parse(request.data.r); + + expect(r.site.keywords).to.exist; + expect(r.site.search).to.exist; + expect(r.site.testProperty).to.be.undefined; + expect(r.user.keywords).to.exist; + expect(r.user.testProperty).to.be.undefined; + }); + + it('should not add fpd data to r object if it exceeds maximum request', function () { + config.setConfig({ + ortb2: { + site: { + keywords: 'power tools, drills', + search: 'drill', + }, + user: { + keywords: ['Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. sunt in culpa qui officia deserunt mollit anim id est laborum. sunt in culpa qui officia deserunt mollit anim id est laborum.'], + } + } + }); + + const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); + bid.mediaTypes.banner.sizes = LARGE_SET_OF_SIZES; + + const request = spec.buildRequests([bid])[0]; + const r = JSON.parse(request.data.r); + + expect(r.site.ref).to.exist; + expect(r.site.keywords).to.be.undefined; + expect(r.user).to.be.undefined; + }); + }); + describe('buildRequests', function () { let request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0]; const requestUrl = request.url; From e394c3efa95d214d75af86c24697bfcef73e1779 Mon Sep 17 00:00:00 2001 From: Kajan Umakanthan Date: Tue, 18 May 2021 13:26:28 -0700 Subject: [PATCH 2/7] remove .repeat() func in tests --- test/spec/modules/ixBidAdapter_spec.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js index 698ec807138..51e6afd8028 100644 --- a/test/spec/modules/ixBidAdapter_spec.js +++ b/test/spec/modules/ixBidAdapter_spec.js @@ -1232,14 +1232,12 @@ describe('IndexexchangeAdapter', function () { }); }); - describe('First party data', function () { - afterEach(function () { + describe.only('First party data', function () { + it('should not set ixdiag.fpd value if not defined', function () { config.setConfig({ ortb2: {} }); - }); - it('should not set ixdiag.fpd value if not defined', function () { const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0]; const r = JSON.parse(request.data.r); From 7d5677115b6e9d11cf314b50a086185d56b97195 Mon Sep 17 00:00:00 2001 From: Kajan Umakanthan Date: Thu, 3 Jun 2021 11:49:54 -0700 Subject: [PATCH 3/7] check if r.site.page exists --- test/spec/modules/ixBidAdapter_spec.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js index 51e6afd8028..3b36da2c604 100644 --- a/test/spec/modules/ixBidAdapter_spec.js +++ b/test/spec/modules/ixBidAdapter_spec.js @@ -1232,7 +1232,13 @@ describe('IndexexchangeAdapter', function () { }); }); - describe.only('First party data', function () { + describe('First party data', function () { + afterEach(function() { + config.setConfig({ + ortb2: {} + }) + }); + it('should not set ixdiag.fpd value if not defined', function () { config.setConfig({ ortb2: {} From 0d6f51ee7e223c468374f44df3671f71966ce782 Mon Sep 17 00:00:00 2001 From: Kajan Umakanthan Date: Thu, 17 Jun 2021 09:54:50 -0700 Subject: [PATCH 4/7] use config.getConfig('ortb2') --- modules/ixBidAdapter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js index 642aa05dc34..58da2bde9c5 100644 --- a/modules/ixBidAdapter.js +++ b/modules/ixBidAdapter.js @@ -721,6 +721,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { r.imp = []; r.ext.ixdiag.msd = 0; r.ext.ixdiag.msi = 0; + isFpdAdded = false; } } From ba0447f68bee85f9241cf8091f3b04eaca1cf300 Mon Sep 17 00:00:00 2001 From: Kajan Umakanthan Date: Mon, 19 Jul 2021 10:09:47 -0700 Subject: [PATCH 5/7] use JSON.stringify to calculate fpd length --- modules/ixBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js index 58da2bde9c5..f41cd709c7c 100644 --- a/modules/ixBidAdapter.js +++ b/modules/ixBidAdapter.js @@ -687,7 +687,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { } }); - const fpdRequestSize = encodeURIComponent(utils.parseQueryStringParameters({ ...site, ...user })).length; + const fpdRequestSize = encodeURIComponent(JSON.stringify({ ...site, ...user })).length; if (currentRequestSize + fpdRequestSize < MAX_REQUEST_SIZE) { r.site = utils.mergeDeep({}, r.site, site); From 42014d1d45fe80d801e455769be621f74ca9d4b0 Mon Sep 17 00:00:00 2001 From: Kajan Umakanthan Date: Thu, 22 Jul 2021 09:06:32 -0700 Subject: [PATCH 6/7] explicitly calculate request size for fpd --- modules/ixBidAdapter.js | 10 ++++++++-- test/spec/modules/ixBidAdapter_spec.js | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js index f41cd709c7c..941fcb1f017 100644 --- a/modules/ixBidAdapter.js +++ b/modules/ixBidAdapter.js @@ -687,12 +687,18 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { } }); - const fpdRequestSize = encodeURIComponent(JSON.stringify({ ...site, ...user })).length; + const clonedRObject = utils.deepClone(r); - if (currentRequestSize + fpdRequestSize < MAX_REQUEST_SIZE) { + clonedRObject.site = utils.mergeDeep({}, clonedRObject.site, site); + clonedRObject.user = utils.mergeDeep({}, clonedRObject.user, user); + + const requestSize = `${baseUrl}${utils.parseQueryStringParameters({ ...payload, r: JSON.stringify(clonedRObject) })}`.length; + + if (requestSize < MAX_REQUEST_SIZE) { r.site = utils.mergeDeep({}, r.site, site); r.user = utils.mergeDeep({}, r.user, user); isFpdAdded = true; + const fpdRequestSize = encodeURIComponent(JSON.stringify({ ...site, ...user })).length; currentRequestSize += fpdRequestSize; } else { utils.logError('ix bidder: FPD request size has exceeded maximum request size.'); diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js index 3b36da2c604..53bfc74af7f 100644 --- a/test/spec/modules/ixBidAdapter_spec.js +++ b/test/spec/modules/ixBidAdapter_spec.js @@ -1344,7 +1344,7 @@ describe('IndexexchangeAdapter', function () { search: 'drill', }, user: { - keywords: ['Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. sunt in culpa qui officia deserunt mollit anim id est laborum. sunt in culpa qui officia deserunt mollit anim id est laborum.'], + keywords: Array(1000).join('#'), } } }); From 111e03aaed6995ffb95ea3a5097cfb525bfe86f2 Mon Sep 17 00:00:00 2001 From: Kajan Umakanthan Date: Thu, 22 Jul 2021 09:58:18 -0700 Subject: [PATCH 7/7] check for impressionObjects.length --- modules/ixBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js index 941fcb1f017..2d7157bc674 100644 --- a/modules/ixBidAdapter.js +++ b/modules/ixBidAdapter.js @@ -639,7 +639,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { currentImpressionSize = encodeURIComponent(JSON.stringify({ impressionObjects })).length; } - if (BANNER in impressionObjects[0]) { + if (impressionObjects.length && BANNER in impressionObjects[0]) { const { id, banner: { topframe } } = impressionObjects[0]; const _bannerImpression = { id,