From 33e1c3ed54866315e4a507d5d00a7b63cda4a063 Mon Sep 17 00:00:00 2001 From: Anass Seddiki Date: Mon, 13 Jun 2022 13:39:27 +0000 Subject: [PATCH 01/12] Complete mock request to PAPI response for tests --- test/spec/modules/1plusXRtdProvider_spec.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/spec/modules/1plusXRtdProvider_spec.js b/test/spec/modules/1plusXRtdProvider_spec.js index c0eb2d6a3b2..e2ec48640f2 100644 --- a/test/spec/modules/1plusXRtdProvider_spec.js +++ b/test/spec/modules/1plusXRtdProvider_spec.js @@ -6,6 +6,14 @@ import { onePlusXSubmodule } from 'modules/1plusXRtdProvider'; describe('1plusXRtdProvider', () => { const reqBidsConfigObj = {}; let fakeServer; + const fakeResponseHeaders = { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*' + }; + const fakeResponse = { + s: ['segment1', 'segment2', 'segment3'], + t: ['targeting1', 'targeting2', 'targeting3'] + }; before(() => { config.resetConfig(); @@ -15,7 +23,7 @@ describe('1plusXRtdProvider', () => { beforeEach(() => { fakeServer = sinon.createFakeServer(); - fakeServer.respondWith('GET', '*', [200, {}, '']); + fakeServer.respondWith('GET', '*', [200, fakeResponseHeaders, JSON.stringify(fakeResponse)]); fakeServer.respondImmediately = true; fakeServer.autoRespond = true; }) From 05b639affcc5cd84b129632023ed365658b6f685 Mon Sep 17 00:00:00 2001 From: Anass Seddiki Date: Mon, 13 Jun 2022 14:39:55 +0000 Subject: [PATCH 02/12] feel like doing a commit now --- modules/1plusXRtdProvider.js | 59 ++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/modules/1plusXRtdProvider.js b/modules/1plusXRtdProvider.js index b9acc5a6e52..dfe5c22ec13 100644 --- a/modules/1plusXRtdProvider.js +++ b/modules/1plusXRtdProvider.js @@ -1,6 +1,11 @@ -import { submodule } from '../src/hook.js' -import { ajax } from '../src/ajax.js' -import { logMessage, logError, deepAccess, isNumber } from '../src/utils.js'; +import { submodule } from '../src/hook.js'; +import { config } from '../src/config.js'; +import { ajax } from '../src/ajax.js'; +import { + logMessage, logError, + deepAccess, mergeDeep, + isNumber, isArray +} from '../src/utils.js'; // Constants const REAL_TIME_MODULE = 'realTimeData'; @@ -8,17 +13,25 @@ const MODULE_NAME = '1plusX'; const PAPI_VERSION = 'v1.0'; // Functions -const extractConfig = (config) => { +const extractConfig = (moduleConfig, reqBidsConfigObj) => { // CustomerId - const customerId = deepAccess(config, 'params.customerId'); + const customerId = deepAccess(moduleConfig, 'params.customerId'); if (!customerId) { throw new Error('REQUIRED CUSTOMER ID'); } // Timeout - const tempTimeout = deepAccess(config, 'params.timeout'); + const tempTimeout = deepAccess(moduleConfig, 'params.timeout'); const timeout = isNumber(tempTimeout) && tempTimeout > 300 ? tempTimeout : 1000; + // Bidders + const adUnitBidders = reqBidsConfigObj.adUnits + .flatMap(({ bids }) => bids.map(({ bidder }) => bidder)) + .filter((e, i, a) => a.indexOf(e) === i); + const biddersTemp = deepAccess(moduleConfig, 'params.bidders'); + const bidders = isArray(biddersTemp) ? + biddersTemp.filter(bidder => adUnitBidders.includes(bidder)) : + []; - return { customerId, timeout }; + return { customerId, timeout, bidders }; } const getPapiUrl = ({ customerId }) => { @@ -51,16 +64,42 @@ const getTargetingDataFromPapi = (papiUrl) => { }) } +const buildOrtb2Object = ({ segments, topics }) => { + const site = { data: segments }; + const user = { data: topics }; + return { site, user }; +} + +const setBidderConfig = (bidder, ortb2, bidderConfigs) => { + const bidderConfig = bidderConfigs[bidder] || {}; + const configForBidder = mergeDeep({}, bidderConfig, { ortb2 }); + + config.setBidderConfig({ + bidder: [bidder], + config: configForBidder + }); +}; + +const setTargetingDataToConfig = (papiResponse, { bidders }) => { + const bidderConfigs = config.getBidderConfig(); + const { s: segments, t: topics } = papiResponse; + const ortb2 = buildOrtb2Object({ segments, topics }); + + for (const bidder of bidders) { + setBidderConfig(bidder, ortb2, bidderConfigs); + } +} + // Functions exported in submodule object const init = (config, userConsent) => { // We prolly get the config again in getBidRequestData return true; } -const getBidRequestData = (reqBidsConfigObj, callback, config, userConsent) => { +const getBidRequestData = (reqBidsConfigObj, callback, moduleConfig, userConsent) => { try { // Get the required config - const { customerId } = extractConfig(config); + const { customerId, bidders } = extractConfig(moduleConfig, reqBidsConfigObj); // Get PAPI URL const papiUrl = getPapiUrl({ customerId }) // Call PAPI @@ -70,7 +109,7 @@ const getBidRequestData = (reqBidsConfigObj, callback, config, userConsent) => { // ---- extract relevant data // ---- set the data to the bid logMessage('REQUEST TO PAPI SUCCESS'); - const { s: segments, t: targeting } = response; + setTargetingDataToConfig(papiResponse, { bidders }); callback(); }) .catch((error) => { From fac84bc8146eba587b72d9495670755b057ab135 Mon Sep 17 00:00:00 2001 From: Anass Seddiki Date: Fri, 17 Jun 2022 09:24:13 +0000 Subject: [PATCH 03/12] WIP; waiting answer to question --- modules/1plusXRtdProvider.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/modules/1plusXRtdProvider.js b/modules/1plusXRtdProvider.js index dfe5c22ec13..32157f29663 100644 --- a/modules/1plusXRtdProvider.js +++ b/modules/1plusXRtdProvider.js @@ -65,8 +65,18 @@ const getTargetingDataFromPapi = (papiUrl) => { } const buildOrtb2Object = ({ segments, topics }) => { - const site = { data: segments }; - const user = { data: topics }; + const site = { + keywords: { + opeaud: segments, + opectx: topics + }, + }; + const user = { + keywords: { + opeaud: segments, + opectx: topics + }, + }; return { site, user }; } From 2a973cff3ab7bfeebd7f8cb98df642d629d9b920 Mon Sep 17 00:00:00 2001 From: Anass Seddiki Date: Tue, 21 Jun 2022 10:04:13 +0000 Subject: [PATCH 04/12] Add bidder in example --- integrationExamples/gpt/1plusXRtdProviderExample.html | 1 + 1 file changed, 1 insertion(+) diff --git a/integrationExamples/gpt/1plusXRtdProviderExample.html b/integrationExamples/gpt/1plusXRtdProviderExample.html index 4da659fb0c4..615e952e576 100644 --- a/integrationExamples/gpt/1plusXRtdProviderExample.html +++ b/integrationExamples/gpt/1plusXRtdProviderExample.html @@ -48,6 +48,7 @@ waitForIt: true, params: { customerId: 'acme', + bidders: ['appnexus'], timeout: 1000 } From 12418bb801c8b5862e1dadf61ee18e9ac12790a5 Mon Sep 17 00:00:00 2001 From: Anass Seddiki Date: Tue, 21 Jun 2022 10:04:27 +0000 Subject: [PATCH 05/12] test buildOrtb2Object --- modules/1plusXRtdProvider.js | 11 ++- test/spec/modules/1plusXRtdProvider_spec.js | 76 ++++++++++++++++++++- 2 files changed, 79 insertions(+), 8 deletions(-) diff --git a/modules/1plusXRtdProvider.js b/modules/1plusXRtdProvider.js index 32157f29663..4aa50c9fcd9 100644 --- a/modules/1plusXRtdProvider.js +++ b/modules/1plusXRtdProvider.js @@ -64,7 +64,7 @@ const getTargetingDataFromPapi = (papiUrl) => { }) } -const buildOrtb2Object = ({ segments, topics }) => { +export const buildOrtb2Object = ({ segments = [], topics = [] }) => { const site = { keywords: { opeaud: segments, @@ -80,7 +80,7 @@ const buildOrtb2Object = ({ segments, topics }) => { return { site, user }; } -const setBidderConfig = (bidder, ortb2, bidderConfigs) => { +export const setBidderConfig = (bidder, ortb2, bidderConfigs) => { const bidderConfig = bidderConfigs[bidder] || {}; const configForBidder = mergeDeep({}, bidderConfig, { ortb2 }); @@ -90,7 +90,7 @@ const setBidderConfig = (bidder, ortb2, bidderConfigs) => { }); }; -const setTargetingDataToConfig = (papiResponse, { bidders }) => { +export const setTargetingDataToConfig = (papiResponse, { bidders }) => { const bidderConfigs = config.getBidderConfig(); const { s: segments, t: topics } = papiResponse; const ortb2 = buildOrtb2Object({ segments, topics }); @@ -114,10 +114,7 @@ const getBidRequestData = (reqBidsConfigObj, callback, moduleConfig, userConsent const papiUrl = getPapiUrl({ customerId }) // Call PAPI getTargetingDataFromPapi(papiUrl) - .then((response) => { - // -- Then : - // ---- extract relevant data - // ---- set the data to the bid + .then((papiResponse) => { logMessage('REQUEST TO PAPI SUCCESS'); setTargetingDataToConfig(papiResponse, { bidders }); callback(); diff --git a/test/spec/modules/1plusXRtdProvider_spec.js b/test/spec/modules/1plusXRtdProvider_spec.js index e2ec48640f2..afde4b6863e 100644 --- a/test/spec/modules/1plusXRtdProvider_spec.js +++ b/test/spec/modules/1plusXRtdProvider_spec.js @@ -1,7 +1,12 @@ import { config } from 'src/config'; import { logMessage } from 'src/utils'; import { server } from 'test/mocks/xhr.js'; -import { onePlusXSubmodule } from 'modules/1plusXRtdProvider'; +import { + onePlusXSubmodule, + buildOrtb2Object, + setBidderConfig, + setTargetingDataToConfig +} from 'modules/1plusXRtdProvider'; describe('1plusXRtdProvider', () => { const reqBidsConfigObj = {}; @@ -55,4 +60,73 @@ describe('1plusXRtdProvider', () => { } }) }) + + describe('buildOrtb2Object', () => { + it('fills site.keywords & user.keywords in the ortb2 config', () => { + const rtdData = { segments: fakeResponse.s, topics: fakeResponse.t }; + const ortb2Object = buildOrtb2Object(rtdData); + + const expectedOutput = { + site: { + keywords: { + opeaud: rtdData.segments, + opectx: rtdData.topics, + } + }, + user: { + keywords: { + opeaud: rtdData.segments, + opectx: rtdData.topics, + } + } + } + expect([ortb2Object]).to.deep.include.members([expectedOutput]); + }); + + it('defaults to empty array if no segment is given', () => { + const rtdData = { topics: fakeResponse.t }; + const ortb2Object = buildOrtb2Object(rtdData); + + const expectedOutput = { + site: { + keywords: { + opeaud: [], + opectx: rtdData.topics + } + }, + user: { + keywords: { + opeaud: [], + opectx: rtdData.topics + } + } + } + + expect(ortb2Object).to.deep.include(expectedOutput); + }) + + it('defaults to empty array if no topic is given', () => { + const rtdData = { segments: fakeResponse.s }; + const ortb2Object = buildOrtb2Object(rtdData); + + const expectedOutput = { + site: { + keywords: { + opeaud: rtdData.segments, + opectx: [] + } + }, + user: { + keywords: { + opeaud: rtdData.segments, + opectx: [] + } + } + } + + expect(ortb2Object).to.deep.include(expectedOutput); + }) + }) + + }) From 1f9dbfb7fa9bb4318726611a386004fca0af03b5 Mon Sep 17 00:00:00 2001 From: Anass Seddiki Date: Tue, 21 Jun 2022 10:14:09 +0000 Subject: [PATCH 06/12] Enforce supported biders in conf --- modules/1plusXRtdProvider.js | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/modules/1plusXRtdProvider.js b/modules/1plusXRtdProvider.js index 4aa50c9fcd9..bd0068fd934 100644 --- a/modules/1plusXRtdProvider.js +++ b/modules/1plusXRtdProvider.js @@ -11,6 +11,7 @@ import { const REAL_TIME_MODULE = 'realTimeData'; const MODULE_NAME = '1plusX'; const PAPI_VERSION = 'v1.0'; +const SUPPORTED_BIDDERS = ['appnexus', 'rubicon'] // Functions const extractConfig = (moduleConfig, reqBidsConfigObj) => { @@ -22,14 +23,27 @@ const extractConfig = (moduleConfig, reqBidsConfigObj) => { // Timeout const tempTimeout = deepAccess(moduleConfig, 'params.timeout'); const timeout = isNumber(tempTimeout) && tempTimeout > 300 ? tempTimeout : 1000; + // Bidders + const biddersTemp = deepAccess(moduleConfig, 'params.bidders'); + if (!isArray(biddersTemp) || !biddersTemp.length) { + throw new Error('REQUIRED BIDDERS IN SUBMODULE CONFIG'); + } + const adUnitBidders = reqBidsConfigObj.adUnits .flatMap(({ bids }) => bids.map(({ bidder }) => bidder)) .filter((e, i, a) => a.indexOf(e) === i); - const biddersTemp = deepAccess(moduleConfig, 'params.bidders'); - const bidders = isArray(biddersTemp) ? - biddersTemp.filter(bidder => adUnitBidders.includes(bidder)) : - []; + if (!isArray(adUnitBidders) || !adUnitBidders.length) { + throw new Error('REQUIRED BIDDERS IN BID REQUEST CONFIG'); + } + + const bidders = biddersTemp.filter( + bidder => + SUPPORTED_BIDDERS.includes(bidder) && adUnitBidders.includes(bidder) + ); + if (!bidders.length) { + throw new Error('NO SUPPORTED BIDDER FOUND IN SUBMODULE/ BID REQUEST CONFIG'); + } return { customerId, timeout, bidders }; } From 6977698b3ae7216d3c0d8e20b585894bb699c3a7 Mon Sep 17 00:00:00 2001 From: Anass Seddiki Date: Tue, 21 Jun 2022 13:27:25 +0000 Subject: [PATCH 07/12] testing setBidderConfig --- modules/1plusXRtdProvider.js | 5 +- test/spec/modules/1plusXRtdProvider_spec.js | 58 +++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/modules/1plusXRtdProvider.js b/modules/1plusXRtdProvider.js index bd0068fd934..31221b396b2 100644 --- a/modules/1plusXRtdProvider.js +++ b/modules/1plusXRtdProvider.js @@ -95,11 +95,14 @@ export const buildOrtb2Object = ({ segments = [], topics = [] }) => { } export const setBidderConfig = (bidder, ortb2, bidderConfigs) => { + if (!SUPPORTED_BIDDERS.includes(bidder)) { + return; + } const bidderConfig = bidderConfigs[bidder] || {}; const configForBidder = mergeDeep({}, bidderConfig, { ortb2 }); config.setBidderConfig({ - bidder: [bidder], + bidders: [bidder], config: configForBidder }); }; diff --git a/test/spec/modules/1plusXRtdProvider_spec.js b/test/spec/modules/1plusXRtdProvider_spec.js index afde4b6863e..3252f648e7f 100644 --- a/test/spec/modules/1plusXRtdProvider_spec.js +++ b/test/spec/modules/1plusXRtdProvider_spec.js @@ -129,4 +129,62 @@ describe('1plusXRtdProvider', () => { }) + describe('setBidderConfig', () => { + const ortb2Object = { + site: { + keywords: { + opeaud: fakeResponse.s, + opectx: fakeResponse.t, + } + }, + user: { + keywords: { + opeaud: fakeResponse.s, + opectx: fakeResponse.t, + } + } + } + + const bidderConfigInitial = { + ortb2: { + user: { data: [] }, + site: { content: { data: [] } } + } + } + + it("doesn't write in config of unsupported bidder", () => { + const unsupportedBidder = Math.random().toString(36).replace(/[^a-z]+/g, '').substring(0, 5); + // Set initial config for this bidder + config.setBidderConfig({ + bidders: [unsupportedBidder], + config: bidderConfigInitial + }) + // Call my own setBidderConfig with targeting data + setBidderConfig(unsupportedBidder, ortb2Object, config.getBidderConfig()); + // Check that the config has not been changed for unsupported bidder + const newConfig = config.getBidderConfig()[unsupportedBidder]; + expect(newConfig.ortb2.user).to.not.have.any.keys('keywords') + expect(newConfig.ortb2.site).to.not.have.any.keys('keywords') + expect(newConfig).to.deep.include(bidderConfigInitial); + }) + + it('merges config for supported bidders', () => { + const bidder = 'appnexus'; + // Set initial config + config.setBidderConfig({ + bidders: [bidder], + config: bidderConfigInitial + }); + // Call submodule's setBidderConfig + setBidderConfig(bidder, ortb2Object, config.getBidderConfig()); + // Check that the targeting data has been set in the config + const newConfig = config.getBidderConfig()[bidder]; + expect(newConfig.ortb2.site).to.deep.include(ortb2Object.site); + expect(newConfig.ortb2.user).to.deep.include(ortb2Object.user); + // Check that existing config didn't get erased + expect(newConfig.ortb2.site).to.deep.include(bidderConfigInitial.ortb2.site); + expect(newConfig.ortb2.user).to.deep.include(bidderConfigInitial.ortb2.user); + }) + }) + }) From 4506d649c31d2c08649a9f5154445c0635a8bd44 Mon Sep 17 00:00:00 2001 From: Anass Seddiki Date: Tue, 21 Jun 2022 13:58:45 +0000 Subject: [PATCH 08/12] Basic JSdoc for functions so I can write my tests quicker --- modules/1plusXRtdProvider.js | 46 ++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/modules/1plusXRtdProvider.js b/modules/1plusXRtdProvider.js index 31221b396b2..b4a6c501d26 100644 --- a/modules/1plusXRtdProvider.js +++ b/modules/1plusXRtdProvider.js @@ -14,6 +14,12 @@ const PAPI_VERSION = 'v1.0'; const SUPPORTED_BIDDERS = ['appnexus', 'rubicon'] // Functions +/** + * Extracts the parameters for 1plusX RTD module from the config object passed at instanciation + * @param {Object} moduleConfig Config object passed to the module + * @param {Object} reqBidsConfigObj Config object for the bidders; each adapter has its own entry + * @returns + */ const extractConfig = (moduleConfig, reqBidsConfigObj) => { // CustomerId const customerId = deepAccess(moduleConfig, 'params.customerId'); @@ -48,6 +54,11 @@ const extractConfig = (moduleConfig, reqBidsConfigObj) => { return { customerId, timeout, bidders }; } +/** + * + * @param {*} param0 + * @returns + */ const getPapiUrl = ({ customerId }) => { logMessage('GET PAPI URL'); // https://[yourClientId].profiles.tagger.opecloud.com/[VERSION]/targeting?url= @@ -56,6 +67,11 @@ const getPapiUrl = ({ customerId }) => { return papiUrl; } +/** + * + * @param {string} papiUrl URL of profile API + * @returns + */ const getTargetingDataFromPapi = (papiUrl) => { return new Promise((resolve, reject) => { const requestOptions = { @@ -78,6 +94,11 @@ const getTargetingDataFromPapi = (papiUrl) => { }) } +/** + * + * @param {*} param0 + * @returns + */ export const buildOrtb2Object = ({ segments = [], topics = [] }) => { const site = { keywords: { @@ -94,6 +115,13 @@ export const buildOrtb2Object = ({ segments = [], topics = [] }) => { return { site, user }; } +/** + * Merges the targeting data with the existing config for bidder and updates + * @param {string} bidder Bidder for which to set config + * @param {Object} ortb2 + * @param {Object} bidderConfigs + * @returns + */ export const setBidderConfig = (bidder, ortb2, bidderConfigs) => { if (!SUPPORTED_BIDDERS.includes(bidder)) { return; @@ -107,6 +135,11 @@ export const setBidderConfig = (bidder, ortb2, bidderConfigs) => { }); }; +/** + * Updates bidder configs with the targeting data retreived from Profile API + * @param {*} papiResponse + * @param {*} param1 + */ export const setTargetingDataToConfig = (papiResponse, { bidders }) => { const bidderConfigs = config.getBidderConfig(); const { s: segments, t: topics } = papiResponse; @@ -118,11 +151,24 @@ export const setTargetingDataToConfig = (papiResponse, { bidders }) => { } // Functions exported in submodule object +/** + * Init + * @param {*} config + * @param {*} userConsent + * @returns + */ const init = (config, userConsent) => { // We prolly get the config again in getBidRequestData return true; } +/** + * + * @param {*} reqBidsConfigObj + * @param {*} callback + * @param {*} moduleConfig + * @param {*} userConsent + */ const getBidRequestData = (reqBidsConfigObj, callback, moduleConfig, userConsent) => { try { // Get the required config From 2b5ec926b041aaf8a8c719e2d3c55a0a6c788ad7 Mon Sep 17 00:00:00 2001 From: Anass Seddiki Date: Tue, 21 Jun 2022 15:46:09 +0000 Subject: [PATCH 09/12] Test setTargetingDataToConfig --- test/spec/modules/1plusXRtdProvider_spec.js | 93 +++++++++++++++++++-- 1 file changed, 86 insertions(+), 7 deletions(-) diff --git a/test/spec/modules/1plusXRtdProvider_spec.js b/test/spec/modules/1plusXRtdProvider_spec.js index 3252f648e7f..8da9076c67e 100644 --- a/test/spec/modules/1plusXRtdProvider_spec.js +++ b/test/spec/modules/1plusXRtdProvider_spec.js @@ -20,6 +20,13 @@ describe('1plusXRtdProvider', () => { t: ['targeting1', 'targeting2', 'targeting3'] }; + const bidderConfigInitial = { + ortb2: { + user: { data: [] }, + site: { content: { data: [] } } + } + } + before(() => { config.resetConfig(); }) @@ -145,13 +152,6 @@ describe('1plusXRtdProvider', () => { } } - const bidderConfigInitial = { - ortb2: { - user: { data: [] }, - site: { content: { data: [] } } - } - } - it("doesn't write in config of unsupported bidder", () => { const unsupportedBidder = Math.random().toString(36).replace(/[^a-z]+/g, '').substring(0, 5); // Set initial config for this bidder @@ -187,4 +187,83 @@ describe('1plusXRtdProvider', () => { }) }) + describe('setTargetingDataToConfig', () => { + const expectedOrtb2 = { + site: { + keywords: { + opeaud: fakeResponse.s, + opectx: fakeResponse.t, + } + }, + user: { + keywords: { + opeaud: fakeResponse.s, + opectx: fakeResponse.t, + } + } + } + + it("doesn't set config for unsupported bidders", () => { + const unsupportedBidder = Math.random().toString(36).replace(/[^a-z]+/g, '').substring(0, 5); + // setting initial config for this bidder + config.setBidderConfig({ + bidders: [unsupportedBidder], + config: bidderConfigInitial + }) + // call setTargetingDataToConfig + setTargetingDataToConfig(fakeResponse, { bidders: [unsupportedBidder] }); + // Check that the config has not been changed for unsupported bidder + const newConfig = config.getBidderConfig()[unsupportedBidder]; + expect(newConfig.ortb2.user).to.not.have.any.keys('keywords') + expect(newConfig.ortb2.site).to.not.have.any.keys('keywords') + expect(newConfig).to.deep.include(bidderConfigInitial); + }) + + it('sets the config for the selected bidders', () => { + const bidders = ['appnexus', 'rubicon']; + // setting initial config for those bidders + config.setBidderConfig({ + bidders, + config: bidderConfigInitial + }) + // call setTargetingDataToConfig + setTargetingDataToConfig(fakeResponse, { bidders }); + + // Check that the targeting data has been set in both configs + for (const bidder of bidders) { + const newConfig = config.getBidderConfig()[bidder]; + expect(newConfig.ortb2.site).to.deep.include(expectedOrtb2.site); + expect(newConfig.ortb2.user).to.deep.include(expectedOrtb2.user); + // Check that existing config didn't get erased + expect(newConfig.ortb2.site).to.deep.include(bidderConfigInitial.ortb2.site); + expect(newConfig.ortb2.user).to.deep.include(bidderConfigInitial.ortb2.user); + } + + }) + it('ignores unsupported bidders', () => { + const unsupportedBidder = Math.random().toString(36).replace(/[^a-z]+/g, '').substring(0, 5); + const bidders = ['appnexus', unsupportedBidder]; + // setting initial config for those bidders + config.setBidderConfig({ + bidders, + config: bidderConfigInitial + }) + // call setTargetingDataToConfig + setTargetingDataToConfig(fakeResponse, { bidders }); + + // Check that the targeting data has been set for supported bidder + const appnexusConfig = config.getBidderConfig()['appnexus']; + expect(appnexusConfig.ortb2.site).to.deep.include(expectedOrtb2.site); + expect(appnexusConfig.ortb2.user).to.deep.include(expectedOrtb2.user); + // Check that existing config didn't get erased + expect(appnexusConfig.ortb2.site).to.deep.include(bidderConfigInitial.ortb2.site); + expect(appnexusConfig.ortb2.user).to.deep.include(bidderConfigInitial.ortb2.user); + + // Check that config for unsupported bidder remained unchanged + const newConfig = config.getBidderConfig()[unsupportedBidder]; + expect(newConfig.ortb2.user).to.not.have.any.keys('keywords') + expect(newConfig.ortb2.site).to.not.have.any.keys('keywords') + expect(newConfig).to.deep.include(bidderConfigInitial); + }) + }) }) From 3798496cb92b32fba15c18c12a65a5fa5b962468 Mon Sep 17 00:00:00 2001 From: Anass Seddiki Date: Tue, 21 Jun 2022 17:02:45 +0000 Subject: [PATCH 10/12] Linting --- modules/1plusXRtdProvider.js | 50 ++++++++++----------- test/spec/modules/1plusXRtdProvider_spec.js | 20 ++++----- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/modules/1plusXRtdProvider.js b/modules/1plusXRtdProvider.js index b4a6c501d26..e21f2306cf6 100644 --- a/modules/1plusXRtdProvider.js +++ b/modules/1plusXRtdProvider.js @@ -18,7 +18,7 @@ const SUPPORTED_BIDDERS = ['appnexus', 'rubicon'] * Extracts the parameters for 1plusX RTD module from the config object passed at instanciation * @param {Object} moduleConfig Config object passed to the module * @param {Object} reqBidsConfigObj Config object for the bidders; each adapter has its own entry - * @returns + * @returns */ const extractConfig = (moduleConfig, reqBidsConfigObj) => { // CustomerId @@ -30,7 +30,7 @@ const extractConfig = (moduleConfig, reqBidsConfigObj) => { const tempTimeout = deepAccess(moduleConfig, 'params.timeout'); const timeout = isNumber(tempTimeout) && tempTimeout > 300 ? tempTimeout : 1000; - // Bidders + // Bidders const biddersTemp = deepAccess(moduleConfig, 'params.bidders'); if (!isArray(biddersTemp) || !biddersTemp.length) { throw new Error('REQUIRED BIDDERS IN SUBMODULE CONFIG'); @@ -55,9 +55,9 @@ const extractConfig = (moduleConfig, reqBidsConfigObj) => { } /** - * - * @param {*} param0 - * @returns + * + * @param {*} param0 + * @returns */ const getPapiUrl = ({ customerId }) => { logMessage('GET PAPI URL'); @@ -68,9 +68,9 @@ const getPapiUrl = ({ customerId }) => { } /** - * - * @param {string} papiUrl URL of profile API - * @returns + * + * @param {string} papiUrl URL of profile API + * @returns */ const getTargetingDataFromPapi = (papiUrl) => { return new Promise((resolve, reject) => { @@ -81,7 +81,7 @@ const getTargetingDataFromPapi = (papiUrl) => { } const callbacks = { success(responseText, response) { - logMessage("Say it has been successful"); + logMessage('Say it has been successful'); resolve(JSON.parse(response.response)); }, error(errorText, error) { @@ -95,9 +95,9 @@ const getTargetingDataFromPapi = (papiUrl) => { } /** - * - * @param {*} param0 - * @returns + * + * @param {*} param0 + * @returns */ export const buildOrtb2Object = ({ segments = [], topics = [] }) => { const site = { @@ -118,9 +118,9 @@ export const buildOrtb2Object = ({ segments = [], topics = [] }) => { /** * Merges the targeting data with the existing config for bidder and updates * @param {string} bidder Bidder for which to set config - * @param {Object} ortb2 - * @param {Object} bidderConfigs - * @returns + * @param {Object} ortb2 + * @param {Object} bidderConfigs + * @returns */ export const setBidderConfig = (bidder, ortb2, bidderConfigs) => { if (!SUPPORTED_BIDDERS.includes(bidder)) { @@ -137,8 +137,8 @@ export const setBidderConfig = (bidder, ortb2, bidderConfigs) => { /** * Updates bidder configs with the targeting data retreived from Profile API - * @param {*} papiResponse - * @param {*} param1 + * @param {*} papiResponse + * @param {*} param1 */ export const setTargetingDataToConfig = (papiResponse, { bidders }) => { const bidderConfigs = config.getBidderConfig(); @@ -153,9 +153,9 @@ export const setTargetingDataToConfig = (papiResponse, { bidders }) => { // Functions exported in submodule object /** * Init - * @param {*} config - * @param {*} userConsent - * @returns + * @param {*} config + * @param {*} userConsent + * @returns */ const init = (config, userConsent) => { // We prolly get the config again in getBidRequestData @@ -163,11 +163,11 @@ const init = (config, userConsent) => { } /** - * - * @param {*} reqBidsConfigObj - * @param {*} callback - * @param {*} moduleConfig - * @param {*} userConsent + * + * @param {*} reqBidsConfigObj + * @param {*} callback + * @param {*} moduleConfig + * @param {*} userConsent */ const getBidRequestData = (reqBidsConfigObj, callback, moduleConfig, userConsent) => { try { diff --git a/test/spec/modules/1plusXRtdProvider_spec.js b/test/spec/modules/1plusXRtdProvider_spec.js index 8da9076c67e..b70f071f4f4 100644 --- a/test/spec/modules/1plusXRtdProvider_spec.js +++ b/test/spec/modules/1plusXRtdProvider_spec.js @@ -135,7 +135,6 @@ describe('1plusXRtdProvider', () => { }) }) - describe('setBidderConfig', () => { const ortb2Object = { site: { @@ -154,12 +153,12 @@ describe('1plusXRtdProvider', () => { it("doesn't write in config of unsupported bidder", () => { const unsupportedBidder = Math.random().toString(36).replace(/[^a-z]+/g, '').substring(0, 5); - // Set initial config for this bidder + // Set initial config for this bidder config.setBidderConfig({ bidders: [unsupportedBidder], config: bidderConfigInitial }) - // Call my own setBidderConfig with targeting data + // Call my own setBidderConfig with targeting data setBidderConfig(unsupportedBidder, ortb2Object, config.getBidderConfig()); // Check that the config has not been changed for unsupported bidder const newConfig = config.getBidderConfig()[unsupportedBidder]; @@ -181,7 +180,7 @@ describe('1plusXRtdProvider', () => { const newConfig = config.getBidderConfig()[bidder]; expect(newConfig.ortb2.site).to.deep.include(ortb2Object.site); expect(newConfig.ortb2.user).to.deep.include(ortb2Object.user); - // Check that existing config didn't get erased + // Check that existing config didn't get erased expect(newConfig.ortb2.site).to.deep.include(bidderConfigInitial.ortb2.site); expect(newConfig.ortb2.user).to.deep.include(bidderConfigInitial.ortb2.user); }) @@ -205,7 +204,7 @@ describe('1plusXRtdProvider', () => { it("doesn't set config for unsupported bidders", () => { const unsupportedBidder = Math.random().toString(36).replace(/[^a-z]+/g, '').substring(0, 5); - // setting initial config for this bidder + // setting initial config for this bidder config.setBidderConfig({ bidders: [unsupportedBidder], config: bidderConfigInitial @@ -221,7 +220,7 @@ describe('1plusXRtdProvider', () => { it('sets the config for the selected bidders', () => { const bidders = ['appnexus', 'rubicon']; - // setting initial config for those bidders + // setting initial config for those bidders config.setBidderConfig({ bidders, config: bidderConfigInitial @@ -234,16 +233,15 @@ describe('1plusXRtdProvider', () => { const newConfig = config.getBidderConfig()[bidder]; expect(newConfig.ortb2.site).to.deep.include(expectedOrtb2.site); expect(newConfig.ortb2.user).to.deep.include(expectedOrtb2.user); - // Check that existing config didn't get erased + // Check that existing config didn't get erased expect(newConfig.ortb2.site).to.deep.include(bidderConfigInitial.ortb2.site); expect(newConfig.ortb2.user).to.deep.include(bidderConfigInitial.ortb2.user); } - }) it('ignores unsupported bidders', () => { const unsupportedBidder = Math.random().toString(36).replace(/[^a-z]+/g, '').substring(0, 5); const bidders = ['appnexus', unsupportedBidder]; - // setting initial config for those bidders + // setting initial config for those bidders config.setBidderConfig({ bidders, config: bidderConfigInitial @@ -255,11 +253,11 @@ describe('1plusXRtdProvider', () => { const appnexusConfig = config.getBidderConfig()['appnexus']; expect(appnexusConfig.ortb2.site).to.deep.include(expectedOrtb2.site); expect(appnexusConfig.ortb2.user).to.deep.include(expectedOrtb2.user); - // Check that existing config didn't get erased + // Check that existing config didn't get erased expect(appnexusConfig.ortb2.site).to.deep.include(bidderConfigInitial.ortb2.site); expect(appnexusConfig.ortb2.user).to.deep.include(bidderConfigInitial.ortb2.user); - // Check that config for unsupported bidder remained unchanged + // Check that config for unsupported bidder remained unchanged const newConfig = config.getBidderConfig()[unsupportedBidder]; expect(newConfig.ortb2.user).to.not.have.any.keys('keywords') expect(newConfig.ortb2.site).to.not.have.any.keys('keywords') From c3e4adcdf13831d18394a52102a81e8eff617e4e Mon Sep 17 00:00:00 2001 From: Anass Seddiki Date: Mon, 27 Jun 2022 15:09:43 +0000 Subject: [PATCH 11/12] Change where we put the data in ortb2 object --- modules/1plusXRtdProvider.js | 60 +++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/modules/1plusXRtdProvider.js b/modules/1plusXRtdProvider.js index e21f2306cf6..81782756719 100644 --- a/modules/1plusXRtdProvider.js +++ b/modules/1plusXRtdProvider.js @@ -4,7 +4,7 @@ import { ajax } from '../src/ajax.js'; import { logMessage, logError, deepAccess, mergeDeep, - isNumber, isArray + isNumber, isArray, deepSetValue } from '../src/utils.js'; // Constants @@ -55,7 +55,7 @@ const extractConfig = (moduleConfig, reqBidsConfigObj) => { } /** - * + * Gets the URL of Profile Api from which targeting data will be fetched * @param {*} param0 * @returns */ @@ -68,7 +68,7 @@ const getPapiUrl = ({ customerId }) => { } /** - * + * Fetches targeting data. It contains the audience segments & the contextual topics * @param {string} papiUrl URL of profile API * @returns */ @@ -95,24 +95,19 @@ const getTargetingDataFromPapi = (papiUrl) => { } /** - * + * Prepares the update for the ORTB2 object * @param {*} param0 * @returns */ -export const buildOrtb2Object = ({ segments = [], topics = [] }) => { - const site = { - keywords: { - opeaud: segments, - opectx: topics - }, +export const buildOrtb2Updates = ({ segments = [], topics = [] }) => { + const userData = { + name: '1plusX.com', + segment: segments.map((segmentId) => ({ id: segmentId })) }; - const user = { - keywords: { - opeaud: segments, - opectx: topics - }, + const site = { + keywords: topics.join(',') }; - return { site, user }; + return { userData, site }; } /** @@ -122,17 +117,26 @@ export const buildOrtb2Object = ({ segments = [], topics = [] }) => { * @param {Object} bidderConfigs * @returns */ -export const setBidderConfig = (bidder, ortb2, bidderConfigs) => { +export const updateBidderConfig = (bidder, ortb2Updates, bidderConfigs) => { if (!SUPPORTED_BIDDERS.includes(bidder)) { return; } - const bidderConfig = bidderConfigs[bidder] || {}; - const configForBidder = mergeDeep({}, bidderConfig, { ortb2 }); + const { site, userData } = ortb2Updates; + const bidderConfigCopy = mergeDeep({}, bidderConfigs[bidder]); - config.setBidderConfig({ - bidders: [bidder], - config: configForBidder - }); + const currentSite = deepAccess(bidderConfigCopy, 'ortb2.site') + const updatedSite = mergeDeep(currentSite, site); + + const currentUserData = deepAccess(bidderConfigCopy, 'ortb2.user.data'); + const updatedUserData = [ + ...currentUserData.filter(({ name }) => name != userData.name), + userData + ]; + + deepSetValue(bidderConfigCopy, 'ortb2.site', updatedSite); + deepSetValue(bidderConfigCopy, 'ortb2.user.data', updatedUserData); + + return bidderConfigCopy }; /** @@ -143,10 +147,16 @@ export const setBidderConfig = (bidder, ortb2, bidderConfigs) => { export const setTargetingDataToConfig = (papiResponse, { bidders }) => { const bidderConfigs = config.getBidderConfig(); const { s: segments, t: topics } = papiResponse; - const ortb2 = buildOrtb2Object({ segments, topics }); + const ortb2Updates = buildOrtb2Updates({ segments, topics }); for (const bidder of bidders) { - setBidderConfig(bidder, ortb2, bidderConfigs); + const updatedBidderConfig = updateBidderConfig(bidder, ortb2Updates, bidderConfigs); + if (updatesBidderConfig) { + config.setBidderConfig({ + bidders: [bidder], + config: updatedBidderConfig + }); + } } } From 375ad613147de3cbb4327e92a11f88ba68b98f81 Mon Sep 17 00:00:00 2001 From: Anass Seddiki Date: Mon, 27 Jun 2022 15:57:26 +0000 Subject: [PATCH 12/12] Updated tests --- modules/1plusXRtdProvider.js | 6 +- test/spec/modules/1plusXRtdProvider_spec.js | 191 ++++++++++++-------- 2 files changed, 120 insertions(+), 77 deletions(-) diff --git a/modules/1plusXRtdProvider.js b/modules/1plusXRtdProvider.js index 81782756719..40bbf1d2e5a 100644 --- a/modules/1plusXRtdProvider.js +++ b/modules/1plusXRtdProvider.js @@ -119,7 +119,7 @@ export const buildOrtb2Updates = ({ segments = [], topics = [] }) => { */ export const updateBidderConfig = (bidder, ortb2Updates, bidderConfigs) => { if (!SUPPORTED_BIDDERS.includes(bidder)) { - return; + return null; } const { site, userData } = ortb2Updates; const bidderConfigCopy = mergeDeep({}, bidderConfigs[bidder]); @@ -127,7 +127,7 @@ export const updateBidderConfig = (bidder, ortb2Updates, bidderConfigs) => { const currentSite = deepAccess(bidderConfigCopy, 'ortb2.site') const updatedSite = mergeDeep(currentSite, site); - const currentUserData = deepAccess(bidderConfigCopy, 'ortb2.user.data'); + const currentUserData = deepAccess(bidderConfigCopy, 'ortb2.user.data') || []; const updatedUserData = [ ...currentUserData.filter(({ name }) => name != userData.name), userData @@ -151,7 +151,7 @@ export const setTargetingDataToConfig = (papiResponse, { bidders }) => { for (const bidder of bidders) { const updatedBidderConfig = updateBidderConfig(bidder, ortb2Updates, bidderConfigs); - if (updatesBidderConfig) { + if (updatedBidderConfig) { config.setBidderConfig({ bidders: [bidder], config: updatedBidderConfig diff --git a/test/spec/modules/1plusXRtdProvider_spec.js b/test/spec/modules/1plusXRtdProvider_spec.js index b70f071f4f4..7ae186dee3e 100644 --- a/test/spec/modules/1plusXRtdProvider_spec.js +++ b/test/spec/modules/1plusXRtdProvider_spec.js @@ -3,8 +3,8 @@ import { logMessage } from 'src/utils'; import { server } from 'test/mocks/xhr.js'; import { onePlusXSubmodule, - buildOrtb2Object, - setBidderConfig, + buildOrtb2Updates, + updateBidderConfig, setTargetingDataToConfig } from 'modules/1plusXRtdProvider'; @@ -22,7 +22,23 @@ describe('1plusXRtdProvider', () => { const bidderConfigInitial = { ortb2: { - user: { data: [] }, + user: { keywords: '' }, + site: { content: { data: [] } } + } + } + const bidderConfigInitialWith1plusXEntry = { + ortb2: { + user: { + data: [{ name: '1plusX.com', segment: [{ id: 'initial' }] }] + }, + site: { content: { data: [] } } + } + } + const bidderConfigInitialWithUserData = { + ortb2: { + user: { + data: [{ name: 'hello.world', segment: [{ id: 'initial' }] }] + }, site: { content: { data: [] } } } } @@ -68,89 +84,68 @@ describe('1plusXRtdProvider', () => { }) }) - describe('buildOrtb2Object', () => { - it('fills site.keywords & user.keywords in the ortb2 config', () => { + describe('buildOrtb2Updates', () => { + it('fills site.keywords & user.data in the ortb2 config', () => { const rtdData = { segments: fakeResponse.s, topics: fakeResponse.t }; - const ortb2Object = buildOrtb2Object(rtdData); + const ortb2Updates = buildOrtb2Updates(rtdData); const expectedOutput = { site: { - keywords: { - opeaud: rtdData.segments, - opectx: rtdData.topics, - } + keywords: rtdData.topics.join(','), }, - user: { - keywords: { - opeaud: rtdData.segments, - opectx: rtdData.topics, - } + userData: { + name: '1plusX.com', + segment: rtdData.segments.map((segmentId) => ({ id: segmentId })) } } - expect([ortb2Object]).to.deep.include.members([expectedOutput]); + expect([ortb2Updates]).to.deep.include.members([expectedOutput]); }); it('defaults to empty array if no segment is given', () => { const rtdData = { topics: fakeResponse.t }; - const ortb2Object = buildOrtb2Object(rtdData); + const ortb2Updates = buildOrtb2Updates(rtdData); const expectedOutput = { site: { - keywords: { - opeaud: [], - opectx: rtdData.topics - } + keywords: rtdData.topics.join(','), }, - user: { - keywords: { - opeaud: [], - opectx: rtdData.topics - } + userData: { + name: '1plusX.com', + segment: [] } } - - expect(ortb2Object).to.deep.include(expectedOutput); + expect(ortb2Updates).to.deep.include(expectedOutput); }) - it('defaults to empty array if no topic is given', () => { + it('defaults to empty string if no topic is given', () => { const rtdData = { segments: fakeResponse.s }; - const ortb2Object = buildOrtb2Object(rtdData); + const ortb2Updates = buildOrtb2Updates(rtdData); const expectedOutput = { site: { - keywords: { - opeaud: rtdData.segments, - opectx: [] - } + keywords: '', }, - user: { - keywords: { - opeaud: rtdData.segments, - opectx: [] - } + userData: { + name: '1plusX.com', + segment: rtdData.segments.map((segmentId) => ({ id: segmentId })) } } - - expect(ortb2Object).to.deep.include(expectedOutput); + expect(ortb2Updates).to.deep.include(expectedOutput); }) }) - describe('setBidderConfig', () => { - const ortb2Object = { + describe('updateBidderConfig', () => { + const ortb2Updates = { site: { - keywords: { - opeaud: fakeResponse.s, - opectx: fakeResponse.t, - } + keywords: fakeResponse.t.join(','), }, - user: { - keywords: { - opeaud: fakeResponse.s, - opectx: fakeResponse.t, - } + userData: { + name: '1plusX.com', + segment: fakeResponse.s.map((segmentId) => ({ id: segmentId })) } } + it("doesn't write in config of unsupported bidder", () => { const unsupportedBidder = Math.random().toString(36).replace(/[^a-z]+/g, '').substring(0, 5); // Set initial config for this bidder @@ -159,15 +154,12 @@ describe('1plusXRtdProvider', () => { config: bidderConfigInitial }) // Call my own setBidderConfig with targeting data - setBidderConfig(unsupportedBidder, ortb2Object, config.getBidderConfig()); + const newBidderConfig = updateBidderConfig(unsupportedBidder, ortb2Updates, config.getBidderConfig()); // Check that the config has not been changed for unsupported bidder - const newConfig = config.getBidderConfig()[unsupportedBidder]; - expect(newConfig.ortb2.user).to.not.have.any.keys('keywords') - expect(newConfig.ortb2.site).to.not.have.any.keys('keywords') - expect(newConfig).to.deep.include(bidderConfigInitial); + expect(newBidderConfig).to.be.null; }) - it('merges config for supported bidders', () => { + it('merges config for supported bidders (appnexus)', () => { const bidder = 'appnexus'; // Set initial config config.setBidderConfig({ @@ -175,30 +167,81 @@ describe('1plusXRtdProvider', () => { config: bidderConfigInitial }); // Call submodule's setBidderConfig - setBidderConfig(bidder, ortb2Object, config.getBidderConfig()); + const newBidderConfig = updateBidderConfig(bidder, ortb2Updates, config.getBidderConfig()); + // Check that the targeting data has been set in the config - const newConfig = config.getBidderConfig()[bidder]; - expect(newConfig.ortb2.site).to.deep.include(ortb2Object.site); - expect(newConfig.ortb2.user).to.deep.include(ortb2Object.user); + expect(newBidderConfig).not.to.be.null; + expect(newBidderConfig.ortb2.site).to.deep.include(ortb2Updates.site); + expect(newBidderConfig.ortb2.user.data).to.deep.include(ortb2Updates.userData); // Check that existing config didn't get erased - expect(newConfig.ortb2.site).to.deep.include(bidderConfigInitial.ortb2.site); - expect(newConfig.ortb2.user).to.deep.include(bidderConfigInitial.ortb2.user); + expect(newBidderConfig.ortb2.site).to.deep.include(bidderConfigInitial.ortb2.site); + expect(newBidderConfig.ortb2.user).to.deep.include(bidderConfigInitial.ortb2.user); }) + + it('merges config for supported bidders (rubicon)', () => { + const bidder = 'rubicon'; + // Set initial config + config.setBidderConfig({ + bidders: [bidder], + config: bidderConfigInitial + }); + // Call submodule's setBidderConfig + const newBidderConfig = updateBidderConfig(bidder, ortb2Updates, config.getBidderConfig()); + // Check that the targeting data has been set in the config + expect(newBidderConfig).not.to.be.null; + expect(newBidderConfig.ortb2.site).to.deep.include(ortb2Updates.site); + expect(newBidderConfig.ortb2.user.data).to.deep.include(ortb2Updates.userData); + // Check that existing config didn't get erased + expect(newBidderConfig.ortb2.site).to.deep.include(bidderConfigInitial.ortb2.site); + expect(newBidderConfig.ortb2.user).to.deep.include(bidderConfigInitial.ortb2.user); + }) + + it('overwrites an existing 1plus.com entry in ortb2.user.data', () => { + const bidder = 'appnexus'; + // Set initial config + config.setBidderConfig({ + bidders: [bidder], + config: bidderConfigInitialWith1plusXEntry + }); + // Save previous user.data entry + const previousUserData = bidderConfigInitialWithUserData.ortb2.user.data[0] + // Call submodule's setBidderConfig + const newBidderConfig = updateBidderConfig(bidder, ortb2Updates, config.getBidderConfig()); + // Check that the targeting data has been set in the config + expect(newBidderConfig).not.to.be.null; + expect(newBidderConfig.ortb2.user.data).to.deep.include(ortb2Updates.userData); + expect(newBidderConfig.ortb2.user.data).not.to.include(previousUserData); + }) + + it("doesn't overwrite entries in ortb2.user.data that aren't 1plusx.com", () => { + const bidder = 'appnexus'; + // Set initial config + config.setBidderConfig({ + bidders: [bidder], + config: bidderConfigInitialWithUserData + }); + // Save previous user.data entry + const previousUserData = bidderConfigInitialWithUserData.ortb2.user.data[0] + // Call submodule's setBidderConfig + const newBidderConfig = updateBidderConfig(bidder, ortb2Updates, config.getBidderConfig()); + // Check that the targeting data has been set in the config + expect(newBidderConfig).not.to.be.null; + expect(newBidderConfig.ortb2.user.data).to.deep.include(ortb2Updates.userData); + expect(newBidderConfig.ortb2.user.data).to.deep.include(previousUserData); + }) + }) describe('setTargetingDataToConfig', () => { const expectedOrtb2 = { site: { - keywords: { - opeaud: fakeResponse.s, - opectx: fakeResponse.t, - } + keywords: fakeResponse.t.join(',') }, user: { - keywords: { - opeaud: fakeResponse.s, - opectx: fakeResponse.t, - } + data: [{ + name: '1plusX.com', + segment: fakeResponse.s.map((segmentId) => ({ id: segmentId })) + }] } } @@ -213,7 +256,7 @@ describe('1plusXRtdProvider', () => { setTargetingDataToConfig(fakeResponse, { bidders: [unsupportedBidder] }); // Check that the config has not been changed for unsupported bidder const newConfig = config.getBidderConfig()[unsupportedBidder]; - expect(newConfig.ortb2.user).to.not.have.any.keys('keywords') + expect(newConfig.ortb2.user.data).to.be.undefined; expect(newConfig.ortb2.site).to.not.have.any.keys('keywords') expect(newConfig).to.deep.include(bidderConfigInitial); }) @@ -259,7 +302,7 @@ describe('1plusXRtdProvider', () => { // Check that config for unsupported bidder remained unchanged const newConfig = config.getBidderConfig()[unsupportedBidder]; - expect(newConfig.ortb2.user).to.not.have.any.keys('keywords') + expect(newConfig.ortb2.user.data).to.be.undefined; expect(newConfig.ortb2.site).to.not.have.any.keys('keywords') expect(newConfig).to.deep.include(bidderConfigInitial); })