prebid.js 6.0.0 → 6.1.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 (61) hide show
  1. package/.babelrc.js +1 -7
  2. package/gulpfile.js +1 -0
  3. package/modules/adheseBidAdapter.js +7 -2
  4. package/modules/adkernelBidAdapter.js +1 -0
  5. package/modules/adlivetechBidAdapter.md +61 -0
  6. package/modules/adomikAnalyticsAdapter.js +10 -4
  7. package/modules/appnexusBidAdapter.js +4 -0
  8. package/modules/codefuelBidAdapter.js +1 -3
  9. package/modules/codefuelBidAdapter.md +3 -3
  10. package/modules/datablocksBidAdapter.js +3 -3
  11. package/modules/deepintentBidAdapter.js +1 -1
  12. package/modules/engageyaBidAdapter.js +68 -54
  13. package/modules/glimpseBidAdapter.js +31 -16
  14. package/modules/gptPreAuction.js +11 -5
  15. package/modules/gridBidAdapter.js +1 -1
  16. package/modules/id5IdSystem.md +6 -6
  17. package/modules/imRtdProvider.js +31 -0
  18. package/modules/ixBidAdapter.js +166 -21
  19. package/modules/merkleIdSystem.js +5 -0
  20. package/modules/nativoBidAdapter.js +27 -1
  21. package/modules/oguryBidAdapter.js +2 -1
  22. package/modules/openxBidAdapter.js +6 -1
  23. package/modules/prebidServerBidAdapter/index.js +3 -3
  24. package/modules/pubmaticBidAdapter.js +2 -0
  25. package/modules/saambaaBidAdapter.js +420 -0
  26. package/modules/saambaaBidAdapter.md +65 -68
  27. package/modules/seedtagBidAdapter.js +6 -0
  28. package/modules/smaatoBidAdapter.js +6 -1
  29. package/modules/sspBCBidAdapter.js +34 -3
  30. package/modules/trustxBidAdapter.js +10 -1
  31. package/modules/vidoomyBidAdapter.js +51 -100
  32. package/modules/visxBidAdapter.js +1 -1
  33. package/modules/yieldlabBidAdapter.js +41 -10
  34. package/modules/yieldlabBidAdapter.md +91 -48
  35. package/package.json +6 -1
  36. package/src/adapterManager.js +14 -8
  37. package/test/spec/modules/adheseBidAdapter_spec.js +27 -1
  38. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
  39. package/test/spec/modules/appnexusBidAdapter_spec.js +14 -0
  40. package/test/spec/modules/codefuelBidAdapter_spec.js +1 -1
  41. package/test/spec/modules/datablocksBidAdapter_spec.js +3 -3
  42. package/test/spec/modules/engageyaBidAdapter_spec.js +231 -95
  43. package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
  44. package/test/spec/modules/glimpseBidAdapter_spec.js +33 -0
  45. package/test/spec/modules/gptPreAuction_spec.js +58 -4
  46. package/test/spec/modules/imRtdProvider_spec.js +25 -0
  47. package/test/spec/modules/ixBidAdapter_spec.js +285 -2
  48. package/test/spec/modules/konduitWrapper_spec.js +0 -1
  49. package/test/spec/modules/merkleIdSystem_spec.js +18 -0
  50. package/test/spec/modules/nativoBidAdapter_spec.js +35 -18
  51. package/test/spec/modules/oguryBidAdapter_spec.js +13 -11
  52. package/test/spec/modules/openxBidAdapter_spec.js +5 -0
  53. package/test/spec/modules/prebidServerBidAdapter_spec.js +19 -2
  54. package/test/spec/modules/seedtagBidAdapter_spec.js +3 -0
  55. package/test/spec/modules/smaatoBidAdapter_spec.js +30 -0
  56. package/test/spec/modules/sspBCBidAdapter_spec.js +33 -3
  57. package/test/spec/modules/trustxBidAdapter_spec.js +42 -0
  58. package/test/spec/modules/vidoomyBidAdapter_spec.js +32 -13
  59. package/test/spec/modules/visxBidAdapter_spec.js +1 -1
  60. package/test/spec/modules/yieldlabBidAdapter_spec.js +81 -0
  61. package/test/spec/unit/core/adapterManager_spec.js +24 -6
@@ -518,6 +518,33 @@ describe('SSPBC adapter', function () {
518
518
  expect(payload.user).to.be.an('object').and.to.have.property('[ortb_extensions.consent]', bidRequest.gdprConsent.consentString);
519
519
  });
520
520
 
