From 6daebf348d67d1c7526cb463d0c411aedf036082 Mon Sep 17 00:00:00 2001 From: nouchy <33549554+nouchy@users.noreply.github.com> Date: Thu, 18 May 2023 17:20:29 +0200 Subject: [PATCH] bidder specific handling removal move bidder specific handling to ortb2 --- .gitignore | 2 + modules/sirdataRtdProvider.js | 107 ++++++---------- package-lock.json | 2 +- test/spec/modules/sirdataRtdProvider_spec.js | 127 ++++++++++++++++--- 4 files changed, 151 insertions(+), 87 deletions(-) diff --git a/.gitignore b/.gitignore index e5f000dd4d5..861bdb0f1e6 100644 --- a/.gitignore +++ b/.gitignore @@ -80,3 +80,5 @@ typings/ # MacOS system files .DS_Store +package-lock.json +package-lock.json diff --git a/modules/sirdataRtdProvider.js b/modules/sirdataRtdProvider.js index 40ee3d8b973..df2359a13b3 100644 --- a/modules/sirdataRtdProvider.js +++ b/modules/sirdataRtdProvider.js @@ -198,7 +198,7 @@ export function applyBidderOrtb2Sda(ortb2Fragments, bidder, type, segments, segt export function setBidderOrtb2(bidderOrtb2Fragments, bidder, path, segments) { try { - if (isEmpty(segments)) { return; } + if (isEmpty(segments)) { return false; } let ortb2Conf = {}; deepSetValue(ortb2Conf, path, segments || {}); mergeDeep(bidderOrtb2Fragments, {[bidder]: ortb2Conf}); @@ -254,7 +254,7 @@ export function getSegAndCatsArray(data, minScore, pid) { return sirdataData; } -export function applySdaGetSpecificData(data, sirdataList, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit) { +export function applySdaGetSpecificData(data, sirdataData, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit) { // only share SDA data if whitelisted if (!biddersParamsExist || indexFound) { // SDA Publisher @@ -269,7 +269,8 @@ export function applySdaGetSpecificData(data, sirdataList, biddersParamsExist, m if (data.shared_taxonomy && data.shared_taxonomy[curationId]) { // Get Bidder Specific Data let curationData = getSegAndCatsArray(data.shared_taxonomy[curationId], minScore, null); - sirdataList = sirdataList.concat(curationData.segments).concat(curationData.categories); + sirdataData.segments = sirdataData.segments.concat(curationData.segments); + sirdataData.categories = sirdataData.categories.concat(curationData.categories); // SDA Partners let curationDataForSDA = getSegAndCatsArray(data.shared_taxonomy[curationId], minScore, curationId); @@ -278,19 +279,22 @@ export function applySdaGetSpecificData(data, sirdataList, biddersParamsExist, m } // Apply custom function or return Bidder Specific Data if publisher is ok - if (sirdataList && sirdataList.length > 0 && (!biddersParamsExist || indexFound)) { + if (!biddersParamsExist || indexFound) { if (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('customFunction')) { - return loadCustomFunction(moduleConfig.params.bidders[bidderIndex].customFunction, adUnit, sirdataList, data, bid); + return loadCustomFunction(moduleConfig.params.bidders[bidderIndex].customFunction, adUnit, sirdataData, data, bid); } else { - return sirdataList; + return sirdataData; } } } -export function applySdaAndDefaultSpecificData(data, sirdataList, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit) { - let specificData = applySdaGetSpecificData(data, sirdataList, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit); - if (specificData && specificData.length > 0) { - setBidderOrtb2(reqBids.ortb2Fragments?.bidder, bid.bidder, 'user.ext.data', {sd_rtd: specificData}); +export function applySdaAndDefaultSpecificData(data, sirdataData, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit) { + sirdataData = applySdaGetSpecificData(data, sirdataData, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit); + if (sirdataData.segments && sirdataData.segments.length > 0) { + setBidderOrtb2(reqBids.ortb2Fragments?.bidder, bid.bidder, 'user.ext.data', {sd_rtd: sirdataData.segments}); + } + if (sirdataData.categories && sirdataData.categories.length > 0) { + setBidderOrtb2(reqBids.ortb2Fragments?.bidder, bid.bidder, 'site.ext.data', {sd_rtd: sirdataData.categories}); } } @@ -301,8 +305,6 @@ export function addSegmentData(reqBids, data, moduleConfig, onDone) { const globalMinScore = moduleConfig.params.hasOwnProperty('contextualMinRelevancyScore') ? moduleConfig.params.contextualMinRelevancyScore : 30; var sirdataData = getSegAndCatsArray(data, globalMinScore, null); - const sirdataList = sirdataData.segments.concat(sirdataData.categories); - const biddersParamsExist = (!!(moduleConfig.params && moduleConfig.params.bidders)); // Global ortb2 SDA @@ -320,15 +322,17 @@ export function addSegmentData(reqBids, data, moduleConfig, onDone) { if (typeof window.googletag !== 'undefined' && (moduleConfig.params.setGptKeyValues || !moduleConfig.params.hasOwnProperty('setGptKeyValues'))) { try { let gptCurationId = (moduleConfig.params.gptCurationId ? moduleConfig.params.gptCurationId : (partnerIds['sdRtdForGpt'] ? partnerIds['sdRtdForGpt'] : null)); - let sirdataMergedList = sirdataList; + let sirdataMergedList = sirdataData.segments.concat(sirdataData.categories); if (gptCurationId && data.shared_taxonomy && data.shared_taxonomy[gptCurationId]) { let gamCurationData = getSegAndCatsArray(data.shared_taxonomy[gptCurationId], globalMinScore, null); sirdataMergedList = sirdataMergedList.concat(gamCurationData.segments).concat(gamCurationData.categories); } - window.googletag.pubads().getSlots().forEach(function (n) { - if (typeof n.setTargeting !== 'undefined' && sirdataMergedList && sirdataMergedList.length > 0) { - n.setTargeting('sd_rtd', sirdataMergedList); - } + window.googletag.cmd.push(function() { + window.googletag.pubads().getSlots().forEach(function (n) { + if (typeof n.setTargeting !== 'undefined' && sirdataMergedList && sirdataMergedList.length > 0) { + n.setTargeting('sd_rtd', sirdataMergedList); + } + }); }); } catch (e) { logError(e); @@ -340,10 +344,6 @@ export function addSegmentData(reqBids, data, moduleConfig, onDone) { var indexFound = false; adUnits.forEach(adUnit => { - if (!biddersParamsExist && !deepAccess(adUnit, 'ortb2Imp.ext.data.sd_rtd')) { - deepSetValue(adUnit, 'ortb2Imp.ext.data.sd_rtd', sirdataList); - } - adUnit.hasOwnProperty('bids') && adUnit.bids.forEach(bid => { bidderIndex = (moduleConfig.params.hasOwnProperty('bidders') ? findIndex(moduleConfig.params.bidders, function (i) { return i.bidder === bid.bidder; @@ -351,7 +351,6 @@ export function addSegmentData(reqBids, data, moduleConfig, onDone) { indexFound = (!!(typeof bidderIndex == 'number' && bidderIndex >= 0)); try { let minScore = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('contextualMinRelevancyScore') ? moduleConfig.params.bidders[bidderIndex].contextualMinRelevancyScore : globalMinScore); - let specificData = null; switch (bid.bidder) { case 'appnexus': @@ -370,57 +369,24 @@ export function addSegmentData(reqBids, data, moduleConfig, onDone) { case 'msq_classic': case 'msq_max': case '366_apx': - specificData = applySdaGetSpecificData(data, sirdataList, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit); - if (specificData && specificData.length > 0) { - deepSetValue(bid, 'params.keywords.sd_rtd', specificData); + sirdataData = applySdaGetSpecificData(data, sirdataData, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit); + if (sirdataData.segments && sirdataData.segments.length > 0) { + setBidderOrtb2(reqBids.ortb2Fragments?.bidder, bid.bidder, 'user.keywords', 'sd_rtd=' + sirdataData.segments.join(',sd_rtd=')); } - break; - - case 'smartadserver': - case 'smart': - specificData = applySdaGetSpecificData(data, sirdataList, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit); - if (specificData && specificData.length > 0) { - var target = []; - if (bid.hasOwnProperty('params') && bid.params.hasOwnProperty('target')) { - target.push(bid.params.target); - } - specificData.forEach(function (entry) { - if (target.indexOf('sd_rtd=' + entry) === -1) { - target.push('sd_rtd=' + entry); - } - }); - deepSetValue(bid, 'params.target', target.join(';')); - } - break; - - case 'ix': - specificData = applySdaGetSpecificData(data, sirdataList, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit); - let ixConfig = config.getConfig('ix.firstPartyData.sd_rtd'); - if (!ixConfig && specificData && specificData.length > 0) { - let cappIxCategories = []; - let ixLength = 0; - let ixLimit = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('sizeLimit') ? moduleConfig.params.bidders[bidderIndex].sizeLimit : 1000); - // Push ids For publisher use and for curation if exists but limit size because the bidder uses GET parameters - specificData.forEach(function (entry) { - if (ixLength < ixLimit) { - cappIxCategories.push(entry); - ixLength += entry.toString().length; - } - }); - config.setConfig({ix: {firstPartyData: {sd_rtd: cappIxCategories}}}); + if (sirdataData.categories && sirdataData.categories.length > 0) { + setBidderOrtb2(reqBids.ortb2Fragments?.bidder, bid.bidder, 'site.content.keywords', 'sd_rtd=' + sirdataData.categories.join(',sd_rtd=')); } break; case 'proxistore': - specificData = applySdaGetSpecificData(data, sirdataList, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit); - if (specificData && specificData.length > 0) { - let psCurationId = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('curationId') ? moduleConfig.params.bidders[bidderIndex].curationId : (partnerIds[bid.bidder] ? partnerIds[bid.bidder] : null)); - if (!data.shared_taxonomy || !data.shared_taxonomy[psCurationId]) { - data.shared_taxonomy[psCurationId] = {segments: [], contextual_categories: {}, segtaxid: null, cattaxid: null}; - } - let psCurationData = getSegAndCatsArray(data.shared_taxonomy[psCurationId], minScore, null); + sirdataData = applySdaGetSpecificData(data, sirdataData, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit); + let psCurationId = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('curationId') ? moduleConfig.params.bidders[bidderIndex].curationId : (partnerIds[bid.bidder] ? partnerIds[bid.bidder] : null)); + if (!data.shared_taxonomy || !data.shared_taxonomy[psCurationId]) { + data.shared_taxonomy[psCurationId] = {segments: [], contextual_categories: {}, segtaxid: null, cattaxid: null}; + } + if ((sirdataData.segments && sirdataData.segments.length > 0) || (sirdataData.categories && sirdataData.categories.length > 0)) { setBidderOrtb2(reqBids.ortb2Fragments?.bidder, bid.bidder, 'user.ext.data', { - segments: sirdataData.segments.concat(psCurationData.segments), + segments: sirdataData.segments, contextual_categories: {...data.contextual_categories, ...data.shared_taxonomy[psCurationId].contextual_categories} }); } @@ -445,12 +411,15 @@ export function addSegmentData(reqBids, data, moduleConfig, onDone) { case 'sublime': case 'rtbhouse': case 'mediasquare': - applySdaAndDefaultSpecificData(data, sirdataList, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit); + case 'smartadserver': + case 'smart': + case 'ix': + applySdaAndDefaultSpecificData(data, sirdataData, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit); break; default: if (!biddersParamsExist || (indexFound && (!moduleConfig.params.bidders[bidderIndex].hasOwnProperty('adUnitCodes') || moduleConfig.params.bidders[bidderIndex].adUnitCodes.indexOf(adUnit.code) !== -1))) { - applySdaAndDefaultSpecificData(data, sirdataList, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit); + applySdaAndDefaultSpecificData(data, sirdataData, biddersParamsExist, minScore, reqBids, bid, moduleConfig, indexFound, bidderIndex, adUnit); } } } catch (e) { diff --git a/package-lock.json b/package-lock.json index a6e6020a443..57c94df0732 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "prebid.js", - "version": "7.48.0-pre", + "version": "7.50.0-pre", "license": "Apache-2.0", "dependencies": { "@babel/core": "^7.16.7", diff --git a/test/spec/modules/sirdataRtdProvider_spec.js b/test/spec/modules/sirdataRtdProvider_spec.js index eccc4777906..f4244fc8414 100644 --- a/test/spec/modules/sirdataRtdProvider_spec.js +++ b/test/spec/modules/sirdataRtdProvider_spec.js @@ -1,26 +1,31 @@ -import {addSegmentData, getSegmentsAndCategories, sirdataSubmodule} from 'modules/sirdataRtdProvider.js'; +import {addSegmentData, getSegmentsAndCategories, sirdataSubmodule, setBidderOrtb2} from 'modules/sirdataRtdProvider.js'; import {server} from 'test/mocks/xhr.js'; const responseHeader = {'Content-Type': 'application/json'}; describe('sirdataRtdProvider', function () { describe('sirdataSubmodule', function () { + it('exists', function () { + expect(sirdataSubmodule.init).to.be.a('function'); + }); it('successfully instantiates', function () { expect(sirdataSubmodule.init()).to.equal(true); }); + it('has the correct module name', function () { + expect(sirdataSubmodule.name).to.equal('SirdataRTDModule'); + }); }); describe('Add Segment Data', function () { it('adds segment data', function () { - const config = { + const firstConfig = { params: { - setGptKeyValues: false, + partnerId: 1, + key: 1, + setGptKeyValues: true, + gptCurationId: 27449, contextualMinRelevancyScore: 50, - bidders: [{ - bidder: 'appnexus' - }, { - bidder: 'other' - }] + bidders: [] } }; @@ -37,21 +42,47 @@ describe('sirdataRtdProvider', function () { } ]; - let data = { + let firstReqBidsConfigObj = { + adUnits: adUnits, + ortb2Fragments: { + global: {} + } + }; + + let firstData = { segments: [111111, 222222], - contextual_categories: {'333333': 100} + contextual_categories: {'333333': 100}, + 'segtaxid': null, + 'cattaxid': null, + 'shared_taxonomy': { + '27449': { + 'segments': [444444, 555555], + 'segtaxid': null, + 'cattaxid': null, + 'contextual_categories': {'666666': 100} + } + }, + 'global_taxonomy': { + '9998': { + 'segments': [123, 234], + 'segtaxid': 4, + 'cattaxid': 7, + 'contextual_categories': {'345': 100, '456': 100} + } + } }; - addSegmentData({adUnits}, data, config, () => { + addSegmentData(firstReqBidsConfigObj, firstData, firstConfig, () => { }); - expect(adUnits[0].bids[0].params.keywords).to.have.deep.property('sd_rtd', ['111111', '222222', '333333']); + + expect(firstReqBidsConfigObj.ortb2Fragments.global.user.data[0].ext.segtax).to.equal(4); }); }); describe('Get Segments And Categories', function () { it('gets data from async request and adds segment data', function () { const overrideAppnexus = function (adUnit, list, data, bid) { - deepSetValue(bid, 'params.keywords.custom', list); + deepSetValue(bid, 'params.keywords.custom', list.segments.concat(list.categories)); } const config = { @@ -60,16 +91,21 @@ describe('sirdataRtdProvider', function () { contextualMinRelevancyScore: 50, bidders: [{ bidder: 'appnexus', - customFunction: overrideAppnexus + customFunction: overrideAppnexus, + curationId: 27446 }, { - bidder: 'smartadserver' + bidder: 'smartadserver', + curationId: 27440 }, { bidder: 'ix', sizeLimit: 1200, + curationId: 27248 }, { bidder: 'rubicon', + curationId: 27452 }, { bidder: 'proxistore', + curationId: 27484 }] } }; @@ -146,6 +182,12 @@ describe('sirdataRtdProvider', function () { 'segtaxid': 552, 'cattaxid': 553, 'contextual_categories': {'666666': 100} + }, + '27446': { + 'segments': [777777, 888888], + 'segtaxid': 552, + 'cattaxid': 553, + 'contextual_categories': {'999999': 100} } }, 'global_taxonomy': { @@ -164,8 +206,6 @@ describe('sirdataRtdProvider', function () { let request = server.requests[0]; request.respond(200, responseHeader, JSON.stringify(data)); - expect(reqBidsConfigObj.adUnits[0].bids[1].params).to.have.deep.property('target', 'sd_rtd=111111;sd_rtd=222222;sd_rtd=333333;sd_rtd=444444;sd_rtd=555555;sd_rtd=666666'); - expect(reqBidsConfigObj.ortb2Fragments.global.site.content.data[0].name).to.equal( 'sirdata.com' ); @@ -185,4 +225,57 @@ describe('sirdataRtdProvider', function () { expect(reqBidsConfigObj.ortb2Fragments.global.user.data[0].ext.segtax).to.equal(4); }); }); + + describe('Set ortb2 for bidder', function () { + it('set ortb2 for a givent bidder', function () { + const config = { + params: { + setGptKeyValues: false, + contextualMinRelevancyScore: 50, + bidders: [{ + bidder: 'appnexus', + }] + } + }; + + let reqBidsConfigObj = { + adUnits: [{ + bids: [{ + bidder: 'appnexus', + params: { + placementId: 13144370 + } + }] + }], + ortb2Fragments: { + global: {} + } + }; + + let data = { + 'segments': [111111, 222222], + 'segtaxid': null, + 'cattaxid': null, + 'contextual_categories': {'333333': 100}, + 'shared_taxonomy': { + '27440': { + 'segments': [444444, 555555], + 'segtaxid': null, + 'cattaxid': null, + 'contextual_categories': {'666666': 100} + } + }, + 'global_taxonomy': {} + }; + + window.googletag = window.googletag || {}; + window.googletag.cmd = window.googletag.cmd || []; + + let test = setBidderOrtb2(reqBidsConfigObj.ortb2Fragments, 'appnexus', 'user', []); + expect(test).to.be.false; + + test = setBidderOrtb2(reqBidsConfigObj.ortb2Fragments, 'appnexus', 'user', ['1']); + expect(test).to.be.true; + }); + }); });