diff --git a/modules/33acrossBidAdapter.js b/modules/33acrossBidAdapter.js index b496a66d081..8e73d5c87b4 100644 --- a/modules/33acrossBidAdapter.js +++ b/modules/33acrossBidAdapter.js @@ -1,5 +1,6 @@ +import { userSync } from 'src/userSync' const { registerBidder } = require('../src/adapters/bidderFactory'); -const utils = require('../src/utils'); +const { config } = require('../src/config'); const BIDDER_CODE = '33across'; const END_POINT = 'https://ssc.33across.com/api/v1/hb'; @@ -38,9 +39,7 @@ function _createServerRequest(bidRequest) { } } - // Allowing site to be a test configuration object or just the id (former required for testing, - // latter when used by publishers) - ttxRequest.site = params.site || { id: params.siteId }; + ttxRequest.site = { id: params.siteId }; // Go ahead send the bidId in request to 33exchange so it's kept track of in the bid response and // therefore in ad targetting process @@ -51,28 +50,18 @@ function _createServerRequest(bidRequest) { withCredentials: false }; - if (bidRequest.params.customHeaders) { - options.customHeaders = bidRequest.params.customHeaders; - } + // Allow the ability to configure the HB endpoint for testing purposes. + const ttxSettings = config.getConfig('ttxSettings'); + const url = (ttxSettings && ttxSettings.url) || END_POINT; return { 'method': 'POST', - 'url': bidRequest.params.url || END_POINT, + 'url': url, 'data': JSON.stringify(ttxRequest), 'options': options } } -// Sync object will always be of type iframe for ttx -function _createSync(bid) { - const syncUrl = bid.params.syncUrl || SYNC_ENDPOINT; - - return { - type: 'iframe', - url: `${syncUrl}&id=${bid.params.siteId || bid.params.site.id}` - } -} - function _getFormatSize(sizeArr) { return { w: sizeArr[0], @@ -81,6 +70,24 @@ function _getFormatSize(sizeArr) { } } +// Register one sync per bid since each ad unit may potenitally be linked to a uniqe guid +// Sync type will always be 'iframe' for 33Across +function _registerUserSyncs(requestData) { + let ttxRequest; + try { + ttxRequest = JSON.parse(requestData); + } catch (err) { + // No point in trying to register sync since the requisite data cannot be parsed. + return; + } + const ttxSettings = config.getConfig('ttxSettings'); + + let syncUrl = (ttxSettings && ttxSettings.syncUrl) || SYNC_ENDPOINT; + + syncUrl = `${syncUrl}&id=${ttxRequest.site.id}`; + userSync.registerSync('iframe', BIDDER_CODE, syncUrl); +} + function isBidRequestValid(bid) { if (bid.bidder !== BIDDER_CODE || typeof bid.params === 'undefined') { return false; @@ -104,7 +111,12 @@ function buildRequests(bidRequests) { } // NOTE: At this point, the response from 33exchange will only ever contain one bid i.e. the highest bid -function interpretResponse(serverResponse) { +function interpretResponse(serverResponse, bidRequest) { + // Register user sync first + if (bidRequest && bidRequest.data) { + _registerUserSyncs(bidRequest.data); + } + const bidResponses = []; // If there are bids, look at the first bid of the first seatbid (see NOTE above for assumption about ttx) @@ -115,24 +127,11 @@ function interpretResponse(serverResponse) { return bidResponses; } -// Register one sync per bid since each ad unit may potenitally be linked to a uniqe guid -function getUserSyncs(syncOptions) { - let syncs = []; - const ttxBidRequests = utils.getBidderRequestAllAdUnits(BIDDER_CODE).bids; - - if (syncOptions.iframeEnabled) { - syncs = ttxBidRequests.map(_createSync); - } - - return syncs; -} - const spec = { code: BIDDER_CODE, isBidRequestValid, buildRequests, - interpretResponse, - getUserSyncs + interpretResponse } registerBidder(spec); diff --git a/test/spec/modules/33acrossBidAdapter_spec.js b/test/spec/modules/33acrossBidAdapter_spec.js index 3c25aee4199..4754e4d1fa5 100644 --- a/test/spec/modules/33acrossBidAdapter_spec.js +++ b/test/spec/modules/33acrossBidAdapter_spec.js @@ -1,12 +1,21 @@ +const { userSync } = require('../../../src/userSync'); +const { config } = require('../../../src/config'); + const { expect } = require('chai'); -const utils = require('../../../src/utils'); -const { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } = require('../../../modules/33acrossBidAdapter'); + +const { + isBidRequestValid, + buildRequests, + interpretResponse, + getUserSyncs +} = require('../../../modules/33acrossBidAdapter'); describe('33acrossBidAdapter:', function () { const BIDDER_CODE = '33across'; const SITE_ID = 'pub1234'; const PRODUCT_ID = 'product1'; const END_POINT = 'https://ssc.33across.com/api/v1/hb'; + const SYNC_ENDPOINT = 'https://de.tynt.com/deb/v2?m=xch'; beforeEach(function() { this.bidRequests = [ @@ -21,12 +30,12 @@ describe('33acrossBidAdapter:', function () { adUnitCode: 'div-id', requestId: 'r1', sizes: [ - [300, 250], - [728, 90] + [ 300, 250 ], + [ 728, 90 ] ], transactionId: 't1' } - ] + ]; this.sandbox = sinon.sandbox.create(); }); @@ -113,7 +122,7 @@ describe('33acrossBidAdapter:', function () { describe('buildRequests:', function() { it('returns corresponding server requests for each valid bidRequest', function() { const ttxRequest = { - imp: [{ + imp: [ { banner: { format: [ { @@ -133,7 +142,7 @@ describe('33acrossBidAdapter:', function () { prod: PRODUCT_ID } } - }], + } ], site: { id: SITE_ID }, @@ -149,23 +158,19 @@ describe('33acrossBidAdapter:', function () { } } const builtServerRequests = buildRequests(this.bidRequests); - expect(builtServerRequests).to.deep.equal([serverRequest]); + expect(builtServerRequests).to.deep.equal([ serverRequest ]); expect(builtServerRequests.length).to.equal(1); }); - it('returns corresponding server requests for each valid test bidRequest', function() { - delete this.bidRequests[0].params.siteId; - this.bidRequests[0].params.site = { - id: SITE_ID, - page: 'http://test-url.com' - } - this.bidRequests[0].params.customHeaders = { - foo: 'bar' - }; - this.bidRequests[0].params.url = '//staging-ssc.33across.com/api/v1/hb'; + it('returns corresponding test server requests for each valid bidRequest', function() { + this.sandbox.stub(config, 'getConfig', () => { + return { + 'url': 'https://foo.com/hb/' + } + }); const ttxRequest = { - imp: [{ + imp: [ { banner: { format: [ { @@ -185,28 +190,24 @@ describe('33acrossBidAdapter:', function () { prod: PRODUCT_ID } } - }], + } ], site: { - id: SITE_ID, - page: 'http://test-url.com' + id: SITE_ID }, id: 'b1' }; const serverRequest = { method: 'POST', - url: '//staging-ssc.33across.com/api/v1/hb', + url: 'https://foo.com/hb/', data: JSON.stringify(ttxRequest), options: { contentType: 'application/json', - withCredentials: false, - customHeaders: { - foo: 'bar' - } + withCredentials: false } }; const builtServerRequests = buildRequests(this.bidRequests); - expect(builtServerRequests).to.deep.equal([serverRequest]); + expect(builtServerRequests).to.deep.equal([ serverRequest ]); expect(builtServerRequests.length).to.equal(1); }); @@ -216,6 +217,46 @@ describe('33acrossBidAdapter:', function () { }); describe('interpretResponse', function() { + beforeEach(function() { + this.ttxRequest = { + imp: [ { + banner: { + format: [ + { + w: 300, + h: 250, + ext: {} + }, + { + w: 728, + h: 90, + ext: {} + } + ] + }, + ext: { + ttx: { + prod: PRODUCT_ID + } + } + } ], + site: { + id: SITE_ID, + page: 'http://test-url.com' + }, + id: 'b1' + }; + this.serverRequest = { + method: 'POST', + url: '//staging-ssc.33across.com/api/v1/hb', + data: JSON.stringify(this.ttxRequest), + options: { + contentType: 'application/json', + withCredentials: false + } + }; + }); + context('when exactly one bid is returned', function() { it('interprets and returns the single bid response', function() { const serverResponse = { @@ -224,7 +265,7 @@ describe('33acrossBidAdapter:', function () { id: 'b1', seatbid: [ { - bid: [{ + bid: [ { id: '1', adm: '