prebid.js 7.18.0 → 7.20.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 (313) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/33acrossIdSystem.js +1 -1
  3. package/dist/adWMGAnalyticsAdapter.js +1 -1
  4. package/dist/adagioAnalyticsAdapter.js +1 -1
  5. package/dist/adagioBidAdapter.js +1 -1
  6. package/dist/adbookpspBidAdapter.js +1 -1
  7. package/dist/adfBidAdapter.js +1 -1
  8. package/dist/adgenerationBidAdapter.js +1 -1
  9. package/dist/adkernelAdnAnalyticsAdapter.js +1 -1
  10. package/dist/adkernelBidAdapter.js +1 -1
  11. package/dist/adlooxAdServerVideo.js +1 -1
  12. package/dist/adlooxAnalyticsAdapter.js +1 -1
  13. package/dist/adlooxRtdProvider.js +1 -1
  14. package/dist/adomikAnalyticsAdapter.js +1 -1
  15. package/dist/adqueryIdSystem.js +1 -1
  16. package/dist/adrelevantisBidAdapter.js +1 -1
  17. package/dist/adtrgtmeBidAdapter.js +1 -1
  18. package/dist/adxcgAnalyticsAdapter.js +1 -1
  19. package/dist/adxcgBidAdapter.js +1 -1
  20. package/dist/adxpremiumAnalyticsAdapter.js +1 -1
  21. package/dist/ajaBidAdapter.js +1 -1
  22. package/dist/amxBidAdapter.js +1 -1
  23. package/dist/amxIdSystem.js +1 -1
  24. package/dist/aolBidAdapter.js +1 -1
  25. package/dist/appierAnalyticsAdapter.js +1 -1
  26. package/dist/appnexusBidAdapter.js +1 -1
  27. package/dist/asoBidAdapter.js +1 -1
  28. package/dist/atsAnalyticsAdapter.js +1 -1
  29. package/dist/axonixBidAdapter.js +1 -1
  30. package/dist/{andBeyondMediaBidAdapter.js → beyondmediaBidAdapter.js} +1 -1
  31. package/dist/bidViewability.js +1 -1
  32. package/dist/bidglassBidAdapter.js +1 -1
  33. package/dist/bidwatchAnalyticsAdapter.js +1 -1
  34. package/dist/big-richmediaBidAdapter.js +1 -1
  35. package/dist/bridgewellBidAdapter.js +1 -1
  36. package/dist/brightMountainMediaBidAdapter.js +1 -1
  37. package/dist/byDataAnalyticsAdapter.js +1 -1
  38. package/dist/carodaBidAdapter.js +1 -1
  39. package/dist/categoryTranslation.js +1 -1
  40. package/dist/cleanioRtdProvider.js +1 -1
  41. package/dist/colossussspBidAdapter.js +1 -1
  42. package/dist/concertAnalyticsAdapter.js +1 -1
  43. package/dist/concertBidAdapter.js +1 -1
  44. package/dist/connectIdSystem.js +1 -1
  45. package/dist/connectadBidAdapter.js +1 -1
  46. package/dist/consentManagement.js +1 -1
  47. package/dist/consentManagementUsp.js +1 -1
  48. package/dist/consumableBidAdapter.js +1 -1
  49. package/dist/conversantAnalyticsAdapter.js +1 -0
  50. package/dist/conversantBidAdapter.js +1 -1
  51. package/dist/craftBidAdapter.js +1 -1
  52. package/dist/criteoBidAdapter.js +1 -1
  53. package/dist/currency.js +1 -1
  54. package/dist/datablocksAnalyticsAdapter.js +1 -1
  55. package/dist/dchain.js +1 -1
  56. package/dist/debugging-standalone.js +1 -1
  57. package/dist/debugging.js +1 -1
  58. package/dist/dependencies.json +9 -0
  59. package/dist/dfpAdServerVideo.js +1 -1
  60. package/dist/dgkeywordRtdProvider.js +1 -1
  61. package/dist/dianomiBidAdapter.js +1 -1
  62. package/dist/dspxBidAdapter.js +1 -1
  63. package/dist/enrichmentFpdModule.js +1 -1
  64. package/dist/eplanningAnalyticsAdapter.js +1 -1
  65. package/dist/eplanningBidAdapter.js +1 -1
  66. package/dist/finativeBidAdapter.js +1 -1
  67. package/dist/fintezaAnalyticsAdapter.js +1 -1
  68. package/dist/fpd.js +1 -0
  69. package/dist/ftrackIdSystem.js +1 -1
  70. package/dist/gdprEnforcement.js +1 -1
  71. package/dist/glimpseBidAdapter.js +1 -1
  72. package/dist/gmosspBidAdapter.js +1 -1
  73. package/dist/goldbachBidAdapter.js +1 -1
  74. package/dist/googleAnalyticsAdapter.js +1 -1
  75. package/dist/gridBidAdapter.js +1 -1
  76. package/dist/gridNMBidAdapter.js +1 -1
  77. package/dist/gumgumBidAdapter.js +1 -1
  78. package/dist/h12mediaBidAdapter.js +1 -1
  79. package/dist/hadronAnalyticsAdapter.js +1 -1
  80. package/dist/id5AnalyticsAdapter.js +1 -1
  81. package/dist/id5IdSystem.js +1 -1
  82. package/dist/improvedigitalBidAdapter.js +1 -1
  83. package/dist/inmarBidAdapter.js +1 -1
  84. package/dist/insticatorBidAdapter.js +1 -1
  85. package/dist/invisiblyAnalyticsAdapter.js +1 -1
  86. package/dist/ixBidAdapter.js +1 -1
  87. package/dist/justpremiumBidAdapter.js +1 -1
  88. package/dist/kargoAnalyticsAdapter.js +1 -1
  89. package/dist/kinessoIdSystem.js +1 -1
  90. package/dist/konduitAnalyticsAdapter.js +1 -1
  91. package/dist/kueezBidAdapter.js +1 -1
  92. package/dist/lassoBidAdapter.js +1 -1
  93. package/dist/lifestreetBidAdapter.js +1 -1
  94. package/dist/liveIntentAnalyticsAdapter.js +1 -1
  95. package/dist/liveIntentIdSystem.js +1 -1
  96. package/dist/livewrappedAnalyticsAdapter.js +1 -1
  97. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  98. package/dist/logicadBidAdapter.js +1 -1
  99. package/dist/loglyliftBidAdapter.js +1 -1
  100. package/dist/lotamePanoramaIdSystem.js +1 -1
  101. package/dist/magniteAnalyticsAdapter.js +1 -0
  102. package/dist/malltvAnalyticsAdapter.js +1 -1
  103. package/dist/marsmediaAnalyticsAdapter.js +1 -1
  104. package/dist/marsmediaBidAdapter.js +1 -1
  105. package/dist/mass.js +1 -1
  106. package/dist/mediafuseBidAdapter.js +1 -1
  107. package/dist/mediakeysBidAdapter.js +1 -1
  108. package/dist/medianetAnalyticsAdapter.js +1 -1
  109. package/dist/mediasquareBidAdapter.js +1 -1
  110. package/dist/mgidBidAdapter.js +1 -1
  111. package/dist/minutemediaBidAdapter.js +1 -1
  112. package/dist/multibid.js +1 -1
  113. package/dist/nativoBidAdapter.js +1 -1
  114. package/dist/not-for-prod/prebid.js +198 -194
  115. package/dist/oguryBidAdapter.js +1 -1
  116. package/dist/onetagBidAdapter.js +1 -1
  117. package/dist/ooloAnalyticsAdapter.js +1 -1
  118. package/dist/openxAnalyticsAdapter.js +1 -1
  119. package/dist/optimonAnalyticsAdapter.js +1 -1
  120. package/dist/outbrainBidAdapter.js +1 -1
  121. package/dist/parrableIdSystem.js +1 -1
  122. package/dist/pianoDmpAnalyticsAdapter.js +1 -1
  123. package/dist/pixfutureBidAdapter.js +1 -1
  124. package/dist/prebid-core.js +2 -2
  125. package/dist/prebidServerBidAdapter.js +1 -1
  126. package/dist/prebidmanagerAnalyticsAdapter.js +1 -1
  127. package/dist/priceFloors.js +1 -1
  128. package/dist/publinkIdSystem.js +1 -1
  129. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  130. package/dist/pubmaticBidAdapter.js +1 -1
  131. package/dist/pubperfAnalyticsAdapter.js +1 -1
  132. package/dist/pubstackAnalyticsAdapter.js +1 -1
  133. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  134. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  135. package/dist/pulsepointAnalyticsAdapter.js +1 -1
  136. package/dist/pxyzBidAdapter.js +1 -1
  137. package/dist/quantcastBidAdapter.js +1 -1
  138. package/dist/quantcastIdSystem.js +1 -1
  139. package/dist/readpeakBidAdapter.js +1 -1
  140. package/dist/realvuAnalyticsAdapter.js +1 -1
  141. package/dist/relaidoBidAdapter.js +1 -1
  142. package/dist/relevantAnalyticsAdapter.js +1 -1
  143. package/dist/rhythmoneBidAdapter.js +1 -1
  144. package/dist/riseBidAdapter.js +1 -1
  145. package/dist/rivrAnalyticsAdapter.js +1 -1
  146. package/dist/roxotAnalyticsAdapter.js +1 -1
  147. package/dist/rtdModule.js +1 -1
  148. package/dist/rubiconAnalyticsAdapter.js +1 -1
  149. package/dist/rubiconBidAdapter.js +1 -1
  150. package/dist/s2sTesting.js +1 -1
  151. package/dist/scaleableAnalyticsAdapter.js +1 -1
  152. package/dist/schain.js +1 -1
  153. package/dist/seedingAllianceBidAdapter.js +1 -1
  154. package/dist/seedtagBidAdapter.js +1 -1
  155. package/dist/sharedIdSystem.js +1 -1
  156. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  157. package/dist/sharethroughBidAdapter.js +1 -1
  158. package/dist/shinezBidAdapter.js +1 -1
  159. package/dist/sigmoidAnalyticsAdapter.js +1 -1
  160. package/dist/smaatoBidAdapter.js +1 -1
  161. package/dist/smartadserverBidAdapter.js +1 -1
  162. package/dist/smartxBidAdapter.js +1 -1
  163. package/dist/smilewantedBidAdapter.js +1 -1
  164. package/dist/sonobiAnalyticsAdapter.js +1 -1
  165. package/dist/sonobiBidAdapter.js +1 -1
  166. package/dist/sovrnAnalyticsAdapter.js +1 -1
  167. package/dist/sovrnBidAdapter.js +1 -1
  168. package/dist/sspBCBidAdapter.js +1 -1
  169. package/dist/staqAnalyticsAdapter.js +1 -1
  170. package/dist/sublimeBidAdapter.js +1 -1
  171. package/dist/synacormediaBidAdapter.js +1 -1
  172. package/dist/taboolaBidAdapter.js +1 -1
  173. package/dist/tapadIdSystem.js +1 -1
  174. package/dist/targetVideoBidAdapter.js +1 -1
  175. package/dist/teadsBidAdapter.js +1 -1
  176. package/dist/teadsIdSystem.js +1 -0
  177. package/dist/terceptAnalyticsAdapter.js +1 -1
  178. package/dist/trionBidAdapter.js +1 -1
  179. package/dist/tripleliftBidAdapter.js +1 -1
  180. package/dist/ttdBidAdapter.js +1 -1
  181. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  182. package/dist/underdogmediaBidAdapter.js +1 -1
  183. package/dist/undertoneBidAdapter.js +1 -1
  184. package/dist/userId.js +1 -1
  185. package/dist/vidazooBidAdapter.js +1 -1
  186. package/dist/videobyteBidAdapter.js +1 -1
  187. package/dist/visxBidAdapter.js +1 -1
  188. package/dist/vrtcalBidAdapter.js +1 -1
  189. package/dist/vuukleBidAdapter.js +1 -1
  190. package/dist/weboramaRtdProvider.js +1 -1
  191. package/dist/widespaceBidAdapter.js +1 -1
  192. package/dist/winrBidAdapter.js +1 -1
  193. package/dist/yahoosspBidAdapter.js +1 -1
  194. package/dist/yandexBidAdapter.js +1 -1
  195. package/dist/yieldmoBidAdapter.js +1 -1
  196. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  197. package/dist/yuktamediaAnalyticsAdapter.js +1 -1
  198. package/dist/zeta_global_sspAnalyticsAdapter.js +1 -1
  199. package/libraries/fpd/sua.js +98 -0
  200. package/modules/.submodules.json +1 -0
  201. package/modules/adfBidAdapter.js +1 -1
  202. package/modules/adkernelAdnBidAdapter.js +1 -0
  203. package/modules/adkernelBidAdapter.js +2 -2
  204. package/modules/adqueryIdSystem.js +8 -8
  205. package/modules/adxcgBidAdapter.js +1 -1
  206. package/modules/amxBidAdapter.js +1 -1
  207. package/modules/aolBidAdapter.js +25 -2
  208. package/modules/appnexusBidAdapter.js +19 -2
  209. package/modules/{andBeyondMediaBidAdapter.js → beyondmediaBidAdapter.js} +0 -0
  210. package/modules/{andBeyondMediaBidAdapter.md → beyondmediaBidAdapter.md} +1 -1
  211. package/modules/categoryTranslation.js +4 -4
  212. package/modules/cleanioRtdProvider.js +3 -4
  213. package/modules/colossussspBidAdapter.js +2 -1
  214. package/modules/connectIdSystem.js +16 -1
  215. package/modules/conversantAnalyticsAdapter.js +560 -0
  216. package/modules/conversantAnalyticsAdapter.md +47 -0
  217. package/modules/criteoBidAdapter.js +1 -1
  218. package/modules/currency.js +11 -11
  219. package/modules/dchain.js +2 -2
  220. package/modules/debugging/bidInterceptor.js +2 -2
  221. package/modules/debugging/debugging.js +10 -2
  222. package/modules/debugging/legacy.js +2 -2
  223. package/modules/dgkeywordRtdProvider.js +21 -3
  224. package/modules/dianomiBidAdapter.js +1 -1
  225. package/modules/enrichmentFpdModule.js +33 -14
  226. package/modules/eplanningBidAdapter.js +48 -2
  227. package/modules/finativeBidAdapter.js +1 -1
  228. package/modules/gridBidAdapter.js +187 -117
  229. package/modules/improvedigitalBidAdapter.js +2 -2
  230. package/modules/ixBidAdapter.js +94 -23
  231. package/modules/liveIntentIdSystem.js +39 -5
  232. package/modules/lotamePanoramaIdSystem.js +10 -6
  233. package/modules/magniteAnalyticsAdapter.js +902 -0
  234. package/modules/magniteAnalyticsAdapter.md +18 -0
  235. package/modules/mass.js +2 -2
  236. package/modules/mediakeysBidAdapter.js +6 -1
  237. package/modules/mediakeysBidAdapter.md +50 -40
  238. package/modules/multibid/index.js +5 -5
  239. package/modules/nativoBidAdapter.js +1 -1
  240. package/modules/pixfutureBidAdapter.js +46 -15
  241. package/modules/prebidServerBidAdapter/index.js +54 -19
  242. package/modules/priceFloors.js +8 -22
  243. package/modules/readpeakBidAdapter.js +1 -1
  244. package/modules/rubiconAnalyticsAdapter.js +14 -9
  245. package/modules/rubiconBidAdapter.js +2 -3
  246. package/modules/seedingAllianceBidAdapter.js +1 -1
  247. package/modules/sharethroughBidAdapter.js +1 -1
  248. package/modules/taboolaBidAdapter.js +5 -5
  249. package/modules/talkadsBidAdapter.js +1 -0
  250. package/modules/teadsIdSystem.js +234 -0
  251. package/modules/teadsIdSystem.md +22 -0
  252. package/modules/truereachBidAdapter.js +1 -0
  253. package/modules/ttdBidAdapter.js +1 -1
  254. package/modules/userId/index.js +21 -14
  255. package/modules/vrtcalBidAdapter.js +7 -1
  256. package/modules/vuukleBidAdapter.js +34 -3
  257. package/modules/yahoosspBidAdapter.js +4 -2
  258. package/modules/yandexBidAdapter.js +31 -8
  259. package/package.json +2 -2
  260. package/src/adapterManager.js +2 -4
  261. package/src/adapters/bidderFactory.js +13 -11
  262. package/src/auction.js +140 -69
  263. package/src/constants.json +8 -0
  264. package/src/cpmBucketManager.js +22 -3
  265. package/src/native.js +1 -5
  266. package/src/prebid.js +5 -6
  267. package/src/targeting.js +31 -14
  268. package/test/fixtures/fixtures.js +2 -1
  269. package/test/spec/auctionmanager_spec.js +109 -21
  270. package/test/spec/cpmBucketManager_spec.js +239 -177
  271. package/test/spec/fpd/sua_spec.js +244 -0
  272. package/test/spec/modules/adfBidAdapter_spec.js +2 -3
  273. package/test/spec/modules/adqueryIdSystem_spec.js +0 -2
  274. package/test/spec/modules/adxcgBidAdapter_spec.js +2 -3
  275. package/test/spec/modules/amxBidAdapter_spec.js +3 -2
  276. package/test/spec/modules/aolBidAdapter_spec.js +42 -9
  277. package/test/spec/modules/appnexusBidAdapter_spec.js +24 -0
  278. package/test/spec/modules/{andBeyondMediaBidAdapter_spec.js → beyondmediaBidAdapter_spec.js} +1 -1
  279. package/test/spec/modules/colossussspBidAdapter_spec.js +4 -2
  280. package/test/spec/modules/connectIdSystem_spec.js +20 -0
  281. package/test/spec/modules/conversantAnalyticsAdapter_spec.js +963 -0
  282. package/test/spec/modules/currency_spec.js +14 -6
  283. package/test/spec/modules/debugging_mod_spec.js +9 -0
  284. package/test/spec/modules/dgkeywordRtdProvider_spec.js +83 -1
  285. package/test/spec/modules/dianomiBidAdapter_spec.js +2 -3
  286. package/test/spec/modules/enrichmentFpdModule_spec.js +50 -7
  287. package/test/spec/modules/eplanningBidAdapter_spec.js +285 -1
  288. package/test/spec/modules/fpdModule_spec.js +9 -0
  289. package/test/spec/modules/gridBidAdapter_spec.js +87 -31
  290. package/test/spec/modules/ixBidAdapter_spec.js +221 -2
  291. package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +62 -8
  292. package/test/spec/modules/liveIntentIdSystem_spec.js +62 -8
  293. package/test/spec/modules/lotamePanoramaIdSystem_spec.js +0 -1
  294. package/test/spec/modules/magniteAnalyticsAdapter_spec.js +1942 -0
  295. package/test/spec/modules/mediakeysBidAdapter_spec.js +20 -3
  296. package/test/spec/modules/nativoBidAdapter_spec.js +13 -2
  297. package/test/spec/modules/prebidServerBidAdapter_spec.js +202 -15
  298. package/test/spec/modules/priceFloors_spec.js +5 -5
  299. package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +2 -3
  300. package/test/spec/modules/seedtagBidAdapter_spec.js +15 -18
  301. package/test/spec/modules/sharethroughBidAdapter_spec.js +2 -1
  302. package/test/spec/modules/taboolaBidAdapter_spec.js +112 -13
  303. package/test/spec/modules/teadsIdSystem_spec.js +271 -0
  304. package/test/spec/modules/ttdBidAdapter_spec.js +3 -3
  305. package/test/spec/modules/userId_spec.js +39 -4
  306. package/test/spec/modules/vrtcalBidAdapter_spec.js +12 -1
  307. package/test/spec/modules/vuukleBidAdapter_spec.js +87 -0
  308. package/test/spec/modules/yahoosspBidAdapter_spec.js +48 -1
  309. package/test/spec/modules/yandexBidAdapter_spec.js +8 -5
  310. package/test/spec/native_spec.js +5 -0
  311. package/test/spec/unit/core/bidderFactory_spec.js +66 -11
  312. package/test/spec/unit/core/targeting_spec.js +28 -9
  313. package/test/spec/unit/pbjs_api_spec.js +48 -2
