prebid.js 7.4.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.
Files changed (239) hide show
  1. package/.circleci/config.yml +11 -6
  2. package/dist/1plusXRtdProvider.js +1 -0
  3. package/dist/33acrossBidAdapter.js +1 -1
  4. package/dist/adagioBidAdapter.js +1 -1
  5. package/dist/adbookpspBidAdapter.js +1 -1
  6. package/dist/adgenerationBidAdapter.js +1 -1
  7. package/dist/adnuntiusBidAdapter.js +1 -1
  8. package/dist/adoceanBidAdapter.js +1 -1
  9. package/dist/adotBidAdapter.js +1 -1
  10. package/dist/adrelevantisBidAdapter.js +1 -1
  11. package/dist/adrinoBidAdapter.js +1 -1
  12. package/dist/adtelligentBidAdapter.js +1 -1
  13. package/dist/adxcgBidAdapter.js +1 -1
  14. package/dist/ajaBidAdapter.js +1 -1
  15. package/dist/amxBidAdapter.js +1 -1
  16. package/dist/amxIdSystem.js +1 -1
  17. package/dist/appierAnalyticsAdapter.js +1 -1
  18. package/dist/appnexusBidAdapter.js +1 -1
  19. package/dist/asoBidAdapter.js +1 -1
  20. package/dist/atsAnalyticsAdapter.js +1 -1
  21. package/dist/axonixBidAdapter.js +1 -1
  22. package/dist/bidglassBidAdapter.js +1 -1
  23. package/dist/big-richmediaBidAdapter.js +1 -1
  24. package/dist/bliinkBidAdapter.js +1 -1
  25. package/dist/bridgewellBidAdapter.js +1 -1
  26. package/dist/brightMountainMediaBidAdapter.js +1 -1
  27. package/dist/byDataAnalyticsAdapter.js +1 -1
  28. package/dist/concertBidAdapter.js +1 -1
  29. package/dist/connectadBidAdapter.js +1 -1
  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/currency.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/gdprEnforcement.js +1 -1
  39. package/dist/glimpseBidAdapter.js +1 -1
  40. package/dist/gmosspBidAdapter.js +1 -1
  41. package/dist/goldbachBidAdapter.js +1 -1
  42. package/dist/gridBidAdapter.js +1 -1
  43. package/dist/gridNMBidAdapter.js +1 -1
  44. package/dist/gumgumBidAdapter.js +1 -1
  45. package/dist/h12mediaBidAdapter.js +1 -1
  46. package/dist/hadronIdSystem.js +1 -1
  47. package/dist/hadronRtdProvider.js +1 -1
  48. package/dist/id5IdSystem.js +1 -1
  49. package/dist/imRtdProvider.js +1 -1
  50. package/dist/impactifyBidAdapter.js +1 -1
  51. package/dist/improvedigitalBidAdapter.js +1 -1
  52. package/dist/inmarBidAdapter.js +1 -1
  53. package/dist/insticatorBidAdapter.js +1 -1
  54. package/dist/ixBidAdapter.js +1 -1
  55. package/dist/jixieBidAdapter.js +1 -1
  56. package/dist/justpremiumBidAdapter.js +1 -1
  57. package/dist/kargoAnalyticsAdapter.js +1 -1
  58. package/dist/konduitAnalyticsAdapter.js +1 -1
  59. package/dist/kueezBidAdapter.js +1 -1
  60. package/dist/lassoBidAdapter.js +1 -1
  61. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  62. package/dist/logicadBidAdapter.js +1 -1
  63. package/dist/loglyliftBidAdapter.js +1 -1
  64. package/dist/malltvAnalyticsAdapter.js +1 -1
  65. package/dist/marsmediaBidAdapter.js +1 -1
  66. package/dist/mediafuseBidAdapter.js +1 -1
  67. package/dist/mediasquareBidAdapter.js +1 -1
  68. package/dist/mgidBidAdapter.js +1 -1
  69. package/dist/minutemediaBidAdapter.js +1 -1
  70. package/dist/naveggIdSystem.js +1 -1
  71. package/dist/newspassidBidAdapter.js +1 -0
  72. package/dist/nextMillenniumBidAdapter.js +1 -1
  73. package/dist/not-for-prod/prebid.js +131 -128
  74. package/dist/oguryBidAdapter.js +1 -1
  75. package/dist/onetagBidAdapter.js +1 -1
  76. package/dist/ooloAnalyticsAdapter.js +1 -1
  77. package/dist/outbrainBidAdapter.js +1 -1
  78. package/dist/parrableIdSystem.js +1 -1
  79. package/dist/pixfutureBidAdapter.js +1 -1
  80. package/dist/prebid-core.js +1 -1
  81. package/dist/prebidServerBidAdapter.js +1 -1
  82. package/dist/priceFloors.js +1 -1
  83. package/dist/pubCommonId.js +1 -1
  84. package/dist/publinkIdSystem.js +1 -1
  85. package/dist/pubmaticBidAdapter.js +1 -1
  86. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  87. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  88. package/dist/pxyzBidAdapter.js +1 -1
  89. package/dist/quantcastBidAdapter.js +1 -1
  90. package/dist/rasBidAdapter.js +1 -0
  91. package/dist/readpeakBidAdapter.js +1 -1
  92. package/dist/relaidoBidAdapter.js +1 -1
  93. package/dist/rhythmoneBidAdapter.js +1 -1
  94. package/dist/riseBidAdapter.js +1 -1
  95. package/dist/rubiconAnalyticsAdapter.js +1 -1
  96. package/dist/rubiconBidAdapter.js +1 -1
  97. package/dist/seedingAllianceBidAdapter.js +1 -1
  98. package/dist/seedtagBidAdapter.js +1 -1
  99. package/dist/sharedIdSystem.js +1 -1
  100. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  101. package/dist/sharethroughBidAdapter.js +1 -1
  102. package/dist/shinezBidAdapter.js +1 -1
  103. package/dist/smaatoBidAdapter.js +1 -1
  104. package/dist/smartadserverBidAdapter.js +1 -1
  105. package/dist/smartxBidAdapter.js +1 -1
  106. package/dist/smilewantedBidAdapter.js +1 -1
  107. package/dist/sonobiBidAdapter.js +1 -1
  108. package/dist/sovrnAnalyticsAdapter.js +1 -1
  109. package/dist/sovrnBidAdapter.js +1 -1
  110. package/dist/sspBCBidAdapter.js +1 -1
  111. package/dist/sublimeBidAdapter.js +1 -1
  112. package/dist/synacormediaBidAdapter.js +1 -1
  113. package/dist/taboolaBidAdapter.js +1 -1
  114. package/dist/targetVideoBidAdapter.js +1 -1
  115. package/dist/teadsBidAdapter.js +1 -1
  116. package/dist/trionBidAdapter.js +1 -1
  117. package/dist/tripleliftBidAdapter.js +1 -1
  118. package/dist/ttdBidAdapter.js +1 -1
  119. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  120. package/dist/underdogmediaBidAdapter.js +1 -1
  121. package/dist/undertoneBidAdapter.js +1 -1
  122. package/dist/userId.js +1 -1
  123. package/dist/vidazooBidAdapter.js +1 -1
  124. package/dist/videobyteBidAdapter.js +1 -1
  125. package/dist/visxBidAdapter.js +1 -1
  126. package/dist/vuukleBidAdapter.js +1 -1
  127. package/dist/widespaceBidAdapter.js +1 -1
  128. package/dist/winrBidAdapter.js +1 -1
  129. package/dist/yahoosspBidAdapter.js +1 -1
  130. package/dist/yieldmoBidAdapter.js +1 -1
  131. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  132. package/integrationExamples/gpt/1plusXRtdProviderExample.html +112 -0
  133. package/karma.conf.maker.js +3 -1
  134. package/modules/.submodules.json +2 -1
  135. package/modules/1plusXRtdProvider.js +251 -0
  136. package/modules/1plusXRtdProvider.md +65 -0
  137. package/modules/adgenerationBidAdapter.js +24 -1
  138. package/modules/adnuntiusBidAdapter.js +26 -8
  139. package/modules/adoceanBidAdapter.js +10 -3
  140. package/modules/adotBidAdapter.js +13 -4
  141. package/modules/adrinoBidAdapter.js +10 -2
  142. package/modules/adrinoBidAdapter.md +6 -0
  143. package/modules/adtelligentBidAdapter.js +2 -1
  144. package/modules/appnexusBidAdapter.js +3 -3
  145. package/modules/atsAnalyticsAdapter.js +4 -5
  146. package/modules/big-richmediaBidAdapter.js +3 -3
  147. package/modules/bliinkBidAdapter.js +120 -193
  148. package/modules/bliinkBidAdapter.md +2 -5
  149. package/modules/byDataAnalyticsAdapter.js +172 -74
  150. package/modules/byDataAnalyticsAdapter.md +5 -6
  151. package/modules/consumableBidAdapter.js +21 -1
  152. package/modules/criteoBidAdapter.js +7 -1
  153. package/modules/currency.js +2 -2
  154. package/modules/cwireBidAdapter.md +1 -1
  155. package/modules/eplanningBidAdapter.js +82 -97
  156. package/modules/gdprEnforcement.js +8 -14
  157. package/modules/gridNMBidAdapter.js +45 -4
  158. package/modules/hadronAnalyticsAdapter.md +5 -5
  159. package/modules/hadronIdSystem.js +18 -5
  160. package/modules/hadronIdSystem.md +15 -11
  161. package/modules/hadronRtdProvider.js +14 -1
  162. package/modules/hadronRtdProvider.md +17 -13
  163. package/modules/imRtdProvider.js +0 -8
  164. package/modules/impactifyBidAdapter.js +6 -2
  165. package/modules/ixBidAdapter.js +133 -23
  166. package/modules/ixBidAdapter.md +2 -5
  167. package/modules/jixieBidAdapter.js +10 -10
  168. package/modules/kargoAnalyticsAdapter.js +88 -6
  169. package/modules/kargoAnalyticsAdapter.md +33 -0
  170. package/modules/minutemediaBidAdapter.js +1 -0
  171. package/modules/naveggIdSystem.js +1 -12
  172. package/modules/newspassidBidAdapter.js +649 -0
  173. package/modules/nextMillenniumBidAdapter.js +17 -1
  174. package/modules/nextMillenniumBidAdapter.md +1 -1
  175. package/modules/oguryBidAdapter.js +2 -0
  176. package/modules/onetagBidAdapter.js +44 -7
  177. package/modules/prebidServerBidAdapter/index.js +7 -0
  178. package/modules/priceFloors.js +1 -1
  179. package/modules/pubCommonId.js +1 -2
  180. package/modules/pubxaiAnalyticsAdapter.js +6 -1
  181. package/modules/rasBidAdapter.js +149 -0
  182. package/modules/rasBidAdapter.md +50 -0
  183. package/modules/rubiconBidAdapter.js +5 -0
  184. package/modules/seedingAllianceBidAdapter.js +3 -0
  185. package/modules/seedtagBidAdapter.js +37 -1
  186. package/modules/sharedIdSystem.js +11 -5
  187. package/modules/sharethroughBidAdapter.js +9 -24
  188. package/modules/taboolaBidAdapter.js +1 -1
  189. package/modules/taboolaBidAdapter.md +3 -3
  190. package/modules/targetVideoBidAdapter.js +18 -0
  191. package/modules/userId/index.js +39 -21
  192. package/package.json +1 -1
  193. package/src/auction.js +6 -5
  194. package/src/consentHandler.js +11 -11
  195. package/src/debugging.js +5 -3
  196. package/src/hook.js +2 -2
  197. package/src/storageManager.js +4 -5
  198. package/src/utils/promise.js +96 -21
  199. package/src/utils.js +3 -2
  200. package/test/helpers/consentData.js +2 -1
  201. package/test/spec/auctionmanager_spec.js +1 -6
  202. package/test/spec/debugging_spec.js +2 -2
  203. package/test/spec/modules/1plusXRtdProvider_spec.js +430 -0
  204. package/test/spec/modules/adgenerationBidAdapter_spec.js +52 -4
  205. package/test/spec/modules/adnuntiusBidAdapter_spec.js +126 -14
  206. package/test/spec/modules/adoceanBidAdapter_spec.js +4 -1
  207. package/test/spec/modules/adotBidAdapter_spec.js +12 -9
  208. package/test/spec/modules/adrinoBidAdapter_spec.js +22 -0
  209. package/test/spec/modules/appnexusBidAdapter_spec.js +165 -156
  210. package/test/spec/modules/bliinkBidAdapter_spec.js +323 -136
  211. package/test/spec/modules/byDataAnalyticsAdapter_spec.js +74 -24
  212. package/test/spec/modules/consumableBidAdapter_spec.js +122 -1
  213. package/test/spec/modules/criteoBidAdapter_spec.js +15 -5
  214. package/test/spec/modules/eplanningBidAdapter_spec.js +58 -18
  215. package/test/spec/modules/gdprEnforcement_spec.js +53 -100
  216. package/test/spec/modules/gridNMBidAdapter_spec.js +32 -0
  217. package/test/spec/modules/hadronIdSystem_spec.js +2 -2
  218. package/test/spec/modules/idxIdSystem_spec.js +1 -1
  219. package/test/spec/modules/imRtdProvider_spec.js +0 -1
  220. package/test/spec/modules/ixBidAdapter_spec.js +212 -5
  221. package/test/spec/modules/jixieBidAdapter_spec.js +8 -8
  222. package/test/spec/modules/kargoAnalyticsAdapter_spec.js +42 -0
  223. package/test/spec/modules/minutemediaBidAdapter_spec.js +3 -0
  224. package/test/spec/modules/newspassidBidAdapter_spec.js +1793 -0
  225. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +20 -0
  226. package/test/spec/modules/onetagBidAdapter_spec.js +53 -4
  227. package/test/spec/modules/parrableIdSystem_spec.js +2 -1
  228. package/test/spec/modules/prebidServerBidAdapter_spec.js +20 -0
  229. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +5 -0
  230. package/test/spec/modules/rasBidAdapter_spec.js +190 -0
  231. package/test/spec/modules/rubiconBidAdapter_spec.js +27 -0
  232. package/test/spec/modules/seedtagBidAdapter_spec.js +29 -0
  233. package/test/spec/modules/sharethroughBidAdapter_spec.js +4 -4
  234. package/test/spec/modules/taboolaBidAdapter_spec.js +1 -1
  235. package/test/spec/modules/targetVideoBidAdapter_spec.js +43 -0
  236. package/test/spec/modules/userId_spec.js +15 -2
  237. package/test/spec/unit/pbjs_api_spec.js +1 -5
  238. package/test/spec/unit/utils/promise_spec.js +283 -38
  239. package/test/helpers/syncPromise.js +0 -71
