diff --git a/modules/onetagBidAdapter.js b/modules/onetagBidAdapter.js index 40ef6d596be..b5217e77cd6 100644 --- a/modules/onetagBidAdapter.js +++ b/modules/onetagBidAdapter.js @@ -3,7 +3,7 @@ import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { INSTREAM, OUTSTREAM } from '../src/video.js'; import { Renderer } from '../src/Renderer.js'; -import {find} from '../src/polyfill.js'; +import { find } from '../src/polyfill.js'; import { getStorageManager } from '../src/storageManager.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { deepClone, logError, deepAccess } from '../src/utils.js'; @@ -13,7 +13,7 @@ const USER_SYNC_ENDPOINT = 'https://onetag-sys.com/usync/'; const BIDDER_CODE = 'onetag'; const GVLID = 241; -const storage = getStorageManager({gvlid: GVLID, bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ gvlid: GVLID, bidderCode: BIDDER_CODE }); /** * Determines whether or not the given bid request is valid. @@ -53,7 +53,7 @@ export function isValid(type, bid) { function buildRequests(validBidRequests, bidderRequest) { const payload = { bids: requestsToBids(validBidRequests), - ...getPageInfo() + ...getPageInfo(bidderRequest) }; if (bidderRequest && bidderRequest.gdprConsent) { payload.gdprConsent = { @@ -74,7 +74,10 @@ function buildRequests(validBidRequests, bidderRequest) { if (storage.hasLocalStorage()) { payload.onetagSid = storage.getDataFromLocalStorage('onetag_sid'); } - } catch (e) {} + } catch (e) { } + const connection = navigator.connection || navigator.webkitConnection; + payload.networkConnectionType = (connection && connection.type) ? connection.type : null; + payload.networkEffectiveConnectionType = (connection && connection.effectiveType) ? connection.effectiveType : null; return { method: 'POST', url: ENDPOINT, @@ -112,7 +115,7 @@ function interpretResponse(serverResponse, bidderRequest) { if (bid.mediaType === BANNER) { responseBid.ad = bid.ad; } else if (bid.mediaType === VIDEO) { - const {context, adUnitCode} = find(requestData.bids, (item) => + const { context, adUnitCode } = find(requestData.bids, (item) => item.bidId === bid.requestId && item.type === VIDEO ); @@ -141,7 +144,7 @@ function createRenderer(bid, rendererOptions = {}) { loaded: false }); try { - renderer.setRender(({renderer, width, height, vastXml, adUnitCode}) => { + renderer.setRender(({ renderer, width, height, vastXml, adUnitCode }) => { renderer.push(() => { window.onetag.Player.init({ ...bid, @@ -162,7 +165,6 @@ function createRenderer(bid, rendererOptions = {}) { function getFrameNesting() { let topmostFrame = window; let parent = window.parent; - let currentFrameNesting = 0; try { while (topmostFrame !== topmostFrame.parent) { parent = topmostFrame.parent; @@ -170,13 +172,8 @@ function getFrameNesting() { parent.location.href; topmostFrame = topmostFrame.parent; } - } catch (e) { - currentFrameNesting = parent === topmostFrame.top ? 1 : 2; - } - return { - topmostFrame, - currentFrameNesting - } + } catch (e) { } + return topmostFrame; } function getDocumentVisibility(window) { @@ -197,21 +194,15 @@ function getDocumentVisibility(window) { /** * Returns information about the page needed by the server in an object to be converted in JSON - * @returns {{location: *, referrer: (*|string), masked: *, wWidth: (*|Number), wHeight: (*|Number), sWidth, sHeight, date: string, timeOffset: number}} + * @returns {{location: *, referrer: (*|string), stack: (*|Array.), numIframes: (*|Number), wWidth: (*|Number), wHeight: (*|Number), sWidth, sHeight, date: string, timeOffset: number}} */ -function getPageInfo() { - const { topmostFrame, currentFrameNesting } = getFrameNesting(); +function getPageInfo(bidderRequest) { + const topmostFrame = getFrameNesting(); return { - location: topmostFrame.location.href, - referrer: - topmostFrame.document.referrer !== '' - ? topmostFrame.document.referrer - : null, - ancestorOrigin: - window.location.ancestorOrigins && window.location.ancestorOrigins.length > 0 - ? window.location.ancestorOrigins[window.location.ancestorOrigins.length - 1] - : null, - masked: currentFrameNesting, + location: deepAccess(bidderRequest, 'refererInfo.page', null), + referrer: deepAccess(bidderRequest, 'refererInfo.ref', null), + stack: deepAccess(bidderRequest, 'refererInfo.stack', []), + numIframes: deepAccess(bidderRequest, 'refererInfo.numIframes', 0), wWidth: topmostFrame.innerWidth, wHeight: topmostFrame.innerHeight, oWidth: topmostFrame.outerWidth, @@ -230,7 +221,7 @@ function getPageInfo() { timing: getTiming(), version: { prebid: '$prebid.version$', - adapter: '1.1.0' + adapter: '1.1.1' } }; } @@ -344,7 +335,7 @@ function getSizes(sizes) { const ret = []; for (let i = 0; i < sizes.length; i++) { const size = sizes[i]; - ret.push({width: size[0], height: size[1]}) + ret.push({ width: size[0], height: size[1] }) } return ret; } diff --git a/test/spec/modules/onetagBidAdapter_spec.js b/test/spec/modules/onetagBidAdapter_spec.js index 2dc0a43bbb0..71e897c7f9e 100644 --- a/test/spec/modules/onetagBidAdapter_spec.js +++ b/test/spec/modules/onetagBidAdapter_spec.js @@ -1,8 +1,8 @@ import { spec, isValid, hasTypeVideo, isSchainValid } from 'modules/onetagBidAdapter.js'; import { expect } from 'chai'; -import {find} from 'src/polyfill.js'; +import { find } from 'src/polyfill.js'; import { BANNER, VIDEO } from 'src/mediaTypes.js'; -import {INSTREAM, OUTSTREAM} from 'src/video.js'; +import { INSTREAM, OUTSTREAM } from 'src/video.js'; describe('onetag', function () { function createBid() { @@ -122,14 +122,14 @@ describe('onetag', function () { it('Should return true when correct multi format bid is passed', function () { expect(spec.isBidRequestValid(createMultiFormatBid())).to.be.true; }); - it('Should split multi format bid into two single format bid with same bidId', function() { - const bids = JSON.parse(spec.buildRequests([ createMultiFormatBid() ]).data).bids; + it('Should split multi format bid into two single format bid with same bidId', function () { + const bids = JSON.parse(spec.buildRequests([createMultiFormatBid()]).data).bids; expect(bids.length).to.equal(2); expect(bids[0].bidId).to.equal(bids[1].bidId); }); - it('Should retrieve correct request bid when extracting video request data', function() { + it('Should retrieve correct request bid when extracting video request data', function () { const requestBid = createMultiFormatBid(); - const multiFormatRequest = spec.buildRequests([ requestBid ]); + const multiFormatRequest = spec.buildRequests([requestBid]); const serverResponse = { body: { bids: [ @@ -173,24 +173,30 @@ describe('onetag', function () { const data = JSON.parse(d); it('Should contain all keys', function () { expect(data).to.be.an('object'); - expect(data).to.include.all.keys('location', 'referrer', 'masked', 'sHeight', 'sWidth', 'docHeight', 'wHeight', 'wWidth', 'oHeight', 'oWidth', 'aWidth', 'aHeight', 'sLeft', 'sTop', 'hLength', 'bids', 'docHidden', 'xOffset', 'yOffset', 'timing', 'version'); - expect(data.location).to.be.a('string'); - expect(data.masked).to.be.oneOf([0, 1, 2]); + expect(data).to.include.all.keys('location', 'referrer', 'stack', 'numIframes', 'sHeight', 'sWidth', 'docHeight', 'wHeight', 'wWidth', 'oHeight', 'oWidth', 'aWidth', 'aHeight', 'sLeft', 'sTop', 'hLength', 'bids', 'docHidden', 'xOffset', 'yOffset', 'networkConnectionType', 'networkEffectiveConnectionType', 'timing', 'version'); + expect(data.location).to.satisfy(function (value) { + return value === null || typeof value === 'string'; + }); expect(data.referrer).to.satisfy(referrer => referrer === null || typeof referrer === 'string'); + expect(data.stack).to.be.an('array'); + expect(data.numIframes).to.be.a('number'); expect(data.sHeight).to.be.a('number'); expect(data.sWidth).to.be.a('number'); expect(data.wWidth).to.be.a('number'); expect(data.wHeight).to.be.a('number'); expect(data.oHeight).to.be.a('number'); expect(data.oWidth).to.be.a('number'); - expect(data.ancestorOrigin).to.satisfy(function (value) { - return value === null || typeof value === 'string'; - }); expect(data.aWidth).to.be.a('number'); expect(data.aHeight).to.be.a('number'); expect(data.sLeft).to.be.a('number'); expect(data.sTop).to.be.a('number'); expect(data.hLength).to.be.a('number'); + expect(data.networkConnectionType).to.satisfy(function (value) { + return value === null || typeof value === 'string' + }); + expect(data.networkEffectiveConnectionType).to.satisfy(function (value) { + return value === null || typeof value === 'string' + }); expect(data.bids).to.be.an('array'); expect(data.version).to.have.all.keys('prebid', 'adapter'); const bids = data['bids']; @@ -231,14 +237,14 @@ describe('onetag', function () { expect(bid.pubId).to.be.a('string'); } }); - } catch (e) {} + } catch (e) { } it('Returns empty data if no valid requests are passed', function () { serverRequest = spec.buildRequests([]); let dataString = serverRequest.data; try { let dataObj = JSON.parse(dataString); expect(dataObj.bids).to.be.an('array').that.is.empty; - } catch (e) {} + } catch (e) { } }); it('should send GDPR consent data', function () { let consentString = 'consentString'; @@ -287,7 +293,7 @@ describe('onetag', function () { let dataItem = interpretedResponse[i]; expect(dataItem).to.include.all.keys('requestId', 'cpm', 'width', 'height', 'ttl', 'creativeId', 'netRevenue', 'currency', 'meta', 'dealId'); if (dataItem.meta.mediaType === VIDEO) { - const {context} = find(requestData.bids, (item) => item.bidId === dataItem.requestId); + const { context } = find(requestData.bids, (item) => item.bidId === dataItem.requestId); if (context === INSTREAM) { expect(dataItem).to.include.all.keys('videoCacheKey', 'vastUrl'); expect(dataItem.vastUrl).to.be.a('string'); @@ -321,7 +327,7 @@ describe('onetag', function () { describe('getUserSyncs', function () { const sync_endpoint = 'https://onetag-sys.com/usync/'; it('Returns an iframe if iframeEnabled is true', function () { - const syncs = spec.getUserSyncs({iframeEnabled: true}); + const syncs = spec.getUserSyncs({ iframeEnabled: true }); expect(syncs).to.be.an('array'); expect(syncs.length).to.equal(1); expect(syncs[0].type).to.equal('iframe'); @@ -383,16 +389,16 @@ describe('onetag', function () { expect(isSchainValid(undefined)).to.be.false; }); it('Should return false when schain is missing nodes key', function () { - const schain = {'otherKey': 'otherValue'}; + const schain = { 'otherKey': 'otherValue' }; expect(isSchainValid(schain)).to.be.false; }); it('Should return false when schain is missing one of the required SupplyChainNode attribute', function () { - const missingAsiNode = {'sid': '00001', 'hp': 1}; - const missingSidNode = {'asi': 'indirectseller.com', 'hp': 1}; - const missingHpNode = {'asi': 'indirectseller.com', 'sid': '00001'}; - expect(isSchainValid({'config': {'nodes': [missingAsiNode]}})).to.be.false; - expect(isSchainValid({'config': {'nodes': [missingSidNode]}})).to.be.false; - expect(isSchainValid({'config': {'nodes': [missingHpNode]}})).to.be.false; + const missingAsiNode = { 'sid': '00001', 'hp': 1 }; + const missingSidNode = { 'asi': 'indirectseller.com', 'hp': 1 }; + const missingHpNode = { 'asi': 'indirectseller.com', 'sid': '00001' }; + expect(isSchainValid({ 'config': { 'nodes': [missingAsiNode] } })).to.be.false; + expect(isSchainValid({ 'config': { 'nodes': [missingSidNode] } })).to.be.false; + expect(isSchainValid({ 'config': { 'nodes': [missingHpNode] } })).to.be.false; }); it('Should return true when schain contains all required attributes', function () { const validSchain = {