From 8b69b011d8d50b58640b4e1df53475ce82c3f133 Mon Sep 17 00:00:00 2001 From: Jason Snellbaker Date: Tue, 28 May 2024 11:33:56 -0400 Subject: [PATCH 1/3] appnexusBidAdapter 9.0 - move transformBidParams logic to module --- libraries/appnexusUtils/anUtils.js | 16 ++ modules/anPspParamsConverter.js | 142 ++++++++++++++++ modules/anPspParamsConverter.md | 10 ++ modules/appnexusBidAdapter.js | 93 +---------- .../spec/modules/anPspParamsConverter_spec.js | 151 ++++++++++++++++++ test/spec/modules/appnexusBidAdapter_spec.js | 101 ++++++------ 6 files changed, 372 insertions(+), 141 deletions(-) create mode 100644 modules/anPspParamsConverter.js create mode 100644 modules/anPspParamsConverter.md create mode 100644 test/spec/modules/anPspParamsConverter_spec.js diff --git a/libraries/appnexusUtils/anUtils.js b/libraries/appnexusUtils/anUtils.js index 9b55cd5c2a4..d599c0813f0 100644 --- a/libraries/appnexusUtils/anUtils.js +++ b/libraries/appnexusUtils/anUtils.js @@ -10,6 +10,22 @@ export function convertCamelToUnderscore(value) { }).replace(/^_/, ''); } +export const appnexusAliases = [ + { code: 'appnexusAst', gvlid: 32 }, + { code: 'emxdigital', gvlid: 183 }, + { code: 'emetriq', gvlid: 213 }, + { code: 'pagescience', gvlid: 32 }, + { code: 'gourmetads', gvlid: 32 }, + { code: 'matomy', gvlid: 32 }, + { code: 'featureforward', gvlid: 32 }, + { code: 'oftmedia', gvlid: 32 }, + { code: 'adasta', gvlid: 32 }, + { code: 'beintoo', gvlid: 618 }, + { code: 'projectagora', gvlid: 1032 }, + { code: 'uol', gvlid: 32 }, + { code: 'adzymic', gvlid: 32 }, +]; + /** * Creates an array of n length and fills each item with the given value */ diff --git a/modules/anPspParamsConverter.js b/modules/anPspParamsConverter.js new file mode 100644 index 00000000000..8411614bee7 --- /dev/null +++ b/modules/anPspParamsConverter.js @@ -0,0 +1,142 @@ +/* +- register a hook function on the makeBidRequests hook (after the main function ran) + +- this hook function will: +1. verify s2sconfig is defined and we (or our aliases) are included to the config +2. filter bidRequests that match to our bidderName or any registered aliases +3. for each request, read the bidderRequests.bids[].params to modify the keys/values + a. in particular change the keywords structure, apply underscore casing for keys, adjust use_payment_rule name, and convert certain values' types + b. will import some functions from the anKeywords library, but ideally should be kept separate to avoid including this code when it's not needed (strict client-side setups) and avoid the rest of the appnexus adapter's need for inclusion for those strictly server-side setups. +*/ + +import { + isArray, + isPlainObject, + isStr +} from '../src/utils.js'; +import { + getHook +} from '../src/hook.js'; +import { + config +} from '../src/config.js'; +import { + convertCamelToUnderscore, + appnexusAliases +} from '../libraries/appnexusUtils/anUtils.js'; +import { + convertTypes +} from '../libraries/transformParamsUtils/convertTypes.js'; + +import adapterManager from '../src/adapterManager.js'; + +// keywords: { 'genre': ['rock', 'pop'], 'pets': ['dog'] } goes to 'genre=rock,genre=pop,pets=dog' +function convertKeywordsToString(keywords) { + let result = ''; + Object.keys(keywords).forEach(key => { + // if 'text' or '' + if (isStr(keywords[key])) { + if (keywords[key] !== '') { + result += `${key}=${keywords[key]},` + } else { + result += `${key},`; + } + } else if (isArray(keywords[key])) { + if (keywords[key][0] === '') { + result += `${key},` + } else { + keywords[key].forEach(val => { + result += `${key}=${val},` + }); + } + } + }); + + // remove last trailing comma + result = result.substring(0, result.length - 1); + return result; +} + +function digForAppNexusBidder(s2sConfig) { + let result = false; + // check for plain setup + if (s2sConfig?.bidders?.includes('appnexus')) result = true; + + // check for server-side alias + if (!result && isPlainObject(s2sConfig?.extPrebid?.aliases) && (Object.values(s2sConfig?.extPrebid?.aliases).includes('appnexus'))) result = true; + + // registered aliases + const aliasList = appnexusAliases.map(aliasObj => (aliasObj.code)); + if (!result && s2sConfig?.bidders?.filter(s2sBidder => aliasList.includes(s2sBidder)).length > 0) result = true; + + // pbjs.aliasBidder + if (!result) { + result = !!(s2sConfig?.bidders?.find(bidder => (adapterManager.resolveAlias(bidder) === 'appnexus'))); + } + + return result; +} + +// need a separate check b/c we're checking a specific bidRequest to see if we modify it, not just that we have a server-side bidder somewhere in prebid.js +function isThisOurBidderInDisguise(tarBidder, s2sConfig) { + if (tarBidder === 'appnexus') return true; + + if (isPlainObject(s2sConfig?.extPrebid?.aliases) && !!(Object.entries(s2sConfig?.extPrebid?.aliases).find((pair) => (pair[0] === tarBidder && pair[1] === 'appnexus')))) return true; + + if (appnexusAliases.map(aliasObj => (aliasObj.code)).includes(tarBidder)) return true; + + if (adapterManager.resolveAlias(tarBidder) === 'appnexus') return true; + + return false; +} + +export function convertAnParams(next, bidderRequests) { + // check s2sconfig + const s2sConfig = config.getConfig('s2sConfig'); + let proceed = false; + + // check for dynamic aliases (from pbjs.aliasBidder) + if (isPlainObject(s2sConfig)) { + proceed = digForAppNexusBidder(s2sConfig); + } else if (isArray(s2sConfig)) { + s2sConfig.forEach(s2sCfg => { + proceed = digForAppNexusBidder(s2sCfg); + }); + } + + if (proceed) { + bidderRequests.forEach(bidRequest => { + if (isThisOurBidderInDisguise(bidRequest.bidderCode, s2sConfig)) { + bidRequest.bids.forEach(bid => { + let params = bid.params; + if (params) { + params = convertTypes({ + 'member': 'string', + 'invCode': 'string', + 'placementId': 'number', + 'keywords': convertKeywordsToString, + 'publisherId': 'number' + }, params); + + Object.keys(params).forEach(paramKey => { + let convertedKey = convertCamelToUnderscore(paramKey); + if (convertedKey !== paramKey) { + params[convertedKey] = params[paramKey]; + delete params[paramKey]; + } + }); + + params.use_pmt_rule = (typeof params.use_payment_rule === 'boolean') ? params.use_payment_rule : false; + if (params.use_payment_rule) { + delete params.use_payment_rule; + } + } + }); + } + }); + } + + next(bidderRequests); +} + +getHook('makeBidRequests').after(convertAnParams, 9); diff --git a/modules/anPspParamsConverter.md b/modules/anPspParamsConverter.md new file mode 100644 index 00000000000..f341b0a5976 --- /dev/null +++ b/modules/anPspParamsConverter.md @@ -0,0 +1,10 @@ +## Quick Summary + +This module is a temporary measure for publishers running Prebid.js 9.0+ and using the AppNexus PSP endpoint through their Prebid.js setup. Please ensure to include this module in your builds of Prebid.js 9.0+, otherwise requests to PSP may not complete successfully. + +## Module's purpose + +This module replicates certain functionality that was previously stored in the appnexusBidAdapter.js file within a function named transformBidParams. + +This transformBidParams was a standard function in all adapters, which helped to change/modify the params and their values to a format that matched the bidder's request structure on the server-side endpoint. In Prebid.js 9.0, this standard function was removed in all adapter files, so that the whole client-side file (eg appnexusBidAdapter.js) wouldn't have to be included in a prebid.js build file that was meant for server-side bidders. + diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index 551bf5401e2..da4f539db5a 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -31,10 +31,9 @@ import {APPNEXUS_CATEGORY_MAPPING} from '../libraries/categoryTranslationMapping import { convertKeywordStringToANMap, getANKewyordParamFromMaps, - getANKeywordParam, - transformBidderParamKeywords + getANKeywordParam } from '../libraries/appnexusUtils/anKeywords.js'; -import {convertCamelToUnderscore, fill} from '../libraries/appnexusUtils/anUtils.js'; +import {convertCamelToUnderscore, fill, appnexusAliases} from '../libraries/appnexusUtils/anUtils.js'; import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js'; import {chunk} from '../libraries/chunk/chunk.js'; @@ -108,21 +107,7 @@ const storage = getStorageManager({bidderCode: BIDDER_CODE}); export const spec = { code: BIDDER_CODE, gvlid: GVLID, - aliases: [ - { code: 'appnexusAst', gvlid: 32 }, - { code: 'emxdigital', gvlid: 183 }, - { code: 'emetriq', gvlid: 213 }, - { code: 'pagescience', gvlid: 32 }, - { code: 'gourmetads', gvlid: 32 }, - { code: 'matomy', gvlid: 32 }, - { code: 'featureforward', gvlid: 32 }, - { code: 'oftmedia', gvlid: 32 }, - { code: 'adasta', gvlid: 32 }, - { code: 'beintoo', gvlid: 618 }, - { code: 'projectagora', gvlid: 1032 }, - { code: 'uol', gvlid: 32 }, - { code: 'adzymic', gvlid: 32 }, - ], + aliases: appnexusAliases, supportedMediaTypes: [BANNER, VIDEO, NATIVE], /** @@ -449,51 +434,6 @@ export const spec = { url: 'https://acdn.adnxs.com/dmp/async_usersync.html' }]; } - }, - - transformBidParams: function (params, isOpenRtb, adUnit, bidRequests) { - let conversionFn = transformBidderParamKeywords; - if (isOpenRtb === true) { - let s2sEndpointUrl = null; - let s2sConfig = config.getConfig('s2sConfig'); - - if (isPlainObject(s2sConfig)) { - s2sEndpointUrl = deepAccess(s2sConfig, 'endpoint.p1Consent'); - } else if (isArray(s2sConfig)) { - s2sConfig.forEach(s2sCfg => { - if (includes(s2sCfg.bidders, adUnit.bids[0].bidder)) { - s2sEndpointUrl = deepAccess(s2sCfg, 'endpoint.p1Consent'); - } - }); - } - - if (s2sEndpointUrl && s2sEndpointUrl.match('/openrtb2/prebid')) { - conversionFn = convertKeywordsToString; - } - } - - params = convertTypes({ - 'member': 'string', - 'invCode': 'string', - 'placementId': 'number', - 'keywords': conversionFn, - 'publisherId': 'number' - }, params); - - if (isOpenRtb) { - Object.keys(params).forEach(paramKey => { - let convertedKey = convertCamelToUnderscore(paramKey); - if (convertedKey !== paramKey) { - params[convertedKey] = params[paramKey]; - delete params[paramKey]; - } - }); - - params.use_pmt_rule = (typeof params.use_payment_rule === 'boolean') ? params.use_payment_rule : false; - if (params.use_payment_rule) { delete params.use_payment_rule; } - } - - return params; } }; @@ -1256,31 +1196,4 @@ function getBidFloor(bid) { return null; } -// keywords: { 'genre': ['rock', 'pop'], 'pets': ['dog'] } goes to 'genre=rock,genre=pop,pets=dog' -function convertKeywordsToString(keywords) { - let result = ''; - Object.keys(keywords).forEach(key => { - // if 'text' or '' - if (isStr(keywords[key])) { - if (keywords[key] !== '') { - result += `${key}=${keywords[key]},` - } else { - result += `${key},`; - } - } else if (isArray(keywords[key])) { - if (keywords[key][0] === '') { - result += `${key},` - } else { - keywords[key].forEach(val => { - result += `${key}=${val},` - }); - } - } - }); - - // remove last trailing comma - result = result.substring(0, result.length - 1); - return result; -} - registerBidder(spec); diff --git a/test/spec/modules/anPspParamsConverter_spec.js b/test/spec/modules/anPspParamsConverter_spec.js new file mode 100644 index 00000000000..2f3f5341a11 --- /dev/null +++ b/test/spec/modules/anPspParamsConverter_spec.js @@ -0,0 +1,151 @@ +import { expect } from 'chai'; + +import {convertAnParams} from '../../../modules/anPspParamsConverter'; +import { config } from '../../../src/config.js'; +import { deepClone } from '../../../src/utils'; +import adapterManager from '../../../src/adapterManager.js'; + + +describe('anPspParamsConverter', function () { + let configStub; + let resolveAliasStub; + let didHookRun = false; + + const bidderRequests = [{ + bidderCode: 'appnexus', + bids: [{ + params: { + member: 958, + invCode: 12345, + placementId: '10001', + keywords: { + music: 'rock', + genre: ['80s', '90s'] + }, + publisherId: '111', + use_payment_rule: true + } + }] + }]; + + beforeEach(function () { + configStub = sinon.stub(config, 'getConfig'); + resolveAliasStub = sinon.stub(adapterManager, 'resolveAlias'); + }); + + afterEach(function () { + didHookRun = false; + configStub.restore(); + resolveAliasStub.restore(); + }); + + it('does not modify params when appnexus is not in s2sconfig', function () { + configStub.callsFake(function () { + return { + bidders: ['rubicon'] + }; + }); + + const testBidderRequests = deepClone(bidderRequests); + + convertAnParams(function () { + didHookRun = true; + }, testBidderRequests); + + expect(didHookRun).to.equal(true); + const resultParams = testBidderRequests[0].bids[0].params; + expect(resultParams.member).to.equal(958); + expect(resultParams.invCode).to.equal(12345); + expect(resultParams.placementId).to.equal('10001'); + expect(resultParams.keywords).to.deep.equal({ + music: 'rock', + genre: ['80s', '90s'] + }); + expect(resultParams.publisherId).to.equal('111'); + expect(resultParams.use_payment_rule).to.equal(true); + }); + + const tests = [{ + testName: 'modifies params when appnexus is the bidder', + fakeConfigFn: function () { + return { + bidders: ['appnexus'] + }; + }, + applyBidderRequestChanges: function () { + const testBidderRequests = deepClone(bidderRequests); + + return testBidderRequests; + } + }, { + testName: 'modifies params when a registered appnexus alias is used', + fakeConfigFn: function () { + return { + bidders: ['beintoo'] + }; + }, + applyBidderRequestChanges: function () { + const testBidderRequests = deepClone(bidderRequests); + testBidderRequests.bidderCode = 'beintoo'; + + return testBidderRequests; + } + }, { + testName: 'modifies params when an server-side alias is setup in s2sConfig', + fakeConfigFn: function () { + return { + bidders: ['serverSideAlias'], + extPrebid: { + aliases: { + 'serverSideAlias': 'appnexus' + } + } + }; + }, + applyBidderRequestChanges: function () { + const testBidderRequests = deepClone(bidderRequests); + testBidderRequests.bidderCode = 'serverSideAlias'; + + return testBidderRequests; + } + }, { + testName: 'modifies params when pbjs.aliasBidder alias is used', + fakeConfigFn: function () { + return { + bidders: ['aliasBidderTest'], + }; + }, + applyBidderRequestChanges: function () { + resolveAliasStub.callsFake(function () { + return 'appnexus'; + }); + + const testBidderRequests = deepClone(bidderRequests); + testBidderRequests.bidderCode = 'aliasBidderTest'; + + return testBidderRequests; + } + }]; + + tests.forEach((testCfg) => { + it(testCfg.testName, function () { + configStub.callsFake(testCfg.fakeConfigFn); + + const testBidderRequests = testCfg.applyBidderRequestChanges(); + + + convertAnParams(function () { + didHookRun = true; + }, testBidderRequests); + + expect(didHookRun).to.equal(true); + const resultParams = testBidderRequests[0].bids[0].params; + expect(resultParams.member).to.equal('958'); + expect(resultParams.inv_code).to.equal('12345'); + expect(resultParams.placement_id).to.equal(10001); + expect(resultParams.keywords).to.equal('music=rock,genre=80s,genre=90s'); + expect(resultParams.publisher_id).to.equal(111); + expect(resultParams.use_pmt_rule).to.equal(true); + }); + }); +}); diff --git a/test/spec/modules/appnexusBidAdapter_spec.js b/test/spec/modules/appnexusBidAdapter_spec.js index c2da2f36223..b3b049a1598 100644 --- a/test/spec/modules/appnexusBidAdapter_spec.js +++ b/test/spec/modules/appnexusBidAdapter_spec.js @@ -1,7 +1,6 @@ import { expect } from 'chai'; import { spec } from 'modules/appnexusBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; -import * as bidderFactory from 'src/adapters/bidderFactory.js'; import { auctionManager } from 'src/auctionManager.js'; import { deepClone } from 'src/utils.js'; import * as utils from 'src/utils.js'; @@ -2151,54 +2150,54 @@ describe('AppNexusAdapter', function () { }); }); - describe('transformBidParams', function () { - let gcStub; - let adUnit = { bids: [{ bidder: 'appnexus' }] }; ; - - before(function () { - gcStub = sinon.stub(config, 'getConfig'); - }); - - after(function () { - gcStub.restore(); - }); - - it('convert keywords param differently for psp endpoint with single s2sConfig', function () { - gcStub.withArgs('s2sConfig').returns({ - bidders: ['appnexus'], - endpoint: { - p1Consent: 'https://ib.adnxs.com/openrtb2/prebid' - } - }); - - const oldParams = { - keywords: { - genre: ['rock', 'pop'], - pets: 'dog' - } - }; - - const newParams = spec.transformBidParams(oldParams, true, adUnit); - expect(newParams.keywords).to.equal('genre=rock,genre=pop,pets=dog'); - }); - - it('convert keywords param differently for psp endpoint with array s2sConfig', function () { - gcStub.withArgs('s2sConfig').returns([{ - bidders: ['appnexus'], - endpoint: { - p1Consent: 'https://ib.adnxs.com/openrtb2/prebid' - } - }]); - - const oldParams = { - keywords: { - genre: ['rock', 'pop'], - pets: 'dog' - } - }; - - const newParams = spec.transformBidParams(oldParams, true, adUnit); - expect(newParams.keywords).to.equal('genre=rock,genre=pop,pets=dog'); - }); - }); + // describe('transformBidParams', function () { + // let gcStub; + // let adUnit = { bids: [{ bidder: 'appnexus' }] }; ; + + // before(function () { + // gcStub = sinon.stub(config, 'getConfig'); + // }); + + // after(function () { + // gcStub.restore(); + // }); + + // it('convert keywords param differently for psp endpoint with single s2sConfig', function () { + // gcStub.withArgs('s2sConfig').returns({ + // bidders: ['appnexus'], + // endpoint: { + // p1Consent: 'https://ib.adnxs.com/openrtb2/prebid' + // } + // }); + + // const oldParams = { + // keywords: { + // genre: ['rock', 'pop'], + // pets: 'dog' + // } + // }; + + // const newParams = spec.transformBidParams(oldParams, true, adUnit); + // expect(newParams.keywords).to.equal('genre=rock,genre=pop,pets=dog'); + // }); + + // it('convert keywords param differently for psp endpoint with array s2sConfig', function () { + // gcStub.withArgs('s2sConfig').returns([{ + // bidders: ['appnexus'], + // endpoint: { + // p1Consent: 'https://ib.adnxs.com/openrtb2/prebid' + // } + // }]); + + // const oldParams = { + // keywords: { + // genre: ['rock', 'pop'], + // pets: 'dog' + // } + // }; + + // const newParams = spec.transformBidParams(oldParams, true, adUnit); + // expect(newParams.keywords).to.equal('genre=rock,genre=pop,pets=dog'); + // }); + // }); }); From 91c940ecdf6cb74c474f0b17909d73376be282b0 Mon Sep 17 00:00:00 2001 From: Jason Snellbaker Date: Tue, 28 May 2024 13:32:37 -0400 Subject: [PATCH 2/3] fix lint errors in test file --- test/spec/modules/anPspParamsConverter_spec.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/spec/modules/anPspParamsConverter_spec.js b/test/spec/modules/anPspParamsConverter_spec.js index 2f3f5341a11..0da99f65aaf 100644 --- a/test/spec/modules/anPspParamsConverter_spec.js +++ b/test/spec/modules/anPspParamsConverter_spec.js @@ -5,7 +5,6 @@ import { config } from '../../../src/config.js'; import { deepClone } from '../../../src/utils'; import adapterManager from '../../../src/adapterManager.js'; - describe('anPspParamsConverter', function () { let configStub; let resolveAliasStub; @@ -119,7 +118,7 @@ describe('anPspParamsConverter', function () { resolveAliasStub.callsFake(function () { return 'appnexus'; }); - + const testBidderRequests = deepClone(bidderRequests); testBidderRequests.bidderCode = 'aliasBidderTest'; @@ -130,14 +129,13 @@ describe('anPspParamsConverter', function () { tests.forEach((testCfg) => { it(testCfg.testName, function () { configStub.callsFake(testCfg.fakeConfigFn); - + const testBidderRequests = testCfg.applyBidderRequestChanges(); - convertAnParams(function () { didHookRun = true; }, testBidderRequests); - + expect(didHookRun).to.equal(true); const resultParams = testBidderRequests[0].bids[0].params; expect(resultParams.member).to.equal('958'); From 76471612775704b6ccd4b6ff320827df0dce3794 Mon Sep 17 00:00:00 2001 From: Jason Snellbaker Date: Wed, 29 May 2024 15:26:09 -0400 Subject: [PATCH 3/3] rework logic that reads bidderRequests --- modules/anPspParamsConverter.js | 104 ++++++++---------- .../spec/modules/anPspParamsConverter_spec.js | 31 ++---- 2 files changed, 53 insertions(+), 82 deletions(-) diff --git a/modules/anPspParamsConverter.js b/modules/anPspParamsConverter.js index 8411614bee7..27b90168476 100644 --- a/modules/anPspParamsConverter.js +++ b/modules/anPspParamsConverter.js @@ -9,25 +9,12 @@ b. will import some functions from the anKeywords library, but ideally should be kept separate to avoid including this code when it's not needed (strict client-side setups) and avoid the rest of the appnexus adapter's need for inclusion for those strictly server-side setups. */ -import { - isArray, - isPlainObject, - isStr -} from '../src/utils.js'; -import { - getHook -} from '../src/hook.js'; -import { - config -} from '../src/config.js'; -import { - convertCamelToUnderscore, - appnexusAliases -} from '../libraries/appnexusUtils/anUtils.js'; -import { - convertTypes -} from '../libraries/transformParamsUtils/convertTypes.js'; - +// import { CONSTANTS } from '../src/cons tants.js'; +import {isArray, isPlainObject, isStr} from '../src/utils.js'; +import {getHook} from '../src/hook.js'; +import {config} from '../src/config.js'; +import {convertCamelToUnderscore, appnexusAliases} from '../libraries/appnexusUtils/anUtils.js'; +import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js'; import adapterManager from '../src/adapterManager.js'; // keywords: { 'genre': ['rock', 'pop'], 'pets': ['dog'] } goes to 'genre=rock,genre=pop,pets=dog' @@ -62,9 +49,6 @@ function digForAppNexusBidder(s2sConfig) { // check for plain setup if (s2sConfig?.bidders?.includes('appnexus')) result = true; - // check for server-side alias - if (!result && isPlainObject(s2sConfig?.extPrebid?.aliases) && (Object.values(s2sConfig?.extPrebid?.aliases).includes('appnexus'))) result = true; - // registered aliases const aliasList = appnexusAliases.map(aliasObj => (aliasObj.code)); if (!result && s2sConfig?.bidders?.filter(s2sBidder => aliasList.includes(s2sBidder)).length > 0) result = true; @@ -78,24 +62,23 @@ function digForAppNexusBidder(s2sConfig) { } // need a separate check b/c we're checking a specific bidRequest to see if we modify it, not just that we have a server-side bidder somewhere in prebid.js -function isThisOurBidderInDisguise(tarBidder, s2sConfig) { - if (tarBidder === 'appnexus') return true; +// function isThisOurBidderInDisguise(tarBidder, s2sConfig) { +// if (tarBidder === 'appnexus') return true; - if (isPlainObject(s2sConfig?.extPrebid?.aliases) && !!(Object.entries(s2sConfig?.extPrebid?.aliases).find((pair) => (pair[0] === tarBidder && pair[1] === 'appnexus')))) return true; +// if (isPlainObject(s2sConfig?.extPrebid?.aliases) && !!(Object.entries(s2sConfig?.extPrebid?.aliases).find((pair) => (pair[0] === tarBidder && pair[1] === 'appnexus')))) return true; - if (appnexusAliases.map(aliasObj => (aliasObj.code)).includes(tarBidder)) return true; +// if (appnexusAliases.map(aliasObj => (aliasObj.code)).includes(tarBidder)) return true; - if (adapterManager.resolveAlias(tarBidder) === 'appnexus') return true; +// if (adapterManager.resolveAlias(tarBidder) === 'appnexus') return true; - return false; -} +// return false; +// } export function convertAnParams(next, bidderRequests) { // check s2sconfig const s2sConfig = config.getConfig('s2sConfig'); let proceed = false; - // check for dynamic aliases (from pbjs.aliasBidder) if (isPlainObject(s2sConfig)) { proceed = digForAppNexusBidder(s2sConfig); } else if (isArray(s2sConfig)) { @@ -105,38 +88,41 @@ export function convertAnParams(next, bidderRequests) { } if (proceed) { - bidderRequests.forEach(bidRequest => { - if (isThisOurBidderInDisguise(bidRequest.bidderCode, s2sConfig)) { - bidRequest.bids.forEach(bid => { - let params = bid.params; - if (params) { - params = convertTypes({ - 'member': 'string', - 'invCode': 'string', - 'placementId': 'number', - 'keywords': convertKeywordsToString, - 'publisherId': 'number' - }, params); - - Object.keys(params).forEach(paramKey => { - let convertedKey = convertCamelToUnderscore(paramKey); - if (convertedKey !== paramKey) { - params[convertedKey] = params[paramKey]; - delete params[paramKey]; - } - }); - - params.use_pmt_rule = (typeof params.use_payment_rule === 'boolean') ? params.use_payment_rule : false; - if (params.use_payment_rule) { - delete params.use_payment_rule; - } - } - }); - } - }); + bidderRequests + .flatMap(br => br.bids) + .filter(bid => bid.src === 's2s' && adapterManager.resolveAlias(bid.bidder) === 'appnexus') + .forEach((bid) => { + transformBidParams(bid); + }); } next(bidderRequests); } +function transformBidParams(bid) { + let params = bid.params; + if (params) { + params = convertTypes({ + 'member': 'string', + 'invCode': 'string', + 'placementId': 'number', + 'keywords': convertKeywordsToString, + 'publisherId': 'number' + }, params); + + Object.keys(params).forEach(paramKey => { + let convertedKey = convertCamelToUnderscore(paramKey); + if (convertedKey !== paramKey) { + params[convertedKey] = params[paramKey]; + delete params[paramKey]; + } + }); + + params.use_pmt_rule = (typeof params.use_payment_rule === 'boolean') ? params.use_payment_rule : false; + if (params.use_payment_rule) { + delete params.use_payment_rule; + } + } +} + getHook('makeBidRequests').after(convertAnParams, 9); diff --git a/test/spec/modules/anPspParamsConverter_spec.js b/test/spec/modules/anPspParamsConverter_spec.js index 0da99f65aaf..0d01d0e78a9 100644 --- a/test/spec/modules/anPspParamsConverter_spec.js +++ b/test/spec/modules/anPspParamsConverter_spec.js @@ -13,6 +13,8 @@ describe('anPspParamsConverter', function () { const bidderRequests = [{ bidderCode: 'appnexus', bids: [{ + bidder: 'appnexus', + src: 's2s', params: { member: 958, invCode: 12345, @@ -29,7 +31,9 @@ describe('anPspParamsConverter', function () { beforeEach(function () { configStub = sinon.stub(config, 'getConfig'); - resolveAliasStub = sinon.stub(adapterManager, 'resolveAlias'); + resolveAliasStub = sinon.stub(adapterManager, 'resolveAlias').callsFake(function (tarBidder) { + return (tarBidder === 'rubicon') ? 'rubicon' : 'appnexus'; + }); }); afterEach(function () { @@ -47,6 +51,7 @@ describe('anPspParamsConverter', function () { const testBidderRequests = deepClone(bidderRequests); + debugger; //eslint-disable-line convertAnParams(function () { didHookRun = true; }, testBidderRequests); @@ -86,24 +91,7 @@ describe('anPspParamsConverter', function () { applyBidderRequestChanges: function () { const testBidderRequests = deepClone(bidderRequests); testBidderRequests.bidderCode = 'beintoo'; - - return testBidderRequests; - } - }, { - testName: 'modifies params when an server-side alias is setup in s2sConfig', - fakeConfigFn: function () { - return { - bidders: ['serverSideAlias'], - extPrebid: { - aliases: { - 'serverSideAlias': 'appnexus' - } - } - }; - }, - applyBidderRequestChanges: function () { - const testBidderRequests = deepClone(bidderRequests); - testBidderRequests.bidderCode = 'serverSideAlias'; + testBidderRequests[0].bids[0].bidder = 'beintoo'; return testBidderRequests; } @@ -115,12 +103,9 @@ describe('anPspParamsConverter', function () { }; }, applyBidderRequestChanges: function () { - resolveAliasStub.callsFake(function () { - return 'appnexus'; - }); - const testBidderRequests = deepClone(bidderRequests); testBidderRequests.bidderCode = 'aliasBidderTest'; + testBidderRequests[0].bids[0].bidder = 'aliasBidderTest'; return testBidderRequests; }