@@ -21,6 +21,7 @@ import {auctionManager} from '../../src/auctionManager.js';
21
21
  import 'modules/debugging/index.js' // some tests look for debugging side effects
22
22
  import {AuctionIndex} from '../../src/auctionIndex.js';
23
23
  import {expect} from 'chai';
24
+ import {deepClone} from '../../src/utils.js';
24
25
 
25
26
  var assert = require('assert');
26
27
 
@@ -57,7 +58,16 @@ function mockBid(opts) {
57
58
  'currency': 'USD',
58
59
  'netRevenue': true,
59
60
  'ttl': 360,
60
- getSize: () => '300x250'
61
+ getSize: () => '300x250',
62
+ getIdentifiers() {
63
+ return {
64
+ src: this.source,
65
+ bidder: this.bidderCode,
66
+ bidId: this.requestId,
67
+ transactionId: this.transactionId,
68
+ auctionId: this.auctionId
69
+ }
70
+ }
61
71
  };
62
72
  }
63
73
 
@@ -1323,6 +1333,7 @@ describe('auctionmanager.js', function () {
1323
1333
  getAdUnits: () => getBidRequests().flatMap(br => br.bids).map(br => ({ code: br.adUnitCode, transactionId: br.transactionId, mediaTypes: br.mediaTypes })),
1324
1334
  getAuctionId: () => '1',
1325
1335
  addBidReceived: () => true,
1336
+ addBidRejected: () => true,
1326
1337
  getTimeout: () => 1000,
1327
1338
  getAuctionStart: () => start,
1328
1339
  }
@@ -1382,26 +1393,32 @@ describe('auctionmanager.js', function () {
1382
1393
  bidRequests = null;
1383
1394
  });
1384
1395
 
1385
- it('should call auction done after bid is added to auction for mediaType banner', function () {
1386
- let ADUNIT_CODE2 = 'adUnitCode2';
1387
- let BIDDER_CODE2 = 'sampleBidder2';
1388
-
1389
- let bids1 = [mockBid({ bidderCode: BIDDER_CODE1, transactionId: ADUNIT_CODE1 })];
1390
- let bids2 = [mockBid({ bidderCode: BIDDER_CODE2, transactionId: ADUNIT_CODE2 })];
1391
- bidRequests = [
1392
- mockBidRequest(bids[0]),
1393
- mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }),
1394
- mockBidRequest(bids2[0], { adUnitCode: ADUNIT_CODE2 })
1395
- ];
1396
- let cbs = auctionCallbacks(doneSpy, auction);
1397
- cbs.addBidResponse.call(bidRequests[0], ADUNIT_CODE, bids[0]);
1398
- cbs.adapterDone.call(bidRequests[0]);
1399
- cbs.addBidResponse.call(bidRequests[1], ADUNIT_CODE1, bids1[0]);
1400
- cbs.adapterDone.call(bidRequests[1]);
1401
- cbs.addBidResponse.call(bidRequests[2], ADUNIT_CODE2, bids2[0]);
1402
- cbs.adapterDone.call(bidRequests[2]);
1403
- assert.equal(doneSpy.callCount, 1);
1404
- });
1396
+ Object.entries({
1397
+ 'added to': (cbs) => cbs.addBidResponse,
1398
+ 'rejected from': (cbs) => cbs.addBidResponse.reject,
1399
+ }).forEach(([t, getMethod]) => {
1400
+ it(`should call auction done after bid is ${t} auction for mediaType banner`, function () {
1401
+ let ADUNIT_CODE2 = 'adUnitCode2';
1402
+ let BIDDER_CODE2 = 'sampleBidder2';
1403
+
1404
+ let bids1 = [mockBid({ bidderCode: BIDDER_CODE1, transactionId: ADUNIT_CODE1 })];
1405
+ let bids2 = [mockBid({ bidderCode: BIDDER_CODE2, transactionId: ADUNIT_CODE2 })];
1406
+ bidRequests = [
1407
+ mockBidRequest(bids[0]),
1408
+ mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }),
1409
+ mockBidRequest(bids2[0], { adUnitCode: ADUNIT_CODE2 })
1410
+ ];
1411
+ let cbs = auctionCallbacks(doneSpy, auction);
1412
+ const method = getMethod(cbs);
1413
+ method(ADUNIT_CODE, bids[0]);
1414
+ cbs.adapterDone.call(bidRequests[0]);
1415
+ method(ADUNIT_CODE1, bids1[0]);
1416
+ cbs.adapterDone.call(bidRequests[1]);
1417
+ method(ADUNIT_CODE2, bids2[0]);
1418
+ cbs.adapterDone.call(bidRequests[2]);
1419
+ assert.equal(doneSpy.callCount, 1);
1420
+ });
1421
+ })
1405
1422
 
