prebid.js 6.24.0 → 6.26.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 (178) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/adagioBidAdapter.js +1 -1
  3. package/dist/adbookpspBidAdapter.js +1 -1
  4. package/dist/adgenerationBidAdapter.js +1 -1
  5. package/dist/adrelevantisBidAdapter.js +1 -1
  6. package/dist/adtelligentBidAdapter.js +1 -1
  7. package/dist/adxcgBidAdapter.js +1 -1
  8. package/dist/adyoulikeBidAdapter.js +1 -1
  9. package/dist/ajaBidAdapter.js +1 -1
  10. package/dist/amxBidAdapter.js +1 -1
  11. package/dist/amxIdSystem.js +1 -1
  12. package/dist/appierAnalyticsAdapter.js +1 -1
  13. package/dist/appnexusBidAdapter.js +1 -1
  14. package/dist/asoBidAdapter.js +1 -1
  15. package/dist/audiencerunBidAdapter.js +1 -1
  16. package/dist/axonixBidAdapter.js +1 -1
  17. package/dist/beopBidAdapter.js +1 -1
  18. package/dist/bidglassBidAdapter.js +1 -1
  19. package/dist/big-richmediaBidAdapter.js +1 -1
  20. package/dist/bluebillywigBidAdapter.js +1 -1
  21. package/dist/bridgewellBidAdapter.js +1 -1
  22. package/dist/brightMountainMediaBidAdapter.js +1 -1
  23. package/dist/concertBidAdapter.js +1 -1
  24. package/dist/connectadBidAdapter.js +1 -1
  25. package/dist/consumableBidAdapter.js +1 -1
  26. package/dist/conversantBidAdapter.js +1 -1
  27. package/dist/cpexIdSystem.js +1 -1
  28. package/dist/craftBidAdapter.js +1 -1
  29. package/dist/criteoBidAdapter.js +1 -1
  30. package/dist/currency.js +1 -1
  31. package/dist/dfpAdServerVideo.js +1 -1
  32. package/dist/dspxBidAdapter.js +1 -1
  33. package/dist/eplanningBidAdapter.js +1 -1
  34. package/dist/glimpseBidAdapter.js +1 -1
  35. package/dist/gmosspBidAdapter.js +1 -1
  36. package/dist/goldbachBidAdapter.js +1 -1
  37. package/dist/gravitoIdSystem.js +1 -0
  38. package/dist/gridBidAdapter.js +1 -1
  39. package/dist/gridNMBidAdapter.js +1 -1
  40. package/dist/gumgumBidAdapter.js +1 -1
  41. package/dist/h12mediaBidAdapter.js +1 -1
  42. package/dist/id5IdSystem.js +1 -1
  43. package/dist/impactifyBidAdapter.js +1 -1
  44. package/dist/improvedigitalBidAdapter.js +1 -1
  45. package/dist/inmarBidAdapter.js +1 -1
  46. package/dist/insticatorBidAdapter.js +1 -1
  47. package/dist/invibesBidAdapter.js +1 -1
  48. package/dist/ixBidAdapter.js +1 -1
  49. package/dist/jixieBidAdapter.js +1 -1
  50. package/dist/justpremiumBidAdapter.js +1 -1
  51. package/dist/kargoBidAdapter.js +1 -1
  52. package/dist/konduitAnalyticsAdapter.js +1 -1
  53. package/dist/liveIntentIdSystem.js +1 -1
  54. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  55. package/dist/logicadBidAdapter.js +1 -1
  56. package/dist/loglyliftBidAdapter.js +1 -1
  57. package/dist/malltvAnalyticsAdapter.js +1 -1
  58. package/dist/marsmediaBidAdapter.js +1 -1
  59. package/dist/mediafuseBidAdapter.js +1 -1
  60. package/dist/mediakeysBidAdapter.js +1 -1
  61. package/dist/mediasquareBidAdapter.js +1 -1
  62. package/dist/mgidBidAdapter.js +1 -1
  63. package/dist/minutemediaBidAdapter.js +1 -1
  64. package/dist/not-for-prod/prebid.js +123 -121
  65. package/dist/oguryBidAdapter.js +1 -1
  66. package/dist/oneVideoBidAdapter.js +1 -1
  67. package/dist/onetagBidAdapter.js +1 -1
  68. package/dist/ooloAnalyticsAdapter.js +1 -1
  69. package/dist/outbrainBidAdapter.js +1 -1
  70. package/dist/parrableIdSystem.js +1 -1
  71. package/dist/pixfutureBidAdapter.js +1 -1
  72. package/dist/prebid-core.js +3 -3
  73. package/dist/publinkIdSystem.js +1 -1
  74. package/dist/pubmaticBidAdapter.js +1 -1
  75. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  76. package/dist/pxyzBidAdapter.js +1 -1
  77. package/dist/quantcastBidAdapter.js +1 -1
  78. package/dist/readpeakBidAdapter.js +1 -1
  79. package/dist/relaidoBidAdapter.js +1 -1
  80. package/dist/rhythmoneBidAdapter.js +1 -1
  81. package/dist/riseBidAdapter.js +1 -1
  82. package/dist/rubiconAnalyticsAdapter.js +1 -1
  83. package/dist/rubiconBidAdapter.js +1 -1
  84. package/dist/seedingAllianceBidAdapter.js +1 -1
  85. package/dist/seedtagBidAdapter.js +1 -1
  86. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  87. package/dist/sharethroughBidAdapter.js +1 -1
  88. package/dist/smaatoBidAdapter.js +1 -1
  89. package/dist/smartadserverBidAdapter.js +1 -1
  90. package/dist/smartxBidAdapter.js +1 -1
  91. package/dist/smilewantedBidAdapter.js +1 -1
  92. package/dist/sonobiBidAdapter.js +1 -1
  93. package/dist/sortableBidAdapter.js +1 -1
  94. package/dist/sovrnAnalyticsAdapter.js +1 -1
  95. package/dist/sovrnBidAdapter.js +1 -1
  96. package/dist/sspBCBidAdapter.js +1 -1
  97. package/dist/sublimeBidAdapter.js +1 -1
  98. package/dist/synacormediaBidAdapter.js +1 -1
  99. package/dist/targetVideoBidAdapter.js +1 -1
  100. package/dist/teadsBidAdapter.js +1 -1
  101. package/dist/trionBidAdapter.js +1 -1
  102. package/dist/tripleliftBidAdapter.js +1 -1
  103. package/dist/trustpidSystem.js +1 -1
  104. package/dist/trustxBidAdapter.js +1 -1
  105. package/dist/ttdBidAdapter.js +1 -1
  106. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  107. package/dist/underdogmediaBidAdapter.js +1 -1
  108. package/dist/undertoneBidAdapter.js +1 -1
  109. package/dist/userId.js +1 -1
  110. package/dist/vidazooBidAdapter.js +1 -1
  111. package/dist/videobyteBidAdapter.js +1 -1
  112. package/dist/videoheroesBidAdapter.js +1 -0
  113. package/dist/vidoomyBidAdapter.js +1 -1
  114. package/dist/visxBidAdapter.js +1 -1
  115. package/dist/vuukleBidAdapter.js +1 -1
  116. package/dist/weboramaRtdProvider.js +1 -1
  117. package/dist/widespaceBidAdapter.js +1 -1
  118. package/dist/winrBidAdapter.js +1 -1
  119. package/dist/yahoosspBidAdapter.js +1 -1
  120. package/dist/yieldmoBidAdapter.js +1 -1
  121. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  122. package/dist/zeta_global_sspBidAdapter.js +1 -1
  123. package/integrationExamples/gpt/userId_example.html +3 -0
  124. package/integrationExamples/gpt/weboramaRtdProvider_example.html +65 -11
  125. package/modules/.submodules.json +2 -1
  126. package/modules/adagioBidAdapter.js +2 -0
  127. package/modules/adtelligentBidAdapter.js +3 -1
  128. package/modules/alkimiBidAdapter.md +10 -4
  129. package/modules/appnexusBidAdapter.js +13 -2
  130. package/modules/beopBidAdapter.js +51 -6
  131. package/modules/cpexIdSystem.js +1 -2
  132. package/modules/currency.js +4 -13
  133. package/modules/dacIdSystem.md +4 -4
  134. package/modules/dfpAdServerVideo.js +8 -0
  135. package/modules/gravitoIdSystem.js +57 -0
  136. package/modules/gravitoIdSystem.md +28 -0
  137. package/modules/improvedigitalBidAdapter.js +100 -43
  138. package/modules/invibesBidAdapter.js +55 -34
  139. package/modules/ixBidAdapter.js +62 -26
  140. package/modules/ixBidAdapter.md +42 -42
  141. package/modules/jixieBidAdapter.js +2 -0
  142. package/modules/kargoBidAdapter.js +23 -8
  143. package/modules/oguryBidAdapter.js +27 -1
  144. package/modules/trustpidSystem.js +9 -28
  145. package/modules/trustpidSystem.md +11 -34
  146. package/modules/userId/eids.js +6 -0
  147. package/modules/userId/index.js +30 -55
  148. package/modules/userId/userId.md +3 -11
  149. package/modules/videoheroesBidAdapter.js +267 -0
  150. package/modules/videoheroesBidAdapter.md +134 -0
  151. package/modules/vidoomyBidAdapter.js +2 -6
  152. package/modules/weboramaRtdProvider.js +515 -241
  153. package/modules/weboramaRtdProvider.md +488 -51
  154. package/modules/zeta_global_sspBidAdapter.js +1 -1
  155. package/package.json +4 -4
  156. package/src/adserver.js +7 -0
  157. package/src/hook.js +19 -1
  158. package/src/utils/promise.js +36 -0
  159. package/test/spec/modules/adtelligentBidAdapter_spec.js +1 -0
  160. package/test/spec/modules/appnexusBidAdapter_spec.js +37 -10
  161. package/test/spec/modules/beopBidAdapter_spec.js +15 -2
  162. package/test/spec/modules/dfpAdServerVideo_spec.js +45 -0
  163. package/test/spec/modules/gravitoIdSystem_spec.js +51 -0
  164. package/test/spec/modules/improvedigitalBidAdapter_spec.js +289 -72
  165. package/test/spec/modules/invibesBidAdapter_spec.js +98 -7
  166. package/test/spec/modules/ixBidAdapter_spec.js +132 -26
  167. package/test/spec/modules/jixieBidAdapter_spec.js +17 -0
  168. package/test/spec/modules/kargoBidAdapter_spec.js +45 -3
  169. package/test/spec/modules/liveIntentIdSystem_spec.js +2 -2
  170. package/test/spec/modules/loglyliftBidAdapter_spec.js +8 -0
  171. package/test/spec/modules/oguryBidAdapter_spec.js +181 -3
  172. package/test/spec/modules/trustpidSystem_spec.js +42 -19
  173. package/test/spec/modules/userId_spec.js +18 -0
  174. package/test/spec/modules/videoheroesBidAdapter_spec.js +363 -0
  175. package/test/spec/modules/weboramaRtdProvider_spec.js +2333 -266
  176. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +37 -24
  177. package/test/spec/unit/utils/promise_spec.js +49 -0
  178. package/test/spec/modules/medianetRtdProvider_spec.js +0 -146
