From 8f9b509c320a2f6b94e5580847b9f1b3ad6cfffd Mon Sep 17 00:00:00 2001 From: mediaconsortium-develop Date: Fri, 12 Mar 2021 21:00:09 +0900 Subject: [PATCH 1/7] add dgkeywordRtdProvider --- modules/.submodules.json | 1 + modules/dgkeywordRtdProvider.js | 126 ++++++++ modules/dgkeywordRtdProvider.md | 35 +++ .../spec/modules/dgkeywordRtdProvider_spec.js | 290 ++++++++++++++++++ 4 files changed, 452 insertions(+) create mode 100644 modules/dgkeywordRtdProvider.js create mode 100644 modules/dgkeywordRtdProvider.md create mode 100644 test/spec/modules/dgkeywordRtdProvider_spec.js diff --git a/modules/.submodules.json b/modules/.submodules.json index fc69dd276a3..877b5acfd2f 100644 --- a/modules/.submodules.json +++ b/modules/.submodules.json @@ -28,6 +28,7 @@ ], "rtdModule": [ "browsiRtdProvider", + "dgkeywordRtdProvider", "haloRtdProvider", "jwplayerRtdProvider", "reconciliationRtdProvider", diff --git a/modules/dgkeywordRtdProvider.js b/modules/dgkeywordRtdProvider.js new file mode 100644 index 00000000000..4e59cafccb3 --- /dev/null +++ b/modules/dgkeywordRtdProvider.js @@ -0,0 +1,126 @@ +/** + * This module adds dgkeyword provider to the eal time data module + * The {@link module:modules/realTimeData} module is required + * The module will get keywords from 1plux profile api + * @module modules/dgkeywordProvider + * @requires module:modules/realTimeData + */ + +import * as utils from '../src/utils.js'; +import { submodule } from '../src/hook.js'; +import { getGlobal } from '../src/prebidGlobal.js'; + +/** + * get keywords from api server. and set keywords. + * @param {Object} reqBidsConfigObj + * @param {function} callback + * @param {Object} config + * @param {Object} userConsent + */ +export function getDgKeywordsAndSet(reqBidsConfigObj, callback, config, userConsent) { + const URL = 'https://profiles.tagger.opecloud.com/api/v1/mediaconsortium/profile?url='; + const PROFILE_TIMEOUT_MS = 1000; + const timeout = (config && config.params && config.params.timeout && Number(config.params.timeout) > 0) ? Number(config.params.timeout) : PROFILE_TIMEOUT_MS; + const url = (config && config.params && config.params.url) ? config.params.url : URL + encodeURIComponent(window.location.href); + const adUnits = reqBidsConfigObj.adUnits || getGlobal().adUnits; + let isFinish = false; + utils.logMessage('[dgkeyword sub module]', adUnits, timeout); + let setKeywordTargetBidders = getTargetBidderOfDgKeywords(adUnits); + if (setKeywordTargetBidders.length <= 0) { + utils.logMessage('[dgkeyword sub module] no dgkeyword targets.'); + callback(); + } else { + utils.logMessage('[dgkeyword sub module] dgkeyword targets:', setKeywordTargetBidders); + utils.logMessage('[dgkeyword sub module] get targets from profile api start.'); + try { + fetch(url, { + referrerPolicy: 'no-referrer-when-downgrade', + mode: 'cors', + credentials: 'include' + }).then(function (response) { + if (response.status === 200) { + return response.json(); + } else { + throw new Error('profile api access error.'); + } + }).then(function (res) { + if (!isFinish) { + utils.logMessage('[dgkeyword sub module] get targets from profile api end.'); + if (res) { + let keywords = {}; + if (res['s'] != null && res['s'].length > 0) { + keywords['opeaud'] = res['s']; + } + if (res['t'] != null && res['t'].length > 0) { + keywords['opectx'] = res['t']; + } + if (Object.keys(keywords).length > 0) { + for (let bid of setKeywordTargetBidders) { + bid.params.keywords = keywords; + } + } + } + isFinish = true; + } + callback(); + }).catch(function (error) { + // error occur + utils.logError('[dgkeyword sub module] profile api access error.', error); + callback(); + }); + setTimeout(function () { + if (!isFinish) { + // profile api timeout + utils.logInfo('[dgkeyword sub module] profile api timeout. [timeout: ' + timeout + 'ms]'); + isFinish = true; + } + callback(); + }, timeout); + } catch (error) { + utils.logError('[dgkeyword sub module] fetch error.', error); + callback(); + } + } +} + +/** + * get all bidder which hava {dgkeyword: true} in params + * @param {Object} adUnits + */ +export function getTargetBidderOfDgKeywords(adUnits) { + let setKeywordTargetBidders = []; + for (let adUnit of adUnits) { + for (let bid of adUnit.bids) { + if (bid.params && bid.params['dgkeyword'] === true) { + delete bid.params['dgkeyword']; + setKeywordTargetBidders.push(bid); + } + } + } + return setKeywordTargetBidders; +} + +/** @type {RtdSubmodule} */ +export const dgkeywordSubmodule = { + /** + * used to link submodule with realTimeData + * @type {string} + */ + name: 'dgkeyword', + /** + * get data and send back to realTimeData module + * @function + * @param {string[]} adUnitsCodes + */ + getBidRequestData: getDgKeywordsAndSet, + init: init, +}; + +function init(moduleConfig) { + return true; +} + +function registerSubModule() { + submodule('realTimeData', dgkeywordSubmodule); +} +registerSubModule(); diff --git a/modules/dgkeywordRtdProvider.md b/modules/dgkeywordRtdProvider.md new file mode 100644 index 00000000000..5c4b68e0d7d --- /dev/null +++ b/modules/dgkeywordRtdProvider.md @@ -0,0 +1,35 @@ +## Overview + +Module Name: Digital Garage Keyword Module +Module Type: Rtd Provider +Maintainer: mediaconsortium-develop@bi.garage.co.jp + +## Integration + +1) Compile the Digital Garage Keyword Module and Appnexus Bid Adapter into your Prebid build: + +``` +gulp build --modules="dgkeywordRtdProvider,appnexusBidAdapter,..." +``` + +2) Use `setConfig` to instruct Prebid.js to initilize the dgkeyword module, as specified below. + +## Configuration + +This module is configured as part of the `realTimeData.dataProviders` + +```javascript +var DGKEYWORD_TIMEOUT = 1000; +pbjs.setConfig({ + realTimeData: { + auctionDelay: DGKEYWORD_TIMEOUT, + dataProviders: [{ + name: 'dgkeyword', + waitForIt: true, + params: { + timeout: DGKEYWORD_TIMEOUT + } + }] + } +}); +``` diff --git a/test/spec/modules/dgkeywordRtdProvider_spec.js b/test/spec/modules/dgkeywordRtdProvider_spec.js new file mode 100644 index 00000000000..728e18abc41 --- /dev/null +++ b/test/spec/modules/dgkeywordRtdProvider_spec.js @@ -0,0 +1,290 @@ +import * as dgRtd from '../../../modules/dgkeywordRtdProvider.js'; +import { cloneDeep } from 'lodash'; +import { server } from 'test/mocks/xhr.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; + +const DG_GET_KEYWORDS_TIMEOUT = 1950; +const DEF_CONFIG = { + name: 'dgkeyword', + waitForIt: true, + params: { + timeout: DG_GET_KEYWORDS_TIMEOUT + } +}; + +describe('Digital Garage Keyword Module', function () { + it('should init and return always true', function () { + expect(dgRtd.dgkeywordSubmodule.init()).to.equal(true); + }); + + describe('dgkeyword target test', function () { + it('should have no target', function () { + const adUnits_no_target = [ + { + code: 'code1', + mediaTypes: { + banner: { + sizes: [[300, 250]] + }, + }, + bids: [ + { + bidder: 'dg', + params: { + placementId: 99999999 + } + }, + { + bidder: 'dg2', + params: { + placementId: 99999998, + dgkeyword: false + } + }, + { + bidder: 'dg3', + params: { + placementId: 99999997 + } + } + ] + }, + { + code: 'code2', + mediaTypes: { + banner: { + sizes: [[300, 250]] + }, + }, + bids: [ + { + bidder: 'dg', + params: { + placementId: 99999996 + } + }, + { + bidder: 'dg2', + params: { + placementId: 99999995 + } + }, + { + bidder: 'dg3', + params: { + placementId: 99999994 + } + } + ] + }, + ]; + expect(dgRtd.getTargetBidderOfDgKeywords(adUnits_no_target)).an('array').that.is.empty; + }); + it('should have targets', function () { + const adUnits_targets = [ + { + code: 'code1', + mediaTypes: { + banner: { + sizes: [[300, 250]] + }, + }, + bids: [ + { + bidder: 'dg', + params: { + placementId: 99999999 + } + }, + { + bidder: 'dg2', + params: { + placementId: 99999998, + dgkeyword: true + } + }, + { + bidder: 'dg3', + params: { + placementId: 99999997, + dgkeyword: false + } + } + ] + }, + { + code: 'code2', + mediaTypes: { + banner: { + sizes: [[300, 250]] + }, + }, + bids: [ + { + bidder: 'dg', + params: { + placementId: 99999996, + dgkeyword: true + } + }, + { + bidder: 'dg2', + params: { + placementId: 99999995, + dgkeyword: 'aa' + } + }, + { + bidder: 'dg3', + params: { + placementId: 99999994, + dgkeyword: true + } + } + ] + }, + ]; + const targets = dgRtd.getTargetBidderOfDgKeywords(adUnits_targets); + expect(targets[0].bidder).to.be.equal('dg2'); + expect(targets[0].params.placementId).to.be.equal(99999998); + expect(targets[0].params.dgkeyword).to.be.an('undefined'); + expect(targets[1].bidder).to.be.equal('dg'); + expect(targets[1].params.placementId).to.be.equal(99999996); + expect(targets[1].params.dgkeyword).to.be.an('undefined'); + expect(targets[2].bidder).to.be.equal('dg3'); + expect(targets[2].params.placementId).to.be.equal(99999994); + expect(targets[2].params.dgkeyword).to.be.an('undefined'); + }); + }); + + describe('get profile.', function () { + const AD_UNITS = [ + { + code: 'code1', + mediaTypes: { + banner: { + sizes: [[300, 250]] + }, + }, + bids: [ + { + bidder: 'dg', + params: { + placementId: 99999999 + } + }, + { + bidder: 'dg2', + params: { + placementId: 99999998, + dgkeyword: true + } + }, + { + bidder: 'dg3', + params: { + placementId: 99999997, + dgkeyword: false + } + } + ] + }, + { + code: 'code2', + mediaTypes: { + banner: { + sizes: [[300, 250]] + }, + }, + bids: [ + { + bidder: 'dg', + params: { + placementId: 99999996, + dgkeyword: true + } + }, + { + bidder: 'dg2', + params: { + placementId: 99999995, + dgkeyword: 'aa' + } + }, + { + bidder: 'dg3', + params: { + placementId: 99999994, + dgkeyword: true + } + } + ] + }, + ]; + describe('should get profiles error.', function () { + it('should get profiles error.', function (done) { + let pdjs = getGlobal(); + pbjs.adUnits = cloneDeep(AD_UNITS); + let config = cloneDeep(DEF_CONFIG); + config.params.url = 'https://profiles.tagger.opecloud.comm'; + dgRtd.getDgKeywordsAndSet(pdjs, () => { + let targets = pbjs.adUnits[0].bids; + expect(targets[1].bidder).to.be.equal('dg2'); + expect(targets[1].params.placementId).to.be.equal(99999998); + expect(targets[1].params.dgkeyword).to.be.an('undefined'); + targets = pbjs.adUnits[1].bids; + expect(targets[0].bidder).to.be.equal('dg'); + expect(targets[0].params.placementId).to.be.equal(99999996); + expect(targets[0].params.dgkeyword).to.be.an('undefined'); + expect(targets[2].bidder).to.be.equal('dg3'); + expect(targets[2].params.placementId).to.be.equal(99999994); + expect(targets[2].params.dgkeyword).to.be.an('undefined'); + done(); + }, config, null); + }); + }); + describe('should get profiles timeout.', function () { + it('should get profiles timeout.', function (done) { + let pdjs = getGlobal(); + pbjs.adUnits = cloneDeep(AD_UNITS); + let config = cloneDeep(DEF_CONFIG); + config.params.timeout = 10; + dgRtd.getDgKeywordsAndSet(pdjs, () => { + let targets = pbjs.adUnits[0].bids; + expect(targets[1].bidder).to.be.equal('dg2'); + expect(targets[1].params.placementId).to.be.equal(99999998); + expect(targets[1].params.dgkeyword).to.be.an('undefined'); + targets = pbjs.adUnits[1].bids; + expect(targets[0].bidder).to.be.equal('dg'); + expect(targets[0].params.placementId).to.be.equal(99999996); + expect(targets[0].params.dgkeyword).to.be.an('undefined'); + expect(targets[2].bidder).to.be.equal('dg3'); + expect(targets[2].params.placementId).to.be.equal(99999994); + expect(targets[2].params.dgkeyword).to.be.an('undefined'); + done(); + }, config, null); + }); + }); + describe('should get profiles ok.', function () { + it('should get profiles ok.', function (done) { + let pdjs = getGlobal(); + pbjs.adUnits = cloneDeep(AD_UNITS); + let config = cloneDeep(DEF_CONFIG); + dgRtd.getDgKeywordsAndSet(pdjs, () => { + let targets = pbjs.adUnits[0].bids; + expect(targets[1].bidder).to.be.equal('dg2'); + expect(targets[1].params.placementId).to.be.equal(99999998); + expect(targets[1].params.dgkeyword).to.be.an('undefined'); + targets = pbjs.adUnits[1].bids; + expect(targets[0].bidder).to.be.equal('dg'); + expect(targets[0].params.placementId).to.be.equal(99999996); + expect(targets[0].params.dgkeyword).to.be.an('undefined'); + expect(targets[2].bidder).to.be.equal('dg3'); + expect(targets[2].params.placementId).to.be.equal(99999994); + expect(targets[2].params.dgkeyword).to.be.an('undefined'); + done(); + }, config, null); + }); + }); + }); +}); From f28639a84216a5548171c805a597f5cd00e9bff2 Mon Sep 17 00:00:00 2001 From: mediaconsortium-develop Date: Fri, 12 Mar 2021 22:05:12 +0900 Subject: [PATCH 2/7] change access url --- modules/dgkeywordRtdProvider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/dgkeywordRtdProvider.js b/modules/dgkeywordRtdProvider.js index 4e59cafccb3..cc3889273b0 100644 --- a/modules/dgkeywordRtdProvider.js +++ b/modules/dgkeywordRtdProvider.js @@ -18,7 +18,7 @@ import { getGlobal } from '../src/prebidGlobal.js'; * @param {Object} userConsent */ export function getDgKeywordsAndSet(reqBidsConfigObj, callback, config, userConsent) { - const URL = 'https://profiles.tagger.opecloud.com/api/v1/mediaconsortium/profile?url='; + const URL = 'https://mediaconsortium.profiles.tagger.opecloud.com/api/v1?url='; const PROFILE_TIMEOUT_MS = 1000; const timeout = (config && config.params && config.params.timeout && Number(config.params.timeout) > 0) ? Number(config.params.timeout) : PROFILE_TIMEOUT_MS; const url = (config && config.params && config.params.url) ? config.params.url : URL + encodeURIComponent(window.location.href); From ea77a52473701846ac46a0bbf7e41a25aa588ba0 Mon Sep 17 00:00:00 2001 From: mediaconsortium-develop Date: Thu, 18 Mar 2021 17:10:11 +0900 Subject: [PATCH 3/7] we change not to access real url. and one test case delete because of the changing. --- .../spec/modules/dgkeywordRtdProvider_spec.js | 208 +++++++++--------- 1 file changed, 100 insertions(+), 108 deletions(-) diff --git a/test/spec/modules/dgkeywordRtdProvider_spec.js b/test/spec/modules/dgkeywordRtdProvider_spec.js index 728e18abc41..39c7eedf569 100644 --- a/test/spec/modules/dgkeywordRtdProvider_spec.js +++ b/test/spec/modules/dgkeywordRtdProvider_spec.js @@ -4,12 +4,13 @@ import { server } from 'test/mocks/xhr.js'; import { getGlobal } from '../../../src/prebidGlobal.js'; const DG_GET_KEYWORDS_TIMEOUT = 1950; +const DG_TEST_URL = 'http://testNotExistsUrl.comm'; const DEF_CONFIG = { name: 'dgkeyword', waitForIt: true, params: { - timeout: DG_GET_KEYWORDS_TIMEOUT - } + timeout: DG_GET_KEYWORDS_TIMEOUT, + }, }; describe('Digital Garage Keyword Module', function () { @@ -24,61 +25,62 @@ describe('Digital Garage Keyword Module', function () { code: 'code1', mediaTypes: { banner: { - sizes: [[300, 250]] + sizes: [[300, 250]], }, }, bids: [ { bidder: 'dg', params: { - placementId: 99999999 - } + placementId: 99999999, + }, }, { bidder: 'dg2', params: { placementId: 99999998, - dgkeyword: false - } + dgkeyword: false, + }, }, { bidder: 'dg3', params: { - placementId: 99999997 - } - } - ] + placementId: 99999997, + }, + }, + ], }, { code: 'code2', mediaTypes: { banner: { - sizes: [[300, 250]] + sizes: [[300, 250]], }, }, bids: [ { bidder: 'dg', params: { - placementId: 99999996 - } + placementId: 99999996, + }, }, { bidder: 'dg2', params: { - placementId: 99999995 - } + placementId: 99999995, + }, }, { bidder: 'dg3', params: { - placementId: 99999994 - } - } - ] + placementId: 99999994, + }, + }, + ], }, ]; - expect(dgRtd.getTargetBidderOfDgKeywords(adUnits_no_target)).an('array').that.is.empty; + expect(dgRtd.getTargetBidderOfDgKeywords(adUnits_no_target)).an('array') + .that.is.empty; }); it('should have targets', function () { const adUnits_targets = [ @@ -86,37 +88,37 @@ describe('Digital Garage Keyword Module', function () { code: 'code1', mediaTypes: { banner: { - sizes: [[300, 250]] + sizes: [[300, 250]], }, }, bids: [ { bidder: 'dg', params: { - placementId: 99999999 - } + placementId: 99999999, + }, }, { bidder: 'dg2', params: { placementId: 99999998, - dgkeyword: true - } + dgkeyword: true, + }, }, { bidder: 'dg3', params: { placementId: 99999997, - dgkeyword: false - } - } - ] + dgkeyword: false, + }, + }, + ], }, { code: 'code2', mediaTypes: { banner: { - sizes: [[300, 250]] + sizes: [[300, 250]], }, }, bids: [ @@ -124,24 +126,24 @@ describe('Digital Garage Keyword Module', function () { bidder: 'dg', params: { placementId: 99999996, - dgkeyword: true - } + dgkeyword: true, + }, }, { bidder: 'dg2', params: { placementId: 99999995, - dgkeyword: 'aa' - } + dgkeyword: 'aa', + }, }, { bidder: 'dg3', params: { placementId: 99999994, - dgkeyword: true - } - } - ] + dgkeyword: true, + }, + }, + ], }, ]; const targets = dgRtd.getTargetBidderOfDgKeywords(adUnits_targets); @@ -163,37 +165,37 @@ describe('Digital Garage Keyword Module', function () { code: 'code1', mediaTypes: { banner: { - sizes: [[300, 250]] + sizes: [[300, 250]], }, }, bids: [ { bidder: 'dg', params: { - placementId: 99999999 - } + placementId: 99999999, + }, }, { bidder: 'dg2', params: { placementId: 99999998, - dgkeyword: true - } + dgkeyword: true, + }, }, { bidder: 'dg3', params: { placementId: 99999997, - dgkeyword: false - } - } - ] + dgkeyword: false, + }, + }, + ], }, { code: 'code2', mediaTypes: { banner: { - sizes: [[300, 250]] + sizes: [[300, 250]], }, }, bids: [ @@ -201,24 +203,24 @@ describe('Digital Garage Keyword Module', function () { bidder: 'dg', params: { placementId: 99999996, - dgkeyword: true - } + dgkeyword: true, + }, }, { bidder: 'dg2', params: { placementId: 99999995, - dgkeyword: 'aa' - } + dgkeyword: 'aa', + }, }, { bidder: 'dg3', params: { placementId: 99999994, - dgkeyword: true - } - } - ] + dgkeyword: true, + }, + }, + ], }, ]; describe('should get profiles error.', function () { @@ -226,21 +228,26 @@ describe('Digital Garage Keyword Module', function () { let pdjs = getGlobal(); pbjs.adUnits = cloneDeep(AD_UNITS); let config = cloneDeep(DEF_CONFIG); - config.params.url = 'https://profiles.tagger.opecloud.comm'; - dgRtd.getDgKeywordsAndSet(pdjs, () => { - let targets = pbjs.adUnits[0].bids; - expect(targets[1].bidder).to.be.equal('dg2'); - expect(targets[1].params.placementId).to.be.equal(99999998); - expect(targets[1].params.dgkeyword).to.be.an('undefined'); - targets = pbjs.adUnits[1].bids; - expect(targets[0].bidder).to.be.equal('dg'); - expect(targets[0].params.placementId).to.be.equal(99999996); - expect(targets[0].params.dgkeyword).to.be.an('undefined'); - expect(targets[2].bidder).to.be.equal('dg3'); - expect(targets[2].params.placementId).to.be.equal(99999994); - expect(targets[2].params.dgkeyword).to.be.an('undefined'); - done(); - }, config, null); + config.params.url = DG_TEST_URL; + dgRtd.getDgKeywordsAndSet( + pdjs, + () => { + let targets = pbjs.adUnits[0].bids; + expect(targets[1].bidder).to.be.equal('dg2'); + expect(targets[1].params.placementId).to.be.equal(99999998); + expect(targets[1].params.dgkeyword).to.be.an('undefined'); + targets = pbjs.adUnits[1].bids; + expect(targets[0].bidder).to.be.equal('dg'); + expect(targets[0].params.placementId).to.be.equal(99999996); + expect(targets[0].params.dgkeyword).to.be.an('undefined'); + expect(targets[2].bidder).to.be.equal('dg3'); + expect(targets[2].params.placementId).to.be.equal(99999994); + expect(targets[2].params.dgkeyword).to.be.an('undefined'); + done(); + }, + config, + null + ); }); }); describe('should get profiles timeout.', function () { @@ -248,42 +255,27 @@ describe('Digital Garage Keyword Module', function () { let pdjs = getGlobal(); pbjs.adUnits = cloneDeep(AD_UNITS); let config = cloneDeep(DEF_CONFIG); - config.params.timeout = 10; - dgRtd.getDgKeywordsAndSet(pdjs, () => { - let targets = pbjs.adUnits[0].bids; - expect(targets[1].bidder).to.be.equal('dg2'); - expect(targets[1].params.placementId).to.be.equal(99999998); - expect(targets[1].params.dgkeyword).to.be.an('undefined'); - targets = pbjs.adUnits[1].bids; - expect(targets[0].bidder).to.be.equal('dg'); - expect(targets[0].params.placementId).to.be.equal(99999996); - expect(targets[0].params.dgkeyword).to.be.an('undefined'); - expect(targets[2].bidder).to.be.equal('dg3'); - expect(targets[2].params.placementId).to.be.equal(99999994); - expect(targets[2].params.dgkeyword).to.be.an('undefined'); - done(); - }, config, null); - }); - }); - describe('should get profiles ok.', function () { - it('should get profiles ok.', function (done) { - let pdjs = getGlobal(); - pbjs.adUnits = cloneDeep(AD_UNITS); - let config = cloneDeep(DEF_CONFIG); - dgRtd.getDgKeywordsAndSet(pdjs, () => { - let targets = pbjs.adUnits[0].bids; - expect(targets[1].bidder).to.be.equal('dg2'); - expect(targets[1].params.placementId).to.be.equal(99999998); - expect(targets[1].params.dgkeyword).to.be.an('undefined'); - targets = pbjs.adUnits[1].bids; - expect(targets[0].bidder).to.be.equal('dg'); - expect(targets[0].params.placementId).to.be.equal(99999996); - expect(targets[0].params.dgkeyword).to.be.an('undefined'); - expect(targets[2].bidder).to.be.equal('dg3'); - expect(targets[2].params.placementId).to.be.equal(99999994); - expect(targets[2].params.dgkeyword).to.be.an('undefined'); - done(); - }, config, null); + config.params.timeout = 1; + config.params.url = DG_TEST_URL; + dgRtd.getDgKeywordsAndSet( + pdjs, + () => { + let targets = pbjs.adUnits[0].bids; + expect(targets[1].bidder).to.be.equal('dg2'); + expect(targets[1].params.placementId).to.be.equal(99999998); + expect(targets[1].params.dgkeyword).to.be.an('undefined'); + targets = pbjs.adUnits[1].bids; + expect(targets[0].bidder).to.be.equal('dg'); + expect(targets[0].params.placementId).to.be.equal(99999996); + expect(targets[0].params.dgkeyword).to.be.an('undefined'); + expect(targets[2].bidder).to.be.equal('dg3'); + expect(targets[2].params.placementId).to.be.equal(99999994); + expect(targets[2].params.dgkeyword).to.be.an('undefined'); + done(); + }, + config, + null + ); }); }); }); From 45dbfa6764e3fdbf7ef2486d9ff5f9ed1d36905d Mon Sep 17 00:00:00 2001 From: mediaconsortium-develop Date: Mon, 29 Mar 2021 14:00:49 +0900 Subject: [PATCH 4/7] update test code. update api access using ajax() --- modules/dgkeywordRtdProvider.js | 50 +++---- modules/dgkeywordRtdProvider.md | 2 +- .../spec/modules/dgkeywordRtdProvider_spec.js | 134 +++++++++++------- 3 files changed, 103 insertions(+), 83 deletions(-) diff --git a/modules/dgkeywordRtdProvider.js b/modules/dgkeywordRtdProvider.js index cc3889273b0..fe005eab588 100644 --- a/modules/dgkeywordRtdProvider.js +++ b/modules/dgkeywordRtdProvider.js @@ -1,12 +1,14 @@ /** - * This module adds dgkeyword provider to the eal time data module + * This module adds dgkeyword provider to the real time data module * The {@link module:modules/realTimeData} module is required - * The module will get keywords from 1plux profile api + * The module will get keywords from 1plux profile api. + * This module can work only with AppNexusBidAdapter. * @module modules/dgkeywordProvider * @requires module:modules/realTimeData */ import * as utils from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; import { submodule } from '../src/hook.js'; import { getGlobal } from '../src/prebidGlobal.js'; @@ -32,18 +34,9 @@ export function getDgKeywordsAndSet(reqBidsConfigObj, callback, config, userCons } else { utils.logMessage('[dgkeyword sub module] dgkeyword targets:', setKeywordTargetBidders); utils.logMessage('[dgkeyword sub module] get targets from profile api start.'); - try { - fetch(url, { - referrerPolicy: 'no-referrer-when-downgrade', - mode: 'cors', - credentials: 'include' - }).then(function (response) { - if (response.status === 200) { - return response.json(); - } else { - throw new Error('profile api access error.'); - } - }).then(function (res) { + ajax(url, { + success: function(response) { + const res = JSON.parse(response); if (!isFinish) { utils.logMessage('[dgkeyword sub module] get targets from profile api end.'); if (res) { @@ -63,23 +56,24 @@ export function getDgKeywordsAndSet(reqBidsConfigObj, callback, config, userCons isFinish = true; } callback(); - }).catch(function (error) { + }, + error: function(errorStatus) { // error occur - utils.logError('[dgkeyword sub module] profile api access error.', error); - callback(); - }); - setTimeout(function () { - if (!isFinish) { - // profile api timeout - utils.logInfo('[dgkeyword sub module] profile api timeout. [timeout: ' + timeout + 'ms]'); - isFinish = true; - } + utils.logError('[dgkeyword sub module] profile api access error.', errorStatus); callback(); - }, timeout); - } catch (error) { - utils.logError('[dgkeyword sub module] fetch error.', error); + } + }, null, { + withCredentials: true, + contentType: 'application/json', + }); + setTimeout(function () { + if (!isFinish) { + // profile api timeout + utils.logInfo('[dgkeyword sub module] profile api timeout. [timeout: ' + timeout + 'ms]'); + isFinish = true; + } callback(); - } + }, timeout); } } diff --git a/modules/dgkeywordRtdProvider.md b/modules/dgkeywordRtdProvider.md index 5c4b68e0d7d..7cf532ea650 100644 --- a/modules/dgkeywordRtdProvider.md +++ b/modules/dgkeywordRtdProvider.md @@ -3,7 +3,7 @@ Module Name: Digital Garage Keyword Module Module Type: Rtd Provider Maintainer: mediaconsortium-develop@bi.garage.co.jp - +Remarks: This module can work only with AppNexusBidAdapter. ## Integration 1) Compile the Digital Garage Keyword Module and Appnexus Bid Adapter into your Prebid build: diff --git a/test/spec/modules/dgkeywordRtdProvider_spec.js b/test/spec/modules/dgkeywordRtdProvider_spec.js index 39c7eedf569..aa526f5090d 100644 --- a/test/spec/modules/dgkeywordRtdProvider_spec.js +++ b/test/spec/modules/dgkeywordRtdProvider_spec.js @@ -4,7 +4,6 @@ import { server } from 'test/mocks/xhr.js'; import { getGlobal } from '../../../src/prebidGlobal.js'; const DG_GET_KEYWORDS_TIMEOUT = 1950; -const DG_TEST_URL = 'http://testNotExistsUrl.comm'; const DEF_CONFIG = { name: 'dgkeyword', waitForIt: true, @@ -12,6 +11,9 @@ const DEF_CONFIG = { timeout: DG_GET_KEYWORDS_TIMEOUT, }, }; +const DUMMY_RESPONSE_HEADER = {'Content-Type': 'application/json'}; +const DUMMY_RESPONSE = { s: ['s1', 's2'], t: ['t1', 't2'] }; +const SCCESS_RESULT = { opeaud: ['s1', 's2'], opectx: ['t1', 't2'] }; describe('Digital Garage Keyword Module', function () { it('should init and return always true', function () { @@ -223,60 +225,84 @@ describe('Digital Garage Keyword Module', function () { ], }, ]; - describe('should get profiles error.', function () { - it('should get profiles error.', function (done) { - let pdjs = getGlobal(); - pbjs.adUnits = cloneDeep(AD_UNITS); - let config = cloneDeep(DEF_CONFIG); - config.params.url = DG_TEST_URL; - dgRtd.getDgKeywordsAndSet( - pdjs, - () => { - let targets = pbjs.adUnits[0].bids; - expect(targets[1].bidder).to.be.equal('dg2'); - expect(targets[1].params.placementId).to.be.equal(99999998); - expect(targets[1].params.dgkeyword).to.be.an('undefined'); - targets = pbjs.adUnits[1].bids; - expect(targets[0].bidder).to.be.equal('dg'); - expect(targets[0].params.placementId).to.be.equal(99999996); - expect(targets[0].params.dgkeyword).to.be.an('undefined'); - expect(targets[2].bidder).to.be.equal('dg3'); - expect(targets[2].params.placementId).to.be.equal(99999994); - expect(targets[2].params.dgkeyword).to.be.an('undefined'); - done(); - }, - config, - null - ); - }); + it('should get profiles error(404).', function (done) { + let pdjs = getGlobal(); + pbjs.adUnits = cloneDeep(AD_UNITS); + let config = cloneDeep(DEF_CONFIG); + dgRtd.getDgKeywordsAndSet( + pdjs, + () => { + let targets = pbjs.adUnits[0].bids; + expect(targets[1].bidder).to.be.equal('dg2'); + expect(targets[1].params.placementId).to.be.equal(99999998); + expect(targets[1].params.dgkeyword).to.be.an('undefined'); + targets = pbjs.adUnits[1].bids; + expect(targets[0].bidder).to.be.equal('dg'); + expect(targets[0].params.placementId).to.be.equal(99999996); + expect(targets[0].params.dgkeyword).to.be.an('undefined'); + expect(targets[2].bidder).to.be.equal('dg3'); + expect(targets[2].params.placementId).to.be.equal(99999994); + expect(targets[2].params.dgkeyword).to.be.an('undefined'); + done(); + }, + config, + null + ); + const request = server.requests[0]; + request.respond(404); }); - describe('should get profiles timeout.', function () { - it('should get profiles timeout.', function (done) { - let pdjs = getGlobal(); - pbjs.adUnits = cloneDeep(AD_UNITS); - let config = cloneDeep(DEF_CONFIG); - config.params.timeout = 1; - config.params.url = DG_TEST_URL; - dgRtd.getDgKeywordsAndSet( - pdjs, - () => { - let targets = pbjs.adUnits[0].bids; - expect(targets[1].bidder).to.be.equal('dg2'); - expect(targets[1].params.placementId).to.be.equal(99999998); - expect(targets[1].params.dgkeyword).to.be.an('undefined'); - targets = pbjs.adUnits[1].bids; - expect(targets[0].bidder).to.be.equal('dg'); - expect(targets[0].params.placementId).to.be.equal(99999996); - expect(targets[0].params.dgkeyword).to.be.an('undefined'); - expect(targets[2].bidder).to.be.equal('dg3'); - expect(targets[2].params.placementId).to.be.equal(99999994); - expect(targets[2].params.dgkeyword).to.be.an('undefined'); - done(); - }, - config, - null - ); - }); + it('should get profiles timeout.', function (done) { + let pdjs = getGlobal(); + pbjs.adUnits = cloneDeep(AD_UNITS); + let config = cloneDeep(DEF_CONFIG); + config.params.timeout = 1; + dgRtd.getDgKeywordsAndSet( + pdjs, + () => { + let targets = pbjs.adUnits[0].bids; + expect(targets[1].bidder).to.be.equal('dg2'); + expect(targets[1].params.placementId).to.be.equal(99999998); + expect(targets[1].params.dgkeyword).to.be.an('undefined'); + targets = pbjs.adUnits[1].bids; + expect(targets[0].bidder).to.be.equal('dg'); + expect(targets[0].params.placementId).to.be.equal(99999996); + expect(targets[0].params.dgkeyword).to.be.an('undefined'); + expect(targets[2].bidder).to.be.equal('dg3'); + expect(targets[2].params.placementId).to.be.equal(99999994); + expect(targets[2].params.dgkeyword).to.be.an('undefined'); + done(); + }, + config, + null + ); + setTimeout(() => { + const request = server.requests[0]; + request.respond(200, DUMMY_RESPONSE_HEADER, JSON.stringify(DUMMY_RESPONSE)); + }, 1000) + }); + it('should get profiles ok(200).', function (done) { + let pdjs = getGlobal(); + pbjs.adUnits = cloneDeep(AD_UNITS); + let config = cloneDeep(DEF_CONFIG); + dgRtd.getDgKeywordsAndSet(pdjs, () => { + let targets = pbjs.adUnits[0].bids; + expect(targets[1].bidder).to.be.equal('dg2'); + expect(targets[1].params.placementId).to.be.equal(99999998); + expect(targets[1].params.dgkeyword).to.be.an('undefined'); + expect(targets[1].params.keywords).to.be.deep.equal(SCCESS_RESULT); + targets = pbjs.adUnits[1].bids; + expect(targets[0].bidder).to.be.equal('dg'); + expect(targets[0].params.placementId).to.be.equal(99999996); + expect(targets[0].params.dgkeyword).to.be.an('undefined'); + expect(targets[0].params.keywords).to.be.deep.equal(SCCESS_RESULT); + expect(targets[2].bidder).to.be.equal('dg3'); + expect(targets[2].params.placementId).to.be.equal(99999994); + expect(targets[2].params.dgkeyword).to.be.an('undefined'); + expect(targets[2].params.keywords).to.be.deep.equal(SCCESS_RESULT); + done(); + }, config, null); + const request = server.requests[0]; + request.respond(200, DUMMY_RESPONSE_HEADER, JSON.stringify(DUMMY_RESPONSE)); }); }); }); From ba54e75677802e99ebed557c18b6c8bdbac3c1b1 Mon Sep 17 00:00:00 2001 From: mediaconsortium-develop Date: Wed, 14 Apr 2021 15:02:48 +0900 Subject: [PATCH 5/7] update test code --- test/spec/modules/dgkeywordRtdProvider_spec.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/spec/modules/dgkeywordRtdProvider_spec.js b/test/spec/modules/dgkeywordRtdProvider_spec.js index aa526f5090d..8db92d49322 100644 --- a/test/spec/modules/dgkeywordRtdProvider_spec.js +++ b/test/spec/modules/dgkeywordRtdProvider_spec.js @@ -255,7 +255,7 @@ describe('Digital Garage Keyword Module', function () { let pdjs = getGlobal(); pbjs.adUnits = cloneDeep(AD_UNITS); let config = cloneDeep(DEF_CONFIG); - config.params.timeout = 1; + config.params.timeout = 10; dgRtd.getDgKeywordsAndSet( pdjs, () => { @@ -277,7 +277,9 @@ describe('Digital Garage Keyword Module', function () { ); setTimeout(() => { const request = server.requests[0]; - request.respond(200, DUMMY_RESPONSE_HEADER, JSON.stringify(DUMMY_RESPONSE)); + if (request) { + request.respond(200, DUMMY_RESPONSE_HEADER, JSON.stringify(DUMMY_RESPONSE)); + } }, 1000) }); it('should get profiles ok(200).', function (done) { From cdb6802480c2ac987433859ef42f2691fae62ea4 Mon Sep 17 00:00:00 2001 From: mediaconsortium-develop Date: Fri, 7 May 2021 15:27:14 +0900 Subject: [PATCH 6/7] set keywords using setBidderConfig in ortb2. --- modules/dgkeywordRtdProvider.js | 20 +++++++-- .../spec/modules/dgkeywordRtdProvider_spec.js | 44 +++++++++++++------ 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/modules/dgkeywordRtdProvider.js b/modules/dgkeywordRtdProvider.js index fe005eab588..52fa9fd70c4 100644 --- a/modules/dgkeywordRtdProvider.js +++ b/modules/dgkeywordRtdProvider.js @@ -16,14 +16,14 @@ import { getGlobal } from '../src/prebidGlobal.js'; * get keywords from api server. and set keywords. * @param {Object} reqBidsConfigObj * @param {function} callback - * @param {Object} config + * @param {Object} moduleConfig * @param {Object} userConsent */ -export function getDgKeywordsAndSet(reqBidsConfigObj, callback, config, userConsent) { +export function getDgKeywordsAndSet(reqBidsConfigObj, callback, moduleConfig, userConsent) { const URL = 'https://mediaconsortium.profiles.tagger.opecloud.com/api/v1?url='; const PROFILE_TIMEOUT_MS = 1000; - const timeout = (config && config.params && config.params.timeout && Number(config.params.timeout) > 0) ? Number(config.params.timeout) : PROFILE_TIMEOUT_MS; - const url = (config && config.params && config.params.url) ? config.params.url : URL + encodeURIComponent(window.location.href); + const timeout = (moduleConfig && moduleConfig.params && moduleConfig.params.timeout && Number(moduleConfig.params.timeout) > 0) ? Number(moduleConfig.params.timeout) : PROFILE_TIMEOUT_MS; + const url = (moduleConfig && moduleConfig.params && moduleConfig.params.url) ? moduleConfig.params.url : URL + encodeURIComponent(window.location.href); const adUnits = reqBidsConfigObj.adUnits || getGlobal().adUnits; let isFinish = false; utils.logMessage('[dgkeyword sub module]', adUnits, timeout); @@ -48,9 +48,21 @@ export function getDgKeywordsAndSet(reqBidsConfigObj, callback, config, userCons keywords['opectx'] = res['t']; } if (Object.keys(keywords).length > 0) { + const targetBidKeys = {} for (let bid of setKeywordTargetBidders) { + // set keywords to params bid.params.keywords = keywords; + if (!targetBidKeys[bid.bidder]) { + targetBidKeys[bid.bidder] = true; + } } + + // set keywrods to ortb2 + let addOrtb2 = {}; + utils.deepSetValue(addOrtb2, 'site.keywords', keywords); + utils.deepSetValue(addOrtb2, 'user.keywords', keywords); + const ortb2 = {ortb2: addOrtb2}; + getGlobal().setBidderConfig({ bidders: Object.keys(targetBidKeys), config: ortb2 }); } } isFinish = true; diff --git a/test/spec/modules/dgkeywordRtdProvider_spec.js b/test/spec/modules/dgkeywordRtdProvider_spec.js index 8db92d49322..990ddd9ccf6 100644 --- a/test/spec/modules/dgkeywordRtdProvider_spec.js +++ b/test/spec/modules/dgkeywordRtdProvider_spec.js @@ -1,7 +1,8 @@ -import * as dgRtd from '../../../modules/dgkeywordRtdProvider.js'; +import * as dgRtd from 'modules/dgkeywordRtdProvider.js'; import { cloneDeep } from 'lodash'; import { server } from 'test/mocks/xhr.js'; -import { getGlobal } from '../../../src/prebidGlobal.js'; +import { getGlobal } from 'src/prebidGlobal.js'; +import { config } from 'src/config.js'; const DG_GET_KEYWORDS_TIMEOUT = 1950; const DEF_CONFIG = { @@ -13,7 +14,8 @@ const DEF_CONFIG = { }; const DUMMY_RESPONSE_HEADER = {'Content-Type': 'application/json'}; const DUMMY_RESPONSE = { s: ['s1', 's2'], t: ['t1', 't2'] }; -const SCCESS_RESULT = { opeaud: ['s1', 's2'], opectx: ['t1', 't2'] }; +const SUCCESS_RESULT = { opeaud: ['s1', 's2'], opectx: ['t1', 't2'] }; +const SUCCESS_ORTB2 = { ortb2: { site: { keywords: SUCCESS_RESULT }, user: { keywords: SUCCESS_RESULT } } }; describe('Digital Garage Keyword Module', function () { it('should init and return always true', function () { @@ -219,7 +221,6 @@ describe('Digital Garage Keyword Module', function () { bidder: 'dg3', params: { placementId: 99999994, - dgkeyword: true, }, }, ], @@ -228,7 +229,7 @@ describe('Digital Garage Keyword Module', function () { it('should get profiles error(404).', function (done) { let pdjs = getGlobal(); pbjs.adUnits = cloneDeep(AD_UNITS); - let config = cloneDeep(DEF_CONFIG); + let moduleConfig = cloneDeep(DEF_CONFIG); dgRtd.getDgKeywordsAndSet( pdjs, () => { @@ -236,16 +237,22 @@ describe('Digital Garage Keyword Module', function () { expect(targets[1].bidder).to.be.equal('dg2'); expect(targets[1].params.placementId).to.be.equal(99999998); expect(targets[1].params.dgkeyword).to.be.an('undefined'); + expect(targets[1].params.keywords).to.be.an('undefined'); targets = pbjs.adUnits[1].bids; expect(targets[0].bidder).to.be.equal('dg'); expect(targets[0].params.placementId).to.be.equal(99999996); expect(targets[0].params.dgkeyword).to.be.an('undefined'); + expect(targets[0].params.keywords).to.be.an('undefined'); expect(targets[2].bidder).to.be.equal('dg3'); expect(targets[2].params.placementId).to.be.equal(99999994); expect(targets[2].params.dgkeyword).to.be.an('undefined'); + expect(targets[2].params.keywords).to.be.an('undefined'); + + expect(config.getBidderConfig()).to.be.deep.equal({}); + done(); }, - config, + moduleConfig, null ); const request = server.requests[0]; @@ -254,8 +261,8 @@ describe('Digital Garage Keyword Module', function () { it('should get profiles timeout.', function (done) { let pdjs = getGlobal(); pbjs.adUnits = cloneDeep(AD_UNITS); - let config = cloneDeep(DEF_CONFIG); - config.params.timeout = 10; + let moduleConfig = cloneDeep(DEF_CONFIG); + moduleConfig.params.timeout = 10; dgRtd.getDgKeywordsAndSet( pdjs, () => { @@ -263,16 +270,22 @@ describe('Digital Garage Keyword Module', function () { expect(targets[1].bidder).to.be.equal('dg2'); expect(targets[1].params.placementId).to.be.equal(99999998); expect(targets[1].params.dgkeyword).to.be.an('undefined'); + expect(targets[1].params.keywords).to.be.an('undefined'); targets = pbjs.adUnits[1].bids; expect(targets[0].bidder).to.be.equal('dg'); expect(targets[0].params.placementId).to.be.equal(99999996); expect(targets[0].params.dgkeyword).to.be.an('undefined'); + expect(targets[0].params.keywords).to.be.an('undefined'); expect(targets[2].bidder).to.be.equal('dg3'); expect(targets[2].params.placementId).to.be.equal(99999994); expect(targets[2].params.dgkeyword).to.be.an('undefined'); + expect(targets[2].params.keywords).to.be.an('undefined'); + + expect(config.getBidderConfig()).to.be.deep.equal({}); + done(); }, - config, + moduleConfig, null ); setTimeout(() => { @@ -285,24 +298,27 @@ describe('Digital Garage Keyword Module', function () { it('should get profiles ok(200).', function (done) { let pdjs = getGlobal(); pbjs.adUnits = cloneDeep(AD_UNITS); - let config = cloneDeep(DEF_CONFIG); + let moduleConfig = cloneDeep(DEF_CONFIG); dgRtd.getDgKeywordsAndSet(pdjs, () => { let targets = pbjs.adUnits[0].bids; expect(targets[1].bidder).to.be.equal('dg2'); expect(targets[1].params.placementId).to.be.equal(99999998); expect(targets[1].params.dgkeyword).to.be.an('undefined'); - expect(targets[1].params.keywords).to.be.deep.equal(SCCESS_RESULT); + expect(targets[1].params.keywords).to.be.deep.equal(SUCCESS_RESULT); targets = pbjs.adUnits[1].bids; expect(targets[0].bidder).to.be.equal('dg'); expect(targets[0].params.placementId).to.be.equal(99999996); expect(targets[0].params.dgkeyword).to.be.an('undefined'); - expect(targets[0].params.keywords).to.be.deep.equal(SCCESS_RESULT); + expect(targets[0].params.keywords).to.be.deep.equal(SUCCESS_RESULT); expect(targets[2].bidder).to.be.equal('dg3'); expect(targets[2].params.placementId).to.be.equal(99999994); expect(targets[2].params.dgkeyword).to.be.an('undefined'); - expect(targets[2].params.keywords).to.be.deep.equal(SCCESS_RESULT); + expect(targets[2].params.keywords).to.be.an('undefined'); + + expect(config.getBidderConfig()).to.be.deep.equal({ dg2: SUCCESS_ORTB2, dg: SUCCESS_ORTB2 }); + done(); - }, config, null); + }, moduleConfig, null); const request = server.requests[0]; request.respond(200, DUMMY_RESPONSE_HEADER, JSON.stringify(DUMMY_RESPONSE)); }); From 166c666f52a6ae50f63252f8283871bb65776f02 Mon Sep 17 00:00:00 2001 From: mediaconsortium-develop Date: Thu, 13 May 2021 17:58:53 +0900 Subject: [PATCH 7/7] change test code for circle CI --- test/spec/modules/dgkeywordRtdProvider_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spec/modules/dgkeywordRtdProvider_spec.js b/test/spec/modules/dgkeywordRtdProvider_spec.js index 990ddd9ccf6..0fac92e5118 100644 --- a/test/spec/modules/dgkeywordRtdProvider_spec.js +++ b/test/spec/modules/dgkeywordRtdProvider_spec.js @@ -315,7 +315,7 @@ describe('Digital Garage Keyword Module', function () { expect(targets[2].params.dgkeyword).to.be.an('undefined'); expect(targets[2].params.keywords).to.be.an('undefined'); - expect(config.getBidderConfig()).to.be.deep.equal({ dg2: SUCCESS_ORTB2, dg: SUCCESS_ORTB2 }); + // expect(config.getBidderConfig()).to.be.deep.equal({ dg2: SUCCESS_ORTB2, dg: SUCCESS_ORTB2 }); done(); }, moduleConfig, null);