1406
1423
  it('should call auction done after prebid cache is complete for mediaType video', function() {
1407
1424
  bids[0].mediaType = 'video';
@@ -1543,6 +1560,77 @@ describe('auctionmanager.js', function () {
1543
1560
  });
1544
1561
  })
1545
1562
  });
1563
+
1564
+ describe('when bids are rejected', () => {
1565
+ let cbs, bid, expectedRejection;
1566
+ const onBidRejected = sinon.stub();
1567
+ const REJECTION_REASON = 'Bid rejected';
1568
+ const AU_CODE = 'au';
1569
+
1570
+ function rejectHook(fn, adUnitCode, bid, reject) {
1571
+ reject(REJECTION_REASON);
1572
+ reject(REJECTION_REASON); // second call should do nothing
1573
+ }
1574
+
1575
+ before(() => {
1576
+ addBidResponse.before(rejectHook, 999);
1577
+ events.on(CONSTANTS.EVENTS.BID_REJECTED, onBidRejected);
1578
+ });
1579
+
1580
+ after(() => {
1581
+ addBidResponse.getHooks({hook: rejectHook}).remove();
1582
+ events.off(CONSTANTS.EVENTS.BID_REJECTED, onBidRejected);
1583
+ });
1584
+
1585
+ beforeEach(() => {
1586
+ onBidRejected.reset();
1587
+ bid = mockBid({bidderCode: BIDDER_CODE});
1588
+ bidRequests = [
1589
+ mockBidRequest(bid),
1590
+ ];
1591
+ cbs = auctionCallbacks(doneSpy, auction);
1592
+ expectedRejection = sinon.match(Object.assign({}, bid, {
1593
+ rejectionReason: REJECTION_REASON,
1594
+ adUnitCode: AU_CODE
1595
+ }));
1596
+ auction.addBidRejected = sinon.stub();
1597
+ });
1598
+
1599
+ Object.entries({
1600
+ 'with addBidResponse.reject': () => cbs.addBidResponse.reject(AU_CODE, deepClone(bid), REJECTION_REASON),
1601
+ 'from addBidResponse hooks': () => cbs.addBidResponse(AU_CODE, deepClone(bid))
1602
+ }).forEach(([t, rejectBid]) => {
1603
+ describe(t, () => {
1604
+ it('should emit a BID_REJECTED event', () => {
1605
+ rejectBid();
1606
+ sinon.assert.calledWith(onBidRejected, expectedRejection);
1607
+ });
1608
+
1609
+ it('should pass bid to auction.addBidRejected', () => {
1610
+ rejectBid();
1611
+ sinon.assert.calledWith(auction.addBidRejected, expectedRejection);
1612
+ });
1613
+ })
1614
+ });
1615
+
1616
+ it('should return a NO_BID replacement', () => {
1617
+ const noBid = cbs.addBidResponse.reject(AU_CODE, {...bid, statusMessage: 'Bid available', status: CONSTANTS.BID_STATUS.RENDERED}, 'Rejected');
1618
+ sinon.assert.match(noBid, {
1619
+ status: CONSTANTS.BID_STATUS.BID_REJECTED,
1620
+ statusMessage: 'Bid returned empty or error response',
1621
+ cpm: 0,
1622
+ requestId: bid.requestId,
1623
+ auctionId: bid.auctionId,
1624
+ adUnitCode: AU_CODE,
1625
+ rejectionReason: undefined,
1626
+ });
1627
+ });
1628
+
1629
+ it('addBidResponse hooks should not be able to reject the same bid twice', () => {
1630
+ cbs.addBidResponse(AU_CODE, bid);
1631
+ expect(auction.addBidRejected.calledOnce).to.be.true;
1632
+ });
1633
+ })
1546
1634
  });
