prebid.js 5.19.0 → 6.2.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 (161) hide show
  1. package/.babelrc.js +1 -10
  2. package/README.md +4 -2
  3. package/browsers.json +13 -37
  4. package/gulpfile.js +1 -0
  5. package/karma.conf.maker.js +1 -1
  6. package/modules/adheseBidAdapter.js +7 -2
  7. package/modules/adkernelBidAdapter.js +1 -0
  8. package/modules/adlivetechBidAdapter.md +61 -0
  9. package/modules/admixerBidAdapter.js +2 -1
  10. package/modules/adnuntiusBidAdapter.js +2 -1
  11. package/modules/adomikAnalyticsAdapter.js +10 -4
  12. package/modules/adplusBidAdapter.js +203 -0
  13. package/modules/adplusBidAdapter.md +39 -0
  14. package/modules/adyoulikeBidAdapter.js +7 -2
  15. package/modules/airgridRtdProvider.js +1 -1
  16. package/modules/appnexusBidAdapter.js +28 -5
  17. package/modules/atsAnalyticsAdapter.js +67 -46
  18. package/modules/atsAnalyticsAdapter.md +1 -0
  19. package/modules/beachfrontBidAdapter.js +14 -17
  20. package/modules/betweenBidAdapter.js +2 -1
  21. package/modules/browsiRtdProvider.js +106 -18
  22. package/modules/cleanioRtdProvider.js +192 -0
  23. package/modules/cleanioRtdProvider.md +59 -0
  24. package/modules/codefuelBidAdapter.js +1 -3
  25. package/modules/codefuelBidAdapter.md +3 -3
  26. package/modules/craftBidAdapter.js +5 -3
  27. package/modules/datablocksBidAdapter.js +3 -3
  28. package/modules/dchain.js +149 -0
  29. package/modules/dchain.md +45 -0
  30. package/modules/deepintentBidAdapter.js +1 -1
  31. package/modules/deltaprojectsBidAdapter.js +252 -0
  32. package/modules/deltaprojectsBidAdapter.md +32 -0
  33. package/modules/emx_digitalBidAdapter.js +9 -1
  34. package/modules/engageyaBidAdapter.js +68 -54
  35. package/modules/freewheel-sspBidAdapter.js +6 -0
  36. package/modules/glimpseBidAdapter.js +31 -16
  37. package/modules/goldbachBidAdapter.js +1176 -0
  38. package/modules/goldbachBidAdapter.md +151 -0
  39. package/modules/gptPreAuction.js +11 -5
  40. package/modules/gridBidAdapter.js +1 -0
  41. package/modules/gumgumBidAdapter.js +5 -1
  42. package/modules/id5IdSystem.md +6 -6
  43. package/modules/imRtdProvider.js +31 -0
  44. package/modules/intersectionRtdProvider.js +114 -0
  45. package/modules/invibesBidAdapter.js +15 -9
  46. package/modules/ipromBidAdapter.js +79 -0
  47. package/modules/ixBidAdapter.js +173 -22
  48. package/modules/jixieBidAdapter.js +8 -2
  49. package/modules/justpremiumBidAdapter.js +6 -1
  50. package/modules/limelightDigitalBidAdapter.js +2 -1
  51. package/modules/livewrappedAnalyticsAdapter.js +5 -0
  52. package/modules/luponmediaBidAdapter.js +570 -0
  53. package/modules/merkleIdSystem.js +5 -0
  54. package/modules/missenaBidAdapter.js +89 -0
  55. package/modules/multibid/index.js +3 -3
  56. package/modules/nativoBidAdapter.js +32 -2
  57. package/modules/oguryBidAdapter.js +2 -1
  58. package/modules/openxBidAdapter.js +7 -2
  59. package/modules/operaadsBidAdapter.js +21 -1
  60. package/modules/otmBidAdapter.js +146 -0
  61. package/modules/otmBidAdapter.md +27 -26
  62. package/modules/outbrainBidAdapter.js +5 -0
  63. package/modules/playwireBidAdapter.md +61 -0
  64. package/modules/prebidServerBidAdapter/index.js +3 -3
  65. package/modules/pubmaticBidAdapter.js +5 -3
  66. package/modules/relaidoBidAdapter.js +86 -65
  67. package/modules/richaudienceBidAdapter.js +1 -1
  68. package/modules/rtdModule/index.js +2 -2
  69. package/modules/saambaaBidAdapter.js +420 -0
  70. package/modules/saambaaBidAdapter.md +65 -68
  71. package/modules/seedtagBidAdapter.js +6 -0
  72. package/modules/smaatoBidAdapter.js +9 -1
  73. package/modules/smartxBidAdapter.js +17 -1
  74. package/modules/sonobiBidAdapter.js +7 -0
  75. package/modules/sortableBidAdapter.js +1 -0
  76. package/modules/sspBCBidAdapter.js +34 -3
  77. package/modules/tappxBidAdapter.js +3 -1
  78. package/modules/teadsBidAdapter.js +3 -0
  79. package/modules/trustxBidAdapter.js +18 -7
  80. package/modules/undertoneBidAdapter.js +8 -1
  81. package/modules/userId/index.js +27 -2
  82. package/modules/ventes.md +71 -0
  83. package/modules/ventesBidAdapter.js +410 -0
  84. package/modules/ventesBidAdapter.md +93 -0
  85. package/modules/vidoomyBidAdapter.js +51 -100
  86. package/modules/visxBidAdapter.js +20 -3
  87. package/modules/visxBidAdapter.md +4 -6
  88. package/modules/yahoosspBidAdapter.js +6 -6
  89. package/modules/yahoosspBidAdapter.md +1 -1
  90. package/modules/yieldlabBidAdapter.js +41 -10
  91. package/modules/yieldlabBidAdapter.md +91 -48
  92. package/modules/yieldoneBidAdapter.js +115 -11
  93. package/package.json +6 -1
  94. package/src/adapterManager.js +14 -8
  95. package/src/auction.js +14 -13
  96. package/src/targeting.js +2 -2
  97. package/src/utils.js +7 -0
  98. package/test/spec/integration/faker/googletag.js +6 -0
  99. package/test/spec/modules/adheseBidAdapter_spec.js +27 -1
  100. package/test/spec/modules/adnuntiusBidAdapter_spec.js +18 -0
  101. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
  102. package/test/spec/modules/adplusBidAdapter_spec.js +213 -0
  103. package/test/spec/modules/adyoulikeBidAdapter_spec.js +26 -0
  104. package/test/spec/modules/appnexusBidAdapter_spec.js +65 -2
  105. package/test/spec/modules/atsAnalyticsAdapter_spec.js +42 -9
  106. package/test/spec/modules/beachfrontBidAdapter_spec.js +65 -1
  107. package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
  108. package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
  109. package/test/spec/modules/codefuelBidAdapter_spec.js +1 -1
  110. package/test/spec/modules/datablocksBidAdapter_spec.js +3 -3
  111. package/test/spec/modules/dchain_spec.js +329 -0
  112. package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
  113. package/test/spec/modules/emx_digitalBidAdapter_spec.js +10 -0
  114. package/test/spec/modules/engageyaBidAdapter_spec.js +231 -95
  115. package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
  116. package/test/spec/modules/freewheel-sspBidAdapter_spec.js +19 -0
  117. package/test/spec/modules/glimpseBidAdapter_spec.js +33 -0
  118. package/test/spec/modules/goldbachBidAdapter_spec.js +1359 -0
  119. package/test/spec/modules/gptPreAuction_spec.js +58 -4
  120. package/test/spec/modules/gumgumBidAdapter_spec.js +6 -0
  121. package/test/spec/modules/imRtdProvider_spec.js +25 -0
  122. package/test/spec/modules/intersectionRtdProvider_spec.js +141 -0
  123. package/test/spec/modules/invibesBidAdapter_spec.js +29 -4
  124. package/test/spec/modules/ipromBidAdapter_spec.js +195 -0
  125. package/test/spec/modules/ixBidAdapter_spec.js +288 -5
  126. package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
  127. package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
  128. package/test/spec/modules/konduitWrapper_spec.js +0 -1
  129. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +10 -7
  130. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +23 -4
  131. package/test/spec/modules/luponmediaBidAdapter_spec.js +412 -0
  132. package/test/spec/modules/merkleIdSystem_spec.js +18 -0
  133. package/test/spec/modules/missenaBidAdapter_spec.js +134 -0
  134. package/test/spec/modules/multibid_spec.js +31 -31
  135. package/test/spec/modules/nativoBidAdapter_spec.js +35 -18
  136. package/test/spec/modules/oguryBidAdapter_spec.js +13 -11
  137. package/test/spec/modules/openxBidAdapter_spec.js +5 -26
  138. package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
  139. package/test/spec/modules/otmBidAdapter_spec.js +67 -0
  140. package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
  141. package/test/spec/modules/prebidServerBidAdapter_spec.js +19 -2
  142. package/test/spec/modules/pubmaticBidAdapter_spec.js +1 -1
  143. package/test/spec/modules/relaidoBidAdapter_spec.js +71 -63
  144. package/test/spec/modules/seedtagBidAdapter_spec.js +3 -0
  145. package/test/spec/modules/smaatoBidAdapter_spec.js +61 -0
  146. package/test/spec/modules/smartxBidAdapter_spec.js +9 -0
  147. package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
  148. package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
  149. package/test/spec/modules/sspBCBidAdapter_spec.js +33 -3
  150. package/test/spec/modules/tappxBidAdapter_spec.js +4 -0
  151. package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
  152. package/test/spec/modules/trustxBidAdapter_spec.js +45 -3
  153. package/test/spec/modules/userId_spec.js +51 -0
  154. package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
  155. package/test/spec/modules/vidoomyBidAdapter_spec.js +32 -13
  156. package/test/spec/modules/visxBidAdapter_spec.js +121 -5
  157. package/test/spec/modules/yieldlabBidAdapter_spec.js +81 -0
  158. package/test/spec/modules/yieldoneBidAdapter_spec.js +299 -53
  159. package/test/spec/unit/core/adapterManager_spec.js +26 -7
  160. package/test/spec/unit/core/targeting_spec.js +44 -0
  161. package/wdio.conf.js +1 -1