@@ -14,6 +14,16 @@ describe('nextMillenniumBidAdapterTests', function() {
14
14
  gdprConsent: {
15
15
  consentString: 'kjfdniwjnifwenrif3',
16
16
  gdprApplies: true
17
+ },
18
+ ortb2: {
19
+ device: {
20
+ w: 1500,
21
+ h: 1000
22
+ },
23
+ site: {
24
+ domain: 'example.com',
25
+ page: 'http://example.com'
26
+ }
17
27
  }
18
28
  }
19
29
  ];
@@ -94,6 +104,16 @@ describe('nextMillenniumBidAdapterTests', function() {
94
104
  expect(JSON.parse(request[0].data).ext.nextMillennium.refresh_count).to.equal(3);
95
105
  });
96
106
 
107
+ it('Check if ORTB was added', function() {
108
+ const request = spec.buildRequests(bidRequestData)
109
+ expect(JSON.parse(request[0].data).site.domain).to.equal('example.com')
110
+ })
111
+
112
+ it('Check if elOffsets was added', function() {
113
+ const request = spec.buildRequests(bidRequestData)
114
+ expect(JSON.parse(request[0].data).ext.nextMillennium.elOffsets).to.be.an('object')
115
+ })
116
+
97
117
  it('Test getUserSyncs function', function () {
98
118
  const syncOptions = {
99
119
  'iframeEnabled': true
@@ -1,4 +1,4 @@
1
- import { spec, isValid, hasTypeVideo } from 'modules/onetagBidAdapter.js';
1
+ import { spec, isValid, hasTypeVideo, isSchainValid } from 'modules/onetagBidAdapter.js';
2
2
  import { expect } from 'chai';
3
3
  import {find} from 'src/polyfill.js';
4
4
  import { BANNER, VIDEO } from 'src/mediaTypes.js';
@@ -15,7 +15,21 @@ describe('onetag', function () {
15
15
  'bidId': '30b31c1838de1e',
16
16
  'bidderRequestId': '22edbae2733bf6',
17
17
  'auctionId': '1d1a030790a475',
18
- 'transactionId': 'qwerty123'
18
+ 'transactionId': 'qwerty123',
19
+ 'schain': {
20
+ 'validation': 'off',
21
+ 'config': {
22
+ 'ver': '1.0',
23
+ 'complete': 1,
24
+ 'nodes': [
25
+ {
26
+ 'asi': 'indirectseller.com',
27
+ 'sid': '00001',
28
+ 'hp': 1
29
+ }
30
+ ]
31
+ }
32
+ },
19
33
  };
20
34
  }
21
35
 
@@ -193,7 +207,8 @@ describe('onetag', function () {
193
207
  'context',
194
208
  'playerSize',
195
209
  'mediaTypeInfo',
196
- 'type'
210
+ 'type',
211
+ 'priceFloors'
197
212
  );
198
213
  } else if (isValid(BANNER, bid)) {
199
214
  expect(bid).to.have.all.keys(
@@ -205,9 +220,13 @@ describe('onetag', function () {
205
220
  'transactionId',
206
221
  'mediaTypeInfo',
207
222
  'sizes',
208
- 'type'
223
+ 'type',
224
+ 'priceFloors'
209
225
  );
210
226
  }
227
+ if (bid.schain && isSchainValid(bid.schain)) {
228
+ expect(data).to.have.all.keys('schain');
229
+ }
211
230
  expect(bid.bidId).to.be.a('string');
212
231
  expect(bid.pubId).to.be.a('string');
213
232
  }
@@ -358,6 +377,36 @@ describe('onetag', function () {
358
377
  expect(syncs[0].url).to.match(/(?:[?&](?:us_privacy=us_foo(?:[&][^&]*)*))+$/);
359
378
  });
360
379
  });
380
+ describe('isSchainValid', function () {
381
+ it('Should return false when schain is null or undefined', function () {
382
+ expect(isSchainValid(null)).to.be.false;
383
+ expect(isSchainValid(undefined)).to.be.false;
384
+ });
385
+ it('Should return false when schain is missing nodes key', function () {
386
+ const schain = {'otherKey': 'otherValue'};
387
+ expect(isSchainValid(schain)).to.be.false;
388
+ });
389
+ it('Should return false when schain is missing one of the required SupplyChainNode attribute', function () {
390
+ const missingAsiNode = {'sid': '00001', 'hp': 1};
391
+ const missingSidNode = {'asi': 'indirectseller.com', 'hp': 1};
392
+ const missingHpNode = {'asi': 'indirectseller.com', 'sid': '00001'};
393
+ expect(isSchainValid({'config': {'nodes': [missingAsiNode]}})).to.be.false;
394
+ expect(isSchainValid({'config': {'nodes': [missingSidNode]}})).to.be.false;
395
+ expect(isSchainValid({'config': {'nodes': [missingHpNode]}})).to.be.false;
396
+ });
397
+ it('Should return true when schain contains all required attributes', function () {
398
+ const validSchain = {
399
+ 'nodes': [
400
+ {
401
+ 'asi': 'indirectseller.com',
402
+ 'sid': '00001',
403
+ 'hp': 1
404
+ }
405
+ ]
406
+ };
407
+ expect(isSchainValid(validSchain)).to.be.true;
408
+ })
409
+ });
361
410
  });