521
+ it('should send net info and pvid', function () {
522
+ expect(payload.user).to.be.an('object').and.to.have.property('data').that.is.an('array');
523
+
524
+ const userData = payload.user.data;
525
+ expect(userData.length).to.equal(2);
526
+
527
+ const netInfo = userData[0];
528
+ expect(netInfo.id).to.equal('12');
529
+ expect(netInfo.name).to.equal('NetInfo');
530
+ expect(netInfo).to.have.property('segment').that.is.an('array');
531
+
532
+ const pvid = userData[1];
533
+ expect(pvid.id).to.equal('7');
534
+ expect(pvid.name).to.equal('pvid');
535
+ expect(pvid).to.have.property('segment').that.is.an('array');
536
+ expect(pvid.segment[0]).to.have.property('value');
537
+ });
538
+
539
+ it('pvid should be constant on a single page view', function () {
540
+ const userData1 = payload.user.data;
541
+ const userData2 = payloadNative.user.data;
542
+ const pvid1 = userData1[1];
543
+ const pvid2 = userData2[1];
544
+
545
+ expect(pvid1.segment[0].value).to.equal(pvid2.segment[0].value);
546
+ });
547
+
521
548
  it('should build correct native payload', function () {
522
549
  const nativeAssets = payloadNative.imp && payloadNative.imp[0].native.request;
523
550
 
@@ -543,13 +570,16 @@ describe('SSPBC adapter', function () {
543
570
  expect(videoAssets).to.have.property('api').that.is.an('array');
544
571
  });
545
572
 
546
- it('should create auxilary placement identifier (size_numUsed)', function () {
573
+ it('should create auxilary placement identifier (size_numUsed), that is constant for a given adUnit', function () {
547
574
  const extAssets1 = payload.imp && payload.imp[0].ext.data;
548
575
  const extAssets2 = payloadSingle.imp && payloadSingle.imp[0].ext.data;
549
576
 
550
- // note that payload comes from first, and payloadSingle from second auction in the test run
577
+ /*
578
+ note that payload comes from first, and payloadSingle from second auction in the test run
579
+ also, since both have same adUnitName, value of pbsize property should be the same
580
+ */
551
581
  expect(extAssets1).to.have.property('pbsize').that.equals('750x200_1')
552
- expect(extAssets2).to.have.property('pbsize').that.equals('750x200_2')
582
+ expect(extAssets2).to.have.property('pbsize').that.equals('750x200_1')
553
583
  });
554
584
  });
555
585
 
@@ -519,6 +519,48 @@ describe('TrustXAdapter', function () {
519
519
  expect(payload.tmax).to.equal(3000);
520
520
  getConfigStub.restore();
521
521
  });
522
+ it('should contain imp[].ext.data.adserver if available', function() {
523
+ const ortb2Imp = [{
524
+ ext: {
525
+ data: {
526
+ adserver: {
527
+ name: 'ad_server_name',
528
+ adslot: '/111111/slot'
529
+ },
530
+ pbadslot: '/111111/slot'
531
+ }
532
+ }
533
+ }, {
534
+ ext: {
535
+ data: {
536
+ adserver: {
537
+ name: 'ad_server_name',
538
+ adslot: '/222222/slot'
539
+ },
540
+ pbadslot: '/222222/slot'
541
+ }
542
+ }
543
+ }];
544
+ const bidRequestsWithOrtb2Imp = bidRequests.slice(0, 3).map((bid, ind) => {
545
+ return Object.assign(ortb2Imp[ind] ? { ortb2Imp: ortb2Imp[ind] } : {}, bid);
546
+ });
547
+ const request = spec.buildRequests(bidRequestsWithOrtb2Imp, bidderRequest);
548
+ expect(request.data).to.be.an('string');
549
+ const payload = parseRequest(request.data);
550
+ expect(payload.imp[0].ext).to.deep.equal({
551
+ divid: bidRequests[0].adUnitCode,
552
+ data: ortb2Imp[0].ext.data,
553
+ gpid: ortb2Imp[0].ext.data.adserver.adslot
554
+ });
555
+ expect(payload.imp[1].ext).to.deep.equal({
556
+ divid: bidRequests[1].adUnitCode,
557
+ data: ortb2Imp[1].ext.data,
558
+ gpid: ortb2Imp[1].ext.data.adserver.adslot
559
+ });
560
+ expect(payload.imp[2].ext).to.deep.equal({
561
+ divid: bidRequests[2].adUnitCode
562
+ });
563
+ });
522
564
  it('all id like request fields must be a string', function () {
523
565
  const bidderRequestWithNumId = Object.assign({}, bidderRequest, { bidderRequestId: 123123, auctionId: 345345543 });
524
566
 
@@ -4,6 +4,7 @@ import { newBidder } from 'src/adapters/bidderFactory.js';
4
4
  import { INSTREAM } from '../../../src/video';
5
5
 
6
6
  const ENDPOINT = `https://d.vidoomy.com/api/rtbserver/prebid/`;
7
+ const PIXELS = ['/test.png', '/test2.png?gdpr={{GDPR}}&gdpr_consent={{GDPR_CONSENT}}']
7
8
 
8
9
  describe('vidoomyBidAdapter', function() {
9
10
  const adapter = newBidder(spec);
@@ -101,24 +102,24 @@ describe('vidoomyBidAdapter', function() {
101
102
  });
102
103
 
103
104
  it('attaches source and version to endpoint URL as query params', function () {
104
- expect(request[0].url).to.include(ENDPOINT);
105
- expect(request[1].url).to.include(ENDPOINT);
105
+ expect(request[0].url).to.equal(ENDPOINT);
106
+ expect(request[1].url).to.equal(ENDPOINT);
106
107
  });
107
108
 
108
109
  it('only accepts first width and height sizes', function () {
109
- expect(request[0].url).to.include('w=300');
110
- expect(request[0].url).to.include('h=250');
111
- expect(request[0].url).to.not.include('w=200');
112
- expect(request[0].url).to.not.include('h=100');
113
- expect(request[1].url).to.include('w=400');
114
- expect(request[1].url).to.include('h=225');
110
+ expect('' + request[0].data.w).to.equal('300');
111
+ expect('' + request[0].data.h).to.equal('250');
112
+ expect('' + request[0].data.w).to.not.equal('200');
113
+ expect('' + request[0].data.h).to.not.equal('100');
114
+ expect('' + request[1].data.w).to.equal('400');
115
+ expect('' + request[1].data.h).to.equal('225');
115
116
  });
116
117
 
117
118
  it('should send id and pid parameters', function () {
118
- expect(request[0].url).to.include('id=123123');
119
- expect(request[0].url).to.include('pid=123123');
120
- expect(request[1].url).to.include('id=456456');
121
- expect(request[1].url).to.include('pid=456456');
119
+ expect('' + request[0].data.id).to.equal('123123');
120
+ expect('' + request[0].data.pid).to.equal('123123');
121
+ expect('' + request[1].data.id).to.equal('456456');
122
+ expect('' + request[1].data.pid).to.equal('456456');
122
123
  });
123
124
  });
124
125
 
@@ -182,7 +183,8 @@ describe('vidoomyBidAdapter', function() {
182
183
  'networkName': null,
183
184
  'primaryCatId': 'IAB3-1',
184
185
  'secondaryCatIds': null
185
- }
186
+ },
187
+ 'pixels': PIXELS
186
188
  }
187
189
  }
188
190
 
@@ -206,5 +208,22 @@ describe('vidoomyBidAdapter', function() {
206
208
 
207
209
  expect(result[0].requestId).to.equal(serverResponseBanner.body.requestId);
208
210
  });
211
+
212
+ it('should sync user cookies', function () {
213
+ const GDPR_CONSENT = 'GDPR_TEST'
214
+ const result = spec.getUserSyncs({
215
+ pixelEnabled: true
216
+ }, [serverResponseBanner], { consentString: GDPR_CONSENT, gdprApplies: 1 }, null)
217
+ expect(result).to.eql([
218
+ {
219
+ type: 'image',
220
+ url: PIXELS[0]
221
+ },
222
+ {
223
+ type: 'image',
224
+ url: `/test2.png?gdpr=1&gdpr_consent=${GDPR_CONSENT}`
225
+ }
226
+ ])
227
+ });
209
228
  });
