From e1ddfc4b17fb2e64c1e1b492a99d46e667d190e8 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Mon, 4 Feb 2019 17:40:34 -0500 Subject: [PATCH 01/16] category translation module --- modules/appnexusBidAdapter.js | 9 ++ modules/categoryTranslation.js | 76 +++++++++++++++ src/adapters/bidderFactory.js | 48 +++++++++- src/utils.js | 16 ++++ test/spec/modules/categoryTranslation_spec.js | 66 +++++++++++++ test/spec/unit/core/bidderFactory_spec.js | 96 ++++++++++++++++++- 6 files changed, 309 insertions(+), 2 deletions(-) create mode 100644 modules/categoryTranslation.js create mode 100644 test/spec/modules/categoryTranslation_spec.js diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index d330c09aa10..0052afca596 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -7,6 +7,7 @@ import includes from 'core-js/library/fn/array/includes'; const BIDDER_CODE = 'appnexus'; const URL = '//ib.adnxs.com/ut/v3/prebid'; +const mappingFileUrl = 'http://sample.com/mappnig.json'; const VIDEO_TARGETING = ['id', 'mimes', 'minduration', 'maxduration', 'startdelay', 'skippable', 'playback_method', 'frameworks']; const USER_PARAMS = ['age', 'external_uid', 'segments', 'gender', 'dnt', 'language']; @@ -209,6 +210,14 @@ export const spec = { return bids; }, + getMappingFileInfo: function() { + return { + url: mappingFileUrl, + refreshInDays: 7, + key: `${spec.code}MappingFile` + } + }, + getUserSyncs: function(syncOptions) { if (syncOptions.iframeEnabled) { return [{ diff --git a/modules/categoryTranslation.js b/modules/categoryTranslation.js new file mode 100644 index 00000000000..51cf6f76a50 --- /dev/null +++ b/modules/categoryTranslation.js @@ -0,0 +1,76 @@ +/** + * This module translates iab category to freewheel industry using translation mapping file + * Publisher can set translation file by using setConfig method + * + * Example: + * config.setConfig({ + * 'brandCategoryTranslation': { + * 'translationFile': 'http://sample.com' + * } + * }); + * If publisher has not defined translation file than prebid will use default prebid translation file provided here + */ + +import { config } from '../src/config'; +import { hooks } from '../src/hook'; +import { ajax } from '../src/ajax'; +import { timestamp, logError, setDataInLocalStorage, getDataFromLocalStorage } from '../src/utils'; + +// TODO udpate url once it is uploaded on cdn +const DEFAULT_TRANSLATION_FILE_URL = 'https://api.myjson.com/bins/j5d0k'; +const DEFAULT_IAB_TO_FW_MAPPING_KEY = 'iabToFwMappingkey'; +const refreshInDays = 1; + +export function getFreeWheelCategoryHook(fn, adUnitCode, bid) { + if (!bid) { + return fn.call(this, adUnitCode); // if no bid, call original and let it display warnings + } + + if (bid.meta && !bid.meta.adServerCatId) { + let mapping = getDataFromLocalStorage(DEFAULT_IAB_TO_FW_MAPPING_KEY); + if (mapping) { + try { + mapping = JSON.parse(mapping); + } catch (error) { + logError('Failed to parse translation mapping file'); + } + if (bid.meta) { + bid.meta.adServerCatId = (bid.meta.iabSubCatId) ? mapping.mapping[bid.meta.iabSubCatId] : undefined; + } + } else { + logError('Translation mapping data not found in local storage'); + } + } + return fn.call(this, adUnitCode, bid); +} + +export function initTranslation() { + hooks['addBidResponse'].before(getFreeWheelCategoryHook, 50); + let pubTranslationFile = config.getConfig('brandCategoryTranslation.translationFile'); + let url = (typeof pubTranslationFile !== 'undefined') ? pubTranslationFile : DEFAULT_TRANSLATION_FILE_URL; + + let mappingData = getDataFromLocalStorage(DEFAULT_IAB_TO_FW_MAPPING_KEY); + if (!mappingData || timestamp() < mappingData.lastUpdated + refreshInDays * 24 * 60 * 60 * 1000) { + ajax(url, + { + success: (response) => { + try { + response = JSON.parse(response); + let mapping = { + lastUpdated: timestamp(), + mapping: response.mapping + } + setDataInLocalStorage(DEFAULT_IAB_TO_FW_MAPPING_KEY, JSON.stringify(mapping)); + } catch (error) { + logError('Failed to parse translation mapping file'); + } + }, + error: () => { + logError('Failed to load brand category translation file.') + } + }, + ); + } +} + +initTranslation(); diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index 13439e2a457..968c028e862 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -8,7 +8,12 @@ import { isValidVideoBid } from '../video'; import CONSTANTS from '../constants.json'; import events from '../events'; import includes from 'core-js/library/fn/array/includes'; -import { logWarn, logError, parseQueryStringParameters, delayExecution, parseSizesInput, getBidderRequest } from '../utils'; +import { ajax } from '../ajax'; +import { logWarn, logError, parseQueryStringParameters, delayExecution, parseSizesInput, getBidderRequest, flatten, uniques, timestamp, setDataInLocalStorage, getDataFromLocalStorage, deepAccess } from '../utils'; +import { hooks } from '../hook'; +// import { ADPOD } from './adpod'; + +const ADPOD = 'adpod'; // TODO remove once ADPOD const is imported /** * This file aims to support Adapters during the Prebid 0.x -> 1.x transition. @@ -341,6 +346,47 @@ export function newBidder(spec) { } } +if (hooks['checkAdUnitSetup']) { + hooks['checkAdUnitSetup'].before(preloadBidderMappingFile); +} + +export function preloadBidderMappingFile(adUnits) { + let adPodBidders = adUnits + .filter((adUnit) => deepAccess(adUnit, 'mediaTypes.video.context') === ADPOD) + .map((adUnit) => adUnit.bids.map((bid) => bid.bidder)) + .reduce(flatten, []) + .filter(uniques); + + adPodBidders.forEach(bidder => { + let bidderSpec = adapterManager.getBidAdapter(bidder); + if (bidderSpec.getMappingFileInfo) { + let info = bidderSpec.getMappingFileInfo(); + let mappingData = getDataFromLocalStorage(info.key); + if (!mappingData || timestamp() < mappingData.lastUpdated + info.refreshInDays * 24 * 60 * 60 * 1000) { + ajax(info.url, + { + success: (response) => { + try { + response = JSON.parse(response); + let mapping = { + lastUpdated: timestamp(), + mapping: response.mapping + } + setDataInLocalStorage(info.key, JSON.stringify(mapping)); + } catch (error) { + logError(`Failed to parse ${bidder} bidder translation mapping file`); + } + }, + error: () => { + logError(`Failed to load ${bidder} bidder translation file`) + } + }, + ); + } + } + }); +} + // check that the bid has a width and height set function validBidSize(adUnitCode, bid, bidRequests) { if ((bid.width || bid.width === 0) && (bid.height || bid.height === 0)) { diff --git a/src/utils.js b/src/utils.js index f21c555bbbb..bded21a4ecb 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1183,3 +1183,19 @@ export function convertTypes(types, params) { }); return params; } + +export function setDataInLocalStorage(key, value) { + if (hasLocalStorage()) { + window.localStorage.setItem(key, value); + } +} + +export function getDataFromLocalStorage(key) { + if (hasLocalStorage()) { + window.localStorage.getItem(key); + } +} + +export function hasLocalStorage() { + return !!window.localStorage; +} diff --git a/test/spec/modules/categoryTranslation_spec.js b/test/spec/modules/categoryTranslation_spec.js new file mode 100644 index 00000000000..fa2ae1bab2f --- /dev/null +++ b/test/spec/modules/categoryTranslation_spec.js @@ -0,0 +1,66 @@ +import { getFreeWheelCategoryHook, initTranslation } from 'modules/categoryTranslation'; +import { config } from 'src/config'; +import * as utils from 'src/utils'; +import { expect } from 'chai'; + +describe('category translation', function () { + let fakeTranslationServer; + let getLocalStorageStub; + + beforeEach(function () { + fakeTranslationServer = sinon.fakeServer.create(); + getLocalStorageStub = sinon.stub(utils, 'getDataFromLocalStorage'); + }); + + afterEach(function() { + getLocalStorageStub.restore(); + config.resetConfig(); + }); + + it('should translate iab category to adserver category', function () { + getLocalStorageStub.returns(JSON.stringify({ + mapping: { + 'iab-1': '1' + } + })); + let bid = { + meta: { + iabSubCatId: 'iab-1' + } + } + getFreeWheelCategoryHook(sinon.spy(), 'code', bid); + expect(bid.meta.adServerCatId).to.equal('1'); + }); + + it('should not make ajax call to update mapping file if data found in localstorage and is not expired', function () { + let clock = sinon.useFakeTimers(utils.timestamp()); + getLocalStorageStub.returns(JSON.stringify({ + lastUpdated: utils.timestamp(), + mapping: { + 'iab-1': '1' + } + })); + initTranslation(); + expect(fakeTranslationServer.requests.length).to.equal(0); + clock.restore(); + }); + + it('should use default mapping file if publisher has not defined in config', function () { + getLocalStorageStub.returns(null); + initTranslation(); + expect(fakeTranslationServer.requests.length).to.equal(1); + expect(fakeTranslationServer.requests[0].url).to.equal('https://api.myjson.com/bins/j5d0k'); + }); + + it('should use publisher defined defined mapping file', function () { + config.setConfig({ + 'brandCategoryTranslation': { + 'translationFile': 'http://sample.com' + } + }); + getLocalStorageStub.returns(null); + initTranslation(); + expect(fakeTranslationServer.requests.length).to.equal(1); + expect(fakeTranslationServer.requests[0].url).to.equal('http://sample.com'); + }); +}); diff --git a/test/spec/unit/core/bidderFactory_spec.js b/test/spec/unit/core/bidderFactory_spec.js index 5149bbd38a6..d1161894079 100644 --- a/test/spec/unit/core/bidderFactory_spec.js +++ b/test/spec/unit/core/bidderFactory_spec.js @@ -1,4 +1,4 @@ -import { newBidder, registerBidder } from 'src/adapters/bidderFactory'; +import { newBidder, registerBidder, preloadBidderMappingFile } from 'src/adapters/bidderFactory'; import adapterManager from 'src/adapterManager'; import * as ajax from 'src/ajax'; import { expect } from 'chai'; @@ -775,3 +775,97 @@ describe('validate bid response: ', function () { expect(logErrorSpy.callCount).to.equal(0); }); }); + +describe('preload mapping url hook', function() { + let fakeTranslationServer; + let getLocalStorageStub; + let adapterManagerStub; + + beforeEach(function () { + fakeTranslationServer = sinon.fakeServer.create(); + getLocalStorageStub = sinon.stub(utils, 'getDataFromLocalStorage'); + adapterManagerStub = sinon.stub(adapterManager, 'getBidAdapter'); + }); + + afterEach(function() { + getLocalStorageStub.restore(); + adapterManagerStub.restore(); + }); + + it('should preload mapping url file', function() { + let adUnits = [{ + code: 'midroll_1', + mediaTypes: { + video: { + context: 'adpod' + } + }, + bids: [ + { + bidder: 'sampleBidder1', + params: { + placementId: 14542875, + } + } + ] + }]; + getLocalStorageStub.returns(null); + adapterManagerStub.withArgs('sampleBidder1').returns({ + getMappingFileInfo: function() { + return { + url: 'http://sample.com', + refreshInDays: 7, + key: `sampleBidder1MappingFile` + } + }, + }); + preloadBidderMappingFile(adUnits); + expect(fakeTranslationServer.requests.length).to.equal(1); + }); + + it('should preload mapping url file for all bidders', function() { + let adUnits = [{ + code: 'midroll_1', + mediaTypes: { + video: { + context: 'adpod' + } + }, + bids: [ + { + bidder: 'sampleBidder1', + params: { + placementId: 14542875, + } + }, + { + bidder: 'sampleBidder2', + params: { + placementId: 123456, + } + } + ] + }]; + getLocalStorageStub.returns(null); + adapterManagerStub.withArgs('sampleBidder1').returns({ + getMappingFileInfo: function() { + return { + url: 'http://sample.com', + refreshInDays: 7, + key: `sampleBidder1MappingFile` + } + }, + }); + adapterManagerStub.withArgs('sampleBidder2').returns({ + getMappingFileInfo: function() { + return { + url: 'http://sample2.com', + refreshInDays: 7, + key: `sampleBidder2MappingFile` + } + }, + }); + preloadBidderMappingFile(adUnits); + expect(fakeTranslationServer.requests.length).to.equal(2); + }); +}); From 759018b6301aa4c376b23ea3cfb8dbebc60a960c Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Wed, 6 Feb 2019 17:33:15 -0500 Subject: [PATCH 02/16] update function name, refactor code and add getIabSubCategory function --- modules/appnexusBidAdapter.js | 20 ++++++++++++++++--- modules/categoryTranslation.js | 6 +++--- src/adapters/bidderFactory.js | 4 ++-- src/utils.js | 19 +++++++++++++++++- test/spec/modules/categoryTranslation_spec.js | 4 ++-- 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index 0052afca596..9194cac3c39 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -7,7 +7,6 @@ import includes from 'core-js/library/fn/array/includes'; const BIDDER_CODE = 'appnexus'; const URL = '//ib.adnxs.com/ut/v3/prebid'; -const mappingFileUrl = 'http://sample.com/mappnig.json'; const VIDEO_TARGETING = ['id', 'mimes', 'minduration', 'maxduration', 'startdelay', 'skippable', 'playback_method', 'frameworks']; const USER_PARAMS = ['age', 'external_uid', 'segments', 'gender', 'dnt', 'language']; @@ -33,6 +32,10 @@ const NATIVE_MAPPING = { displayUrl: 'displayurl' }; const SOURCE = 'pbjs'; +const mappingFileInfo = Object.freeze({ + mappingFileUrl: 'http://sample.com/mappnig.json', + uniqueKey: utils.getUniqueIdentifierStr() +}); export const spec = { code: BIDDER_CODE, @@ -210,11 +213,22 @@ export const spec = { return bids; }, + /** + * @typedef {Object} mappingFileInfo + * @property {string} url mapping file json url + * @property {number} refreshInDays prebid stores mapping data in localstorage so you can return in how many days you want to update value stored in localstorage. + * @property {string} localStorageKey unique key to store your mapping json in localstorage + */ + + /** + * Returns mapping file info. This info will be used by bidderFactory to preload mapping file and store data in local storage + * @returns {mappingFileInfo} + */ getMappingFileInfo: function() { return { - url: mappingFileUrl, + url: mappingFileInfo.mappingFileUrl, refreshInDays: 7, - key: `${spec.code}MappingFile` + localStorageKey: `${spec.code}_${mappingFileInfo.uniqueKey}` } }, diff --git a/modules/categoryTranslation.js b/modules/categoryTranslation.js index 51cf6f76a50..c8daecea776 100644 --- a/modules/categoryTranslation.js +++ b/modules/categoryTranslation.js @@ -21,7 +21,7 @@ const DEFAULT_TRANSLATION_FILE_URL = 'https://api.myjson.com/bins/j5d0k'; const DEFAULT_IAB_TO_FW_MAPPING_KEY = 'iabToFwMappingkey'; const refreshInDays = 1; -export function getFreeWheelCategoryHook(fn, adUnitCode, bid) { +export function getAdserverCategoryHook(fn, adUnitCode, bid) { if (!bid) { return fn.call(this, adUnitCode); // if no bid, call original and let it display warnings } @@ -41,11 +41,11 @@ export function getFreeWheelCategoryHook(fn, adUnitCode, bid) { logError('Translation mapping data not found in local storage'); } } - return fn.call(this, adUnitCode, bid); + fn.call(this, adUnitCode, bid); } export function initTranslation() { - hooks['addBidResponse'].before(getFreeWheelCategoryHook, 50); + hooks['addBidResponse'].before(getAdserverCategoryHook, 50); let pubTranslationFile = config.getConfig('brandCategoryTranslation.translationFile'); let url = (typeof pubTranslationFile !== 'undefined') ? pubTranslationFile : DEFAULT_TRANSLATION_FILE_URL; diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index 0fbd2fab1f4..ef22a3ee353 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -365,7 +365,7 @@ export function preloadBidderMappingFile(adUnits) { let bidderSpec = adapterManager.getBidAdapter(bidder); if (bidderSpec.getMappingFileInfo) { let info = bidderSpec.getMappingFileInfo(); - let mappingData = getDataFromLocalStorage(info.key); + let mappingData = getDataFromLocalStorage(info.localStorageKey); if (!mappingData || timestamp() < mappingData.lastUpdated + info.refreshInDays * 24 * 60 * 60 * 1000) { ajax(info.url, { @@ -376,7 +376,7 @@ export function preloadBidderMappingFile(adUnits) { lastUpdated: timestamp(), mapping: response.mapping } - setDataInLocalStorage(info.key, JSON.stringify(mapping)); + setDataInLocalStorage(info.localStorageKey, JSON.stringify(mapping)); } catch (error) { logError(`Failed to parse ${bidder} bidder translation mapping file`); } diff --git a/src/utils.js b/src/utils.js index bded21a4ecb..2495806b514 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1192,10 +1192,27 @@ export function setDataInLocalStorage(key, value) { export function getDataFromLocalStorage(key) { if (hasLocalStorage()) { - window.localStorage.getItem(key); + return window.localStorage.getItem(key); } } export function hasLocalStorage() { return !!window.localStorage; } + +/** + * Reads the data stored in localstorage and returns iab subcategory + * @param {string} localStorageKey key to get data from local storage + * @param {string} category bidders category + */ +export function getIabSubCategory(localStorageKey, category) { + let data = getDataFromLocalStorage(localStorageKey); + if (data) { + try { + data = JSON.parse(data); + } catch (error) { + logError(`Failed to parse translation data stored in local storage`); + } + return (data.mapping[category]) ? data.mapping[category] : null; + } +} diff --git a/test/spec/modules/categoryTranslation_spec.js b/test/spec/modules/categoryTranslation_spec.js index fa2ae1bab2f..70dd172df75 100644 --- a/test/spec/modules/categoryTranslation_spec.js +++ b/test/spec/modules/categoryTranslation_spec.js @@ -1,4 +1,4 @@ -import { getFreeWheelCategoryHook, initTranslation } from 'modules/categoryTranslation'; +import { getAdserverCategoryHook, initTranslation } from 'modules/categoryTranslation'; import { config } from 'src/config'; import * as utils from 'src/utils'; import { expect } from 'chai'; @@ -28,7 +28,7 @@ describe('category translation', function () { iabSubCatId: 'iab-1' } } - getFreeWheelCategoryHook(sinon.spy(), 'code', bid); + getAdserverCategoryHook(sinon.spy(), 'code', bid); expect(bid.meta.adServerCatId).to.equal('1'); }); From cbd7df451a36bd509c5f6a87f6552258ce47bd7c Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Thu, 7 Feb 2019 14:29:40 -0500 Subject: [PATCH 03/16] move hook init and import adpod --- src/adapters/bidderFactory.js | 12 +++--------- src/prebid.js | 5 ++++- test/spec/unit/core/bidderFactory_spec.js | 4 ++-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index ef22a3ee353..284cb955af2 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -10,10 +10,7 @@ import events from '../events'; import includes from 'core-js/library/fn/array/includes'; import { ajax } from '../ajax'; import { logWarn, logError, parseQueryStringParameters, delayExecution, parseSizesInput, getBidderRequest, flatten, uniques, timestamp, setDataInLocalStorage, getDataFromLocalStorage, deepAccess } from '../utils'; -import { hooks } from '../hook'; -// import { ADPOD } from './adpod'; - -const ADPOD = 'adpod'; // TODO remove once ADPOD const is imported +import { ADPOD } from '../mediaTypes'; /** * This file aims to support Adapters during the Prebid 0.x -> 1.x transition. @@ -350,11 +347,7 @@ export function newBidder(spec) { } } -if (hooks['checkAdUnitSetup']) { - hooks['checkAdUnitSetup'].before(preloadBidderMappingFile); -} - -export function preloadBidderMappingFile(adUnits) { +export function preloadBidderMappingFile(fn, adUnits) { let adPodBidders = adUnits .filter((adUnit) => deepAccess(adUnit, 'mediaTypes.video.context') === ADPOD) .map((adUnit) => adUnit.bids.map((bid) => bid.bidder)) @@ -389,6 +382,7 @@ export function preloadBidderMappingFile(adUnits) { } } }); + fn.call(this, adUnits); } // check that the bid has a width and height set diff --git a/src/prebid.js b/src/prebid.js index 92f6d819ecf..6563b38c422 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -8,12 +8,13 @@ import { loadScript } from './adloader'; import { config } from './config'; import { auctionManager } from './auctionManager'; import { targeting, getHighestCpmBidsFromBidPool } from './targeting'; -import { hook } from './hook'; +import { hook, hooks } from './hook'; import { sessionLoader } from './debugging'; import includes from 'core-js/library/fn/array/includes'; import { adunitCounter } from './adUnits'; import { isRendererRequired, executeRenderer } from './Renderer'; import { createBid } from './bidfactory'; +import { preloadBidderMappingFile } from './adapters/bidderFactory'; const $$PREBID_GLOBAL$$ = getGlobal(); const CONSTANTS = require('./constants.json'); @@ -125,6 +126,8 @@ const checkAdUnitSetup = hook('sync', function (adUnits) { return adUnits; }, 'checkAdUnitSetup'); +hooks['checkAdUnitSetup'].before(preloadBidderMappingFile); + /// /////////////////////////////// // // // Start Public APIs // diff --git a/test/spec/unit/core/bidderFactory_spec.js b/test/spec/unit/core/bidderFactory_spec.js index a20e962c5bf..030c49859ad 100644 --- a/test/spec/unit/core/bidderFactory_spec.js +++ b/test/spec/unit/core/bidderFactory_spec.js @@ -819,7 +819,7 @@ describe('preload mapping url hook', function() { } }, }); - preloadBidderMappingFile(adUnits); + preloadBidderMappingFile(sinon.spy(), adUnits); expect(fakeTranslationServer.requests.length).to.equal(1); }); @@ -865,7 +865,7 @@ describe('preload mapping url hook', function() { } }, }); - preloadBidderMappingFile(adUnits); + preloadBidderMappingFile(sinon.spy(), adUnits); expect(fakeTranslationServer.requests.length).to.equal(2); }); }); From d2d8313c6c3ea5645425d5446c97137f3f50320e Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Fri, 8 Feb 2019 13:24:52 -0500 Subject: [PATCH 04/16] bugfix in getting adapter spec --- src/adapters/bidderFactory.js | 4 +-- test/spec/unit/core/bidderFactory_spec.js | 42 +++++++++++++++-------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index 284cb955af2..941210a7b63 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -356,8 +356,8 @@ export function preloadBidderMappingFile(fn, adUnits) { adPodBidders.forEach(bidder => { let bidderSpec = adapterManager.getBidAdapter(bidder); - if (bidderSpec.getMappingFileInfo) { - let info = bidderSpec.getMappingFileInfo(); + if (bidderSpec.getSpec().getMappingFileInfo) { + let info = bidderSpec.getSpec().getMappingFileInfo(); let mappingData = getDataFromLocalStorage(info.localStorageKey); if (!mappingData || timestamp() < mappingData.lastUpdated + info.refreshInDays * 24 * 60 * 60 * 1000) { ajax(info.url, diff --git a/test/spec/unit/core/bidderFactory_spec.js b/test/spec/unit/core/bidderFactory_spec.js index 030c49859ad..0ae09edeb83 100644 --- a/test/spec/unit/core/bidderFactory_spec.js +++ b/test/spec/unit/core/bidderFactory_spec.js @@ -811,13 +811,17 @@ describe('preload mapping url hook', function() { }]; getLocalStorageStub.returns(null); adapterManagerStub.withArgs('sampleBidder1').returns({ - getMappingFileInfo: function() { + getSpec: function() { return { - url: 'http://sample.com', - refreshInDays: 7, - key: `sampleBidder1MappingFile` + 'getMappingFileInfo': function() { + return { + url: 'http://sample.com', + refreshInDays: 7, + key: `sampleBidder1MappingFile` + } + } } - }, + } }); preloadBidderMappingFile(sinon.spy(), adUnits); expect(fakeTranslationServer.requests.length).to.equal(1); @@ -848,22 +852,30 @@ describe('preload mapping url hook', function() { }]; getLocalStorageStub.returns(null); adapterManagerStub.withArgs('sampleBidder1').returns({ - getMappingFileInfo: function() { + getSpec: function() { return { - url: 'http://sample.com', - refreshInDays: 7, - key: `sampleBidder1MappingFile` + 'getMappingFileInfo': function() { + return { + url: 'http://sample.com', + refreshInDays: 7, + key: `sampleBidder1MappingFile` + } + } } - }, + } }); adapterManagerStub.withArgs('sampleBidder2').returns({ - getMappingFileInfo: function() { + getSpec: function() { return { - url: 'http://sample2.com', - refreshInDays: 7, - key: `sampleBidder2MappingFile` + 'getMappingFileInfo': function() { + return { + url: 'http://sample.com', + refreshInDays: 7, + key: `sampleBidder2MappingFile` + } + } } - }, + } }); preloadBidderMappingFile(sinon.spy(), adUnits); expect(fakeTranslationServer.requests.length).to.equal(2); From 37391e45bc833784e7509ccf821615f52861c00d Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Sun, 10 Feb 2019 21:42:04 -0500 Subject: [PATCH 05/16] add hook for adserver in use --- modules/categoryTranslation.js | 36 +++++++++++++++---- test/spec/modules/categoryTranslation_spec.js | 14 ++++++-- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/modules/categoryTranslation.js b/modules/categoryTranslation.js index c8daecea776..0a78e293f6f 100644 --- a/modules/categoryTranslation.js +++ b/modules/categoryTranslation.js @@ -12,19 +12,28 @@ */ import { config } from '../src/config'; -import { hooks } from '../src/hook'; +import { hooks, hook } from '../src/hook'; import { ajax } from '../src/ajax'; import { timestamp, logError, setDataInLocalStorage, getDataFromLocalStorage } from '../src/utils'; // TODO udpate url once it is uploaded on cdn const DEFAULT_TRANSLATION_FILE_URL = 'https://api.myjson.com/bins/j5d0k'; const DEFAULT_IAB_TO_FW_MAPPING_KEY = 'iabToFwMappingkey'; +const DEFAULT_IAB_TO_FW_MAPPING_KEY_PUB = 'iabToFwMappingkeyPub'; const refreshInDays = 1; +let adServerInUse; +export const registerAdserver = hook('async', function(adServer) { + adServerInUse = adServer; +}, 'registerAdserver'); + export function getAdserverCategoryHook(fn, adUnitCode, bid) { if (!bid) { return fn.call(this, adUnitCode); // if no bid, call original and let it display warnings } + if (!adServerInUse) { + registerAdserver(); + } if (bid.meta && !bid.meta.adServerCatId) { let mapping = getDataFromLocalStorage(DEFAULT_IAB_TO_FW_MAPPING_KEY); @@ -35,7 +44,7 @@ export function getAdserverCategoryHook(fn, adUnitCode, bid) { logError('Failed to parse translation mapping file'); } if (bid.meta) { - bid.meta.adServerCatId = (bid.meta.iabSubCatId) ? mapping.mapping[bid.meta.iabSubCatId] : undefined; + bid.meta.adServerCatId = (bid.meta.iabSubCatId && mapping[adServerInUse] && mapping[adServerInUse]['mapping']) ? mapping[adServerInUse]['mapping'][bid.meta.iabSubCatId] : undefined; } } else { logError('Translation mapping data not found in local storage'); @@ -44,12 +53,17 @@ export function getAdserverCategoryHook(fn, adUnitCode, bid) { fn.call(this, adUnitCode, bid); } -export function initTranslation() { +export function initTranslation(...args) { hooks['addBidResponse'].before(getAdserverCategoryHook, 50); - let pubTranslationFile = config.getConfig('brandCategoryTranslation.translationFile'); - let url = (typeof pubTranslationFile !== 'undefined') ? pubTranslationFile : DEFAULT_TRANSLATION_FILE_URL; + let url = DEFAULT_TRANSLATION_FILE_URL; + let localStorageKey = DEFAULT_IAB_TO_FW_MAPPING_KEY; + if (args && args.length > 0) { + // use publisher defined translation file + url = args[0]; + localStorageKey = DEFAULT_IAB_TO_FW_MAPPING_KEY_PUB; + } - let mappingData = getDataFromLocalStorage(DEFAULT_IAB_TO_FW_MAPPING_KEY); + let mappingData = getDataFromLocalStorage(localStorageKey); if (!mappingData || timestamp() < mappingData.lastUpdated + refreshInDays * 24 * 60 * 60 * 1000) { ajax(url, { @@ -60,7 +74,7 @@ export function initTranslation() { lastUpdated: timestamp(), mapping: response.mapping } - setDataInLocalStorage(DEFAULT_IAB_TO_FW_MAPPING_KEY, JSON.stringify(mapping)); + setDataInLocalStorage(localStorageKey, JSON.stringify(mapping)); } catch (error) { logError('Failed to parse translation mapping file'); } @@ -73,4 +87,12 @@ export function initTranslation() { } } +function setConfig(config) { + if (config.translationFile) { + // if publisher has defined the translation file, preload that file here + initTranslation(config.translationFile); + } +} + initTranslation(); +config.getConfig('brandCategoryTranslation', config => setConfig(config.brandCategoryTranslation)); diff --git a/test/spec/modules/categoryTranslation_spec.js b/test/spec/modules/categoryTranslation_spec.js index 70dd172df75..38ce914c4d6 100644 --- a/test/spec/modules/categoryTranslation_spec.js +++ b/test/spec/modules/categoryTranslation_spec.js @@ -2,6 +2,7 @@ import { getAdserverCategoryHook, initTranslation } from 'modules/categoryTransl import { config } from 'src/config'; import * as utils from 'src/utils'; import { expect } from 'chai'; +import { hooks } from 'src/hook'; describe('category translation', function () { let fakeTranslationServer; @@ -18,9 +19,16 @@ describe('category translation', function () { }); it('should translate iab category to adserver category', function () { + hooks['registerAdserver'].before(notifyTranslationModule); + function notifyTranslationModule(fn) { + fn.call(this, 'freewheel'); + } + getLocalStorageStub.returns(JSON.stringify({ - mapping: { - 'iab-1': '1' + 'freewheel': { + mapping: { + 'iab-1': '1' + } } })); let bid = { @@ -60,7 +68,7 @@ describe('category translation', function () { }); getLocalStorageStub.returns(null); initTranslation(); - expect(fakeTranslationServer.requests.length).to.equal(1); + expect(fakeTranslationServer.requests.length).to.equal(2); expect(fakeTranslationServer.requests[0].url).to.equal('http://sample.com'); }); }); From 2b818565220f6de55123890f9bfad18ae9f85330 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Sun, 10 Feb 2019 21:50:37 -0500 Subject: [PATCH 06/16] updated getting iab subcategory code --- modules/appnexusBidAdapter.js | 29 ++++++++++++++++++++--------- src/adapters/bidderFactory.js | 27 +++++++++++++++++++++++++-- src/utils.js | 17 ----------------- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index 9194cac3c39..7a81515537b 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -1,7 +1,7 @@ import { Renderer } from '../src/Renderer'; import * as utils from '../src/utils'; -import { registerBidder } from '../src/adapters/bidderFactory'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes'; +import { registerBidder, getIabSubCategory } from '../src/adapters/bidderFactory'; +import { BANNER, NATIVE, VIDEO, ADPOD } from '../src/mediaTypes'; import find from 'core-js/library/fn/array/find'; import includes from 'core-js/library/fn/array/includes'; @@ -32,10 +32,7 @@ const NATIVE_MAPPING = { displayUrl: 'displayurl' }; const SOURCE = 'pbjs'; -const mappingFileInfo = Object.freeze({ - mappingFileUrl: 'http://sample.com/mappnig.json', - uniqueKey: utils.getUniqueIdentifierStr() -}); +const mappingFileUrl = 'https://api.myjson.com/bins/11f7yo'; export const spec = { code: BIDDER_CODE, @@ -226,9 +223,8 @@ export const spec = { */ getMappingFileInfo: function() { return { - url: mappingFileInfo.mappingFileUrl, - refreshInDays: 7, - localStorageKey: `${spec.code}_${mappingFileInfo.uniqueKey}` + url: mappingFileUrl, + refreshInDays: 7 } }, @@ -339,6 +335,21 @@ function newBid(serverBid, rtbBid, bidderRequest) { vastImpUrl: rtbBid.notify_url, ttl: 3600 }); + + const videoContext = utils.deepAccess(bidRequest, 'mediaTypes.video.context'); + if (videoContext === ADPOD) { + const iabSubCatId = getIabSubCategory(bidRequest.bidder, rtbBid.brand_category_id); + + bid.meta = { + iabSubCatId + }; + + bid.video = { + context: ADPOD, + durationSeconds: Math.ceil(rtbBid.rtb.video.duration_ms / 1000), + }; + } + // This supports Outstream Video if (rtbBid.renderer_url) { const rendererOptions = utils.deepAccess( diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index 941210a7b63..3d45421e547 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -358,7 +358,8 @@ export function preloadBidderMappingFile(fn, adUnits) { let bidderSpec = adapterManager.getBidAdapter(bidder); if (bidderSpec.getSpec().getMappingFileInfo) { let info = bidderSpec.getSpec().getMappingFileInfo(); - let mappingData = getDataFromLocalStorage(info.localStorageKey); + let key = (info.localStorageKey) ? info.localStorageKey : bidderSpec.getSpec().code; + let mappingData = getDataFromLocalStorage(key); if (!mappingData || timestamp() < mappingData.lastUpdated + info.refreshInDays * 24 * 60 * 60 * 1000) { ajax(info.url, { @@ -369,7 +370,7 @@ export function preloadBidderMappingFile(fn, adUnits) { lastUpdated: timestamp(), mapping: response.mapping } - setDataInLocalStorage(info.localStorageKey, JSON.stringify(mapping)); + setDataInLocalStorage(key, JSON.stringify(mapping)); } catch (error) { logError(`Failed to parse ${bidder} bidder translation mapping file`); } @@ -385,6 +386,28 @@ export function preloadBidderMappingFile(fn, adUnits) { fn.call(this, adUnits); } +/** + * Reads the data stored in localstorage and returns iab subcategory + * @param {string} bidderCode bidderCode + * @param {string} category bidders category + */ +export function getIabSubCategory(bidderCode, category) { + let bidderSpec = adapterManager.getBidAdapter(bidderCode); + if (bidderSpec.getSpec().getMappingFileInfo) { + let info = bidderSpec.getSpec().getMappingFileInfo(); + let key = (info.localStorageKey) ? info.localStorageKey : bidderSpec.getBidderCode(); + let data = getDataFromLocalStorage(key); + if (data) { + try { + data = JSON.parse(data); + } catch (error) { + logError(`Failed to parse ${bidderCode} mapping data stored in local storage`); + } + return (data.mapping[category]) ? data.mapping[category] : null; + } + } +} + // check that the bid has a width and height set function validBidSize(adUnitCode, bid, bidRequests) { if ((bid.width || bid.width === 0) && (bid.height || bid.height === 0)) { diff --git a/src/utils.js b/src/utils.js index 0f401f9f954..7239cd86bcd 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1203,23 +1203,6 @@ export function hasLocalStorage() { return !!window.localStorage; } -/** - * Reads the data stored in localstorage and returns iab subcategory - * @param {string} localStorageKey key to get data from local storage - * @param {string} category bidders category - */ -export function getIabSubCategory(localStorageKey, category) { - let data = getDataFromLocalStorage(localStorageKey); - if (data) { - try { - data = JSON.parse(data); - } catch (error) { - logError(`Failed to parse translation data stored in local storage`); - } - return (data.mapping[category]) ? data.mapping[category] : null; - } -} - export function isArrayOfNums(val, size) { return (isArray(val)) && ((size) ? val.length === size : true) && (val.every(v => isInteger(v))); } From e70ba4e8349064dc2430398b5e0da6dd2cd3a803 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Sun, 10 Feb 2019 23:52:27 -0500 Subject: [PATCH 07/16] bugfix --- modules/categoryTranslation.js | 7 +++++-- test/spec/modules/categoryTranslation_spec.js | 8 +++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/modules/categoryTranslation.js b/modules/categoryTranslation.js index 0a78e293f6f..c87b3f7537c 100644 --- a/modules/categoryTranslation.js +++ b/modules/categoryTranslation.js @@ -35,11 +35,14 @@ export function getAdserverCategoryHook(fn, adUnitCode, bid) { registerAdserver(); } + let localStorageKey = (config.getConfig('brandCategoryTranslation.translationFile')) ? DEFAULT_IAB_TO_FW_MAPPING_KEY_PUB : DEFAULT_IAB_TO_FW_MAPPING_KEY; + if (bid.meta && !bid.meta.adServerCatId) { - let mapping = getDataFromLocalStorage(DEFAULT_IAB_TO_FW_MAPPING_KEY); + let mapping = getDataFromLocalStorage(localStorageKey); if (mapping) { try { mapping = JSON.parse(mapping); + mapping = mapping['data']; } catch (error) { logError('Failed to parse translation mapping file'); } @@ -72,7 +75,7 @@ export function initTranslation(...args) { response = JSON.parse(response); let mapping = { lastUpdated: timestamp(), - mapping: response.mapping + data: response } setDataInLocalStorage(localStorageKey, JSON.stringify(mapping)); } catch (error) { diff --git a/test/spec/modules/categoryTranslation_spec.js b/test/spec/modules/categoryTranslation_spec.js index 38ce914c4d6..7299f43154b 100644 --- a/test/spec/modules/categoryTranslation_spec.js +++ b/test/spec/modules/categoryTranslation_spec.js @@ -25,9 +25,11 @@ describe('category translation', function () { } getLocalStorageStub.returns(JSON.stringify({ - 'freewheel': { - mapping: { - 'iab-1': '1' + 'data': { + 'freewheel': { + mapping: { + 'iab-1': '1' + } } } })); From 230e6c103cde14f135d12bc7e2549d42fbfbb538 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Tue, 12 Feb 2019 22:46:55 -0500 Subject: [PATCH 08/16] Use individual mapping file for translation --- modules/categoryTranslation.js | 36 +++++++------------ test/spec/modules/categoryTranslation_spec.js | 20 ++++------- 2 files changed, 18 insertions(+), 38 deletions(-) diff --git a/modules/categoryTranslation.js b/modules/categoryTranslation.js index c87b3f7537c..f7abe6825f8 100644 --- a/modules/categoryTranslation.js +++ b/modules/categoryTranslation.js @@ -17,23 +17,24 @@ import { ajax } from '../src/ajax'; import { timestamp, logError, setDataInLocalStorage, getDataFromLocalStorage } from '../src/utils'; // TODO udpate url once it is uploaded on cdn -const DEFAULT_TRANSLATION_FILE_URL = 'https://api.myjson.com/bins/j5d0k'; +const DEFAULT_TRANSLATION_FILE_URL = 'http://acdn.adnxs.com/prebid/test/jp/freewheel-mapping.json'; const DEFAULT_IAB_TO_FW_MAPPING_KEY = 'iabToFwMappingkey'; const DEFAULT_IAB_TO_FW_MAPPING_KEY_PUB = 'iabToFwMappingkeyPub'; const refreshInDays = 1; -let adServerInUse; export const registerAdserver = hook('async', function(adServer) { - adServerInUse = adServer; + let url; + if (adServer === 'freewheel') { + url = DEFAULT_TRANSLATION_FILE_URL; + } + initTranslation(url, DEFAULT_IAB_TO_FW_MAPPING_KEY); }, 'registerAdserver'); +registerAdserver(); export function getAdserverCategoryHook(fn, adUnitCode, bid) { if (!bid) { return fn.call(this, adUnitCode); // if no bid, call original and let it display warnings } - if (!adServerInUse) { - registerAdserver(); - } let localStorageKey = (config.getConfig('brandCategoryTranslation.translationFile')) ? DEFAULT_IAB_TO_FW_MAPPING_KEY_PUB : DEFAULT_IAB_TO_FW_MAPPING_KEY; @@ -42,12 +43,11 @@ export function getAdserverCategoryHook(fn, adUnitCode, bid) { if (mapping) { try { mapping = JSON.parse(mapping); - mapping = mapping['data']; } catch (error) { logError('Failed to parse translation mapping file'); } if (bid.meta) { - bid.meta.adServerCatId = (bid.meta.iabSubCatId && mapping[adServerInUse] && mapping[adServerInUse]['mapping']) ? mapping[adServerInUse]['mapping'][bid.meta.iabSubCatId] : undefined; + bid.meta.adServerCatId = (bid.meta.iabSubCatId && mapping['mapping']) ? mapping['mapping'][bid.meta.iabSubCatId] : undefined; } } else { logError('Translation mapping data not found in local storage'); @@ -56,16 +56,8 @@ export function getAdserverCategoryHook(fn, adUnitCode, bid) { fn.call(this, adUnitCode, bid); } -export function initTranslation(...args) { +export function initTranslation(url, localStorageKey) { hooks['addBidResponse'].before(getAdserverCategoryHook, 50); - let url = DEFAULT_TRANSLATION_FILE_URL; - let localStorageKey = DEFAULT_IAB_TO_FW_MAPPING_KEY; - if (args && args.length > 0) { - // use publisher defined translation file - url = args[0]; - localStorageKey = DEFAULT_IAB_TO_FW_MAPPING_KEY_PUB; - } - let mappingData = getDataFromLocalStorage(localStorageKey); if (!mappingData || timestamp() < mappingData.lastUpdated + refreshInDays * 24 * 60 * 60 * 1000) { ajax(url, @@ -73,11 +65,8 @@ export function initTranslation(...args) { success: (response) => { try { response = JSON.parse(response); - let mapping = { - lastUpdated: timestamp(), - data: response - } - setDataInLocalStorage(localStorageKey, JSON.stringify(mapping)); + response['lastUpdated'] = timestamp(); + setDataInLocalStorage(localStorageKey, JSON.stringify(response)); } catch (error) { logError('Failed to parse translation mapping file'); } @@ -93,9 +82,8 @@ export function initTranslation(...args) { function setConfig(config) { if (config.translationFile) { // if publisher has defined the translation file, preload that file here - initTranslation(config.translationFile); + initTranslation(config.translationFile, DEFAULT_IAB_TO_FW_MAPPING_KEY_PUB); } } -initTranslation(); config.getConfig('brandCategoryTranslation', config => setConfig(config.brandCategoryTranslation)); diff --git a/test/spec/modules/categoryTranslation_spec.js b/test/spec/modules/categoryTranslation_spec.js index 7299f43154b..6c608d9ac6e 100644 --- a/test/spec/modules/categoryTranslation_spec.js +++ b/test/spec/modules/categoryTranslation_spec.js @@ -14,23 +14,15 @@ describe('category translation', function () { }); afterEach(function() { + fakeTranslationServer.reset(); getLocalStorageStub.restore(); config.resetConfig(); }); it('should translate iab category to adserver category', function () { - hooks['registerAdserver'].before(notifyTranslationModule); - function notifyTranslationModule(fn) { - fn.call(this, 'freewheel'); - } - getLocalStorageStub.returns(JSON.stringify({ - 'data': { - 'freewheel': { - mapping: { - 'iab-1': '1' - } - } + 'mapping': { + 'iab-1': '1' } })); let bid = { @@ -57,9 +49,9 @@ describe('category translation', function () { it('should use default mapping file if publisher has not defined in config', function () { getLocalStorageStub.returns(null); - initTranslation(); + initTranslation('http://sample.com', 'somekey'); expect(fakeTranslationServer.requests.length).to.equal(1); - expect(fakeTranslationServer.requests[0].url).to.equal('https://api.myjson.com/bins/j5d0k'); + expect(fakeTranslationServer.requests[0].url).to.equal('http://sample.com'); }); it('should use publisher defined defined mapping file', function () { @@ -69,7 +61,7 @@ describe('category translation', function () { } }); getLocalStorageStub.returns(null); - initTranslation(); + initTranslation('http://sample.com', 'somekey'); expect(fakeTranslationServer.requests.length).to.equal(2); expect(fakeTranslationServer.requests[0].url).to.equal('http://sample.com'); }); From 632f4da9d87f1c4145fd6c4dbc33d9bf52e6dcc6 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Tue, 12 Feb 2019 23:14:50 -0500 Subject: [PATCH 09/16] Update default mapping url --- modules/appnexusBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index 7a81515537b..1ea2982b111 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -32,7 +32,7 @@ const NATIVE_MAPPING = { displayUrl: 'displayurl' }; const SOURCE = 'pbjs'; -const mappingFileUrl = 'https://api.myjson.com/bins/11f7yo'; +const mappingFileUrl = 'http://acdn.adnxs.com/prebid/test/jp/appnexus-mapping.json'; export const spec = { code: BIDDER_CODE, From 8bebe7cfb1e40e94e0ae4b9acdf5853e9ab36b71 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Tue, 12 Feb 2019 23:15:01 -0500 Subject: [PATCH 10/16] add hook only once --- modules/categoryTranslation.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/categoryTranslation.js b/modules/categoryTranslation.js index f7abe6825f8..1b2d853585a 100644 --- a/modules/categoryTranslation.js +++ b/modules/categoryTranslation.js @@ -57,7 +57,15 @@ export function getAdserverCategoryHook(fn, adUnitCode, bid) { } export function initTranslation(url, localStorageKey) { - hooks['addBidResponse'].before(getAdserverCategoryHook, 50); + // TODO use function from adpod module + function setupHookFnOnce(hookId, hookFn, priority = 15) { + let result = hooks[hookId].getHooks({hook: hookFn}); + if (result.length === 0) { + hooks[hookId].before(hookFn, priority); + } + } + + setupHookFnOnce('addBidResponse', getAdserverCategoryHook, 50); let mappingData = getDataFromLocalStorage(localStorageKey); if (!mappingData || timestamp() < mappingData.lastUpdated + refreshInDays * 24 * 60 * 60 * 1000) { ajax(url, From 37695d7af59dac17199bbd72701c13bd16f013f1 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Tue, 19 Feb 2019 15:17:56 -0500 Subject: [PATCH 11/16] update mapping url --- modules/appnexusBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index 1ea2982b111..375c7d45c78 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -32,7 +32,7 @@ const NATIVE_MAPPING = { displayUrl: 'displayurl' }; const SOURCE = 'pbjs'; -const mappingFileUrl = 'http://acdn.adnxs.com/prebid/test/jp/appnexus-mapping.json'; +const mappingFileUrl = '//acdn.adnxs.com/prebid/appnexus-mapping/mappings.json'; export const spec = { code: BIDDER_CODE, From d9a818f179a0832289960ae341d6f8d20957fb4b Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Mon, 25 Feb 2019 23:50:48 -0500 Subject: [PATCH 12/16] Update brandCategoryExclusion logic --- modules/categoryTranslation.js | 15 +++++--- src/adapters/bidderFactory.js | 3 ++ test/spec/modules/categoryTranslation_spec.js | 35 +++++++++++++++++-- test/spec/unit/core/bidderFactory_spec.js | 19 ++++++++++ 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/modules/categoryTranslation.js b/modules/categoryTranslation.js index 1b2d853585a..7d27226940a 100644 --- a/modules/categoryTranslation.js +++ b/modules/categoryTranslation.js @@ -16,8 +16,8 @@ import { hooks, hook } from '../src/hook'; import { ajax } from '../src/ajax'; import { timestamp, logError, setDataInLocalStorage, getDataFromLocalStorage } from '../src/utils'; -// TODO udpate url once it is uploaded on cdn -const DEFAULT_TRANSLATION_FILE_URL = 'http://acdn.adnxs.com/prebid/test/jp/freewheel-mapping.json'; +// TODO udpate url once it is uploaded on jsDelivr +const DEFAULT_TRANSLATION_FILE_URL = '//api.myjson.com/bins/dw1tm'; const DEFAULT_IAB_TO_FW_MAPPING_KEY = 'iabToFwMappingkey'; const DEFAULT_IAB_TO_FW_MAPPING_KEY_PUB = 'iabToFwMappingkeyPub'; const refreshInDays = 1; @@ -36,6 +36,10 @@ export function getAdserverCategoryHook(fn, adUnitCode, bid) { return fn.call(this, adUnitCode); // if no bid, call original and let it display warnings } + if (!config.getConfig('adpod.brandCategoryExclusion')) { + return fn.call(this, adUnitCode, bid); + } + let localStorageKey = (config.getConfig('brandCategoryTranslation.translationFile')) ? DEFAULT_IAB_TO_FW_MAPPING_KEY_PUB : DEFAULT_IAB_TO_FW_MAPPING_KEY; if (bid.meta && !bid.meta.adServerCatId) { @@ -46,8 +50,11 @@ export function getAdserverCategoryHook(fn, adUnitCode, bid) { } catch (error) { logError('Failed to parse translation mapping file'); } - if (bid.meta) { - bid.meta.adServerCatId = (bid.meta.iabSubCatId && mapping['mapping']) ? mapping['mapping'][bid.meta.iabSubCatId] : undefined; + if (bid.meta.iabSubCatId && mapping['mapping'] && mapping['mapping'][bid.meta.iabSubCatId]) { + bid.meta.adServerCatId = mapping['mapping'][bid.meta.iabSubCatId]['id']; + } else { + // This bid will be automatically ignored by adpod module as adServerCatId was not found + bid.meta.adServerCatId = undefined; } } else { logError('Translation mapping data not found in local storage'); diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index 3d45421e547..8c85285bd0a 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -348,6 +348,9 @@ export function newBidder(spec) { } export function preloadBidderMappingFile(fn, adUnits) { + if (!config.getConfig('adpod.brandCategoryExclusion')) { + return fn.call(this, adUnits); + } let adPodBidders = adUnits .filter((adUnit) => deepAccess(adUnit, 'mediaTypes.video.context') === ADPOD) .map((adUnit) => adUnit.bids.map((bid) => bid.bidder)) diff --git a/test/spec/modules/categoryTranslation_spec.js b/test/spec/modules/categoryTranslation_spec.js index 6c608d9ac6e..e601c690b60 100644 --- a/test/spec/modules/categoryTranslation_spec.js +++ b/test/spec/modules/categoryTranslation_spec.js @@ -20,9 +20,17 @@ describe('category translation', function () { }); it('should translate iab category to adserver category', function () { + config.setConfig({ + 'adpod': { + 'brandCategoryExclusion': true + } + }); getLocalStorageStub.returns(JSON.stringify({ 'mapping': { - 'iab-1': '1' + 'iab-1': { + 'id': 1, + 'name': 'sample' + } } })); let bid = { @@ -31,7 +39,30 @@ describe('category translation', function () { } } getAdserverCategoryHook(sinon.spy(), 'code', bid); - expect(bid.meta.adServerCatId).to.equal('1'); + expect(bid.meta.adServerCatId).to.equal(1); + }); + + it('should set adserverCatId to undefined if not found in mapping file', function() { + config.setConfig({ + 'adpod': { + 'brandCategoryExclusion': true + } + }); + getLocalStorageStub.returns(JSON.stringify({ + 'mapping': { + 'iab-1': { + 'id': 1, + 'name': 'sample' + } + } + })); + let bid = { + meta: { + iabSubCatId: 'iab-2' + } + } + getAdserverCategoryHook(sinon.spy(), 'code', bid); + expect(bid.meta.adServerCatId).to.equal(undefined); }); it('should not make ajax call to update mapping file if data found in localstorage and is not expired', function () { diff --git a/test/spec/unit/core/bidderFactory_spec.js b/test/spec/unit/core/bidderFactory_spec.js index 0ae09edeb83..9e201afbe6c 100644 --- a/test/spec/unit/core/bidderFactory_spec.js +++ b/test/spec/unit/core/bidderFactory_spec.js @@ -790,9 +790,15 @@ describe('preload mapping url hook', function() { afterEach(function() { getLocalStorageStub.restore(); adapterManagerStub.restore(); + config.resetConfig(); }); it('should preload mapping url file', function() { + config.setConfig({ + 'adpod': { + 'brandCategoryExclusion': true + } + }); let adUnits = [{ code: 'midroll_1', mediaTypes: { @@ -828,6 +834,11 @@ describe('preload mapping url hook', function() { }); it('should preload mapping url file for all bidders', function() { + config.setConfig({ + 'adpod': { + 'brandCategoryExclusion': true + } + }); let adUnits = [{ code: 'midroll_1', mediaTypes: { @@ -879,5 +890,13 @@ describe('preload mapping url hook', function() { }); preloadBidderMappingFile(sinon.spy(), adUnits); expect(fakeTranslationServer.requests.length).to.equal(2); + + config.setConfig({ + 'adpod': { + 'brandCategoryExclusion': false + } + }); + preloadBidderMappingFile(sinon.spy(), adUnits); + expect(fakeTranslationServer.requests.length).to.equal(2); }); }); From f7f65c29d2831b13f71d2f61860f5fe63ce9fa24 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Tue, 26 Feb 2019 15:22:26 -0500 Subject: [PATCH 13/16] wrap in try catch --- src/utils.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/utils.js b/src/utils.js index 7239cd86bcd..4138401833a 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1200,7 +1200,11 @@ export function getDataFromLocalStorage(key) { } export function hasLocalStorage() { - return !!window.localStorage; + try { + return !!window.localStorage; + } catch (e) { + logError('Local storage api disabled'); + } } export function isArrayOfNums(val, size) { From e334120194ec1bbf9674b84109d5ad9149f71e20 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Tue, 26 Feb 2019 15:22:59 -0500 Subject: [PATCH 14/16] update todos and add default refreshInDays --- modules/categoryTranslation.js | 5 ++--- src/adapters/bidderFactory.js | 5 ++++- test/spec/modules/categoryTranslation_spec.js | 1 - 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/categoryTranslation.js b/modules/categoryTranslation.js index 7d27226940a..eb187b25998 100644 --- a/modules/categoryTranslation.js +++ b/modules/categoryTranslation.js @@ -8,7 +8,7 @@ * 'translationFile': 'http://sample.com' * } * }); - * If publisher has not defined translation file than prebid will use default prebid translation file provided here + * If publisher has not defined translation file than prebid will use default prebid translation file provided here //cdn.jsdelivr.net/gh/prebid/category-mapping-file@1/freewheel-mapping.json */ import { config } from '../src/config'; @@ -16,8 +16,7 @@ import { hooks, hook } from '../src/hook'; import { ajax } from '../src/ajax'; import { timestamp, logError, setDataInLocalStorage, getDataFromLocalStorage } from '../src/utils'; -// TODO udpate url once it is uploaded on jsDelivr -const DEFAULT_TRANSLATION_FILE_URL = '//api.myjson.com/bins/dw1tm'; +const DEFAULT_TRANSLATION_FILE_URL = '//cdn.jsdelivr.net/gh/prebid/category-mapping-file@1/freewheel-mapping.json'; const DEFAULT_IAB_TO_FW_MAPPING_KEY = 'iabToFwMappingkey'; const DEFAULT_IAB_TO_FW_MAPPING_KEY_PUB = 'iabToFwMappingkeyPub'; const refreshInDays = 1; diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index 8c85285bd0a..dca88890be6 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -128,6 +128,8 @@ import { ADPOD } from '../mediaTypes'; // common params for all mediaTypes const COMMON_BID_RESPONSE_KEYS = ['requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency']; +const DEFAULT_REFRESHIN_DAYS = 1; + /** * Register a bidder with prebid, using the given spec. * @@ -361,9 +363,10 @@ export function preloadBidderMappingFile(fn, adUnits) { let bidderSpec = adapterManager.getBidAdapter(bidder); if (bidderSpec.getSpec().getMappingFileInfo) { let info = bidderSpec.getSpec().getMappingFileInfo(); + let refreshInDays = (info.refreshInDays) ? info.refreshInDays : DEFAULT_REFRESHIN_DAYS; let key = (info.localStorageKey) ? info.localStorageKey : bidderSpec.getSpec().code; let mappingData = getDataFromLocalStorage(key); - if (!mappingData || timestamp() < mappingData.lastUpdated + info.refreshInDays * 24 * 60 * 60 * 1000) { + if (!mappingData || timestamp() < mappingData.lastUpdated + refreshInDays * 24 * 60 * 60 * 1000) { ajax(info.url, { success: (response) => { diff --git a/test/spec/modules/categoryTranslation_spec.js b/test/spec/modules/categoryTranslation_spec.js index e601c690b60..17cc07269b0 100644 --- a/test/spec/modules/categoryTranslation_spec.js +++ b/test/spec/modules/categoryTranslation_spec.js @@ -2,7 +2,6 @@ import { getAdserverCategoryHook, initTranslation } from 'modules/categoryTransl import { config } from 'src/config'; import * as utils from 'src/utils'; import { expect } from 'chai'; -import { hooks } from 'src/hook'; describe('category translation', function () { let fakeTranslationServer; From d31d8d904f187e1b16d1388829f28c79f88301e1 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Wed, 27 Feb 2019 12:07:27 -0500 Subject: [PATCH 15/16] udpate hooks --- modules/categoryTranslation.js | 13 +---- package-lock.json | 103 +++++++++++++++++++-------------- src/adapters/bidderFactory.js | 4 +- src/prebid.js | 5 +- 4 files changed, 68 insertions(+), 57 deletions(-) diff --git a/modules/categoryTranslation.js b/modules/categoryTranslation.js index eb187b25998..ee1b088e408 100644 --- a/modules/categoryTranslation.js +++ b/modules/categoryTranslation.js @@ -12,9 +12,10 @@ */ import { config } from '../src/config'; -import { hooks, hook } from '../src/hook'; +import { setupBeforeHookFnOnce, hook } from '../src/hook'; import { ajax } from '../src/ajax'; import { timestamp, logError, setDataInLocalStorage, getDataFromLocalStorage } from '../src/utils'; +import { addBidResponse } from '../src/auction'; const DEFAULT_TRANSLATION_FILE_URL = '//cdn.jsdelivr.net/gh/prebid/category-mapping-file@1/freewheel-mapping.json'; const DEFAULT_IAB_TO_FW_MAPPING_KEY = 'iabToFwMappingkey'; @@ -63,15 +64,7 @@ export function getAdserverCategoryHook(fn, adUnitCode, bid) { } export function initTranslation(url, localStorageKey) { - // TODO use function from adpod module - function setupHookFnOnce(hookId, hookFn, priority = 15) { - let result = hooks[hookId].getHooks({hook: hookFn}); - if (result.length === 0) { - hooks[hookId].before(hookFn, priority); - } - } - - setupHookFnOnce('addBidResponse', getAdserverCategoryHook, 50); + setupBeforeHookFnOnce(addBidResponse, getAdserverCategoryHook, 50); let mappingData = getDataFromLocalStorage(localStorageKey); if (!mappingData || timestamp() < mappingData.lastUpdated + refreshInDays * 24 * 60 * 60 * 1000) { ajax(url, diff --git a/package-lock.json b/package-lock.json index 69e270c5505..d51bb4a9dab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3038,7 +3038,7 @@ }, "query-string": { "version": "5.1.1", - "resolved": "http://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", "dev": true, "requires": { @@ -3463,7 +3463,7 @@ }, "commander": { "version": "2.15.1", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "dev": true }, @@ -4590,7 +4590,7 @@ "engine.io": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", - "integrity": "sha1-tgKBw1SEpw7gNR6g6/+D7IyVIqI=", + "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", "dev": true, "requires": { "accepts": "~1.3.4", @@ -4604,7 +4604,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -4620,7 +4620,7 @@ }, "engine.io-client": { "version": "3.2.1", - "resolved": "http://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", "dev": true, "requires": { @@ -4640,7 +4640,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -5333,7 +5333,7 @@ }, "event-stream": { "version": "3.3.4", - "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", "dev": true, "requires": { @@ -5846,7 +5846,7 @@ "flatted": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", - "integrity": "sha1-VRIrZTbqSWtLRIk+4mCBQdENmRY=", + "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", "dev": true }, "flush-write-stream": { @@ -6044,7 +6044,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -6065,12 +6066,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6085,17 +6088,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -6212,7 +6218,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -6224,6 +6231,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -6238,6 +6246,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -6245,12 +6254,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -6269,6 +6280,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -6349,7 +6361,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -6361,6 +6374,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -6446,7 +6460,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -6482,6 +6497,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6501,6 +6517,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -6544,12 +6561,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -7343,7 +7362,7 @@ "gulp-connect": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/gulp-connect/-/gulp-connect-5.7.0.tgz", - "integrity": "sha1-fpJfXkw06/7fnzGFdpZuj+iEDVo=", + "integrity": "sha512-8tRcC6wgXMLakpPw9M7GRJIhxkYdgZsXwn7n56BA2bQYGLR9NOPhMzx7js+qYDy6vhNkbApGKURjAw1FjY4pNA==", "dev": true, "requires": { "ansi-colors": "^2.0.5", @@ -7360,7 +7379,7 @@ "ansi-colors": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-2.0.5.tgz", - "integrity": "sha1-XaN4Jf7z51872kf3YNZL/RDhXhA=", + "integrity": "sha512-yAdfUZ+c2wetVNIFsNRn44THW+Lty6S5TwMpUfLA/UaGhiXbBv/F8E60/1hMLd0cnF/CDoWH8vzVaI5bAcHCjw==", "dev": true } } @@ -8105,7 +8124,7 @@ }, "http-errors": { "version": "1.6.3", - "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { @@ -9094,7 +9113,7 @@ "karma": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/karma/-/karma-3.1.4.tgz", - "integrity": "sha1-OJDKlyKxDR0UtybhM1kxRVeISZ4=", + "integrity": "sha512-31Vo8Qr5glN+dZEVIpnPCxEGleqE0EY6CtC2X9TagRV3rRQ3SNrvfhddICkJgUK3AgqpeKSZau03QumTGhGoSw==", "dev": true, "requires": { "bluebird": "^3.3.0", @@ -9130,7 +9149,7 @@ "mime": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", - "integrity": "sha1-4FH9iBNYWF8yed8zP+aU2gvP/dY=", + "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", "dev": true }, "rimraf": { @@ -9803,7 +9822,7 @@ "log4js": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.6.tgz", - "integrity": "sha1-5srO2Uln7uuc45n5+GgqSysoyP8=", + "integrity": "sha512-ezXZk6oPJCWL483zj64pNkMuY/NcRX5MPiB0zE6tjZM137aeusrOnW1ecxgF9cmwMWkBMhjteQxBPoZBh9FDxQ==", "dev": true, "requires": { "circular-json": "^0.5.5", @@ -9816,7 +9835,7 @@ "circular-json": { "version": "0.5.9", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", - "integrity": "sha1-kydjroj0996teg0JyKUaR0OlOx0=", + "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==", "dev": true }, "debug": { @@ -10337,7 +10356,7 @@ }, "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, @@ -10373,7 +10392,7 @@ "dependencies": { "minimist": { "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true } @@ -10981,7 +11000,7 @@ "opn": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", - "integrity": "sha1-y1Reeqt4VivrEao7+rxwQuF2EDU=", + "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", "dev": true, "requires": { "is-wsl": "^1.1.0" @@ -10999,7 +11018,7 @@ "dependencies": { "minimist": { "version": "0.0.10", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", "dev": true }, @@ -12591,7 +12610,7 @@ "rfdc": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.2.tgz", - "integrity": "sha1-5uctdPXcOd6PU49l4Aw2wYAY40k=", + "integrity": "sha512-92ktAgvZhBzYTIK0Mja9uen5q5J3NRVMoDkJL2VMwq6SXjVCgqvQeVP2XAaUY6HT+XpQYeLSjb3UoitBryKmdA==", "dev": true }, "right-align": { @@ -13046,7 +13065,7 @@ "socket.io": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", - "integrity": "sha1-oGnF/qvuPmshSnW0DOBlLhz7mYA=", + "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", "dev": true, "requires": { "debug": "~3.1.0", @@ -13060,7 +13079,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -13083,7 +13102,7 @@ "socket.io-client": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", - "integrity": "sha1-3LOBA0NqtFeN2wJmOK4vIbYjZx8=", + "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", "dev": true, "requires": { "backo2": "1.0.2", @@ -13105,7 +13124,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -13121,7 +13140,7 @@ }, "socket.io-parser": { "version": "3.2.0", - "resolved": "http://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", "dev": true, "requires": { @@ -13133,7 +13152,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -13271,7 +13290,7 @@ }, "split": { "version": "0.3.3", - "resolved": "http://registry.npmjs.org/split/-/split-0.3.3.tgz", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", "dev": true, "requires": { @@ -13399,7 +13418,7 @@ }, "stream-combiner": { "version": "0.0.4", - "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", "dev": true, "requires": { @@ -14267,7 +14286,7 @@ "dependencies": { "bluebird": { "version": "3.4.7", - "resolved": "http://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", "dev": true } @@ -14368,7 +14387,7 @@ "useragent": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", - "integrity": "sha1-IX+UOtVAyyEoZYqyP8lg9qiMmXI=", + "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", "dev": true, "requires": { "lru-cache": "4.1.x", @@ -15045,7 +15064,7 @@ }, "webpack-dev-middleware": { "version": "2.0.6", - "resolved": "http://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-2.0.6.tgz", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-2.0.6.tgz", "integrity": "sha512-tj5LLD9r4tDuRIDa5Mu9lnY2qBBehAITv6A9irqXhw/HQquZgTx3BCd57zYbU2gMDnncA49ufK2qVQSbaKJwOw==", "dev": true, "requires": { diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index dca88890be6..5b51c400dc1 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -11,7 +11,7 @@ import includes from 'core-js/library/fn/array/includes'; import { ajax } from '../ajax'; import { logWarn, logError, parseQueryStringParameters, delayExecution, parseSizesInput, getBidderRequest, flatten, uniques, timestamp, setDataInLocalStorage, getDataFromLocalStorage, deepAccess } from '../utils'; import { ADPOD } from '../mediaTypes'; - +import { checkAdUnitSetup } from '../src/prebid'; /** * This file aims to support Adapters during the Prebid 0.x -> 1.x transition. * @@ -392,6 +392,8 @@ export function preloadBidderMappingFile(fn, adUnits) { fn.call(this, adUnits); } +checkAdUnitSetup.before(preloadBidderMappingFile); + /** * Reads the data stored in localstorage and returns iab subcategory * @param {string} bidderCode bidderCode diff --git a/src/prebid.js b/src/prebid.js index d5de071a265..75f0cd9a6d9 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -8,13 +8,12 @@ import { loadScript } from './adloader'; import { config } from './config'; import { auctionManager } from './auctionManager'; import { targeting, getHighestCpmBidsFromBidPool } from './targeting'; -import { hook, hooks } from './hook'; +import { hook } from './hook'; import { sessionLoader } from './debugging'; import includes from 'core-js/library/fn/array/includes'; import { adunitCounter } from './adUnits'; import { isRendererRequired, executeRenderer } from './Renderer'; import { createBid } from './bidfactory'; -import { preloadBidderMappingFile } from './adapters/bidderFactory'; const $$PREBID_GLOBAL$$ = getGlobal(); const CONSTANTS = require('./constants.json'); @@ -126,8 +125,6 @@ const checkAdUnitSetup = hook('sync', function (adUnits) { return adUnits; }, 'checkAdUnitSetup'); -hooks['checkAdUnitSetup'].before(preloadBidderMappingFile); - /// /////////////////////////////// // // // Start Public APIs // From 2e8fe49a6900a83bd8ecb9abac77af6aed84302f Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Wed, 27 Feb 2019 12:41:48 -0500 Subject: [PATCH 16/16] update hook --- src/adapters/bidderFactory.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js index 5b51c400dc1..a65c657cbb5 100644 --- a/src/adapters/bidderFactory.js +++ b/src/adapters/bidderFactory.js @@ -11,7 +11,8 @@ import includes from 'core-js/library/fn/array/includes'; import { ajax } from '../ajax'; import { logWarn, logError, parseQueryStringParameters, delayExecution, parseSizesInput, getBidderRequest, flatten, uniques, timestamp, setDataInLocalStorage, getDataFromLocalStorage, deepAccess } from '../utils'; import { ADPOD } from '../mediaTypes'; -import { checkAdUnitSetup } from '../src/prebid'; +import { getHook } from '../hook'; + /** * This file aims to support Adapters during the Prebid 0.x -> 1.x transition. * @@ -392,7 +393,7 @@ export function preloadBidderMappingFile(fn, adUnits) { fn.call(this, adUnits); } -checkAdUnitSetup.before(preloadBidderMappingFile); +getHook('checkAdUnitSetup').before(preloadBidderMappingFile); /** * Reads the data stored in localstorage and returns iab subcategory