362
411
 
363
412
  function getBannerVideoResponse() {
@@ -655,7 +655,6 @@ describe('Parrable ID System', function() {
655
655
  writeParrableCookie({ eid: P_COOKIE_EID, ibaOptout: true });
656
656
  init(config);
657
657
  setSubmoduleRegistry([parrableIdSubmodule]);
658
- config.setConfig(getConfigMock());
659
658
  });
660
659
 
661
660
  afterEach(function() {
@@ -665,6 +664,7 @@ describe('Parrable ID System', function() {
665
664
  });
666
665
 
667
666
  it('when a stored Parrable ID exists it is added to bids', function(done) {
667
+ config.setConfig(getConfigMock());
668
668
  requestBidsHook(function() {
669
669
  adUnits.forEach(unit => {
670
670
  unit.bids.forEach(bid => {
@@ -691,6 +691,7 @@ describe('Parrable ID System', function() {
691
691
  it('supplies an optout reason when the EID is missing due to CCPA non-consent', function(done) {
692
692
  // the ID system itself will not write a cookie with an EID when CCPA=true
693
693
  writeParrableCookie({ ccpaOptout: true });
694
+ config.setConfig(getConfigMock());
694
695
 
695
696
  requestBidsHook(function() {
696
697
  adUnits.forEach(unit => {
@@ -2692,6 +2692,26 @@ describe('S2S Adapter', function () {
2692
2692
  sinon.assert.match(actual.imp[0], sinon.match(ortb2Imp));
2693
2693
  });
2694
2694
 
2695
+ it('setting adapterCode for default bidder', function () {
2696
+ config.setConfig({ CONFIG });
2697
+ adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
2698
+ server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB));
2699
+
2700
+ const response = addBidResponse.firstCall.args[1];
2701
+ expect(response).to.have.property('adapterCode', 'appnexus');
2702
+ });
2703
+
2704
+ it('setting adapterCode for alternate bidder', function () {
2705
+ config.setConfig({ CONFIG });
2706
+ let RESPONSE_OPENRTB2 = deepClone(RESPONSE_OPENRTB);
2707
+ RESPONSE_OPENRTB2.seatbid[0].bid[0].ext.prebid.meta.adaptercode = 'appnexus2'
2708
+ adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
2709
+ server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB2));
2710
+
2711
+ const response = addBidResponse.firstCall.args[1];
2712
+ expect(response).to.have.property('adapterCode', 'appnexus2');
2713
+ });
2714
+
2695
2715
  describe('on sync requested with no cookie', () => {
2696
2716
  let cfg, req, csRes;
2697
2717
 
@@ -624,6 +624,11 @@ describe('pubxai analytics adapter', function() {
624
624
  }
625
625
  },
626
626
  'floorProvider': 'PubXFloorProvider',
627
+ 'floorFetchStatus': 'success',
628
+ 'floorLocation': 'fetch',
629
+ 'floorModelVersion': 'test model 1.0',
630
+ 'floorSkipRate': 0,
631
+ 'isFloorSkipped': false,
627
632
  'isWinningBid': true,
628
633
  'mediaType': 'banner',
629
634
  'netRevenue': true,
@@ -0,0 +1,190 @@
1
+ import { expect } from 'chai';
2
+ import { spec } from 'modules/rasBidAdapter.js';
3
+ import { newBidder } from 'src/adapters/bidderFactory.js';
4
+
5
+ const CSR_ENDPOINT = 'https://csr.onet.pl/4178463/csr-006/csr.json?';
6
+
7
+ describe('rasBidAdapter', function () {
8
+ const adapter = newBidder(spec);
9
+
10
+ describe('inherited functions', function () {
11
+ it('exists and is a function', function () {
12
+ expect(adapter.callBids).to.exist.and.to.be.a('function');
13
+ });
14
+ });
15
+
16
+ describe('isBidRequestValid', function () {
17
+ it('should return true when required params found', function () {
18
+ const bid = {
19
+ sizes: [[300, 250], [300, 600]],
20
+ bidder: 'ras',
21
+ params: {
22
+ slot: 'slot',
23
+ area: 'areatest',
24
+ site: 'test',
25
+ network: '4178463'
26
+ }
27
+ };
28
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
29
+ });
30
+
31
+ it('should return false when required params not found', function () {
32
+ const failBid = {
33
+ sizes: [[300, 250], [300, 300]],
34
+ bidder: 'ras',
35
+ params: {
36
+ site: 'test',
37
+ network: '4178463'
38
+ }
39
+ };
40
+ expect(spec.isBidRequestValid(failBid)).to.equal(false);
41
+ });
42
+
43
+ it('should return nothing when bid request is malformed', function () {
44
+ const failBid = {
45
+ sizes: [[300, 250], [300, 300]],
46
+ bidder: 'ras',
47
+ };
48
+ expect(spec.isBidRequestValid(failBid)).to.equal(undefined);
49
+ });
50
+ });
51
+
52
+ describe('buildRequests', function () {
53
+ const bid = {
54
+ sizes: [[300, 250], [300, 600]],
55
+ bidder: 'ras',
56
+ bidId: 1,
57
+ params: {
58
+ slot: 'test',
59
+ area: 'areatest',
60
+ site: 'test',
61
+ network: '4178463'
62
+ }
63
+ };
64
+ const bid2 = {
65
+ sizes: [[750, 300]],
66
+ bidder: 'ras',
67
+ bidId: 2,
68
+ params: {
69
+ slot: 'test2',
70
+ area: 'areatest',
71
+ site: 'test',
72
+ network: '4178463'
73
+ }
74
+ };
75
+
76
+ it('should parse bids to request', function () {
77
+ const requests = spec.buildRequests([bid], {
78
+ 'gdprConsent': {
79
+ 'gdprApplies': true,
80
+ 'consentString': 'some-consent-string'
81
+ },
82
+ 'refererInfo': {
83
+ 'ref': 'https://example.org/',
84
+ 'page': 'https://example.com/'
85
+ }
86
+ });
87
+ expect(requests[0].url).to.have.string(CSR_ENDPOINT);
88
+ expect(requests[0].url).to.have.string('slot0=test');
89
+ expect(requests[0].url).to.have.string('id0=1');
90
+ expect(requests[0].url).to.have.string('site=test');
91
+ expect(requests[0].url).to.have.string('area=areatest');
92
+ expect(requests[0].url).to.have.string('cre_format=html');
93
+ expect(requests[0].url).to.have.string('systems=das');
94
+ expect(requests[0].url).to.have.string('ems_url=1');
95
+ expect(requests[0].url).to.have.string('bid_rate=1');
96
+ expect(requests[0].url).to.have.string('gdpr_applies=true');
97
+ expect(requests[0].url).to.have.string('euconsent=some-consent-string');
98
+ expect(requests[0].url).to.have.string('du=https%3A%2F%2Fexample.com%2F');
99
+ expect(requests[0].url).to.have.string('dr=https%3A%2F%2Fexample.org%2F');
100
+ });
101
+
102
+ it('should return empty consent string when undefined', function () {
103
+ const requests = spec.buildRequests([bid]);
104
+ const gdpr = requests[0].url.search('gdpr_applies');
105
+ const euconsent = requests[0].url.search('euconsent=');
106
+ expect(gdpr).to.equal(-1);
107
+ expect(euconsent).to.equal(-1);
108
+ });
109
+
110
+ it('should parse bids to request from pageContext', function () {
111
+ const bidCopy = { ...bid };
112
+ bidCopy.params = {
113
+ ...bid.params,
114
+ pageContext: {
115
+ dv: 'test/areatest',
116
+ du: 'https://example.com/',
117
+ dr: 'https://example.org/',
118
+ keyWords: ['val1', 'val2'],
119
+ keyValues: {
120
+ adunit: 'test/areatest'
121
+ }
122
+ }
123
+ };
124
+ const requests = spec.buildRequests([bidCopy, bid2]);
125
+ expect(requests[0].url).to.have.string(CSR_ENDPOINT);
126
+ expect(requests[0].url).to.have.string('slot0=test');
127
+ expect(requests[0].url).to.have.string('id0=1');
128
+ expect(requests[0].url).to.have.string('iusizes0=300x250%2C300x600');
129
+ expect(requests[0].url).to.have.string('slot1=test2');
130
+ expect(requests[0].url).to.have.string('id1=2');
131
+ expect(requests[0].url).to.have.string('iusizes1=750x300');
132
+ expect(requests[0].url).to.have.string('site=test');
133
+ expect(requests[0].url).to.have.string('area=areatest');
134
+ expect(requests[0].url).to.have.string('cre_format=html');
135
+ expect(requests[0].url).to.have.string('systems=das');
136
+ expect(requests[0].url).to.have.string('ems_url=1');
137
+ expect(requests[0].url).to.have.string('bid_rate=1');
138
+ expect(requests[0].url).to.have.string('du=https%3A%2F%2Fexample.com%2F');
139
+ expect(requests[0].url).to.have.string('dr=https%3A%2F%2Fexample.org%2F');
140
+ expect(requests[0].url).to.have.string('DV=test%2Fareatest');
141
+ expect(requests[0].url).to.have.string('kwrd=val1%2Bval2');
142
+ expect(requests[0].url).to.have.string('kvadunit=test%2Fareatest');
143
+ });
144
+ });
145
+
146
+ describe('interpretResponse', function () {
147
+ const response = {
148
+ 'adsCheck': 'ok',
149
+ 'geoloc': {},
150
+ 'ir': '92effd60-0c84-4dac-817e-763ea7b8ac65',
151
+ 'ads': [
152
+ {
153
+ 'id': 'flat-belkagorna',
154
+ 'slot': 'flat-belkagorna',
155
+ 'prio': 10,
156
+ 'type': 'html',
157
+ 'bid_rate': 0.321123,
158
+ 'adid': 'das,50463,152276',
159
+ 'id_3': '12734',
160
+ 'html': '<script type=\"text/javascript\">test</script>'
161
+ }
162
+ ],
163
+ 'iv': '202003191334467636346500'
164
+ };
165
+
166
+ it('should get correct bid response', function () {
167
+ const resp = spec.interpretResponse({ body: response }, { bidIds: [{ slot: 'flat-belkagorna', bidId: 1 }] });
168
+ expect(resp[0]).to.have.all.keys('cpm', 'currency', 'netRevenue', 'requestId', 'ttl', 'width', 'height', 'creativeId', 'dealId', 'ad', 'meta');
169
+ expect(resp.length).to.equal(1);
170
+ });
171
+
172
+ it('should handle empty ad', function () {
173
+ let res = {
174
+ 'ads': [{
175
+ type: 'empty'
176
+ }]
177
+ };
178
+ const resp = spec.interpretResponse({ body: res }, {});
179
+ expect(resp).to.deep.equal([]);
180
+ });
181
+
182
+ it('should handle empty server response', function () {
183
+ let res = {
184
+ 'ads': []
185
+ };
186
+ const resp = spec.interpretResponse({ body: res }, {});
187
+ expect(resp).to.deep.equal([]);
188
+ });
189
+ });
190
+ });
@@ -2139,6 +2139,33 @@ describe('the rubicon adapter', function () {
2139
2139
  expect(request.data.imp[0].ext.data.pbadslot).to.equal('1234567890');
2140
2140
  });
2141
2141
 
2142
+ it('should NOT include storedrequests in pbs payload', function () {
2143
+ createVideoBidderRequest();
2144
+ bidderRequest.bids[0].ortb2 = {
2145
+ ext: {
2146
+ prebid: {
2147
+ storedrequest: 'no-send-top-level-sr'
2148
+ }
2149
+ }
2150
+ }
2151
+
2152
+ bidderRequest.bids[0].ortb2Imp = {
2153
+ ext: {
2154
+ prebid: {
2155
+ storedrequest: 'no-send-imp-sr'
2156
+ }
2157
+ }
2158
+ }
2159
+
2160
+ sandbox.stub(Date, 'now').callsFake(() =>
2161
+ bidderRequest.auctionStart + 100
2162
+ );
2163
+
2164
+ const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest);
2165
+ expect(request.data.ext.prebid.storedrequest).to.be.undefined;
2166
+ expect(request.data.imp[0].ext.prebid.storedrequest).to.be.undefined;
2167
+ });
2168
+
2142
2169
  it('should include GAM ad unit in bid request', function () {
2143
2170
  createVideoBidderRequest();
2144
2171
  bidderRequest.bids[0].ortb2Imp = {
@@ -223,6 +223,7 @@ describe('Seedtag Adapter', function () {
223
223
  });
224
224
 
225
225
  it('Common data request should be correct', function () {
226
+ const now = Date.now();
226
227
  const request = spec.buildRequests(validBidRequests, bidderRequest);
227
228
  const data = JSON.parse(request.data);
228
229
  expect(data.url).to.equal('referer');
@@ -231,6 +232,9 @@ describe('Seedtag Adapter', function () {
231
232
  expect(
232
233
  ['fixed', 'mobile', 'unknown'].indexOf(data.connectionType)
233
234
  ).to.be.above(-1);
235
+ expect(data.auctionStart).to.be.greaterThanOrEqual(now);
236
+ expect(data.ttfb).to.be.greaterThanOrEqual(0);
237
+
234
238
  expect(data.bidRequests[0].adUnitCode).to.equal('adunit-code');
235
239
  });
236
240
 
@@ -288,6 +292,31 @@ describe('Seedtag Adapter', function () {
288
292
  it('should expose gvlid', function () {
289
293
  expect(spec.gvlid).to.equal(157);
290
294
  });
295
+ it('should handle uspConsent', function () {
296
+ const uspConsent = '1---';
297
+
298
+ bidderRequest['uspConsent'] = uspConsent;
299
+
300
+ const request = spec.buildRequests(validBidRequests, bidderRequest);
301
+ const payload = JSON.parse(request.data);
302
+
303
+ expect(payload.uspConsent).to.exist;
304
+ expect(payload.uspConsent).to.equal(uspConsent);
305
+ });
306
+
307
+ it("shouldn't send uspConsent when not available", function () {
308
+ const uspConsent = undefined;
309
+
310
+ bidderRequest['uspConsent'] = uspConsent;
311
+
312
+ const request = spec.buildRequests(
313
+ validBidRequests,
314
+ bidderRequest
315
+ );
316
+ const payload = JSON.parse(request.data);
317
+
318
+ expect(payload.uspConsent).to.not.exist;
319
+ });
291
320
  });
292
321
  });
293
322
 
@@ -601,11 +601,11 @@ describe('sharethrough adapter spec', function () {
601
601
  const serverResponses = [{ body: { cookieSyncUrls: cookieSyncs } }];
602
602
 
603
603
  it('returns an array of correctly formatted user syncs', function () {
604
- const syncArray = spec.getUserSyncs({ pixelEnabled: true }, serverResponses, null, 'fake-privacy-signal');
604
+ const syncArray = spec.getUserSyncs({ pixelEnabled: true }, serverResponses);
605
605
  expect(syncArray).to.deep.equal([
606
- { type: 'image', url: 'cookieUrl1&us_privacy=fake-privacy-signal' },
607
- { type: 'image', url: 'cookieUrl2&us_privacy=fake-privacy-signal' },
608
- { type: 'image', url: 'cookieUrl3&us_privacy=fake-privacy-signal' }],
606
+ { type: 'image', url: 'cookieUrl1' },
607
+ { type: 'image', url: 'cookieUrl2' },
608
+ { type: 'image', url: 'cookieUrl3' }],
609
609
  );
610
610
  });
611
611
 
@@ -370,7 +370,7 @@ describe('Taboola Adapter', function () {
370
370
  requestId: request.bids[0].bidId,
371
371
  cpm: bid.price,
372
372
  creativeId: bid.crid,
373
- ttl: 360,
373
+ ttl: 60,
374
374
  netRevenue: false,
375
375
  currency: serverResponse.body.cur,
376
376
  mediaType: 'banner',
@@ -93,4 +93,47 @@ describe('TargetVideo Bid Adapter', function() {
93
93
  expect(bid.ad).to.include('<script src="https://player.target-video.com/custom/targetvideo-banner.js"></script>')
94
94
  expect(bid.ad).to.include('initPlayer')
95
95
  });
96
+
97
+ it('Test GDPR consent information is present in the request', function () {
98
+ let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==';
99
+ let bidderRequest = {
100
+ 'bidderCode': 'targetVideo',
101
+ 'auctionId': '1d1a030790a475',
102
+ 'bidderRequestId': '22edbae2733bf6',
103
+ 'timeout': 3000,
104
+ 'gdprConsent': {
105
+ consentString: consentString,
106
+ gdprApplies: true,
107
+ addtlConsent: '1~7.12.35.62.66.70.89.93.108'
108
+ }
109
+ };
110
+ bidderRequest.bids = bannerRequest;
111
+
112
+ const request = spec.buildRequests(bannerRequest, bidderRequest);
113
+ expect(request.options).to.deep.equal({withCredentials: true});
114
+ const payload = JSON.parse(request.data);
115
+
116
+ expect(payload.gdpr_consent).to.exist;
117
+ expect(payload.gdpr_consent.consent_string).to.exist.and.to.equal(consentString);
118
+ expect(payload.gdpr_consent.consent_required).to.exist.and.to.be.true;
119
+ expect(payload.gdpr_consent.addtl_consent).to.exist.and.to.deep.equal([7, 12, 35, 62, 66, 70, 89, 93, 108]);
120
+ });
121
+
122
+ it('Test US Privacy string is present in the request', function() {
123
+ let consentString = '1YA-';
124
+ let bidderRequest = {
125
+ 'bidderCode': 'targetVideo',
126
+ 'auctionId': '1d1a030790a475',
127
+ 'bidderRequestId': '22edbae2733bf6',
128
+ 'timeout': 3000,
129
+ 'uspConsent': consentString
130
+ };
131
+ bidderRequest.bids = bannerRequest;
132
+
133
+ const request = spec.buildRequests(bannerRequest, bidderRequest);
134
+ const payload = JSON.parse(request.data);
135
+
136
+ expect(payload.us_privacy).to.exist;
137
+ expect(payload.us_privacy).to.exist.and.to.equal(consentString);
138
+ });
96
139
  });
@@ -466,6 +466,7 @@ describe('User ID', function () {
466
466
  describe('refreshing before init is complete', () => {
467
467
  const MOCK_ID = {'MOCKID': '1111'};
468
468
  let mockIdCallback;
469
+ let startInit;
469
470
 
470
471
  beforeEach(() => {
471
472
  mockIdCallback = sinon.stub();
@@ -480,7 +481,7 @@ describe('User ID', function () {
480
481
  };
481
482
  init(config);
482
483
  setSubmoduleRegistry([mockIdSystem]);
483
- config.setConfig({
484
+ startInit = () => config.setConfig({
484
485
  userSync: {
485
486
  auctionDelay: 10,
486
487
  userIds: [{
@@ -492,6 +493,7 @@ describe('User ID', function () {
492
493
  });
493
494
 
494
495
  it('should still resolve promises returned by getUserIdsAsync', () => {
496
+ startInit();
495
497
  let result = null;
496
498
  getGlobal().getUserIdsAsync().then((val) => { result = val; });
497
499
  return clearStack().then(() => {
@@ -506,6 +508,7 @@ describe('User ID', function () {
506
508
  it('should not stop auctions', (done) => {
507
509
  // simulate an infinite `auctionDelay`; refreshing should still allow the auction to continue
508
510
  // as soon as ID submodules have completed init
511
+ startInit();
509
512
  requestBidsHook(() => {
510
513
  done();
511
514
  }, {adUnits: [getAdUnitMock()]}, {delay: delay()});
@@ -519,6 +522,7 @@ describe('User ID', function () {
519
522
  it('should not get stuck when init fails', () => {
520
523
  const err = new Error();
521
524
  mockIdCallback.callsFake(() => { throw err; });
525
+ startInit();
522
526
  return getGlobal().getUserIdsAsync().catch((e) =>
523
527
  expect(e).to.equal(err)
524
528
  );
@@ -2531,7 +2535,6 @@ describe('User ID', function () {
2531
2535
 
2532
2536
  // init id system
2533
2537
  attachIdSystem(mockIdSystem);
2534
- config.setConfig(userIdConfig);
2535
2538
  });
2536
2539
 
2537
2540
  afterEach(function () {
@@ -2542,6 +2545,8 @@ describe('User ID', function () {
2542
2545
  coreStorage.setCookie(mockIdCookieName, JSON.stringify({id: '1234'}), expStr);
2543
2546
  coreStorage.setCookie(`${mockIdCookieName}_last`, (new Date(Date.now() - 1 * 1000).toUTCString()), expStr);
2544
2547
 
2548
+ config.setConfig(userIdConfig);
2549
+
2545
2550
  let innerAdUnits;
2546
2551
  return runBidsHook((config) => {
2547
2552
  innerAdUnits = config.adUnits
@@ -2556,6 +2561,8 @@ describe('User ID', function () {
2556
2561
  coreStorage.setCookie(mockIdCookieName, JSON.stringify({id: '1234'}), expStr);
2557
2562
  coreStorage.setCookie(`${mockIdCookieName}_last`, (new Date(Date.now() - 60 * 1000).toUTCString()), expStr);
2558
2563
 
2564
+ config.setConfig(userIdConfig);
2565
+
2559
2566
  let innerAdUnits;
2560
2567
  return runBidsHook((config) => {
2561
2568
  innerAdUnits = config.adUnits
@@ -2572,6 +2579,8 @@ describe('User ID', function () {
2572
2579
 
2573
2580
  setStoredConsentData();
2574
2581
 
2582
+ config.setConfig(userIdConfig);
2583
+
2575
2584
  let innerAdUnits;
2576
2585
  return runBidsHook((config) => {
2577
2586
  innerAdUnits = config.adUnits
@@ -2588,6 +2597,8 @@ describe('User ID', function () {
2588
2597
 
2589
2598
  setStoredConsentData({...consentData, consentString: 'different'});
2590
2599
 
2600
+ config.setConfig(userIdConfig);
2601
+
2591
2602
  let innerAdUnits;
2592
2603
  return runBidsHook((config) => {
2593
2604
  innerAdUnits = config.adUnits
@@ -2604,6 +2615,8 @@ describe('User ID', function () {
2604
2615
 
2605
2616
  setStoredConsentData({...consentData});
2606
2617
 
2618
+ config.setConfig(userIdConfig);
2619
+
2607
2620
  let innerAdUnits;
2608
2621
  return runBidsHook((config) => {
2609
2622
  innerAdUnits = config.adUnits
@@ -16,7 +16,6 @@ import * as auctionModule from 'src/auction.js';
16
16
  import { registerBidder } from 'src/adapters/bidderFactory.js';
17
17
  import { _sendAdToCreative } from 'src/secureCreatives.js';
18
18
  import {find} from 'src/polyfill.js';
19
- import {synchronizePromise} from '../../helpers/syncPromise.js';
20
19
  import * as pbjsModule from 'src/prebid.js';
21
20
  import {hook} from '../../../src/hook.js';
22
21
  import {reset as resetDebugging} from '../../../src/debugging.js';
@@ -195,7 +194,7 @@ window.apntag = {
195
194
  }
196
195
 
197
196
  describe('Unit: Prebid Module', function () {
198
- let bidExpiryStub, promiseSandbox;
197
+ let bidExpiryStub
199
198
 
200
199
  before(() => {
201
200
  hook.ready();
@@ -204,15 +203,12 @@ describe('Unit: Prebid Module', function () {
204
203
  });
205
204
 
206
205
  beforeEach(function () {
207
- promiseSandbox = sinon.createSandbox();
208
- synchronizePromise(promiseSandbox);
209
206
  bidExpiryStub = sinon.stub(filters, 'isBidNotExpired').callsFake(() => true);
210
207
  configObj.setConfig({ useBidCache: true });
211
208
  resetAuctionState();
212
209
  });
213
210
 
214
211
  afterEach(function() {
215
- promiseSandbox.restore();
216
212
  $$PREBID_GLOBAL$$.adUnits = [];
217
213
  bidExpiryStub.restore();
218
214
  configObj.setConfig({ useBidCache: false });