prebid.js 5.16.0 → 5.20.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 (182) hide show
  1. package/.devcontainer/Dockerfile +11 -0
  2. package/.devcontainer/devcontainer.json +27 -0
  3. package/.devcontainer/postCreate.sh +6 -0
  4. package/browsers.json +1 -0
  5. package/integrationExamples/gpt/akamaidap_segments_example.html +132 -0
  6. package/modules/.submodules.json +1 -0
  7. package/modules/adfBidAdapter.js +21 -16
  8. package/modules/adgenerationBidAdapter.js +28 -4
  9. package/modules/adkernelBidAdapter.js +3 -1
  10. package/modules/admixerBidAdapter.js +11 -0
  11. package/modules/adnuntiusBidAdapter.js +1 -0
  12. package/modules/adtelligentBidAdapter.js +2 -1
  13. package/modules/airgridRtdProvider.js +1 -1
  14. package/modules/akamaiDapRtdProvider.js +474 -0
  15. package/modules/akamaiDapRtdProvider.md +47 -0
  16. package/modules/aolBidAdapter.js +2 -1
  17. package/modules/appnexusBidAdapter.js +5 -3
  18. package/modules/atsAnalyticsAdapter.js +89 -63
  19. package/modules/atsAnalyticsAdapter.md +1 -0
  20. package/modules/betweenBidAdapter.js +20 -3
  21. package/modules/bliinkBidAdapter.js +58 -32
  22. package/modules/bliinkBidAdapter.md +29 -6
  23. package/modules/browsiRtdProvider.js +106 -18
  24. package/modules/cleanioRtdProvider.js +192 -0
  25. package/modules/cleanioRtdProvider.md +59 -0
  26. package/modules/codefuelBidAdapter.js +183 -0
  27. package/modules/codefuelBidAdapter.md +111 -0
  28. package/modules/connectIdSystem.js +104 -0
  29. package/modules/connectIdSystem.md +33 -0
  30. package/modules/cwireBidAdapter.js +272 -0
  31. package/modules/cwireBidAdapter.md +43 -0
  32. package/modules/deepintentBidAdapter.js +106 -9
  33. package/modules/deepintentBidAdapter.md +36 -1
  34. package/modules/deltaprojectsBidAdapter.js +252 -0
  35. package/modules/deltaprojectsBidAdapter.md +32 -0
  36. package/modules/dgkeywordRtdProvider.js +0 -1
  37. package/modules/engageyaBidAdapter.js +157 -0
  38. package/modules/glimpseBidAdapter.js +160 -48
  39. package/modules/glimpseBidAdapter.md +11 -74
  40. package/modules/gridBidAdapter.js +1 -0
  41. package/modules/gridNMBidAdapter.js +7 -6
  42. package/modules/gumgumBidAdapter.js +16 -2
  43. package/modules/iasRtdProvider.js +83 -67
  44. package/modules/inskinBidAdapter.js +7 -3
  45. package/modules/ixBidAdapter.js +8 -1
  46. package/modules/jixieBidAdapter.js +8 -2
  47. package/modules/justpremiumBidAdapter.js +6 -1
  48. package/modules/kargoBidAdapter.js +14 -7
  49. package/modules/kargoBidAdapter.md +20 -0
  50. package/modules/limelightDigitalBidAdapter.js +22 -2
  51. package/modules/livewrappedAnalyticsAdapter.js +53 -3
  52. package/modules/mediakeysBidAdapter.js +405 -14
  53. package/modules/mediakeysBidAdapter.md +108 -0
  54. package/modules/multibid/index.js +3 -3
  55. package/modules/mytargetBidAdapter.js +112 -0
  56. package/modules/nativoBidAdapter.js +48 -29
  57. package/modules/nativoBidAdapter.md +0 -1
  58. package/modules/nextMillenniumBidAdapter.js +12 -3
  59. package/modules/nextrollBidAdapter.js +375 -0
  60. package/modules/nobidBidAdapter.js +2 -1
  61. package/modules/oguryBidAdapter.js +36 -7
  62. package/modules/openxBidAdapter.js +34 -22
  63. package/modules/operaadsBidAdapter.js +21 -1
  64. package/modules/otmBidAdapter.js +146 -0
  65. package/modules/otmBidAdapter.md +27 -26
  66. package/modules/outbrainBidAdapter.js +5 -0
  67. package/modules/pixfutureBidAdapter.js +24 -4
  68. package/modules/pixfutureBidAdapter.md +127 -0
  69. package/modules/playwireBidAdapter.md +61 -0
  70. package/modules/prebidServerBidAdapter/index.js +1 -1
  71. package/modules/proxistoreBidAdapter.js +4 -6
  72. package/modules/publinkIdSystem.js +17 -7
  73. package/modules/publinkIdSystem.md +7 -2
  74. package/modules/pubmaticBidAdapter.js +22 -6
  75. package/modules/pubmaticBidAdapter.md +1 -1
  76. package/modules/relaidoBidAdapter.js +8 -2
  77. package/modules/rtdModule/index.js +2 -2
  78. package/modules/sharethroughBidAdapter.js +12 -19
  79. package/modules/slimcutBidAdapter.js +121 -0
  80. package/modules/sonobiBidAdapter.js +7 -0
  81. package/modules/sortableBidAdapter.js +1 -0
  82. package/modules/spotxBidAdapter.js +15 -1
  83. package/modules/sspBCBidAdapter.js +207 -12
  84. package/modules/sspBCBidAdapter.md +1 -1
  85. package/modules/talkadsBidAdapter.js +129 -0
  86. package/modules/talkadsBidAdapter.md +60 -0
  87. package/modules/tappxBidAdapter.js +6 -5
  88. package/modules/teadsBidAdapter.js +3 -0
  89. package/modules/tripleliftBidAdapter.js +22 -5
  90. package/modules/trustxBidAdapter.js +17 -11
  91. package/modules/undertoneBidAdapter.js +9 -5
  92. package/modules/undertoneBidAdapter.md +5 -1
  93. package/modules/unicornBidAdapter.js +3 -3
  94. package/modules/userId/eids.js +18 -0
  95. package/modules/userId/eids.md +7 -0
  96. package/modules/userId/userId.md +12 -0
  97. package/modules/ventesBidAdapter.js +370 -0
  98. package/modules/ventesBidAdapter.md +94 -0
  99. package/modules/videobyteBidAdapter.js +13 -6
  100. package/modules/videobyteBidAdapter.md +49 -0
  101. package/modules/vidoomyBidAdapter.js +20 -12
  102. package/modules/visxBidAdapter.js +15 -22
  103. package/modules/yahoosspBidAdapter.js +637 -0
  104. package/modules/yahoosspBidAdapter.md +795 -0
  105. package/modules/yieldlabBidAdapter.js +48 -3
  106. package/modules/yieldlabBidAdapter.md +16 -1
  107. package/modules/yieldmoBidAdapter.js +20 -6
  108. package/modules/yieldmoSyntheticInventoryModule.js +46 -0
  109. package/modules/yieldmoSyntheticInventoryModule.md +68 -0
  110. package/package.json +1 -1
  111. package/src/adapterManager.js +5 -0
  112. package/src/adapters/bidderFactory.js +4 -3
  113. package/src/auction.js +11 -11
  114. package/src/constants.json +1 -0
  115. package/src/secureCreatives.js +6 -7
  116. package/src/targeting.js +11 -9
  117. package/test/.eslintrc.js +2 -1
  118. package/test/spec/modules/adfBidAdapter_spec.js +83 -29
  119. package/test/spec/modules/adgenerationBidAdapter_spec.js +121 -50
  120. package/test/spec/modules/adnuntiusBidAdapter_spec.js +68 -0
  121. package/test/spec/modules/adtelligentBidAdapter_spec.js +1 -0
  122. package/test/spec/modules/akamaiDapRtdProvider_spec.js +246 -0
  123. package/test/spec/modules/appnexusBidAdapter_spec.js +2 -1
  124. package/test/spec/modules/atsAnalyticsAdapter_spec.js +77 -9
  125. package/test/spec/modules/betweenBidAdapter_spec.js +41 -0
  126. package/test/spec/modules/bliinkBidAdapter_spec.js +87 -36
  127. package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
  128. package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
  129. package/test/spec/modules/codefuelBidAdapter_spec.js +316 -0
  130. package/test/spec/modules/connectIdSystem_spec.js +189 -0
  131. package/test/spec/modules/cwireBidAdapter_spec.js +246 -0
  132. package/test/spec/modules/deepintentBidAdapter_spec.js +153 -3
  133. package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
  134. package/test/spec/modules/engageyaBidAdapter_spec.js +286 -0
  135. package/test/spec/modules/glimpseBidAdapter_spec.js +302 -204
  136. package/test/spec/modules/gridNMBidAdapter_spec.js +40 -1
  137. package/test/spec/modules/gumgumBidAdapter_spec.js +23 -6
  138. package/test/spec/modules/iasRtdProvider_spec.js +71 -6
  139. package/test/spec/modules/ixBidAdapter_spec.js +13 -3
  140. package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
  141. package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
  142. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +155 -1
  143. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +67 -12
  144. package/test/spec/modules/mediakeysBidAdapter_spec.js +406 -51
  145. package/test/spec/modules/multibid_spec.js +31 -31
  146. package/test/spec/modules/mytargetBidAdapter_spec.js +199 -0
  147. package/test/spec/modules/nativoBidAdapter_spec.js +50 -3
  148. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +13 -1
  149. package/test/spec/modules/nextrollBidAdapter_spec.js +290 -0
  150. package/test/spec/modules/nobidBidAdapter_spec.js +65 -1
  151. package/test/spec/modules/oguryBidAdapter_spec.js +125 -37
  152. package/test/spec/modules/openxBidAdapter_spec.js +85 -13
  153. package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
  154. package/test/spec/modules/otmBidAdapter_spec.js +67 -0
  155. package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
  156. package/test/spec/modules/publinkIdSystem_spec.js +34 -15
  157. package/test/spec/modules/pubmaticBidAdapter_spec.js +217 -1
  158. package/test/spec/modules/relaidoBidAdapter_spec.js +21 -20
  159. package/test/spec/modules/sharethroughBidAdapter_spec.js +156 -136
  160. package/test/spec/modules/slimcutBidAdapter_spec.js +200 -0
  161. package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
  162. package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
  163. package/test/spec/modules/spotxBidAdapter_spec.js +36 -0
  164. package/test/spec/modules/sspBCBidAdapter_spec.js +210 -62
  165. package/test/spec/modules/talkadsBidAdapter_spec.js +231 -0
  166. package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
  167. package/test/spec/modules/tripleliftBidAdapter_spec.js +128 -0
  168. package/test/spec/modules/trustxBidAdapter_spec.js +38 -5
  169. package/test/spec/modules/undertoneBidAdapter_spec.js +52 -0
  170. package/test/spec/modules/unicornBidAdapter_spec.js +4 -4
  171. package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
  172. package/test/spec/modules/videobyteBidAdapter_spec.js +2 -2
  173. package/test/spec/modules/visxBidAdapter_spec.js +48 -4
  174. package/test/spec/modules/yahoosspBidAdapter_spec.js +1332 -0
  175. package/test/spec/modules/yieldlabBidAdapter_spec.js +65 -1
  176. package/test/spec/modules/yieldmoBidAdapter_spec.js +30 -9
  177. package/test/spec/modules/yieldmoSyntheticInventoryModule_spec.js +89 -0
  178. package/test/spec/unit/core/adapterManager_spec.js +32 -0
  179. package/test/spec/unit/core/bidderFactory_spec.js +61 -1
  180. package/test/spec/unit/pbjs_api_spec.js +37 -2
  181. package/test/spec/unit/secureCreatives_spec.js +54 -25
  182. package/modules/turktelekomBidAdapter.md +0 -49
