prebid.js 6.1.0 → 6.5.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 (184) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/README.md +1 -1
  3. package/browsers.json +13 -29
  4. package/gulpfile.js +87 -82
  5. package/integrationExamples/gpt/weboramaRtdProvider_example.html +23 -14
  6. package/karma.conf.maker.js +2 -2
  7. package/modules/33acrossBidAdapter.js +189 -102
  8. package/modules/adagioBidAdapter.js +1 -1
  9. package/modules/addefendBidAdapter.js +1 -0
  10. package/modules/adkernelBidAdapter.js +146 -61
  11. package/modules/adlooxAdServerVideo.js +2 -2
  12. package/modules/adlooxAnalyticsAdapter.js +4 -4
  13. package/modules/admanBidAdapter.js +1 -0
  14. package/modules/admixerBidAdapter.js +3 -2
  15. package/modules/adnuntiusBidAdapter.js +5 -2
  16. package/modules/adomikAnalyticsAdapter.js +6 -0
  17. package/modules/adplusBidAdapter.js +203 -0
  18. package/modules/adplusBidAdapter.md +39 -0
  19. package/modules/adxcgBidAdapter.js +311 -359
  20. package/modules/adxcgBidAdapter.md +22 -21
  21. package/modules/adyoulikeBidAdapter.js +20 -11
  22. package/modules/aniviewBidAdapter.js +1 -1
  23. package/modules/appnexusBidAdapter.js +19 -3
  24. package/modules/beachfrontBidAdapter.js +14 -17
  25. package/modules/beopBidAdapter.js +6 -4
  26. package/modules/bidViewability.js +3 -3
  27. package/modules/bidViewabilityIO.js +3 -3
  28. package/modules/bliinkBidAdapter.js +1 -1
  29. package/modules/colossussspBidAdapter.js +7 -0
  30. package/modules/compassBidAdapter.js +201 -0
  31. package/modules/compassBidAdapter.md +79 -0
  32. package/modules/consentManagement.js +7 -1
  33. package/modules/craftBidAdapter.js +5 -3
  34. package/modules/criteoBidAdapter.js +1 -1
  35. package/modules/currency.js +2 -2
  36. package/modules/cwireBidAdapter.js +3 -0
  37. package/modules/dailyhuntBidAdapter.js +435 -0
  38. package/modules/dailyhuntBidAdapter.md +4 -0
  39. package/modules/dchain.js +149 -0
  40. package/modules/dchain.md +45 -0
  41. package/modules/docereeBidAdapter.js +10 -1
  42. package/modules/docereeBidAdapter.md +2 -0
  43. package/modules/dspxBidAdapter.js +1 -1
  44. package/modules/emx_digitalBidAdapter.js +9 -1
  45. package/modules/engageyaBidAdapter.js +1 -1
  46. package/modules/feedadBidAdapter.js +2 -2
  47. package/modules/feedadBidAdapter.md +4 -2
  48. package/modules/freewheel-sspBidAdapter.js +6 -0
  49. package/modules/futureads.md +48 -0
  50. package/modules/glimpseBidAdapter.js +16 -3
  51. package/modules/goldbachBidAdapter.js +1176 -0
  52. package/modules/goldbachBidAdapter.md +151 -0
  53. package/modules/gptPreAuction.js +55 -7
  54. package/modules/gridBidAdapter.js +4 -3
  55. package/modules/gumgumBidAdapter.js +7 -3
  56. package/modules/improvedigitalBidAdapter.js +19 -3
  57. package/modules/instreamTracking.js +4 -4
  58. package/modules/intersectionRtdProvider.js +114 -0
  59. package/modules/invibesBidAdapter.js +64 -14
  60. package/modules/invibesBidAdapter.md +2 -1
  61. package/modules/ipromBidAdapter.js +79 -0
  62. package/modules/ixBidAdapter.js +53 -18
  63. package/modules/kinessoIdSystem.js +1 -1
  64. package/modules/limelightDigitalBidAdapter.js +3 -1
  65. package/modules/livewrappedAnalyticsAdapter.js +3 -1
  66. package/modules/livewrappedBidAdapter.js +8 -2
  67. package/modules/loglyliftBidAdapter.js +79 -0
  68. package/modules/loglyliftBidAdapter.md +55 -0
  69. package/modules/lotamePanoramaIdSystem.js +80 -8
  70. package/modules/luponmediaBidAdapter.js +570 -0
  71. package/modules/mediasquareBidAdapter.js +1 -9
  72. package/modules/missenaBidAdapter.js +89 -0
  73. package/modules/nextMillenniumBidAdapter.js +37 -7
  74. package/modules/optimeraRtdProvider.js +8 -1
  75. package/modules/ozoneBidAdapter.js +21 -64
  76. package/modules/prebidServerBidAdapter/index.js +16 -12
  77. package/modules/pubgeniusBidAdapter.js +1 -1
  78. package/modules/pubmaticBidAdapter.js +3 -3
  79. package/modules/pubxaiAnalyticsAdapter.js +17 -0
  80. package/modules/relaidoBidAdapter.js +86 -65
  81. package/modules/richaudienceBidAdapter.js +2 -3
  82. package/modules/rtdModule/index.js +48 -18
  83. package/modules/rubiconBidAdapter.js +31 -19
  84. package/modules/sharedIdSystem.js +27 -1
  85. package/modules/smaatoBidAdapter.js +4 -1
  86. package/modules/smartxBidAdapter.js +17 -1
  87. package/modules/tappxBidAdapter.js +3 -1
  88. package/modules/targetVideoBidAdapter.js +187 -0
  89. package/modules/targetVideoBidAdapter.md +34 -0
  90. package/modules/telariaBidAdapter.js +2 -2
  91. package/modules/trustxBidAdapter.js +8 -16
  92. package/modules/undertoneBidAdapter.js +8 -1
  93. package/modules/userId/index.js +27 -2
  94. package/modules/ventes.md +71 -0
  95. package/modules/ventesBidAdapter.js +104 -64
  96. package/modules/ventesBidAdapter.md +0 -1
  97. package/modules/vidoomyBidAdapter.js +16 -10
  98. package/modules/visxBidAdapter.js +19 -2
  99. package/modules/visxBidAdapter.md +4 -6
  100. package/modules/weboramaRtdProvider.js +288 -73
  101. package/modules/weboramaRtdProvider.md +27 -10
  102. package/modules/yahoosspBidAdapter.js +5 -1
  103. package/modules/yahoosspBidAdapter.md +1 -1
  104. package/modules/yieldmoBidAdapter.js +23 -5
  105. package/modules/yieldoneBidAdapter.js +115 -11
  106. package/modules/zetaSspBidAdapter.md +33 -1
  107. package/modules/zeta_global_sspAnalyticsAdapter.js +97 -0
  108. package/modules/zeta_global_sspAnalyticsAdapter.md +24 -0
  109. package/modules/zeta_global_sspBidAdapter.js +22 -1
  110. package/package.json +1 -1
  111. package/plugins/pbjsGlobals.js +28 -1
  112. package/src/auction.js +5 -4
  113. package/src/config.js +27 -3
  114. package/src/prebid.js +3 -2
  115. package/src/targeting.js +24 -3
  116. package/src/utils.js +53 -8
  117. package/test/helpers/prebidGlobal.js +1 -0
  118. package/test/spec/config_spec.js +279 -0
  119. package/test/spec/integration/faker/googletag.js +6 -0
  120. package/test/spec/modules/33acrossBidAdapter_spec.js +300 -78
  121. package/test/spec/modules/adlooxAnalyticsAdapter_spec.js +6 -6
  122. package/test/spec/modules/adnuntiusBidAdapter_spec.js +35 -0
  123. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +6 -0
  124. package/test/spec/modules/adplusBidAdapter_spec.js +213 -0
  125. package/test/spec/modules/adxcgBidAdapter_spec.js +820 -571
  126. package/test/spec/modules/adyoulikeBidAdapter_spec.js +75 -0
  127. package/test/spec/modules/appnexusBidAdapter_spec.js +49 -1
  128. package/test/spec/modules/beachfrontBidAdapter_spec.js +65 -1
  129. package/test/spec/modules/beopBidAdapter_spec.js +1 -1
  130. package/test/spec/modules/bidViewabilityIO_spec.js +2 -2
  131. package/test/spec/modules/bidViewability_spec.js +4 -4
  132. package/test/spec/modules/colossussspBidAdapter_spec.js +9 -0
  133. package/test/spec/modules/compassBidAdapter_spec.js +397 -0
  134. package/test/spec/modules/consentManagement_spec.js +20 -0
  135. package/test/spec/modules/cwireBidAdapter_spec.js +10 -8
  136. package/test/spec/modules/dailyhuntBidAdapter_spec.js +404 -0
  137. package/test/spec/modules/dchain_spec.js +329 -0
  138. package/test/spec/modules/docereeBidAdapter_spec.js +9 -1
  139. package/test/spec/modules/emx_digitalBidAdapter_spec.js +10 -0
  140. package/test/spec/modules/feedadBidAdapter_spec.js +15 -0
  141. package/test/spec/modules/freewheel-sspBidAdapter_spec.js +19 -0
  142. package/test/spec/modules/goldbachBidAdapter_spec.js +1359 -0
  143. package/test/spec/modules/gptPreAuction_spec.js +177 -2
  144. package/test/spec/modules/gumgumBidAdapter_spec.js +6 -0
  145. package/test/spec/modules/improvedigitalBidAdapter_spec.js +3 -1
  146. package/test/spec/modules/intersectionRtdProvider_spec.js +141 -0
  147. package/test/spec/modules/invibesBidAdapter_spec.js +148 -4
  148. package/test/spec/modules/ipromBidAdapter_spec.js +195 -0
  149. package/test/spec/modules/ixBidAdapter_spec.js +112 -62
  150. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +84 -23
  151. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +22 -0
  152. package/test/spec/modules/livewrappedBidAdapter_spec.js +31 -0
  153. package/test/spec/modules/loglyliftBidAdapter_spec.js +172 -0
  154. package/test/spec/modules/lotamePanoramaIdSystem_spec.js +227 -0
  155. package/test/spec/modules/luponmediaBidAdapter_spec.js +412 -0
  156. package/test/spec/modules/mediasquareBidAdapter_spec.js +4 -4
  157. package/test/spec/modules/missenaBidAdapter_spec.js +134 -0
  158. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +26 -1
  159. package/test/spec/modules/optimeraRtdProvider_spec.js +14 -1
  160. package/test/spec/modules/ozoneBidAdapter_spec.js +43 -31
  161. package/test/spec/modules/prebidServerBidAdapter_spec.js +43 -0
  162. package/test/spec/modules/pubgeniusBidAdapter_spec.js +3 -3
  163. package/test/spec/modules/pubmaticBidAdapter_spec.js +1 -1
  164. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +11 -0
  165. package/test/spec/modules/realTimeDataModule_spec.js +135 -49
  166. package/test/spec/modules/relaidoBidAdapter_spec.js +71 -63
  167. package/test/spec/modules/richaudienceBidAdapter_spec.js +2 -2
  168. package/test/spec/modules/rubiconBidAdapter_spec.js +65 -9
  169. package/test/spec/modules/sharedIdSystem_spec.js +52 -6
  170. package/test/spec/modules/smaatoBidAdapter_spec.js +31 -0
  171. package/test/spec/modules/smartxBidAdapter_spec.js +9 -0
  172. package/test/spec/modules/tappxBidAdapter_spec.js +4 -0
  173. package/test/spec/modules/targetVideoBidAdapter_spec.js +96 -0
  174. package/test/spec/modules/userId_spec.js +51 -0
  175. package/test/spec/modules/visxBidAdapter_spec.js +120 -4
  176. package/test/spec/modules/weboramaRtdProvider_spec.js +408 -214
  177. package/test/spec/modules/yahoosspBidAdapter_spec.js +28 -1
  178. package/test/spec/modules/yieldoneBidAdapter_spec.js +299 -53
  179. package/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +427 -0
  180. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +33 -1
  181. package/test/spec/unit/core/targeting_spec.js +116 -0
  182. package/test/spec/utils_spec.js +38 -0
  183. package/test/test_deps.js +3 -0
  184. package/test/test_index.js +1 -3
