prebid.js 7.29.0 → 7.30.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/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.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/bidViewability.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/byDataAnalyticsAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/ccxBidAdapter.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/colossussspBidAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consentManagement.js +1 -1
- package/dist/consentManagementGpp.js +1 -0
- 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/dfpAdServerVideo.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/improvedigitalBidAdapter.js +1 -1
- package/dist/inmarBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/magniteAnalyticsAdapter.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/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +122 -120
- 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/rtdModule.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/uid2IdSystem.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/viouslyBidAdapter.js +1 -0
- 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/gpp_us_hello_world.html +124 -0
- package/integrationExamples/gpt/gpp_us_hello_world_iframe.html +12 -0
- package/integrationExamples/gpt/gpp_us_hello_world_iframe_subpage.html +140 -0
- package/karma.conf.maker.js +1 -1
- package/modules/appnexusBidAdapter.js +23 -2
- package/modules/bidViewability.js +6 -1
- package/modules/ccxBidAdapter.js +3 -2
- package/modules/colossussspBidAdapter.js +8 -0
- package/modules/consentManagement.js +4 -4
- package/modules/consentManagementGpp.js +386 -0
- package/modules/dfpAdServerVideo.js +6 -1
- package/modules/gridBidAdapter.js +1 -2
- package/modules/lassoBidAdapter.js +2 -2
- package/modules/magniteAnalyticsAdapter.js +9 -1
- package/modules/onetagBidAdapter.js +20 -29
- package/modules/prebidServerBidAdapter/index.js +19 -8
- package/modules/rtdModule/index.js +2 -1
- package/modules/viouslyBidAdapter.js +209 -0
- package/modules/viouslyBidAdapter.md +35 -0
- package/package.json +1 -1
- package/src/adapterManager.js +11 -10
- package/src/adapters/bidderFactory.js +5 -5
- package/src/consentHandler.js +11 -0
- package/src/prebid.js +2 -1
- package/test/helpers/hookSetup.js +5 -0
- package/test/spec/modules/ViouslyBidAdapter_spec.js +378 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +46 -0
- package/test/spec/modules/colossussspBidAdapter_spec.js +89 -2
- package/test/spec/modules/consentManagementGpp_spec.js +577 -0
- package/test/spec/modules/gridBidAdapter_spec.js +0 -18
- package/test/spec/modules/magniteAnalyticsAdapter_spec.js +36 -14
- package/test/spec/modules/onetagBidAdapter_spec.js +29 -23
- package/test/spec/modules/topicsFpdModule_spec.js +41 -22
|
@@ -0,0 +1,577 @@
|
|
|
1
|
+
import { setConsentConfig, requestBidsHook, resetConsentData, userCMP, consentTimeout, staticConsentData } from 'modules/consentManagementGpp.js';
|
|
2
|
+
import { gppDataHandler } from 'src/adapterManager.js';
|
|
3
|
+
import * as utils from 'src/utils.js';
|
|
4
|
+
import { config } from 'src/config.js';
|
|
5
|
+
import 'src/prebid.js';
|
|
6
|
+
|
|
7
|
+
let expect = require('chai').expect;
|
|
8
|
+
|
|
9
|
+
describe('consentManagementGpp', function () {
|
|
10
|
+
describe('setConsentConfig tests:', function () {
|
|
11
|
+
describe('empty setConsentConfig value', function () {
|
|
12
|
+
beforeEach(function () {
|
|
13
|
+
sinon.stub(utils, 'logInfo');
|
|
14
|
+
sinon.stub(utils, 'logWarn');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
afterEach(function () {
|
|
18
|
+
utils.logInfo.restore();
|
|
19
|
+
utils.logWarn.restore();
|
|
20
|
+
config.resetConfig();
|
|
21
|
+
resetConsentData();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should use system default values', function () {
|
|
25
|
+
setConsentConfig({
|
|
26
|
+
gpp: {}
|
|
27
|
+
});
|
|
28
|
+
expect(userCMP).to.be.equal('iab');
|
|
29
|
+
expect(consentTimeout).to.be.equal(10000);
|
|
30
|
+
sinon.assert.callCount(utils.logInfo, 3);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should exit consent manager if config is not an object', function () {
|
|
34
|
+
setConsentConfig('');
|
|
35
|
+
expect(userCMP).to.be.undefined;
|
|
36
|
+
sinon.assert.calledOnce(utils.logWarn);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should exit consentManagement module if config is "undefined"', function () {
|
|
40
|
+
setConsentConfig(undefined);
|
|
41
|
+
expect(userCMP).to.be.undefined;
|
|
42
|
+
sinon.assert.calledOnce(utils.logWarn);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should not produce any consent metadata', function () {
|
|
46
|
+
setConsentConfig(undefined)
|
|
47
|
+
let consentMetadata = gppDataHandler.getConsentMeta();
|
|
48
|
+
expect(consentMetadata).to.be.undefined;
|
|
49
|
+
sinon.assert.calledOnce(utils.logWarn);
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('should immediately look up consent data', () => {
|
|
53
|
+
setConsentConfig({
|
|
54
|
+
gpp: {
|
|
55
|
+
cmpApi: 'invalid'
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
expect(gppDataHandler.ready).to.be.true;
|
|
59
|
+
})
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe('valid setConsentConfig value', function () {
|
|
63
|
+
afterEach(function () {
|
|
64
|
+
config.resetConfig();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('results in all user settings overriding system defaults', function () {
|
|
68
|
+
let allConfig = {
|
|
69
|
+
gpp: {
|
|
70
|
+
cmpApi: 'iab',
|
|
71
|
+
timeout: 7500
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
setConsentConfig(allConfig);
|
|
76
|
+
expect(userCMP).to.be.equal('iab');
|
|
77
|
+
expect(consentTimeout).to.be.equal(7500);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should recognize config.gpp, with default cmpApi and timeout', function () {
|
|
81
|
+
setConsentConfig({
|
|
82
|
+
gpp: {}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
expect(userCMP).to.be.equal('iab');
|
|
86
|
+
expect(consentTimeout).to.be.equal(10000);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should enable gppDataHandler', () => {
|
|
90
|
+
setConsentConfig({
|
|
91
|
+
gpp: {}
|
|
92
|
+
});
|
|
93
|
+
expect(gppDataHandler.enabled).to.be.true;
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('static consent string setConsentConfig value', () => {
|
|
98
|
+
afterEach(() => {
|
|
99
|
+
config.resetConfig();
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('results in user settings overriding system defaults for v2 spec', () => {
|
|
103
|
+
let staticConfig = {
|
|
104
|
+
gpp: {
|
|
105
|
+
cmpApi: 'static',
|
|
106
|
+
timeout: 7500,
|
|
107
|
+
consentData: {
|
|
108
|
+
applicableSections: [7],
|
|
109
|
+
gppString: 'ABCDEFG1234',
|
|
110
|
+
gppVersion: 1,
|
|
111
|
+
sectionId: 3,
|
|
112
|
+
sectionList: []
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
setConsentConfig(staticConfig);
|
|
118
|
+
expect(userCMP).to.be.equal('static');
|
|
119
|
+
expect(consentTimeout).to.be.equal(0); // should always return without a timeout when config is used
|
|
120
|
+
const consent = gppDataHandler.getConsentData();
|
|
121
|
+
expect(consent.gppString).to.eql(staticConfig.gpp.consentData.gppString);
|
|
122
|
+
expect(consent.fullGppData).to.eql(staticConfig.gpp.consentData);
|
|
123
|
+
expect(staticConsentData).to.be.equal(staticConfig.gpp.consentData);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
describe('requestBidsHook tests:', function () {
|
|
129
|
+
let goodConfig = {
|
|
130
|
+
gpp: {
|
|
131
|
+
cmpApi: 'iab',
|
|
132
|
+
timeout: 7500,
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const staticConfig = {
|
|
137
|
+
gpp: {
|
|
138
|
+
cmpApi: 'static',
|
|
139
|
+
timeout: 7500,
|
|
140
|
+
consentData: {
|
|
141
|
+
gppString: 'abc12345',
|
|
142
|
+
applicableSections: [7]
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
let didHookReturn;
|
|
148
|
+
|
|
149
|
+
beforeEach(resetConsentData);
|
|
150
|
+
after(resetConsentData);
|
|
151
|
+
|
|
152
|
+
describe('error checks:', function () {
|
|
153
|
+
beforeEach(function () {
|
|
154
|
+
didHookReturn = false;
|
|
155
|
+
sinon.stub(utils, 'logWarn');
|
|
156
|
+
sinon.stub(utils, 'logError');
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
afterEach(function () {
|
|
160
|
+
utils.logWarn.restore();
|
|
161
|
+
utils.logError.restore();
|
|
162
|
+
config.resetConfig();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should throw a warning and return to hooked function when an unknown CMP framework ID is used', function () {
|
|
166
|
+
let badCMPConfig = {
|
|
167
|
+
gpp: {
|
|
168
|
+
cmpApi: 'bad'
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
setConsentConfig(badCMPConfig);
|
|
172
|
+
expect(userCMP).to.be.equal(badCMPConfig.gpp.cmpApi);
|
|
173
|
+
|
|
174
|
+
requestBidsHook(() => {
|
|
175
|
+
didHookReturn = true;
|
|
176
|
+
}, {});
|
|
177
|
+
let consent = gppDataHandler.getConsentData();
|
|
178
|
+
|
|
179
|
+
sinon.assert.calledOnce(utils.logWarn);
|
|
180
|
+
expect(didHookReturn).to.be.true;
|
|
181
|
+
expect(consent).to.be.null;
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('should call gppDataHandler.setConsentData() when unknown CMP api is used', () => {
|
|
185
|
+
setConsentConfig({
|
|
186
|
+
gpp: {
|
|
187
|
+
cmpApi: 'invalid'
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
let hookRan = false;
|
|
191
|
+
requestBidsHook(() => {
|
|
192
|
+
hookRan = true;
|
|
193
|
+
}, {});
|
|
194
|
+
expect(hookRan).to.be.true;
|
|
195
|
+
expect(gppDataHandler.ready).to.be.true;
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
it('should throw proper errors when CMP is not found', function () {
|
|
199
|
+
setConsentConfig(goodConfig);
|
|
200
|
+
|
|
201
|
+
requestBidsHook(() => {
|
|
202
|
+
didHookReturn = true;
|
|
203
|
+
}, {});
|
|
204
|
+
let consent = gppDataHandler.getConsentData();
|
|
205
|
+
// throw 2 errors; one for no bidsBackHandler and for CMP not being found (this is an error due to gdpr config)
|
|
206
|
+
sinon.assert.calledTwice(utils.logError);
|
|
207
|
+
expect(didHookReturn).to.be.false;
|
|
208
|
+
expect(consent).to.be.null;
|
|
209
|
+
expect(gppDataHandler.ready).to.be.true;
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('should not trip when adUnits have no size', () => {
|
|
213
|
+
setConsentConfig(staticConfig);
|
|
214
|
+
let ran = false;
|
|
215
|
+
requestBidsHook(() => {
|
|
216
|
+
ran = true;
|
|
217
|
+
}, {
|
|
218
|
+
adUnits: [{
|
|
219
|
+
code: 'test',
|
|
220
|
+
mediaTypes: {
|
|
221
|
+
video: {}
|
|
222
|
+
}
|
|
223
|
+
}]
|
|
224
|
+
});
|
|
225
|
+
return gppDataHandler.promise.then(() => {
|
|
226
|
+
expect(ran).to.be.true;
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('should continue the auction immediately, without consent data, if timeout is 0', (done) => {
|
|
231
|
+
setConsentConfig({
|
|
232
|
+
gpp: {
|
|
233
|
+
cmpApi: 'iab',
|
|
234
|
+
timeout: 0
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
window.__gpp = function () {};
|
|
238
|
+
try {
|
|
239
|
+
requestBidsHook(() => {
|
|
240
|
+
const consent = gppDataHandler.getConsentData();
|
|
241
|
+
expect(consent.applicableSections).to.deep.equal([]);
|
|
242
|
+
expect(consent.gppString).to.be.undefined;
|
|
243
|
+
done();
|
|
244
|
+
}, {})
|
|
245
|
+
} finally {
|
|
246
|
+
delete window.__gpp;
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
describe('already known consentData:', function () {
|
|
252
|
+
let cmpStub = sinon.stub();
|
|
253
|
+
|
|
254
|
+
function mockCMP(cmpResponse) {
|
|
255
|
+
return function (...args) {
|
|
256
|
+
if (args[0] === 'addEventListener') {
|
|
257
|
+
args[1](({
|
|
258
|
+
eventName: 'sectionChange'
|
|
259
|
+
}));
|
|
260
|
+
} else if (args[0] === 'getGPPData') {
|
|
261
|
+
return cmpResponse;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
beforeEach(function () {
|
|
267
|
+
didHookReturn = false;
|
|
268
|
+
window.__gpp = function () {};
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
afterEach(function () {
|
|
272
|
+
config.resetConfig();
|
|
273
|
+
cmpStub.restore();
|
|
274
|
+
delete window.__gpp;
|
|
275
|
+
resetConsentData();
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it('should bypass CMP and simply use previously stored consentData', function () {
|
|
279
|
+
let testConsentData = {
|
|
280
|
+
applicableSections: [7],
|
|
281
|
+
gppString: 'xyz',
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
cmpStub = sinon.stub(window, '__gpp').callsFake(mockCMP(testConsentData));
|
|
285
|
+
setConsentConfig(goodConfig);
|
|
286
|
+
requestBidsHook(() => {}, {});
|
|
287
|
+
cmpStub.reset();
|
|
288
|
+
|
|
289
|
+
requestBidsHook(() => {
|
|
290
|
+
didHookReturn = true;
|
|
291
|
+
}, {});
|
|
292
|
+
let consent = gppDataHandler.getConsentData();
|
|
293
|
+
|
|
294
|
+
expect(didHookReturn).to.be.true;
|
|
295
|
+
expect(consent.gppString).to.equal(testConsentData.gppString);
|
|
296
|
+
expect(consent.applicableSections).to.deep.equal(testConsentData.applicableSections);
|
|
297
|
+
sinon.assert.notCalled(cmpStub);
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
describe('iframe tests', function () {
|
|
302
|
+
let cmpPostMessageCb = () => {};
|
|
303
|
+
let stringifyResponse;
|
|
304
|
+
|
|
305
|
+
function createIFrameMarker(frameName) {
|
|
306
|
+
let ifr = document.createElement('iframe');
|
|
307
|
+
ifr.width = 0;
|
|
308
|
+
ifr.height = 0;
|
|
309
|
+
ifr.name = frameName;
|
|
310
|
+
document.body.appendChild(ifr);
|
|
311
|
+
return ifr;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function creatCmpMessageHandler(prefix, returnEvtValue, returnGPPValue) {
|
|
315
|
+
return function (event) {
|
|
316
|
+
if (event && event.data) {
|
|
317
|
+
let data = event.data;
|
|
318
|
+
if (data[`${prefix}Call`]) {
|
|
319
|
+
let callId = data[`${prefix}Call`].callId;
|
|
320
|
+
let response;
|
|
321
|
+
if (data[`${prefix}Call`].command === 'addEventListener') {
|
|
322
|
+
response = {
|
|
323
|
+
[`${prefix}Return`]: {
|
|
324
|
+
callId,
|
|
325
|
+
returnValue: returnEvtValue,
|
|
326
|
+
success: true
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
} else if (data[`${prefix}Call`].command === 'getGPPData') {
|
|
330
|
+
response = {
|
|
331
|
+
[`${prefix}Return`]: {
|
|
332
|
+
callId,
|
|
333
|
+
returnValue: returnGPPValue,
|
|
334
|
+
success: true
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
event.source.postMessage(stringifyResponse ? JSON.stringify(response) : response, '*');
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function testIFramedPage(testName, messageFormatString, tarConsentString, tarSections) {
|
|
345
|
+
it(`should return the consent string from a postmessage + addEventListener response - ${testName}`, (done) => {
|
|
346
|
+
stringifyResponse = messageFormatString;
|
|
347
|
+
setConsentConfig(goodConfig);
|
|
348
|
+
requestBidsHook(() => {
|
|
349
|
+
let consent = gppDataHandler.getConsentData();
|
|
350
|
+
sinon.assert.notCalled(utils.logError);
|
|
351
|
+
expect(consent.gppString).to.equal(tarConsentString);
|
|
352
|
+
expect(consent.applicableSections).to.deep.equal(tarSections);
|
|
353
|
+
done();
|
|
354
|
+
}, {});
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
beforeEach(function () {
|
|
359
|
+
sinon.stub(utils, 'logError');
|
|
360
|
+
sinon.stub(utils, 'logWarn');
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
afterEach(function () {
|
|
364
|
+
utils.logError.restore();
|
|
365
|
+
utils.logWarn.restore();
|
|
366
|
+
config.resetConfig();
|
|
367
|
+
resetConsentData();
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
describe('v2 CMP workflow for iframe pages:', function () {
|
|
371
|
+
stringifyResponse = false;
|
|
372
|
+
let ifr2 = null;
|
|
373
|
+
|
|
374
|
+
beforeEach(function () {
|
|
375
|
+
ifr2 = createIFrameMarker('__gppLocator');
|
|
376
|
+
cmpPostMessageCb = creatCmpMessageHandler('__gpp', {
|
|
377
|
+
eventName: 'sectionChange'
|
|
378
|
+
}, {
|
|
379
|
+
gppString: 'abc12345234',
|
|
380
|
+
applicableSections: [7]
|
|
381
|
+
});
|
|
382
|
+
window.addEventListener('message', cmpPostMessageCb, false);
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
afterEach(function () {
|
|
386
|
+
delete window.__gpp; // deletes the local copy made by the postMessage CMP call function
|
|
387
|
+
document.body.removeChild(ifr2);
|
|
388
|
+
window.removeEventListener('message', cmpPostMessageCb);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
testIFramedPage('with/JSON response', false, 'abc12345234', [7]);
|
|
392
|
+
testIFramedPage('with/String response', true, 'abc12345234', [7]);
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
describe('direct calls to CMP API tests', function () {
|
|
397
|
+
let cmpStub = sinon.stub();
|
|
398
|
+
|
|
399
|
+
beforeEach(function () {
|
|
400
|
+
didHookReturn = false;
|
|
401
|
+
sinon.stub(utils, 'logError');
|
|
402
|
+
sinon.stub(utils, 'logWarn');
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
afterEach(function () {
|
|
406
|
+
config.resetConfig();
|
|
407
|
+
cmpStub.restore();
|
|
408
|
+
utils.logError.restore();
|
|
409
|
+
utils.logWarn.restore();
|
|
410
|
+
resetConsentData();
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
describe('v2 CMP workflow for normal pages:', function () {
|
|
414
|
+
beforeEach(function () {
|
|
415
|
+
window.__gpp = function () {};
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
afterEach(function () {
|
|
419
|
+
delete window.__gpp;
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
it('performs lookup check and stores consentData for a valid existing user', function () {
|
|
423
|
+
let testConsentData = {
|
|
424
|
+
gppString: 'abc12345234',
|
|
425
|
+
applicableSections: [7]
|
|
426
|
+
};
|
|
427
|
+
cmpStub = sinon.stub(window, '__gpp').callsFake((...args) => {
|
|
428
|
+
if (args[0] === 'addEventListener') {
|
|
429
|
+
args[1]({
|
|
430
|
+
eventName: 'sectionChange'
|
|
431
|
+
});
|
|
432
|
+
} else if (args[0] === 'getGPPData') {
|
|
433
|
+
return testConsentData;
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
setConsentConfig(goodConfig);
|
|
438
|
+
|
|
439
|
+
requestBidsHook(() => {
|
|
440
|
+
didHookReturn = true;
|
|
441
|
+
}, {});
|
|
442
|
+
let consent = gppDataHandler.getConsentData();
|
|
443
|
+
sinon.assert.notCalled(utils.logError);
|
|
444
|
+
expect(didHookReturn).to.be.true;
|
|
445
|
+
expect(consent.gppString).to.equal(testConsentData.gppString);
|
|
446
|
+
expect(consent.applicableSections).to.deep.equal(testConsentData.applicableSections);
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
it('produces gdpr metadata', function () {
|
|
450
|
+
let testConsentData = {
|
|
451
|
+
gppString: 'abc12345234',
|
|
452
|
+
applicableSections: [7]
|
|
453
|
+
};
|
|
454
|
+
cmpStub = sinon.stub(window, '__gpp').callsFake((...args) => {
|
|
455
|
+
if (args[0] === 'addEventListener') {
|
|
456
|
+
args[1]({
|
|
457
|
+
eventName: 'sectionChange'
|
|
458
|
+
});
|
|
459
|
+
} else if (args[0] === 'getGPPData') {
|
|
460
|
+
return testConsentData;
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
setConsentConfig(goodConfig);
|
|
465
|
+
|
|
466
|
+
requestBidsHook(() => {
|
|
467
|
+
didHookReturn = true;
|
|
468
|
+
}, {});
|
|
469
|
+
let consentMeta = gppDataHandler.getConsentMeta();
|
|
470
|
+
sinon.assert.notCalled(utils.logError);
|
|
471
|
+
expect(consentMeta.generatedAt).to.be.above(1644367751709);
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
it('throws an error when processCmpData check fails + does not call requestBids callback', function () {
|
|
475
|
+
let testConsentData = {};
|
|
476
|
+
let bidsBackHandlerReturn = false;
|
|
477
|
+
|
|
478
|
+
cmpStub = sinon.stub(window, '__gpp').callsFake((...args) => {
|
|
479
|
+
if (args[0] === 'addEventListener') {
|
|
480
|
+
args[1]({
|
|
481
|
+
eventName: 'sectionChange'
|
|
482
|
+
});
|
|
483
|
+
} else if (args[0] === 'getGPPData') {
|
|
484
|
+
return testConsentData;
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
setConsentConfig(goodConfig);
|
|
489
|
+
|
|
490
|
+
sinon.assert.notCalled(utils.logWarn);
|
|
491
|
+
sinon.assert.notCalled(utils.logError);
|
|
492
|
+
|
|
493
|
+
[utils.logWarn, utils.logError].forEach((stub) => stub.reset());
|
|
494
|
+
|
|
495
|
+
requestBidsHook(() => {
|
|
496
|
+
didHookReturn = true;
|
|
497
|
+
}, {
|
|
498
|
+
bidsBackHandler: () => bidsBackHandlerReturn = true
|
|
499
|
+
});
|
|
500
|
+
let consent = gppDataHandler.getConsentData();
|
|
501
|
+
|
|
502
|
+
sinon.assert.calledOnce(utils.logError);
|
|
503
|
+
sinon.assert.notCalled(utils.logWarn);
|
|
504
|
+
expect(didHookReturn).to.be.false;
|
|
505
|
+
expect(bidsBackHandlerReturn).to.be.true;
|
|
506
|
+
expect(consent).to.be.null;
|
|
507
|
+
expect(gppDataHandler.ready).to.be.true;
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
describe('when proper consent is not available', () => {
|
|
511
|
+
let gppStub;
|
|
512
|
+
|
|
513
|
+
function runAuction() {
|
|
514
|
+
setConsentConfig({
|
|
515
|
+
gpp: {
|
|
516
|
+
cmpApi: 'iab',
|
|
517
|
+
timeout: 10,
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
return new Promise((resolve, reject) => {
|
|
521
|
+
requestBidsHook(() => {
|
|
522
|
+
didHookReturn = true;
|
|
523
|
+
}, {});
|
|
524
|
+
setTimeout(() => didHookReturn ? resolve() : reject(new Error('Auction did not run')), 20);
|
|
525
|
+
})
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
function mockGppCmp(gppdata) {
|
|
529
|
+
gppStub.callsFake((api, cb) => {
|
|
530
|
+
if (api === 'addEventListener') {
|
|
531
|
+
// eslint-disable-next-line standard/no-callback-literal
|
|
532
|
+
cb({
|
|
533
|
+
pingData: {
|
|
534
|
+
cmpStatus: 'loaded'
|
|
535
|
+
}
|
|
536
|
+
}, true);
|
|
537
|
+
}
|
|
538
|
+
if (api === 'getGPPData') {
|
|
539
|
+
return gppdata;
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
beforeEach(() => {
|
|
545
|
+
gppStub = sinon.stub(window, '__gpp');
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
afterEach(() => {
|
|
549
|
+
gppStub.restore();
|
|
550
|
+
})
|
|
551
|
+
|
|
552
|
+
it('should continue auction with null consent when CMP is unresponsive', () => {
|
|
553
|
+
return runAuction().then(() => {
|
|
554
|
+
const consent = gppDataHandler.getConsentData();
|
|
555
|
+
expect(consent.applicableSections).to.deep.equal([]);
|
|
556
|
+
expect(consent.gppString).to.be.undefined;
|
|
557
|
+
expect(gppDataHandler.ready).to.be.true;
|
|
558
|
+
});
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
it('should use consent provided by events other than sectionChange', () => {
|
|
562
|
+
mockGppCmp({
|
|
563
|
+
gppString: 'mock-consent-string',
|
|
564
|
+
applicableSections: [7]
|
|
565
|
+
});
|
|
566
|
+
return runAuction().then(() => {
|
|
567
|
+
const consent = gppDataHandler.getConsentData();
|
|
568
|
+
expect(consent.applicableSections).to.deep.equal([7]);
|
|
569
|
+
expect(consent.gppString).to.equal('mock-consent-string');
|
|
570
|
+
expect(gppDataHandler.ready).to.be.true;
|
|
571
|
+
});
|
|
572
|
+
});
|
|
573
|
+
});
|
|
574
|
+
});
|
|
575
|
+
});
|
|
576
|
+
});
|
|
577
|
+
});
|
|
@@ -840,24 +840,6 @@ describe('TheMediaGrid Adapter', function () {
|
|
|
840
840
|
expect(payload.site.content.id).to.equal(contentId);
|
|
841
841
|
});
|
|
842
842
|
|
|
843
|
-
it('should be right tmax when timeout in config is less then timeout in bidderRequest', function() {
|
|
844
|
-
const getConfigStub = sinon.stub(config, 'getConfig').callsFake(
|
|
845
|
-
arg => arg === 'bidderTimeout' ? 2000 : null);
|
|
846
|
-
const [request] = spec.buildRequests([bidRequests[0]], bidderRequest);
|
|
847
|
-
expect(request.data).to.be.an('string');
|
|
848
|
-
const payload = parseRequest(request.data);
|
|
849
|
-
expect(payload.tmax).to.equal(2000);
|
|
850
|
-
getConfigStub.restore();
|
|
851
|
-
});
|
|
852
|
-
it('should be right tmax when timeout in bidderRequest is less then timeout in config', function() {
|
|
853
|
-
const getConfigStub = sinon.stub(config, 'getConfig').callsFake(
|
|
854
|
-
arg => arg === 'bidderTimeout' ? 5000 : null);
|
|
855
|
-
const [request] = spec.buildRequests([bidRequests[0]], bidderRequest);
|
|
856
|
-
expect(request.data).to.be.an('string');
|
|
857
|
-
const payload = parseRequest(request.data);
|
|
858
|
-
expect(payload.tmax).to.equal(3000);
|
|
859
|
-
getConfigStub.restore();
|
|
860
|
-
});
|
|
861
843
|
it('should contain regs.coppa if coppa is true in config', function () {
|
|
862
844
|
const getConfigStub = sinon.stub(config, 'getConfig').callsFake(
|
|
863
845
|
arg => arg === 'coppa' ? true : null);
|
|
@@ -306,7 +306,7 @@ const ANALYTICS_MESSAGE = {
|
|
|
306
306
|
describe('magnite analytics adapter', function () {
|
|
307
307
|
let sandbox;
|
|
308
308
|
let clock;
|
|
309
|
-
let getDataFromLocalStorageStub, setDataInLocalStorageStub, localStorageIsEnabledStub;
|
|
309
|
+
let getDataFromLocalStorageStub, setDataInLocalStorageStub, localStorageIsEnabledStub, removeDataFromLocalStorageStub;
|
|
310
310
|
let gptSlot0;
|
|
311
311
|
let gptSlotRenderEnded0;
|
|
312
312
|
beforeEach(function () {
|
|
@@ -325,6 +325,7 @@ describe('magnite analytics adapter', function () {
|
|
|
325
325
|
getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage');
|
|
326
326
|
setDataInLocalStorageStub = sinon.stub(storage, 'setDataInLocalStorage');
|
|
327
327
|
localStorageIsEnabledStub = sinon.stub(storage, 'localStorageIsEnabled');
|
|
328
|
+
removeDataFromLocalStorageStub = sinon.stub(storage, 'removeDataFromLocalStorage')
|
|
328
329
|
sandbox = sinon.sandbox.create();
|
|
329
330
|
|
|
330
331
|
localStorageIsEnabledStub.returns(true);
|
|
@@ -355,6 +356,7 @@ describe('magnite analytics adapter', function () {
|
|
|
355
356
|
getDataFromLocalStorageStub.restore();
|
|
356
357
|
setDataInLocalStorageStub.restore();
|
|
357
358
|
localStorageIsEnabledStub.restore();
|
|
359
|
+
removeDataFromLocalStorageStub.restore();
|
|
358
360
|
magniteAdapter.disableAnalytics();
|
|
359
361
|
});
|
|
360
362
|
|
|
@@ -1932,19 +1934,21 @@ describe('magnite analytics adapter', function () {
|
|
|
1932
1934
|
});
|
|
1933
1935
|
});
|
|
1934
1936
|
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1937
|
+
describe('getHostNameFromReferer', () => {
|
|
1938
|
+
it('correctly grabs hostname from an input URL', function () {
|
|
1939
|
+
let inputUrl = 'https://www.prebid.org/some/path?pbjs_debug=true';
|
|
1940
|
+
expect(getHostNameFromReferer(inputUrl)).to.equal('www.prebid.org');
|
|
1941
|
+
inputUrl = 'https://www.prebid.com/some/path?pbjs_debug=true';
|
|
1942
|
+
expect(getHostNameFromReferer(inputUrl)).to.equal('www.prebid.com');
|
|
1943
|
+
inputUrl = 'https://prebid.org/some/path?pbjs_debug=true';
|
|
1944
|
+
expect(getHostNameFromReferer(inputUrl)).to.equal('prebid.org');
|
|
1945
|
+
inputUrl = 'http://xn--p8j9a0d9c9a.xn--q9jyb4c/';
|
|
1946
|
+
expect(typeof getHostNameFromReferer(inputUrl)).to.equal('string');
|
|
1947
|
+
|
|
1948
|
+
// not non-UTF char's in query / path which break if noDecodeWholeURL not set
|
|
1949
|
+
inputUrl = 'https://prebid.org/search_results/%95x%8Em%92%CA/?category=000';
|
|
1950
|
+
expect(getHostNameFromReferer(inputUrl)).to.equal('prebid.org');
|
|
1951
|
+
});
|
|
1948
1952
|
});
|
|
1949
1953
|
|
|
1950
1954
|
describe(`handle currency conversions`, () => {
|
|
@@ -1985,4 +1989,22 @@ describe('magnite analytics adapter', function () {
|
|
|
1985
1989
|
expect(bidResponseObj.bidPriceUSD).to.equal(0);
|
|
1986
1990
|
});
|
|
1987
1991
|
});
|
|
1992
|
+
|
|
1993
|
+
describe('onDataDeletionRequest', () => {
|
|
1994
|
+
it('attempts to delete the magnite cookie when local storage is enabled', () => {
|
|
1995
|
+
magniteAdapter.onDataDeletionRequest();
|
|
1996
|
+
|
|
1997
|
+
expect(removeDataFromLocalStorageStub.getCall(0).args[0]).to.equal('mgniSession');
|
|
1998
|
+
});
|
|
1999
|
+
|
|
2000
|
+
it('throws an error if it cannot access the cookie', (done) => {
|
|
2001
|
+
localStorageIsEnabledStub.returns(false);
|
|
2002
|
+
try {
|
|
2003
|
+
magniteAdapter.onDataDeletionRequest();
|
|
2004
|
+
} catch (error) {
|
|
2005
|
+
expect(error.message).to.equal('Unable to access local storage, no data deleted');
|
|
2006
|
+
done();
|
|
2007
|
+
}
|
|
2008
|
+
})
|
|
2009
|
+
});
|
|
1988
2010
|
});
|