@@ -1,9 +1,11 @@
1
1
  import { expect } from 'chai';
2
+ import find from 'core-js-pure/features/array/find.js';
2
3
  import { spec } from 'modules/mediakeysBidAdapter.js';
3
4
  import { newBidder } from 'src/adapters/bidderFactory.js';
4
5
  import * as utils from 'src/utils.js';
5
6
  import { config } from 'src/config.js';
6
7
  import { BANNER, NATIVE, VIDEO } from '../../../src/mediaTypes.js';
8
+ import { OUTSTREAM } from '../../../src/video.js';
7
9
 
8
10
  describe('mediakeysBidAdapter', function () {
9
11
  const adapter = newBidder(spec);
@@ -39,39 +41,100 @@ describe('mediakeysBidAdapter', function () {
39
41
  }
40
42
  };
41
43
 
44
+ const bidNative = {
45
+ bidder: 'mediakeys',
46
+ params: {},
47
+ mediaTypes: {
48
+ native: {
49
+ body: {
50
+ required: true
51
+ },
52
+ title: {
53
+ required: true,
54
+ len: 800
55
+ },
56
+ sponsoredBy: {
57
+ required: true
58
+ },
59
+ body2: {
60
+ required: true
61
+ },
62
+ image: {
63
+ required: true,
64
+ sizes: [[300, 250], [300, 600], [100, 150]],
65
+ },
66
+ icon: {
67
+ required: true,
68
+ sizes: [50, 50],
69
+ },
70
+ },
71
+ },
72
+ nativeParams: {
73
+ body: {
74
+ required: true
75
+ },
76
+ title: {
77
+ required: true,
78
+ len: 800
79
+ },
80
+ sponsoredBy: {
81
+ required: true
82
+ },
83
+ body2: {
84
+ required: true
85
+ },
86
+ image: {
87
+ required: true,
88
+ sizes: [[300, 250], [300, 600], [100, 150]],
89
+ },
90
+ icon: {
91
+ required: true,
92
+ sizes: [50, 50],
93
+ },
94
+ },
95
+ adUnitCode: 'div-gpt-ad-1460505748561-0',
96
+ transactionId: '47789656-9e5c-4250-b7e0-2ce4cbe71a55',
97
+ bidId: '299320f4de980d',
98
+ bidderRequestId: '1c1b642f803242',
99
+ auctionId: '84212956-c377-40e8-b000-9885a06dc692',
100
+ src: 'client',
101
+ bidRequestsCount: 1,
102
+ bidderRequestsCount: 1,
103
+ bidderWinsCount: 0,
104
+ ortb2Imp: {
105
+ ext: { data: { something: 'test' } }
106
+ }
107
+ };
108
+
109
+ const bidVideo = {
110
+ bidder: 'mediakeys',
111
+ params: {},
112
+ mediaTypes: {
113
+ video: {
114
+ context: OUTSTREAM,
115
+ playerSize: [480, 320]
116
+ }
117
+ },
118
+ adUnitCode: 'div-gpt-ad-1460505748561-0',
119
+ transactionId: '47789656-9e5c-4250-b7e0-2ce4cbe71a55',
120
+ bidId: '299320f4de980d',
121
+ bidderRequestId: '1c1b642f803242',
122
+ auctionId: '84212956-c377-40e8-b000-9885a06dc692',
123
+ src: 'client',
124
+ bidRequestsCount: 1,
125
+ bidderRequestsCount: 1,
126
+ bidderWinsCount: 0,
127
+ ortb2Imp: {
128
+ ext: { data: { something: 'test' } }
129
+ }
130
+ };
131
+
42
132
  const bidderRequest = {
43
133
  bidderCode: 'mediakeys',
44
134
  auctionId: '84212956-c377-40e8-b000-9885a06dc692',
45
135
  bidderRequestId: '1c1b642f803242',
46
136
  bids: [
47
- {
48
- bidder: 'mediakeys',
49
- params: {},
50
- mediaTypes: {
51
- banner: {
52
- sizes: [
53
- [300, 250],
54
- [300, 600],
55
- ],
56
- },
57
- },
58
- adUnitCode: 'div-gpt-ad-1460505748561-0',
59
- transactionId: '47789656-9e5c-4250-b7e0-2ce4cbe71a55',
60
- sizes: [
61
- [300, 250],
62
- [300, 600],
63
- ],
64
- bidId: '299320f4de980d',
65
- bidderRequestId: '1c1b642f803242',
66
- auctionId: '84212956-c377-40e8-b000-9885a06dc692',
67
- src: 'client',
68
- bidRequestsCount: 1,
69
- bidderRequestsCount: 1,
70
- bidderWinsCount: 0,
71
- ortb2Imp: {
72
- ext: { data: { something: 'test' } }
73
- }
74
- },
137
+ bid
75
138
  ],
76
139
  auctionStart: 1620973766319,
77
140
  timeout: 1000,
@@ -116,23 +179,25 @@ describe('mediakeysBidAdapter', function () {
116
179
  it('should create imp for supported mediaType only', function() {
117
180
  const bidRequests = [utils.deepClone(bid)];
118
181
  const bidderRequestCopy = utils.deepClone(bidderRequest);
182
+ bidderRequestCopy.bids = bidRequests;
119
183
 
120
184
  bidRequests[0].mediaTypes.video = {
121
185
  playerSize: [300, 250],
122
- context: 'outstream'
186
+ context: OUTSTREAM
123
187
  }
124
188
 
125
- bidRequests[0].mediaTypes.native = {
126
- type: 'image'
127
- }
189
+ bidRequests[0].mediaTypes.native = bidNative.mediaTypes.native;
190
+ bidRequests[0].nativeParams = bidNative.mediaTypes.native;
191
+
192
+ bidderRequestCopy.bids = bidRequests[0];
128
193
 
129
194
  const request = spec.buildRequests(bidRequests, bidderRequestCopy);
130
195
  const data = request.data;
131
196
 
132
197
  expect(data.imp.length).to.equal(1);
133
198
  expect(data.imp[0].banner).to.exist;
134
- expect(data.imp[0].video).to.not.exist;
135
- expect(data.imp[0].native).to.not.exist;
199
+ expect(data.imp[0].video).to.exist;
200
+ expect(data.imp[0].native).to.exist;
136
201
  });
137
202
 
138
203
  it('should get expected properties with default values (no params set)', function () {
@@ -161,6 +226,205 @@ describe('mediakeysBidAdapter', function () {
161
226
  expect(data.imp[0].ext.data.something).to.equal('test');
162
227
  });
163
228
 
229
+ describe('native imp', function() {
230
+ it('should get a native object in request', function() {
231
+ const bidRequests = [utils.deepClone(bidNative)];
232
+ const bidderRequestCopy = utils.deepClone(bidderRequest);
233
+ bidderRequestCopy.bids = bidRequests;
234
+
235
+ const request = spec.buildRequests(bidRequests, bidderRequestCopy);
236
+ const data = request.data;
237
+
238
+ expect(data.imp.length).to.equal(1);
239
+ expect(data.imp[0].id).to.equal(bidRequests[0].bidId);
240
+ expect(data.imp[0].native).to.exist;
241
+ expect(data.imp[0].native.request.ver).to.equal('1.2');
242
+ expect(data.imp[0].native.request.context).to.equal(1);
243
+ expect(data.imp[0].native.request.plcmttype).to.equal(1);
244
+ expect(data.imp[0].native.request.assets.length).to.equal(6);
245
+ // find the asset body
246
+ const bodyAsset = find(data.imp[0].native.request.assets, asset => asset.id === 6);
247
+ expect(bodyAsset.data.type).to.equal(2);
248
+ });
249
+
250
+ it('should get a native object in request with properties filled with params values', function() {
251
+ const bidRequests = [utils.deepClone(bidNative)];
252
+ bidRequests[0].params = {
253
+ native: {
254
+ context: 3,
255
+ plcmttype: 3,
256
+ }
257
+ }
258
+ const bidderRequestCopy = utils.deepClone(bidderRequest);
259
+ bidderRequestCopy.bids = bidRequests;
260
+
261
+ const request = spec.buildRequests(bidRequests, bidderRequestCopy);
262
+ const data = request.data;
263
+
264
+ expect(data.imp.length).to.equal(1);
265
+ expect(data.imp[0].id).to.equal(bidRequests[0].bidId);
266
+ expect(data.imp[0].native).to.exist;
267
+ expect(data.imp[0].native.request.ver).to.equal('1.2');
268
+ expect(data.imp[0].native.request.context).to.equal(3);
269
+ expect(data.imp[0].native.request.plcmttype).to.equal(3);
270
+ expect(data.imp[0].native.request.assets.length).to.equal(6);
271
+ });
272
+
273
+ it('should get a native object in request when native type ,image" has been set', function() {
274
+ const bidRequests = [utils.deepClone(bidNative)];
275
+ bidRequests[0].mediaTypes.native = { type: 'image' };
276
+ bidRequests[0].nativeParams = {
277
+ image: { required: true },
278
+ title: { required: true },
279
+ sponsoredBy: { required: true },
280
+ clickUrl: { required: true }, // [1] Will be ignored as it is used in response validation only
281
+ body: { required: false },
282
+ icon: { required: false },
283
+ };
284
+
285
+ const bidderRequestCopy = utils.deepClone(bidderRequest);
286
+ bidderRequestCopy.bids = bidRequests;
287
+
288
+ const request = spec.buildRequests(bidRequests, bidderRequestCopy);
289
+ const data = request.data;
290
+
291
+ expect(data.imp.length).to.equal(1);
292
+ expect(data.imp[0].id).to.equal(bidRequests[0].bidId);
293
+ expect(data.imp[0].native).to.exist;
294
+ expect(data.imp[0].native.request.ver).to.equal('1.2');
295
+ expect(data.imp[0].native.request.context).to.equal(1);
296
+ expect(data.imp[0].native.request.plcmttype).to.equal(1);
297
+ expect(data.imp[0].native.request.assets.length).to.equal(5); // [1] clickUrl ignored
298
+ });
299
+
300
+ it('should log errors and ignore misformated assets', function() {
301
+ const bidRequests = [utils.deepClone(bidNative)];
302
+ delete bidRequests[0].nativeParams.title.len;
303
+ bidRequests[0].nativeParams.unregistred = {required: true};
304
+
305
+ const bidderRequestCopy = utils.deepClone(bidderRequest);
306
+ bidderRequestCopy.bids = bidRequests;
307
+
308
+ utilsMock.expects('logWarn').twice();
309
+
310
+ const request = spec.buildRequests(bidRequests, bidderRequestCopy);
311
+ const data = request.data;
312
+
313
+ expect(data.imp.length).to.equal(1);
314
+ expect(data.imp[0].id).to.equal(bidRequests[0].bidId);
315
+ expect(data.imp[0].native).to.exist;
316
+ expect(data.imp[0].native.request.assets.length).to.equal(5);
317
+ });
318
+ });
319
+
320
+ describe('video imp', function() {
321
+ it('should get a video object in request', function() {
322
+ const bidRequests = [utils.deepClone(bidVideo)];
323
+ const bidderRequestCopy = utils.deepClone(bidderRequest);
324
+ bidderRequestCopy.bids = bidRequests;
325
+
326
+ const request = spec.buildRequests(bidRequests, bidderRequestCopy);
327
+ const data = request.data;
328
+
329
+ expect(data.imp.length).to.equal(1);
330
+ expect(data.imp[0].id).to.equal(bidRequests[0].bidId);
331
+ expect(data.imp[0].banner).to.not.exist;
332
+ expect(data.imp[0].video).to.exist;
333
+ expect(data.imp[0].video.w).to.equal(480);
334
+ expect(data.imp[0].video.h).to.equal(320);
335
+ });
336
+
337
+ it('should ignore and warn misformated ORTB video properties', function() {
338
+ const bidRequests = [utils.deepClone(bidVideo)];
339
+ bidRequests[0].mediaTypes.video.unknown = 'foo';
340
+ bidRequests[0].mediaTypes.video.placement = 10;
341
+ bidRequests[0].mediaTypes.video.skipmin = 5;
342
+ const bidderRequestCopy = utils.deepClone(bidderRequest);
343
+ bidderRequestCopy.bids = bidRequests;
344
+
345
+ const request = spec.buildRequests(bidRequests, bidderRequestCopy);
346
+ const data = request.data;
347
+
348
+ expect(data.imp.length).to.equal(1);
349
+ expect(data.imp[0].id).to.equal(bidRequests[0].bidId);
350
+ expect(data.imp[0].banner).to.not.exist;
351
+ expect(data.imp[0].video).to.exist;
352
+ expect(data.imp[0].video.w).to.equal(480);
353
+ expect(data.imp[0].video.h).to.equal(320);
354
+ expect(data.imp[0].video.skipmin).to.equal(5);
355
+ expect(data.imp[0].video.placement).to.not.exist;
356
+ expect(data.imp[0].video.unknown).to.not.exist;
357
+ });
358
+
359
+ it('should merge adUnit mediaTypes level and bidder level params properties ', function() {
360
+ const bidRequests = [utils.deepClone(bidVideo)];
361
+ bidRequests[0].mediaTypes.video.placement = 1;
362
+ bidRequests[0].mediaTypes.video.mimes = ['video/mpeg4'];
363
+ bidRequests[0].mediaTypes.video.protocols = [1];
364
+ bidRequests[0].mediaTypes.video.minduration = 10;
365
+ bidRequests[0].mediaTypes.video.maxduration = 45;
366
+ bidRequests[0].mediaTypes.video.skipmin = 5;
367
+ bidRequests[0].mediaTypes.video.sequence = 3;
368
+ bidRequests[0].mediaTypes.video.linearity = 1;
369
+ bidRequests[0].mediaTypes.video.battr = [12];
370
+ bidRequests[0].mediaTypes.video.maxextended = 10;
371
+ bidRequests[0].mediaTypes.video.minbitrate = 720;
372
+ bidRequests[0].mediaTypes.video.maxbitrate = 720;
373
+ bidRequests[0].mediaTypes.video.boxingallowed = 1;
374
+ bidRequests[0].mediaTypes.video.playbackmethod = [1];
375
+ bidRequests[0].mediaTypes.video.playbackend = 2;
376
+ bidRequests[0].mediaTypes.video.delivery = 2;
377
+ bidRequests[0].mediaTypes.video.pos = 0;
378
+ bidRequests[0].mediaTypes.video.companionad = [{ w: 360, h: 80 }]
379
+ bidRequests[0].mediaTypes.video.api = [1];
380
+ bidRequests[0].mediaTypes.video.companiontype = [1];
381
+
382
+ // bidder level
383
+ bidRequests[0].params.video = {
384
+ pos: 2, // override
385
+ skip: 1,
386
+ skipafter: 10,
387
+ startdelay: 3
388
+ };
389
+
390
+ const bidderRequestCopy = utils.deepClone(bidderRequest);
391
+ bidderRequestCopy.bids = bidRequests;
392
+
393
+ utilsMock.expects('logWarn').never();
394
+
395
+ const request = spec.buildRequests(bidRequests, bidderRequestCopy);
396
+ const data = request.data;
397
+
398
+ expect(data.imp.length).to.equal(1);
399
+ expect(data.imp[0].id).to.equal(bidRequests[0].bidId);
400
+ expect(data.imp[0].banner).to.not.exist;
401
+ expect(data.imp[0].video).to.exist;
402
+
403
+ expect(Object.keys(data.imp[0].video).length).to.equal(23); // 21 ortb params (2 skipped) + computed width/height.
404
+ expect(data.imp[0].video.w).to.equal(480);
405
+ expect(data.imp[0].video.h).to.equal(320);
406
+ expect(data.imp[0].video.mimes[0]).to.equal('video/mpeg4');
407
+ expect(data.imp[0].video.pos).to.equal(2);
408
+ expect(data.imp[0].video.skip).to.equal(1);
409
+ expect(data.imp[0].video.skipafter).to.equal(10);
410
+ expect(data.imp[0].video.startdelay).to.equal(3);
411
+ expect(data.imp[0].video.companionad).to.not.exist;
412
+ expect(data.imp[0].video.companiontype).to.not.exist;
413
+ });
414
+
415
+ it('should log warn message when OpenRTB validation fails ', function() {
416
+ const bidRequests = [utils.deepClone(bidVideo)];
417
+ bidRequests[0].mediaTypes.video.placement = 'string';
418
+ bidRequests[0].mediaTypes.video.api = 1;
419
+ const bidderRequestCopy = utils.deepClone(bidderRequest);
420
+ bidderRequestCopy.bids = bidRequests;
421
+
422
+ utilsMock.expects('logWarn').twice();
423
+
424
+ spec.buildRequests(bidRequests, bidderRequestCopy);
425
+ });
426
+ });
427
+
164
428
  it('should get expected properties with values from params', function () {
165
429
  const bidRequests = [utils.deepClone(bid)];
166
430
  bidRequests[0].params = {
@@ -265,13 +529,25 @@ describe('mediakeysBidAdapter', function () {
265
529
  expect(data.imp[0].bidfloor).to.not.exist;
266
530
  });
267
531
 
268
- it('should get and set floor by mediatype', function() {
532
+ it('should get the highest floorPrice found when bid have several mediaTypes', function() {
269
533
  const bidWithPriceFloors = utils.deepClone(bid);
270
534
 
271
535
  bidWithPriceFloors.mediaTypes.video = {
272
536
  playerSize: [600, 480]
273
537
  };
274
538
 
539
+ bidWithPriceFloors.mediaTypes.native = {
540
+ body: {
541
+ required: true
542
+ }
543
+ };
544
+
545
+ bidWithPriceFloors.nativeParams = {
546
+ body: {
547
+ required: true
548
+ }
549
+ };
550
+
275
551
  bidWithPriceFloors.getFloor = getFloorTest;
276
552
 
277
553
  const bidRequests = [bidWithPriceFloors];
@@ -279,10 +555,9 @@ describe('mediakeysBidAdapter', function () {
279
555
  const data = request.data;
280
556
 
281
557
  expect(data.imp[0].banner).to.exist;
282
- expect(data.imp[0].bidfloor).to.equal(1);
283
-
284
- // expect(data.imp[1].video).to.exist;
285
- // expect(data.imp[1].bidfloor).to.equal(5);
558
+ expect(data.imp[0].video).to.exist;
559
+ expect(data.imp[0].native).to.exist;
560
+ expect(data.imp[0].bidfloor).to.equal(5);
286
561
  });
287
562
 
288
563
  it('should set properties at payload level from FPD', function() {
@@ -420,8 +695,8 @@ describe('mediakeysBidAdapter', function () {
420
695
  const bidRequests = [utils.deepClone(bid)];
421
696
  const request = spec.buildRequests(bidRequests, bidderRequest);
422
697
  sinon.stub(utils, 'isArray').throws();
423
- spec.interpretResponse(rawServerResponse, request);
424
698
  utilsMock.expects('logError').once();
699
+ spec.interpretResponse(rawServerResponse, request);
425
700
  utils.isArray.restore();
426
701
  });
427
702
 
@@ -483,28 +758,108 @@ describe('mediakeysBidAdapter', function () {
483
758
  });
484
759
  });
485
760
 
486
- it('Build video response', function () {
487
- const bidRequests = [utils.deepClone(bid)];
761
+ it('interprets video bid response', function () {
762
+ const vastUrl = 'https://url.local?req=content';
763
+ const bidRequests = [utils.deepClone(bidVideo)];
488
764
  const request = spec.buildRequests(bidRequests, bidderRequest);
765
+
489
766
  const rawServerResponseVideo = utils.deepClone(rawServerResponse);
490
767
  rawServerResponseVideo.body.seatbid[0].bid[0].ext.prebid.type = 'V';
768
+ rawServerResponseVideo.body.seatbid[0].bid[0].ext.vast_url = vastUrl;
769
+
491
770
  const response = spec.interpretResponse(rawServerResponseVideo, request);
492
771
 
493
772
  expect(response.length).to.equal(1);
494
773
  expect(response[0].mediaType).to.equal('video');
495
774
  expect(response[0].meta.mediaType).to.equal('video');
775
+ expect(response[0].vastXml).to.not.exist;
776
+ expect(response[0].vastUrl).to.equal(vastUrl + '&no_cache');
777
+ expect(response[0].videoCacheKey).to.equal('no_cache');
496
778
  });
497
779
 
498
- it('Build native response', function () {
499
- const bidRequests = [utils.deepClone(bid)];
500
- const request = spec.buildRequests(bidRequests, bidderRequest);
501
- const rawServerResponseVideo = utils.deepClone(rawServerResponse);
502
- rawServerResponseVideo.body.seatbid[0].bid[0].ext.prebid.type = 'N';
503
- const response = spec.interpretResponse(rawServerResponseVideo, request);
780
+ describe('Native response', function () {
781
+ let bidRequests;
782
+ let bidderRequestCopy;
783
+ let request;
784
+ let rawServerResponseNative;
785
+ let nativeObject;
786
+
787
+ beforeEach(function() {
788
+ bidRequests = [utils.deepClone(bidNative)];
789
+ bidderRequestCopy = utils.deepClone(bidderRequest);
790
+ bidderRequestCopy.bids = bidRequests;
791
+
792
+ request = spec.buildRequests(bidRequests, bidderRequestCopy);
793
+
794
+ nativeObject = {
795
+ ver: '1.2',
796
+ privacy: 'https://privacy.me',
797
+ assets: [
798
+ { id: 5, data: { type: 1, value: 'Sponsor Brand' } },
799
+ { id: 6, data: { type: 2, value: 'Brand Body' } },
800
+ { id: 14, data: { type: 10, value: 'Brand Body 2' } },
801
+ { id: 1, title: { text: 'Brand Title' } },
802
+ { id: 2, img: { type: 3, url: 'https://url.com/img.jpg', w: 300, h: 250 } },
803
+ { id: 3, img: { type: 1, url: 'https://url.com/ico.png', w: 50, h: 50 } },
804
+ ],
805
+ link: {
806
+ url: 'https://brand.me',
807
+ clicktrackers: [
808
+ 'https://click.me'
809
+ ]
810
+ },
811
+ eventtrackers: [
812
+ { event: 1, method: 1, url: 'https://click.me' },
813
+ { event: 1, method: 2, url: 'https://click-script.me' }
814
+ ]
815
+ };
504
816
 
505
- expect(response.length).to.equal(1);
506
- expect(response[0].mediaType).to.equal('native');
507
- expect(response[0].meta.mediaType).to.equal('native');
817
+ rawServerResponseNative = utils.deepClone(rawServerResponse);
818
+ rawServerResponseNative.body.seatbid[0].bid[0].ext.prebid.type = 'N';
819
+ rawServerResponseNative.body.seatbid[0].bid[0].adm = JSON.stringify(nativeObject)
820
+ });
821
+
822
+ it('should ignore invalid native response', function() {
823
+ const nativeObjectCopy = utils.deepClone(nativeObject);
824
+ nativeObjectCopy.assets = [];
825
+ const rawServerResponseNativeCopy = utils.deepClone(rawServerResponseNative);
826
+ rawServerResponseNativeCopy.body.seatbid[0].bid[0].adm = JSON.stringify(nativeObjectCopy)
827
+ const response = spec.interpretResponse(rawServerResponseNativeCopy, request);
828
+ expect(response.length).to.equal(1);
829
+ expect(response[0].native).to.not.exist;
830
+ });
831
+
832
+ it('should build a classic Prebid.js native object for response', function() {
833
+ const rawServerResponseNativeCopy = utils.deepClone(rawServerResponseNative);
834
+ const response = spec.interpretResponse(rawServerResponseNativeCopy, request);
835
+ expect(response.length).to.equal(1);
836
+ expect(response[0].mediaType).to.equal('native');
837
+ expect(response[0].meta.mediaType).to.equal('native');
838
+ expect(response[0].native).to.exist;
839
+ expect(response[0].native.body).to.exist;
840
+ expect(response[0].native.privacyLink).to.exist;
841
+ expect(response[0].native.body2).to.exist;
842
+ expect(response[0].native.sponsoredBy).to.exist;
843
+ expect(response[0].native.image).to.exist;
844
+ expect(response[0].native.icon).to.exist;
845
+ expect(response[0].native.title).to.exist;
846
+ expect(response[0].native.clickUrl).to.exist;
847
+ expect(response[0].native.clickTrackers).to.exist;
848
+ expect(response[0].native.clickTrackers.length).to.equal(1);
849
+ expect(response[0].native.javascriptTrackers).to.equal('<script src="https://click-script.me"></script>');
850
+ expect(response[0].native.impressionTrackers).to.exist;
851
+ expect(response[0].native.impressionTrackers.length).to.equal(1);
852
+ });
853
+
854
+ it('should ignore eventtrackers with a unsupported type', function() {
855
+ const rawServerResponseNativeCopy = utils.deepClone(rawServerResponseNative);
856
+ const nativeObjectCopy = utils.deepClone(nativeObject);
857
+ nativeObjectCopy.eventtrackers[0].event = 2;
858
+ rawServerResponseNativeCopy.body.seatbid[0].bid[0].adm = JSON.stringify(nativeObjectCopy);
859
+ const response = spec.interpretResponse(rawServerResponseNativeCopy, request);
860
+ expect(response[0].native.impressionTrackers).to.exist;
861
+ expect(response[0].native.impressionTrackers.length).to.equal(0);
862
+ })
508
863
  });
509
864
  });
510
865