package/src/utils.js CHANGED
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable no-console */
2
2
  import { config } from './config.js';
3
+ import { getGlobal } from './prebidGlobal.js';
3
4
  import clone from 'just-clone';
4
5
  import find from 'core-js-pure/features/array/find.js';
5
6
  import includes from 'core-js-pure/features/array/includes.js';
@@ -481,16 +482,43 @@ export function insertElement(elm, doc, target, asLastChildChild) {
481
482
  } catch (e) {}
482
483
  }
483
484
 
485
+ /**
486
+ * Returns a promise that completes when the given element triggers a 'load' or 'error' DOM event, or when
487
+ * `timeout` milliseconds have elapsed.
488
+ *
489
+ * @param {HTMLElement} element
490
+ * @param {Number} [timeout]
491
+ * @returns {Promise}
492
+ */
493
+ export function waitForElementToLoad(element, timeout) {
494
+ let timer = null;
495
+ return new Promise((resolve) => {
496
+ const onLoad = function() {
497
+ element.removeEventListener('load', onLoad);
498
+ element.removeEventListener('error', onLoad);
499
+ if (timer != null) {
500
+ window.clearTimeout(timer);
501
+ }
502
+ resolve();
503
+ };
504
+ element.addEventListener('load', onLoad);
505
+ element.addEventListener('error', onLoad);
506
+ if (timeout != null) {
507
+ timer = window.setTimeout(onLoad, timeout);
508
+ }
509
+ });
510
+ }
511
+
484
512
  /**
485
513
  * Inserts an image pixel with the specified `url` for cookie sync
486
514
  * @param {string} url URL string of the image pixel to load
487
515
  * @param {function} [done] an optional exit callback, used when this usersync pixel is added during an async process
516
+ * @param {Number} [timeout] an optional timeout in milliseconds for the image to load before calling `done`
488
517
  */
