prebid.js 5.18.0 → 5.20.2

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 (114) hide show
  1. package/browsers.json +1 -0
  2. package/integrationExamples/gpt/akamaidap_segments_example.html +132 -0
  3. package/modules/.submodules.json +1 -0
  4. package/modules/adfBidAdapter.js +21 -16
  5. package/modules/adtelligentBidAdapter.js +2 -1
  6. package/modules/adxcgBidAdapter.js +311 -359
  7. package/modules/airgridRtdProvider.js +1 -1
  8. package/modules/akamaiDapRtdProvider.js +474 -0
  9. package/modules/akamaiDapRtdProvider.md +47 -0
  10. package/modules/appnexusBidAdapter.js +9 -3
  11. package/modules/atsAnalyticsAdapter.js +67 -46
  12. package/modules/atsAnalyticsAdapter.md +1 -0
  13. package/modules/betweenBidAdapter.js +20 -3
  14. package/modules/browsiRtdProvider.js +106 -18
  15. package/modules/cleanioRtdProvider.js +192 -0
  16. package/modules/cleanioRtdProvider.md +59 -0
  17. package/modules/codefuelBidAdapter.js +183 -0
  18. package/modules/codefuelBidAdapter.md +111 -0
  19. package/modules/connectIdSystem.js +104 -0
  20. package/modules/connectIdSystem.md +33 -0
  21. package/modules/deepintentBidAdapter.js +106 -9
  22. package/modules/deepintentBidAdapter.md +36 -1
  23. package/modules/deltaprojectsBidAdapter.js +252 -0
  24. package/modules/deltaprojectsBidAdapter.md +32 -0
  25. package/modules/engageyaBidAdapter.js +157 -0
  26. package/modules/gridBidAdapter.js +1 -0
  27. package/modules/gumgumBidAdapter.js +8 -0
  28. package/modules/inskinBidAdapter.js +7 -3
  29. package/modules/ipromBidAdapter.js +79 -0
  30. package/modules/ixBidAdapter.js +8 -1
  31. package/modules/jixieBidAdapter.js +8 -2
  32. package/modules/justpremiumBidAdapter.js +6 -1
  33. package/modules/kinessoIdSystem.js +1 -1
  34. package/modules/limelightDigitalBidAdapter.js +22 -2
  35. package/modules/livewrappedAnalyticsAdapter.js +49 -1
  36. package/modules/multibid/index.js +3 -3
  37. package/modules/nativoBidAdapter.js +5 -1
  38. package/modules/nextMillenniumBidAdapter.js +12 -3
  39. package/modules/oguryBidAdapter.js +14 -1
  40. package/modules/openxBidAdapter.js +34 -22
  41. package/modules/operaadsBidAdapter.js +21 -1
  42. package/modules/otmBidAdapter.js +146 -0
  43. package/modules/otmBidAdapter.md +27 -26
  44. package/modules/outbrainBidAdapter.js +5 -0
  45. package/modules/playwireBidAdapter.md +61 -0
  46. package/modules/publinkIdSystem.js +11 -6
  47. package/modules/rtdModule/index.js +2 -2
  48. package/modules/sonobiBidAdapter.js +7 -0
  49. package/modules/sortableBidAdapter.js +1 -0
  50. package/modules/teadsBidAdapter.js +3 -0
  51. package/modules/tripleliftBidAdapter.js +22 -5
  52. package/modules/trustxBidAdapter.js +8 -6
  53. package/modules/undertoneBidAdapter.js +9 -5
  54. package/modules/undertoneBidAdapter.md +5 -1
  55. package/modules/userId/eids.js +18 -0
  56. package/modules/userId/eids.md +7 -0
  57. package/modules/userId/userId.md +12 -0
  58. package/modules/ventesBidAdapter.js +370 -0
  59. package/modules/ventesBidAdapter.md +94 -0
  60. package/modules/videobyteBidAdapter.js +13 -6
  61. package/modules/videobyteBidAdapter.md +49 -0
  62. package/modules/yahoosspBidAdapter.js +6 -6
  63. package/modules/yieldmoSyntheticInventoryModule.js +46 -0
  64. package/modules/yieldmoSyntheticInventoryModule.md +68 -0
  65. package/package.json +1 -1
  66. package/src/adapterManager.js +5 -0
  67. package/src/adapters/bidderFactory.js +4 -3
  68. package/src/auction.js +11 -11
  69. package/src/constants.json +1 -0
  70. package/src/secureCreatives.js +6 -7
  71. package/src/targeting.js +11 -9
  72. package/test/spec/modules/adfBidAdapter_spec.js +83 -29
  73. package/test/spec/modules/adtelligentBidAdapter_spec.js +1 -0
  74. package/test/spec/modules/adxcgBidAdapter_spec.js +827 -571
  75. package/test/spec/modules/akamaiDapRtdProvider_spec.js +246 -0
  76. package/test/spec/modules/appnexusBidAdapter_spec.js +16 -1
  77. package/test/spec/modules/atsAnalyticsAdapter_spec.js +42 -9
  78. package/test/spec/modules/betweenBidAdapter_spec.js +41 -0
  79. package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
  80. package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
  81. package/test/spec/modules/codefuelBidAdapter_spec.js +316 -0
  82. package/test/spec/modules/connectIdSystem_spec.js +189 -0
  83. package/test/spec/modules/deepintentBidAdapter_spec.js +153 -3
  84. package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
  85. package/test/spec/modules/engageyaBidAdapter_spec.js +286 -0
  86. package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
  87. package/test/spec/modules/gumgumBidAdapter_spec.js +5 -1
  88. package/test/spec/modules/ipromBidAdapter_spec.js +195 -0
  89. package/test/spec/modules/ixBidAdapter_spec.js +13 -3
  90. package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
  91. package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
  92. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +155 -1
  93. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +52 -7
  94. package/test/spec/modules/multibid_spec.js +31 -31
  95. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +13 -1
  96. package/test/spec/modules/oguryBidAdapter_spec.js +53 -12
  97. package/test/spec/modules/openxBidAdapter_spec.js +85 -13
  98. package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
  99. package/test/spec/modules/otmBidAdapter_spec.js +67 -0
  100. package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
  101. package/test/spec/modules/publinkIdSystem_spec.js +6 -6
  102. package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
  103. package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
  104. package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
  105. package/test/spec/modules/tripleliftBidAdapter_spec.js +128 -0
  106. package/test/spec/modules/trustxBidAdapter_spec.js +3 -3
  107. package/test/spec/modules/undertoneBidAdapter_spec.js +52 -0
  108. package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
  109. package/test/spec/modules/videobyteBidAdapter_spec.js +2 -2
  110. package/test/spec/modules/yieldmoSyntheticInventoryModule_spec.js +89 -0
  111. package/test/spec/unit/core/adapterManager_spec.js +37 -2
  112. package/test/spec/unit/core/bidderFactory_spec.js +61 -1
  113. package/test/spec/unit/pbjs_api_spec.js +37 -2
  114. package/test/spec/unit/secureCreatives_spec.js +54 -25
