From 265a8a9b6fbcff24fbc7caabbb2df6113efc100d Mon Sep 17 00:00:00 2001 From: Rich Snapp Date: Mon, 30 Oct 2017 06:38:20 -0600 Subject: [PATCH] Change prebidServer to call client user syncs if they exist (#1734) --- modules/prebidServerBidAdapter.js | 8 +++++ modules/rubiconBidAdapter.js | 4 +-- src/adaptermanager.js | 4 +++ src/adapters/bidderFactory.js | 33 +++++++++++-------- .../modules/prebidServerBidAdapter_spec.js | 18 ++++++++++ test/spec/modules/rubiconBidAdapter_spec.js | 9 +++-- 6 files changed, 58 insertions(+), 18 deletions(-) diff --git a/modules/prebidServerBidAdapter.js b/modules/prebidServerBidAdapter.js index 89a59fa7c67..7120d67eb56 100644 --- a/modules/prebidServerBidAdapter.js +++ b/modules/prebidServerBidAdapter.js @@ -183,6 +183,14 @@ function PrebidServer() { }); } + // do client-side syncs if available + requestedBidders.forEach(bidder => { + let clientAdapter = adaptermanager.getBidAdapter(bidder); + if (clientAdapter && clientAdapter.registerSyncs) { + clientAdapter.registerSyncs(); + } + }); + if (result.bids) { result.bids.forEach(bidObj => { let bidRequest = utils.getBidRequest(bidObj.bid_id); diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index 866e02bc258..2830711a4c9 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -287,8 +287,8 @@ export const spec = { return bids; }, []); }, - getUserSyncs: function() { - if (!hasSynced) { + getUserSyncs: function(syncOptions) { + if (!hasSynced && syncOptions.iframeEnabled) { hasSynced = true; return { type: 'iframe', diff --git a/src/adaptermanager.js b/src/adaptermanager.js index 37ab5dffafb..34866365445 100644 --- a/src/adaptermanager.js +++ b/src/adaptermanager.js @@ -325,6 +325,10 @@ exports.setBidderSequence = function (order) { } }; +exports.getBidAdapter = function(bidder) { + return _bidderRegistry[bidder]; +}; + exports.setS2SConfig = function (config) { _s2sConfig = config; }; diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index 241891640c5..9641c4c484b 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -154,6 +154,7 @@ export function newBidder(spec) { getSpec: function() { return Object.freeze(spec); }, + registerSyncs, callBids: function(bidderRequest) { if (!Array.isArray(bidderRequest.bids)) { return; @@ -195,20 +196,7 @@ export function newBidder(spec) { const responses = []; function afterAllResponses() { fillNoBids(); - if (spec.getUserSyncs) { - let syncs = spec.getUserSyncs({ - iframeEnabled: config.getConfig('userSync.iframeEnabled'), - pixelEnabled: config.getConfig('userSync.pixelEnabled'), - }, responses); - if (syncs) { - if (!Array.isArray(syncs)) { - syncs = [syncs]; - } - syncs.forEach((sync) => { - userSync.registerSync(sync.type, spec.code, sync.url) - }); - } - } + registerSyncs(responses); } const validBidRequests = bidderRequest.bids.filter(filterAndWarn); @@ -337,6 +325,23 @@ export function newBidder(spec) { } }); + function registerSyncs(responses) { + if (spec.getUserSyncs) { + let syncs = spec.getUserSyncs({ + iframeEnabled: config.getConfig('userSync.iframeEnabled'), + pixelEnabled: config.getConfig('userSync.pixelEnabled'), + }, responses); + if (syncs) { + if (!Array.isArray(syncs)) { + syncs = [syncs]; + } + syncs.forEach((sync) => { + userSync.registerSync(sync.type, spec.code, sync.url) + }); + } + } + } + function filterAndWarn(bid) { if (!spec.isBidRequestValid(bid)) { logWarn(`Invalid bid sent to bidder ${spec.code}: ${JSON.stringify(bid)}`); diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js index 21098a2859f..78eef4b016b 100644 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -1,5 +1,6 @@ import { expect } from 'chai'; import Adapter from 'modules/prebidServerBidAdapter'; +import adapterManager from 'src/adaptermanager'; import bidmanager from 'src/bidmanager'; import CONSTANTS from 'src/constants.json'; import * as utils from 'src/utils'; @@ -353,6 +354,23 @@ describe('S2S Adapter', () => { expect(response).to.have.property('adserverTargeting').that.deep.equals({'foo': 'bar'}); }); + it('registers client user syncs when client bid adapter is present', () => { + let rubiconAdapter = { + registerSyncs: sinon.spy() + }; + sinon.stub(adapterManager, 'getBidAdapter', () => rubiconAdapter); + + server.respondWith(JSON.stringify(RESPONSE_NO_PBS_COOKIE)); + + adapter.setConfig(CONFIG); + adapter.callBids(REQUEST); + server.respond(); + + sinon.assert.calledOnce(rubiconAdapter.registerSyncs); + + adapterManager.getBidAdapter.restore(); + }); + it('registers bid responses when server requests cookie sync', () => { server.respondWith(JSON.stringify(RESPONSE_NO_PBS_COOKIE)); diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js index 6c08c66f485..f77391dffe2 100644 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -4,6 +4,7 @@ import { spec, masSizeOrdering, resetUserSync } from 'modules/rubiconBidAdapter' import { parse as parseQuery } from 'querystring'; import { newBidder } from 'src/adapters/bidderFactory'; import { userSync } from 'src/userSync'; +import { config } from 'src/config'; var CONSTANTS = require('src/constants.json'); @@ -779,13 +780,17 @@ describe('the rubicon adapter', () => { }); it('should register the Emily iframe', () => { - let syncs = spec.getUserSyncs(); + let syncs = spec.getUserSyncs({ + iframeEnabled: true + }); expect(syncs).to.deep.equal({type: 'iframe', url: emilyUrl}); }); it('should not register the Emily iframe more than once', () => { - let syncs = spec.getUserSyncs(); + let syncs = spec.getUserSyncs({ + iframeEnabled: true + }); expect(syncs).to.deep.equal({type: 'iframe', url: emilyUrl}); // when called again, should still have only been called once