package/src/auction.js CHANGED
@@ -59,7 +59,7 @@
59
59
 
60
60
  import {
61
61
  flatten, timestamp, adUnitsFilter, deepAccess, getBidRequest, getValue, parseUrl, generateUUID,
62
- logMessage, bind, logError, logInfo, logWarn, isEmpty, _each, isFn, isEmptyStr
62
+ logMessage, bind, logError, logInfo, logWarn, isEmpty, _each, isFn, isEmptyStr, isAllowZeroCpmBidsEnabled
63
63
  } from './utils.js';
64
64
  import { getPriceBucketString } from './cpmBucketManager.js';
65
65
  import { getNativeTargeting } from './native.js';
@@ -567,7 +567,8 @@ function getPreparedBidForAuction({adUnitCode, bid, bidderRequest, auctionId}) {
567
567
 
568
568
  function setupBidTargeting(bidObject, bidderRequest) {
569
569
  let keyValues;
570
- if (bidObject.bidderCode && (bidObject.cpm > 0 || bidObject.dealId)) {
570
+ const cpmCheck = (isAllowZeroCpmBidsEnabled(bidObject.bidderCode)) ? bidObject.cpm >= 0 : bidObject.cpm > 0;
571
+ if (bidObject.bidderCode && (cpmCheck || bidObject.dealId)) {
571
572
  let bidReq = find(bidderRequest.bids, bid => bid.adUnitCode === bidObject.adUnitCode);
572
573
  keyValues = getKeyValueTargetingPairs(bidObject.bidderCode, bidObject, bidReq);
573
574
  }
@@ -613,7 +614,8 @@ export const getPriceGranularity = (mediaType, bidReq) => {
613
614
  * @returns {function}
614
615
  */
615
616
  export const getPriceByGranularity = (granularity) => {
616
- return (bid) => {
617
+ return (bid, bidReq) => {
618
+ granularity = granularity || getPriceGranularity(bid.mediaType, bidReq);
617
619
  if (granularity === CONSTANTS.GRANULARITY_OPTIONS.AUTO) {
618
620
  return bid.pbAg;
619
621
  } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.DENSE) {
@@ -646,14 +648,14 @@ export const getAdvertiserDomain = () => {
646
648
  * @param {BidRequest} bidReq
647
649
  * @returns {*}
648
650
  */
649
- export function getStandardBidderSettings(mediaType, bidderCode, bidReq) {
651
+ export function getStandardBidderSettings(mediaType, bidderCode) {
650
652
  // factory for key value objs
651
653
  function createKeyVal(key, value) {
652
654
  return {
653
655
  key,
654
656
  val: (typeof value === 'function')
655
- ? function (bidResponse) {
656
- return value(bidResponse);
657
+ ? function (bidResponse, bidReq) {
658
+ return value(bidResponse, bidReq);
657
659
  }
658
660
  : function (bidResponse) {
659
661
  return getValue(bidResponse, value);
@@ -661,7 +663,6 @@ export function getStandardBidderSettings(mediaType, bidderCode, bidReq) {
661
663
  };
662
664
  }
663
665
  const TARGETING_KEYS = CONSTANTS.TARGETING_KEYS;
664
- const granularity = getPriceGranularity(mediaType, bidReq);
665
666
 
666
667
  let bidderSettings = $$PREBID_GLOBAL$$.bidderSettings;
667
668
  if (!bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD]) {
@@ -671,7 +672,7 @@ export function getStandardBidderSettings(mediaType, bidderCode, bidReq) {
671
672
  bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING] = [
672
673
  createKeyVal(TARGETING_KEYS.BIDDER, 'bidderCode'),
673
674
  createKeyVal(TARGETING_KEYS.AD_ID, 'adId'),
674
- createKeyVal(TARGETING_KEYS.PRICE_BUCKET, getPriceByGranularity(granularity)),
675
+ createKeyVal(TARGETING_KEYS.PRICE_BUCKET, getPriceByGranularity()),
675
676
  createKeyVal(TARGETING_KEYS.SIZE, 'size'),
676
677
  createKeyVal(TARGETING_KEYS.DEAL, 'dealId'),
677
678
  createKeyVal(TARGETING_KEYS.SOURCE, 'source'),
@@ -716,12 +717,12 @@ export function getKeyValueTargetingPairs(bidderCode, custBidObj, bidReq) {
716
717
  // 1) set the keys from "standard" setting or from prebid defaults
717
718
  if (bidderSettings) {
718
719
  // initialize default if not set
719
- const standardSettings = getStandardBidderSettings(custBidObj.mediaType, bidderCode, bidReq);
720
- setKeys(keyValues, standardSettings, custBidObj);
720
+ const standardSettings = getStandardBidderSettings(custBidObj.mediaType, bidderCode);
721
+ setKeys(keyValues, standardSettings, custBidObj, bidReq);
721
722
 
722
723
  // 2) set keys from specific bidder setting override if they exist
723
724
  if (bidderCode && bidderSettings[bidderCode] && bidderSettings[bidderCode][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]) {
724
- setKeys(keyValues, bidderSettings[bidderCode], custBidObj);
725
+ setKeys(keyValues, bidderSettings[bidderCode], custBidObj, bidReq);
725
726
  custBidObj.sendStandardTargeting = bidderSettings[bidderCode].sendStandardTargeting;
726
727
  }
727
728
  }
@@ -734,7 +735,7 @@ export function getKeyValueTargetingPairs(bidderCode, custBidObj, bidReq) {
734
735
  return keyValues;
735
736
  }
736
737
 
737
- function setKeys(keyValues, bidderSettings, custBidObj) {
738
+ function setKeys(keyValues, bidderSettings, custBidObj, bidReq) {
738
739
  var targeting = bidderSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING];
739
740
  custBidObj.size = custBidObj.getSize();
740
741
 
@@ -748,7 +749,7 @@ function setKeys(keyValues, bidderSettings, custBidObj) {
748
749
 
749
750
  if (isFn(value)) {
750
751
  try {
751
- value = value(custBidObj);
752
+ value = value(custBidObj, bidReq);
752
753
  } catch (e) {
753
754
  logError('bidmanager', 'ERROR', e);
754
755
  }
package/src/targeting.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  uniques, isGptPubadsDefined, getHighestCpm, getOldestHighestCpmBid, groupBy, isAdUnitCodeMatchingSlot, timestamp,
3
- deepAccess, deepClone, logError, logWarn, logInfo, isFn, isArray, logMessage, isStr
3
+ deepAccess, deepClone, logError, logWarn, logInfo, isFn, isArray, logMessage, isStr, isAllowZeroCpmBidsEnabled
4
4
  } from './utils.js';
5
5
  import { config } from './config.js';
6
6
  import { NATIVE_TARGETING_KEYS } from './native.js';
@@ -438,7 +438,7 @@ export function newTargeting(auctionManager) {
438
438
  const adUnitCodes = getAdUnitCodes(adUnitCode);
439
439
  return bidsReceived
440
440
  .filter(bid => includes(adUnitCodes, bid.adUnitCode))
441
- .filter(bid => bid.cpm > 0)
441
+ .filter(bid => (isAllowZeroCpmBidsEnabled(bid.bidderCode)) ? bid.cpm >= 0 : bid.cpm > 0)
442
442
  .map(bid => bid.adUnitCode)
443
443
  .filter(uniques)
444
444
  .map(adUnitCode => bidsReceived
package/src/utils.js CHANGED
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable no-console */
2
2
  import { config } from './config.js';
3
+ import { getGlobal } from './prebidGlobal.js';
3
4
  import clone from 'just-clone';
4
5
  import find from 'core-js-pure/features/array/find.js';
5
6
  import includes from 'core-js-pure/features/array/includes.js';
@@ -1294,3 +1295,9 @@ export function cyrb53Hash(str, seed = 0) {
1294
1295
  h2 = imul(h2 ^ (h2 >>> 16), 2246822507) ^ imul(h1 ^ (h1 >>> 13), 3266489909);
1295
1296
  return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString();
1296
1297
  }
1298
+
1299
+ export function isAllowZeroCpmBidsEnabled(bidderCode) {
1300
+ const bidderSettings = getGlobal().bidderSettings;
1301
+ return ((bidderSettings[bidderCode] && bidderSettings[bidderCode].allowZeroCpmBids === true) ||
1302
+ (bidderSettings.standard && bidderSettings.standard.allowZeroCpmBids === true));
1303
+ }
@@ -51,9 +51,15 @@ export function enable() {
51
51
  window.googletag = {
52
52
  _slots: [],
53
53
  _callbackMap: {},
54
+ _ppid: undefined,
55
+ cmd: [],
54
56
  pubads: function () {
55
57
  var self = this;
56
58
  return {
59
+ setPublisherProvidedId: function (ppid) {
60
+ self._ppid = ppid;
61
+ },
62
+
57
63
  getSlots: function () {
58
64
  return self._slots;
59
65
  },
@@ -1,5 +1,6 @@
1
1
  import {expect} from 'chai';
2
2
  import {spec} from 'modules/adheseBidAdapter.js';
3
+ import {config} from 'src/config.js';
3
4
 
4
5
  const BID_ID = 456;
5
6
  const TTL = 360;
@@ -131,12 +132,21 @@ describe('AdheseAdapter', function () {
131
132
  expect(JSON.parse(req.data)).to.not.have.key('eids');
132
133
  });
133
134
 
134
- it('should request vast content as url', function () {
135
+ it('should request vast content as url by default', function () {
135
136
  let req = spec.buildRequests([ minimalBid() ], bidderRequest);
136
137
 
137
138
  expect(JSON.parse(req.data).vastContentAsUrl).to.equal(true);
138
139
  });
139
140
 
141
+ it('should request vast content as markup when configured', function () {
142
+ sinon.stub(config, 'getConfig').withArgs('adhese').returns({ vastContentAsUrl: false });
143
+
144
+ let req = spec.buildRequests([ minimalBid() ], bidderRequest);
145
+
146
+ expect(JSON.parse(req.data).vastContentAsUrl).to.equal(false);
147
+ config.getConfig.restore();
148
+ });
149
+
140
150
  it('should include bids', function () {
141
151
  let bid = minimalBid();
142
152
  let req = spec.buildRequests([ bid ], bidderRequest);
@@ -155,6 +165,22 @@ describe('AdheseAdapter', function () {
155
165
 
156
166
  expect(req.url).to.equal('https://ads-demo.adhese.com/json');
157
167
  });
168
+
169
+ it('should include params specified in the config', function () {
170
+ sinon.stub(config, 'getConfig').withArgs('adhese').returns({ globalTargets: { 'tl': [ 'all' ] } });
171
+ let req = spec.buildRequests([ minimalBid() ], bidderRequest);
172
+
173
+ expect(JSON.parse(req.data).parameters).to.deep.include({ 'tl': [ 'all' ] });
174
+ config.getConfig.restore();
175
+ });
176
+
177
+ it('should give priority to bid params over config params', function () {
178
+ sinon.stub(config, 'getConfig').withArgs('adhese').returns({ globalTargets: { 'xt': ['CONFIG_CONSENT_STRING'] } });
179
+ let req = spec.buildRequests([ minimalBid() ], bidderRequest);
180
+
181
+ expect(JSON.parse(req.data).parameters).to.deep.include({ 'xt': [ 'CONSENT_STRING' ] });
182
+ config.getConfig.restore();
183
+ });
158
184
  });
159
185
 
160
186
  describe('interpretResponse', () => {
@@ -251,6 +251,24 @@ describe('adnuntiusBidAdapter', function () {
251
251
  expect(request[0]).to.have.property('url')
252
252
  expect(request[0].url).to.equal(ENDPOINT_URL_SEGMENTS);
253
253
  });
254
+
255
+ it('should user user ID if present in ortb2.user.id field', function () {
256
+ config.setBidderConfig({
257
+ bidders: ['adnuntius', 'other'],
258
+ config: {
259
+ ortb2: {
260
+ user: {
261
+ id: usi
262
+ }
263
+ }
264
+ }
265
+ });
266
+
267
+ const request = config.runWithBidder('adnuntius', () => spec.buildRequests(bidRequests));
268
+ expect(request.length).to.equal(1);
269
+ expect(request[0]).to.have.property('url')
270
+ expect(request[0].url).to.equal(ENDPOINT_URL);
271
+ });
254
272
  });
255
273
 
256
274
  describe('user privacy', function () {
@@ -1,5 +1,6 @@
1
1
  import adomikAnalytics from 'modules/adomikAnalyticsAdapter.js';
2
2
  import {expect} from 'chai';
3
+
3
4
  let events = require('src/events');
4
5
  let adapterManager = require('src/adapterManager').default;
5
6
  let constants = require('src/constants.json');
@@ -8,6 +9,7 @@ describe('Adomik Prebid Analytic', function () {
8
9
  let sendEventStub;
9
10
  let sendWonEventStub;
10
11
  let clock;
12
+
11
13
  before(function () {
12
14
  clock = sinon.useFakeTimers();
13
15
  });
@@ -91,7 +93,7 @@ describe('Adomik Prebid Analytic', function () {
91
93
  type: 'request',
92
94
  event: {
93
95
  bidder: 'BIDDERTEST',
94
- placementCode: 'placementtest',
96
+ placementCode: '0000',
95
97
  }
96
98
  });
97
99
 
@@ -0,0 +1,213 @@
1
+ import {expect} from 'chai';
2
+ import {spec, BIDDER_CODE, ADPLUS_ENDPOINT, } from 'modules/adplusBidAdapter.js';
3
+ import {newBidder} from 'src/adapters/bidderFactory.js';
4
+
5
+ describe('AplusBidAdapter', function () {
6
+ const adapter = newBidder(spec);
7
+
8
+ describe('inherited functions', function () {
9
+ it('exists and is a function', function () {
10
+ expect(adapter.callBids).to.be.exist.and.to.be.a('function');
11
+ });
12
+ });
13
+
14
+ describe('isBidRequestValid', function () {
15
+ it('should return true when required params found', function () {
16
+ let validRequest = {
17
+ mediaTypes: {
18
+ banner: {
19
+ sizes: [[300, 250]]
20
+ }
21
+ },
22
+ params: {
23
+ inventoryId: '30',
24
+ adUnitId: '1',
25
+ }
26
+ };
27
+ expect(spec.isBidRequestValid(validRequest)).to.equal(true);
28
+ });
29
+
30
+ it('should return false when required params are not passed', function () {
31
+ let validRequest = {
32
+ mediaTypes: {
33
+ banner: {
34
+ sizes: [[300, 250]]
35
+ }
36
+ },
37
+ params: {
38
+ inventoryId: '30',
39
+ }
40
+ };
41
+ expect(spec.isBidRequestValid(validRequest)).to.equal(false);
42
+ });
43
+
44
+ it('should return false when required param types are wrong', function () {
45
+ let validRequest = {
46
+ mediaTypes: {
47
+ banner: {
48
+ sizes: [[300, 250]]
49
+ }
50
+ },
51
+ params: {
52
+ inventoryId: 30,
53
+ adUnitId: '1',
54
+ }
55
+ };
56
+ expect(spec.isBidRequestValid(validRequest)).to.equal(false);
57
+ });
58
+
59
+ it('should return false when size is not exists', function () {
60
+ let validRequest = {
61
+ params: {
62
+ inventoryId: 30,
63
+ adUnitId: '1',
64
+ }
65
+ };
66
+ expect(spec.isBidRequestValid(validRequest)).to.equal(false);
67
+ });
68
+
69
+ it('should return false when size is wrong', function () {
70
+ let validRequest = {
71
+ mediaTypes: {
72
+ banner: {
73
+ sizes: [[300]]
74
+ }
75
+ },
76
+ params: {
77
+ inventoryId: 30,
78
+ adUnitId: '1',
79
+ }
80
+ };
81
+ expect(spec.isBidRequestValid(validRequest)).to.equal(false);
82
+ });
83
+ });
84
+
85
+ describe('buildRequests', function () {
86
+ let validRequest = [
87
+ {
88
+ bidder: BIDDER_CODE,
89
+ mediaTypes: {
90
+ banner: {
91
+ sizes: [[300, 250]]
92
+ }
93
+ },
94
+ params: {
95
+ inventoryId: '-1',
96
+ adUnitId: '-3',
97
+ },
98
+ bidId: '2bdcb0b203c17d'
99
+ },
100
+ ];
101
+
102
+ let bidderRequest = {
103
+ refererInfo: {
104
+ referer: 'https://test.domain'
105
+ }
106
+ };
107
+
108
+ it('bidRequest HTTP method', function () {
109
+ const request = spec.buildRequests(validRequest, bidderRequest);
110
+ expect(request[0].method).to.equal('GET');
111
+ });
112
+
113
+ it('bidRequest url', function () {
114
+ const request = spec.buildRequests(validRequest, bidderRequest);
115
+ expect(request[0].url).to.equal(ADPLUS_ENDPOINT);
116
+ });
117
+
118
+ it('tests bidRequest data is clean and has the right values', function () {
119
+ const request = spec.buildRequests(validRequest, bidderRequest);
120
+
121
+ expect(request[0].data.bidId).to.equal('2bdcb0b203c17d');
122
+ expect(request[0].data.inventoryId).to.equal('-1');
123
+ expect(request[0].data.adUnitId).to.equal('-3');
124
+ expect(request[0].data.adUnitWidth).to.equal(300);
125
+ expect(request[0].data.adUnitHeight).to.equal(250);
126
+ expect(request[0].data.sdkVersion).to.equal('1');
127
+ expect(typeof request[0].data.session).to.equal('string');
128
+ expect(request[0].data.session).length(36);
129
+ expect(request[0].data.interstitial).to.equal(0);
130
+ expect(request[0].data).to.not.have.deep.property('extraData');
131
+ expect(request[0].data).to.not.have.deep.property('yearOfBirth');
132
+ expect(request[0].data).to.not.have.deep.property('gender');
133
+ expect(request[0].data).to.not.have.deep.property('categories');
134
+ expect(request[0].data).to.not.have.deep.property('latitude');
135
+ expect(request[0].data).to.not.have.deep.property('longitude');
136
+ });
137
+ });
138
+
139
+ describe('interpretResponse', function () {
140
+ const requestData = {
141
+ language: window.navigator.language,
142
+ screenWidth: 1440,
143
+ screenHeight: 900,
144
+ sdkVersion: '1',
145
+ inventoryId: '-1',
146
+ adUnitId: '-3',
147
+ adUnitWidth: 300,
148
+ adUnitHeight: 250,
149
+ domain: 'tassandigi.com',
150
+ pageUrl: 'https%3A%2F%2Ftassandigi.com%2Fserafettin%2Fads.html',
151
+ interstitial: 0,
152
+ session: '1c02db03-5289-932a-93af-7b4022611fec',
153
+ token: '1c02db03-5289-937a-93df-7b4022611fec',
154
+ secure: 1,
155
+ bidId: '2bdcb0b203c17d',
156
+ };
157
+ const bidRequest = {
158
+ 'method': 'GET',
159
+ 'url': ADPLUS_ENDPOINT,
160
+ 'data': requestData,
161
+ };
162
+
163
+ const bidResponse = {
164
+ body: [
165
+ {
166
+ 'ad': '<div>ad</div>',
167
+ 'advertiserDomains': [
168
+ 'advertiser.com'
169
+ ],
170
+ 'categoryIDs': [
171
+ 'IAB-111'
172
+ ],
173
+ 'cpm': 3.57,
174
+ 'creativeID': '1',
175
+ 'currency': 'TRY',
176
+ 'dealID': '1',
177
+ 'height': 300,
178
+ 'mediaType': 'banner',
179
+ 'netRevenue': true,
180
+ 'requestID': '2bdcb0b203c17d',
181
+ 'ttl': 300,
182
+ 'width': 250
183
+ }
184
+ ],
185
+ headers: {}
186
+ };
187
+
188
+ const emptyBidResponse = {
189
+ body: null,
190
+ };
191
+
192
+ it('returns an empty array when the result body is not valid', function () {
193
+ const result = spec.interpretResponse(emptyBidResponse, bidRequest);
194
+ expect(result).to.deep.equal([]);
195
+ });
196
+
197
+ it('result is correct', function () {
198
+ const result = spec.interpretResponse(bidResponse, bidRequest);
199
+ expect(result[0].requestId).to.equal('2bdcb0b203c17d');
200
+ expect(result[0].cpm).to.equal(3.57);
201
+ expect(result[0].width).to.equal(250);
202
+ expect(result[0].height).to.equal(300);
203
+ expect(result[0].creativeId).to.equal('1');
204
+ expect(result[0].currency).to.equal('TRY');
205
+ expect(result[0].dealId).to.equal('1');
206
+ expect(result[0].mediaType).to.equal('banner');
207
+ expect(result[0].netRevenue).to.equal(true);
208
+ expect(result[0].ttl).to.equal(300);
209
+ expect(result[0].meta.advertiserDomains).to.deep.equal(['advertiser.com']);
210
+ expect(result[0].meta.secondaryCatIds).to.deep.equal(['IAB-111']);
211
+ });
212
+ });
213
+ });
@@ -590,6 +590,32 @@ describe('Adyoulike Adapter', function () {
590
590
  expect(payload.gdprConsent.consentRequired).to.be.null;
591
591
  });
592
592
 
593
+ it('should add userid eids information to the request', function () {
594
+ let bidderRequest = {
595
+ 'auctionId': '1d1a030790a475',
596
+ 'bidderRequestId': '22edbae2733bf6',
597
+ 'timeout': 3000,
598
+ 'userId': {
599
+ pubcid: '01EAJWWNEPN3CYMM5N8M5VXY22',
600
+ unsuported: '666'
601
+ }
602
+ };
603
+
604
+ bidderRequest.bids = bidRequestWithSinglePlacement;
605
+
606
+ const request = spec.buildRequests(bidRequestWithSinglePlacement, bidderRequest);
607
+ const payload = JSON.parse(request.data);
608
+
609
+ expect(payload.userId).to.exist;
610
+ expect(payload.userId).to.deep.equal([{
611
+ 'source': 'pubcid.org',
612
+ 'uids': [{
613
+ 'atype': 1,
614
+ 'id': '01EAJWWNEPN3CYMM5N8M5VXY22'
615
+ }]
616
+ }]);
617
+ });
618
+
593
619
  it('sends bid request to endpoint with single placement', function () {
594
620
  const request = spec.buildRequests(bidRequestWithSinglePlacement, bidderRequest);
595
621
  const payload = JSON.parse(request.data);
@@ -1004,12 +1004,16 @@ describe('AppNexusAdapter', function () {
1004
1004
 
1005
1005
  describe('interpretResponse', function () {
1006
1006
  let bfStub;
1007
+ let bidderSettingsStorage;
1008
+
1007
1009
  before(function() {
1008
1010
  bfStub = sinon.stub(bidderFactory, 'getIabSubCategory');
1011
+ bidderSettingsStorage = $$PREBID_GLOBAL$$.bidderSettings;
1009
1012
  });
1010
1013
 
1011
1014
  after(function() {
1012
1015
  bfStub.restore();
1016
+ $$PREBID_GLOBAL$$.bidderSettings = bidderSettingsStorage;
1013
1017
  });
1014
1018
 
1015
1019
  let response = {
@@ -1047,7 +1051,8 @@ describe('AppNexusAdapter', function () {
1047
1051
  'trackers': [
1048
1052
  {
1049
1053
  'impression_urls': [
1050
- 'https://lax1-ib.adnxs.com/impression'
1054
+ 'https://lax1-ib.adnxs.com/impression',
1055
+ 'https://www.test.com/tracker'
1051
1056
  ],
1052
1057
  'video_events': {}
1053
1058
  }
@@ -1076,6 +1081,15 @@ describe('AppNexusAdapter', function () {
1076
1081
  'adUnitCode': 'code',
1077
1082
  'appnexus': {
1078
1083
  'buyerMemberId': 958
1084
+ },
1085
+ 'meta': {
1086
+ 'dchain': {
1087
+ 'ver': '1.0',
1088
+ 'complete': 0,
1089
+ 'nodes': [{
1090
+ 'bsid': '958'
1091
+ }]
1092
+ }
1079
1093
  }
1080
1094
  }
1081
1095
  ];
@@ -1084,11 +1098,46 @@ describe('AppNexusAdapter', function () {
1084
1098
  bidId: '3db3773286ee59',
1085
1099
  adUnitCode: 'code'
1086
1100
  }]
1087
- }
1101
+ };
1088
1102
  let result = spec.interpretResponse({ body: response }, {bidderRequest});
1089
1103
  expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0]));
1090
1104
  });
1091
1105
 
1106
+ it('should reject 0 cpm bids', function () {
1107
+ let zeroCpmResponse = deepClone(response);
1108
+ zeroCpmResponse.tags[0].ads[0].cpm = 0;
1109
+
1110
+ let bidderRequest = {
1111
+ bidderCode: 'appnexus'
1112
+ };
1113
+
1114
+ let result = spec.interpretResponse({ body: zeroCpmResponse }, { bidderRequest });
1115
+ expect(result.length).to.equal(0);
1116
+ });
1117
+
1118
+ it('should allow 0 cpm bids if allowZeroCpmBids setConfig is true', function () {
1119
+ $$PREBID_GLOBAL$$.bidderSettings = {
1120
+ appnexus: {
1121
+ allowZeroCpmBids: true
1122
+ }
1123
+ };
1124
+
1125
+ let zeroCpmResponse = deepClone(response);
1126
+ zeroCpmResponse.tags[0].ads[0].cpm = 0;
1127
+
1128
+ let bidderRequest = {
1129
+ bidderCode: 'appnexus',
1130
+ bids: [{
1131
+ bidId: '3db3773286ee59',
1132
+ adUnitCode: 'code'
1133
+ }]
1134
+ };
1135
+
1136
+ let result = spec.interpretResponse({ body: zeroCpmResponse }, { bidderRequest });
1137
+ expect(result.length).to.equal(1);
1138
+ expect(result[0].cpm).to.equal(0);
1139
+ });
1140
+
1092
1141
  it('handles nobid responses', function () {
1093
1142
  let response = {
1094
1143
  'version': '0.0.1',
@@ -1334,6 +1383,20 @@ describe('AppNexusAdapter', function () {
1334
1383
  expect(Object.keys(result[0].meta)).to.include.members(['advertiserId']);
1335
1384
  });
1336
1385
 
1386
+ it('should add brand id', function() {
1387
+ let responseBrandId = deepClone(response);
1388
+ responseBrandId.tags[0].ads[0].brand_id = 123;
1389
+
1390
+ let bidderRequest = {
1391
+ bids: [{
1392
+ bidId: '3db3773286ee59',
1393
+ adUnitCode: 'code'
1394
+ }]
1395
+ }
1396
+ let result = spec.interpretResponse({ body: responseBrandId }, {bidderRequest});
1397
+ expect(Object.keys(result[0].meta)).to.include.members(['brandId']);
1398
+ });
1399
+
1337
1400
  it('should add advertiserDomains', function() {
1338
1401
  let responseAdvertiserId = deepClone(response);
1339
1402
  responseAdvertiserId.tags[0].ads[0].adomain = ['123'];