diff --git a/modules/aolBidAdapter.js b/modules/aolBidAdapter.js index 18d30685c568..28e8cb0b46eb 100644 --- a/modules/aolBidAdapter.js +++ b/modules/aolBidAdapter.js @@ -31,7 +31,7 @@ const SYNC_TYPES = { } }; -const pubapiTemplate = template`//${'host'}/pubapi/3.0/${'network'}/${'placement'}/${'pageid'}/${'sizeid'}/ADTECH;v=2;cmd=bid;cors=yes;alias=${'alias'};misc=${'misc'}${'bidfloor'}${'keyValues'}${'consentData'}`; +const pubapiTemplate = template`//${'host'}/pubapi/3.0/${'network'}/${'placement'}/${'pageid'}/${'sizeid'}/ADTECH;v=2;cmd=bid;cors=yes;alias=${'alias'};misc=${'misc'};${'dynamicParams'}`; const nexageBaseApiTemplate = template`//${'host'}/bidRequest?`; const nexageGetApiTemplate = template`dcn=${'dcn'}&pos=${'pos'}&cmd=bid${'dynamicParams'}`; const MP_SERVER_MAP = { @@ -47,6 +47,11 @@ $$PREBID_GLOBAL$$.aolGlobals = { pixelsDropped: false }; +const NUMERIC_VALUES = { + TRUE: 1, + FALSE: 0 +}; + let showCpmAdjustmentWarning = (function() { let showCpmWarning = true; @@ -101,20 +106,6 @@ function parsePixelItems(pixels) { return pixelsItems; } -function formatMarketplaceBidFloor(bidFloor) { - return (typeof bidFloor !== 'undefined') ? `;bidfloor=${bidFloor.toString()}` : ''; -} - -function formatMarketplaceKeyValues(keyValues) { - let formattedKeyValues = ''; - - utils._each(keyValues, (value, key) => { - formattedKeyValues += `;kv${key}=${encodeURIComponent(value)}`; - }); - - return formattedKeyValues; -} - function _isMarketplaceBidder(bidder) { return bidder === AOL_BIDDERS_CODES.AOL || bidder === AOL_BIDDERS_CODES.ONEDISPLAY; } @@ -268,10 +259,8 @@ export const spec = { pageid: params.pageId || 0, sizeid: params.sizeId || 0, alias: params.alias || utils.getUniqueIdentifierStr(), - misc: new Date().getTime(), // cache busting, - bidfloor: formatMarketplaceBidFloor(params.bidFloor), - keyValues: formatMarketplaceKeyValues(params.keyValues), - consentData: this.formatMarketplaceConsentData(consentData) + misc: new Date().getTime(), // cache busting + dynamicParams: this.formatMarketplaceDynamicParams(params, consentData) }); }, buildOneMobileGetUrl(bid, consentData) { @@ -288,15 +277,29 @@ export const spec = { host: bid.params.host || NEXAGE_SERVER }); }, + formatMarketplaceDynamicParams(params = {}, consentData) { + let queryParams = {}; + + if (params.bidFloor) { + queryParams.bidfloor = params.bidFloor; + } + + Object.assign(queryParams, this.formatKeyValues(params.keyValues)); + Object.assign(queryParams, this.formatConsentData(consentData)); + + let paramsFormatted = ''; + utils._each(queryParams, (value, key) => { + paramsFormatted += `${key}=${encodeURIComponent(value)};`; + }); + + return paramsFormatted; + }, formatOneMobileDynamicParams(params = {}, consentData) { if (this.isSecureProtocol()) { - params.secure = 1; + params.secure = NUMERIC_VALUES.TRUE; } - if (this.isConsentRequired(consentData)) { - params.euconsent = consentData.consentString; - params.gdpr = 1; - } + Object.assign(params, this.formatConsentData(consentData)); let paramsFormatted = ''; utils._each(params, (value, key) => { @@ -312,27 +315,47 @@ export const spec = { }; if (this.isConsentRequired(consentData)) { - openRtbObject.user = { - ext: { - consent: consentData.consentString - } - }; openRtbObject.regs = { ext: { - gdpr: 1 + gdpr: NUMERIC_VALUES.TRUE } }; + + if (consentData.consentString) { + openRtbObject.user = { + ext: { + consent: consentData.consentString + } + }; + } } return openRtbObject; }, isConsentRequired(consentData) { - return !!(consentData && consentData.consentString && consentData.gdprApplies); + return !!(consentData && consentData.gdprApplies); }, - formatMarketplaceConsentData(consentData) { - let consentRequired = this.isConsentRequired(consentData); + formatKeyValues(keyValues) { + let keyValuesHash = {}; + + utils._each(keyValues, (value, key) => { + keyValuesHash[`kv${key}`] = value; + }); + + return keyValuesHash; + }, + formatConsentData(consentData) { + let params = {}; + + if (this.isConsentRequired(consentData)) { + params.gdpr = NUMERIC_VALUES.TRUE; + + if (consentData.consentString) { + params.euconsent = consentData.consentString; + } + } - return consentRequired ? `;euconsent=${consentData.consentString};gdpr=1` : ''; + return params; }, _parseBidResponse(response, bidRequest) { diff --git a/test/spec/modules/aolBidAdapter_spec.js b/test/spec/modules/aolBidAdapter_spec.js index d69b9e6e3d80..bc42f69ce63f 100644 --- a/test/spec/modules/aolBidAdapter_spec.js +++ b/test/spec/modules/aolBidAdapter_spec.js @@ -576,13 +576,13 @@ describe('AolAdapter', () => { expect(spec.isConsentRequired(null)).to.be.false; }); - it('should return false when gdprApplies equals true and consentString is not present', () => { + it('should return true when gdprApplies equals true and consentString is not present', () => { let consentData = { consentString: null, gdprApplies: true }; - expect(spec.isConsentRequired(consentData)).to.be.false; + expect(spec.isConsentRequired(consentData)).to.be.true; }); it('should return false when consentString is present and gdprApplies equals false', () => { @@ -604,28 +604,46 @@ describe('AolAdapter', () => { }); }); - describe('formatMarketplaceConsentData()', () => { - let consentRequiredStub; + describe('formatMarketplaceDynamicParams()', () => { + let formatConsentDataStub; + let formatKeyValuesStub; beforeEach(() => { - consentRequiredStub = sinon.stub(spec, 'isConsentRequired'); + formatConsentDataStub = sinon.stub(spec, 'formatConsentData'); + formatKeyValuesStub = sinon.stub(spec, 'formatKeyValues'); }); afterEach(() => { - consentRequiredStub.restore(); + formatConsentDataStub.restore(); + formatKeyValuesStub.restore(); }); - it('should return empty string when consent is not required', () => { - consentRequiredStub.returns(false); - expect(spec.formatMarketplaceConsentData()).to.be.equal(''); + it('should return empty string when params are not present', () => { + expect(spec.formatMarketplaceDynamicParams()).to.be.equal(''); }); - it('should return formatted consent data when consent is required', () => { - consentRequiredStub.returns(true); - let formattedConsentData = spec.formatMarketplaceConsentData({ - consentString: 'test-consent' + it('should return formatted params when formatConsentData returns data', () => { + formatConsentDataStub.returns({ + euconsent: 'test-consent', + gdpr: 1 + }); + expect(spec.formatMarketplaceDynamicParams()).to.be.equal('euconsent=test-consent;gdpr=1;'); + }); + + it('should return formatted params when formatKeyValues returns data', () => { + formatKeyValuesStub.returns({ + param1: 'val1', + param2: 'val2', + param3: 'val3' }); - expect(formattedConsentData).to.be.equal(';euconsent=test-consent;gdpr=1'); + expect(spec.formatMarketplaceDynamicParams()).to.be.equal('param1=val1;param2=val2;param3=val3;'); + }); + + it('should return formatted bid floor param when it is present', () => { + let params = { + bidFloor: 0.45 + }; + expect(spec.formatMarketplaceDynamicParams(params)).to.be.equal('bidfloor=0.45;'); }); }); @@ -661,7 +679,7 @@ describe('AolAdapter', () => { consentString: 'test-consent' }; consentRequiredStub.returns(true); - expect(spec.formatOneMobileDynamicParams({}, consentData)).to.be.equal('&euconsent=test-consent&gdpr=1'); + expect(spec.formatOneMobileDynamicParams({}, consentData)).to.be.equal('&gdpr=1&euconsent=test-consent'); }); it('should return formatted secure param when isSecureProtocol returns true', () => {