diff --git a/modules/livewrappedAnalyticsAdapter.js b/modules/livewrappedAnalyticsAdapter.js index 47f7f60d141..b331448161e 100644 --- a/modules/livewrappedAnalyticsAdapter.js +++ b/modules/livewrappedAnalyticsAdapter.js @@ -16,8 +16,7 @@ let initOptions; export const BID_WON_TIMEOUT = 500; const cache = { - auctions: {}, - bidAdUnits: {} + auctions: {} }; let livewrappedAnalyticsAdapter = Object.assign(adapter({EMPTYURL, ANALYTICSTYPE}), { @@ -28,7 +27,7 @@ let livewrappedAnalyticsAdapter = Object.assign(adapter({EMPTYURL, ANALYTICSTYPE switch (eventType) { case CONSTANTS.EVENTS.AUCTION_INIT: utils.logInfo('LIVEWRAPPED_AUCTION_INIT:', args); - cache.auctions[args.auctionId] = {bids: {}}; + cache.auctions[args.auctionId] = {bids: {}, bidAdUnits: {}}; break; case CONSTANTS.EVENTS.BID_REQUESTED: utils.logInfo('LIVEWRAPPED_BID_REQUESTED:', args); @@ -64,8 +63,12 @@ let livewrappedAnalyticsAdapter = Object.assign(adapter({EMPTYURL, ANALYTICSTYPE if (!bidResponse.ttr) { bidResponse.ttr = time - bidResponse.start; } - if (!cache.bidAdUnits[bidResponse.adUnit]) { - cache.bidAdUnits[bidResponse.adUnit] = {sent: 0, timeStamp: cache.auctions[args.auctionId].timeStamp}; + if (!cache.auctions[args.auctionId].bidAdUnits[bidResponse.adUnit]) { + cache.auctions[args.auctionId].bidAdUnits[bidResponse.adUnit] = + { + sent: 0, + timeStamp: cache.auctions[args.auctionId].timeStamp + }; } break; case CONSTANTS.EVENTS.BIDDER_DONE: @@ -240,16 +243,19 @@ function getTimeouts() { function getbidAdUnits() { var bidAdUnits = []; - Object.keys(cache.bidAdUnits).forEach(adUnit => { - let bidAdUnit = cache.bidAdUnits[adUnit]; - if (!bidAdUnit.sent) { - bidAdUnit.sent = 1; - - bidAdUnits.push({ - adUnit: adUnit, - timeStamp: bidAdUnit.timeStamp - }); - } + Object.keys(cache.auctions).forEach(auctionId => { + let auction = cache.auctions[auctionId]; + Object.keys(auction.bidAdUnits).forEach(adUnit => { + let bidAdUnit = auction.bidAdUnits[adUnit]; + if (!bidAdUnit.sent) { + bidAdUnit.sent = 1; + + bidAdUnits.push({ + adUnit: adUnit, + timeStamp: bidAdUnit.timeStamp + }); + } + }); }); return bidAdUnits; diff --git a/modules/livewrappedBidAdapter.js b/modules/livewrappedBidAdapter.js index 5a9ef302d51..57e5a5a7c2f 100644 --- a/modules/livewrappedBidAdapter.js +++ b/modules/livewrappedBidAdapter.js @@ -9,7 +9,7 @@ export const storage = getStorageManager(); const BIDDER_CODE = 'livewrapped'; export const URL = 'https://lwadm.com/ad'; -const VERSION = '1.2'; +const VERSION = '1.3'; export const spec = { code: BIDDER_CODE, @@ -29,6 +29,7 @@ export const spec = { * seats: List of bidders and seats Optional. {"bidder name": ["seat 1", "seat 2"], ...} * deviceId: Device id if available Optional. * ifa: Advertising ID Optional. + * bundle: App bundle Optional. Read from config if exists. * options Dynamic data Optional. Optional data to send into adapter. * * @param {BidRequest} bid The bid params to validate. @@ -55,9 +56,10 @@ export const spec = { const seats = find(bidRequests, hasSeatsParam); const deviceId = find(bidRequests, hasDeviceIdParam); const ifa = find(bidRequests, hasIfaParam); + const bundle = find(bidRequests, hasBundleParam); const tid = find(bidRequests, hasTidParam); bidUrl = bidUrl ? bidUrl.params.bidUrl : URL; - url = url ? url.params.url : getTopWindowLocation(bidderRequest); + url = url ? url.params.url : (getAppDomain() || getTopWindowLocation(bidderRequest)); test = test ? test.params.test : undefined; var adRequests = bidRequests.map(bidToAdRequest); @@ -69,7 +71,10 @@ export const spec = { test: test, seats: seats ? seats.params.seats : undefined, deviceId: deviceId ? deviceId.params.deviceId : undefined, - ifa: ifa ? ifa.params.ifa : undefined, + ifa: ifa ? ifa.params.ifa : getDeviceIfa(), + bundle: bundle ? bundle.params.bundle : getAppBundle(), + width: getDeviceWidth(), + height: getDeviceHeight(), tid: tid ? tid.params.tid : undefined, version: VERSION, gdprApplies: bidderRequest.gdprConsent ? bidderRequest.gdprConsent.gdprApplies : undefined, @@ -178,6 +183,10 @@ function hasIfaParam(bid) { return !!bid.params.ifa; } +function hasBundleParam(bid) { + return !!bid.params.bundle; +} + function hasTidParam(bid) { return !!bid.params.tid; } @@ -264,4 +273,40 @@ function getTopWindowLocation(bidderRequest) { return config.getConfig('pageUrl') || url; } +function getAppBundle() { + if (typeof config.getConfig('app') === 'object') { + return config.getConfig('app').bundle; + } +} + +function getAppDomain() { + if (typeof config.getConfig('app') === 'object') { + return config.getConfig('app').domain; + } +} + +function getDeviceIfa() { + if (typeof config.getConfig('device') === 'object') { + return config.getConfig('device').ifa; + } +} + +function getDeviceWidth() { + let device = config.getConfig('device'); + if (typeof device === 'object' && device.width) { + return device.width; + } + + return window.innerWidth; +} + +function getDeviceHeight() { + let device = config.getConfig('device'); + if (typeof device === 'object' && device.height) { + return device.height; + } + + return window.innerHeight; +} + registerBidder(spec); diff --git a/test/spec/modules/livewrappedBidAdapter_spec.js b/test/spec/modules/livewrappedBidAdapter_spec.js index 7b26f5b533d..b82bf8db160 100644 --- a/test/spec/modules/livewrappedBidAdapter_spec.js +++ b/test/spec/modules/livewrappedBidAdapter_spec.js @@ -100,7 +100,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', @@ -135,7 +137,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', @@ -171,7 +175,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ callerAdUnitId: 'caller id 1', @@ -200,7 +206,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ callerAdUnitId: 'panorama_d_1', @@ -228,7 +236,9 @@ describe('Livewrapped adapter tests', function () { let expectedQuery = { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', @@ -258,7 +268,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, deviceId: 'deviceid', ifa: 'ifa', cookieSupport: true, @@ -289,7 +301,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, tid: 'tracking id', test: true, cookieSupport: true, @@ -319,7 +333,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ callerAdUnitId: 'panorama_d_1', @@ -348,7 +364,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, rcv: true, adRequests: [{ @@ -377,7 +395,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ callerAdUnitId: 'panorama_d_1', @@ -406,7 +426,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ callerAdUnitId: 'panorama_d_1', @@ -421,6 +443,53 @@ describe('Livewrapped adapter tests', function () { expect(data).to.deep.equal(expectedQuery); }); + it('should use app objects', function() { + sandbox.stub(utils, 'isSafariBrowser').callsFake(() => false); + sandbox.stub(storage, 'cookiesAreEnabled').callsFake(() => true); + + let testbidRequest = clone(bidderRequest); + delete testbidRequest.bids[0].params.url; + + let origGetConfig = config.getConfig; + sandbox.stub(config, 'getConfig').callsFake(function (key) { + if (key === 'app') { + return {bundle: 'bundle', domain: 'https://appdomain.com'}; + } + if (key === 'device') { + return {ifa: 'ifa', width: 300, height: 200}; + } + return origGetConfig.apply(config, arguments); + }); + + let result = spec.buildRequests(testbidRequest.bids, testbidRequest); + let data = JSON.parse(result.data); + + expect(result.url).to.equal('https://lwadm.com/ad'); + + let expectedQuery = { + auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', + publisherId: '26947112-2289-405D-88C1-A7340C57E63E', + userId: 'user id', + url: 'https://appdomain.com', + seats: {'dsp': ['seat 1']}, + version: '1.3', + width: 300, + height: 200, + ifa: 'ifa', + bundle: 'bundle', + cookieSupport: true, + adRequests: [{ + adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', + callerAdUnitId: 'panorama_d_1', + bidId: '2ffb201a808da7', + transactionId: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D', + formats: [{width: 980, height: 240}, {width: 980, height: 120}] + }] + }; + + expect(data).to.deep.equal(expectedQuery); + }); + it('should use mediaTypes.banner.sizes before legacy sizes', function() { sandbox.stub(utils, 'isSafariBrowser').callsFake(() => false); sandbox.stub(storage, 'cookiesAreEnabled').callsFake(() => true); @@ -436,7 +505,9 @@ describe('Livewrapped adapter tests', function () { auctionId: 'F7557995-65F5-4682-8782-7D5D34D82A8C', publisherId: '26947112-2289-405D-88C1-A7340C57E63E', url: 'https://www.domain.com', - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ callerAdUnitId: 'panorama_d_1', @@ -468,7 +539,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, gdprApplies: true, gdprConsent: 'test', @@ -502,7 +575,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, gdprApplies: false, adRequests: [{ @@ -531,7 +606,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: false, adRequests: [{ adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', @@ -559,7 +636,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: false, adRequests: [{ adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', @@ -620,7 +699,9 @@ describe('Livewrapped adapter tests', function () { userId: 'pubcid 123', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', @@ -650,7 +731,9 @@ describe('Livewrapped adapter tests', function () { userId: 'user id', url: 'https://www.domain.com', seats: {'dsp': ['seat 1']}, - version: '1.2', + version: '1.3', + width: 100, + height: 100, cookieSupport: true, adRequests: [{ adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37',