prebid.js 6.7.0 → 6.11.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 (160) hide show
  1. package/.eslintrc.js +8 -1
  2. package/integrationExamples/gpt/{haloRtdProvider_example.html → hadronRtdProvider_example.html} +9 -9
  3. package/integrationExamples/gpt/idImportLibrary_example.html +2 -2
  4. package/integrationExamples/gpt/userId_example.html +2 -2
  5. package/integrationExamples/gpt/weboramaRtdProvider_example.html +154 -115
  6. package/integrationExamples/gpt/x-domain/creative.html +63 -29
  7. package/modules/.submodules.json +3 -0
  8. package/modules/adagioBidAdapter.js +0 -8
  9. package/modules/adagioBidAdapter.md +1 -1
  10. package/modules/adkernelBidAdapter.js +2 -1
  11. package/modules/adnuntiusRtdProvider.js +96 -0
  12. package/modules/adnuntiusRtdProvider.md +41 -0
  13. package/modules/adotBidAdapter.js +516 -567
  14. package/modules/adotBidAdapter.md +6 -44
  15. package/modules/adpod.js +12 -14
  16. package/modules/adyoulikeBidAdapter.js +2 -0
  17. package/modules/appnexusBidAdapter.js +14 -2
  18. package/modules/asealBidAdapter.js +58 -0
  19. package/modules/asealBidAdapter.md +52 -0
  20. package/modules/brandmetricsRtdProvider.js +168 -0
  21. package/modules/brandmetricsRtdProvider.md +40 -0
  22. package/modules/conversantBidAdapter.js +7 -0
  23. package/modules/criteoBidAdapter.js +9 -0
  24. package/modules/currency.js +27 -5
  25. package/modules/displayioBidAdapter.js +157 -0
  26. package/modules/displayioBidAdapter.md +148 -0
  27. package/modules/dspxBidAdapter.js +69 -29
  28. package/modules/dspxBidAdapter.md +2 -1
  29. package/modules/e_volutionBidAdapter.js +158 -0
  30. package/modules/gridBidAdapter.js +15 -1
  31. package/modules/gumgumBidAdapter.js +52 -38
  32. package/modules/hadronIdSystem.js +96 -0
  33. package/modules/hadronIdSystem.md +35 -0
  34. package/modules/hadronRtdProvider.js +254 -0
  35. package/modules/hadronRtdProvider.md +126 -0
  36. package/modules/haloIdSystem.md +4 -35
  37. package/modules/haloRtdProvider.md +3 -126
  38. package/modules/imRtdProvider.js +10 -0
  39. package/modules/improvedigitalBidAdapter.js +5 -0
  40. package/modules/interactiveOffersBidAdapter.js +9 -6
  41. package/modules/iqzoneBidAdapter.js +10 -3
  42. package/modules/iqzoneBidAdapter.md +16 -0
  43. package/modules/ixBidAdapter.js +2 -6
  44. package/modules/kubientBidAdapter.js +50 -19
  45. package/modules/lunamediahbBidAdapter.js +32 -4
  46. package/modules/malltvBidAdapter.js +7 -3
  47. package/modules/malltvBidAdapter.md +64 -51
  48. package/modules/mass.js +3 -5
  49. package/modules/mediakeysBidAdapter.js +0 -5
  50. package/modules/medianetAnalyticsAdapter.js +1 -1
  51. package/modules/mediasquareBidAdapter.js +9 -1
  52. package/modules/nextMillenniumBidAdapter.js +1 -0
  53. package/modules/oguryBidAdapter.js +7 -14
  54. package/modules/prebidServerBidAdapter/index.js +61 -39
  55. package/modules/priceFloors.js +20 -12
  56. package/modules/pubmaticBidAdapter.js +1 -1
  57. package/modules/richaudienceBidAdapter.js +8 -3
  58. package/modules/riseBidAdapter.js +17 -6
  59. package/modules/rtbhouseBidAdapter.js +2 -0
  60. package/modules/rubiconAnalyticsAdapter.js +5 -0
  61. package/modules/rubiconBidAdapter.js +2 -2
  62. package/modules/sizeMappingV2.js +1 -8
  63. package/modules/sortableAnalyticsAdapter.js +5 -4
  64. package/modules/sovrnBidAdapter.js +93 -18
  65. package/modules/sovrnBidAdapter.md +80 -2
  66. package/modules/sspBCBidAdapter.js +53 -20
  67. package/modules/telariaBidAdapter.js +22 -29
  68. package/modules/trustpidSystem.js +197 -0
  69. package/modules/trustpidSystem.md +45 -0
  70. package/modules/undertoneBidAdapter.js +17 -1
  71. package/modules/userId/eids.js +16 -1
  72. package/modules/userId/eids.md +10 -2
  73. package/modules/userId/userId.md +17 -2
  74. package/modules/vibrantmediaBidAdapter.js +220 -0
  75. package/modules/vibrantmediaBidAdapter.md +92 -0
  76. package/modules/vidoomyBidAdapter.js +8 -0
  77. package/modules/vidoomyBidAdapter.md +4 -2
  78. package/modules/weboramaRtdProvider.js +264 -34
  79. package/modules/weboramaRtdProvider.md +110 -40
  80. package/modules/yahoosspBidAdapter.js +3 -1
  81. package/modules/yieldoneBidAdapter.js +6 -0
  82. package/package.json +2 -1
  83. package/src/adRendering.js +38 -0
  84. package/src/adapterManager.js +24 -19
  85. package/src/adapters/bidderFactory.js +14 -11
  86. package/src/adloader.js +2 -1
  87. package/src/auction.js +138 -115
  88. package/src/auctionIndex.js +85 -0
  89. package/src/auctionManager.js +3 -0
  90. package/src/bidderSettings.js +69 -0
  91. package/src/bidfactory.js +18 -6
  92. package/src/native.js +29 -21
  93. package/src/prebid.js +3 -19
  94. package/src/secureCreatives.js +128 -45
  95. package/src/targeting.js +11 -2
  96. package/src/utils.js +14 -17
  97. package/src/video.js +10 -11
  98. package/src/videoCache.js +10 -9
  99. package/test/fixtures/fixtures.js +2 -1
  100. package/test/helpers/indexStub.js +28 -0
  101. package/test/helpers/syncPromise.js +71 -0
  102. package/test/spec/auctionmanager_spec.js +268 -89
  103. package/test/spec/config_spec.js +24 -1
  104. package/test/spec/modules/adagioBidAdapter_spec.js +0 -10
  105. package/test/spec/modules/adnuntiusRtdProvider_spec.js +145 -0
  106. package/test/spec/modules/adotBidAdapter_spec.js +294 -3124
  107. package/test/spec/modules/adpod_spec.js +91 -156
  108. package/test/spec/modules/adyoulikeBidAdapter_spec.js +4 -0
  109. package/test/spec/modules/appnexusBidAdapter_spec.js +27 -0
  110. package/test/spec/modules/asealBidAdapter_spec.js +144 -0
  111. package/test/spec/modules/brandmetricsRtdProvider_spec.js +191 -0
  112. package/test/spec/modules/conversantBidAdapter_spec.js +54 -2
  113. package/test/spec/modules/criteoBidAdapter_spec.js +21 -0
  114. package/test/spec/modules/currency_spec.js +36 -15
  115. package/test/spec/modules/displayioBidAdapter_spec.js +239 -0
  116. package/test/spec/modules/dspxBidAdapter_spec.js +20 -15
  117. package/test/spec/modules/e_volutionBidAdapter_spec.js +242 -0
  118. package/test/spec/modules/eids_spec.js +2 -2
  119. package/test/spec/modules/gridBidAdapter_spec.js +18 -0
  120. package/test/spec/modules/gumgumBidAdapter_spec.js +49 -3
  121. package/test/spec/modules/hadronIdSystem_spec.js +57 -0
  122. package/test/spec/modules/hadronRtdProvider_spec.js +762 -0
  123. package/test/spec/modules/imRtdProvider_spec.js +30 -1
  124. package/test/spec/modules/improvedigitalBidAdapter_spec.js +19 -0
  125. package/test/spec/modules/iqzoneBidAdapter_spec.js +1 -0
  126. package/test/spec/modules/ixBidAdapter_spec.js +1 -1
  127. package/test/spec/modules/kubientBidAdapter_spec.js +182 -84
  128. package/test/spec/modules/lunamediahbBidAdapter_spec.js +27 -1
  129. package/test/spec/modules/mass_spec.js +2 -14
  130. package/test/spec/modules/mediakeysBidAdapter_spec.js +9 -5
  131. package/test/spec/modules/mediasquareBidAdapter_spec.js +25 -1
  132. package/test/spec/modules/oguryBidAdapter_spec.js +63 -5
  133. package/test/spec/modules/prebidServerBidAdapter_spec.js +43 -6
  134. package/test/spec/modules/priceFloors_spec.js +83 -24
  135. package/test/spec/modules/pubmaticBidAdapter_spec.js +40 -0
  136. package/test/spec/modules/riseBidAdapter_spec.js +30 -4
  137. package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +31 -1
  138. package/test/spec/modules/rubiconBidAdapter_spec.js +1 -1
  139. package/test/spec/modules/sortableAnalyticsAdapter_spec.js +2 -3
  140. package/test/spec/modules/sovrnBidAdapter_spec.js +413 -333
  141. package/test/spec/modules/sspBCBidAdapter_spec.js +7 -7
  142. package/test/spec/modules/telariaBidAdapter_spec.js +1 -3
  143. package/test/spec/modules/trustpidSystem_spec.js +232 -0
  144. package/test/spec/modules/undertoneBidAdapter_spec.js +55 -2
  145. package/test/spec/modules/userId_spec.js +39 -39
  146. package/test/spec/modules/vibrantmediaBidAdapter_spec.js +1237 -0
  147. package/test/spec/modules/vidoomyBidAdapter_spec.js +7 -1
  148. package/test/spec/modules/weboramaRtdProvider_spec.js +536 -20
  149. package/test/spec/modules/yahoosspBidAdapter_spec.js +10 -0
  150. package/test/spec/modules/yieldoneBidAdapter_spec.js +33 -0
  151. package/test/spec/native_spec.js +62 -40
  152. package/test/spec/unit/core/adapterManager_spec.js +22 -0
  153. package/test/spec/unit/core/auctionIndex_spec.js +129 -0
  154. package/test/spec/unit/core/bidderFactory_spec.js +65 -12
  155. package/test/spec/unit/core/bidderSettings_spec.js +123 -0
  156. package/test/spec/unit/core/targeting_spec.js +93 -0
  157. package/test/spec/unit/pbjs_api_spec.js +80 -42
  158. package/test/spec/unit/secureCreatives_spec.js +143 -24
  159. package/test/spec/videoCache_spec.js +18 -19
  160. package/test/spec/video_spec.js +51 -61
