prebid.js 7.6.0 → 7.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/1plusXRtdProvider.js +1 -0
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adoceanBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bliinkBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/currency.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gridNMBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/impactifyBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmarBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/jixieBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/naveggIdSystem.js +1 -1
- package/dist/not-for-prod/prebid.js +112 -111
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/prebidServerBidAdapter.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rubiconAnalyticsAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/userId.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/integrationExamples/gpt/1plusXRtdProviderExample.html +112 -0
- package/modules/.submodules.json +2 -1
- package/modules/1plusXRtdProvider.js +251 -0
- package/modules/1plusXRtdProvider.md +65 -0
- package/modules/adoceanBidAdapter.js +10 -3
- package/modules/big-richmediaBidAdapter.js +3 -3
- package/modules/bliinkBidAdapter.js +120 -193
- package/modules/bliinkBidAdapter.md +2 -5
- package/modules/consumableBidAdapter.js +9 -0
- package/modules/currency.js +2 -2
- package/modules/impactifyBidAdapter.js +6 -2
- package/modules/ixBidAdapter.js +61 -14
- package/modules/ixBidAdapter.md +2 -5
- package/modules/jixieBidAdapter.js +10 -10
- package/modules/naveggIdSystem.js +1 -12
- package/modules/nextMillenniumBidAdapter.md +1 -1
- package/modules/onetagBidAdapter.js +44 -7
- package/modules/prebidServerBidAdapter/index.js +7 -0
- package/modules/rubiconBidAdapter.js +5 -0
- package/modules/seedingAllianceBidAdapter.js +3 -0
- package/modules/targetVideoBidAdapter.js +18 -0
- package/modules/userId/index.js +39 -21
- package/package.json +1 -1
- package/src/auction.js +6 -5
- package/src/consentHandler.js +11 -11
- package/src/debugging.js +5 -3
- package/src/hook.js +2 -2
- package/src/utils/promise.js +96 -21
- package/src/utils.js +3 -2
- package/test/helpers/consentData.js +2 -1
- package/test/spec/auctionmanager_spec.js +1 -6
- package/test/spec/debugging_spec.js +2 -2
- package/test/spec/modules/1plusXRtdProvider_spec.js +430 -0
- package/test/spec/modules/adoceanBidAdapter_spec.js +4 -1
- package/test/spec/modules/bliinkBidAdapter_spec.js +323 -136
- package/test/spec/modules/consumableBidAdapter_spec.js +47 -1
- package/test/spec/modules/idxIdSystem_spec.js +1 -1
- package/test/spec/modules/ixBidAdapter_spec.js +77 -2
- package/test/spec/modules/jixieBidAdapter_spec.js +8 -8
- package/test/spec/modules/onetagBidAdapter_spec.js +53 -4
- package/test/spec/modules/parrableIdSystem_spec.js +2 -1
- package/test/spec/modules/prebidServerBidAdapter_spec.js +20 -0
- package/test/spec/modules/rubiconBidAdapter_spec.js +27 -0
- package/test/spec/modules/targetVideoBidAdapter_spec.js +43 -0
- package/test/spec/modules/userId_spec.js +15 -2
- package/test/spec/unit/pbjs_api_spec.js +1 -5
- package/test/spec/unit/utils/promise_spec.js +283 -38
- package/test/helpers/syncPromise.js +0 -71
package/src/utils.js
CHANGED
|
@@ -2,6 +2,7 @@ import { config } from './config.js';
|
|
|
2
2
|
import clone from 'just-clone';
|
|
3
3
|
import {find, includes} from './polyfill.js';
|
|
4
4
|
import CONSTANTS from './constants.json';
|
|
5
|
+
import {GreedyPromise} from './utils/promise.js';
|
|
5
6
|
export { default as deepAccess } from 'dlv/index.js';
|
|
6
7
|
export { default as deepSetValue } from 'dset';
|
|
7
8
|
|
|
@@ -487,7 +488,7 @@ export function hasOwn(objectToCheck, propertyToCheckFor) {
|
|
|
487
488
|
* @param {HTMLElement} [doc]
|
|
488
489
|
* @param {HTMLElement} [target]
|
|
489
490
|
* @param {Boolean} [asLastChildChild]
|
|
490
|
-
* @return {
|
|
491
|
+
* @return {HTML Element}
|
|
491
492
|
*/
|
|
492
493
|
export function insertElement(elm, doc, target, asLastChildChild) {
|
|
493
494
|
doc = doc || document;
|
|
@@ -517,7 +518,7 @@ export function insertElement(elm, doc, target, asLastChildChild) {
|
|
|
517
518
|
*/
|
|
518
519
|
export function waitForElementToLoad(element, timeout) {
|
|
519
520
|
let timer = null;
|
|
520
|
-
return new
|
|
521
|
+
return new GreedyPromise((resolve) => {
|
|
521
522
|
const onLoad = function() {
|
|
522
523
|
element.removeEventListener('load', onLoad);
|
|
523
524
|
element.removeEventListener('error', onLoad);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {gdprDataHandler} from 'src/adapterManager.js';
|
|
2
|
+
import {GreedyPromise} from '../../src/utils/promise.js';
|
|
2
3
|
|
|
3
4
|
export function mockGdprConsent(sandbox, getConsentData = () => null) {
|
|
4
|
-
sandbox.stub(gdprDataHandler, 'promise').get(() =>
|
|
5
|
+
sandbox.stub(gdprDataHandler, 'promise').get(() => GreedyPromise.resolve(getConsentData()));
|
|
5
6
|
sandbox.stub(gdprDataHandler, 'getConsentData').callsFake(getConsentData)
|
|
6
7
|
}
|
|
@@ -21,7 +21,6 @@ import {auctionManager} from '../../src/auctionManager.js';
|
|
|
21
21
|
import 'modules/debugging/index.js' // some tests look for debugging side effects
|
|
22
22
|
import {AuctionIndex} from '../../src/auctionIndex.js';
|
|
23
23
|
import {expect} from 'chai';
|
|
24
|
-
import {synchronizePromise} from '../helpers/syncPromise.js';
|
|
25
24
|
|
|
26
25
|
var assert = require('assert');
|
|
27
26
|
|
|
@@ -134,7 +133,7 @@ function mockAjaxBuilder() {
|
|
|
134
133
|
}
|
|
135
134
|
|
|
136
135
|
describe('auctionmanager.js', function () {
|
|
137
|
-
let indexAuctions, indexStub
|
|
136
|
+
let indexAuctions, indexStub
|
|
138
137
|
|
|
139
138
|
before(() => {
|
|
140
139
|
// hooks are global and their side effects depend on what has been loaded
|
|
@@ -150,13 +149,10 @@ describe('auctionmanager.js', function () {
|
|
|
150
149
|
indexAuctions = [];
|
|
151
150
|
indexStub = sinon.stub(auctionManager, 'index');
|
|
152
151
|
indexStub.get(() => new AuctionIndex(() => indexAuctions));
|
|
153
|
-
promiseSandbox = sinon.createSandbox();
|
|
154
|
-
synchronizePromise(promiseSandbox);
|
|
155
152
|
});
|
|
156
153
|
|
|
157
154
|
afterEach(() => {
|
|
158
155
|
indexStub.restore();
|
|
159
|
-
promiseSandbox.restore();
|
|
160
156
|
});
|
|
161
157
|
|
|
162
158
|
describe('getKeyValueTargetingPairs', function () {
|
|
@@ -1458,7 +1454,6 @@ describe('auctionmanager.js', function () {
|
|
|
1458
1454
|
}
|
|
1459
1455
|
|
|
1460
1456
|
beforeEach(() => {
|
|
1461
|
-
promiseSandbox.restore();
|
|
1462
1457
|
bids = [
|
|
1463
1458
|
mockBid({bidderCode: BIDDER_CODE1}),
|
|
1464
1459
|
mockBid({bidderCode: BIDDER_CODE})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {ready, loadSession, getConfig, reset, debuggingModuleLoader, debuggingControls} from '../../src/debugging.js';
|
|
2
2
|
import {getGlobal} from '../../src/prebidGlobal.js';
|
|
3
|
-
import {
|
|
3
|
+
import {defer} from '../../src/utils/promise.js';
|
|
4
4
|
import funHooks from 'fun-hooks/no-eval/index.js';
|
|
5
5
|
|
|
6
6
|
describe('Debugging', () => {
|
|
@@ -67,7 +67,7 @@ describe('Debugging', () => {
|
|
|
67
67
|
let debugging, loader, hook, hookRan;
|
|
68
68
|
|
|
69
69
|
beforeEach(() => {
|
|
70
|
-
loader =
|
|
70
|
+
loader = defer();
|
|
71
71
|
hookRan = false;
|
|
72
72
|
hook = funHooks()('sync', () => { hookRan = true });
|
|
73
73
|
debugging = debuggingControls({load: sinon.stub().returns(loader.promise), hook});
|
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
import { config } from 'src/config';
|
|
2
|
+
import {
|
|
3
|
+
onePlusXSubmodule,
|
|
4
|
+
segtaxes,
|
|
5
|
+
extractConfig,
|
|
6
|
+
buildOrtb2Updates,
|
|
7
|
+
updateBidderConfig,
|
|
8
|
+
setTargetingDataToConfig
|
|
9
|
+
} from 'modules/1plusXRtdProvider';
|
|
10
|
+
|
|
11
|
+
describe('1plusXRtdProvider', () => {
|
|
12
|
+
// Fake server config
|
|
13
|
+
let fakeServer;
|
|
14
|
+
const fakeResponseHeaders = {
|
|
15
|
+
'Content-Type': 'application/json',
|
|
16
|
+
'Access-Control-Allow-Origin': '*'
|
|
17
|
+
};
|
|
18
|
+
const fakeResponse = {
|
|
19
|
+
s: ['segment1', 'segment2', 'segment3'],
|
|
20
|
+
t: ['targeting1', 'targeting2', 'targeting3']
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Bid request config
|
|
24
|
+
const reqBidsConfigObj = {
|
|
25
|
+
adUnits: [{
|
|
26
|
+
bids: [
|
|
27
|
+
{ bidder: 'appnexus' }
|
|
28
|
+
]
|
|
29
|
+
}]
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Bidder configs
|
|
33
|
+
const bidderConfigInitial = {
|
|
34
|
+
ortb2: {
|
|
35
|
+
user: { keywords: '' },
|
|
36
|
+
site: { ext: {} }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const bidderConfigInitialWith1plusXUserData = {
|
|
40
|
+
ortb2: {
|
|
41
|
+
user: {
|
|
42
|
+
data: [{ name: '1plusX.com', segment: [{ id: 'initial' }] }]
|
|
43
|
+
},
|
|
44
|
+
site: { content: { data: [] } }
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const bidderConfigInitialWithUserData = {
|
|
48
|
+
ortb2: {
|
|
49
|
+
user: {
|
|
50
|
+
data: [{ name: 'hello.world', segment: [{ id: 'initial' }] }]
|
|
51
|
+
},
|
|
52
|
+
site: { content: { data: [] } }
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const bidderConfigInitialWith1plusXSiteContent = {
|
|
56
|
+
ortb2: {
|
|
57
|
+
user: { data: [] },
|
|
58
|
+
site: {
|
|
59
|
+
content: {
|
|
60
|
+
data: [{
|
|
61
|
+
name: '1plusX.com', segment: [{ id: 'initial' }], ext: { segtax: 525 }
|
|
62
|
+
}]
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const bidderConfigInitialWithSiteContent = {
|
|
68
|
+
ortb2: {
|
|
69
|
+
user: { data: [] },
|
|
70
|
+
site: {
|
|
71
|
+
content: {
|
|
72
|
+
data: [{ name: 'hello.world', segment: [{ id: 'initial' }] }]
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Util functions
|
|
78
|
+
const randomBidder = (len = 5) => Math.random().toString(36).replace(/[^a-z]+/g, '').substring(0, len);
|
|
79
|
+
|
|
80
|
+
before(() => {
|
|
81
|
+
config.resetConfig();
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
after(() => { })
|
|
85
|
+
|
|
86
|
+
beforeEach(() => {
|
|
87
|
+
fakeServer = sinon.createFakeServer();
|
|
88
|
+
fakeServer.respondWith('GET', '*', [200, fakeResponseHeaders, JSON.stringify(fakeResponse)]);
|
|
89
|
+
fakeServer.respondImmediately = true;
|
|
90
|
+
fakeServer.autoRespond = true;
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
describe('onePlusXSubmodule', () => {
|
|
94
|
+
it('init is successfull', () => {
|
|
95
|
+
const initResult = onePlusXSubmodule.init();
|
|
96
|
+
expect(initResult).to.be.true;
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('callback is called after getBidRequestData', () => {
|
|
100
|
+
// Nice case; everything runs as expected
|
|
101
|
+
{
|
|
102
|
+
const callbackSpy = sinon.spy();
|
|
103
|
+
const config = { params: { customerId: 'test', bidders: ['appnexus'] } };
|
|
104
|
+
onePlusXSubmodule.getBidRequestData(reqBidsConfigObj, callbackSpy, config);
|
|
105
|
+
setTimeout(() => {
|
|
106
|
+
expect(callbackSpy.calledOnce).to.be.true
|
|
107
|
+
}, 100)
|
|
108
|
+
}
|
|
109
|
+
// No customer id in config => error but still callback called
|
|
110
|
+
{
|
|
111
|
+
const callbackSpy = sinon.spy();
|
|
112
|
+
const config = {}
|
|
113
|
+
onePlusXSubmodule.getBidRequestData(reqBidsConfigObj, callbackSpy, config);
|
|
114
|
+
setTimeout(() => {
|
|
115
|
+
expect(callbackSpy.calledOnce).to.be.true
|
|
116
|
+
}, 100);
|
|
117
|
+
}
|
|
118
|
+
// No bidders in config => error but still callback called
|
|
119
|
+
{
|
|
120
|
+
const callbackSpy = sinon.spy();
|
|
121
|
+
const config = { customerId: 'test' }
|
|
122
|
+
onePlusXSubmodule.getBidRequestData(reqBidsConfigObj, callbackSpy, config);
|
|
123
|
+
setTimeout(() => {
|
|
124
|
+
expect(callbackSpy.calledOnce).to.be.true
|
|
125
|
+
}, 100);
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
describe('extractConfig', () => {
|
|
131
|
+
const customerId = 'test';
|
|
132
|
+
const timeout = 1000;
|
|
133
|
+
const bidders = ['appnexus'];
|
|
134
|
+
|
|
135
|
+
it('Throws an error if no customerId is specified', () => {
|
|
136
|
+
const moduleConfig = { params: { timeout, bidders } };
|
|
137
|
+
expect(() => extractConfig(moduleConfig, reqBidsConfigObj)).to.throw();
|
|
138
|
+
})
|
|
139
|
+
it('Throws an error if no bidder is specified', () => {
|
|
140
|
+
const moduleConfig = { params: { customerId, timeout } };
|
|
141
|
+
expect(() => extractConfig(moduleConfig, reqBidsConfigObj)).to.throw();
|
|
142
|
+
})
|
|
143
|
+
it("Throws an error if there's no bidder in reqBidsConfigObj", () => {
|
|
144
|
+
const moduleConfig = { params: { customerId, timeout, bidders } };
|
|
145
|
+
const reqBidsConfigEmpty = { adUnits: [{ bids: [] }] };
|
|
146
|
+
expect(() => extractConfig(moduleConfig, reqBidsConfigEmpty)).to.throw();
|
|
147
|
+
})
|
|
148
|
+
it('Returns an object containing the parameters specified', () => {
|
|
149
|
+
const moduleConfig = { params: { customerId, timeout, bidders } };
|
|
150
|
+
const expectedKeys = ['customerId', 'timeout', 'bidders']
|
|
151
|
+
const extractedConfig = extractConfig(moduleConfig, reqBidsConfigObj);
|
|
152
|
+
expect(extractedConfig).to.be.an('object').and.to.have.all.keys(expectedKeys);
|
|
153
|
+
expect(extractedConfig.customerId).to.equal(customerId);
|
|
154
|
+
expect(extractedConfig.timeout).to.equal(timeout);
|
|
155
|
+
expect(extractedConfig.bidders).to.deep.equal(bidders);
|
|
156
|
+
})
|
|
157
|
+
/* 1plusX RTD module may only use bidders that are both specified in :
|
|
158
|
+
- the bid request configuration
|
|
159
|
+
- AND in the 1plusX RTD module configuration
|
|
160
|
+
Below 2 tests are enforcing those rules
|
|
161
|
+
*/
|
|
162
|
+
it('Returns the intersection of bidders found in bid request config & module config', () => {
|
|
163
|
+
const bidders = ['appnexus', 'rubicon'];
|
|
164
|
+
const moduleConfig = { params: { customerId, timeout, bidders } };
|
|
165
|
+
const { bidders: extractedBidders } = extractConfig(moduleConfig, reqBidsConfigObj);
|
|
166
|
+
expect(extractedBidders).to.be.an('array').and.to.have.length(1); 7
|
|
167
|
+
expect(extractedBidders[0]).to.equal('appnexus');
|
|
168
|
+
})
|
|
169
|
+
it('Throws an error if no bidder can be used by the module', () => {
|
|
170
|
+
const bidders = ['rubicon'];
|
|
171
|
+
const moduleConfig = { params: { customerId, timeout, bidders } };
|
|
172
|
+
expect(() => extractConfig(moduleConfig, reqBidsConfigObj)).to.throw();
|
|
173
|
+
})
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
describe('buildOrtb2Updates', () => {
|
|
177
|
+
it('fills site.content.data & user.data in the ortb2 config', () => {
|
|
178
|
+
const rtdData = { segments: fakeResponse.s, topics: fakeResponse.t };
|
|
179
|
+
const ortb2Updates = buildOrtb2Updates(rtdData, randomBidder());
|
|
180
|
+
|
|
181
|
+
const expectedOutput = {
|
|
182
|
+
siteContentData: {
|
|
183
|
+
name: '1plusX.com',
|
|
184
|
+
segment: rtdData.topics.map((topicId) => ({ id: topicId })),
|
|
185
|
+
ext: { segtax: segtaxes.CONTENT }
|
|
186
|
+
},
|
|
187
|
+
userData: {
|
|
188
|
+
name: '1plusX.com',
|
|
189
|
+
segment: rtdData.segments.map((segmentId) => ({ id: segmentId }))
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
expect([ortb2Updates]).to.deep.include.members([expectedOutput]);
|
|
193
|
+
});
|
|
194
|
+
it('fills site.keywords in the ortb2 config (appnexus specific)', () => {
|
|
195
|
+
const rtdData = { segments: fakeResponse.s, topics: fakeResponse.t };
|
|
196
|
+
const ortb2Updates = buildOrtb2Updates(rtdData, 'appnexus');
|
|
197
|
+
|
|
198
|
+
const expectedOutput = {
|
|
199
|
+
site: {
|
|
200
|
+
keywords: rtdData.topics.join(','),
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
expect([ortb2Updates]).to.deep.include.members([expectedOutput]);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('defaults to empty array if no segment is given', () => {
|
|
207
|
+
const rtdData = { topics: fakeResponse.t };
|
|
208
|
+
const ortb2Updates = buildOrtb2Updates(rtdData, randomBidder());
|
|
209
|
+
|
|
210
|
+
const expectedOutput = {
|
|
211
|
+
siteContentData: {
|
|
212
|
+
name: '1plusX.com',
|
|
213
|
+
segment: rtdData.topics.map((topicId) => ({ id: topicId })),
|
|
214
|
+
ext: { segtax: segtaxes.CONTENT }
|
|
215
|
+
},
|
|
216
|
+
userData: {
|
|
217
|
+
name: '1plusX.com',
|
|
218
|
+
segment: []
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
expect(ortb2Updates).to.deep.include(expectedOutput);
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
it('defaults to empty array if no topic is given', () => {
|
|
225
|
+
const rtdData = { segments: fakeResponse.s };
|
|
226
|
+
const ortb2Updates = buildOrtb2Updates(rtdData, randomBidder());
|
|
227
|
+
|
|
228
|
+
const expectedOutput = {
|
|
229
|
+
siteContentData: {
|
|
230
|
+
name: '1plusX.com',
|
|
231
|
+
segment: [],
|
|
232
|
+
ext: { segtax: segtaxes.CONTENT }
|
|
233
|
+
},
|
|
234
|
+
userData: {
|
|
235
|
+
name: '1plusX.com',
|
|
236
|
+
segment: rtdData.segments.map((segmentId) => ({ id: segmentId }))
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
expect(ortb2Updates).to.deep.include(expectedOutput);
|
|
240
|
+
})
|
|
241
|
+
it('defaults to empty string if no topic is given (appnexus specific)', () => {
|
|
242
|
+
const rtdData = { segments: fakeResponse.s };
|
|
243
|
+
const ortb2Updates = buildOrtb2Updates(rtdData, 'appnexus');
|
|
244
|
+
|
|
245
|
+
const expectedOutput = {
|
|
246
|
+
site: {
|
|
247
|
+
keywords: '',
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
expect(ortb2Updates).to.deep.include(expectedOutput);
|
|
251
|
+
})
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
describe('updateBidderConfig', () => {
|
|
255
|
+
const ortb2UpdatesAppNexus = {
|
|
256
|
+
site: {
|
|
257
|
+
keywords: fakeResponse.t.join(','),
|
|
258
|
+
},
|
|
259
|
+
userData: {
|
|
260
|
+
name: '1plusX.com',
|
|
261
|
+
segment: fakeResponse.s.map((segmentId) => ({ id: segmentId }))
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
const ortb2Updates = {
|
|
265
|
+
siteContentData: {
|
|
266
|
+
name: '1plusX.com',
|
|
267
|
+
segment: fakeResponse.t.map((topicId) => ({ id: topicId })),
|
|
268
|
+
ext: { segtax: segtaxes.CONTENT }
|
|
269
|
+
},
|
|
270
|
+
userData: {
|
|
271
|
+
name: '1plusX.com',
|
|
272
|
+
segment: fakeResponse.s.map((segmentId) => ({ id: segmentId }))
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
it('merges fetched data in bidderConfig for configured bidders', () => {
|
|
277
|
+
const bidder = randomBidder();
|
|
278
|
+
// Set initial config
|
|
279
|
+
config.setBidderConfig({
|
|
280
|
+
bidders: [bidder],
|
|
281
|
+
config: bidderConfigInitial
|
|
282
|
+
});
|
|
283
|
+
// Call submodule's setBidderConfig
|
|
284
|
+
const newBidderConfig = updateBidderConfig(bidder, ortb2Updates, config.getBidderConfig());
|
|
285
|
+
// Check that the targeting data has been set in the config
|
|
286
|
+
expect(newBidderConfig).not.to.be.null;
|
|
287
|
+
expect(newBidderConfig.ortb2.site.content.data).to.deep.include(ortb2Updates.siteContentData);
|
|
288
|
+
expect(newBidderConfig.ortb2.user.data).to.deep.include(ortb2Updates.userData);
|
|
289
|
+
// Check that existing config didn't get erased
|
|
290
|
+
expect(newBidderConfig.ortb2.site).to.deep.include(bidderConfigInitial.ortb2.site);
|
|
291
|
+
expect(newBidderConfig.ortb2.user).to.deep.include(bidderConfigInitial.ortb2.user);
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
it('merges fetched data in bidderConfig for configured bidders (appnexus specific)', () => {
|
|
295
|
+
const bidder = 'appnexus';
|
|
296
|
+
// Set initial config
|
|
297
|
+
config.setBidderConfig({
|
|
298
|
+
bidders: [bidder],
|
|
299
|
+
config: bidderConfigInitial
|
|
300
|
+
});
|
|
301
|
+
// Call submodule's setBidderConfig
|
|
302
|
+
const newBidderConfig = updateBidderConfig(bidder, ortb2UpdatesAppNexus, config.getBidderConfig());
|
|
303
|
+
|
|
304
|
+
// Check that the targeting data has been set in the config
|
|
305
|
+
expect(newBidderConfig).not.to.be.null;
|
|
306
|
+
expect(newBidderConfig.ortb2.site).to.deep.include(ortb2UpdatesAppNexus.site);
|
|
307
|
+
// Check that existing config didn't get erased
|
|
308
|
+
expect(newBidderConfig.ortb2.site).to.deep.include(bidderConfigInitial.ortb2.site);
|
|
309
|
+
expect(newBidderConfig.ortb2.user).to.deep.include(bidderConfigInitial.ortb2.user);
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
it('overwrites an existing 1plus.com entry in ortb2.user.data', () => {
|
|
313
|
+
const bidder = randomBidder();
|
|
314
|
+
// Set initial config
|
|
315
|
+
config.setBidderConfig({
|
|
316
|
+
bidders: [bidder],
|
|
317
|
+
config: bidderConfigInitialWith1plusXUserData
|
|
318
|
+
});
|
|
319
|
+
// Save previous user.data entry
|
|
320
|
+
const previousUserData = bidderConfigInitialWith1plusXUserData.ortb2.user.data[0];
|
|
321
|
+
// Call submodule's setBidderConfig
|
|
322
|
+
const newBidderConfig = updateBidderConfig(bidder, ortb2Updates, config.getBidderConfig());
|
|
323
|
+
// Check that the targeting data has been set in the config
|
|
324
|
+
expect(newBidderConfig).not.to.be.null;
|
|
325
|
+
expect(newBidderConfig.ortb2.user.data).to.deep.include(ortb2Updates.userData);
|
|
326
|
+
expect(newBidderConfig.ortb2.user.data).not.to.include(previousUserData);
|
|
327
|
+
})
|
|
328
|
+
it("doesn't overwrite entries in ortb2.user.data that aren't 1plusx.com", () => {
|
|
329
|
+
const bidder = randomBidder();
|
|
330
|
+
// Set initial config
|
|
331
|
+
config.setBidderConfig({
|
|
332
|
+
bidders: [bidder],
|
|
333
|
+
config: bidderConfigInitialWithUserData
|
|
334
|
+
});
|
|
335
|
+
// Save previous user.data entry
|
|
336
|
+
const previousUserData = bidderConfigInitialWithUserData.ortb2.user.data[0];
|
|
337
|
+
// Call submodule's setBidderConfig
|
|
338
|
+
const newBidderConfig = updateBidderConfig(bidder, ortb2Updates, config.getBidderConfig());
|
|
339
|
+
// Check that the targeting data has been set in the config
|
|
340
|
+
expect(newBidderConfig).not.to.be.null;
|
|
341
|
+
expect(newBidderConfig.ortb2.user.data).to.deep.include(ortb2Updates.userData);
|
|
342
|
+
expect(newBidderConfig.ortb2.user.data).to.deep.include(previousUserData);
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
it('overwrites an existing 1plus.com entry in ortb2.site.content.data', () => {
|
|
346
|
+
const bidder = randomBidder();
|
|
347
|
+
// Set initial config
|
|
348
|
+
config.setBidderConfig({
|
|
349
|
+
bidders: [bidder],
|
|
350
|
+
config: bidderConfigInitialWith1plusXSiteContent
|
|
351
|
+
});
|
|
352
|
+
// Save previous user.data entry
|
|
353
|
+
const previousSiteContent = bidderConfigInitialWith1plusXSiteContent.ortb2.site.content.data[0];
|
|
354
|
+
// Call submodule's setBidderConfig
|
|
355
|
+
const newBidderConfig = updateBidderConfig(bidder, ortb2Updates, config.getBidderConfig());
|
|
356
|
+
// Check that the targeting data has been set in the config
|
|
357
|
+
expect(newBidderConfig).not.to.be.null;
|
|
358
|
+
expect(newBidderConfig.ortb2.site.content.data).to.deep.include(ortb2Updates.siteContentData);
|
|
359
|
+
expect(newBidderConfig.ortb2.site.content.data).not.to.include(previousSiteContent);
|
|
360
|
+
})
|
|
361
|
+
it("doesn't overwrite entries in ortb2.site.content.data that aren't 1plusx.com", () => {
|
|
362
|
+
const bidder = randomBidder();
|
|
363
|
+
// Set initial config
|
|
364
|
+
config.setBidderConfig({
|
|
365
|
+
bidders: [bidder],
|
|
366
|
+
config: bidderConfigInitialWithSiteContent
|
|
367
|
+
});
|
|
368
|
+
// Save previous user.data entry
|
|
369
|
+
const previousSiteContent = bidderConfigInitialWithSiteContent.ortb2.site.content.data[0];
|
|
370
|
+
// Call submodule's setBidderConfig
|
|
371
|
+
const newBidderConfig = updateBidderConfig(bidder, ortb2Updates, config.getBidderConfig());
|
|
372
|
+
// Check that the targeting data has been set in the config
|
|
373
|
+
expect(newBidderConfig).not.to.be.null;
|
|
374
|
+
expect(newBidderConfig.ortb2.site.content.data).to.deep.include(ortb2Updates.siteContentData);
|
|
375
|
+
expect(newBidderConfig.ortb2.site.content.data).to.deep.include(previousSiteContent);
|
|
376
|
+
})
|
|
377
|
+
})
|
|
378
|
+
|
|
379
|
+
describe('setTargetingDataToConfig', () => {
|
|
380
|
+
const expectedKeywords = fakeResponse.t.join(',');
|
|
381
|
+
const expectedSiteContentObj = {
|
|
382
|
+
data: [{
|
|
383
|
+
name: '1plusX.com',
|
|
384
|
+
segment: fakeResponse.t.map((topicId) => ({ id: topicId })),
|
|
385
|
+
ext: { segtax: segtaxes.CONTENT }
|
|
386
|
+
}]
|
|
387
|
+
}
|
|
388
|
+
const expectedUserObj = {
|
|
389
|
+
data: [{
|
|
390
|
+
name: '1plusX.com',
|
|
391
|
+
segment: fakeResponse.s.map((segmentId) => ({ id: segmentId }))
|
|
392
|
+
}]
|
|
393
|
+
}
|
|
394
|
+
const expectedOrtb2 = {
|
|
395
|
+
appnexus: {
|
|
396
|
+
site: { keywords: expectedKeywords }
|
|
397
|
+
},
|
|
398
|
+
rubicon: {
|
|
399
|
+
site: { content: expectedSiteContentObj },
|
|
400
|
+
user: expectedUserObj
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
it('sets the config for the selected bidders', () => {
|
|
405
|
+
const bidders = ['appnexus', 'rubicon'];
|
|
406
|
+
// setting initial config for those bidders
|
|
407
|
+
config.setBidderConfig({
|
|
408
|
+
bidders,
|
|
409
|
+
config: bidderConfigInitial
|
|
410
|
+
})
|
|
411
|
+
// call setTargetingDataToConfig
|
|
412
|
+
setTargetingDataToConfig(fakeResponse, { bidders });
|
|
413
|
+
|
|
414
|
+
// Check that the targeting data has been set in both configs
|
|
415
|
+
for (const bidder of bidders) {
|
|
416
|
+
const newConfig = config.getBidderConfig()[bidder];
|
|
417
|
+
// Check that we got what we expect
|
|
418
|
+
const expectedConfErr = (prop) => `New config for ${bidder} doesn't comply with expected at ${prop}`;
|
|
419
|
+
expect(newConfig.ortb2.site, expectedConfErr('site')).to.deep.include(expectedOrtb2[bidder].site);
|
|
420
|
+
if (expectedOrtb2[bidder].user) {
|
|
421
|
+
expect(newConfig.ortb2.user, expectedConfErr('user')).to.deep.include(expectedOrtb2[bidder].user);
|
|
422
|
+
}
|
|
423
|
+
// Check that existing config didn't get erased
|
|
424
|
+
const existingConfErr = (prop) => `Existing config for ${bidder} got unlawfully overwritten at ${prop}`;
|
|
425
|
+
expect(newConfig.ortb2.site, existingConfErr('site')).to.deep.include(bidderConfigInitial.ortb2.site);
|
|
426
|
+
expect(newConfig.ortb2.user, existingConfErr('user')).to.deep.include(bidderConfigInitial.ortb2.user);
|
|
427
|
+
}
|
|
428
|
+
})
|
|
429
|
+
})
|
|
430
|
+
})
|
|
@@ -136,10 +136,12 @@ describe('AdoceanAdapter', function () {
|
|
|
136
136
|
expect(request.url).to.include('gdpr_consent=' + bidderRequest.gdprConsent.consentString);
|
|
137
137
|
});
|
|
138
138
|
|
|
139
|
-
it('should attach sizes information to url', function () {
|
|
139
|
+
it('should attach sizes and slaves information to url', function () {
|
|
140
140
|
let requests = spec.buildRequests(bidRequests, bidderRequest);
|
|
141
141
|
expect(requests[0].url).to.include('aosspsizes=myaozpniqismex~300x250_300x600');
|
|
142
|
+
expect(requests[0].url).to.include('slaves=zpniqismex');
|
|
142
143
|
expect(requests[1].url).to.include('aosspsizes=myaozpniqismex~300x200_600x250');
|
|
144
|
+
expect(requests[1].url).to.include('slaves=zpniqismex');
|
|
143
145
|
|
|
144
146
|
const differentSlavesBids = deepClone(bidRequests);
|
|
145
147
|
differentSlavesBids[1].params.slaveId = 'adoceanmyaowafpdwlrks';
|
|
@@ -147,6 +149,7 @@ describe('AdoceanAdapter', function () {
|
|
|
147
149
|
expect(requests.length).to.equal(1);
|
|
148
150
|
expect(requests[0].url).to.include('aosspsizes=myaozpniqismex~300x250_300x600-myaowafpdwlrks~300x200_600x250');
|
|
149
151
|
expect((requests[0].url.match(/aosspsizes=/g) || []).length).to.equal(1);
|
|
152
|
+
expect(requests[0].url).to.include('slaves=zpniqismex,wafpdwlrks');
|
|
150
153
|
});
|
|
151
154
|
|
|
152
155
|
it('should attach schain parameter if available', function() {
|