From 3b8bcb35284edad1817356bdf6d884c998f2c3e2 Mon Sep 17 00:00:00 2001 From: Jonathan Go Date: Wed, 20 Mar 2019 10:25:52 -0400 Subject: [PATCH 1/5] added param to sonobi bid request bid url that lets sonobi know if its ok to drop iframe pixels. --- modules/sonobiBidAdapter.js | 8 ++++++++ src/userSync.js | 2 ++ test/spec/modules/sonobiBidAdapter_spec.js | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/modules/sonobiBidAdapter.js b/modules/sonobiBidAdapter.js index ab4058b1978..6c5ac659cd9 100644 --- a/modules/sonobiBidAdapter.js +++ b/modules/sonobiBidAdapter.js @@ -3,6 +3,7 @@ import { parseSizesInput, logError, generateUUID, isEmpty, deepAccess, logWarn, import { BANNER, VIDEO } from '../src/mediaTypes'; import { config } from '../src/config'; import { Renderer } from '../src/Renderer'; +import { userSync } from '../src/userSync'; const BIDDER_CODE = 'sonobi'; const STR_ENDPOINT = 'https://apex.go.sonobi.com/trinity.json'; @@ -62,6 +63,13 @@ export const spec = { payload.us = config.getConfig('userSync').syncsPerBidder; } + // use userSync's internal function to determine if we can drop an iframe sync pixel + if (userSync._shouldBidderBeBlocked('iframe', BIDDER_CODE)) { + payload.ius = 0; + } else { + payload.ius = 1; + } + if (deepAccess(validBidRequests[0], 'crumbs.pubcid') || deepAccess(validBidRequests[0], 'params.hfa')) { payload.hfa = deepAccess(validBidRequests[0], 'params.hfa') ? deepAccess(validBidRequests[0], 'params.hfa') : `PRE-${deepAccess(validBidRequests[0], 'crumbs.pubcid')}`; } diff --git a/src/userSync.js b/src/userSync.js index 8e0b919572e..1c4fbdef79f 100644 --- a/src/userSync.js +++ b/src/userSync.js @@ -262,6 +262,8 @@ export function newUserSync(userSyncDependencies) { } }; + publicApi._shouldBidderBeBlocked = shouldBidderBeBlocked; + return publicApi; } diff --git a/test/spec/modules/sonobiBidAdapter_spec.js b/test/spec/modules/sonobiBidAdapter_spec.js index 4fe9d92b2d4..808aa2e5b95 100644 --- a/test/spec/modules/sonobiBidAdapter_spec.js +++ b/test/spec/modules/sonobiBidAdapter_spec.js @@ -1,6 +1,7 @@ import { expect } from 'chai' import { spec, _getPlatform } from 'modules/sonobiBidAdapter' import { newBidder } from 'src/adapters/bidderFactory' +import {userSync} from '../../../src/userSync'; describe('SonobiBidAdapter', function () { const adapter = newBidder(spec) @@ -101,6 +102,12 @@ describe('SonobiBidAdapter', function () { }) describe('.buildRequests', function () { + beforeEach(function() { + sinon.stub(userSync, '_shouldBidderBeBlocked'); + }); + afterEach(function() { + userSync._shouldBidderBeBlocked.restore(); + }); let bidRequest = [{ 'bidder': 'sonobi', 'params': { @@ -303,6 +310,18 @@ describe('SonobiBidAdapter', function () { expect(bidRequests.data.s).not.to.be.empty expect(bidRequests.data.hfa).to.equal('hfakey') }) + + it('should set ius as 0 if Sonobi cannot drop iframe pixels', function () { + userSync._shouldBidderBeBlocked.returns(true); + const bidRequests = spec.buildRequests(bidRequest, bidderRequests); + expect(bidRequests.data.ius).to.equal(0); + }); + + it('should set ius as 1 if Sonobi can drop iframe pixels', function() { + userSync._shouldBidderBeBlocked.returns(false); + const bidRequests = spec.buildRequests(bidRequest, bidderRequests); + expect(bidRequests.data.ius).to.equal(1); + }); }) describe('.interpretResponse', function () { From 44e2a0be6d241210bdfaa86a8b6ecf77bded97c6 Mon Sep 17 00:00:00 2001 From: Jonathan Go Date: Wed, 20 Mar 2019 13:40:36 -0400 Subject: [PATCH 2/5] added case to isFilterConfigValid to check if it is falsey --- sonobi_video.html | 0 src/userSync.js | 4 ++++ 2 files changed, 4 insertions(+) create mode 100644 sonobi_video.html diff --git a/sonobi_video.html b/sonobi_video.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/userSync.js b/src/userSync.js index 1c4fbdef79f..cfff55f024b 100644 --- a/src/userSync.js +++ b/src/userSync.js @@ -208,6 +208,10 @@ export function newUserSync(userSyncDependencies) { * @returns {boolean} true => config is setup correctly, false => setup incorrectly or filterConfig[type] is not present */ function isFilterConfigValid(filterConfig, type) { + if(!filterConfig) { + return false; + } + if (filterConfig.all && filterConfig[type]) { utils.logWarn(`Detected presence of the "filterSettings.all" and "filterSettings.${type}" in userSync config. You cannot mix "all" with "iframe/image" configs; they are mutually exclusive.`); return false; From d3a1ed42f73a0cb42cadd89614cc7c7755c31ad8 Mon Sep 17 00:00:00 2001 From: Jonathan Go Date: Wed, 20 Mar 2019 14:08:04 -0400 Subject: [PATCH 3/5] fixed eslint issues. --- src/userSync.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/userSync.js b/src/userSync.js index cfff55f024b..26a3bd85d6c 100644 --- a/src/userSync.js +++ b/src/userSync.js @@ -208,7 +208,7 @@ export function newUserSync(userSyncDependencies) { * @returns {boolean} true => config is setup correctly, false => setup incorrectly or filterConfig[type] is not present */ function isFilterConfigValid(filterConfig, type) { - if(!filterConfig) { + if (!filterConfig) { return false; } From 91bd039ea1a187e9471d1177e345902e1b1b5a2f Mon Sep 17 00:00:00 2001 From: Jonathan Go Date: Thu, 21 Mar 2019 15:52:45 -0400 Subject: [PATCH 4/5] refactor userSync checking if a bidder can drop a sync pixel to publicAPI function canBidderRegisterSync --- modules/sonobiBidAdapter.js | 10 +- src/userSync.js | 31 ++++--- test/spec/modules/sonobiBidAdapter_spec.js | 8 +- test/spec/userSync_spec.js | 101 +++++++++++++++++++++ 4 files changed, 130 insertions(+), 20 deletions(-) diff --git a/modules/sonobiBidAdapter.js b/modules/sonobiBidAdapter.js index 6c5ac659cd9..5bbc1d27a73 100644 --- a/modules/sonobiBidAdapter.js +++ b/modules/sonobiBidAdapter.js @@ -64,10 +64,10 @@ export const spec = { } // use userSync's internal function to determine if we can drop an iframe sync pixel - if (userSync._shouldBidderBeBlocked('iframe', BIDDER_CODE)) { - payload.ius = 0; - } else { + if (_iframeAllowed()) { payload.ius = 1; + } else { + payload.ius = 0; } if (deepAccess(validBidRequests[0], 'crumbs.pubcid') || deepAccess(validBidRequests[0], 'params.hfa')) { @@ -331,4 +331,8 @@ function outstreamRender(bid) { }); } +function _iframeAllowed() { + return userSync.canBidderRegisterSync('iframe', BIDDER_CODE); +} + registerBidder(spec); diff --git a/src/userSync.js b/src/userSync.js index 26a3bd85d6c..3cbdc58a075 100644 --- a/src/userSync.js +++ b/src/userSync.js @@ -156,13 +156,9 @@ export function newUserSync(userSyncDependencies) { return utils.logWarn(`Number of user syncs exceeded for "${bidder}"`); } - if (usConfig.filterSettings) { - if (shouldBidderBeBlocked(type, bidder)) { - return utils.logWarn(`Bidder '${bidder}' is not permitted to register their userSync ${type} pixels as per filterSettings config.`); - } - // TODO remove this else if code that supports deprecated fields (sometime in 2.x); for now - only run if filterSettings config is not present - } else if (usConfig.enabledBidders && usConfig.enabledBidders.length && usConfig.enabledBidders.indexOf(bidder) < 0) { - return utils.logWarn(`Bidder "${bidder}" not permitted to register their userSync pixels.`); + const canBidderRegisterSync = publicApi.canBidderRegisterSync(type, bidder); + if (!canBidderRegisterSync) { + return utils.logWarn(`Bidder "${bidder}" not permitted to register their "${type}" userSync pixels.`); } // the bidder's pixel has passed all checks and is allowed to register @@ -208,10 +204,6 @@ export function newUserSync(userSyncDependencies) { * @returns {boolean} true => config is setup correctly, false => setup incorrectly or filterConfig[type] is not present */ function isFilterConfigValid(filterConfig, type) { - if (!filterConfig) { - return false; - } - if (filterConfig.all && filterConfig[type]) { utils.logWarn(`Detected presence of the "filterSettings.all" and "filterSettings.${type}" in userSync config. You cannot mix "all" with "iframe/image" configs; they are mutually exclusive.`); return false; @@ -266,8 +258,21 @@ export function newUserSync(userSyncDependencies) { } }; - publicApi._shouldBidderBeBlocked = shouldBidderBeBlocked; - + publicApi.canBidderRegisterSync = (type, bidder) => { + if (usConfig.filterSettings) { + if (shouldBidderBeBlocked(type, bidder)) { + return false; + } + // TODO remove this else if code that supports deprecated fields (sometime in 2.x); for now - only run if filterSettings config is not present + } else if (usConfig.enabledBidders && usConfig.enabledBidders.length && usConfig.enabledBidders.indexOf(bidder) < 0) { + return false + } else if (type === 'iframe' && !(usConfig.iframeEnabled || permittedPixels.iframe)) { + return false; + } else if (type === 'image' && !(usConfig.pixelEnabled || permittedPixels.image)) { + return false; + } + return true; + } return publicApi; } diff --git a/test/spec/modules/sonobiBidAdapter_spec.js b/test/spec/modules/sonobiBidAdapter_spec.js index 808aa2e5b95..26b16390eaf 100644 --- a/test/spec/modules/sonobiBidAdapter_spec.js +++ b/test/spec/modules/sonobiBidAdapter_spec.js @@ -103,10 +103,10 @@ describe('SonobiBidAdapter', function () { describe('.buildRequests', function () { beforeEach(function() { - sinon.stub(userSync, '_shouldBidderBeBlocked'); + sinon.stub(userSync, 'canBidderRegisterSync'); }); afterEach(function() { - userSync._shouldBidderBeBlocked.restore(); + userSync.canBidderRegisterSync.restore(); }); let bidRequest = [{ 'bidder': 'sonobi', @@ -312,13 +312,13 @@ describe('SonobiBidAdapter', function () { }) it('should set ius as 0 if Sonobi cannot drop iframe pixels', function () { - userSync._shouldBidderBeBlocked.returns(true); + userSync.canBidderRegisterSync.returns(false); const bidRequests = spec.buildRequests(bidRequest, bidderRequests); expect(bidRequests.data.ius).to.equal(0); }); it('should set ius as 1 if Sonobi can drop iframe pixels', function() { - userSync._shouldBidderBeBlocked.returns(false); + userSync.canBidderRegisterSync.returns(true); const bidRequests = spec.buildRequests(bidRequest, bidderRequests); expect(bidRequests.data.ius).to.equal(1); }); diff --git a/test/spec/userSync_spec.js b/test/spec/userSync_spec.js index dfe6372288f..f330be4c2f4 100644 --- a/test/spec/userSync_spec.js +++ b/test/spec/userSync_spec.js @@ -355,4 +355,105 @@ describe('user sync', function () { expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.equal('http://example.com/1'); expect(insertUserSyncIframeStub.getCall(0)).to.be.null; }); + + describe('publicAPI', function () { + describe('canBidderRegisterSync', function() { + describe('with filterSettings', function() { + it('should return false if filter settings does not allow it', function () { + const userSync = newUserSync({ + config: { + filterSettings: { + image: { + bidders: '*', + filter: 'include' + }, + iframe: { + bidders: ['testBidder'], + filter: 'include' + } + } + } + }); + expect(userSync.canBidderRegisterSync('iframe', 'otherTestBidder')).to.equal(false); + }); + it('should return true if filter settings does allow it', function () { + const userSync = newUserSync({ + config: { + filterSettings: { + image: { + bidders: '*', + filter: 'include' + }, + iframe: { + bidders: ['testBidder'], + filter: 'include' + } + } + } + }); + expect(userSync.canBidderRegisterSync('iframe', 'testBidder')).to.equal(true); + }); + }); + describe('almost deprecated - without filterSettings', function() { + describe('enabledBidders contains testBidder', function() { + it('should return false if type is iframe and iframeEnabled is false', function () { + const userSync = newUserSync({ + config: { + pixelEnabled: true, + iframeEnabled: false, + enabledBidders: ['testBidder'], + } + }); + expect(userSync.canBidderRegisterSync('iframe', 'testBidder')).to.equal(false); + }); + + it('should return true if type is iframe and iframeEnabled is true', function () { + const userSync = newUserSync({ + config: { + pixelEnabled: true, + iframeEnabled: true, + enabledBidders: ['testBidder'], + } + }); + expect(userSync.canBidderRegisterSync('iframe', 'testBidder')).to.equal(true); + }); + + it('should return false if type is image and pixelEnabled is false', function () { + const userSync = newUserSync({ + config: { + pixelEnabled: false, + iframeEnabled: true, + enabledBidders: ['testBidder'], + } + }); + expect(userSync.canBidderRegisterSync('image', 'testBidder')).to.equal(false); + }); + + it('should return true if type is image and pixelEnabled is true', function () { + const userSync = newUserSync({ + config: { + pixelEnabled: true, + iframeEnabled: true, + enabledBidders: ['testBidder'], + } + }); + expect(userSync.canBidderRegisterSync('image', 'testBidder')).to.equal(true); + }); + }); + + describe('enabledBidders does not container testBidder', function() { + it('should return false since testBidder is not in enabledBidders', function() { + const userSync = newUserSync({ + config: { + pixelEnabled: true, + iframeEnabled: true, + enabledBidders: ['otherTestBidder'], + } + }); + expect(userSync.canBidderRegisterSync('iframe', 'testBidder')).to.equal(false); + }); + }); + }); + }); + }); }); From f3917fa9c56c044d5139d2fd299efed76e144203 Mon Sep 17 00:00:00 2001 From: Jonathan Go Date: Tue, 9 Apr 2019 11:25:16 -0400 Subject: [PATCH 5/5] fixed lint error --- modules/sonobiBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/sonobiBidAdapter.js b/modules/sonobiBidAdapter.js index 87674d998ba..a82d19a485c 100644 --- a/modules/sonobiBidAdapter.js +++ b/modules/sonobiBidAdapter.js @@ -62,7 +62,7 @@ export const spec = { if (config.getConfig('userSync') && config.getConfig('userSync').syncsPerBidder) { payload.us = config.getConfig('userSync').syncsPerBidder; } - + // use userSync's internal function to determine if we can drop an iframe sync pixel if (_iframeAllowed()) { payload.ius = 1;