prebid.js 7.3.0 → 7.6.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 (225) hide show
  1. package/.circleci/config.yml +11 -6
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/adagioBidAdapter.js +1 -1
  4. package/dist/adbookpspBidAdapter.js +1 -1
  5. package/dist/adgenerationBidAdapter.js +1 -1
  6. package/dist/adnuntiusBidAdapter.js +1 -1
  7. package/dist/adotBidAdapter.js +1 -1
  8. package/dist/adpod.js +1 -1
  9. package/dist/adrelevantisBidAdapter.js +1 -1
  10. package/dist/adrinoBidAdapter.js +1 -1
  11. package/dist/adtelligentBidAdapter.js +1 -1
  12. package/dist/adxcgBidAdapter.js +1 -1
  13. package/dist/ajaBidAdapter.js +1 -1
  14. package/dist/amxBidAdapter.js +1 -1
  15. package/dist/amxIdSystem.js +1 -1
  16. package/dist/appierAnalyticsAdapter.js +1 -1
  17. package/dist/appnexusBidAdapter.js +1 -1
  18. package/dist/asoBidAdapter.js +1 -1
  19. package/dist/atsAnalyticsAdapter.js +1 -1
  20. package/dist/axonixBidAdapter.js +1 -1
  21. package/dist/bidglassBidAdapter.js +1 -1
  22. package/dist/big-richmediaBidAdapter.js +1 -1
  23. package/dist/bridgewellBidAdapter.js +1 -1
  24. package/dist/brightMountainMediaBidAdapter.js +1 -1
  25. package/dist/byDataAnalyticsAdapter.js +1 -1
  26. package/dist/concertBidAdapter.js +1 -1
  27. package/dist/connectadBidAdapter.js +1 -1
  28. package/dist/consumableBidAdapter.js +1 -1
  29. package/dist/conversantBidAdapter.js +1 -1
  30. package/dist/craftBidAdapter.js +1 -1
  31. package/dist/criteoBidAdapter.js +1 -1
  32. package/dist/debugging-standalone.js +1 -1
  33. package/dist/debugging.js +1 -1
  34. package/dist/dspxBidAdapter.js +1 -1
  35. package/dist/eplanningBidAdapter.js +1 -1
  36. package/dist/finativeBidAdapter.js +1 -1
  37. package/dist/gdprEnforcement.js +1 -1
  38. package/dist/glimpseBidAdapter.js +1 -1
  39. package/dist/gmosspBidAdapter.js +1 -1
  40. package/dist/goldbachBidAdapter.js +1 -1
  41. package/dist/gridBidAdapter.js +1 -1
  42. package/dist/gridNMBidAdapter.js +1 -1
  43. package/dist/gumgumBidAdapter.js +1 -1
  44. package/dist/h12mediaBidAdapter.js +1 -1
  45. package/dist/hadronIdSystem.js +1 -1
  46. package/dist/hadronRtdProvider.js +1 -1
  47. package/dist/id5IdSystem.js +1 -1
  48. package/dist/imRtdProvider.js +1 -1
  49. package/dist/improvedigitalBidAdapter.js +1 -1
  50. package/dist/inmarBidAdapter.js +1 -1
  51. package/dist/insticatorBidAdapter.js +1 -1
  52. package/dist/ixBidAdapter.js +1 -1
  53. package/dist/justpremiumBidAdapter.js +1 -1
  54. package/dist/kargoAnalyticsAdapter.js +1 -1
  55. package/dist/kargoBidAdapter.js +1 -1
  56. package/dist/konduitAnalyticsAdapter.js +1 -1
  57. package/dist/kueezBidAdapter.js +1 -1
  58. package/dist/lassoBidAdapter.js +1 -1
  59. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  60. package/dist/logicadBidAdapter.js +1 -1
  61. package/dist/loglyliftBidAdapter.js +1 -1
  62. package/dist/malltvAnalyticsAdapter.js +1 -1
  63. package/dist/marsmediaBidAdapter.js +1 -1
  64. package/dist/mediafuseBidAdapter.js +1 -1
  65. package/dist/mediasquareBidAdapter.js +1 -1
  66. package/dist/mgidBidAdapter.js +1 -1
  67. package/dist/minutemediaBidAdapter.js +1 -1
  68. package/dist/missenaBidAdapter.js +1 -1
  69. package/dist/newspassidBidAdapter.js +1 -0
  70. package/dist/nextMillenniumBidAdapter.js +1 -1
  71. package/dist/not-for-prod/prebid.js +131 -127
  72. package/dist/oguryBidAdapter.js +1 -1
  73. package/dist/onetagBidAdapter.js +1 -1
  74. package/dist/ooloAnalyticsAdapter.js +1 -1
  75. package/dist/openxOrtbBidAdapter.js +1 -0
  76. package/dist/outbrainBidAdapter.js +1 -1
  77. package/dist/parrableIdSystem.js +1 -1
  78. package/dist/pixfutureBidAdapter.js +1 -1
  79. package/dist/prebid-core.js +2 -2
  80. package/dist/priceFloors.js +1 -1
  81. package/dist/pubCommonId.js +1 -1
  82. package/dist/publinkIdSystem.js +1 -1
  83. package/dist/pubmaticBidAdapter.js +1 -1
  84. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  85. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  86. package/dist/pxyzBidAdapter.js +1 -1
  87. package/dist/quantcastBidAdapter.js +1 -1
  88. package/dist/rasBidAdapter.js +1 -0
  89. package/dist/readpeakBidAdapter.js +1 -1
  90. package/dist/relaidoBidAdapter.js +1 -1
  91. package/dist/rhythmoneBidAdapter.js +1 -1
  92. package/dist/riseBidAdapter.js +1 -1
  93. package/dist/rubiconAnalyticsAdapter.js +1 -1
  94. package/dist/rubiconBidAdapter.js +1 -1
  95. package/dist/seedingAllianceBidAdapter.js +1 -1
  96. package/dist/seedtagBidAdapter.js +1 -1
  97. package/dist/sharedIdSystem.js +1 -1
  98. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  99. package/dist/sharethroughBidAdapter.js +1 -1
  100. package/dist/shinezBidAdapter.js +1 -0
  101. package/dist/sizeMappingV2.js +1 -1
  102. package/dist/smaatoBidAdapter.js +1 -1
  103. package/dist/smartadserverBidAdapter.js +1 -1
  104. package/dist/smartxBidAdapter.js +1 -1
  105. package/dist/smilewantedBidAdapter.js +1 -1
  106. package/dist/sonobiBidAdapter.js +1 -1
  107. package/dist/sovrnAnalyticsAdapter.js +1 -1
  108. package/dist/sovrnBidAdapter.js +1 -1
  109. package/dist/sspBCBidAdapter.js +1 -1
  110. package/dist/sublimeBidAdapter.js +1 -1
  111. package/dist/synacormediaBidAdapter.js +1 -1
  112. package/dist/taboolaBidAdapter.js +1 -1
  113. package/dist/targetVideoBidAdapter.js +1 -1
  114. package/dist/teadsBidAdapter.js +1 -1
  115. package/dist/trionBidAdapter.js +1 -1
  116. package/dist/tripleliftBidAdapter.js +1 -1
  117. package/dist/ttdBidAdapter.js +1 -1
  118. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  119. package/dist/underdogmediaBidAdapter.js +1 -1
  120. package/dist/undertoneBidAdapter.js +1 -1
  121. package/dist/ventesBidAdapter.js +1 -1
  122. package/dist/vidazooBidAdapter.js +1 -1
  123. package/dist/videobyteBidAdapter.js +1 -1
  124. package/dist/visxBidAdapter.js +1 -1
  125. package/dist/vrtcalBidAdapter.js +1 -1
  126. package/dist/vuukleBidAdapter.js +1 -1
  127. package/dist/widespaceBidAdapter.js +1 -1
  128. package/dist/winrBidAdapter.js +1 -1
  129. package/dist/yahoosspBidAdapter.js +1 -1
  130. package/dist/yieldmoBidAdapter.js +1 -1
  131. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  132. package/gulpfile.js +1 -1
  133. package/karma.conf.maker.js +3 -1
  134. package/modules/adgenerationBidAdapter.js +24 -1
  135. package/modules/adnuntiusBidAdapter.js +26 -8
  136. package/modules/adotBidAdapter.js +13 -4
  137. package/modules/adrinoBidAdapter.js +10 -2
  138. package/modules/adrinoBidAdapter.md +6 -0
  139. package/modules/adtelligentBidAdapter.js +2 -1
  140. package/modules/appnexusBidAdapter.js +3 -3
  141. package/modules/atsAnalyticsAdapter.js +4 -5
  142. package/modules/byDataAnalyticsAdapter.js +172 -74
  143. package/modules/byDataAnalyticsAdapter.md +5 -6
  144. package/modules/consumableBidAdapter.js +12 -1
  145. package/modules/criteoBidAdapter.js +7 -1
  146. package/modules/cwireBidAdapter.md +1 -1
  147. package/modules/debugging/bidInterceptor.js +1 -1
  148. package/modules/debugging/index.js +2 -1
  149. package/modules/eplanningBidAdapter.js +82 -97
  150. package/modules/gdprEnforcement.js +8 -14
  151. package/modules/gridNMBidAdapter.js +45 -4
  152. package/modules/hadronAnalyticsAdapter.md +5 -5
  153. package/modules/hadronIdSystem.js +18 -5
  154. package/modules/hadronIdSystem.md +15 -11
  155. package/modules/hadronRtdProvider.js +14 -1
  156. package/modules/hadronRtdProvider.md +17 -13
  157. package/modules/imRtdProvider.js +0 -8
  158. package/modules/insticatorBidAdapter.js +9 -0
  159. package/modules/ixBidAdapter.js +462 -58
  160. package/modules/ixBidAdapter.md +95 -5
  161. package/modules/kargoAnalyticsAdapter.js +88 -6
  162. package/modules/kargoAnalyticsAdapter.md +33 -0
  163. package/modules/kargoBidAdapter.js +1 -2
  164. package/modules/minutemediaBidAdapter.js +1 -0
  165. package/modules/missenaBidAdapter.js +20 -2
  166. package/modules/newspassidBidAdapter.js +649 -0
  167. package/modules/nextMillenniumBidAdapter.js +17 -1
  168. package/modules/oguryBidAdapter.js +2 -0
  169. package/modules/openxBidAdapter.md +3 -1
  170. package/modules/openxOrtbBidAdapter.js +349 -0
  171. package/modules/openxOrtbBidAdapter.md +105 -0
  172. package/modules/priceFloors.js +1 -1
  173. package/modules/pubCommonId.js +1 -2
  174. package/modules/pubxaiAnalyticsAdapter.js +6 -1
  175. package/modules/rasBidAdapter.js +149 -0
  176. package/modules/rasBidAdapter.md +50 -0
  177. package/modules/readpeakBidAdapter.js +15 -6
  178. package/modules/relaidoBidAdapter.js +19 -4
  179. package/modules/seedtagBidAdapter.js +37 -1
  180. package/modules/sharedIdSystem.js +11 -5
  181. package/modules/sharethroughBidAdapter.js +9 -24
  182. package/modules/shinezBidAdapter.js +435 -0
  183. package/modules/shinezBidAdapter.md +76 -0
  184. package/modules/taboolaBidAdapter.js +1 -1
  185. package/modules/taboolaBidAdapter.md +3 -3
  186. package/modules/ventesBidAdapter.js +1 -1
  187. package/modules/ventesBidAdapter.md +1 -1
  188. package/modules/vrtcalBidAdapter.js +35 -0
  189. package/package.json +1 -1
  190. package/plugins/pbjsGlobals.js +2 -1
  191. package/src/storageManager.js +4 -5
  192. package/test/spec/modules/adgenerationBidAdapter_spec.js +52 -4
  193. package/test/spec/modules/adnuntiusBidAdapter_spec.js +126 -14
  194. package/test/spec/modules/adotBidAdapter_spec.js +12 -9
  195. package/test/spec/modules/adrinoBidAdapter_spec.js +22 -0
  196. package/test/spec/modules/appnexusBidAdapter_spec.js +165 -156
  197. package/test/spec/modules/byDataAnalyticsAdapter_spec.js +74 -24
  198. package/test/spec/modules/consumableBidAdapter_spec.js +75 -0
  199. package/test/spec/modules/criteoBidAdapter_spec.js +15 -5
  200. package/test/spec/modules/debugging_mod_spec.js +7 -0
  201. package/test/spec/modules/eplanningBidAdapter_spec.js +58 -18
  202. package/test/spec/modules/gdprEnforcement_spec.js +53 -100
  203. package/test/spec/modules/gridNMBidAdapter_spec.js +32 -0
  204. package/test/spec/modules/hadronIdSystem_spec.js +2 -2
  205. package/test/spec/modules/imRtdProvider_spec.js +0 -1
  206. package/test/spec/modules/insticatorBidAdapter_spec.js +22 -1
  207. package/test/spec/modules/ixBidAdapter_spec.js +470 -10
  208. package/test/spec/modules/kargoAnalyticsAdapter_spec.js +42 -0
  209. package/test/spec/modules/kargoBidAdapter_spec.js +1 -0
  210. package/test/spec/modules/minutemediaBidAdapter_spec.js +3 -0
  211. package/test/spec/modules/missenaBidAdapter_spec.js +36 -14
  212. package/test/spec/modules/newspassidBidAdapter_spec.js +1793 -0
  213. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +20 -0
  214. package/test/spec/modules/openxOrtbBidAdapter_spec.js +1303 -0
  215. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +5 -0
  216. package/test/spec/modules/rasBidAdapter_spec.js +190 -0
  217. package/test/spec/modules/readpeakBidAdapter_spec.js +1 -0
  218. package/test/spec/modules/relaidoBidAdapter_spec.js +29 -2
  219. package/test/spec/modules/seedtagBidAdapter_spec.js +29 -0
  220. package/test/spec/modules/sharethroughBidAdapter_spec.js +4 -4
  221. package/test/spec/modules/shinezBidAdapter_spec.js +479 -0
  222. package/test/spec/modules/taboolaBidAdapter_spec.js +1 -1
  223. package/test/spec/modules/ventesBidAdapter_spec.js +2 -2
  224. package/test/spec/modules/vrtcalBidAdapter_spec.js +17 -0
  225. package/webpack.conf.js +1 -1