@@ -0,0 +1,67 @@
1
+ import {expect} from 'chai';
2
+ import {spec} from 'modules/otmBidAdapter';
3
+
4
+ describe('otmBidAdapter', function () {
5
+ it('validate_pub_params', function () {
6
+ expect(spec.isBidRequestValid({
7
+ bidder: 'otm',
8
+ params: {
9
+ tid: '123',
10
+ bidfloor: 20
11
+ }
12
+ })).to.equal(true);
13
+ });
14
+
15
+ it('validate_generated_params', function () {
16
+ let bidRequestData = [{
17
+ bidId: 'bid1234',
18
+ bidder: 'otm',
19
+ params: {
20
+ tid: '123',
21
+ bidfloor: 20
22
+ },
23
+ sizes: [[240, 400]]
24
+ }];
25
+
26
+ let request = spec.buildRequests(bidRequestData);
27
+ let req_data = request[0].data;
28
+
29
+ expect(req_data.bidid).to.equal('bid1234');
30
+ });
31
+
32
+ it('validate_response_params', function () {
33
+ let bidRequestData = {
34
+ data: {
35
+ bidId: 'bid1234'
36
+ }
37
+ };
38
+
39
+ let serverResponse = {
40
+ body: [
41
+ {
42
+ 'auctionid': '3c6f8e22-541b-485c-9214-e974d9fb1b6f',
43
+ 'cpm': 847.097,
44
+ 'ad': '<html><body>test html</body></html>',
45
+ 'w': 240,
46
+ 'h': 400,
47
+ 'currency': 'RUB',
48
+ 'ttl': 300,
49
+ 'creativeid': '1_7869053',
50
+ 'bidid': '101f211def7c99',
51
+ 'transactionid': 'transaction_id_1'
52
+ }
53
+ ]
54
+ };
55
+
56
+ let bids = spec.interpretResponse(serverResponse, bidRequestData);
57
+ expect(bids).to.have.lengthOf(1);
58
+ let bid = bids[0];
59
+ expect(bid.cpm).to.equal(847.097);
60
+ expect(bid.currency).to.equal('RUB');
61
+ expect(bid.width).to.equal(240);
62
+ expect(bid.height).to.equal(400);
63
+ expect(bid.netRevenue).to.equal(true);
64
+ expect(bid.requestId).to.equal('101f211def7c99');
65
+ expect(bid.ad).to.equal('<html><body>test html</body></html>');
66
+ });
67
+ });
@@ -2,6 +2,7 @@ import {expect} from 'chai';
2
2
  import {spec} from 'modules/outbrainBidAdapter.js';