@@ -3,10 +3,13 @@ import { spec } from 'modules/improvedigitalBidAdapter.js';
3
3
  import { config } from 'src/config.js';
4
4
  import { deepClone } from 'src/utils.js';
5
5
  import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes';
6
+ import { deepSetValue } from '../../../src/utils';
6
7
 
7
8
  describe('Improve Digital Adapter Tests', function () {
8
9
  const METHOD = 'POST';
9
- const URL = 'https://ad.360yield.com/pb';
10
+ const AD_SERVER_URL = 'https://ad.360yield.com/pb';
11
+ const EXTEND_URL = 'https://pbs.360yield.com/openrtb2/auction';
12
+ const IFRAME_SYNC_URL = 'https://hb.360yield.com/prebid-universal-creative/load-cookie.html';
10
13
  const INSTREAM_TYPE = 1;
11
14
  const OUTSTREAM_TYPE = 3;
12
15
 
@@ -28,21 +31,34 @@ describe('Improve Digital Adapter Tests', function () {
28
31
  sizes: [[300, 250], [160, 600]]
29
32
  };
30
33
 
34
+ const extendBidRequest = deepClone(simpleBidRequest);
35
+ extendBidRequest.params.extend = true;
36
+
31
37
  const videoParams = {
32
38
  skip: 1,
33
39
  skipmin: 5,
34
40
  skipafter: 30
35
41
  }
36
42
 
37
- const instreamBidRequest = deepClone(simpleBidRequest);
38
- instreamBidRequest.mediaTypes = {
39
- video: {
40
- context: 'instream',
41
- playerSize: [640, 480]
43
+ const instreamBidRequest = {
44
+ bidder: 'improvedigital',
45
+ params: {
46
+ placementId: 123456
47
+ },
48
+ adUnitCode: 'video1',
49
+ transactionId: 'vf183e871-fbed-45f0-a427-c8a63c4c01eb',
50
+ bidId: '33e9500b21129f',
51
+ bidderRequestId: 'v2772c1e566670b',
52
+ auctionId: 'v192721e36a0239',
53
+ mediaTypes: {
54
+ video: {
55
+ context: 'instream',
56
+ playerSize: [640, 480]
57
+ }
42
58
  }
43
59
  };
44
60
 
45
- const outstreamBidRequest = deepClone(simpleBidRequest);
61
+ const outstreamBidRequest = deepClone(instreamBidRequest);
46
62
  outstreamBidRequest.mediaTypes = {
47
63
  video: {
48
64
  context: 'outstream',
@@ -89,6 +105,10 @@ describe('Improve Digital Adapter Tests', function () {
89
105
  bids: [simpleBidRequest]
90
106
  };
91
107
 
108
+ const extendBidderRequest = {
109
+ bids: [extendBidRequest]
110
+ };
111
+
92
112
  const instreamBidderRequest = {
93
113
  bids: [instreamBidRequest]
94
114
  };
@@ -105,14 +125,17 @@ describe('Improve Digital Adapter Tests', function () {
105
125
  bids: [nativeBidRequest]
106
126
  };
107
127
 
128
+ const gdprConsent = {
129
+ apiVersion: 2,
130
+ consentString: 'CONSENT',
131
+ vendorData: { purpose: { consents: { 1: true } } },
132
+ gdprApplies: true,
133
+ addtlConsent: '1~1.35.41.101',
134
+ };
135
+
108
136
  const bidderRequestGdpr = {
109
137
  bids: [simpleBidRequest],
110
- gdprConsent: {
111
- consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==',
112
- vendorData: {},
113
- gdprApplies: true,
114
- addtlConsent: '1~1.35.41.101',
115
- },
138
+ gdprConsent
116
139
  };
117
140
 
118
141
  const bidderRequestReferrer = {
@@ -162,13 +185,22 @@ describe('Improve Digital Adapter Tests', function () {
162
185
  });
163
186
 
164
187
  describe('buildRequests', function () {
188
+ let getConfigStub = null;
189
+
190
+ afterEach(function () {
191
+ if (getConfigStub) {
192
+ getConfigStub.restore();
193
+ getConfigStub = null;
194
+ }
195
+ });
196
+
165
197
  it('should make a well-formed request objects', function () {
166
- const getConfigStub = sinon.stub(config, 'getConfig');
198
+ getConfigStub = sinon.stub(config, 'getConfig');
167
199
  getConfigStub.withArgs('improvedigital.usePrebidSizes').returns(true);
168
200
  const request = spec.buildRequests([simpleBidRequest], bidderRequest)[0];
169
201
  expect(request).to.be.an('object');
170
202
  expect(request.method).to.equal(METHOD);
171
- expect(request.url).to.equal(URL);
203
+ expect(request.url).to.equal(AD_SERVER_URL);
172
204
  expect(request.bidderRequest).to.deep.equal(bidderRequest);
173
205
 
174
206
  const payload = JSON.parse(request.data);
@@ -178,7 +210,7 @@ describe('Improve Digital Adapter Tests', function () {
178
210
  expect(payload.cur).to.be.an('array');
179
211
  expect(payload.regs).to.not.exist;
180
212
  expect(payload.schain).to.not.exist;
181
- expect(payload.source).to.be.an('object');
213
+ expect(payload.source).to.deep.equal({ ext: {}, tid: 'f183e871-fbed-45f0-a427-c8a63c4c01eb' });
182
214
  expect(payload.device).to.be.an('object');
183
215
  expect(payload.user).to.not.exist;
184
216
  expect(payload.imp).to.deep.equal([
@@ -198,16 +230,15 @@ describe('Improve Digital Adapter Tests', function () {
198
230
  }
199
231
  }
200
232
  ]);
201
- getConfigStub.restore();
202
233
  });
203
234
 
204
235
  it('should make a well-formed request object for multi-format ad unit', function () {
205
- const getConfigStub = sinon.stub(config, 'getConfig');
236
+ getConfigStub = sinon.stub(config, 'getConfig');
206
237
  getConfigStub.withArgs('improvedigital.usePrebidSizes').returns(true);
207
238
  const request = spec.buildRequests([multiFormatBidRequest], multiFormatBidderRequest)[0];
208
239
  expect(request).to.be.an('object');
209
240
  expect(request.method).to.equal(METHOD);
210
- expect(request.url).to.equal(URL);
241
+ expect(request.url).to.equal(AD_SERVER_URL);
211
242
  expect(request.bidderRequest).to.deep.equal(multiFormatBidderRequest);
212
243
 
213
244
  const payload = JSON.parse(request.data);
@@ -239,7 +270,28 @@ describe('Improve Digital Adapter Tests', function () {
239
270
  }
240
271
  }
241
272
  ]);
242
- getConfigStub.restore();
273
+ });
274
+
275
+ it('should make a well-formed native request', function () {
276
+ const payload = JSON.parse(spec.buildRequests([nativeBidRequest])[0].data);
277
+ expect(payload.imp[0].native).to.deep.equal({
278
+ ver: '1.2',
279
+ request: '{\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":3,\"required\":1,\"data\":{\"type\":2}}]}'
280
+ });
281
+ });
282
+
283
+ it('should not make native request when nativeParams is undefined', function () {
284
+ const request = deepClone(nativeBidRequest);
285
+ delete request.nativeParams;
286
+ const payload = JSON.parse(spec.buildRequests([request])[0].data);
287
+ expect(payload.imp[0].native).to.not.exist;
288
+ });
289
+
290
+ it('should not make native request when no assets', function () {
291
+ const request = deepClone(nativeBidRequest);
292
+ request.nativeParams = {};
293
+ const payload = JSON.parse(spec.buildRequests([request])[0].data);
294
+ expect(payload.imp[0].native).to.not.exist;
243
295
  });
244
296
 
245
297
  it('should make a well-formed native request', function () {
@@ -284,10 +336,9 @@ describe('Improve Digital Adapter Tests', function () {
284
336
 
285
337
  it('should add currency', function () {
286
338
  const bidRequest = Object.assign({}, simpleBidRequest);
287
- const getConfigStub = sinon.stub(config, 'getConfig').returns('JPY');
339
+ getConfigStub = sinon.stub(config, 'getConfig').returns('JPY');
288
340
  const payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequest)[0].data);
289
341
  expect(payload.cur).to.deep.equal(['JPY']);
290
- getConfigStub.restore();
291
342
  });
292
343
 
293
344
  it('should add bid floor', function () {
@@ -320,7 +371,7 @@ describe('Improve Digital Adapter Tests', function () {
320
371
  const bidRequest = Object.assign({}, simpleBidRequest);
321
372
  const payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequestGdpr)[0].data);
322
373
  expect(payload.regs.ext.gdpr).to.exist.and.to.equal(1);
323
- expect(payload.user.ext.consent).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A==');
374
+ expect(payload.user.ext.consent).to.equal('CONSENT');
324
375
  expect(payload.user.ext.consented_providers_settings.consented_providers).to.exist.and.to.deep.equal([1, 35, 41, 101]);
325
376
  });
326
377
 
@@ -339,6 +390,18 @@ describe('Improve Digital Adapter Tests', function () {
339
390
  expect(payload.regs.ext.us_privacy).to.equal('1YYY');
340
391
  });
341
392
 
393
+ it('should add COPPA flag', function () {
394
+ getConfigStub = sinon.stub(config, 'getConfig');
395
+ getConfigStub.withArgs('coppa').returns(true);
396
+ let bidRequest = Object.assign({}, simpleBidRequest);
397
+ let payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequestGdpr)[0].data);
398
+ expect(payload.regs.coppa).to.equal(1);
399
+ getConfigStub.withArgs('coppa').returns(false);
400
+ bidRequest = Object.assign({}, simpleBidRequest);
401
+ payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequestGdpr)[0].data);
402
+ expect(payload.regs.coppa).to.equal(0);
403
+ });
404
+
342
405
  it('should add referrer', function () {
343
406
  const bidRequest = Object.assign({}, simpleBidRequest);
344
407
  const request = spec.buildRequests([bidRequest], bidderRequestReferrer)[0];
@@ -361,7 +424,7 @@ describe('Improve Digital Adapter Tests', function () {
361
424
  });
362
425
 
363
426
  it('should not add video params for banner', function () {
364
- const bidRequest = JSON.parse(JSON.stringify(simpleBidRequest));
427
+ const bidRequest = deepClone(simpleBidRequest);
365
428
  bidRequest.params.video = videoParams;
366
429
  const request = spec.buildRequests([bidRequest], bidderRequest)[0];
367
430
  const payload = JSON.parse(request.data);
@@ -369,11 +432,11 @@ describe('Improve Digital Adapter Tests', function () {
369
432
  });
370
433
 
371
434
  it('should add correct placement value for instream and outstream video', function () {
372
- let bidRequest = JSON.parse(JSON.stringify(simpleBidRequest));
435
+ let bidRequest = deepClone(simpleBidRequest);
373
436
  let payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequest)[0].data);
374
437
  expect(payload.imp[0].video).to.not.exist;
375
438
 
376
- bidRequest = JSON.parse(JSON.stringify(simpleBidRequest));
439
+ bidRequest = deepClone(simpleBidRequest);
377
440
  bidRequest.mediaTypes = {
378
441
  video: {
379
442
  context: 'instream',
@@ -388,7 +451,7 @@ describe('Improve Digital Adapter Tests', function () {
388
451
  });
389
452
 
390
453
  it('should set video params for instream', function() {
391
- const bidRequest = JSON.parse(JSON.stringify(instreamBidRequest));
454
+ const bidRequest = deepClone(instreamBidRequest);
392
455
  delete bidRequest.mediaTypes.video.playerSize;
393
456
  const videoParams = {
394
457
  mimes: ['video/mp4'],
@@ -411,7 +474,7 @@ describe('Improve Digital Adapter Tests', function () {
411
474
  });
412
475
 
413
476
  it('should set video playerSize over video params', () => {
414
- const bidRequest = JSON.parse(JSON.stringify(instreamBidRequest));
477
+ const bidRequest = deepClone(instreamBidRequest);
415
478
  bidRequest.params.video = {
416
479
  w: 1024, h: 640
417
480
  }
@@ -422,7 +485,7 @@ describe('Improve Digital Adapter Tests', function () {
422
485
  });
423
486
 
424
487
  it('should set skip params only if skip=1', function() {
425
- const bidRequest = JSON.parse(JSON.stringify(instreamBidRequest));
488
+ const bidRequest = deepClone(instreamBidRequest);
426
489
  // 1
427
490
  const videoTest = {
428
491
  skip: 1,
@@ -456,7 +519,7 @@ describe('Improve Digital Adapter Tests', function () {
456
519
  });
457
520
 
458
521
  it('should ignore invalid/unexpected video params', function() {
459
- const bidRequest = JSON.parse(JSON.stringify(instreamBidRequest));
522
+ const bidRequest = deepClone(instreamBidRequest);
460
523
  // 1
461
524
  const videoTest = {
462
525
  skip: 1,
@@ -472,7 +535,7 @@ describe('Improve Digital Adapter Tests', function () {
472
535
  });
473
536
 
474
537
  it('should set video params for outstream', function() {
475
- const bidRequest = JSON.parse(JSON.stringify(outstreamBidRequest));
538
+ const bidRequest = deepClone(outstreamBidRequest);
476
539
  bidRequest.params.video = videoParams;
477
540
  const request = spec.buildRequests([bidRequest])[0];
478
541
  const payload = JSON.parse(request.data);
@@ -486,7 +549,7 @@ describe('Improve Digital Adapter Tests', function () {
486
549
  });
487
550
  //
488
551
  it('should set video params for multi-format', function() {
489
- const bidRequest = JSON.parse(JSON.stringify(multiFormatBidRequest));
552
+ const bidRequest = deepClone(multiFormatBidRequest);
490
553
  bidRequest.params.video = videoParams;
491
554
  const request = spec.buildRequests([bidRequest])[0];
492
555
  const payload = JSON.parse(request.data);
@@ -536,19 +599,34 @@ describe('Improve Digital Adapter Tests', function () {
536
599
  });
537
600
 
538
601
  it('should return one request in a single request mode', function () {
539
- const getConfigStub = sinon.stub(config, 'getConfig');
602
+ getConfigStub = sinon.stub(config, 'getConfig');
540
603
  getConfigStub.withArgs('improvedigital.singleRequest').returns(true);
541
- const requests = spec.buildRequests([
542
- simpleBidRequest,
543
- simpleSmartTagBidRequest
544
- ], bidderRequest);
604
+ const requests = spec.buildRequests([ simpleBidRequest, instreamBidRequest ], bidderRequest);
545
605
  expect(requests).to.be.an('array');
546
606
  expect(requests.length).to.equal(1);
547
- getConfigStub.restore();
607
+ expect(requests[0].url).to.equal(AD_SERVER_URL);
608
+ const request = JSON.parse(requests[0].data);
609
+ expect(request.imp.length).to.equal(2);
610
+ expect(request.imp[0].banner).to.exist;
611
+ expect(request.imp[1].video).to.exist;
612
+ });
613
+
614
+ it('should create one request per endpoint in a single request mode', function () {
615
+ getConfigStub = sinon.stub(config, 'getConfig');
616
+ getConfigStub.withArgs('improvedigital.singleRequest').returns(true);
617
+ const requests = spec.buildRequests([ extendBidRequest, simpleBidRequest, instreamBidRequest ], bidderRequest);
618
+ expect(requests).to.be.an('array');
619
+ expect(requests.length).to.equal(2);
620
+ expect(requests[0].url).to.equal(EXTEND_URL);
621
+ expect(requests[1].url).to.equal(AD_SERVER_URL);
622
+ const adServerRequest = JSON.parse(requests[1].data);
623
+ expect(adServerRequest.imp.length).to.equal(2);
624
+ expect(adServerRequest.imp[0].banner).to.exist;
625
+ expect(adServerRequest.imp[1].video).to.exist;
548
626
  });
549
627
 
550
628
  it('should set Prebid sizes in bid request', function () {
551
- const getConfigStub = sinon.stub(config, 'getConfig');
629
+ getConfigStub = sinon.stub(config, 'getConfig');
552
630
  getConfigStub.withArgs('improvedigital.usePrebidSizes').returns(true);
553
631
  const request = spec.buildRequests([simpleBidRequest], bidderRequest)[0];
554
632
  const payload = JSON.parse(request.data);
@@ -558,11 +636,10 @@ describe('Improve Digital Adapter Tests', function () {
558
636
  { w: 160, h: 600 }
559
637
  ]
560
638
  });
561
- getConfigStub.restore();
562
639
  });
563
640
 
564
641
  it('should not add single size filter when using Prebid sizes', function () {
565
- const getConfigStub = sinon.stub(config, 'getConfig');
642
+ getConfigStub = sinon.stub(config, 'getConfig');
566
643
  getConfigStub.withArgs('improvedigital.usePrebidSizes').returns(true);
567
644
  const bidRequest = Object.assign({}, simpleBidRequest);
568
645
  const size = {
@@ -578,7 +655,6 @@ describe('Improve Digital Adapter Tests', function () {
578
655
  { w: 160, h: 600 }
579
656
  ]
580
657
  });
581
- getConfigStub.restore();
582
658
  });
583
659
 
584
660
  it('should set GPID and Instl Signal', function () {
@@ -620,29 +696,27 @@ describe('Improve Digital Adapter Tests', function () {
620
696
  });
621
697
 
622
698
  it('should not set site when app is defined in FPD', function () {
623
- const getConfigStub = sinon.stub(config, 'getConfig');
699
+ getConfigStub = sinon.stub(config, 'getConfig');
624
700
  getConfigStub.withArgs('ortb2.app').returns({ content: 'XYZ' });
625
701
  let request = spec.buildRequests([simpleBidRequest], bidderRequest)[0];
626
702
  let payload = JSON.parse(request.data);
627
703
  expect(payload.site).does.not.exist;
628
704
  expect(payload.app).does.exist;
629
705
  expect(payload.app.content).does.exist.and.equal('XYZ');
630
- getConfigStub.restore();
631
706
  });
632
707
 
633
708
  it('should not set site when app is defined in CONFIG', function () {
634
- const getConfigStub = sinon.stub(config, 'getConfig');
709
+ getConfigStub = sinon.stub(config, 'getConfig');
635
710
  getConfigStub.withArgs('app').returns({ content: 'XYZ' });
636
711
  let request = spec.buildRequests([simpleBidRequest], bidderRequest)[0];
637
712
  let payload = JSON.parse(request.data);
638
713
  expect(payload.site).does.not.exist;
639
714
  expect(payload.app).does.exist;
640
715
  expect(payload.app.content).does.exist.and.equal('XYZ');
641
- getConfigStub.restore();
642
716
  });
643
717
 
644
718
  it('should set correct site params', function () {
645
- let getConfigStub = sinon.stub(config, 'getConfig');
719
+ getConfigStub = sinon.stub(config, 'getConfig');
646
720
  getConfigStub.withArgs('site').returns({
647
721
  content: 'XYZ',
648
722
  page: 'https://improveditigal.com/',
@@ -669,11 +743,10 @@ describe('Improve Digital Adapter Tests', function () {
669
743
  expect(payload.site.content).does.exist.and.equal('ZZZ');
670
744
  expect(payload.site.page).does.exist.and.equal('https://blah.com/test.html');
671
745
  expect(payload.site.domain).does.exist.and.equal('blah.com');
672
- getConfigStub.restore();
673
746
  });
674
747
 
675
748
  it('should set pageUrl as site param', function () {
676
- let getConfigStub = sinon.stub(config, 'getConfig');
749
+ getConfigStub = sinon.stub(config, 'getConfig');
677
750
  getConfigStub.withArgs('pageUrl').returns('https://improvidigital.com/test-page');
678
751
  let request = spec.buildRequests([simpleBidRequest], bidderRequestReferrer)[0];
679
752
  let payload = JSON.parse(request.data);
@@ -686,17 +759,64 @@ describe('Improve Digital Adapter Tests', function () {
686
759
  payload = JSON.parse(request.data);
687
760
  expect(payload.site.page).does.exist.and.equal('https://blah.com/test.html');
688
761
  expect(payload.site.domain).does.exist.and.equal('blah.com');
689
- getConfigStub.restore();
690
762
  });
691
763
 
692
764
  it('should set site when app not available', function () {
693
- const getConfigStub = sinon.stub(config, 'getConfig');
765
+ getConfigStub = sinon.stub(config, 'getConfig');
694
766
  getConfigStub.withArgs('app').returns(undefined);
695
767
  let request = spec.buildRequests([simpleBidRequest], bidderRequest)[0];
696
768
  let payload = JSON.parse(request.data);
697
769
  expect(payload.site).does.exist;
698
770
  expect(payload.app).does.not.exist;
699
- getConfigStub.restore();
771
+ });
772
+
773
+ it('should set extend params when extend mode enabled from global configuration', function () {
774
+ getConfigStub = sinon.stub(config, 'getConfig');
775
+ const bannerRequest = deepClone(simpleBidRequest);
776
+ const keyValues = { testKey: [ 'testValue' ] };
777
+ bannerRequest.params.keyValues = keyValues;
778
+
779
+ getConfigStub.withArgs('improvedigital.extend').returns(true);
780
+ const requests = spec.buildRequests([bannerRequest, instreamBidRequest], bidderRequest);
781
+ expect(requests[0].method).to.equal(METHOD);
782
+ expect(requests[0].url).to.equal(EXTEND_URL);
783
+ expect(requests[1].url).to.equal(EXTEND_URL);
784
+ // banner
785
+ let payload = JSON.parse(requests[0].data);
786
+ expect(payload.imp[0].ext.bidder).to.not.exist;
787
+ expect(payload.imp[0].ext.prebid.bidder.improvedigital).to.deep.equal({
788
+ placementId: 1053688,
789
+ keyValues
790
+ });
791
+ expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal('1053688');
792
+ // video
793
+ payload = JSON.parse(requests[1].data);
794
+ expect(payload.imp[0].ext.bidder).to.not.exist;
795
+ expect(payload.imp[0].ext.prebid.bidder.improvedigital.placementId).to.equal(123456);
796
+ expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal('123456');
797
+ });
798
+
799
+ it('should set extend url when extend mode enabled in adunit params', function () {
800
+ const bidRequest = deepClone(extendBidRequest);
801
+ let request = spec.buildRequests([bidRequest], { bids: [bidRequest] })[0];
802
+ expect(request.url).to.equal(EXTEND_URL);
803
+
804
+ getConfigStub = sinon.stub(config, 'getConfig');
805
+
806
+ // adunit param takes precedence over the global config
807
+ getConfigStub.withArgs('improvedigital.extend').returns(false);
808
+ request = spec.buildRequests([bidRequest], { bids: [bidRequest] })[0];
809
+ expect(request.url).to.equal(EXTEND_URL);
810
+
811
+ bidRequest.params.extend = false;
812
+ getConfigStub.withArgs('improvedigital.extend').returns(true);
813
+ request = spec.buildRequests([bidRequest], { bids: [bidRequest] })[0];
814
+ expect(request.url).to.equal(AD_SERVER_URL);
815
+
816
+ const requests = spec.buildRequests([bidRequest, instreamBidRequest], { bids: [bidRequest, instreamBidRequest] });
817
+ expect(requests.length).to.equal(2);
818
+ expect(requests[0].url).to.equal(AD_SERVER_URL);
819
+ expect(requests[1].url).to.equal(EXTEND_URL);
700
820
  });
701
821
  });
702
822
 
@@ -730,7 +850,16 @@ describe('Improve Digital Adapter Tests', function () {
730
850
  ],
731
851
  'seat': 'improvedigital'
732
852
  }
733
- ]
853
+ ],
854
+ ext: {
855
+ improvedigital: {
856
+ sync: [
857
+ 'https://link1',
858
+ 'https://link2',
859
+ 'https://link3',
860
+ ]
861
+ }
862
+ }
734
863
  }
735
864
  };
736
865
 
@@ -790,7 +919,7 @@ describe('Improve Digital Adapter Tests', function () {
790
919
  sync: [
791
920
  'https://link1',
792
921
  'https://link2',
793
- 'https://link3',
922
+ 'https://link4',
794
923
  ]
795
924
  }
796
925
  }
@@ -989,7 +1118,7 @@ describe('Improve Digital Adapter Tests', function () {
989
1118
  });
990
1119
 
991
1120
  it('should set dealId correctly', function () {
992
- const response = JSON.parse(JSON.stringify(serverResponse));
1121
+ const response = deepClone(serverResponse);
993
1122
  let bids;
994
1123
 
995
1124
  delete response.body.seatbid[0].bid[0].ext.improvedigital.line_item_id;
@@ -1019,14 +1148,14 @@ describe('Improve Digital Adapter Tests', function () {
1019
1148
  });
1020
1149
 
1021
1150
  it('should set currency', function () {
1022
- const response = JSON.parse(JSON.stringify(serverResponse));
1151
+ const response = deepClone(serverResponse);
1023
1152
  response.body.cur = 'eur';
1024
1153
  const bids = spec.interpretResponse(response, {bidderRequest});
1025
1154
  expect(bids[0].currency).to.equal('EUR');
1026
1155
  });
1027
1156
 
1028
1157
  it('should return empty array for bad response or no price', function () {
1029
- let response = JSON.parse(JSON.stringify(serverResponse));
1158
+ let response = deepClone(serverResponse);
1030
1159
  let bids;
1031
1160
 
1032
1161
  // Price missing or 0
@@ -1041,13 +1170,13 @@ describe('Improve Digital Adapter Tests', function () {
1041
1170
  expect(bids).to.deep.equal([]);
1042
1171
 
1043
1172
  // errorCode present
1044
- response = JSON.parse(JSON.stringify(serverResponse));
1173
+ response = deepClone(serverResponse);
1045
1174
  response.body.seatbid[0].bid[0].errorCode = undefined;
1046
1175
  bids = spec.interpretResponse(response, {bidderRequest});
1047
1176
  expect(bids).to.deep.equal([]);
1048
1177
 
1049
1178
  // adm and native missing
1050
- response = JSON.parse(JSON.stringify(serverResponse));
1179
+ response = deepClone(serverResponse);
1051
1180
  delete response.body.seatbid[0].bid[0].adm;
1052
1181
  bids = spec.interpretResponse(response, {bidderRequest});
1053
1182
  expect(bids).to.deep.equal([]);
@@ -1057,7 +1186,7 @@ describe('Improve Digital Adapter Tests', function () {
1057
1186
  });
1058
1187
 
1059
1188
  it('should set netRevenue', function () {
1060
- const response = JSON.parse(JSON.stringify(serverResponse));
1189
+ const response = deepClone(serverResponse);
1061
1190
  response.body.seatbid[0].bid[0].ext.improvedigital.is_net = true;
1062
1191
  const bids = spec.interpretResponse(response, {bidderRequest});
1063
1192
  expect(bids[0].netRevenue).to.equal(true);
@@ -1065,7 +1194,7 @@ describe('Improve Digital Adapter Tests', function () {
1065
1194
 
1066
1195
  it('should set advertiserDomains', function () {
1067
1196
  const adomain = ['domain.com'];
1068
- const response = JSON.parse(JSON.stringify(serverResponse));
1197
+ const response = deepClone(serverResponse);
1069
1198
  response.body.seatbid[0].bid[0].adomain = adomain;
1070
1199
  const bids = spec.interpretResponse(response, {bidderRequest});
1071
1200
  expect(bids[0].meta.advertiserDomains).to.equal(adomain);
@@ -1108,10 +1237,19 @@ describe('Improve Digital Adapter Tests', function () {
1108
1237
  });
1109
1238
 
1110
1239
  it('should return a well-formed outstream video bid for multi-format ad unit', function () {
1111
- const bids = spec.interpretResponse(serverResponseVideo, {bidderRequest: multiFormatBidderRequest});
1240
+ const videoResponse = deepClone(serverResponseVideo);
1241
+ let bids = spec.interpretResponse(videoResponse, {bidderRequest: multiFormatBidderRequest});
1112
1242
  expect(bids[0].renderer).to.exist;
1113
1243
  delete (bids[0].renderer);
1114
1244
  expect(bids).to.deep.equal(expectedBidOutstreamVideo);
1245
+
1246
+ videoResponse.body.seatbid[0].bid[0].adm = '<vAst';
1247
+ bids = spec.interpretResponse(videoResponse, {bidderRequest: multiFormatBidderRequest});
1248
+ expect(bids[0].mediaType).to.equal(VIDEO);
1249
+
1250
+ videoResponse.body.seatbid[0].bid[0].adm = '<?xml';
1251
+ bids = spec.interpretResponse(videoResponse, {bidderRequest: multiFormatBidderRequest});
1252
+ expect(bids[0].mediaType).to.equal(VIDEO);
1115
1253
  });
1116
1254
 
1117
1255
  it('should not affect non-RAZR bids', function () {
@@ -1126,21 +1264,100 @@ describe('Improve Digital Adapter Tests', function () {
1126
1264
  });
1127
1265
 
1128
1266
  describe('getUserSyncs', function () {
1129
- const serverResponses = [ serverResponseTwoBids ];
1267
+ const serverResponses = [ serverResponse, serverResponseTwoBids ];
1268
+ const pixelSyncs = [
1269
+ { type: 'image', url: 'https://link1' },
1270
+ { type: 'image', url: 'https://link2' },
1271
+ { type: 'image', url: 'https://link3' },
1272
+ { type: 'image', url: 'https://link4' }
1273
+ ];
1274
+
1275
+ const basicIframeSyncUrl = `${IFRAME_SYNC_URL}?placement_id=1053688`;
1276
+
1277
+ const uspConsent = '1YYY';
1278
+
1279
+ let getConfigStub = null;
1130
1280
 
1131
- it('should return no syncs when pixel syncing is disabled', function () {
1132
- const syncs = spec.getUserSyncs({ pixelEnabled: false }, serverResponses);
1281
+ beforeEach(function () {
1282
+ spec.syncStore = { extendMode: false, placementId: null };
1283
+ });
1284
+
1285
+ afterEach(function () {
1286
+ if (getConfigStub) {
1287
+ getConfigStub.restore();
1288
+ getConfigStub = null;
1289
+ }
1290
+ });
1291
+
1292
+ it('should return no syncs when neither iframe nor pixel syncing is enabled', function () {
1293
+ const syncs = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }, serverResponses);
1133
1294
  expect(syncs).to.deep.equal([]);
1134
1295
  });
1135
1296
 
1136
- it('should return user syncs', function () {
1297
+ it('should return no syncs for COPPA users', function () {
1298
+ getConfigStub = sinon.stub(config, 'getConfig');
1299
+ getConfigStub.withArgs('coppa').returns(true);
1300
+ const syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses);
1301
+ expect(syncs).to.deep.equal([]);
1302
+ });
1303
+
1304
+ it('should return no syncs for when GDPR consent for purpose 1 not given', function () {
1305
+ const consent = deepClone(gdprConsent);
1306
+ deepSetValue(consent, 'vendorData.purpose.consents.1', false);
1307
+ const syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses, consent);
1308
+ expect(syncs).to.deep.equal([]);
1309
+ });
1310
+
1311
+ it('should return pixel user syncs for the ad server mode', function () {
1312
+ const syncs = spec.getUserSyncs({ pixelEnabled: true }, serverResponses);
1313
+ expect(syncs).to.deep.equal(pixelSyncs);
1314
+ });
1315
+
1316
+ it('should return pixel user syncs for extend mode when iframe mode disabled', function () {
1317
+ // Set spec.syncStore vars
1318
+ getConfigStub = sinon.stub(config, 'getConfig');
1319
+ getConfigStub.withArgs('improvedigital.extend').returns(true);
1320
+ spec.buildRequests([simpleBidRequest], bidderRequest);
1321
+
1137
1322
  const syncs = spec.getUserSyncs({ pixelEnabled: true }, serverResponses);
1138
- const expected = [
1139
- { type: 'image', url: 'https://link1' },
1140
- { type: 'image', url: 'https://link2' },
1141
- { type: 'image', url: 'https://link3' }
1142
- ];
1143
- expect(syncs).to.deep.equal(expected);
1323
+ expect(syncs).to.deep.equal(pixelSyncs);
1324
+ });
1325
+
1326
+ it('should return iframe user sync for the ad server mode when pixel mode disabled', function () {
1327
+ spec.buildRequests([simpleBidRequest], bidderRequest);
1328
+ const syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, serverResponses);
1329
+ expect(syncs).to.deep.equal([{ type: 'iframe', url: basicIframeSyncUrl }]);
1330
+ });
1331
+
1332
+ it('should attach gdpr consent to iframe sync url', function () {
1333
+ spec.buildRequests([simpleBidRequest], bidderRequest);
1334
+ let syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, serverResponses, gdprConsent);
1335
+ expect(syncs).to.deep.equal([{ type: 'iframe', url: `${basicIframeSyncUrl}&gdpr=1&gdpr_consent=CONSENT` }]);
1336
+
1337
+ syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, serverResponses, { gdprApplies: false });
1338
+ expect(syncs).to.deep.equal([{ type: 'iframe', url: `${basicIframeSyncUrl}&gdpr=0` }]);
1339
+ });
1340
+
1341
+ it('should attach usp consent to iframe sync url', function () {
1342
+ spec.buildRequests([simpleBidRequest], bidderRequest);
1343
+ let syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, serverResponses, null, uspConsent);
1344
+ expect(syncs).to.deep.equal([{ type: 'iframe', url: `${basicIframeSyncUrl}&us_privacy=${uspConsent}` }]);
1345
+ });
1346
+
1347
+ it('should return iframe user sync for the adunit extend mode if iframe mode enabled', function () {
1348
+ // buildRequests() sets spec.syncStore vars
1349
+ spec.buildRequests([simpleBidRequest, extendBidRequest]);
1350
+ const syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses);
1351
+ expect(syncs).to.deep.equal([{ type: 'iframe', url: basicIframeSyncUrl + '&pbs=1' }]);
1352
+ });
1353
+
1354
+ it('should return iframe user sync for the global extend mode if iframe mode enabled', function () {
1355
+ getConfigStub = sinon.stub(config, 'getConfig');
1356
+ getConfigStub.withArgs('improvedigital.extend').returns(true);
1357
+ // buildRequests() sets spec.syncStore vars
1358
+ spec.buildRequests([simpleBidRequest]);
1359
+ const syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses);
1360
+ expect(syncs).to.deep.equal([{ type: 'iframe', url: basicIframeSyncUrl + '&pbs=1' }]);
1144
1361
  });
1145
1362
  });
1146
1363
  });