@@ -4,12 +4,13 @@ import { expect } from 'chai';
4
4
  import { newBidder } from 'src/adapters/bidderFactory.js';
5
5
  import { spec, storage, ERROR_CODES } from '../../../modules/ixBidAdapter.js';
6
6
  import { createEidsArray } from 'modules/userId/eids.js';
7
- import { deepAccess } from '../../../src/utils.js';
7
+ import { deepAccess, deepClone } from '../../../src/utils.js';
8
8
 
9
9
  describe('IndexexchangeAdapter', function () {
10
10
  const IX_SECURE_ENDPOINT = 'https://htlb.casalemedia.com/openrtb/pbjs';
11
11
  const VIDEO_ENDPOINT_VERSION = 8.1;
12
12
  const BANNER_ENDPOINT_VERSION = 7.2;
13
+ const NATIVE_ENDPOINT_VERSION = undefined;
13
14
 
14
15
  const SAMPLE_SCHAIN = {
15
16
  'ver': '1.0',
@@ -120,6 +121,11 @@ describe('IndexexchangeAdapter', function () {
120
121
  playerSize: [[400, 100]]
121
122
  }
122
123
  },
124
+ ortb2Imp: {
125
+ ext: {
126
+ tid: '173f49a8-7549-4218-a23c-e7ba59b47230'
127
+ }
128
+ },
123
129
  adUnitCode: 'div-gpt-ad-1460505748562-0',
124
130
  transactionId: '173f49a8-7549-4218-a23c-e7ba59b47230',
125
131
  bidId: '1a2b3c4e',
@@ -142,6 +148,11 @@ describe('IndexexchangeAdapter', function () {
142
148
  sizes: [[300, 250]]
143
149
  }
144
150
  },
151
+ ortb2Imp: {
152
+ ext: {
153
+ tid: '173f49a8-7549-4218-a23c-e7ba59b47229'
154
+ }
155
+ },
145
156
  adUnitCode: 'div-gpt-ad-1460505748561-0',
146
157
  transactionId: '173f49a8-7549-4218-a23c-e7ba59b47229',
147
158
  bidId: '1a2b3c4d',
@@ -164,6 +175,11 @@ describe('IndexexchangeAdapter', function () {
164
175
  sizes: [[300, 250], [300, 600]]
165
176
  }
166
177
  },
178
+ ortb2Imp: {
179
+ ext: {
180
+ tid: '173f49a8-7549-4218-a23c-e7ba59b47229'
181
+ }
182
+ },
167
183
  adUnitCode: 'div-gpt-ad-1460505748561-0',
168
184
  transactionId: '173f49a8-7549-4218-a23c-e7ba59b47229',
169
185
  bidId: '1a2b3c4d',
@@ -184,6 +200,11 @@ describe('IndexexchangeAdapter', function () {
184
200
  sizes: [[300, 250], [300, 600]]
185
201
  }
186
202
  },
203
+ ortb2Imp: {
204
+ ext: {
205
+ tid: '173f49a8-7549-4218-a23c-e7ba59b47229'
206
+ }
207
+ },
187
208
  adUnitCode: 'div-gpt-ad-1460505748561-0',
188
209
  transactionId: '173f49a8-7549-4218-a23c-e7ba59b47229',
189
210
  bidId: '1a2b3c4d',
@@ -213,6 +234,11 @@ describe('IndexexchangeAdapter', function () {
213
234
  protocols: [2]
214
235
  }
215
236
  },
237
+ ortb2Imp: {
238
+ ext: {
239
+ tid: '173f49a8-7549-4218-a23c-e7ba59b47230'
240
+ }
241
+ },
216
242
  adUnitCode: 'div-gpt-ad-1460505748562-0',
217
243
  transactionId: '173f49a8-7549-4218-a23c-e7ba59b47230',
218
244
  bidId: '1a2b3c4e',
@@ -246,6 +272,11 @@ describe('IndexexchangeAdapter', function () {
246
272
  playerSize: [[400, 100], [200, 400]]
247
273
  }
248
274
  },
275
+ ortb2Imp: {
276
+ ext: {
277
+ tid: '173f49a8-7549-4218-a23c-e7ba59b47230'
278
+ }
279
+ },
249
280
  adUnitCode: 'div-gpt-ad-1460505748562-0',
250
281
  transactionId: '173f49a8-7549-4218-a23c-e7ba59b47230',
251
282
  bidId: '1a2b3c4e',
@@ -271,6 +302,11 @@ describe('IndexexchangeAdapter', function () {
271
302
  sizes: [[300, 250], [300, 600], [400, 500]]
272
303
  }
273
304
  },
305
+ ortb2Imp: {
306
+ ext: {
307
+ tid: '173f49a8-7549-4218-a23c-e7ba59b47230'
308
+ }
309
+ },
274
310
  adUnitCode: 'div-gpt-ad-1460505748562-0',
275
311
  transactionId: '173f49a8-7549-4218-a23c-e7ba59b47230',
276
312
  bidId: '1a2b3c4e',
@@ -306,6 +342,11 @@ describe('IndexexchangeAdapter', function () {
306
342
  sizes: [[300, 250], [300, 600]]
307
343
  }
308
344
  },
345
+ ortb2Imp: {
346
+ ext: {
347
+ tid: '173f49a8-7549-4218-a23c-e7ba59b47230'
348
+ }
349
+ },
309
350
  adUnitCode: 'div-gpt-ad-1460505748562-0',
310
351
  transactionId: '273f49a8-7549-4218-a23c-e7ba59b47230',
311
352
  bidId: '1a2b3c4e',
@@ -315,6 +356,88 @@ describe('IndexexchangeAdapter', function () {
315
356
  }
316
357
  ];
317
358
 
359
+ const DEFAULT_NATIVE_VALID_BID = [
360
+ {
361
+ bidder: 'ix',
362
+ params: {
363
+ siteId: '123',
364
+ size: [300, 250]
365
+ },
366
+ sizes: [[300, 250], [300, 600]],
367
+ mediaTypes: {
368
+ native: {
369
+ icon: {
370
+ required: false
371
+ },
372
+ title: {
373
+ required: true
374
+ },
375
+ body: {
376
+ required: true
377
+ },
378
+ image: {
379
+ required: true
380
+ },
381
+ video: {
382
+ required: false
383
+ },
384
+ sponsoredBy: {
385
+ required: true
386
+ }
387
+ }
388
+ },
389
+ adUnitCode: 'div-gpt-ad-1460505748563-0',
390
+ transactionId: '173f49a8-7549-4218-a23c-e7ba59b47231',
391
+ bidId: '1a2b3c4f',
392
+ bidderRequestId: '11a22b33c44f',
393
+ auctionId: '1aa2bb3cc4df',
394
+ schain: SAMPLE_SCHAIN
395
+ }
396
+ ];
397
+
398
+ const DEFAULT_MULTIFORMAT_NATIVE_VALID_BID = [
399
+ {
400
+ bidder: 'ix',
401
+ params: {
402
+ siteId: '123',
403
+ size: [300, 250],
404
+ },
405
+ mediaTypes: {
406
+ banner: {
407
+ sizes: [[300, 250], [300, 600], [400, 500]]
408
+ },
409
+ native: {
410
+ title: {
411
+ required: true
412
+ },
413
+ body: {
414
+ required: true
415
+ },
416
+ image: {
417
+ required: true
418
+ },
419
+ sponsoredBy: {
420
+ required: true
421
+ },
422
+ icon: {
423
+ required: false
424
+ }
425
+ }
426
+ },
427
+ adUnitCode: 'div-gpt-ad-1460505748562-0',
428
+ transactionId: '173f49a8-7549-4218-a23c-e7ba59b47230',
429
+ bidId: '1a2b3c4e',
430
+ bidderRequestId: '11a22b33c44e',
431
+ auctionId: '1aa2bb3cc4de',
432
+ schain: SAMPLE_SCHAIN
433
+ }
434
+ ];
435
+
436
+ const DEFAULT_NATIVE_IMP = {
437
+ request: '{"assets":[{"required":0,"img":{"type":1},"id":201},{"required":1,"title":{"len":25},"id":100},{"required":1,"data":{"type":2},"id":402},{"required":1,"img":{"type":3},"id":203},{"required":0,"video":{"mimes":["video/mp4","video/webm"],"minduration":0,"maxduration":120,"protocols":[2,3,5,6]},"id":300},{"required":1,"data":{"type":1},"id":401}],"ver":"1.2","eventtrackers":[{"event":1,"methods":[1,2]}],"privacy":1}',
438
+ ver: '1.2'
439
+ }
440
+
318
441
  const DEFAULT_BANNER_BID_RESPONSE = {
319
442
  cur: 'USD',
320
443
  id: '11a22b33c44d',
@@ -437,6 +560,34 @@ describe('IndexexchangeAdapter', function () {
437
560
  ]
438
561
  };
439
562
 
563
+ const DEFAULT_NATIVE_BID_RESPONSE = {
564
+ cur: 'USD',
565
+ id: '11a22b33c44d',
566
+ seatbid: [
567
+ {
568
+ bid: [
569
+ {
570
+ crid: '12345',
571
+ adomain: ['www.abc.com'],
572
+ adid: '14851455',
573
+ impid: '1a2b3c4d',
574
+ cid: '3051266',
575
+ price: 100,
576
+ id: '1',
577
+ ext: {
578
+ dspid: 50,
579
+ pricelevel: '_100',
580
+ advbrandid: 303325,
581
+ advbrand: 'OECTA'
582
+ },
583
+ adm: '{"native":{"ver":"1.2","assets":[{"id":201,"img":{"url":"https://cdn.liftoff.io/customers/1209/creatives/2501-icon-250x250.png","w":250,"h":250}},{"id":203,"img":{"url":"https://cdn.liftoff.io/customers/5a9cab9cc6/image/lambda_png/a0355879b06c09b09232.png","w":1200,"h":627}},{"id":401,"data":{"value":"autodoc.co.uk"}},{"id":402,"data":{"value":"Les pièces automobiles dont vous avez besoin, toujours sous la main."}},{"id":100,"title":{"text":"Autodoc"}},{"id":300,"video":{"vasttag":"<VAST>blah</VAST>"}}],"link":{"url":"https://play.google.com/store/apps/details?id=de.autodoc.gmbh","clicktrackers":["https://click.liftoff.io/v1/campaign_click/blah"]},"eventtrackers":[{"event":1,"method":1,"url":"https://impression-europe.liftoff.io/index/impression"},{"event":1,"method":1,"url":"https://a701.casalemedia.com/impression/v1"}],"privacy":"https://privacy.link.com"}}'
584
+ }
585
+ ],
586
+ seat: '3970'
587
+ }
588
+ ]
589
+ };
590
+
440
591
  const DEFAULT_OPTION = {
441
592
  gdprConsent: {
442
593
  gdprApplies: true,
@@ -566,18 +717,109 @@ describe('IndexexchangeAdapter', function () {
566
717
  const syncOptions = {
567
718
  'iframeEnabled': true
568
719
  }
569
- let userSync = spec.getUserSyncs(syncOptions);
720
+ let userSync = spec.getUserSyncs(syncOptions, []);
570
721
  expect(userSync[0].type).to.equal('iframe');
571
722
  const USER_SYNC_URL = 'https://js-sec.indexww.com/um/ixmatch.html';
572
723
  expect(userSync[0].url).to.equal(USER_SYNC_URL);
573
724
  });
574
725
 
575
- it('When iframeEnabled is false, no userSync should be returned', function () {
726
+ it('When iframeEnabled = false, default to img', function () {
727
+ const syncOptions = {
728
+ 'iframeEnabled': false,
729
+ }
730
+ let userSync = spec.getUserSyncs(syncOptions, []);
731
+ expect(userSync[0].type).to.equal('image');
732
+ const USER_SYNC_URL = 'https://dsum.casalemedia.com/pbusermatch?origin=prebid&site_id=123&p=1&i=0&gdpr=1&gdpr_consent=3huaa11=qu3198ae&us_privacy=';
733
+ expect(userSync[0].url).to.equal(USER_SYNC_URL);
734
+ });
735
+
736
+ it('UserSync test : check type = pixel, check usermatch URL, no exchange data, only drop 1', function () {
576
737
  const syncOptions = {
577
- 'iframeEnabled': false
738
+ 'pixelEnabled': true
578
739
  }
579
- let userSync = spec.getUserSyncs(syncOptions);
580
- expect(userSync).to.be.an('array').that.is.empty;
740
+ config.setConfig({
741
+ userSync: {
742
+ pixelEnabled: true,
743
+ syncsPerBidder: 3
744
+ }
745
+ })
746
+ let userSync = spec.getUserSyncs(syncOptions, []);
747
+ expect(userSync[0].type).to.equal('image');
748
+ const USER_SYNC_URL = 'https://dsum.casalemedia.com/pbusermatch?origin=prebid&site_id=123&p=1&i=0&gdpr=1&gdpr_consent=3huaa11=qu3198ae&us_privacy=';
749
+ expect(userSync[0].url).to.equal(USER_SYNC_URL);
750
+ });
751
+
752
+ it('UserSync test : check type = pixel, check usermatch URL with override set to 0', function () {
753
+ const syncOptions = {
754
+ 'pixelEnabled': true
755
+ }
756
+ config.setConfig({
757
+ userSync: {
758
+ pixelEnabled: true,
759
+ syncsPerBidder: 3
760
+ }
761
+ });
762
+ let userSync = spec.getUserSyncs(syncOptions, [{'body': {'ext': {'publishersyncsperbidderoverride': 0}}}]);
763
+ expect(userSync.length).to.equal(0);
764
+ });
765
+
766
+ it('UserSync test : check type = pixel, check usermatch URL with override set', function () {
767
+ const syncOptions = {
768
+ 'pixelEnabled': true
769
+ }
770
+ config.setConfig({
771
+ userSync: {
772
+ pixelEnabled: true,
773
+ syncsPerBidder: 3
774
+ }
775
+ });
776
+ let userSync = spec.getUserSyncs(syncOptions, [{'body': {'ext': {'publishersyncsperbidderoverride': 2}}}]);
777
+ expect(userSync[0].type).to.equal('image');
778
+ const USER_SYNC_URL_0 = 'https://dsum.casalemedia.com/pbusermatch?origin=prebid&site_id=123&p=2&i=0&gdpr=1&gdpr_consent=3huaa11=qu3198ae&us_privacy=';
779
+ const USER_SYNC_URL_1 = 'https://dsum.casalemedia.com/pbusermatch?origin=prebid&site_id=123&p=2&i=1&gdpr=1&gdpr_consent=3huaa11=qu3198ae&us_privacy=';
780
+ expect(userSync[0].url).to.equal(USER_SYNC_URL_0);
781
+ expect(userSync[1].url).to.equal(USER_SYNC_URL_1);
782
+ expect(userSync.length).to.equal(2);
783
+ });
784
+
785
+ it('UserSync test : check type = pixel, check usermatch URL with override greater than publisher syncs per bidder , use syncsperbidder', function () {
786
+ const syncOptions = {
787
+ 'pixelEnabled': true
788
+ }
789
+ config.setConfig({
790
+ userSync: {
791
+ pixelEnabled: true,
792
+ syncsPerBidder: 3
793
+ }
794
+ });
795
+ let userSync = spec.getUserSyncs(syncOptions, [{'body': {'ext': {'publishersyncsperbidderoverride': 4}}}]);
796
+ expect(userSync[0].type).to.equal('image');
797
+ const USER_SYNC_URL_0 = 'https://dsum.casalemedia.com/pbusermatch?origin=prebid&site_id=123&p=3&i=0&gdpr=1&gdpr_consent=3huaa11=qu3198ae&us_privacy=';
798
+ const USER_SYNC_URL_1 = 'https://dsum.casalemedia.com/pbusermatch?origin=prebid&site_id=123&p=3&i=1&gdpr=1&gdpr_consent=3huaa11=qu3198ae&us_privacy=';
799
+ const USER_SYNC_URL_2 = 'https://dsum.casalemedia.com/pbusermatch?origin=prebid&site_id=123&p=3&i=2&gdpr=1&gdpr_consent=3huaa11=qu3198ae&us_privacy=';
800
+ expect(userSync[0].url).to.equal(USER_SYNC_URL_0);
801
+ expect(userSync[1].url).to.equal(USER_SYNC_URL_1);
802
+ expect(userSync[2].url).to.equal(USER_SYNC_URL_2);
803
+ expect(userSync.length).to.equal(3);
804
+ });
805
+
806
+ it('UserSync test : check type = pixel, syncsPerBidder = 0, still use override', function () {
807
+ const syncOptions = {
808
+ 'pixelEnabled': true
809
+ }
810
+ config.setConfig({
811
+ userSync: {
812
+ pixelEnabled: true,
813
+ syncsPerBidder: 0
814
+ }
815
+ });
816
+ let userSync = spec.getUserSyncs(syncOptions, [{'body': {'ext': {'publishersyncsperbidderoverride': 2}}}]);
817
+ expect(userSync[0].type).to.equal('image');
818
+ const USER_SYNC_URL_0 = 'https://dsum.casalemedia.com/pbusermatch?origin=prebid&site_id=123&p=2&i=0&gdpr=1&gdpr_consent=3huaa11=qu3198ae&us_privacy=';
819
+ const USER_SYNC_URL_1 = 'https://dsum.casalemedia.com/pbusermatch?origin=prebid&site_id=123&p=2&i=1&gdpr=1&gdpr_consent=3huaa11=qu3198ae&us_privacy=';
820
+ expect(userSync[0].url).to.equal(USER_SYNC_URL_0);
821
+ expect(userSync[1].url).to.equal(USER_SYNC_URL_1);
822
+ expect(userSync.length).to.equal(2);
581
823
  });
582
824
  });
583
825
 
@@ -617,6 +859,7 @@ describe('IndexexchangeAdapter', function () {
617
859
  it('should return true when required params found for a banner or video ad', function () {
618
860
  expect(spec.isBidRequestValid(DEFAULT_BANNER_VALID_BID[0])).to.equal(true);
619
861
  expect(spec.isBidRequestValid(DEFAULT_VIDEO_VALID_BID[0])).to.equal(true);
862
+ expect(spec.isBidRequestValid(DEFAULT_NATIVE_VALID_BID[0])).to.equal(true);
620
863
  });
621
864
 
622
865
  it('should return true when optional bidFloor params found for an ad', function () {
@@ -705,11 +948,11 @@ describe('IndexexchangeAdapter', function () {
705
948
  });
706
949
 
707
950
  it('should return false when mediaType is native', function () {
708
- const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]);
951
+ const bid = utils.deepClone(DEFAULT_NATIVE_VALID_BID[0]);
709
952
  delete bid.params.mediaTypes;
710
953
  bid.mediaType = 'native';
711
954
  bid.sizes = [[300, 250]];
712
- expect(spec.isBidRequestValid(bid)).to.equal(false);
955
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
713
956
  });
714
957
 
715
958
  it('should return true when mediaType is missing and has sizes', function () {
@@ -745,6 +988,11 @@ describe('IndexexchangeAdapter', function () {
745
988
  expect(spec.isBidRequestValid(bid)).to.equal(true);
746
989
  });
747
990
 
991
+ it('shoult return true for native bid when there are multiple mediaTypes (banner, native)', function () {
992
+ const bid = utils.deepClone(DEFAULT_MULTIFORMAT_NATIVE_VALID_BID[0]);
993
+ expect(spec.isBidRequestValid(bid)).to.be.true;
994
+ });
995
+
748
996
  it('should return false when there is only bidFloor', function () {
749
997
  const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]);
750
998
  bid.params.bidFloor = 50;
@@ -807,6 +1055,18 @@ describe('IndexexchangeAdapter', function () {
807
1055
  delete bid.params.video.protocols;
808
1056
  expect(spec.isBidRequestValid(bid)).to.equal(false);
809
1057
  });
1058
+
1059
+ it('should fail when native contains unrecongized properties', function () {
1060
+ let bid = utils.deepClone(DEFAULT_NATIVE_VALID_BID[0]);
1061
+ bid.mediaTypes.native.test = {}
1062
+ expect(spec.isBidRequestValid(bid)).to.be.false;
1063
+ });
1064
+
1065
+ it('should fail if native mediaTypes should contains no valid assets', function () {
1066
+ let bid = utils.deepClone(DEFAULT_NATIVE_VALID_BID[0]);
1067
+ bid.mediaTypes.native = {}
1068
+ expect(spec.isBidRequestValid(bid)).to.be.false;
1069
+ });
810
1070
  });
811
1071
 
812
1072
  describe('Roundel alias adapter', function () {
@@ -1500,6 +1760,7 @@ describe('IndexexchangeAdapter', function () {
1500
1760
  expect(impression.id).to.equal(DEFAULT_BANNER_VALID_BID[0].bidId);
1501
1761
  expect(impression.banner.format).to.be.length(2);
1502
1762
  expect(impression.banner.topframe).to.be.oneOf([0, 1]);
1763
+ expect(impression.ext.tid).to.equal(DEFAULT_BANNER_VALID_BID[0].transactionId);
1503
1764
 
1504
1765
  impression.banner.format.map(({ w, h, ext }, index) => {
1505
1766
  const size = DEFAULT_BANNER_VALID_BID[0].mediaTypes.banner.sizes[index];
@@ -1785,6 +2046,39 @@ describe('IndexexchangeAdapter', function () {
1785
2046
  });
1786
2047
  });
1787
2048
 
2049
+ describe('request should contain both banner and native requests', function () {
2050
+ const request = spec.buildRequests([DEFAULT_BANNER_VALID_BID[0], DEFAULT_NATIVE_VALID_BID[0]]);
2051
+
2052
+ it('should have banner request', () => {
2053
+ const bannerImpression = JSON.parse(request[0].data.r).imp[0];
2054
+
2055
+ expect(JSON.parse(request[0].data.r).imp).to.have.lengthOf(1);
2056
+ expect(JSON.parse(request[0].data.v)).to.equal(BANNER_ENDPOINT_VERSION);
2057
+ expect(bannerImpression.id).to.equal(DEFAULT_BANNER_VALID_BID[0].bidId);
2058
+
2059
+ expect(bannerImpression.banner.format).to.be.length(2);
2060
+ expect(bannerImpression.banner.topframe).to.be.oneOf([0, 1]);
2061
+
2062
+ bannerImpression.banner.format.map(({ w, h, ext }, index) => {
2063
+ const size = DEFAULT_BANNER_VALID_BID[0].mediaTypes.banner.sizes[index];
2064
+ const sidValue = utils.parseGPTSingleSizeArray(size);
2065
+
2066
+ expect(w).to.equal(size[0]);
2067
+ expect(h).to.equal(size[1]);
2068
+ expect(ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId);
2069
+ expect(ext.sid).to.equal(sidValue);
2070
+ });
2071
+ });
2072
+
2073
+ it('should have native request', () => {
2074
+ const nativeImpression = JSON.parse(request[1].data.r).imp[0];
2075
+
2076
+ expect(request[1].data.v).to.equal(NATIVE_ENDPOINT_VERSION);
2077
+ expect(nativeImpression.id).to.equal(DEFAULT_NATIVE_VALID_BID[0].bidId);
2078
+ expect(nativeImpression.native).to.deep.equal(DEFAULT_NATIVE_IMP);
2079
+ });
2080
+ });
2081
+
1788
2082
  it('single request under 8k size limit for large ad unit', function () {
1789
2083
  const options = {};
1790
2084
  const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]);
@@ -2120,6 +2414,125 @@ describe('IndexexchangeAdapter', function () {
2120
2414
  })
2121
2415
  });
2122
2416
 
2417
+ describe('buildRequestNative', function () {
2418
+ it('should build request with expected params', function() {
2419
+ const request = spec.buildRequests(DEFAULT_NATIVE_VALID_BID, DEFAULT_OPTION);
2420
+ const query = request[0].data;
2421
+
2422
+ expect(query.v).to.equal(NATIVE_ENDPOINT_VERSION);
2423
+ expect(query.s).to.equal(DEFAULT_NATIVE_VALID_BID[0].params.siteId);
2424
+ expect(query.r).to.exist;
2425
+ expect(query.ac).to.equal('j');
2426
+ expect(query.sd).to.equal(1);
2427
+ expect(JSON.parse(query.r).at).to.equal(1);
2428
+ });
2429
+
2430
+ it('should send gpid in request if ortb2Imp.ext.gpid exists', function () {
2431
+ const GPID = '/19968336/some-adunit-path';
2432
+ const bids = utils.deepClone(DEFAULT_NATIVE_VALID_BID);
2433
+ bids[0].ortb2Imp = {
2434
+ ext: {
2435
+ gpid: GPID
2436
+ }
2437
+ };
2438
+ const requests = spec.buildRequests(bids, DEFAULT_OPTION);
2439
+ const { ext: { gpid } } = JSON.parse(requests[0].data.r).imp[0];
2440
+ expect(gpid).to.equal(GPID);
2441
+ });
2442
+
2443
+ it('should build request with required asset properties with default values', function() {
2444
+ const request = spec.buildRequests(DEFAULT_NATIVE_VALID_BID, DEFAULT_OPTION);
2445
+ const nativeImpression = JSON.parse(request[0].data.r).imp[0];
2446
+
2447
+ expect(request[0].data.v).to.equal(NATIVE_ENDPOINT_VERSION);
2448
+ expect(nativeImpression.id).to.equal(DEFAULT_NATIVE_VALID_BID[0].bidId);
2449
+ expect(nativeImpression.native).to.deep.equal(DEFAULT_NATIVE_IMP);
2450
+ });
2451
+
2452
+ it('should build request with given asset properties', function() {
2453
+ let bid = utils.deepClone(DEFAULT_NATIVE_VALID_BID)
2454
+ bid[0].mediaTypes.native = {
2455
+ title: {
2456
+ len: 200
2457
+ },
2458
+ video: {
2459
+ mimes: [
2460
+ 'javascript'
2461
+ ],
2462
+ minduration: 10,
2463
+ maxduration: 60,
2464
+ protocols: [1]
2465
+ }
2466
+ }
2467
+ const request = spec.buildRequests(bid, DEFAULT_OPTION);
2468
+ const nativeImpression = JSON.parse(request[0].data.r).imp[0];
2469
+ expect(nativeImpression.native).to.deep.equal({request: '{"assets":[{"required":0,"title":{"len":200},"id":100},{"required":0,"video":{"mimes":["javascript"],"minduration":10,"maxduration":60,"protocols":[1]},"id":300}],"ver":"1.2","eventtrackers":[{"event":1,"methods":[1,2]}],"privacy":1}', ver: '1.2'});
2470
+ });
2471
+
2472
+ it('should build request with all possible Prebid asset properties', function() {
2473
+ let bid = utils.deepClone(DEFAULT_NATIVE_VALID_BID)
2474
+ bid[0].mediaTypes.native = {
2475
+ title: {
2476
+ required: false
2477
+ },
2478
+ body: {
2479
+ required: false
2480
+ },
2481
+ body2: {
2482
+ required: false
2483
+ },
2484
+ sponsoredBy: {
2485
+ required: false
2486
+ },
2487
+ icon: {
2488
+ required: false
2489
+ },
2490
+ image: {
2491
+ required: false
2492
+ },
2493
+ clickUrl: {
2494
+ required: false
2495
+ },
2496
+ displayUrl: {
2497
+ required: false
2498
+ },
2499
+ privacyLink: {
2500
+ required: false
2501
+ },
2502
+ privacyIcon: {
2503
+ required: false
2504
+ },
2505
+ cta: {
2506
+ required: false
2507
+ },
2508
+ rating: {
2509
+ required: false
2510
+ },
2511
+ downloads: {
2512
+ required: false
2513
+ },
2514
+ likes: {
2515
+ required: false
2516
+ },
2517
+ price: {
2518
+ required: false
2519
+ },
2520
+ salePrice: {
2521
+ required: false
2522
+ },
2523
+ address: {
2524
+ required: false
2525
+ },
2526
+ phone: {
2527
+ required: false
2528
+ },
2529
+ }
2530
+ const request = spec.buildRequests(bid, DEFAULT_OPTION);
2531
+ const nativeImpression = JSON.parse(request[0].data.r).imp[0];
2532
+ expect(nativeImpression.native).to.deep.equal({request: '{"assets":[{"required":0,"title":{"len":25},"id":100},{"required":0,"data":{"type":2},"id":402},{"required":0,"data":{"type":10},"id":410},{"required":0,"data":{"type":1},"id":401},{"required":0,"img":{"type":1},"id":201},{"required":0,"img":{"type":3},"id":203},{"required":0,"data":{"type":11},"id":411},{"required":0,"data":{"type":12},"id":412},{"required":0,"data":{"type":3},"id":403},{"required":0,"data":{"type":5},"id":405},{"required":0,"data":{"type":4},"id":404},{"required":0,"data":{"type":6},"id":406},{"required":0,"data":{"type":7},"id":407},{"required":0,"data":{"type":9},"id":409},{"required":0,"data":{"type":8},"id":408}],"ver":"1.2","eventtrackers":[{"event":1,"methods":[1,2]}],"privacy":1}', ver: '1.2'});
2533
+ })
2534
+ });
2535
+
2123
2536
  describe('buildRequestMultiFormat', function () {
2124
2537
  it('only banner bidder params set', function () {
2125
2538
  const request = spec.buildRequests(DEFAULT_MULTIFORMAT_BANNER_VALID_BID, {})
@@ -2584,6 +2997,53 @@ describe('IndexexchangeAdapter', function () {
2584
2997
  expect(bannerResult[0].ttl).to.equal(300);
2585
2998
  expect(videoResult[0].ttl).to.equal(3600);
2586
2999
  });
3000
+
3001
+ it('should get correct bid response for native ad', function () {
3002
+ const expectedParse = [
3003
+ {
3004
+ requestId: '1a2b3c4d',
3005
+ cpm: 1,
3006
+ creativeId: '12345',
3007
+ mediaType: 'native',
3008
+ width: 1,
3009
+ height: 1,
3010
+ currency: 'USD',
3011
+ netRevenue: true,
3012
+ meta: {
3013
+ networkId: 50,
3014
+ brandId: 303325,
3015
+ brandName: 'OECTA',
3016
+ advertiserDomains: ['www.abc.com']
3017
+ },
3018
+ native: {
3019
+ body: 'Les pièces automobiles dont vous avez besoin, toujours sous la main.',
3020
+ clickUrl: 'https://play.google.com/store/apps/details?id=de.autodoc.gmbh',
3021
+ icon: {
3022
+ height: 250,
3023
+ width: 250,
3024
+ url: 'https://cdn.liftoff.io/customers/1209/creatives/2501-icon-250x250.png'
3025
+ },
3026
+ image: {
3027
+ height: 627,
3028
+ width: 1200,
3029
+ url: 'https://cdn.liftoff.io/customers/5a9cab9cc6/image/lambda_png/a0355879b06c09b09232.png'
3030
+ },
3031
+ impressionTrackers: [
3032
+ 'https://click.liftoff.io/v1/campaign_click/blah',
3033
+ 'https://impression-europe.liftoff.io/index/impression',
3034
+ 'https://a701.casalemedia.com/impression/v1'
3035
+ ],
3036
+ privacyLink: 'https://privacy.link.com',
3037
+ sponsoredBy: 'autodoc.co.uk',
3038
+ title: 'Autodoc',
3039
+ video: '<VAST>blah</VAST>'
3040
+ },
3041
+ ttl: 3600
3042
+ }
3043
+ ];
3044
+ const result = spec.interpretResponse({ body: DEFAULT_NATIVE_BID_RESPONSE }, { data: DEFAULT_BIDDER_REQUEST_DATA, validBidRequests: [] });
3045
+ expect(result[0]).to.deep.equal(expectedParse[0]);
3046
+ });
2587
3047
  });
2588
3048
 
2589
3049
  describe('bidrequest consent', function () {
@@ -2839,8 +3299,8 @@ describe('IndexexchangeAdapter', function () {
2839
3299
  bid.params.video.maxduration = 0;
2840
3300
 
2841
3301
  expect(spec.isBidRequestValid(bid)).to.be.true;
2842
- spec.buildRequests([bid], {});
2843
- expect(JSON.parse(localStorageValues[key])).to.deep.equal({ [TODAY]: { [ERROR_CODES.VIDEO_DURATION_INVALID]: 3 } });
3302
+ spec.buildRequests([bid]);
3303
+ expect(JSON.parse(localStorageValues[key])).to.deep.equal({ [TODAY]: { [ERROR_CODES.VIDEO_DURATION_INVALID]: 2 } });
2844
3304
  });
2845
3305
 
2846
3306
  it('should increment errors for errorCode', () => {
@@ -0,0 +1,42 @@
1
+ import kargoAnalyticsAdapter from 'modules/kargoAnalyticsAdapter.js';
2
+ import { expect } from 'chai';
3
+ import { server } from 'test/mocks/xhr.js';
4
+ let events = require('src/events');
5
+ let constants = require('src/constants.json');
6
+
7
+ describe('Kargo Analytics Adapter', function () {
8
+ const adapterConfig = {
9
+ provider: 'kargoAnalytics',
10
+ };
11
+
12
+ after(function () {
13
+ kargoAnalyticsAdapter.disableAnalytics();
14
+ });
15
+
16
+ describe('main test flow', function () {
17
+ beforeEach(function () {
18
+ kargoAnalyticsAdapter.enableAnalytics(adapterConfig);
19
+ sinon.stub(events, 'getEvents').returns([]);
20
+ });
21
+
22
+ afterEach(function () {
23
+ events.getEvents.restore();
24
+ });
25
+
26
+ it('bid response data should send one request with auction ID, auction timeout, and response time', function() {
27
+ const bidResponse = {
28
+ bidder: 'kargo',
29
+ auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f',
30
+ timeToRespond: 192,
31
+ };
32
+
33
+ events.emit(constants.EVENTS.AUCTION_INIT, {
34
+ timeout: 1000
35
+ });
36
+ events.emit(constants.EVENTS.BID_RESPONSE, bidResponse);
37
+
38
+ expect(server.requests.length).to.equal(1);
39
+ expect(server.requests[0].url).to.equal('https://krk.kargo.com/api/v1/event/auction-data?aid=66529d4c-8998-47c2-ab3e-5b953490b98f&ato=1000&rt=192&it=0');
40
+ });
41
+ });
42
+ });
@@ -572,6 +572,7 @@ describe('kargo adapter tests', function () {
572
572
  cpm: 2.5,
573
573
  width: 300,
574
574
  height: 250,
575
+ ad: '<VAST></VAST>',
575
576
  vastXml: '<VAST></VAST>',
576
577
  ttl: 300,
577
578
  creativeId: 'bar',