3
3
  import {config} from 'src/config.js';
4
4
  import {server} from 'test/mocks/xhr';
5
+ import { createEidsArray } from 'modules/userId/eids.js';
5
6
 
6
7
  describe('Outbrain Adapter', function () {
7
8
  describe('Bid request and response', function () {
@@ -344,6 +345,23 @@ describe('Outbrain Adapter', function () {
344
345
 
345
346
  config.resetConfig()
346
347
  });
348
+
349
+ it('should pass extended ids', function () {
350
+ let bidRequest = {
351
+ bidId: 'bidId',
352
+ params: {},
353
+ userIdAsEids: createEidsArray({
354
+ idl_env: 'id-value',
355
+ }),
356
+ ...commonBidRequest,
357
+ };
358
+
359
+ let res = spec.buildRequests([bidRequest], commonBidderRequest);
360
+ const resData = JSON.parse(res.data)
361
+ expect(resData.user.ext.eids).to.deep.equal([
362
+ {source: 'liveramp.com', uids: [{id: 'id-value', atype: 3}]}
363
+ ]);
364
+ });
347
365
  })
348
366
 
349
367
  describe('interpretResponse', function () {
@@ -47,12 +47,6 @@ describe('PublinkIdSystem', () => {
47
47
  expect(result.id).to.equal(LOCAL_VALUE.publink);
48
48
  storage.removeDataFromLocalStorage(PUBLINK_COOKIE);
49
49
  });
50
- it('ignore expired cookie', () => {
51
- storage.setDataInLocalStorage(PUBLINK_COOKIE, JSON.stringify({publink: 'value', exp: Date.now() - 60 * 60 * 24 * 1000}));
52
- const result = publinkIdSubmodule.getId();
53
- expect(result.id).to.be.undefined;
54
- storage.removeDataFromLocalStorage(PUBLINK_COOKIE);
55
- });
56
50
  it('priority goes to publink_srv cookie', () => {
57
51
  storage.setCookie(PUBLINK_SRV_COOKIE, JSON.stringify(COOKIE_VALUE), COOKIE_EXPIRATION);
58
52
  storage.setDataInLocalStorage(PUBLINK_COOKIE, JSON.stringify(LOCAL_VALUE));
@@ -61,6 +55,12 @@ describe('PublinkIdSystem', () => {
61
55
  storage.setCookie(PUBLINK_SRV_COOKIE, '', DELETE_COOKIE);
62
56
  storage.removeDataFromLocalStorage(PUBLINK_COOKIE);
63
57
  });
58
+ it('publink non-json cookie', () => {
59
+ storage.setCookie(PUBLINK_COOKIE, COOKIE_VALUE.publink, COOKIE_EXPIRATION);
60
+ const result = publinkIdSubmodule.getId();
61
+ expect(result.id).to.equal(COOKIE_VALUE.publink);
62
+ storage.setCookie(PUBLINK_COOKIE, '', DELETE_COOKIE);
63
+ });
64
64
  });
65
65
 
66
66
  describe('getId', () => {
@@ -238,14 +238,17 @@ describe('SonobiBidAdapter', function () {
238
238
  });
239
239
 
240
240
  describe('.buildRequests', function () {
241
+ let sandbox;
241
242
  beforeEach(function() {
242
243
  sinon.stub(userSync, 'canBidderRegisterSync');
243
244
  sinon.stub(utils, 'getGptSlotInfoForAdUnitCode')
244
- .onFirstCall().returns({gptSlot: '/123123/gpt_publisher/adunit-code-3', divId: 'adunit-code-3-div-id'})
245
+ .onFirstCall().returns({gptSlot: '/123123/gpt_publisher/adunit-code-3', divId: 'adunit-code-3-div-id'});
246
+ sandbox = sinon.createSandbox();
245
247
  });
246
248
  afterEach(function() {
247
249
  userSync.canBidderRegisterSync.restore();
248
250
  utils.getGptSlotInfoForAdUnitCode.restore();
251
+ sandbox.restore();
249
252
  });
250
253
  let bidRequest = [{
251
254
  'schain': {
@@ -333,6 +336,36 @@ describe('SonobiBidAdapter', function () {
333
336
  uspConsent: 'someCCPAString'
334
337
  };
335
338
 
339
+ it('should set fpd if there is any data in ortb2', function() {
340
+ const ortb2 = {
341
+ site: {
342
+ ext: {
343
+ data: {
344
+ pageType: 'article',
345
+ category: 'tools'
346
+ }
347
+ }
348
+ },
349
+ user: {
350
+ ext: {
351
+ data: {
352
+ registered: true,
353
+ interests: ['cars']
354
+ }
355
+ }
356
+ }
357
+ };
358
+
359
+ sandbox.stub(config, 'getConfig').callsFake(key => {
360
+ const config = {
361
+ ortb2: ortb2
362
+ };
363
+ return utils.deepAccess(config, key);
364
+ });
365
+ const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
366
+ expect(bidRequests.data.fpd).to.equal(JSON.stringify(ortb2));
367
+ });
368
+
336
369
  it('should populate coppa as 1 if set in config', function () {
337
370
  config.setConfig({coppa: true});
338
371
  const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
@@ -112,6 +112,13 @@ describe('sortableBidAdapter', function() {
112
112
  'key2': 'val2'
113
113
  }
114
114
  },
115
+ 'ortb2Imp': {
116
+ 'ext': {
117
+ 'data': {
118
+ 'pbadslot': 'abc/123'
119
+ }
120
+ }
121
+ },
115
122
  'sizes': [
116
123
  [300, 250]
117
124
  ],
@@ -176,6 +183,10 @@ describe('sortableBidAdapter', function() {
176
183
  expect(requestBody.imp[0].floor).to.equal(0.21);
177
184
  });
178
185
 
186
+ it('includes pbadslot in the bid request', function () {
187
+ expect(requestBody.imp[0].ext.gpid).to.equal('abc/123');
188
+ });
189
+
179
190
  it('sets domain and href correctly', function () {
180
191
  expect(requestBody.site.domain).to.equal('example.com');
181
192
  expect(requestBody.site.page).to.equal('http://example.com/page?param=val');
@@ -582,6 +582,138 @@ describe('teadsBidAdapter', () => {
582
582
  });
583
583
  });
584
584
 
585
+ describe('Global Placement Id', function () {
586
+ let bidRequests = [
587
+ {
588
+ 'bidder': 'teads',
589
+ 'params': {
590
+ 'placementId': 10433394,
591
+ 'pageId': 1234
592
+ },
593
+ 'adUnitCode': 'adunit-code-1',
594
+ 'sizes': [[300, 250], [300, 600]],
595
+ 'bidId': '30b31c1838de1e',
596
+ 'bidderRequestId': '22edbae2733bf6',
597
+ 'auctionId': '1d1a030790a475',
598
+ 'creativeId': 'er2ee',
599
+ 'deviceWidth': 1680
600
+ },
601
+ {
602
+ 'bidder': 'teads',
603
+ 'params': {
604
+ 'placementId': 10433395,
605
+ 'pageId': 1234
606
+ },
607
+ 'adUnitCode': 'adunit-code-2',
608
+ 'sizes': [[300, 250], [300, 600]],
609
+ 'bidId': '30b31c1838de1f',
610
+ 'bidderRequestId': '22edbae2733bf6',
611
+ 'auctionId': '1d1a030790a475',
612
+ 'creativeId': 'er2ef',
613
+ 'deviceWidth': 1680
614
+ }
615
+ ];
616
+
617
+ it('should add gpid if ortb2Imp.ext.data.pbadslot is present and is non empty (and ortb2Imp.ext.data.adserver.adslot is not present)', function () {
618
+ const updatedBidRequests = bidRequests.map(function(bidRequest, index) {
619
+ return {
620
+ ...bidRequest,
621
+ ortb2Imp: {
622
+ ext: {
623
+ data: {
624
+ pbadslot: '1111/home-left-' + index
625
+ }
626
+ }
627
+ }
628
+ };
629
+ }
630
+ );
631
+ const request = spec.buildRequests(updatedBidRequests, bidderResquestDefault);
632
+ const payload = JSON.parse(request.data);
633
+
634
+ expect(payload.data[0].gpid).to.equal('1111/home-left-0');
635
+ expect(payload.data[1].gpid).to.equal('1111/home-left-1');
636
+ });
637
+
638
+ it('should add gpid if ortb2Imp.ext.data.pbadslot is present and is non empty (even if ortb2Imp.ext.data.adserver.adslot is present and is non empty too)', function () {
639
+ const updatedBidRequests = bidRequests.map(function(bidRequest, index) {
640
+ return {
641
+ ...bidRequest,
642
+ ortb2Imp: {
643
+ ext: {
644
+ data: {
645
+ pbadslot: '1111/home-left-' + index,
646
+ adserver: {
647
+ adslot: '1111/home-left/div-' + index
648
+ }
649
+ }
650
+ }
651
+ }
652
+ };
653
+ }
654
+ );
655
+ const request = spec.buildRequests(updatedBidRequests, bidderResquestDefault);
656
+ const payload = JSON.parse(request.data);
657
+
658
+ expect(payload.data[0].gpid).to.equal('1111/home-left-0');
659
+ expect(payload.data[1].gpid).to.equal('1111/home-left-1');
660
+ });
661
+
662
+ it('should not add gpid if both ortb2Imp.ext.data.pbadslot and ortb2Imp.ext.data.adserver.adslot are present but empty', function () {
663
+ const updatedBidRequests = bidRequests.map(bidRequest => ({
664
+ ...bidRequest,
665
+ ortb2Imp: {
666
+ ext: {
667
+ data: {
668
+ pbadslot: '',
669
+ adserver: {
670
+ adslot: ''
671
+ }
672
+ }
673
+ }
674
+ }
675
+ }));
676
+
677
+ const request = spec.buildRequests(updatedBidRequests, bidderResquestDefault);
678
+ const payload = JSON.parse(request.data);
679
+
680
+ return payload.data.forEach(bid => {
681
+ expect(bid).not.to.have.property('gpid');
682
+ });
683
+ });
684
+
685
+ it('should not add gpid if both ortb2Imp.ext.data.pbadslot and ortb2Imp.ext.data.adserver.adslot are not present', function () {
686
+ const request = spec.buildRequests(bidRequests, bidderResquestDefault);
687
+ const payload = JSON.parse(request.data);
688
+
689
+ return payload.data.forEach(bid => {
690
+ expect(bid).not.to.have.property('gpid');
691
+ });
692
+ });
693
+
694
+ it('should add gpid if ortb2Imp.ext.data.pbadslot is not present but ortb2Imp.ext.data.adserver.adslot is present and is non empty', function () {
695
+ const updatedBidRequests = bidRequests.map(function(bidRequest, index) {
696
+ return {
697
+ ...bidRequest,
698
+ ortb2Imp: {
699
+ ext: {
700
+ data: {
701
+ adserver: {
702
+ adslot: '1111/home-left-' + index
703
+ }
704
+ }
705
+ }
706
+ }
707
+ };
708
+ });
709
+ const request = spec.buildRequests(updatedBidRequests, bidderResquestDefault);
710
+ const payload = JSON.parse(request.data);
711
+
712
+ expect(payload.data[0].gpid).to.equal('1111/home-left-0');
713
+ expect(payload.data[1].gpid).to.equal('1111/home-left-1');
714
+ });
715
+ });
716
+
585
717
  function checkMediaTypesSizes(mediaTypes, expectedSizes) {
586
718
  const bidRequestWithBannerSizes = Object.assign(bidRequests[0], mediaTypes);
587
719
  const requestWithBannerSizes = spec.buildRequests([bidRequestWithBannerSizes], bidderResquestDefault);
@@ -568,6 +568,134 @@ describe('triplelift adapter', function () {
568
568
  expect(payload.user.ext.eids).to.have.lengthOf(4);
569
569
  });
570
570
 
571
+ it('should remove malformed ids that would otherwise break call', function () {
572
+ let tdidId = '6bca7f6b-a98a-46c0-be05-6020f7604598';
573
+ let idlEnvId = null; // fail; can't be null
574
+ let criteoId = '53e30ea700424f7bbdd793b02abc5d7';
575
+ let pubcid = ''; // fail; can't be empty string
576
+
577
+ let bidRequestsMultiple = [
578
+ { ...bidRequests[0], userId: { tdid: tdidId, idl_env: idlEnvId, criteoId, pubcid } },
579
+ { ...bidRequests[0], userId: { tdid: tdidId, idl_env: idlEnvId, criteoId, pubcid } },
580
+ { ...bidRequests[0], userId: { tdid: tdidId, idl_env: idlEnvId, criteoId, pubcid } }
581
+ ];
582
+
583
+ let request = tripleliftAdapterSpec.buildRequests(bidRequestsMultiple, bidderRequest);
584
+ let payload = request.data;
585
+
586
+ expect(payload.user).to.deep.equal({
587
+ ext: {
588
+ eids: [
589
+ {
590
+ source: 'adserver.org',
591
+ uids: [
592
+ {
593
+ id: tdidId,
594
+ ext: { rtiPartner: 'TDID' }
595
+ }
596
+ ],
597
+ },
598
+ {
599
+ source: 'criteo.com',
600
+ uids: [
601
+ {
602
+ id: criteoId,
603
+ ext: { rtiPartner: 'criteoId' }
604
+ }
605
+ ]
606
+ }
607
+ ]
608
+ }
609
+ });
610
+
611
+ expect(payload.user.ext.eids).to.be.an('array');
612
+ expect(payload.user.ext.eids).to.have.lengthOf(2);
613
+
614
+ tdidId = {}; // fail; can't be empty object
615
+ idlEnvId = { id: '987654' }; // pass
616
+ criteoId = [{ id: '123456' }]; // fail; can't be an array
617
+ pubcid = '3261d8ad-435d-481d-abd1-9f1a9ec99f0e'; // pass
618
+
619
+ bidRequestsMultiple = [
620
+ { ...bidRequests[0], userId: { tdid: tdidId, idl_env: idlEnvId, criteoId, pubcid } },
621
+ { ...bidRequests[0], userId: { tdid: tdidId, idl_env: idlEnvId, criteoId, pubcid } },
622
+ { ...bidRequests[0], userId: { tdid: tdidId, idl_env: idlEnvId, criteoId, pubcid } }
623
+ ];
624
+
625
+ request = tripleliftAdapterSpec.buildRequests(bidRequestsMultiple, bidderRequest);
626
+ payload = request.data;
627
+
628
+ expect(payload.user).to.deep.equal({
629
+ ext: {
630
+ eids: [
631
+ {
632
+ source: 'liveramp.com',
633
+ uids: [
634
+ {
635
+ id: '987654',
636
+ ext: { rtiPartner: 'idl' }
637
+ }
638
+ ]
639
+ },
640
+ {
641
+ source: 'pubcid.org',
642
+ uids: [
643
+ {
644
+ id: pubcid,
645
+ ext: { rtiPartner: 'pubcid' }
646
+ }
647
+ ]
648
+ }
649
+ ]
650
+ }
651
+ });
652
+
653
+ expect(payload.user.ext.eids).to.be.an('array');
654
+ expect(payload.user.ext.eids).to.have.lengthOf(2);
655
+
656
+ tdidId = { id: '987654' }; // pass
657
+ idlEnvId = { id: 987654 }; // fail; can't be an int
658
+ criteoId = '53e30ea700424f7bbdd793b02abc5d7'; // pass
659
+ pubcid = { id: '' }; // fail; can't be an empty string
660
+
661
+ bidRequestsMultiple = [
662
+ { ...bidRequests[0], userId: { tdid: tdidId, idl_env: idlEnvId, criteoId, pubcid } },
663
+ { ...bidRequests[0], userId: { tdid: tdidId, idl_env: idlEnvId, criteoId, pubcid } },
664
+ { ...bidRequests[0], userId: { tdid: tdidId, idl_env: idlEnvId, criteoId, pubcid } }
665
+ ];
666
+
667
+ request = tripleliftAdapterSpec.buildRequests(bidRequestsMultiple, bidderRequest);
668
+ payload = request.data;
669
+
670
+ expect(payload.user).to.deep.equal({
671
+ ext: {
672
+ eids: [
673
+ {
674
+ source: 'adserver.org',
675
+ uids: [
676
+ {
677
+ id: '987654',
678
+ ext: { rtiPartner: 'TDID' }
679
+ }
680
+ ],
681
+ },
682
+ {
683
+ source: 'criteo.com',
684
+ uids: [
685
+ {
686
+ id: criteoId,
687
+ ext: { rtiPartner: 'criteoId' }
688
+ }
689
+ ]
690
+ }
691
+ ]
692
+ }
693
+ });
694
+
695
+ expect(payload.user.ext.eids).to.be.an('array');
696
+ expect(payload.user.ext.eids).to.have.lengthOf(2);
697
+ });
698
+
571
699
  it('should return a query string for TL call', function () {
572
700
  const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
573
701
  const url = request.url;
@@ -402,7 +402,7 @@ describe('TrustXAdapter', function () {
402
402
  });
403
403
 
404
404
  it('if segment is present in permutive targeting, payload must have right params', function () {
405
- const permSegments = ['test_perm_1', 'test_perm_2'];
405
+ const permSegments = [{id: 'test_perm_1'}, {id: 'test_perm_2'}];
406
406
  const bidRequestsWithPermutiveTargeting = bidRequests.map((bid) => {
407
407
  return Object.assign({
408
408
  rtd: {
@@ -421,8 +421,8 @@ describe('TrustXAdapter', function () {
421
421
  expect(payload.user.data).to.deep.equal([{
422
422
  name: 'permutive',
423
423
  segment: [
424
- {name: 'p_standard', value: permSegments[0]},
425
- {name: 'p_standard', value: permSegments[1]}
424
+ {name: 'p_standard', value: permSegments[0].id},
425
+ {name: 'p_standard', value: permSegments[1].id}
426
426
  ]
427
427
  }]);
428
428
  });
@@ -60,6 +60,23 @@ const videoBidReq = [{
60
60
  bidId: '263be71e91dd9d',
61
61
  auctionId: '9ad1fa8d-2297-4660-a018-b39945054746'
62
62
  }];
63
+ const schainObj = {
64
+ 'ver': '1.0',
65
+ 'complete': 1,
66
+ 'nodes': [
67
+ {
68
+ 'asi': 'indirectseller.com',
69
+ 'sid': '00001',
70
+ 'hp': 1
71
+ },
72
+
73
+ {
74
+ 'asi': 'indirectseller-2.com',
75
+ 'sid': '00002',
76
+ 'hp': 2
77
+ }
78
+ ]
79
+ };
63
80
  const bidReq = [{
64
81
  adUnitCode: 'div-gpt-ad-1460505748561-0',
65
82
  bidder: BIDDER_CODE,
@@ -72,6 +89,29 @@ const bidReq = [{
72
89
  auctionId: '9ad1fa8d-2297-4660-a018-b39945054746'
73
90
  },
74
91
  {
92
+ adUnitCode: 'div-gpt-ad-1460505748561-0',
93
+ bidder: BIDDER_CODE,
94
+ params: {
95
+ publisherId: 12345
96
+ },
97
+ sizes: [[1, 1]],
98
+ bidId: '453cf42d72bb3c',
99
+ auctionId: '6c22f5a5-59df-4dc6-b92c-f433bcf0a874',
100
+ schain: schainObj
101
+ }];
102
+
103
+ const supplyChainedBidReqs = [{
104
+ adUnitCode: 'div-gpt-ad-1460505748561-0',
105
+ bidder: BIDDER_CODE,
106
+ params: {
107
+ placementId: '10433394',
108
+ publisherId: 12345,
109
+ },
110
+ sizes: [[300, 250], [300, 600]],
111
+ bidId: '263be71e91dd9d',
112
+ auctionId: '9ad1fa8d-2297-4660-a018-b39945054746',
113
+ schain: schainObj
114
+ }, {
75
115
  adUnitCode: 'div-gpt-ad-1460505748561-0',
76
116
  bidder: BIDDER_CODE,
77
117
  params: {
@@ -236,6 +276,18 @@ describe('Undertone Adapter', () => {
236
276
  sandbox.restore();
237
277
  });
238
278
 
279
+ describe('supply chain', function () {
280
+ it('should send supply chain if found on first bid', function () {
281
+ const request = spec.buildRequests(supplyChainedBidReqs, bidderReq);
282
+ const commons = JSON.parse(request.data)['commons'];
283
+ expect(commons.schain).to.deep.equal(schainObj);
284
+ });
285
+ it('should not send supply chain if not found on first bid', function () {
286
+ const request = spec.buildRequests(bidReq, bidderReq);
287
+ const commons = JSON.parse(request.data)['commons'];
288
+ expect(commons.schain).to.not.exist;
289
+ });
290
+ });
239
291
  it('should send request to correct url via POST not in GDPR or CCPA', function () {
240
292
  const request = spec.buildRequests(bidReq, bidderReq);
241
293
  const domainStart = bidderReq.refererInfo.referer.indexOf('//');