prebid.js 5.20.0 → 6.3.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 (168) 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 -8
  5. package/integrationExamples/gpt/weboramaRtdProvider_example.html +23 -14
  6. package/karma.conf.maker.js +1 -1
  7. package/modules/33acrossBidAdapter.js +189 -102
  8. package/modules/adagioBidAdapter.js +1 -1
  9. package/modules/addefendBidAdapter.js +1 -0
  10. package/modules/adheseBidAdapter.js +7 -2
  11. package/modules/adkernelBidAdapter.js +1 -0
  12. package/modules/adlivetechBidAdapter.md +61 -0
  13. package/modules/admanBidAdapter.js +1 -0
  14. package/modules/admixerBidAdapter.js +3 -2
  15. package/modules/adnuntiusBidAdapter.js +5 -2
  16. package/modules/adomikAnalyticsAdapter.js +10 -4
  17. package/modules/adplusBidAdapter.js +203 -0
  18. package/modules/adplusBidAdapter.md +39 -0
  19. package/modules/adxcgBidAdapter.js +311 -359
  20. package/modules/adxcgBidAdapter.md +22 -21
  21. package/modules/adyoulikeBidAdapter.js +7 -2
  22. package/modules/appnexusBidAdapter.js +23 -3
  23. package/modules/beachfrontBidAdapter.js +14 -17
  24. package/modules/beopBidAdapter.js +5 -3
  25. package/modules/codefuelBidAdapter.js +1 -3
  26. package/modules/codefuelBidAdapter.md +3 -3
  27. package/modules/colossussspBidAdapter.js +7 -0
  28. package/modules/craftBidAdapter.js +5 -3
  29. package/modules/criteoBidAdapter.js +1 -1
  30. package/modules/cwireBidAdapter.js +3 -0
  31. package/modules/datablocksBidAdapter.js +3 -3
  32. package/modules/dchain.js +149 -0
  33. package/modules/dchain.md +45 -0
  34. package/modules/deepintentBidAdapter.js +1 -1
  35. package/modules/dspxBidAdapter.js +1 -1
  36. package/modules/emx_digitalBidAdapter.js +9 -1
  37. package/modules/engageyaBidAdapter.js +68 -54
  38. package/modules/freewheel-sspBidAdapter.js +6 -0
  39. package/modules/futureads.md +48 -0
  40. package/modules/glimpseBidAdapter.js +44 -16
  41. package/modules/goldbachBidAdapter.js +1176 -0
  42. package/modules/goldbachBidAdapter.md +151 -0
  43. package/modules/gptPreAuction.js +11 -5
  44. package/modules/gridBidAdapter.js +1 -1
  45. package/modules/gumgumBidAdapter.js +7 -3
  46. package/modules/id5IdSystem.md +6 -6
  47. package/modules/imRtdProvider.js +31 -0
  48. package/modules/intersectionRtdProvider.js +114 -0
  49. package/modules/invibesBidAdapter.js +15 -9
  50. package/modules/ipromBidAdapter.js +79 -0
  51. package/modules/ixBidAdapter.js +166 -21
  52. package/modules/kinessoIdSystem.js +1 -1
  53. package/modules/limelightDigitalBidAdapter.js +2 -1
  54. package/modules/lotamePanoramaIdSystem.js +80 -8
  55. package/modules/luponmediaBidAdapter.js +570 -0
  56. package/modules/mediasquareBidAdapter.js +1 -9
  57. package/modules/merkleIdSystem.js +5 -0
  58. package/modules/missenaBidAdapter.js +89 -0
  59. package/modules/nativoBidAdapter.js +27 -1
  60. package/modules/nextMillenniumBidAdapter.js +29 -1
  61. package/modules/oguryBidAdapter.js +2 -1
  62. package/modules/openxBidAdapter.js +6 -1
  63. package/modules/prebidServerBidAdapter/index.js +19 -15
  64. package/modules/pubmaticBidAdapter.js +5 -3
  65. package/modules/relaidoBidAdapter.js +86 -65
  66. package/modules/richaudienceBidAdapter.js +2 -3
  67. package/modules/rtdModule/index.js +48 -18
  68. package/modules/rubiconBidAdapter.js +10 -8
  69. package/modules/saambaaBidAdapter.js +420 -0
  70. package/modules/saambaaBidAdapter.md +65 -68
  71. package/modules/seedtagBidAdapter.js +6 -0
  72. package/modules/sharedIdSystem.js +27 -1
  73. package/modules/smaatoBidAdapter.js +9 -1
  74. package/modules/smartxBidAdapter.js +17 -1
  75. package/modules/sspBCBidAdapter.js +34 -3
  76. package/modules/tappxBidAdapter.js +3 -1
  77. package/modules/targetVideoBidAdapter.js +187 -0
  78. package/modules/targetVideoBidAdapter.md +34 -0
  79. package/modules/trustxBidAdapter.js +10 -1
  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 +104 -64
  84. package/modules/ventesBidAdapter.md +0 -1
  85. package/modules/vidoomyBidAdapter.js +65 -108
  86. package/modules/visxBidAdapter.js +20 -3
  87. package/modules/visxBidAdapter.md +4 -6
  88. package/modules/weboramaRtdProvider.js +288 -73
  89. package/modules/weboramaRtdProvider.md +27 -10
  90. package/modules/yahoosspBidAdapter.js +5 -1
  91. package/modules/yahoosspBidAdapter.md +1 -1
  92. package/modules/yieldlabBidAdapter.js +41 -10
  93. package/modules/yieldlabBidAdapter.md +91 -48
  94. package/modules/yieldoneBidAdapter.js +115 -11
  95. package/modules/zetaSspBidAdapter.md +33 -1
  96. package/modules/zeta_global_sspBidAdapter.js +22 -1
  97. package/package.json +6 -1
  98. package/plugins/pbjsGlobals.js +28 -1
  99. package/src/adapterManager.js +14 -8
  100. package/src/auction.js +3 -2
  101. package/src/prebid.js +1 -2
  102. package/src/targeting.js +24 -3
  103. package/src/utils.js +41 -7
  104. package/test/spec/integration/faker/googletag.js +6 -0
  105. package/test/spec/modules/33acrossBidAdapter_spec.js +300 -78
  106. package/test/spec/modules/adheseBidAdapter_spec.js +27 -1
  107. package/test/spec/modules/adnuntiusBidAdapter_spec.js +35 -0
  108. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
  109. package/test/spec/modules/adplusBidAdapter_spec.js +213 -0
  110. package/test/spec/modules/adxcgBidAdapter_spec.js +820 -571
  111. package/test/spec/modules/adyoulikeBidAdapter_spec.js +26 -0
  112. package/test/spec/modules/appnexusBidAdapter_spec.js +63 -1
  113. package/test/spec/modules/beachfrontBidAdapter_spec.js +65 -1
  114. package/test/spec/modules/codefuelBidAdapter_spec.js +1 -1
  115. package/test/spec/modules/colossussspBidAdapter_spec.js +9 -0
  116. package/test/spec/modules/cwireBidAdapter_spec.js +10 -8
  117. package/test/spec/modules/datablocksBidAdapter_spec.js +3 -3
  118. package/test/spec/modules/dchain_spec.js +329 -0
  119. package/test/spec/modules/emx_digitalBidAdapter_spec.js +10 -0
  120. package/test/spec/modules/engageyaBidAdapter_spec.js +231 -95
  121. package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
  122. package/test/spec/modules/freewheel-sspBidAdapter_spec.js +19 -0
  123. package/test/spec/modules/glimpseBidAdapter_spec.js +33 -0
  124. package/test/spec/modules/goldbachBidAdapter_spec.js +1359 -0
  125. package/test/spec/modules/gptPreAuction_spec.js +58 -4
  126. package/test/spec/modules/gumgumBidAdapter_spec.js +6 -0
  127. package/test/spec/modules/imRtdProvider_spec.js +25 -0
  128. package/test/spec/modules/intersectionRtdProvider_spec.js +141 -0
  129. package/test/spec/modules/invibesBidAdapter_spec.js +29 -4
  130. package/test/spec/modules/ipromBidAdapter_spec.js +195 -0
  131. package/test/spec/modules/ixBidAdapter_spec.js +285 -2
  132. package/test/spec/modules/konduitWrapper_spec.js +0 -1
  133. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +10 -7
  134. package/test/spec/modules/lotamePanoramaIdSystem_spec.js +227 -0
  135. package/test/spec/modules/luponmediaBidAdapter_spec.js +412 -0
  136. package/test/spec/modules/mediasquareBidAdapter_spec.js +4 -4
  137. package/test/spec/modules/merkleIdSystem_spec.js +18 -0
  138. package/test/spec/modules/missenaBidAdapter_spec.js +134 -0
  139. package/test/spec/modules/nativoBidAdapter_spec.js +35 -18
  140. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +18 -0
  141. package/test/spec/modules/oguryBidAdapter_spec.js +13 -11
  142. package/test/spec/modules/openxBidAdapter_spec.js +5 -0
  143. package/test/spec/modules/prebidServerBidAdapter_spec.js +62 -2
  144. package/test/spec/modules/pubmaticBidAdapter_spec.js +1 -1
  145. package/test/spec/modules/realTimeDataModule_spec.js +135 -49
  146. package/test/spec/modules/relaidoBidAdapter_spec.js +71 -63
  147. package/test/spec/modules/richaudienceBidAdapter_spec.js +2 -2
  148. package/test/spec/modules/rubiconBidAdapter_spec.js +17 -0
  149. package/test/spec/modules/seedtagBidAdapter_spec.js +3 -0
  150. package/test/spec/modules/sharedIdSystem_spec.js +52 -6
  151. package/test/spec/modules/smaatoBidAdapter_spec.js +61 -0
  152. package/test/spec/modules/smartxBidAdapter_spec.js +9 -0
  153. package/test/spec/modules/sspBCBidAdapter_spec.js +33 -3
  154. package/test/spec/modules/tappxBidAdapter_spec.js +4 -0
  155. package/test/spec/modules/targetVideoBidAdapter_spec.js +96 -0
  156. package/test/spec/modules/trustxBidAdapter_spec.js +42 -0
  157. package/test/spec/modules/userId_spec.js +51 -0
  158. package/test/spec/modules/vidoomyBidAdapter_spec.js +32 -13
  159. package/test/spec/modules/visxBidAdapter_spec.js +121 -5
  160. package/test/spec/modules/weboramaRtdProvider_spec.js +408 -214
  161. package/test/spec/modules/yahoosspBidAdapter_spec.js +28 -1
  162. package/test/spec/modules/yieldlabBidAdapter_spec.js +81 -0
  163. package/test/spec/modules/yieldoneBidAdapter_spec.js +299 -53
  164. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +33 -1
  165. package/test/spec/unit/core/adapterManager_spec.js +24 -6
  166. package/test/spec/unit/core/targeting_spec.js +116 -0
  167. package/test/spec/utils_spec.js +38 -0
  168. package/wdio.conf.js +1 -1
