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.
Files changed (154) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/33acrossIdSystem.js +1 -1
  3. package/dist/adagioBidAdapter.js +1 -1
  4. package/dist/adbookpspBidAdapter.js +1 -1
  5. package/dist/adgenerationBidAdapter.js +1 -1
  6. package/dist/adrelevantisBidAdapter.js +1 -1
  7. package/dist/adtrgtmeBidAdapter.js +1 -1
  8. package/dist/adxcgBidAdapter.js +1 -1
  9. package/dist/ajaBidAdapter.js +1 -1
  10. package/dist/amxBidAdapter.js +1 -1
  11. package/dist/amxIdSystem.js +1 -1
  12. package/dist/appierAnalyticsAdapter.js +1 -1
  13. package/dist/appnexusBidAdapter.js +1 -1
  14. package/dist/asoBidAdapter.js +1 -1
  15. package/dist/axonixBidAdapter.js +1 -1
  16. package/dist/bidViewability.js +1 -1
  17. package/dist/bidglassBidAdapter.js +1 -1
  18. package/dist/big-richmediaBidAdapter.js +1 -1
  19. package/dist/bridgewellBidAdapter.js +1 -1
  20. package/dist/brightMountainMediaBidAdapter.js +1 -1
  21. package/dist/byDataAnalyticsAdapter.js +1 -1
  22. package/dist/carodaBidAdapter.js +1 -1
  23. package/dist/ccxBidAdapter.js +1 -1
  24. package/dist/chtnwBidAdapter.js +1 -1
  25. package/dist/colossussspBidAdapter.js +1 -1
  26. package/dist/concertBidAdapter.js +1 -1
  27. package/dist/connectadBidAdapter.js +1 -1
  28. package/dist/consentManagement.js +1 -1
  29. package/dist/consentManagementGpp.js +1 -0
  30. package/dist/consumableBidAdapter.js +1 -1
  31. package/dist/conversantBidAdapter.js +1 -1
  32. package/dist/craftBidAdapter.js +1 -1
  33. package/dist/criteoBidAdapter.js +1 -1
  34. package/dist/dfpAdServerVideo.js +1 -1
  35. package/dist/dspxBidAdapter.js +1 -1
  36. package/dist/eplanningBidAdapter.js +1 -1
  37. package/dist/finativeBidAdapter.js +1 -1
  38. package/dist/glimpseBidAdapter.js +1 -1
  39. package/dist/gmosspBidAdapter.js +1 -1
  40. package/dist/goldbachBidAdapter.js +1 -1
  41. package/dist/gridBidAdapter.js +1 -1
  42. package/dist/gridNMBidAdapter.js +1 -1
  43. package/dist/gumgumBidAdapter.js +1 -1
  44. package/dist/h12mediaBidAdapter.js +1 -1
  45. package/dist/id5IdSystem.js +1 -1
  46. package/dist/improvedigitalBidAdapter.js +1 -1
  47. package/dist/inmarBidAdapter.js +1 -1
  48. package/dist/insticatorBidAdapter.js +1 -1
  49. package/dist/ixBidAdapter.js +1 -1
  50. package/dist/justpremiumBidAdapter.js +1 -1
  51. package/dist/konduitAnalyticsAdapter.js +1 -1
  52. package/dist/kueezBidAdapter.js +1 -1
  53. package/dist/kueezRtbBidAdapter.js +1 -1
  54. package/dist/lassoBidAdapter.js +1 -1
  55. package/dist/lifestreetBidAdapter.js +1 -1
  56. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  57. package/dist/logicadBidAdapter.js +1 -1
  58. package/dist/loglyliftBidAdapter.js +1 -1
  59. package/dist/magniteAnalyticsAdapter.js +1 -1
  60. package/dist/malltvAnalyticsAdapter.js +1 -1
  61. package/dist/marsmediaBidAdapter.js +1 -1
  62. package/dist/mediafuseBidAdapter.js +1 -1
  63. package/dist/mediasquareBidAdapter.js +1 -1
  64. package/dist/mgidBidAdapter.js +1 -1
  65. package/dist/minutemediaBidAdapter.js +1 -1
  66. package/dist/nexx360BidAdapter.js +1 -1
  67. package/dist/not-for-prod/prebid.js +122 -120
  68. package/dist/oguryBidAdapter.js +1 -1
  69. package/dist/onetagBidAdapter.js +1 -1
  70. package/dist/ooloAnalyticsAdapter.js +1 -1
  71. package/dist/outbrainBidAdapter.js +1 -1
  72. package/dist/parrableIdSystem.js +1 -1
  73. package/dist/pixfutureBidAdapter.js +1 -1
  74. package/dist/prebid-core.js +1 -1
  75. package/dist/prebidServerBidAdapter.js +1 -1
  76. package/dist/publinkIdSystem.js +1 -1
  77. package/dist/pubmaticBidAdapter.js +1 -1
  78. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  79. package/dist/pxyzBidAdapter.js +1 -1
  80. package/dist/quantcastBidAdapter.js +1 -1
  81. package/dist/readpeakBidAdapter.js +1 -1
  82. package/dist/relaidoBidAdapter.js +1 -1
  83. package/dist/rhythmoneBidAdapter.js +1 -1
  84. package/dist/riseBidAdapter.js +1 -1
  85. package/dist/rtdModule.js +1 -1
  86. package/dist/rubiconAnalyticsAdapter.js +1 -1
  87. package/dist/rubiconBidAdapter.js +1 -1
  88. package/dist/seedingAllianceBidAdapter.js +1 -1
  89. package/dist/seedtagBidAdapter.js +1 -1
  90. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  91. package/dist/sharethroughBidAdapter.js +1 -1
  92. package/dist/shinezBidAdapter.js +1 -1
  93. package/dist/smaatoBidAdapter.js +1 -1
  94. package/dist/smartadserverBidAdapter.js +1 -1
  95. package/dist/smartxBidAdapter.js +1 -1
  96. package/dist/smilewantedBidAdapter.js +1 -1
  97. package/dist/sonobiBidAdapter.js +1 -1
  98. package/dist/sovrnAnalyticsAdapter.js +1 -1
  99. package/dist/sovrnBidAdapter.js +1 -1
  100. package/dist/sspBCBidAdapter.js +1 -1
  101. package/dist/sublimeBidAdapter.js +1 -1
  102. package/dist/synacormediaBidAdapter.js +1 -1
  103. package/dist/targetVideoBidAdapter.js +1 -1
  104. package/dist/teadsBidAdapter.js +1 -1
  105. package/dist/trionBidAdapter.js +1 -1
  106. package/dist/tripleliftBidAdapter.js +1 -1
  107. package/dist/ttdBidAdapter.js +1 -1
  108. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  109. package/dist/uid2IdSystem.js +1 -1
  110. package/dist/underdogmediaBidAdapter.js +1 -1
  111. package/dist/undertoneBidAdapter.js +1 -1
  112. package/dist/vidazooBidAdapter.js +1 -1
  113. package/dist/videobyteBidAdapter.js +1 -1
  114. package/dist/viouslyBidAdapter.js +1 -0
  115. package/dist/visxBidAdapter.js +1 -1
  116. package/dist/vuukleBidAdapter.js +1 -1
  117. package/dist/widespaceBidAdapter.js +1 -1
  118. package/dist/winrBidAdapter.js +1 -1
  119. package/dist/yahoosspBidAdapter.js +1 -1
  120. package/dist/yieldmoBidAdapter.js +1 -1
  121. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  122. package/integrationExamples/gpt/gpp_us_hello_world.html +124 -0
  123. package/integrationExamples/gpt/gpp_us_hello_world_iframe.html +12 -0
  124. package/integrationExamples/gpt/gpp_us_hello_world_iframe_subpage.html +140 -0
  125. package/karma.conf.maker.js +1 -1
  126. package/modules/appnexusBidAdapter.js +23 -2
  127. package/modules/bidViewability.js +6 -1
  128. package/modules/ccxBidAdapter.js +3 -2
  129. package/modules/colossussspBidAdapter.js +8 -0
  130. package/modules/consentManagement.js +4 -4
  131. package/modules/consentManagementGpp.js +386 -0
  132. package/modules/dfpAdServerVideo.js +6 -1
  133. package/modules/gridBidAdapter.js +1 -2
  134. package/modules/lassoBidAdapter.js +2 -2
  135. package/modules/magniteAnalyticsAdapter.js +9 -1
  136. package/modules/onetagBidAdapter.js +20 -29
  137. package/modules/prebidServerBidAdapter/index.js +19 -8
  138. package/modules/rtdModule/index.js +2 -1
  139. package/modules/viouslyBidAdapter.js +209 -0
  140. package/modules/viouslyBidAdapter.md +35 -0
  141. package/package.json +1 -1
  142. package/src/adapterManager.js +11 -10
  143. package/src/adapters/bidderFactory.js +5 -5
  144. package/src/consentHandler.js +11 -0
  145. package/src/prebid.js +2 -1
  146. package/test/helpers/hookSetup.js +5 -0
  147. package/test/spec/modules/ViouslyBidAdapter_spec.js +378 -0
  148. package/test/spec/modules/appnexusBidAdapter_spec.js +46 -0
  149. package/test/spec/modules/colossussspBidAdapter_spec.js +89 -2
  150. package/test/spec/modules/consentManagementGpp_spec.js +577 -0
  151. package/test/spec/modules/gridBidAdapter_spec.js +0 -18
  152. package/test/spec/modules/magniteAnalyticsAdapter_spec.js +36 -14
  153. package/test/spec/modules/onetagBidAdapter_spec.js +29 -23
  154. 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
- it('getHostNameFromReferer correctly grabs hostname from an input URL', function () {
1936
- let inputUrl = 'https://www.prebid.org/some/path?pbjs_debug=true';
1937
- expect(getHostNameFromReferer(inputUrl)).to.equal('www.prebid.org');
1938
- inputUrl = 'https://www.prebid.com/some/path?pbjs_debug=true';
1939
- expect(getHostNameFromReferer(inputUrl)).to.equal('www.prebid.com');
1940
- inputUrl = 'https://prebid.org/some/path?pbjs_debug=true';
1941
- expect(getHostNameFromReferer(inputUrl)).to.equal('prebid.org');
1942
- inputUrl = 'http://xn--p8j9a0d9c9a.xn--q9jyb4c/';
1943
- expect(typeof getHostNameFromReferer(inputUrl)).to.equal('string');
1944
-
1945
- // not non-UTF char's in query / path which break if noDecodeWholeURL not set
1946
- inputUrl = 'https://prebid.org/search_results/%95x%8Em%92%CA/?category=000';
1947
- expect(getHostNameFromReferer(inputUrl)).to.equal('prebid.org');
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
  });