@@ -229,7 +229,7 @@ describe('OguryBidAdapter', function () {
229
229
  const defaultTimeout = 1000;
230
230
  const expectedRequestObject = {
231
231
  id: bidRequests[0].auctionId,
232
- at: 2,
232
+ at: 1,
233
233
  tmax: defaultTimeout,
234
234
  imp: [{
235
235
  id: bidRequests[0].bidId,
@@ -271,7 +271,7 @@ describe('OguryBidAdapter', function () {
271
271
  },
272
272
  ext: {
273
273
  prebidversion: '$prebid.version$',
274
- adapterversion: '1.2.7'
274
+ adapterversion: '1.2.10'
275
275
  }
276
276
  };
277
277
 
@@ -300,7 +300,59 @@ describe('OguryBidAdapter', function () {
300
300
  ...expectedRequestObject,
301
301
  regs: {
302
302
  ext: {
303
- gdpr: 1
303
+ gdpr: 0
304
+ },
305
+ },
306
+ user: {
307
+ ext: {
308
+ consent: ''
309
+ },
310
+ }
311
+ };
312
+
313
+ const validBidRequests = bidRequests
314
+
315
+ const request = spec.buildRequests(validBidRequests, bidderRequestWithoutGdpr);
316
+ expect(request.data).to.deep.equal(expectedRequestObjectWithoutGdpr);
317
+ expect(request.data.regs.ext.gdpr).to.be.a('number');
318
+ });
319
+
320
+ it('should not add gdpr infos if gdprConsent is undefined', () => {
321
+ const bidderRequestWithoutGdpr = {
322
+ ...bidderRequest,
323
+ gdprConsent: undefined,
324
+ }
325
+ const expectedRequestObjectWithoutGdpr = {
326
+ ...expectedRequestObject,
327
+ regs: {
328
+ ext: {
329
+ gdpr: 0
330
+ },
331
+ },
332
+ user: {
333
+ ext: {
334
+ consent: ''
335
+ },
336
+ }
337
+ };
338
+
339
+ const validBidRequests = bidRequests
340
+
341
+ const request = spec.buildRequests(validBidRequests, bidderRequestWithoutGdpr);
342
+ expect(request.data).to.deep.equal(expectedRequestObjectWithoutGdpr);
343
+ expect(request.data.regs.ext.gdpr).to.be.a('number');
344
+ });
345
+
346
+ it('should not add tcString and turn off gdpr-applies if consentString and gdprApplies are undefined', () => {
347
+ const bidderRequestWithoutGdpr = {
348
+ ...bidderRequest,
349
+ gdprConsent: { consentString: undefined, gdprApplies: undefined },
350
+ }
351
+ const expectedRequestObjectWithoutGdpr = {
352
+ ...expectedRequestObject,
353
+ regs: {
354
+ ext: {
355
+ gdpr: 0
304
356
  },
305
357
  },
306
358
  user: {
@@ -430,7 +482,7 @@ describe('OguryBidAdapter', function () {
430
482
  advertiserDomains: openRtbBidResponse.body.seatbid[0].bid[0].adomain
431
483
  },
432
484
  nurl: openRtbBidResponse.body.seatbid[0].bid[0].nurl,
433
- adapterVersion: '1.2.7',
485
+ adapterVersion: '1.2.10',
434
486
  prebidVersion: '$prebid.version$'
435
487
  }, {
436
488
  requestId: openRtbBidResponse.body.seatbid[0].bid[1].impid,
@@ -447,7 +499,7 @@ describe('OguryBidAdapter', function () {
447
499
  advertiserDomains: openRtbBidResponse.body.seatbid[0].bid[1].adomain
448
500
  },
449
501
  nurl: openRtbBidResponse.body.seatbid[0].bid[1].nurl,
450
- adapterVersion: '1.2.7',
502
+ adapterVersion: '1.2.10',
451
503
  prebidVersion: '$prebid.version$'
452
504
  }]
453
505
 
@@ -494,6 +546,11 @@ describe('OguryBidAdapter', function () {
494
546
  expect(requests.length).to.equal(0);
495
547
  })
496
548
 
549
+ it('Should not create nurl request if bid contains undefined nurl', function() {
550
+ spec.onBidWon({ nurl: undefined })
551
+ expect(requests.length).to.equal(0);
552
+ })
553
+
497
554
  it('Should create nurl request if bid nurl', function() {
498
555
  spec.onBidWon({ nurl })
499
556
  expect(requests.length).to.equal(1);
@@ -569,6 +626,7 @@ describe('OguryBidAdapter', function () {
569
626
  expect(requests.length).to.equal(1);
570
627
  expect(requests[0].url).to.equal(TIMEOUT_URL);
571
628
  expect(requests[0].method).to.equal('POST');
629
+ expect(JSON.parse(requests[0].requestBody).location).to.equal(window.location.href);
572
630
  })
573
631
  });
574
632
  });
@@ -9,6 +9,14 @@ import CONSTANTS from 'src/constants.json';
9
9
  import { server } from 'test/mocks/xhr.js';
10
10
  import { createEidsArray } from 'modules/userId/eids.js';
11
11
  import {deepAccess, deepClone} from 'src/utils.js';
12
+ import 'modules/appnexusBidAdapter.js' // appnexus alias test
13
+ import 'modules/rubiconBidAdapter.js' // rubicon alias test
14
+ import 'src/prebid.js' // $$PREBID_GLOBAL$$.aliasBidder test
15
+ import 'modules/currency.js' // adServerCurrency test
16
+ import {hook} from '../../../src/hook.js';
17
+ import {decorateAdUnitsWithNativeParams} from '../../../src/native.js';
18
+ import {auctionManager} from '../../../src/auctionManager.js';
19
+ import {stubAuctionIndex} from '../../helpers/indexStub.js';
12
20
 
13
21
  let CONFIG = {
14
22
  accountId: '1',
@@ -448,6 +456,16 @@ describe('S2S Adapter', function () {
448
456
  addBidResponse = sinon.spy(),
449
457
  done = sinon.spy();
450
458
 
459
+ function prepRequest(req) {
460
+ req.ad_units.forEach((adUnit) => { delete adUnit.nativeParams });
461
+ decorateAdUnitsWithNativeParams(req.ad_units);
462
+ }
463
+
464
+ before(() => {
465
+ hook.ready();
466
+ prepRequest(REQUEST);
467
+ });
468
+
451
469
  beforeEach(function () {
452
470
  config.resetConfig();
453
471
  adapter = new Adapter();
@@ -1096,6 +1114,7 @@ describe('S2S Adapter', function () {
1096
1114
  it('should not include ext.aspectratios if adunit\'s aspect_ratios do not define radio_width and ratio_height', () => {
1097
1115
  const req = deepClone(REQUEST);
1098
1116
  req.ad_units[0].mediaTypes.native.icon.aspect_ratios[0] = {'min_width': 1, 'min_height': 2};
1117
+ prepRequest(req);
1099
1118
  adapter.callBids(req, BID_REQUESTS, addBidResponse, done, ajax);
1100
1119
  const nativeReq = JSON.parse(JSON.parse(server.requests[0].requestBody).imp[0].native.request);
1101
1120
  const icons = nativeReq.assets.map((a) => a.img).filter((img) => img && img.type === 1);
@@ -2404,11 +2423,8 @@ describe('S2S Adapter', function () {
2404
2423
  });
2405
2424
 
2406
2425
  it('handles OpenRTB native responses', function () {
2407
- sinon.stub(utils, 'getBidRequest').returns({
2408
- adUnitCode: 'div-gpt-ad-1460505748561-0',
2409
- bidder: 'appnexus',
2410
- bidId: '123'
2411
- });
2426
+ const stub = sinon.stub(auctionManager, 'index');
2427
+ stub.get(() => stubAuctionIndex({adUnits: REQUEST.ad_units}));
2412
2428
  const s2sConfig = Object.assign({}, CONFIG, {
2413
2429
  endpoint: {
2414
2430
  p1Consent: 'https://prebidserverurl/openrtb2/auction?querystring=param'
@@ -2431,7 +2447,28 @@ describe('S2S Adapter', function () {
2431
2447
  expect(response).to.have.property('requestId', '123');
2432
2448
  expect(response).to.have.property('cpm', 10);
2433
2449
 
2434
- utils.getBidRequest.restore();
2450
+ stub.restore();
2451
+ });
2452
+
2453
+ it('does not (by default) allow bids that were not requested', function () {
2454
+ config.setConfig({ s2sConfig: CONFIG });
2455
+ adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
2456
+ const response = deepClone(RESPONSE_OPENRTB);
2457
+ response.seatbid[0].seat = 'unknown';
2458
+ server.requests[0].respond(200, {}, JSON.stringify(response));
2459
+
2460
+ expect(addBidResponse.called).to.be.false;
2461
+ });
2462
+
2463
+ it('allows unrequested bids if config.allowUnknownBidderCodes', function () {
2464
+ const cfg = {...CONFIG, allowUnknownBidderCodes: true};
2465
+ config.setConfig({s2sConfig: cfg});
2466
+ adapter.callBids({...REQUEST, s2sConfig: cfg}, BID_REQUESTS, addBidResponse, done, ajax);
2467
+ const response = deepClone(RESPONSE_OPENRTB);
2468
+ response.seatbid[0].seat = 'unknown';
2469
+ server.requests[0].respond(200, {}, JSON.stringify(response));
2470
+
2471
+ expect(addBidResponse.calledWith(sinon.match.any, sinon.match({bidderCode: 'unknown'}))).to.be.true;
2435
2472
  });
2436
2473
 
2437
2474
  describe('on sync requested with no cookie', () => {
@@ -16,6 +16,10 @@ import {
16
16
  } from 'modules/priceFloors.js';
17
17
  import events from 'src/events.js';
18
18
  import * as mockGpt from '../integration/faker/googletag.js';
19
+ import 'src/prebid.js';
20
+ import {createBid} from '../../../src/bidfactory.js';
21
+ import {auctionManager} from '../../../src/auctionManager.js';
22
+ import {stubAuctionIndex} from '../../helpers/indexStub.js';
19
23
 
20
24
  describe('the price floors module', function () {
21
25
  let logErrorSpy;
@@ -109,6 +113,7 @@ describe('the price floors module', function () {
109
113
  bidder: 'rubicon',
110
114
  adUnitCode: 'test_div_1',
111
115
  auctionId: '1234-56-789',
116
+ transactionId: 'tr_test_div_1'
112
117
  };
113
118
 
114
119
  function getAdUnitMock(code = 'adUnit-code') {
@@ -401,6 +406,7 @@ describe('the price floors module', function () {
401
406
  });
402
407
  describe('with gpt enabled', function () {
403
408
  let gptFloorData;
409
+ let indexStub, adUnits;
404
410
  beforeEach(function () {
405
411
  gptFloorData = {
406
412
  currency: 'USD',
@@ -426,10 +432,13 @@ describe('the price floors module', function () {
426
432
  code: '/12345/sports/basketball',
427
433
  divId: 'test_div_2'
428
434
  });
435
+ indexStub = sinon.stub(auctionManager, 'index');
436
+ indexStub.get(() => stubAuctionIndex({adUnits}))
429
437
  });
430
438
  afterEach(function () {
431
439
  // reset it so no lingering stuff from other test specs
432
440
  mockGpt.reset();
441
+ indexStub.restore();
433
442
  });
434
443
  it('picks the right rule when looking for gptSlot', function () {
435
444
  expect(getFirstMatchingFloor(gptFloorData, basicBidRequest)).to.deep.equal({
@@ -449,9 +458,10 @@ describe('the price floors module', function () {
449
458
  matchingRule: '/12345/sports/basketball'
450
459
  });
451
460
  });
452
- it('picks the gptSlot from the bidRequest and does not call the slotMatching', function () {
453
- const newBidRequest1 = { ...basicBidRequest };
454
- utils.deepSetValue(newBidRequest1, 'ortb2Imp.ext.data.adserver', {
461
+ it('picks the gptSlot from the adUnit and does not call the slotMatching', function () {
462
+ const newBidRequest1 = { ...basicBidRequest, transactionId: 'au1' };
463
+ adUnits = [{code: newBidRequest1.code, transactionId: 'au1'}];
464
+ utils.deepSetValue(adUnits[0], 'ortb2Imp.ext.data.adserver', {
455
465
  name: 'gam',
456
466
  adslot: '/12345/news/politics'
457
467
  })
@@ -463,8 +473,9 @@ describe('the price floors module', function () {
463
473
  matchingRule: '/12345/news/politics'
464
474
  });
465
475
 
466
- const newBidRequest2 = { ...basicBidRequest, adUnitCode: 'test_div_2' };
467
- utils.deepSetValue(newBidRequest2, 'ortb2Imp.ext.data.adserver', {
476
+ const newBidRequest2 = { ...basicBidRequest, adUnitCode: 'test_div_2', transactionId: 'au2' };
477
+ adUnits = [{code: newBidRequest2.adUnitCode, transactionId: newBidRequest2.transactionId}];
478
+ utils.deepSetValue(adUnits[0], 'ortb2Imp.ext.data.adserver', {
468
479
  name: 'gam',
469
480
  adslot: '/12345/news/weather'
470
481
  })
@@ -1565,17 +1576,12 @@ describe('the price floors module', function () {
1565
1576
  });
1566
1577
  });
1567
1578
  describe('bidResponseHook tests', function () {
1568
- let returnedBidResponse;
1569
- let bidderRequest = {
1570
- bidderCode: 'appnexus',
1571
- auctionId: '123456',
1572
- bids: [{
1573
- bidder: 'appnexus',
1574
- adUnitCode: 'test_div_1',
1575
- auctionId: '123456',
1576
- bidId: '1111'
1577
- }]
1578
- };
1579
+ const AUCTION_ID = '123456';
1580
+ let returnedBidResponse, indexStub;
1581
+ let adUnit = {
1582
+ transactionId: 'au',
1583
+ code: 'test_div_1'
1584
+ }
1579
1585
  let basicBidResponse = {
1580
1586
  bidderCode: 'appnexus',
1581
1587
  width: 300,
@@ -1583,38 +1589,46 @@ describe('the price floors module', function () {
1583
1589
  cpm: 0.5,
1584
1590
  mediaType: 'banner',
1585
1591
  requestId: '1111',
1592
+ transactionId: 'au',
1586
1593
  };
1587
1594
  beforeEach(function () {
1588
1595
  returnedBidResponse = {};
1596
+ indexStub = sinon.stub(auctionManager, 'index');
1597
+ indexStub.get(() => stubAuctionIndex({adUnits: [adUnit]}));
1598
+ });
1599
+
1600
+ afterEach(() => {
1601
+ indexStub.restore();
1589
1602
  });
1603
+
1590
1604
  function runBidResponse(bidResp = basicBidResponse) {
1591
1605
  let next = (adUnitCode, bid) => {
1592
1606
  returnedBidResponse = bid;
1593
1607
  };
1594
- addBidResponseHook.bind({ bidderRequest })(next, bidResp.adUnitCode, bidResp);
1608
+ addBidResponseHook(next, bidResp.adUnitCode, Object.assign(createBid(CONSTANTS.STATUS.GOOD, {auctionId: AUCTION_ID}), bidResp));
1595
1609
  };
1596
1610
  it('continues with the auction if not floors data is present without any flooring', function () {
1597
1611
  runBidResponse();
1598
1612
  expect(returnedBidResponse).to.not.haveOwnProperty('floorData');
1599
1613
  });
1600
1614
  it('if no matching rule it should not floor and should call log warn', function () {
1601
- _floorDataForAuction[bidderRequest.auctionId] = utils.deepClone(basicFloorConfig);
1602
- _floorDataForAuction[bidderRequest.auctionId].data.values = { 'video': 1.0 };
1615
+ _floorDataForAuction[AUCTION_ID] = utils.deepClone(basicFloorConfig);
1616
+ _floorDataForAuction[AUCTION_ID].data.values = { 'video': 1.0 };
1603
1617
  runBidResponse();
1604
1618
  expect(returnedBidResponse).to.not.haveOwnProperty('floorData');
1605
1619
  expect(logWarnSpy.calledOnce).to.equal(true);
1606
1620
  });
1607
1621
  it('if it finds a rule and floors should update the bid accordingly', function () {
1608
- _floorDataForAuction[bidderRequest.auctionId] = utils.deepClone(basicFloorConfig);
1609
- _floorDataForAuction[bidderRequest.auctionId].data.values = { 'banner': 1.0 };
1622
+ _floorDataForAuction[AUCTION_ID] = utils.deepClone(basicFloorConfig);
1623
+ _floorDataForAuction[AUCTION_ID].data.values = { 'banner': 1.0 };
1610
1624
  runBidResponse();
1611
1625
  expect(returnedBidResponse).to.haveOwnProperty('floorData');
1612
1626
  expect(returnedBidResponse.status).to.equal(CONSTANTS.BID_STATUS.BID_REJECTED);
1613
1627
  expect(returnedBidResponse.cpm).to.equal(0);
1614
1628
  });
1615
1629
  it('if it finds a rule and does not floor should update the bid accordingly', function () {
1616
- _floorDataForAuction[bidderRequest.auctionId] = utils.deepClone(basicFloorConfig);
1617
- _floorDataForAuction[bidderRequest.auctionId].data.values = { 'banner': 0.3 };
1630
+ _floorDataForAuction[AUCTION_ID] = utils.deepClone(basicFloorConfig);
1631
+ _floorDataForAuction[AUCTION_ID].data.values = { 'banner': 0.3 };
1618
1632
  runBidResponse();
1619
1633
  expect(returnedBidResponse).to.haveOwnProperty('floorData');
1620
1634
  expect(returnedBidResponse.floorData).to.deep.equal({
@@ -1636,7 +1650,7 @@ describe('the price floors module', function () {
1636
1650
  expect(returnedBidResponse.cpm).to.equal(0.5);
1637
1651
  });
1638
1652
  it('if should work with more complex rules and update accordingly', function () {
1639
- _floorDataForAuction[bidderRequest.auctionId] = {
1653
+ _floorDataForAuction[AUCTION_ID] = {
1640
1654
  ...basicFloorConfig,
1641
1655
  data: {
1642
1656
  currency: 'USD',
@@ -1722,4 +1736,49 @@ describe('the price floors module', function () {
1722
1736
  expect(_floorDataForAuction[AUCTION_END_EVENT.auctionId]).to.be.undefined;
1723
1737
  });
1724
1738
  });
1739
+
1740
+ describe('fieldMatchingFunctions', () => {
1741
+ let sandbox;
1742
+
1743
+ const req = {
1744
+ ...basicBidRequest,
1745
+ }
1746
+
1747
+ const resp = {
1748
+ transactionId: req.transactionId,
1749
+ size: [100, 100],
1750
+ mediaType: 'banner',
1751
+ }
1752
+
1753
+ beforeEach(() => {
1754
+ sandbox = sinon.sandbox.create();
1755
+ sandbox.stub(auctionManager, 'index').get(() => stubAuctionIndex({
1756
+ adUnits: [
1757
+ {
1758
+ code: req.adUnitCode,
1759
+ transactionId: req.transactionId,
1760
+ ortb2Imp: {ext: {data: {adserver: {name: 'gam', adslot: 'slot'}}}}
1761
+ }
1762
+ ]
1763
+ }));
1764
+ });
1765
+
1766
+ afterEach(() => {
1767
+ sandbox.restore();
1768
+ })
1769
+
1770
+ Object.entries({
1771
+ size: '100x100',
1772
+ mediaType: resp.mediaType,
1773
+ gptSlot: 'slot',
1774
+ domain: 'localhost',
1775
+ adUnitCode: req.adUnitCode,
1776
+ }).forEach(([test, expected]) => {
1777
+ describe(`${test}`, () => {
1778
+ it('should work with only bidResponse', () => {
1779
+ expect(fieldMatchingFunctions[test](undefined, resp)).to.eql(expected)
1780
+ })
1781
+ });
1782
+ })
1783
+ });
1725
1784
  });
@@ -3861,4 +3861,44 @@ describe('PubMatic adapter', function () {
3861
3861
  })
3862
3862
  });
3863
3863
  });
3864
+
3865
+ describe('Video request params', function() {
3866
+ let sandbox, utilsMock, newVideoRequest;
3867
+ beforeEach(() => {
3868
+ utilsMock = sinon.mock(utils);
3869
+ sandbox = sinon.sandbox.create();
3870
+ sandbox.spy(utils, 'logWarn');
3871
+ newVideoRequest = utils.deepClone(videoBidRequests)
3872
+ });
3873
+
3874
+ afterEach(() => {
3875
+ utilsMock.restore();
3876
+ sandbox.restore();
3877
+ })
3878
+
3879
+ it('Should log warning if video params from mediaTypes and params obj of bid are not present', function () {
3880
+ delete newVideoRequest[0].mediaTypes.video;
3881
+ delete newVideoRequest[0].params.video;
3882
+
3883
+ let request = spec.buildRequests(newVideoRequest, {
3884
+ auctionId: 'new-auction-id'
3885
+ });
3886
+
3887
+ sinon.assert.calledOnce(utils.logWarn);
3888
+ expect(request).to.equal(undefined);
3889
+ });
3890
+
3891
+ it('Should consider video params from mediaType object of bid', function () {
3892
+ delete newVideoRequest[0].params.video;
3893
+
3894
+ let request = spec.buildRequests(newVideoRequest, {
3895
+ auctionId: 'new-auction-id'
3896
+ });
3897
+ let data = JSON.parse(request.data);
3898
+ expect(data.imp[0].video).to.exist;
3899
+ expect(data.imp[0]['video']['w']).to.equal(videoBidRequests[0].mediaTypes.video.playerSize[0]);
3900
+ expect(data.imp[0]['video']['h']).to.equal(videoBidRequests[0].mediaTypes.video.playerSize[1]);
3901
+ expect(data.imp[0]['video']['battr']).to.equal(undefined);
3902
+ });
3903
+ });
3864
3904
  });
@@ -3,7 +3,7 @@ import { spec } from 'modules/riseBidAdapter.js';
3
3
  import { newBidder } from 'src/adapters/bidderFactory.js';
4
4
  import { config } from 'src/config.js';
5
5
  import { VIDEO } from '../../../src/mediaTypes.js';
6
- import { deepClone } from 'src/utils.js';
6
+ import * as utils from 'src/utils.js';
7
7
 
8
8
  const ENDPOINT = 'https://hb.yellowblue.io/hb';
9
9
  const TEST_ENDPOINT = 'https://hb.yellowblue.io/hb-test';
@@ -262,7 +262,7 @@ describe('riseAdapter', function () {
262
262
  });
263
263
 
264
264
  it('should set floor_price to getFloor.floor value if it is greater than params.floorPrice', function() {
265
- const bid = deepClone(bidRequests[0]);
265
+ const bid = utils.deepClone(bidRequests[0]);
266
266
  bid.getFloor = () => {
267
267
  return {
268
268
  currency: 'USD',
@@ -276,7 +276,7 @@ describe('riseAdapter', function () {
276
276
  });
277
277
 
278
278
  it('should set floor_price to params.floorPrice value if it is greater than getFloor.floor', function() {
279
- const bid = deepClone(bidRequests[0]);
279
+ const bid = utils.deepClone(bidRequests[0]);
280
280
  bid.getFloor = () => {
281
281
  return {
282
282
  currency: 'USD',
@@ -299,7 +299,8 @@ describe('riseAdapter', function () {
299
299
  requestId: '21e12606d47ba7',
300
300
  netRevenue: true,
301
301
  currency: 'USD',
302
- adomain: ['abc.com']
302
+ adomain: ['abc.com'],
303
+ nurl: 'http://example.com/win/1234',
303
304
  };
304
305
 
305
306
  it('should get correct bid response', function () {
@@ -315,6 +316,7 @@ describe('riseAdapter', function () {
315
316
  ttl: TTL,
316
317
  vastXml: '<VAST version="3.0"></VAST>',
317
318
  mediaType: VIDEO,
319
+ nurl: 'http://example.com/win/1234',
318
320
  meta: {
319
321
  advertiserDomains: ['abc.com']
320
322
  }
@@ -402,4 +404,28 @@ describe('riseAdapter', function () {
402
404
  expect(syncs).to.deep.equal([]);
403
405
  });
404
406
  })
407
+
408
+ describe('onBidWon', function() {
409
+ beforeEach(function() {
410
+ sinon.stub(utils, 'triggerPixel');
411
+ });
412
+ afterEach(function() {
413
+ utils.triggerPixel.restore();
414
+ });
415
+
416
+ it('Should trigger pixel if bid nurl', function() {
417
+ const bid = {
418
+ 'bidder': spec.code,
419
+ 'adUnitCode': 'adunit-code',
420
+ 'sizes': [['640', '480']],
421
+ 'nurl': 'http://example.com/win/1234',
422
+ 'params': {
423
+ 'org': 'jdye8weeyirk00000001'
424
+ }
425
+ };
426
+
427
+ spec.onBidWon(bid);
428
+ expect(utils.triggerPixel.callCount).to.equal(1)
429
+ })
430
+ })
405
431
  });
@@ -246,7 +246,7 @@ const MOCK = {
246
246
  }
247
247
  },
248
248
  BID_REQUESTED: {
249
- 'bidder': 'rubicon',
249
+ 'bidderCode': 'rubicon',
250
250
  'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa',
251
251
  'bidderRequestId': '1be65d7958826a',
252
252
  'bids': [
@@ -384,6 +384,10 @@ const ANALYTICS_MESSAGE = {
384
384
  'referrerHostname': 'www.test.com',
385
385
  'auctions': [
386
386
  {
387
+
388
+ 'auctionEnd': 1519767013781,
389
+ 'auctionStart': 1519767010567,
390
+ 'bidderOrder': ['rubicon'],
387
391
  'requestId': '25c6d7f5-699a-4bfc-87c9-996f915341fa',
388
392
  'clientTimeoutMillis': 3000,
389
393
  'serverTimeoutMillis': 1000,
@@ -853,6 +857,32 @@ describe('rubicon analytics adapter', function () {
853
857
  expect(message).to.deep.equal(ANALYTICS_MESSAGE);
854
858
  });
855
859
 
860
+ it('should pass along bidderOrder correctly', function () {
861
+ const appnexusBid = utils.deepClone(MOCK.BID_REQUESTED);
862
+ appnexusBid.bidderCode = 'appnexus';
863
+ const pubmaticBid = utils.deepClone(MOCK.BID_REQUESTED);
864
+ pubmaticBid.bidderCode = 'pubmatic';
865
+ const indexBid = utils.deepClone(MOCK.BID_REQUESTED);
866
+ indexBid.bidderCode = 'ix';
867
+ events.emit(AUCTION_INIT, MOCK.AUCTION_INIT);
868
+ events.emit(BID_REQUESTED, pubmaticBid);
869
+ events.emit(BID_REQUESTED, MOCK.BID_REQUESTED);
870
+ events.emit(BID_REQUESTED, indexBid);
871
+ events.emit(BID_REQUESTED, appnexusBid);
872
+ events.emit(BIDDER_DONE, MOCK.BIDDER_DONE);
873
+ events.emit(AUCTION_END, MOCK.AUCTION_END);
874
+ events.emit(SET_TARGETING, MOCK.SET_TARGETING);
875
+ clock.tick(SEND_TIMEOUT + 1000);
876
+
877
+ let message = JSON.parse(server.requests[0].requestBody);
878
+ expect(message.auctions[0].bidderOrder).to.deep.equal([
879
+ 'pubmatic',
880
+ 'rubicon',
881
+ 'ix',
882
+ 'appnexus'
883
+ ]);
884
+ });
885
+
856
886
  it('should pass along user ids', function () {
857
887
  let auctionInit = utils.deepClone(MOCK.AUCTION_INIT);
858
888
  auctionInit.bidderRequests[0].bids[0].userId = {
@@ -3262,7 +3262,7 @@ describe('the rubicon adapter', function () {
3262
3262
  label: undefined,
3263
3263
  placement: {
3264
3264
  align: 'left',
3265
- attachTo: '#outstream_video1_placement',
3265
+ attachTo: adUnit,
3266
3266
  position: 'append',
3267
3267
  },
3268
3268
  vastUrl: 'https://test.com/vast.xml',
@@ -148,7 +148,6 @@ describe('Sortable Analytics Adapter', function() {
148
148
  }
149
149
  }
150
150
  });
151
-
152
151
  sortableAnalyticsAdapter.enableAnalytics(initialConfig);
153
152
  });
154
153
 
@@ -203,11 +202,11 @@ describe('Sortable Analytics Adapter', function() {
203
202
  brc: 1,
204
203
  brid: ['10141593b1d84a', '37a8760be6db23'],
205
204
  rs: ['300x250', '728x90'],
206
- btcp: [0.70, 0.50],
205
+ btcp: [0.70, 0.50].map(n => n * 0.95),
207
206
  btcc: 'USD',
208
207
  btin: true,
209
208
  btsrc: 'sortable',
210
- c: [0.70, 0.50],
209
+ c: [0.70, 0.50].map(n => n * 0.95),
211
210
  cc: 'USD',
212
211
  did: null,
213
212
  inr: true,