@@ -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 = {
@@ -1077,6 +1081,15 @@ describe('AppNexusAdapter', function () {
1077
1081
  'adUnitCode': 'code',
1078
1082
  'appnexus': {
1079
1083
  'buyerMemberId': 958
1084
+ },
1085
+ 'meta': {
1086
+ 'dchain': {
1087
+ 'ver': '1.0',
1088
+ 'complete': 0,
1089
+ 'nodes': [{
1090
+ 'bsid': '958'
1091
+ }]
1092
+ }
1080
1093
  }
1081
1094
  }
1082
1095
  ];
@@ -1085,11 +1098,46 @@ describe('AppNexusAdapter', function () {
1085
1098
  bidId: '3db3773286ee59',
1086
1099
  adUnitCode: 'code'
1087
1100
  }]
1088
- }
1101
+ };
1089
1102
  let result = spec.interpretResponse({ body: response }, {bidderRequest});
1090
1103
  expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0]));
1091
1104
  });
1092
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
+
1093
1141
  it('handles nobid responses', function () {
1094
1142
  let response = {
1095
1143
  'version': '0.0.1',
@@ -1335,6 +1383,20 @@ describe('AppNexusAdapter', function () {
1335
1383
  expect(Object.keys(result[0].meta)).to.include.members(['advertiserId']);
1336
1384
  });
1337
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
+
1338
1400
  it('should add advertiserDomains', function() {
1339
1401
  let responseAdvertiserId = deepClone(response);
1340
1402
  responseAdvertiserId.tags[0].ads[0].adomain = ['123'];
@@ -1,6 +1,7 @@
1
1
  import { expect } from 'chai';
2
2
  import { spec, VIDEO_ENDPOINT, BANNER_ENDPOINT, OUTSTREAM_SRC, DEFAULT_MIMES } from 'modules/beachfrontBidAdapter.js';
3
- import { parseUrl } from 'src/utils.js';
3
+ import { config } from 'src/config.js';
4
+ import { parseUrl, deepAccess } from 'src/utils.js';
4
5
 
5
6
  describe('BeachfrontAdapter', function () {
6
7
  let bidRequests;
@@ -556,6 +557,69 @@ describe('BeachfrontAdapter', function () {
556
557
  });
557
558
  });
558
559
 
560
+ describe('with first-party data', function () {
561
+ let sandbox
562
+
563
+ beforeEach(function () {
564
+ sandbox = sinon.sandbox.create();
565
+ });
566
+
567
+ afterEach(function () {
568
+ sandbox.restore();
569
+ });
570
+
571
+ it('must add first-party data to the video bid request', function () {
572
+ sandbox.stub(config, 'getConfig').callsFake(key => {
573
+ const cfg = {
574
+ ortb2: {
575
+ site: {
576
+ keywords: 'test keyword'
577
+ },
578
+ user: {
579
+ data: 'some user data'
580
+ }
581
+ }
582
+ };
583
+ return deepAccess(cfg, key);
584
+ });
585
+ const bidRequest = bidRequests[0];
586
+ bidRequest.mediaTypes = { video: {} };
587
+ const bidderRequest = {
588
+ refererInfo: {
589
+ referer: 'http://example.com/page.html'
590
+ }
591
+ };
592
+ const requests = spec.buildRequests([ bidRequest ], bidderRequest);
593
+ const data = requests[0].data;
594
+ expect(data.user.data).to.equal('some user data');
595
+ expect(data.site.keywords).to.equal('test keyword');
596
+ expect(data.site.page).to.equal('http://example.com/page.html');
597
+ expect(data.site.domain).to.equal('example.com');
598
+ });
599
+
600
+ it('must add first-party data to the banner bid request', function () {
601
+ sandbox.stub(config, 'getConfig').callsFake(key => {
602
+ const cfg = {
603
+ ortb2: {
604
+ site: {
605
+ keywords: 'test keyword'
606
+ },
607
+ user: {
608
+ data: 'some user data'
609
+ }
610
+ }
611
+ };
612
+ return deepAccess(cfg, key);
613
+ });
614
+ const bidRequest = bidRequests[0];
615
+ bidRequest.mediaTypes = { banner: {} };
616
+ const requests = spec.buildRequests([ bidRequest ]);
617
+ const data = requests[0].data;
618
+ expect(data.ortb2.user.data).to.equal('some user data');
619
+ expect(data.ortb2.site.keywords).to.equal('test keyword');
620
+ });
621
+ });
622
+
559
623
  describe('for multi-format bids', function () {
560
624
  it('should create a POST request for each bid format', function () {
561
625
  const width = 300;
@@ -183,7 +183,7 @@ describe('Codefuel Adapter', function () {
183
183
  tmax: 500
184
184
  }
185
185
  const res = spec.buildRequests([bidRequest], commonBidderRequest)
186
- expect(res.url).to.equal('https://bidder-url.com')
186
+ expect(res.url).to.equal('https://ai-p-codefuel-ds-rtb-us-east-1-k8s.seccint.com/prebid')
187
187
  expect(res.data).to.deep.equal(expectedData)
188
188
  })
189
189
 
@@ -186,6 +186,15 @@ describe('ColossussspAdapter', function () {
186
186
  });
187
187
  });
188
188
 
189
+ describe('onBidWon', function () {
190
+ it('should make an ajax call', function () {
191
+ const bid = {
192
+ nurl: 'http://example.com/win',
193
+ };
194
+ expect(spec.onBidWon(bid)).to.equals(undefined);
195
+ });
196
+ })
197
+
189
198
  describe('getUserSyncs', function () {
190
199
  let userSync = spec.getUserSyncs();
191
200
  it('Returns valid URL and type', function () {
@@ -36,11 +36,6 @@ const BidderRequestBuilder = function BidderRequestBuilder(options) {
36
36
  bidderRequestId: BID_DEFAULTS.request.bidderRequestId,
37
37
  transactionId: BID_DEFAULTS.request.transactionId,
38
38
  timeout: 3000,
39
- refererInfo: {
40
- numIframes: 0,
41
- reachedTop: true,
42
- referer: 'http://test.io/index.html?pbjs_debug=true'
43
- }
44
39
  };
45
40
 
46
41
  const request = {
@@ -82,16 +77,13 @@ const BidRequestBuilder = function BidRequestBuilder(options, deleteKeys) {
82
77
  };
83
78
 
84
79
  describe('C-WIRE bid adapter', () => {
85
- let utilsMock;
86
80
  let sandbox;
87
81
 
88
82
  beforeEach(() => {
89
- utilsMock = sinon.mock(utils);
90
83
  sandbox = sinon.createSandbox();
91
84
  });
92
85
 
93
86
  afterEach(() => {
94
- utilsMock.restore();
95
87
  sandbox.restore();
96
88
  });
97
89
 
@@ -146,6 +138,12 @@ describe('C-WIRE bid adapter', () => {
146
138
 
147
139
  describe('C-WIRE - buildRequests()', function () {
148
140
  it('creates a valid request', function () {
141
+ // for whatever reason stub for getWindowLocation does not work
142
+ // so this was the closest way to test for get params
143
+ const params = sandbox.stub(utils, 'getParameterByName');
144
+ params.withArgs('cwgroups').returns('group_1');
145
+ params.withArgs('cwcreative').returns('54321');
146
+
149
147
  const bid01 = new BidRequestBuilder({
150
148
  mediaTypes: {
151
149
  banner: {
@@ -153,12 +151,16 @@ describe('C-WIRE bid adapter', () => {
153
151
  }
154
152
  }
155
153
  }).withParams().build();
154
+
156
155
  const bidderRequest01 = new BidderRequestBuilder().build();
157
156
 
158
157
  const requests = spec.buildRequests([bid01], bidderRequest01);
158
+
159
159
  expect(requests.data.slots.length).to.equal(1);
160
160
  expect(requests.data.cwid).to.be.null;
161
161
  expect(requests.data.slots[0].sizes[0]).to.equal('1x1');
162
+ expect(requests.data.cwcreative).to.equal('54321');
163
+ expect(requests.data.refgroups[0]).to.equal('group_1');
162
164
  });
163
165
  });
164
166
 
@@ -96,8 +96,8 @@ const bidderRequest = {
96
96
  refererInfo: {
97
97
  numIframes: 0,
98
98
  reachedTop: true,
99
- referer: 'https://v5demo.datablocks.net/test',
100
- stack: ['https://v5demo.datablocks.net/test']
99
+ referer: 'https://7560.v5demo.datablocks.net/test',
100
+ stack: ['https://7560.v5demo.datablocks.net/test']
101
101
  },
102
102
  start: Date.now(),
103
103
  timeout: 10000
@@ -452,7 +452,7 @@ describe('DatablocksAdapter', function() {
452
452
 
453
453
  it('Returns valid URL', function() {
454
454
  expect(request.url).to.exist;
455
- expect(request.url).to.equal('https://7560.v5demo.datablocks.net/openrtb/?sid=7560');
455
+ expect(request.url).to.equal('https://v5demo.datablocks.net/openrtb/?sid=7560');
456
456
  });
457
457
 
458
458
  it('Creates an array of request objects', function() {
@@ -0,0 +1,329 @@
1
+ import { checkDchainSyntax, addBidResponseHook } from '../../../modules/dchain.js';
2
+ import { config } from '../../../src/config.js';
3
+ import { expect } from 'chai';
4
+
5
+ describe('dchain module', function () {
6
+ const STRICT = 'strict';
7
+ const RELAX = 'relaxed';
8
+ const OFF = 'off';
9
+
10
+ describe('checkDchainSyntax', function () {
11
+ let bid;
12
+
13
+ beforeEach(function () {
14
+ bid = {
15
+ meta: {
16
+ dchain: {
17
+ 'ver': '1.0',
18
+ 'complete': 0,
19
+ 'ext': {},
20
+ 'nodes': [{
21
+ 'asi': 'domain.com',
22
+ 'bsid': '12345',
23
+ }, {
24
+ 'name': 'bidder',
25
+ 'domain': 'bidder.com',
26
+ 'ext': {}
27
+ }]
28
+ }
29
+ }
30
+ };
31
+ });
32
+
33
+ it('Returns false if complete param is not 0 or 1', function () {
34
+ let dchainConfig = bid.meta.dchain;
35
+ dchainConfig.complete = 0; // integer
36
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
37
+ dchainConfig.complete = 1; // integer
38
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
39
+ dchainConfig.complete = '1'; // string
40
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
41
+ dchainConfig.complete = 1.1; // float
42
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
43
+ dchainConfig.complete = {}; // object
44
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
45
+ delete dchainConfig.complete; // undefined
46
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
47
+ dchainConfig.complete = true; // boolean
48
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
49
+ dchainConfig.complete = []; // array
50
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
51
+ });
52
+
53
+ it('Returns false if ver param is not a String', function () {
54
+ let dchainConfig = bid.meta.dchain;
55
+ dchainConfig.ver = 1; // integer
56
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
57
+ dchainConfig.ver = '1'; // string
58
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
59
+ dchainConfig.ver = 1.1; // float
60
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
61
+ dchainConfig.ver = {}; // object
62
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
63
+ delete dchainConfig.ver; // undefined
64
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
65
+ dchainConfig.ver = true; // boolean
66
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
67
+ dchainConfig.ver = []; // array
68
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
69
+ });
70
+
71
+ it('Returns false if ext param is not an Object', function () {
72
+ let dchainConfig = bid.meta.dchain;
73
+ dchainConfig.ext = 1; // integer
74
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
75
+ dchainConfig.ext = '1'; // string
76
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
77
+ dchainConfig.ext = 1.1; // float
78
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
79
+ dchainConfig.ext = {}; // object
80
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
81
+ delete dchainConfig.ext; // undefined
82
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
83
+ dchainConfig.ext = true; // boolean
84
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
85
+ dchainConfig.ext = []; // array
86
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
87
+ });
88
+
89
+ it('Returns false if nodes param is not an Array', function () {
90
+ let dchainConfig = bid.meta.dchain;
91
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
92
+ dchainConfig.nodes = 1; // integer
93
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
94
+ dchainConfig.nodes = '1'; // string
95
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
96
+ dchainConfig.nodes = 1.1; // float
97
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
98
+ dchainConfig.nodes = {}; // object
99
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
100
+ delete dchainConfig.nodes; // undefined
101
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
102
+ dchainConfig.nodes = true; // boolean
103
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
104
+ });
105
+
106
+ it('Returns false if unknown field is used in main dchain', function () {
107
+ let dchainConfig = bid.meta.dchain;
108
+ dchainConfig.test = '1'; // String
109
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
110
+ });
111
+
112
+ it('Returns false if nodes[].asi is not a String', function () {
113
+ let dchainConfig = bid.meta.dchain;
114
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
115
+ dchainConfig.nodes[0].asi = 1; // Integer
116
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
117
+ dchainConfig.nodes[0].asi = 1.1; // float
118
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
119
+ dchainConfig.nodes[0].asi = {}; // object
120
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
121
+ delete dchainConfig.nodes[0].asi; // undefined
122
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
123
+ dchainConfig.nodes[0].asi = true; // boolean
124
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
125
+ dchainConfig.nodes[0].asi = []; // array
126
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
127
+ });
128
+
129
+ it('Returns false if nodes[].bsid is not a String', function () {
130
+ let dchainConfig = bid.meta.dchain;
131
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
132
+ dchainConfig.nodes[0].bsid = 1; // Integer
133
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
134
+ dchainConfig.nodes[0].bsid = 1.1; // float
135
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
136
+ dchainConfig.nodes[0].bsid = {}; // object
137
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
138
+ delete dchainConfig.nodes[0].bsid; // undefined
139
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
140
+ dchainConfig.nodes[0].bsid = true; // boolean
141
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
142
+ dchainConfig.nodes[0].bsid = []; // array
143
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
144
+ });
145
+
146
+ it('Returns false if nodes[].rid is not a String', function () {
147
+ let dchainConfig = bid.meta.dchain;
148
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
149
+ dchainConfig.nodes[0].rid = 1; // Integer
150
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
151
+ dchainConfig.nodes[0].rid = 1.1; // float
152
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
153
+ dchainConfig.nodes[0].rid = {}; // object
154
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
155
+ delete dchainConfig.nodes[0].rid; // undefined
156
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
157
+ dchainConfig.nodes[0].rid = true; // boolean
158
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
159
+ dchainConfig.nodes[0].rid = []; // array
160
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
161
+ });
162
+
163
+ it('Returns false if nodes[].name is not a String', function () {
164
+ let dchainConfig = bid.meta.dchain;
165
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
166
+ dchainConfig.nodes[0].name = 1; // Integer
167
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
168
+ dchainConfig.nodes[0].name = 1.1; // float
169
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
170
+ dchainConfig.nodes[0].name = {}; // object
171
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
172
+ delete dchainConfig.nodes[0].name; // undefined
173
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
174
+ dchainConfig.nodes[0].name = true; // boolean
175
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
176
+ dchainConfig.nodes[0].name = []; // array
177
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
178
+ });
179
+
180
+ it('Returns false if nodes[].domain is not a String', function () {
181
+ let dchainConfig = bid.meta.dchain;
182
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
183
+ dchainConfig.nodes[0].domain = 1; // Integer
184
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
185
+ dchainConfig.nodes[0].domain = 1.1; // float
186
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
187
+ dchainConfig.nodes[0].domain = {}; // object
188
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
189
+ delete dchainConfig.nodes[0].domain; // undefined
190
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
191
+ dchainConfig.nodes[0].domain = true; // boolean
192
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
193
+ dchainConfig.nodes[0].domain = []; // array
194
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
195
+ });
196
+
197
+ it('Returns false if nodes[].ext is not an Object', function () {
198
+ let dchainConfig = bid.meta.dchain;
199
+ dchainConfig.nodes[0].ext = '1'; // String
200
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
201
+ dchainConfig.nodes[0].ext = 1; // Integer
202
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
203
+ dchainConfig.nodes[0].ext = 1.1; // float
204
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
205
+ dchainConfig.nodes[0].ext = {}; // object
206
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
207
+ delete dchainConfig.nodes[0].ext; // undefined
208
+ expect(checkDchainSyntax(bid, STRICT)).to.true;
209
+ dchainConfig.nodes[0].ext = true; // boolean
210
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
211
+ dchainConfig.nodes[0].ext = []; // array
212
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
213
+ });
214
+
215
+ it('Returns false if unknown field is used in nodes[]', function () {
216
+ let dchainConfig = bid.meta.dchain;
217
+ dchainConfig.nodes[0].test = '1'; // String
218
+ expect(checkDchainSyntax(bid, STRICT)).to.false;
219
+ });
220
+
221
+ it('Relaxed mode: returns true even for invalid config', function () {
222
+ bid.meta.dchain = {
223
+ ver: 1.1,
224
+ complete: '0',
225
+ nodes: [{
226
+ name: 'asdf',
227
+ domain: ['domain.com']
228
+ }]
229
+ };
230
+
231
+ expect(checkDchainSyntax(bid, RELAX)).to.true;
232
+ });
233
+ });
234
+
235
+ describe('addBidResponseHook', function () {
236
+ let bid;
237
+ let adUnitCode = 'adUnit1';
238
+
239
+ beforeEach(function () {
240
+ bid = {
241
+ bidderCode: 'bidderA',
242
+ meta: {
243
+ dchain: {
244
+ 'ver': '1.0',
245
+ 'complete': 0,
246
+ 'ext': {},
247
+ 'nodes': [{
248
+ 'asi': 'domain.com',
249
+ 'bsid': '12345',
250
+ }, {
251
+ 'name': 'bidder',
252
+ 'domain': 'bidder.com',
253
+ 'ext': {}
254
+ }]
255
+ },
256
+ networkName: 'myNetworkName',
257
+ networkId: 8475
258
+ }
259
+ };
260
+ });
261
+
262
+ afterEach(function () {
263
+ config.resetConfig();
264
+ });
265
+
266
+ it('good strict config should append a node object to existing bid.meta.dchain object', function () {
267
+ function testCallback(adUnitCode, bid) {
268
+ expect(bid.meta.dchain).to.exist;
269
+ expect(bid.meta.dchain.nodes[1]).to.exist.and.to.deep.equal({
270
+ 'name': 'bidder',
271
+ 'domain': 'bidder.com',
272
+ 'ext': {}
273
+ });
274
+ expect(bid.meta.dchain.nodes[2]).to.exist.and.to.deep.equal({ asi: 'bidderA' });
275
+ }
276
+
277
+ config.setConfig({ dchain: { validation: STRICT } });
278
+ addBidResponseHook(testCallback, adUnitCode, bid);
279
+ });
280
+
281
+ it('bad strict config should delete the bid.meta.dchain object', function () {
282
+ function testCallback(adUnitCode, bid) {
283
+ expect(bid.meta.dchain).to.not.exist;
284
+ }
285
+
286
+ config.setConfig({ dchain: { validation: STRICT } });
287
+ bid.meta.dchain.complete = 3;
288
+ addBidResponseHook(testCallback, adUnitCode, bid);
289
+ });
290
+
291
+ it('relaxed config should allow bid.meta.dchain to proceed, even with bad values', function () {
292
+ function testCallback(adUnitCode, bid) {
293
+ expect(bid.meta.dchain).to.exist;
294
+ expect(bid.meta.dchain.complete).to.exist.and.to.equal(3);
295
+ expect(bid.meta.dchain.nodes[2]).to.exist.and.to.deep.equal({ asi: 'bidderA' });
296
+ }
297
+
298
+ config.setConfig({ dchain: { validation: RELAX } });
299
+ bid.meta.dchain.complete = 3;
300
+ addBidResponseHook(testCallback, adUnitCode, bid);
301
+ });
302
+
303
+ it('off config should allow the bid.meta.dchain to proceed', function () {
304
+ // check for missing nodes
305
+ function testCallback(adUnitCode, bid) {
306
+ expect(bid.meta.dchain).to.exist;
307
+ expect(bid.meta.dchain.complete).to.exist.and.to.equal(0);
308
+ expect(bid.meta.dchain.nodes).to.exist.and.to.deep.equal({ test: 123 });
309
+ }
310
+
311
+ config.setConfig({ dchain: { validation: OFF } });
312
+ bid.meta.dchain.nodes = { test: 123 };
313
+ addBidResponseHook(testCallback, adUnitCode, bid);
314
+ });
315
+
316
+ it('no bidder dchain', function () {
317
+ function testCallback(adUnitCode, bid) {
318
+ expect(bid.meta.dchain).to.exist;
319
+ expect(bid.meta.dchain.ver).to.exist.and.to.equal('1.0');
320
+ expect(bid.meta.dchain.complete).to.exist.and.to.equal(0);
321
+ expect(bid.meta.dchain.nodes).to.exist.and.to.deep.equal([{ name: 'myNetworkName', bsid: '8475' }, { name: 'bidderA' }]);
322
+ }
323
+
324
+ delete bid.meta.dchain;
325
+ config.setConfig({ dchain: { validation: RELAX } });
326
+ addBidResponseHook(testCallback, adUnitCode, bid);
327
+ });
328
+ });
329
+ });
@@ -432,6 +432,16 @@ describe('emx_digital Adapter', function () {
432
432
  });
433
433
  });
434
434
 
435
+ it('should add gpid to request if present', () => {
436
+ const gpid = '/12345/my-gpt-tag-0';
437
+ let bid = utils.deepClone(bidderRequest.bids[0]);
438
+ bid.ortb2Imp = { ext: { data: { adserver: { adslot: gpid } } } };
439
+ bid.ortb2Imp = { ext: { data: { pbadslot: gpid } } };
440
+ let requestWithGPID = spec.buildRequests([bid], bidderRequest);
441
+ requestWithGPID = JSON.parse(requestWithGPID.data);
442
+ expect(requestWithGPID.imp[0].ext.gpid).to.exist.and.equal(gpid);
443
+ });
444
+
435
445
  it('should add UID 2.0 to request', () => {
436
446
  const uid2 = { id: '456' };
437
447
  const bidRequestWithUID = utils.deepClone(bidderRequest);