diff --git a/modules/adagioBidAdapter.js b/modules/adagioBidAdapter.js index f144089b2a2..b2ef5dafb41 100644 --- a/modules/adagioBidAdapter.js +++ b/modules/adagioBidAdapter.js @@ -7,7 +7,7 @@ import sha256 from 'crypto-js/sha256.js'; import { getStorageManager } from '../src/storageManager.js'; const BIDDER_CODE = 'adagio'; -const VERSION = '2.2.1'; +const VERSION = '2.2.2'; const FEATURES_VERSION = '1'; const ENDPOINT = 'https://mp.4dex.io/prebid'; const SUPPORTED_MEDIA_TYPES = ['banner']; @@ -89,7 +89,7 @@ if (canAccessTopWindow()) { initAdagio(); } -const _features = { +export const _features = { getPrintNumber: function (adUnitCode) { const adagioAdUnit = _getOrAddAdagioAdUnit(adUnitCode); return adagioAdUnit.printNumber || 1; @@ -274,6 +274,34 @@ function _getElementFromTopWindow(element, currentWindow) { } } +export function _autoDetectAdUnitElementId(adUnitCode) { + const autoDetectedAdUnit = utils.getGptSlotInfoForAdUnitCode(adUnitCode) + let adUnitElementId = null; + + if (autoDetectedAdUnit && autoDetectedAdUnit.divId) { + adUnitElementId = autoDetectedAdUnit.divId; + } + + return adUnitElementId; +} + +function _autoDetectEnvironment() { + const device = _features.getDevice(); + let environment; + switch (device) { + case 2: + environment = 'desktop' + break; + case 4: + environment = 'mobile' + break; + case 5: + environment = 'tablet' + break; + }; + return environment +} + /** * Returns all features for a specific adUnit element * @@ -283,22 +311,26 @@ function _getElementFromTopWindow(element, currentWindow) { function _getFeatures(bidRequest) { if (!canAccessTopWindow()) return; const w = utils.getWindowTop(); - const adUnitElementId = bidRequest.params.adUnitElementId; const adUnitCode = bidRequest.adUnitCode; + const adUnitElementId = bidRequest.params.adUnitElementId || _autoDetectAdUnitElementId(adUnitCode); + let element; - let element = window.document.getElementById(adUnitElementId); - - if (bidRequest.params.postBid === true) { - element = _getElementFromTopWindow(element, window); - w.ADAGIO.pbjsAdUnits.map((adUnit) => { - if (adUnit.code === adUnitCode) { - const outerElementId = element.getAttribute('id'); - adUnit.outerAdUnitElementId = outerElementId; - bidRequest.params.outerAdUnitElementId = outerElementId; - } - }); + if (!adUnitElementId) { + utils.logWarn('Unable to detect adUnitElementId. Adagio measures won\'t start'); } else { - element = w.document.getElementById(adUnitElementId); + if (bidRequest.params.postBid === true) { + window.document.getElementById(adUnitElementId); + element = _getElementFromTopWindow(element, window); + w.ADAGIO.pbjsAdUnits.map((adUnit) => { + if (adUnit.code === adUnitCode) { + const outerElementId = element.getAttribute('id'); + adUnit.outerAdUnitElementId = outerElementId; + bidRequest.params.outerAdUnitElementId = outerElementId; + } + }); + } else { + element = w.document.getElementById(adUnitElementId); + } } const features = { @@ -316,6 +348,7 @@ function _getFeatures(bidRequest) { }; const adUnitFeature = {}; + adUnitFeature[adUnitElementId] = { features: features, version: FEATURES_VERSION @@ -362,17 +395,29 @@ export const spec = { isBidRequestValid: function (bid) { const { adUnitCode, auctionId, sizes, bidder, params, mediaTypes } = bid; - const { organizationId, site, placement, adUnitElementId } = bid.params; + const { organizationId, site, placement } = bid.params; + const adUnitElementId = bid.params.adUnitElementId || _autoDetectAdUnitElementId(adUnitCode); + const environment = bid.params.environment || _autoDetectEnvironment(); let isValid = false; + utils.logInfo('adUnitElementId', adUnitElementId) + try { if (canAccessTopWindow()) { const w = utils.getWindowTop(); w.ADAGIO = w.ADAGIO || {}; w.ADAGIO.adUnits = w.ADAGIO.adUnits || {}; w.ADAGIO.pbjsAdUnits = w.ADAGIO.pbjsAdUnits || []; - isValid = !!(organizationId && site && placement && adUnitElementId); + isValid = !!(organizationId && site && placement); + const tempAdUnits = w.ADAGIO.pbjsAdUnits.filter((adUnit) => adUnit.code !== adUnitCode); + + bid.params = { + ...bid.params, + adUnitElementId, + environment + } + tempAdUnits.push({ code: adUnitCode, sizes: (mediaTypes && mediaTypes.banner && Array.isArray(mediaTypes.banner.sizes)) ? mediaTypes.banner.sizes : sizes, diff --git a/modules/adagioBidAdapter.md b/modules/adagioBidAdapter.md index 5dc8aa3d80c..b34cc3fe37a 100644 --- a/modules/adagioBidAdapter.md +++ b/modules/adagioBidAdapter.md @@ -12,15 +12,19 @@ Connects to Adagio demand source to fetch bids. ```javascript var adUnits = [ - { - code: 'dfp_banniere_atf', - sizes: [[300, 250], [300, 600]], - bids: [ - { + { + code: 'dfp_banniere_atf', + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]], + } + }, + bids: [{ bidder: 'adagio', // Required params: { organizationId: '0', // Required - Organization ID provided by Adagio. site: 'news-of-the-day', // Required - Site Name provided by Adagio. + placement: 'ban_atf', // Required. Refers to the placement of an adunit in a page. Must not contain any information about the type of device. Other example: `mpu_btf'. adUnitElementId: 'dfp_banniere_atf', // Required - AdUnit element id. Refers to the adunit id in a page. Usually equals to the adunit code above. // The following params are limited to 30 characters, @@ -29,16 +33,14 @@ Connects to Adagio demand source to fetch bids. // - dashes `-` // - underscores `_` // Also, each param can have at most 50 unique active values (case-insensitive). - environment: 'mobile', // Required. Environment where the page is displayed. - placement: 'ban_atf', // Required. Refers to the placement of an adunit in a page. Must not contain any information about the type of device. Other example: `mpu_btf'. - pagetype: 'article', // Required. The pagetype describes what kind of content will be present in the page. + pagetype: 'article', // Highly recommended. The pagetype describes what kind of content will be present in the page. + environment: 'mobile', // Recommended. Environment where the page is displayed. category: 'sport', // Recommended. Category of the content displayed in the page. subcategory: 'handball', // Optional. Subcategory of the content displayed in the page. postBid: false // Optional. Use it in case of Post-bid integration only. } - } - ] - } + }] + } ]; pbjs.addAdUnits(adUnits); diff --git a/test/spec/modules/adagioBidAdapter_spec.js b/test/spec/modules/adagioBidAdapter_spec.js index 8996b288576..97265121ce0 100644 --- a/test/spec/modules/adagioBidAdapter_spec.js +++ b/test/spec/modules/adagioBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { adagioScriptFromLocalStorageCb, spec } from 'modules/adagioBidAdapter.js'; +import { adagioScriptFromLocalStorageCb, _features, spec } from 'modules/adagioBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; import * as utils from 'src/utils.js'; @@ -7,7 +7,7 @@ describe('adagioAdapter', () => { let utilsMock; const adapter = newBidder(spec); const ENDPOINT = 'https://mp.4dex.io/prebid'; - const VERSION = '2.2.1'; + const VERSION = '2.2.2'; beforeEach(function() { localStorage.removeItem('adagioScript'); @@ -51,7 +51,7 @@ describe('adagioAdapter', () => { sandbox.restore(); }); - let bid = { + const bid = { 'bidder': 'adagio', 'params': { organizationId: '0', @@ -67,7 +67,7 @@ describe('adagioAdapter', () => { 'auctionId': 'lel4fhp239i9km', }; - let bidWithMediaTypes = { + const bidWithMediaTypes = { 'bidder': 'adagio', 'params': { organizationId: '0', @@ -108,28 +108,41 @@ describe('adagioAdapter', () => { }); it('should return false when organization params is not passed', () => { - let bidTest = Object.assign({}, bid); + const bidTest = utils.deepClone(bid); delete bidTest.params.organizationId; expect(spec.isBidRequestValid(bidTest)).to.equal(false); }); it('should return false when site params is not passed', () => { - let bidTest = Object.assign({}, bid); + const bidTest = utils.deepClone(bid); delete bidTest.params.site; expect(spec.isBidRequestValid(bidTest)).to.equal(false); }); it('should return false when placement params is not passed', () => { - let bidTest = Object.assign({}, bid); + const bidTest = utils.deepClone(bid); delete bidTest.params.placement; expect(spec.isBidRequestValid(bidTest)).to.equal(false); }); - it('should return false when adUnit element id params is not passed', () => { - let bidTest = Object.assign({}, bid); + it('should add autodetected adUnitElementId and environment params', () => { + const bidTest = utils.deepClone(bid); delete bidTest.params.adUnitElementId; - expect(spec.isBidRequestValid(bidTest)).to.equal(false); - }); + delete bidTest.params.environment; + sandbox.stub(utils, 'getGptSlotInfoForAdUnitCode').returns({divId: 'banner-atf'}); + sandbox.stub(_features, 'getDevice').returns(4); + spec.isBidRequestValid(bidTest) + expect(bidTest.params.adUnitElementId).to.equal('banner-atf'); + expect(bidTest.params.environment).to.equal('mobile'); + }) + + it('should add autodetected tablet environment params', () => { + const bidTest = utils.deepClone(bid); + delete bidTest.params.environment; + sandbox.stub(_features, 'getDevice').returns(5); + spec.isBidRequestValid(bidTest) + expect(bidTest.params.environment).to.equal('tablet'); + }) it('should return false if not in the window.top', () => { sandbox.stub(utils, 'getWindowTop').throws();