diff --git a/modules/livewrappedAnalyticsAdapter.js b/modules/livewrappedAnalyticsAdapter.js index d15577e215b..75d4e90fded 100644 --- a/modules/livewrappedAnalyticsAdapter.js +++ b/modules/livewrappedAnalyticsAdapter.js @@ -60,6 +60,7 @@ let livewrappedAnalyticsAdapter = Object.assign(adapter({EMPTYURL, ANALYTICSTYPE bidResponse.cpm = args.cpm; bidResponse.ttr = args.timeToRespond; bidResponse.readyToSend = 1; + bidResponse.mediaType = args.mediaType == 'native' ? 2 : 1; if (!bidResponse.ttr) { bidResponse.ttr = time - bidResponse.start; } @@ -129,7 +130,7 @@ livewrappedAnalyticsAdapter.sendEvents = function() { return; } - ajax(URL, undefined, JSON.stringify(events), {method: 'POST'}); + ajax(initOptions.endpoint || URL, undefined, JSON.stringify(events), {method: 'POST'}); } function getAdblockerRecovered() { @@ -178,7 +179,8 @@ function getResponses() { height: bid.height, cpm: bid.cpm, ttr: bid.ttr, - IsBid: bid.isBid + IsBid: bid.isBid, + mediaType: bid.mediaType }); } }); @@ -204,6 +206,7 @@ function getWins() { width: bid.width, height: bid.height, cpm: bid.cpm, + mediaType: bid.mediaType }); } }); diff --git a/modules/livewrappedBidAdapter.js b/modules/livewrappedBidAdapter.js index c5c71a4131e..4dfd25c1fcd 100644 --- a/modules/livewrappedBidAdapter.js +++ b/modules/livewrappedBidAdapter.js @@ -193,19 +193,17 @@ function bidToAdRequest(bid) { options: bid.params.options }; - if (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.native) { - adRequest.banner = true; - } + adRequest.native = utils.deepAccess(bid, 'mediaTypes.native'); - if (bid.mediaTypes && bid.mediaTypes.native) { - adRequest.native = bid.mediaTypes.native; + if (adRequest.native && utils.deepAccess(bid, 'mediaTypes.banner')) { + adRequest.banner = true; } return adRequest; } function getSizes(bid) { - if (typeof utils.deepAccess(bid, 'mediaTypes.banner.sizes') !== 'undefined') { + if (utils.deepAccess(bid, 'mediaTypes.banner.sizes')) { return bid.mediaTypes.banner.sizes; } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) { return bid.sizes; diff --git a/modules/nextrollBidAdapter.js b/modules/nextrollBidAdapter.js index d371448e195..7fcf14410be 100644 --- a/modules/nextrollBidAdapter.js +++ b/modules/nextrollBidAdapter.js @@ -11,6 +11,9 @@ const PUBTAG_URL = 'https://s.adroll.com/prebid/pubtag.min.js'; const MAX_PUBTAG_AGE_IN_DAYS = 3; const ADAPTER_VERSION = 3; +const PUBTAG_STORAGE_KEY = 'nextroll_fast_bid'; +const DATE_SUFFIX = '_set_date'; + export const PUBTAG_PUBKEY = `-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/TZ6Gpm7gYg0j6o8LK+sKfYsl +Z3vY2flsA/KFllKyXKTTtC2nJSJlSTuNToIcXnW+2L3Q2V3yM8VExfhCtVg5oZd @@ -248,22 +251,21 @@ function _parseUrl(url) { /** * @return {boolean} */ -function tryGetPubtag() { - const pubtagStorageKey = 'nextroll_fast_bid'; - const dateSuffix = '_set_date'; +export function tryGetPubtag() { const hashPrefix = '// Hash: '; let pubtagFromStorage = null; let pubtagAge = null; try { - pubtagFromStorage = localStorage.getItem(pubtagStorageKey); - pubtagAge = localStorage.getItem(pubtagStorageKey + dateSuffix); + pubtagFromStorage = localStorage.getItem(PUBTAG_STORAGE_KEY); + pubtagAge = localStorage.getItem(PUBTAG_STORAGE_KEY + DATE_SUFFIX); } catch (e) { return; } - if (pubtagStorageKey === null || pubtagAge === null || isPubtagTooOld(pubtagAge)) { + if (PUBTAG_STORAGE_KEY === null || pubtagAge === null || isPubtagTooOld(pubtagAge)) { + removePubtag(); return; } @@ -273,7 +275,7 @@ function tryGetPubtag() { if (firstLine.substr(0, hashPrefix.length) !== hashPrefix) { utils.logWarn('No hash found in Pubtag'); - localStorage.removeItem(pubtagStorageKey); + removePubtag(); } else { // Remove the hash part from the locally stored value const publisherTagHash = firstLine.substr(hashPrefix.length); @@ -283,14 +285,26 @@ function tryGetPubtag() { jsEncrypt.setPublicKey(PUBTAG_PUBKEY); if (jsEncrypt.verify(publisherTag, publisherTagHash, sha256)) { utils.logInfo('Using NextRoll Pubtag'); - eval(publisherTag); // eslint-disable-line no-eval + insertTag(publisherTag); } else { utils.logWarn('Invalid NextRoll Pubtag found'); - localStorage.removeItem(pubtagStorageKey); + removePubtag(); } } } +function insertTag(publisherTag) { + const script = document.createElement('script'); + script.type = 'text/javascript'; + script.text = publisherTag; + utils.insertElement(script); +} + +function removePubtag() { + localStorage.removeItem(PUBTAG_STORAGE_KEY); + localStorage.removeItem(PUBTAG_STORAGE_KEY + DATE_SUFFIX); +} + function isPubtagTooOld(pubtagAge) { const currentDate = (new Date()).getTime(); const ptSetDate = parseInt(pubtagAge); diff --git a/modules/vubleBidAdapter.js b/modules/vubleBidAdapter.js index 288390f01c9..75ad4308db6 100644 --- a/modules/vubleBidAdapter.js +++ b/modules/vubleBidAdapter.js @@ -108,6 +108,13 @@ export const spec = { adUnitCode: bidRequest.adUnitCode }; + if (bidderRequest && bidderRequest.gdprConsent) { + data.gdpr_consent = { + consent_string: bidderRequest.gdprConsent.consentString, + gdpr_applies: (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : true + } + } + return { method: 'POST', url: url, diff --git a/test/spec/modules/livewrappedAnalyticsAdapter_spec.js b/test/spec/modules/livewrappedAnalyticsAdapter_spec.js index 98ed21132e3..2676de0de10 100644 --- a/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +++ b/test/spec/modules/livewrappedAnalyticsAdapter_spec.js @@ -32,6 +32,7 @@ const BID1 = { requestId: '2ecff0db240757', adId: '2ecff0db240757', auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa', + mediaType: 'banner', getStatusCode() { return CONSTANTS.STATUS.GOOD; } @@ -52,6 +53,7 @@ const BID3 = { requestId: '4ecff0db240757', adId: '4ecff0db240757', auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa', + mediaType: 'banner', getStatusCode() { return CONSTANTS.STATUS.NO_BID; } @@ -154,7 +156,8 @@ const ANALYTICS_MESSAGE = { height: 240, cpm: 1.1, ttr: 200, - IsBid: true + IsBid: true, + mediaType: 1 }, { timeStamp: 1519149562216, @@ -164,7 +167,8 @@ const ANALYTICS_MESSAGE = { height: 250, cpm: 2.2, ttr: 300, - IsBid: true + IsBid: true, + mediaType: 1 }, { timeStamp: 1519149562216, @@ -182,7 +186,8 @@ const ANALYTICS_MESSAGE = { bidder: 'livewrapped', width: 980, height: 240, - cpm: 1.1 + cpm: 1.1, + mediaType: 1 }, { timeStamp: 1519149562216, @@ -190,7 +195,8 @@ const ANALYTICS_MESSAGE = { bidder: 'livewrapped', width: 300, height: 250, - cpm: 2.2 + cpm: 2.2, + mediaType: 1 } ] }; @@ -316,4 +322,36 @@ describe('Livewrapped analytics adapter', function () { expect(message.rcv).to.equal(true); }); }); + + describe('when given other endpoint', function () { + adapterManager.registerAnalyticsAdapter({ + code: 'livewrapped', + adapter: livewrappedAnalyticsAdapter + }); + + beforeEach(function () { + adapterManager.enableAnalytics({ + provider: 'livewrapped', + options: { + publisherId: 'CC411485-42BC-4F92-8389-42C503EE38D7', + endpoint: 'https://whitelabeled.com/analytics/10' + } + }); + }); + + afterEach(function () { + livewrappedAnalyticsAdapter.disableAnalytics(); + }); + + it('should call the endpoint', function () { + performStandardAuction(); + + clock.tick(BID_WON_TIMEOUT + 1000); + + expect(server.requests.length).to.equal(1); + let request = server.requests[0]; + + expect(request.url).to.equal('https://whitelabeled.com/analytics/10'); + }); + }); }); diff --git a/test/spec/modules/nextrollBidAdapter_spec.js b/test/spec/modules/nextrollBidAdapter_spec.js index e502face1f0..78d2d5ece11 100644 --- a/test/spec/modules/nextrollBidAdapter_spec.js +++ b/test/spec/modules/nextrollBidAdapter_spec.js @@ -1,7 +1,24 @@ import { expect } from 'chai'; -import { spec } from 'modules/nextrollBidAdapter'; +import { spec, tryGetPubtag } from 'modules/nextrollBidAdapter'; +import * as utils from 'src/utils'; + +const PUBTAG_LOCAL_STORAGE_KEY = 'nextroll_fast_bid'; +const PUBTAG_DATE_SUFFIX = '_set_date' describe('nextrollBidAdapter', function() { + let utilsMock; + beforeEach(function () { + // Remove to avoid side effects + localStorage.removeItem(PUBTAG_LOCAL_STORAGE_KEY); + localStorage.removeItem(PUBTAG_LOCAL_STORAGE_KEY + PUBTAG_DATE_SUFFIX); + utilsMock = sinon.mock(utils); + }); + + afterEach(function() { + global.NextRoll = undefined; + utilsMock.restore(); + }); + let validBid = { bidder: 'nextroll', adUnitCode: 'adunit-code', @@ -133,5 +150,84 @@ describe('nextrollBidAdapter', function() { it('returns an empty list', function () { expect(spec.getUserSyncs({}, {})).to.be.eql([]); }) - }) + }); + + describe('tryGetNextrollPubtag', function () { + const VALID_HASH = 'BPsAzXFFR0bBpo7mqjangJss12ENYlAKM9kUI5mZwJIRtcL2x6vLfwpz1pjdoyTE9FbGNrVl3iMiMmObgkuqagrzkIyoJoyG+/WGd0Pd0sqtPY43pxpgvTnI1JXFLgdUMgLwICrDCqmA6J63oWJgwTb0906AiraSm9cy89PCZ1U='; + const INVALID_HASH = 'invalid'; + const VALID_PUBLISHER_TAG = 'var NextRoll="test value"'; + const INVALID_PUBLISHER_TAG = 'test invalid'; + + it('should verify valid hash with valid publisher tag', function () { + localStorage.setItem(PUBTAG_LOCAL_STORAGE_KEY, '// Hash: ' + VALID_HASH + '\n' + VALID_PUBLISHER_TAG); + localStorage.setItem(PUBTAG_LOCAL_STORAGE_KEY + PUBTAG_DATE_SUFFIX, new Date().getTime()) + + utilsMock.expects('logInfo').withExactArgs('Using NextRoll Pubtag').once(); + utilsMock.expects('logWarn').withExactArgs('No hash found in Pubtag').never(); + utilsMock.expects('logWarn').withExactArgs('Invalid NextRoll Pubtag found').never(); + utilsMock.expects('insertElement').once(); + + tryGetPubtag(); + + expect(localStorage.getItem(PUBTAG_LOCAL_STORAGE_KEY)).to.equals('// Hash: ' + VALID_HASH + '\n' + VALID_PUBLISHER_TAG); + utilsMock.verify(); + }); + + it('should verify valid hash with invalid pubtag', function () { + localStorage.setItem(PUBTAG_LOCAL_STORAGE_KEY, '// Hash: ' + VALID_HASH + '\n' + INVALID_PUBLISHER_TAG); + localStorage.setItem(PUBTAG_LOCAL_STORAGE_KEY + PUBTAG_DATE_SUFFIX, new Date().getTime()) + + utilsMock.expects('logInfo').withExactArgs('Using NextRoll Pubtag').never(); + utilsMock.expects('logWarn').withExactArgs('No hash found in Pubtag').never(); + utilsMock.expects('logWarn').withExactArgs('Invalid NextRoll Pubtag found').once(); + + tryGetPubtag(); + + expect(localStorage.getItem(PUBTAG_LOCAL_STORAGE_KEY)).to.be.null; + utilsMock.verify(); + }); + + it('should verify invalid hash with valid pubtag', function () { + localStorage.setItem(PUBTAG_LOCAL_STORAGE_KEY, '// Hash: ' + INVALID_HASH + '\n' + VALID_PUBLISHER_TAG); + localStorage.setItem(PUBTAG_LOCAL_STORAGE_KEY + PUBTAG_DATE_SUFFIX, new Date().getTime()) + + utilsMock.expects('logInfo').withExactArgs('Using NextRoll Pubtag').never(); + utilsMock.expects('logWarn').withExactArgs('No hash found in Pubtag').never(); + utilsMock.expects('logWarn').withExactArgs('Invalid NextRoll Pubtag found').once(); + + tryGetPubtag(); + + expect(localStorage.getItem(PUBTAG_LOCAL_STORAGE_KEY)).to.be.null; + utilsMock.verify(); + }); + + it('should verify missing hash', function () { + localStorage.setItem(PUBTAG_LOCAL_STORAGE_KEY, VALID_PUBLISHER_TAG); + localStorage.setItem(PUBTAG_LOCAL_STORAGE_KEY + PUBTAG_DATE_SUFFIX, new Date().getTime()) + + utilsMock.expects('logInfo').withExactArgs('Using NextRoll Pubtag').never(); + utilsMock.expects('logWarn').withExactArgs('No hash found in Pubtag').once(); + utilsMock.expects('logWarn').withExactArgs('Invalid NextRoll Pubtag found').never(); + + tryGetPubtag(); + + expect(localStorage.getItem(PUBTAG_LOCAL_STORAGE_KEY)).to.be.null; + utilsMock.verify(); + }); + + it('should verify pubtag age', function () { + let scriptAge = new Date().getTime() - 345600000; // 4 days old + localStorage.setItem(PUBTAG_LOCAL_STORAGE_KEY, VALID_PUBLISHER_TAG); + localStorage.setItem(PUBTAG_LOCAL_STORAGE_KEY + PUBTAG_DATE_SUFFIX, scriptAge); + + utilsMock.expects('logInfo').withExactArgs('Using NextRoll Pubtag').never(); + utilsMock.expects('logWarn').withExactArgs('No hash found in Pubtag').never(); + utilsMock.expects('logWarn').withExactArgs('Invalid NextRoll Pubtag found').never(); + + tryGetPubtag(); + + expect(localStorage.getItem(PUBTAG_LOCAL_STORAGE_KEY)).to.be.null; + utilsMock.verify(); + }); + }); }); diff --git a/test/spec/modules/vubleBidAdapter_spec.js b/test/spec/modules/vubleBidAdapter_spec.js index b00dbca9b01..81e7936809a 100644 --- a/test/spec/modules/vubleBidAdapter_spec.js +++ b/test/spec/modules/vubleBidAdapter_spec.js @@ -202,7 +202,27 @@ describe('VubleAdapter', function () { adUnitCode: '' } }; - let bidderRequest = { + let request4 = { + method: 'POST', + url: 'https://player.mediabong.net/prebid/request', + data: { + width: '640', + height: '360', + pub_id: '3', + zone_id: '3579', + context: 'instream', + floor_price: 0, + url: '', + env: 'net', + bid_id: 'ijkl', + adUnitCode: '', + gdpr_consent: { + consent_string: 'test', + gdpr_applies: true + } + } + }; + let bidderRequest1 = { refererInfo: { referer: 'https://www.vuble.tv/', reachedTop: true, @@ -214,10 +234,17 @@ describe('VubleAdapter', function () { ] } }; + let bidderRequest2 = { + 'gdprConsent': { + consentString: 'test', + gdprApplies: true + } + }; it('must return the right formatted requests', function () { expect(adapter.buildRequests([bid1, bid2])).to.deep.equal([request1, request2]); - expect(adapter.buildRequests([bid3], bidderRequest)).to.deep.equal([request3]); + expect(adapter.buildRequests([bid3], bidderRequest1)).to.deep.equal([request3]); + expect(adapter.buildRequests([bid3], bidderRequest2)).to.deep.equal([request4]); }); });