210
229
  });
@@ -1149,7 +1149,7 @@ describe('VisxAdapter', function () {
1149
1149
  it('onTimeout', function () {
1150
1150
  const data = { timeout: 3000, bidId: '23423', params: { uid: 1 } };
1151
1151
  spec.onTimeout(data);
1152
- expect(utils.triggerPixel.calledOnceWith('https://t.visx.net/track/bid_timeout?data=' + JSON.stringify(data))).to.equal(true);
1152
+ expect(utils.triggerPixel.calledOnceWith('https://t.visx.net/track/bid_timeout//' + JSON.stringify(data))).to.equal(true);
1153
1153
  });
1154
1154
  });
1155
1155
 
@@ -73,6 +73,12 @@ const VIDEO_REQUEST = Object.assign({}, REQUEST, {
73
73
  }
74
74
  })
75
75
 
76
+ const NATIVE_REQUEST = Object.assign({}, REQUEST, {
77
+ 'mediaTypes': {
78
+ 'native': { }
79
+ }
80
+ })
81
+
76
82
  const RESPONSE = {
77
83
  advertiser: 'yieldlab',
78
84
  curl: 'https://www.yieldlab.de',
@@ -84,6 +90,42 @@ const RESPONSE = {
84
90
  adtype: 'BANNER'
85
91
  }
86
92
 
93
+ const NATIVE_RESPONSE = Object.assign({}, RESPONSE, {
94
+ 'adtype': 'NATIVE',
95
+ 'native': {
96
+ 'link': {
97
+ 'url': 'https://www.yieldlab.de'
98
+ },
99
+ 'assets': [
100
+ {
101
+ 'id': 1,
102
+ 'title': {
103
+ 'text': 'This is a great headline'
104
+ }
105
+ },
106
+ {
107
+ 'id': 2,
108
+ 'img': {
109
+ 'url': 'https://localhost:8080/yl-logo100x100.jpg',
110
+ 'w': 100,
111
+ 'h': 100
112
+ }
113
+ },
114
+ {
115
+ 'id': 3,
116
+ 'data': {
117
+ 'value': 'Native body value'
118
+ }
119
+ }
120
+ ],
121
+ 'imptrackers': [
122
+ 'http://localhost:8080/ve?d=ODE9ZSY2MTI1MjAzNjMzMzYxPXN0JjA0NWUwZDk0NTY5Yi05M2FiLWUwZTQtOWFjNy1hYWY0MzFiZj1kaXQmMj12',
123
+ 'http://localhost:8080/md/1111/9efa4e76-2030-4f04-bb9f-322541f8d611?mdata=false&pvid=false&ids=x:1',
124
+ 'http://localhost:8080/imp?s=13216&d=2171514&a=12548955&ts=1633363025216&tid=fb134faa-7ca9-4e0e-ba39-b96549d0e540&l=0'
125
+ ]
126
+ }
127
+ })
128
+
87
129
  const VIDEO_RESPONSE = Object.assign({}, RESPONSE, {
88
130
  'adtype': 'VIDEO'
89
131
  })
@@ -297,6 +339,45 @@ describe('yieldlabBidAdapter', function () {
297
339
  expect(result[0].vastUrl).to.include('&id=abc')
298
340
  })
299
341
 
342
+ it('should add adUrl and native assets when type is Native', function () {
343
+ const result = spec.interpretResponse({body: [NATIVE_RESPONSE]}, {validBidRequests: [NATIVE_REQUEST], queryParams: REQPARAMS})
344
+
345
+ expect(result[0].requestId).to.equal('2d925f27f5079f')
346
+ expect(result[0].cpm).to.equal(0.01)
347
+ expect(result[0].mediaType).to.equal('native')
348
+ expect(result[0].adUrl).to.include('https://ad.yieldlab.net/d/1111/2222/?ts=')
349
+ expect(result[0].native.title).to.equal('This is a great headline')
350
+ expect(result[0].native.body).to.equal('Native body value')
351
+ expect(result[0].native.image.url).to.equal('https://localhost:8080/yl-logo100x100.jpg')
352
+ expect(result[0].native.image.width).to.equal(100)
353
+ expect(result[0].native.image.height).to.equal(100)
354
+ expect(result[0].native.clickUrl).to.equal('https://www.yieldlab.de')
355
+ expect(result[0].native.impressionTrackers.length).to.equal(3)
356
+ })
357
+
358
+ it('should add adUrl and default native assets when type is Native', function () {
359
+ const NATIVE_RESPONSE_2 = Object.assign({}, NATIVE_RESPONSE, {
360
+ 'native': {
361
+ 'link': {
362
+ 'url': 'https://www.yieldlab.de'
363
+ },
364
+ 'assets': [],
365
+ 'imptrackers': []
366
+ }
367
+ })
368
+ const result = spec.interpretResponse({body: [NATIVE_RESPONSE_2]}, {validBidRequests: [NATIVE_REQUEST], queryParams: REQPARAMS})
369
+
370
+ expect(result[0].requestId).to.equal('2d925f27f5079f')
371
+ expect(result[0].cpm).to.equal(0.01)
372
+ expect(result[0].mediaType).to.equal('native')
373
+ expect(result[0].adUrl).to.include('https://ad.yieldlab.net/d/1111/2222/?ts=')
374
+ expect(result[0].native.title).to.equal('')
375
+ expect(result[0].native.body).to.equal('')
376
+ expect(result[0].native.image.url).to.equal('')
377
+ expect(result[0].native.image.width).to.equal(0)
378
+ expect(result[0].native.image.height).to.equal(0)
379
+ })
380
+
300
381
  it('should append gdpr parameters to vastUrl', function () {
301
382
  const result = spec.interpretResponse({body: [VIDEO_RESPONSE]}, {validBidRequests: [VIDEO_REQUEST], queryParams: REQPARAMS_GDPR})
302
383
 
@@ -162,7 +162,7 @@ describe('adapterManager tests', function () {
162
162
  'bidderCode': 'appnexus',
163
163
  'auctionId': '1863e370099523',
164
164
  'bidderRequestId': '2946b569352ef2',
165
- 'tid': '34566b569352ef2',
165
+ 'uniquePbsTid': '34566b569352ef2',
166
166
  'bids': [
167
167
  {
168
168
  'bidder': 'appnexus',
@@ -479,7 +479,7 @@ describe('adapterManager tests', function () {
479
479
  'bidderCode': 'appnexus',
480
480
  'auctionId': '1863e370099523',
481
481
  'bidderRequestId': '2946b569352ef2',
482
- 'tid': '34566b569352ef2',
482
+ 'uniquePbsTid': '34566b569352ef2',
483
483
  'timeout': 1000,
484
484
  'src': 's2s',
485
485
  'adUnitsS2SCopy': [
@@ -708,7 +708,7 @@ describe('adapterManager tests', function () {
708
708
  'bidderCode': 'appnexus',
709
709
  'auctionId': '1863e370099523',
710
710
  'bidderRequestId': '2946b569352ef2',
711
- 'tid': '34566b569352ef2',
711
+ 'uniquePbsTid': '34566b569352ef2',
712
712
  'timeout': 1000,
713
713
  'src': 's2s',
714
714
  'adUnitsS2SCopy': [
@@ -844,7 +844,7 @@ describe('adapterManager tests', function () {
844
844
  'bidderCode': 'pubmatic',
845
845
  'auctionId': '1863e370099523',
846
846
  'bidderRequestId': '2946b569352ef2',
847
- 'tid': '2342342342lfi23',
847
+ 'uniquePbsTid': '2342342342lfi23',
848
848
  'timeout': 1000,
849
849
  'src': 's2s',
850
850
  'adUnitsS2SCopy': [
@@ -1041,6 +1041,21 @@ describe('adapterManager tests', function () {
1041
1041
  sinon.assert.calledTwice(prebidServerAdapterMock.callBids);
1042
1042
  });
1043
1043
 
1044
+ it('should have one tid for ALL s2s bidRequests', function () {
1045
+ let adUnits = utils.deepClone(getAdUnits()).map(adUnit => {
1046
+ adUnit.bids = adUnit.bids.filter(bid => includes(['appnexus', 'pubmatic'], bid.bidder));
1047
+ return adUnit;
1048
+ })
1049
+ let bidRequests = adapterManager.makeBidRequests(adUnits, 1111, 2222, 1000);
1050
+ adapterManager.callBids(adUnits, bidRequests, () => {}, () => {});
1051
+ sinon.assert.calledTwice(prebidServerAdapterMock.callBids);
1052
+ const firstBid = prebidServerAdapterMock.callBids.firstCall.args[0];
1053
+ const secondBid = prebidServerAdapterMock.callBids.secondCall.args[0];
1054
+
1055
+ // TIDS should be the same
1056
+ expect(firstBid.tid).to.equal(secondBid.tid);
1057
+ });
1058
+
1044
1059
  it('should fire for simultaneous s2s and client requests', function () {
1045
1060
  adapterManager.bidderRegistry['adequant'] = adequantAdapterMock;
1046
1061
  let adUnits = utils.deepClone(getAdUnits()).map(adUnit => {
@@ -1697,14 +1712,17 @@ describe('adapterManager tests', function () {
1697
1712
  });
1698
1713
 
1699
1714
  describe('sizeMapping', function () {
1715
+ let sandbox;
1700
1716
  beforeEach(function () {
1717
+ sandbox = sinon.sandbox.create();
1701
1718
  allS2SBidders.length = 0;
1702
1719
  clientTestAdapters.length = 0;
1703
- sinon.stub(window, 'matchMedia').callsFake(() => ({matches: true}));
1720
+ // always have matchMedia return true for us
1721
+ sandbox.stub(utils.getWindowTop(), 'matchMedia').callsFake(() => ({matches: true}));
1704
1722
  });
1705
1723
 
1706
1724
  afterEach(function () {
1707
- matchMedia.restore();
1725
+ sandbox.restore();
1708
1726
  config.resetConfig();
1709
1727
  setSizeConfig([]);
1710
1728
  });