489
- export function triggerPixel(url, done) {
518
+ export function triggerPixel(url, done, timeout) {
490
519
  const img = new Image();
491
520
  if (done && internal.isFn(done)) {
492
- img.addEventListener('load', done);
493
- img.addEventListener('error', done);
521
+ waitForElementToLoad(img, timeout).then(done);
494
522
  }
495
523
  img.src = url;
496
524
  }
@@ -538,18 +566,18 @@ export function insertHtmlIntoIframe(htmlCode) {
538
566
  * @param {string} url URL to be requested
539
567
  * @param {string} encodeUri boolean if URL should be encoded before inserted. Defaults to true
540
568
  * @param {function} [done] an optional exit callback, used when this usersync pixel is added during an async process
569
+ * @param {Number} [timeout] an optional timeout in milliseconds for the iframe to load before calling `done`
541
570
  */
542
- export function insertUserSyncIframe(url, done) {
571
+ export function insertUserSyncIframe(url, done, timeout) {
543
572
  let iframeHtml = internal.createTrackPixelIframeHtml(url, false, 'allow-scripts allow-same-origin');
544
573
  let div = document.createElement('div');
545
574
  div.innerHTML = iframeHtml;
546
575
  let iframe = div.firstChild;
547
576
  if (done && internal.isFn(done)) {
548
- iframe.addEventListener('load', done);
549
- iframe.addEventListener('error', done);
577
+ waitForElementToLoad(iframe, timeout).then(done);
550
578
  }
551
579
  internal.insertElement(iframe, document, 'html', true);
552
- };
580
+ }
553
581
 
554
582
  /**
555
583
  * Creates a snippet of HTML that retrieves the specified `url`
@@ -1244,7 +1272,18 @@ export function mergeDeep(target, ...sources) {
1244
1272
  if (!target[key]) {
1245
1273
  Object.assign(target, { [key]: source[key] });
1246
1274
  } else if (isArray(target[key])) {
1247
- target[key] = target[key].concat(source[key]);
1275
+ source[key].forEach(obj => {
1276
+ let addItFlag = 1;
1277
+ for (let i = 0; i < target[key].length; i++) {
1278
+ if (deepEqual(target[key][i], obj)) {
1279
+ addItFlag = 0;
1280
+ break;
1281
+ }
1282
+ }
1283
+ if (addItFlag) {
1284
+ target[key].push(obj);
1285
+ }
1286
+ });
1248
1287
  }
1249
1288
  } else {
1250
1289
  Object.assign(target, { [key]: source[key] });
@@ -1294,3 +1333,9 @@ export function cyrb53Hash(str, seed = 0) {
1294
1333
  h2 = imul(h2 ^ (h2 >>> 16), 2246822507) ^ imul(h1 ^ (h1 >>> 13), 3266489909);
1295
1334
  return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString();
1296
1335
  }
1336
+
1337
+ export function isAllowZeroCpmBidsEnabled(bidderCode) {
1338
+ const bidderSettings = getGlobal().bidderSettings;
1339
+ return ((bidderSettings[bidderCode] && bidderSettings[bidderCode].allowZeroCpmBids === true) ||
1340
+ (bidderSettings.standard && bidderSettings.standard.allowZeroCpmBids === true));
1341
+ }
@@ -1,3 +1,4 @@
1
1
  window.$$PREBID_GLOBAL$$ = (window.$$PREBID_GLOBAL$$ || {});
2
+ window.$$PREBID_GLOBAL$$.installedModules = (window.$$PREBID_GLOBAL$$.installedModules || []);
2
3
  window.$$PREBID_GLOBAL$$.cmd = window.$$PREBID_GLOBAL$$.cmd || [];
3
4
  window.$$PREBID_GLOBAL$$.que = window.$$PREBID_GLOBAL$$.que || [];
@@ -7,8 +7,10 @@ const utils = require('src/utils');
7
7
  let getConfig;
8
8
  let setConfig;
9
9
  let readConfig;
10
+ let mergeConfig;
10
11
  let getBidderConfig;
11
12
  let setBidderConfig;
13
+ let mergeBidderConfig;
12
14
  let setDefaults;
13
15
 
14
16
  describe('config API', function () {
@@ -19,8 +21,10 @@ describe('config API', function () {
19
21
  getConfig = config.getConfig;
20
22
  setConfig = config.setConfig;
21
23
  readConfig = config.readConfig;
24
+ mergeConfig = config.mergeConfig;
22
25
  getBidderConfig = config.getBidderConfig;
23
26
  setBidderConfig = config.setBidderConfig;
27
+ mergeBidderConfig = config.mergeBidderConfig;
24
28
  setDefaults = config.setDefaults;
25
29
  logErrorSpy = sinon.spy(utils, 'logError');
26
30
  logWarnSpy = sinon.spy(utils, 'logWarn');
@@ -345,4 +349,279 @@ describe('config API', function () {
345
349
  const warning = 'Auction Options given an incorrect param: testing';
346
350
  assert.ok(logWarnSpy.calledWith(warning), 'expected warning was logged');
347
351
  });
352
+
353
+ it('should merge input with existing global config', function () {
354
+ const obj = {
355
+ ortb2: {
356
+ site: {
357
+ name: 'example',
358
+ domain: 'page.example.com',
359
+ cat: ['IAB2'],
360
+ sectioncat: ['IAB2-2'],
361
+ pagecat: ['IAB2-2']
362
+ }
363
+ }
364
+ };
365
+ setConfig({ ortb2: {
366
+ user: {
367
+ ext: {
368
+ data: {
369
+ registered: true,
370
+ interests: ['cars']
371
+ }
372
+ }
373
+ }
374
+ }
375
+ });
376
+ mergeConfig(obj);
377
+ const expected = {
378
+ site: {
379
+ name: 'example',
380
+ domain: 'page.example.com',
381
+ cat: ['IAB2'],
382
+ sectioncat: ['IAB2-2'],
383
+ pagecat: ['IAB2-2']
384
+ },
385
+ user: {
386
+ ext: {
387
+ data: {
388
+ registered: true,
389
+ interests: ['cars']
390
+ }
391
+ }
392
+ }
393
+ }
394
+ expect(getConfig('ortb2')).to.deep.equal(expected);
395
+ });
396
+
397
+ it('input should take precedence over existing config if keys are the same', function() {
398
+ const input = {
399
+ ortb2: {
400
+ user: {
401
+ ext: {
402
+ data: {
403
+ registered: true,
404
+ interests: ['cars']
405
+ }
406
+ }
407
+ }
408
+ }
409
+ }
410
+ setConfig({ ortb2: {
411
+ user: {
412
+ ext: {
413
+ data: {
414
+ registered: false
415
+ }
416
+ }
417
+ }
418
+ }});
419
+ mergeConfig(input);
420
+ const expected = {
421
+ user: {
422
+ ext: {
423
+ data: {
424
+ registered: true,
425
+ interests: ['cars']
426
+ }
427
+ }
428
+ }
429
+ }
430
+ expect(getConfig('ortb2')).to.deep.equal(expected);
431
+ });
432
+
433
+ it('should log error for a non-object value passed in', function () {
434
+ mergeConfig('invalid object');
435
+ expect(logErrorSpy.calledOnce).to.equal(true);
436
+ const error = 'mergeConfig input must be an object';
437
+ assert.ok(logErrorSpy.calledWith(error), 'expected error was logged');
438
+ });
439
+
440
+ it('should merge input with existing bidder config', function () {
441
+ const input = {
442
+ bidders: ['rubicon', 'appnexus'],
443
+ config: {
444
+ ortb2: {
445
+ site: {
446
+ name: 'example',
447
+ domain: 'page.example.com',
448
+ cat: ['IAB2'],
449
+ sectioncat: ['IAB2-2'],
450
+ pagecat: ['IAB2-2']
451
+ },
452
+ user: {
453
+ ext: {
454
+ ssp: 'magnite',
455
+ data: {
456
+ registered: false,
457
+ interests: ['sports']
458
+ }
459
+ }
460
+ }
461
+ }
462
+ }
463
+ };
464
+ setBidderConfig({
465
+ bidders: ['rubicon'],
466
+ config: {
467
+ ortb2: {
468
+ user: {
469
+ ext: {
470
+ data: {
471
+ registered: true,
472
+ interests: ['cars']
473
+ }
474
+ }
475
+ }
476
+ }
477
+ }
478
+ });
479
+ mergeBidderConfig(input);
480
+ const expected = {
481
+ rubicon: {
482
+ ortb2: {
483
+ site: {
484
+ name: 'example',
485
+ domain: 'page.example.com',
486
+ cat: ['IAB2'],
487
+ sectioncat: ['IAB2-2'],
488
+ pagecat: ['IAB2-2']
489
+ },
490
+ user: {
491
+ ext: {
492
+ ssp: 'magnite',
493
+ data: {
494
+ registered: false,
495
+ interests: ['cars', 'sports']
496
+ }
497
+ }
498
+ }
499
+ }
500
+ },
501
+ appnexus: {
502
+ ortb2: {
503
+ site: {
504
+ name: 'example',
505
+ domain: 'page.example.com',
506
+ cat: ['IAB2'],
507
+ sectioncat: ['IAB2-2'],
508
+ pagecat: ['IAB2-2']
509
+ },
510
+ user: {
511
+ ext: {
512
+ ssp: 'magnite',
513
+ data: {
514
+ registered: false,
515
+ interests: ['sports']
516
+ }
517
+ }
518
+ }
519
+ }
520
+ }
521
+ }
522
+ expect(getBidderConfig()).to.deep.equal(expected);
523
+ });
524
+
525
+ it('should log error for a non-object value passed in', function () {
526
+ mergeBidderConfig('invalid object');
527
+ expect(logErrorSpy.calledOnce).to.equal(true);
528
+ const error = 'setBidderConfig bidder options must be an object';
529
+ assert.ok(logErrorSpy.calledWith(error), 'expected error was logged');
530
+ });
531
+
532
+ it('should log error for empty bidders array', function () {
533
+ mergeBidderConfig({
534
+ bidders: [],
535
+ config: {
536
+ ortb2: {
537
+ site: {
538
+ name: 'example',
539
+ domain: 'page.example.com',
540
+ cat: ['IAB2'],
541
+ sectioncat: ['IAB2-2'],
542
+ pagecat: ['IAB2-2']
543
+ }
544
+ }
545
+ }
546
+ });
547
+ expect(logErrorSpy.calledOnce).to.equal(true);
548
+ const error = 'setBidderConfig bidder options must contain a bidders list with at least 1 bidder';
549
+ assert.ok(logErrorSpy.calledWith(error), 'expected error was logged');
550
+ });
551
+
552
+ it('should log error for nonexistent config object', function () {
553
+ mergeBidderConfig({
554
+ bidders: ['appnexus']
555
+ });
556
+ expect(logErrorSpy.calledOnce).to.equal(true);
557
+ const error = 'setBidderConfig bidder options must contain a config object';
558
+ assert.ok(logErrorSpy.calledWith(error), 'expected error was logged');
559
+ });
560
+
561
+ it('should merge without array duplication', function() {
562
+ const userObj1 = {
563
+ name: 'www.dataprovider1.com',
564
+ ext: { taxonomyname: 'iab_audience_taxonomy' },
565
+ segment: [{
566
+ id: '1776'
567
+ }]
568
+ };
569
+
570
+ const userObj2 = {
571
+ name: 'www.dataprovider2.com',
572
+ ext: { taxonomyname: 'iab_audience_taxonomy' },
573
+ segment: [{
574
+ id: '1914'
575
+ }]
576
+ };
577
+
578
+ const siteObj1 = {
579
+ name: 'www.dataprovider3.com',
580
+ ext: {
581
+ taxonomyname: 'iab_audience_taxonomy'
582
+ },
583
+ segment: [
584
+ {
585
+ id: '1812'
586
+ },
587
+ {
588
+ id: '1955'
589
+ }
590
+ ]
591
+ }
592
+
593
+ setConfig({
594
+ ortb2: {
595
+ user: {
596
+ data: [userObj1, userObj2]
597
+ },
598
+ site: {
599
+ content: {
600
+ data: [siteObj1]
601
+ }
602
+ }
603
+ }
604
+ });
605
+
606
+ const rtd = {
607
+ ortb2: {
608
+ user: {
609
+ data: [userObj1]
610
+ },
611
+ site: {
612
+ content: {
613
+ data: [siteObj1]
614
+ }
615
+ }
616
+ }
617
+ };
618
+ mergeConfig(rtd);
619
+
620
+ let ortb2Config = getConfig('ortb2');
621
+
622
+ expect(ortb2Config.user.data).to.deep.include.members([userObj1, userObj2]);
623
+ expect(ortb2Config.site.content.data).to.deep.include.members([siteObj1]);
624
+ expect(ortb2Config.user.data).to.have.lengthOf(2);
625
+ expect(ortb2Config.site.content.data).to.have.lengthOf(1);
626
+ });
348
627
  });
@@ -51,9 +51,15 @@ export function enable() {
51
51
  window.googletag = {
52
52
  _slots: [],
53
53
  _callbackMap: {},
54
+ _ppid: undefined,
55
+ cmd: [],
54
56
  pubads: function () {
55
57
  var self = this;
56
58
  return {
59
+ setPublisherProvidedId: function (ppid) {
60
+ self._ppid = ppid;
61
+ },
62
+
57
63
  getSlots: function () {
58
64
  return self._slots;
59
65
  },