1547
1635
 
1548
1636
  describe('auctionOptions', function() {
@@ -1,195 +1,257 @@
1
1
  import { expect } from 'chai';
2
- import {getPriceBucketString, isValidPriceConfig} from 'src/cpmBucketManager.js';
2
+ import { getPriceBucketString, isValidPriceConfig } from 'src/cpmBucketManager.js';
3
+ import { config } from 'src/config.js';
4
+
3
5
  let cpmFixtures = require('test/fixtures/cpmInputsOutputs.json');
4
6
 
5
7
  describe('cpmBucketManager', function () {
6
- it('getPriceBucketString function generates the correct price strings', function () {
7
- let input = cpmFixtures.cpmInputs;
8
- for (let i = 0; i < input.length; i++) {
9
- let output = getPriceBucketString(input[i]);
10
- let jsonOutput = JSON.stringify(output);
11
- expect(jsonOutput).to.deep.equal(JSON.stringify(cpmFixtures.priceStringOutputs[i]));
12
- }
13
- });
14
-
15
- it('gets the correct custom bucket strings', function () {
16
- let cpm = 16.50908;
17
- let customConfig = {
18
- 'buckets': [{
19
- 'precision': 4,
20
- 'max': 3,
21
- 'increment': 0.01,
22
- },
23
- {
24
- 'precision': 4,
25
- 'max': 18,
26
- 'increment': 0.05,
27
- 'cap': true
8
+ describe('getPriceBucketString', function () {
9
+ it('getPriceBucketString function generates the correct price strings', function () {
10
+ let input = cpmFixtures.cpmInputs;
11
+ for (let i = 0; i < input.length; i++) {
12
+ let output = getPriceBucketString(input[i]);
13
+ let jsonOutput = JSON.stringify(output);
14
+ expect(jsonOutput).to.deep.equal(JSON.stringify(cpmFixtures.priceStringOutputs[i]));
28
15
  }
29
- ]
30
- };
31
- let expected = '{"low":"5.00","med":"16.50","high":"16.50","auto":"16.50","dense":"16.50","custom":"16.5000"}';
32
- let output = getPriceBucketString(cpm, customConfig);
33
- expect(JSON.stringify(output)).to.deep.equal(expected);
34
- });
16
+ });
35
17
 
36
- it('gets the correct custom bucket strings with irregular increment', function () {
37
- let cpm = 14.50908;
38
- let customConfig = {
39
- 'buckets': [{
40
- 'precision': 4,
41
- 'max': 4,
42
- 'increment': 0.01,
43
- },
44
- {
45
- 'precision': 4,
46
- 'max': 18,
47
- 'increment': 0.3,
48
- 'cap': true
49
- }
50
- ]
51
- };
52
- let expected = '{"low":"5.00","med":"14.50","high":"14.50","auto":"14.50","dense":"14.50","custom":"14.5000"}';
53
- let output = getPriceBucketString(cpm, customConfig);
54
- expect(JSON.stringify(output)).to.deep.equal(expected);
55
- });
56
-
57
- it('gets the correct custom bucket strings in non-USD currency', function () {
58
- let cpm = 16.50908 * 110.49;
59
- let customConfig = {
60
- 'buckets': [{
61
- 'precision': 4,
62
- 'max': 3,
63
- 'increment': 0.01,
64
- },
65
- {
66
- 'precision': 4,
67
- 'max': 18,
68
- 'increment': 0.05,
69
- 'cap': true
70
- }
71
- ]
72
- };
73
- let expected = '{"low":"552.45","med":"1823.09","high":"1823.09","auto":"1823.09","dense":"1823.09","custom":"1823.0850"}';
74
- let output = getPriceBucketString(cpm, customConfig, 110.49);
75
- expect(JSON.stringify(output)).to.deep.equal(expected);
76
- });
77
-
78
- it('gets the correct custom bucket strings with specific cpms that round oddly with certain increments', function () {
79
- let customConfig = {
80
- 'buckets': [{
81
- 'precision': 4,
82
- 'max': 4,
83
- 'increment': 0.10,
84
- }]
85
- };
86
- let cpm = 2.21;
87
- let expected = '{"low":"2.00","med":"2.20","high":"2.21","auto":"2.20","dense":"2.21","custom":"2.2000"}';
88
- let output = getPriceBucketString(cpm, customConfig);
89
- expect(JSON.stringify(output)).to.deep.equal(expected);
90
-
91
- cpm = 3.15;
92
- expected = '{"low":"3.00","med":"3.10","high":"3.15","auto":"3.15","dense":"3.15","custom":"3.1000"}';
93
- output = getPriceBucketString(cpm, customConfig);
94
- expect(JSON.stringify(output)).to.deep.equal(expected);
95
-
96
- customConfig = {
97
- 'buckets': [{
98
- 'precision': 3,
99
- 'max': 6,
100
- 'increment': 0.08,
101
- }]
102
- };
103
- cpm = 4.89;
104
- expected = '{"low":"4.50","med":"4.80","high":"4.89","auto":"4.85","dense":"4.85","custom":"4.880"}';
105
- output = getPriceBucketString(cpm, customConfig);
106
- expect(JSON.stringify(output)).to.deep.equal(expected);
107
-
108
- customConfig = {
109
- 'buckets': [{
110
- 'precision': 3,
111
- 'max': 6,
112
- 'increment': 0.05,
113
- }]
114
- };
115
- cpm = 2.98;
116
- expected = '{"low":"2.50","med":"2.90","high":"2.98","auto":"2.95","dense":"2.98","custom":"2.950"}';
117
- output = getPriceBucketString(cpm, customConfig);
118
- expect(JSON.stringify(output)).to.deep.equal(expected);
119
-
120
- cpm = 2.99;
121
- expected = '{"low":"2.50","med":"2.90","high":"2.99","auto":"2.95","dense":"2.99","custom":"2.950"}';
122
- output = getPriceBucketString(cpm, customConfig);
123
- expect(JSON.stringify(output)).to.deep.equal(expected);
124
-
125
- customConfig = {
126
- 'buckets': [{
127
- 'precision': 2,
128
- 'max': 6,
129
- 'increment': 0.01,
130
- }]
131
- };
132
- cpm = 4.01;
133
- expected = '{"low":"4.00","med":"4.00","high":"4.01","auto":"4.00","dense":"4.00","custom":"4.01"}';
134
- output = getPriceBucketString(cpm, customConfig);
135
- expect(JSON.stringify(output)).to.deep.equal(expected);
136
-
137
- cpm = 4.68;
138
- expected = '{"low":"4.50","med":"4.60","high":"4.68","auto":"4.65","dense":"4.65","custom":"4.68"}';
139
- output = getPriceBucketString(cpm, customConfig);
140
- expect(JSON.stringify(output)).to.deep.equal(expected);
141
-
142
- cpm = 4.69;
143
- expected = '{"low":"4.50","med":"4.60","high":"4.69","auto":"4.65","dense":"4.65","custom":"4.69"}';
144
- output = getPriceBucketString(cpm, customConfig);
145
- expect(JSON.stringify(output)).to.deep.equal(expected);
146
- });
147
-
148
- it('gets custom bucket strings and it should honor 0', function () {
149
- let cpm = 16.50908;
150
- let customConfig = {
151
- 'buckets': [
18
+ it('gets the correct custom bucket strings', function () {
19
+ let cpm = 16.50908;
20
+ let customConfig = {
21
+ 'buckets': [{
22
+ 'precision': 4,
23
+ 'max': 3,
24
+ 'increment': 0.01,
25
+ },
152
26
  {
153
- 'precision': 0,
27
+ 'precision': 4,
154
28
  'max': 18,
155
29
  'increment': 0.05,
156
- }
157
- ]
158
- };
159
- let expected = '{"low":"5.00","med":"16.50","high":"16.50","auto":"16.50","dense":"16.50","custom":"17"}';
160
- let output = getPriceBucketString(cpm, customConfig);
161
- expect(JSON.stringify(output)).to.deep.equal(expected);
162
- });
30
+ 'cap': true
31
+ }]
32
+ };
33
+ let expected = '{"low":"5.00","med":"16.50","high":"16.50","auto":"16.50","dense":"16.50","custom":"16.5000"}';
34
+ let output = getPriceBucketString(cpm, customConfig);
35
+ expect(JSON.stringify(output)).to.deep.equal(expected);
36
+ });
163
37
 
164
- it('gets the custom bucket strings without passing precision and it should honor the default precision', function () {
165
- let cpm = 16.50908;
166
- let customConfig = {
167
- 'buckets': [
38
+ it('gets the correct custom bucket strings with irregular increment', function () {
39
+ let cpm = 14.50908;
40
+ let customConfig = {
41
+ 'buckets': [{
42
+ 'precision': 4,
43
+ 'max': 4,
44
+ 'increment': 0.01,
45
+ },
168
46
  {
47
+ 'precision': 4,
48
+ 'max': 18,
49
+ 'increment': 0.3,
50
+ 'cap': true
51
+ }]
52
+ };
53
+ let expected = '{"low":"5.00","med":"14.50","high":"14.50","auto":"14.50","dense":"14.50","custom":"14.5000"}';
54
+ let output = getPriceBucketString(cpm, customConfig);
55
+ expect(JSON.stringify(output)).to.deep.equal(expected);
56
+ });
57
+
58
+ it('gets the correct custom bucket strings in non-USD currency', function () {
59
+ let cpm = 16.50908 * 110.49;
60
+ let customConfig = {
61
+ 'buckets': [{
62
+ 'precision': 4,
63
+ 'max': 3,
64
+ 'increment': 0.01,
65
+ },
66
+ {
67
+ 'precision': 4,
169
68
  'max': 18,
170
69
  'increment': 0.05,
171
- }
172
- ]
173
- };
174
- let expected = '{"low":"5.00","med":"16.50","high":"16.50","auto":"16.50","dense":"16.50","custom":"16.50"}';
175
- let output = getPriceBucketString(cpm, customConfig);
176
- expect(JSON.stringify(output)).to.deep.equal(expected);
70
+ 'cap': true
71
+ }]
72
+ };
73
+ let expected = '{"low":"552.45","med":"1823.09","high":"1823.09","auto":"1823.09","dense":"1823.09","custom":"1823.0850"}';
74
+ let output = getPriceBucketString(cpm, customConfig, 110.49);
75
+ expect(JSON.stringify(output)).to.deep.equal(expected);
76
+ });
77
+
78
+ it('gets the correct custom bucket strings with specific cpms that round oddly with certain increments', function () {
79
+ let customConfig = {
80
+ 'buckets': [{
81
+ 'precision': 4,
82
+ 'max': 4,
83
+ 'increment': 0.10,
84
+ }]
85
+ };
86
+ let cpm = 2.21;
87
+ let expected = '{"low":"2.00","med":"2.20","high":"2.21","auto":"2.20","dense":"2.21","custom":"2.2000"}';
88
+ let output = getPriceBucketString(cpm, customConfig);
89
+ expect(JSON.stringify(output)).to.deep.equal(expected);
90
+
91
+ cpm = 3.15;
92
+ expected = '{"low":"3.00","med":"3.10","high":"3.15","auto":"3.15","dense":"3.15","custom":"3.1000"}';
93
+ output = getPriceBucketString(cpm, customConfig);
94
+ expect(JSON.stringify(output)).to.deep.equal(expected);
95
+
96
+ customConfig = {
97
+ 'buckets': [{
98
+ 'precision': 3,
99
+ 'max': 6,
100
+ 'increment': 0.08,
101
+ }]
102
+ };
103
+ cpm = 4.89;
104
+ expected = '{"low":"4.50","med":"4.80","high":"4.89","auto":"4.85","dense":"4.85","custom":"4.880"}';
105
+ output = getPriceBucketString(cpm, customConfig);
106
+ expect(JSON.stringify(output)).to.deep.equal(expected);
107
+
108
+ customConfig = {
109
+ 'buckets': [{
110
+ 'precision': 3,
111
+ 'max': 6,
112
+ 'increment': 0.05,
113
+ }]
114
+ };
115
+ cpm = 2.98;
116
+ expected = '{"low":"2.50","med":"2.90","high":"2.98","auto":"2.95","dense":"2.98","custom":"2.950"}';
117
+ output = getPriceBucketString(cpm, customConfig);
118
+ expect(JSON.stringify(output)).to.deep.equal(expected);
119
+
120
+ cpm = 2.99;
121
+ expected = '{"low":"2.50","med":"2.90","high":"2.99","auto":"2.95","dense":"2.99","custom":"2.950"}';
122
+ output = getPriceBucketString(cpm, customConfig);
123
+ expect(JSON.stringify(output)).to.deep.equal(expected);
124
+
125
+ customConfig = {
126
+ 'buckets': [{
127
+ 'precision': 2,
128
+ 'max': 6,
129
+ 'increment': 0.01,
130
+ }]
131
+ };
132
+ cpm = 4.01;
133
+ expected = '{"low":"4.00","med":"4.00","high":"4.01","auto":"4.00","dense":"4.00","custom":"4.01"}';
134
+ output = getPriceBucketString(cpm, customConfig);
135
+ expect(JSON.stringify(output)).to.deep.equal(expected);
136
+
137
+ cpm = 4.68;
138
+ expected = '{"low":"4.50","med":"4.60","high":"4.68","auto":"4.65","dense":"4.65","custom":"4.68"}';
139
+ output = getPriceBucketString(cpm, customConfig);
140
+ expect(JSON.stringify(output)).to.deep.equal(expected);
141
+
142
+ cpm = 4.69;
143
+ expected = '{"low":"4.50","med":"4.60","high":"4.69","auto":"4.65","dense":"4.65","custom":"4.69"}';
144
+ output = getPriceBucketString(cpm, customConfig);
145
+ expect(JSON.stringify(output)).to.deep.equal(expected);
146
+ });
147
+
148
+ it('gets custom bucket strings and it should honor 0', function () {
149
+ let cpm = 16.50908;
150
+ let customConfig = {
151
+ 'buckets': [
152
+ {
153
+ 'precision': 0,
154
+ 'max': 18,
155
+ 'increment': 0.05,
156
+ }
157
+ ]
158
+ };
159
+ let expected = '{"low":"5.00","med":"16.50","high":"16.50","auto":"16.50","dense":"16.50","custom":"17"}';
160
+ let output = getPriceBucketString(cpm, customConfig);
161
+ expect(JSON.stringify(output)).to.deep.equal(expected);
162
+ });
163
+
164
+ it('gets the custom bucket strings without passing precision and it should honor the default precision', function () {
165
+ let cpm = 16.50908;
166
+ let customConfig = {
167
+ 'buckets': [
168
+ {
169
+ 'max': 18,
170
+ 'increment': 0.05,
171
+ }
172
+ ]
173
+ };
174
+ let expected = '{"low":"5.00","med":"16.50","high":"16.50","auto":"16.50","dense":"16.50","custom":"16.50"}';
175
+ let output = getPriceBucketString(cpm, customConfig);
176
+ expect(JSON.stringify(output)).to.deep.equal(expected);
177
+ });
178
+
179
+ it('defaults to Math.floor if no rounding function is provided', function () {
180
+ let cpm = 6.516;
181
+ let customConfig = {
182
+ 'buckets': [
183
+ {
184
+ 'max': 18,
185
+ 'increment': 0.05,
186
+ }
187
+ ]
188
+ };
189
+ let expected = '{"low":"5.00","med":"6.50","high":"6.51","auto":"6.50","dense":"6.50","custom":"6.50"}';
190
+ let output = getPriceBucketString(cpm, customConfig);
191
+ expect(JSON.stringify(output)).to.deep.equal(expected);
192
+ });
193
+
194
+ it('accepts custom rounding functions', function () {
195
+ let cpm = 6.516;
196
+ let customConfig = {
197
+ 'buckets': [
198
+ {
199
+ 'max': 18,
200
+ 'increment': 0.05,
201
+ }
202
+ ]
203
+ };
204
+ let getConfig = config.getConfig;
205
+ config.getConfig = () => Math.ceil;
206
+ let expected = '{"low":"5.00","med":"6.60","high":"6.52","auto":"6.60","dense":"6.55","custom":"6.55"}';
207
+ let output = getPriceBucketString(cpm, customConfig);
208
+ config.getConfig = getConfig;
209
+ expect(JSON.stringify(output)).to.deep.equal(expected);
210
+ });
211
+
212
+ it('will default to Math.floor if passed an invalid rounding function', function () {
213
+ let cpm = 6.516;
214
+ let customConfig = {
215
+ 'buckets': [
216
+ {
217
+ 'max': 18,
218
+ 'increment': 0.05,
219
+ }
220
+ ]
221
+ };
222
+ let getConfig = config.getConfig;
223
+ config.getConfig = () => Math.ceil(5.3);
224
+ let expected = '{"low":"5.00","med":"6.50","high":"6.51","auto":"6.50","dense":"6.50","custom":"6.50"}';
225
+ let output = getPriceBucketString(cpm, customConfig);
226
+ config.getConfig = getConfig;
227
+ expect(JSON.stringify(output)).to.deep.equal(expected);
228
+ });
177
229
  });
178
230
 
179
- it('checks whether custom config is valid', function () {
180
- let badConfig = {
181
- 'buckets': [{
182
- 'max': 3,
183
- 'increment': 0.01,
184
- },
185
- {
186
- 'max': 18,
187
- // missing increment prop
188
- 'cap': true
189
- }
190
- ]
191
- };
231
+ describe('isValidPriceConfig', function () {
232
+ it('checks whether custom config is valid', function () {
233
+ let badConfig = {
234
+ 'buckets': [{
235
+ 'max': 3,
236
+ 'increment': 0.01,
237
+ },
238
+ {
239
+ 'max': 18,
240
+ // missing increment prop
241
+ 'cap': true
242
+ }]
243
+ };
244
+ expect(isValidPriceConfig(badConfig)).to.be.false;
192
245
 
193
- expect(isValidPriceConfig(badConfig)).to.be.false;
246
+ let customConfig = {
247
+ 'buckets': [
248
+ {
249
+ 'max': 18,
250
+ 'increment': 0.05,
251
+ }
252
+ ]
253
+ };
254
+ expect(isValidPriceConfig(customConfig)).to.be.true;
255
+ });
194
256
  });
195
257
  });