prebid.js 7.46.0 → 7.48.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 (195) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/33acrossIdSystem.js +1 -1
  3. package/dist/ablidaBidAdapter.js +1 -1
  4. package/dist/adagioBidAdapter.js +1 -1
  5. package/dist/adbookpspBidAdapter.js +1 -1
  6. package/dist/adgenerationBidAdapter.js +1 -1
  7. package/dist/admaticBidAdapter.js +1 -1
  8. package/dist/adrelevantisBidAdapter.js +1 -1
  9. package/dist/adrinoBidAdapter.js +1 -1
  10. package/dist/adtrgtmeBidAdapter.js +1 -1
  11. package/dist/adxcgBidAdapter.js +1 -1
  12. package/dist/adyoulikeBidAdapter.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/axonixBidAdapter.js +1 -1
  20. package/dist/bidglassBidAdapter.js +1 -1
  21. package/dist/big-richmediaBidAdapter.js +1 -1
  22. package/dist/bridgewellBidAdapter.js +1 -1
  23. package/dist/brightMountainMediaBidAdapter.js +1 -1
  24. package/dist/carodaBidAdapter.js +1 -1
  25. package/dist/chtnwBidAdapter.js +1 -1
  26. package/dist/concertBidAdapter.js +1 -1
  27. package/dist/connectIdSystem.js +1 -1
  28. package/dist/connectadBidAdapter.js +1 -1
  29. package/dist/consumableBidAdapter.js +1 -1
  30. package/dist/conversantAnalyticsAdapter.js +1 -1
  31. package/dist/conversantBidAdapter.js +1 -1
  32. package/dist/craftBidAdapter.js +1 -1
  33. package/dist/criteoBidAdapter.js +1 -1
  34. package/dist/criteoIdSystem.js +1 -1
  35. package/dist/cwireBidAdapter.js +1 -1
  36. package/dist/dependencies.json +4 -0
  37. package/dist/dspxBidAdapter.js +1 -1
  38. package/dist/emtvBidAdapter.js +1 -0
  39. package/dist/eplanningBidAdapter.js +1 -1
  40. package/dist/feedadBidAdapter.js +1 -1
  41. package/dist/finativeBidAdapter.js +1 -1
  42. package/dist/freewheel-sspBidAdapter.js +1 -1
  43. package/dist/glimpseBidAdapter.js +1 -1
  44. package/dist/gmosspBidAdapter.js +1 -1
  45. package/dist/goldbachBidAdapter.js +1 -1
  46. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  47. package/dist/greenbidsRtdProvider.js +1 -0
  48. package/dist/gridBidAdapter.js +1 -1
  49. package/dist/gumgumBidAdapter.js +1 -1
  50. package/dist/h12mediaBidAdapter.js +1 -1
  51. package/dist/id5IdSystem.js +1 -1
  52. package/dist/impactifyBidAdapter.js +1 -1
  53. package/dist/improvedigitalBidAdapter.js +1 -1
  54. package/dist/inmarBidAdapter.js +1 -1
  55. package/dist/insticatorBidAdapter.js +1 -1
  56. package/dist/iqmBidAdapter.js +1 -1
  57. package/dist/ixBidAdapter.js +1 -1
  58. package/dist/justpremiumBidAdapter.js +1 -1
  59. package/dist/kargoBidAdapter.js +1 -1
  60. package/dist/konduitAnalyticsAdapter.js +1 -1
  61. package/dist/kueezBidAdapter.js +1 -1
  62. package/dist/kueezRtbBidAdapter.js +1 -1
  63. package/dist/kulturemediaBidAdapter.js +1 -1
  64. package/dist/lassoBidAdapter.js +1 -1
  65. package/dist/lifestreetBidAdapter.js +1 -1
  66. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  67. package/dist/logicadBidAdapter.js +1 -1
  68. package/dist/loglyliftBidAdapter.js +1 -1
  69. package/dist/magniteAnalyticsAdapter.js +1 -1
  70. package/dist/malltvAnalyticsAdapter.js +1 -1
  71. package/dist/marsmediaBidAdapter.js +1 -1
  72. package/dist/mediafuseBidAdapter.js +1 -1
  73. package/dist/mediasquareBidAdapter.js +1 -1
  74. package/dist/mgidBidAdapter.js +1 -1
  75. package/dist/minutemediaBidAdapter.js +1 -1
  76. package/dist/minutemediaplusBidAdapter.js +1 -1
  77. package/dist/missenaBidAdapter.js +1 -1
  78. package/dist/nextMillenniumBidAdapter.js +1 -1
  79. package/dist/nexx360BidAdapter.js +1 -1
  80. package/dist/not-for-prod/prebid.js +142 -139
  81. package/dist/oguryBidAdapter.js +1 -1
  82. package/dist/onetagBidAdapter.js +1 -1
  83. package/dist/ooloAnalyticsAdapter.js +1 -1
  84. package/dist/optidigitalBidAdapter.js +1 -1
  85. package/dist/orbitsoftBidAdapter.js +1 -1
  86. package/dist/outbrainBidAdapter.js +1 -1
  87. package/dist/parrableIdSystem.js +1 -1
  88. package/dist/pixfutureBidAdapter.js +1 -1
  89. package/dist/prebid-core.js +1 -1
  90. package/dist/publinkIdSystem.js +1 -1
  91. package/dist/pubmaticBidAdapter.js +1 -1
  92. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  93. package/dist/pxyzBidAdapter.js +1 -1
  94. package/dist/quantcastBidAdapter.js +1 -1
  95. package/dist/radsBidAdapter.js +1 -1
  96. package/dist/readpeakBidAdapter.js +1 -1
  97. package/dist/relaidoBidAdapter.js +1 -1
  98. package/dist/relevantdigitalBidAdapter.js +1 -0
  99. package/dist/rhythmoneBidAdapter.js +1 -1
  100. package/dist/riseBidAdapter.js +1 -1
  101. package/dist/rtbhouseBidAdapter.js +1 -1
  102. package/dist/rubiconAnalyticsAdapter.js +1 -1
  103. package/dist/rubiconBidAdapter.js +1 -1
  104. package/dist/seedingAllianceBidAdapter.js +1 -1
  105. package/dist/seedtagBidAdapter.js +1 -1
  106. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  107. package/dist/sharethroughBidAdapter.js +1 -1
  108. package/dist/shinezBidAdapter.js +1 -1
  109. package/dist/smaatoBidAdapter.js +1 -1
  110. package/dist/smartadserverBidAdapter.js +1 -1
  111. package/dist/smartxBidAdapter.js +1 -1
  112. package/dist/smilewantedBidAdapter.js +1 -1
  113. package/dist/sonobiBidAdapter.js +1 -1
  114. package/dist/sovrnAnalyticsAdapter.js +1 -1
  115. package/dist/sovrnBidAdapter.js +1 -1
  116. package/dist/sspBCBidAdapter.js +1 -1
  117. package/dist/stvBidAdapter.js +1 -1
  118. package/dist/sublimeBidAdapter.js +1 -1
  119. package/dist/synacormediaBidAdapter.js +1 -1
  120. package/dist/targetVideoBidAdapter.js +1 -1
  121. package/dist/teadsBidAdapter.js +1 -1
  122. package/dist/trionBidAdapter.js +1 -1
  123. package/dist/tripleliftBidAdapter.js +1 -1
  124. package/dist/ttdBidAdapter.js +1 -1
  125. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  126. package/dist/uid2IdSystem.js +1 -1
  127. package/dist/underdogmediaBidAdapter.js +1 -1
  128. package/dist/undertoneBidAdapter.js +1 -1
  129. package/dist/userId.js +1 -1
  130. package/dist/vdoaiBidAdapter.js +1 -1
  131. package/dist/vidazooBidAdapter.js +1 -1
  132. package/dist/videobyteBidAdapter.js +1 -1
  133. package/dist/vidoomyBidAdapter.js +1 -1
  134. package/dist/visxBidAdapter.js +1 -1
  135. package/dist/vuukleBidAdapter.js +1 -1
  136. package/dist/widespaceBidAdapter.js +1 -1
  137. package/dist/winrBidAdapter.js +1 -1
  138. package/dist/wipesBidAdapter.js +1 -1
  139. package/dist/yahoosspBidAdapter.js +1 -1
  140. package/dist/yieldmoBidAdapter.js +1 -1
  141. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  142. package/dist/yieldoneBidAdapter.js +1 -1
  143. package/modules/ablidaBidAdapter.js +4 -5
  144. package/modules/admaticBidAdapter.js +32 -5
  145. package/modules/adrinoBidAdapter.js +11 -4
  146. package/modules/axonixBidAdapter.js +6 -6
  147. package/modules/connectIdSystem.js +5 -2
  148. package/modules/criteoBidAdapter.js +3 -5
  149. package/modules/criteoIdSystem.js +27 -14
  150. package/modules/dspxBidAdapter.js +2 -3
  151. package/modules/emtvBidAdapter.js +211 -0
  152. package/modules/emtvBidAdapter.md +79 -0
  153. package/modules/freewheel-sspBidAdapter.js +32 -7
  154. package/modules/greenbidsRtdProvider.js +110 -0
  155. package/modules/greenbidsRtdProvider.md +65 -0
  156. package/modules/impactifyBidAdapter.js +0 -1
  157. package/modules/iqmBidAdapter.js +1 -2
  158. package/modules/missenaBidAdapter.js +1 -1
  159. package/modules/nextMillenniumBidAdapter.js +2 -0
  160. package/modules/orbitsoftBidAdapter.js +1 -2
  161. package/modules/radsBidAdapter.js +3 -4
  162. package/modules/relevantdigitalBidAdapter.js +198 -0
  163. package/modules/relevantdigitalBidAdapter.md +117 -0
  164. package/modules/rtbhouseBidAdapter.js +9 -12
  165. package/modules/sovrnBidAdapter.js +4 -0
  166. package/modules/stvBidAdapter.js +4 -5
  167. package/modules/tripleliftBidAdapter.js +14 -3
  168. package/modules/ttdBidAdapter.js +73 -71
  169. package/modules/underdogmediaBidAdapter.js +9 -12
  170. package/modules/userId/index.js +1 -1
  171. package/modules/vdoaiBidAdapter.js +2 -3
  172. package/modules/vidoomyBidAdapter.js +19 -6
  173. package/modules/vidoomyBidAdapter.md +12 -2
  174. package/modules/wipesBidAdapter.js +2 -3
  175. package/modules/yieldmoBidAdapter.js +2 -2
  176. package/modules/yieldoneBidAdapter.js +3 -4
  177. package/package.json +1 -1
  178. package/test/spec/modules/adlooxAdServerVideo_spec.js +18 -35
  179. package/test/spec/modules/admaticBidAdapter_spec.js +164 -11
  180. package/test/spec/modules/adrinoBidAdapter_spec.js +50 -2
  181. package/test/spec/modules/connectIdSystem_spec.js +4 -4
  182. package/test/spec/modules/criteoBidAdapter_spec.js +56 -0
  183. package/test/spec/modules/criteoIdSystem_spec.js +99 -9
  184. package/test/spec/modules/emtvBidAdapter_spec.js +400 -0
  185. package/test/spec/modules/freewheel-sspBidAdapter_spec.js +31 -2
  186. package/test/spec/modules/greenbidsRtdProvider_spec.js +210 -0
  187. package/test/spec/modules/relevantdigitalBidAdapter_spec.js +295 -0
  188. package/test/spec/modules/rtbhouseBidAdapter_spec.js +24 -2
  189. package/test/spec/modules/sovrnBidAdapter_spec.js +65 -0
  190. package/test/spec/modules/tripleliftBidAdapter_spec.js +53 -8
  191. package/test/spec/modules/ttdBidAdapter_spec.js +20 -0
  192. package/test/spec/modules/vidoomyBidAdapter_spec.js +49 -0
  193. package/test/spec/modules/yieldmoBidAdapter_spec.js +2 -2
  194. package/test/spec/ortbConverter/userId_spec.js +12 -0
  195. package/test/spec/modules/realvuAnalyticsAdapter_spec.js +0 -189
@@ -1,5 +1,6 @@
1
1
  import { criteoIdSubmodule, storage } from 'modules/criteoIdSystem.js';
2
2
  import * as utils from 'src/utils.js';
3
+ import { gdprDataHandler, uspDataHandler, gppDataHandler } from '../../../src/adapterManager.js';
3
4
  import { server } from '../../mocks/xhr';
4
5
 
5
6
  const pastDateString = new Date(0).toString()
@@ -17,6 +18,9 @@ describe('CriteoId module', function () {
17
18
  let timeStampStub;
18
19
  let parseUrlStub;
19
20
  let triggerPixelStub;
21
+ let gdprConsentDataStub;
22
+ let uspConsentDataStub;
23
+ let gppConsentDataStub;
20
24
 
21
25
  beforeEach(function (done) {
22
26
  getCookieStub = sinon.stub(storage, 'getCookie');
@@ -27,6 +31,9 @@ describe('CriteoId module', function () {
27
31
  timeStampStub = sinon.stub(utils, 'timestamp').returns(nowTimestamp);
28
32
  parseUrlStub = sinon.stub(utils, 'parseUrl').returns({ protocol: 'https', hostname: 'testdev.com' })
29
33
  triggerPixelStub = sinon.stub(utils, 'triggerPixel');
34
+ gdprConsentDataStub = sinon.stub(gdprDataHandler, 'getConsentData');
35
+ uspConsentDataStub = sinon.stub(uspDataHandler, 'getConsentData');
36
+ gppConsentDataStub = sinon.stub(gppDataHandler, 'getConsentData');
30
37
  done();
31
38
  });
32
39
 
@@ -39,6 +46,9 @@ describe('CriteoId module', function () {
39
46
  timeStampStub.restore();
40
47
  triggerPixelStub.restore();
41
48
  parseUrlStub.restore();
49
+ gdprConsentDataStub.restore();
50
+ uspConsentDataStub.restore();
51
+ gppConsentDataStub.restore();
42
52
  });
43
53
 
44
54
  const storageTestCases = [
@@ -136,11 +146,11 @@ describe('CriteoId module', function () {
136
146
  }));
137
147
 
138
148
  const gdprConsentTestCases = [
139
- { consentData: { gdprApplies: true, consentString: 'expectedConsentString' }, expected: 'expectedConsentString' },
140
- { consentData: { gdprApplies: false, consentString: 'expectedConsentString' }, expected: undefined },
141
- { consentData: { gdprApplies: true, consentString: undefined }, expected: undefined },
142
- { consentData: { gdprApplies: 'oui', consentString: 'expectedConsentString' }, expected: undefined },
143
- { consentData: undefined, expected: undefined }
149
+ { consentData: { gdprApplies: true, consentString: 'expectedConsentString' }, expectedGdprConsent: 'expectedConsentString', expectedGdpr: '1' },
150
+ { consentData: { gdprApplies: false, consentString: 'expectedConsentString' }, expectedGdprConsent: 'expectedConsentString', expectedGdpr: '0' },
151
+ { consentData: { gdprApplies: true, consentString: undefined }, expectedGdprConsent: undefined, expectedGdpr: '1' },
152
+ { consentData: { gdprApplies: 'oui', consentString: 'expectedConsentString' }, expectedGdprConsent: 'expectedConsentString', expectedGdpr: '0' },
153
+ { consentData: undefined, expectedGdprConsent: undefined, expectedGdpr: undefined }
144
154
  ];
145
155
 
146
156
  it('should call sync pixels if request by backend', function () {
@@ -225,14 +235,94 @@ describe('CriteoId module', function () {
225
235
 
226
236
  gdprConsentTestCases.forEach(testCase => it('should call user sync url with the gdprConsent', function () {
227
237
  let callBackSpy = sinon.spy();
228
- let result = criteoIdSubmodule.getId(undefined, testCase.consentData);
238
+
239
+ gdprConsentDataStub.returns(testCase.consentData);
240
+
241
+ let result = criteoIdSubmodule.getId(undefined);
242
+ result.callback(callBackSpy);
243
+
244
+ let request = server.requests[0];
245
+
246
+ if (testCase.expectedGdprConsent) {
247
+ expect(request.url).to.have.string(`gdprString=${testCase.expectedGdprConsent}`);
248
+ } else {
249
+ expect(request.url).to.not.have.string('gdprString=');
250
+ }
251
+
252
+ if (testCase.expectedGdpr) {
253
+ expect(request.url).to.have.string(`gdpr=${testCase.expectedGdpr}`);
254
+ } else {
255
+ expect(request.url).to.not.have.string('gdpr=');
256
+ }
257
+
258
+ request.respond(
259
+ 200,
260
+ { 'Content-Type': 'application/json' },
261
+ JSON.stringify({})
262
+ );
263
+
264
+ expect(callBackSpy.calledOnce).to.be.true;
265
+ }));
266
+
267
+ [undefined, 'abc'].forEach(usPrivacy => it('should call user sync url with the us privacy string', function () {
268
+ let callBackSpy = sinon.spy();
269
+
270
+ uspConsentDataStub.returns(usPrivacy);
271
+
272
+ let result = criteoIdSubmodule.getId(undefined);
229
273
  result.callback(callBackSpy);
230
274
 
231
275
  let request = server.requests[0];
232
- if (testCase.expected) {
233
- expect(request.url).to.have.string(`gdprString=${testCase.expected}`);
276
+
277
+ if (usPrivacy) {
278
+ expect(request.url).to.have.string(`us_privacy=${usPrivacy}`);
279
+ } else {
280
+ expect(request.url).to.not.have.string('us_privacy=');
281
+ }
282
+
283
+ request.respond(
284
+ 200,
285
+ { 'Content-Type': 'application/json' },
286
+ JSON.stringify({})
287
+ );
288
+
289
+ expect(callBackSpy.calledOnce).to.be.true;
290
+ }));
291
+
292
+ [
293
+ {
294
+ consentData: {
295
+ gppString: 'abc',
296
+ applicableSections: [1]
297
+ },
298
+ expectedGpp: 'abc',
299
+ expectedGppSid: '1'
300
+ },
301
+ {
302
+ consentData: undefined,
303
+ expectedGpp: undefined,
304
+ expectedGppSid: undefined
305
+ }
306
+ ].forEach(testCase => it('should call user sync url with the gpp string', function () {
307
+ let callBackSpy = sinon.spy();
308
+
309
+ gppConsentDataStub.returns(testCase.consentData);
310
+
311
+ let result = criteoIdSubmodule.getId(undefined);
312
+ result.callback(callBackSpy);
313
+
314
+ let request = server.requests[0];
315
+
316
+ if (testCase.expectedGpp) {
317
+ expect(request.url).to.have.string(`gpp=${testCase.expectedGpp}`);
318
+ } else {
319
+ expect(request.url).to.not.have.string('gpp=');
320
+ }
321
+
322
+ if (testCase.expectedGppSid) {
323
+ expect(request.url).to.have.string(`gpp_sid=${testCase.expectedGppSid}`);
234
324
  } else {
235
- expect(request.url).to.not.have.string('gdprString');
325
+ expect(request.url).to.not.have.string('gpp_sid=');
236
326
  }
237
327
 
238
328
  request.respond(
@@ -0,0 +1,400 @@
1
+ import { expect } from 'chai';
2
+ import { spec } from '../../../modules/emtvBidAdapter.js';
3
+ import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js';
4
+ import { getUniqueIdentifierStr } from '../../../src/utils.js';
5
+
6
+ const bidder = 'emtv'
7
+ const adUrl = 'https://us-east-ep.engagemedia.tv/pbjs';
8
+ const syncUrl = 'https://cs.engagemedia.tv';
9
+
10
+ describe('EMTVBidAdapter', function () {
11
+ const bids = [
12
+ {
13
+ bidId: getUniqueIdentifierStr(),
14
+ bidder: bidder,
15
+ mediaTypes: {
16
+ [BANNER]: {
17
+ sizes: [[300, 250]]
18
+ }
19
+ },
20
+ params: {
21
+ placementId: 'testBanner',
22
+ }
23
+ },
24
+ {
25
+ bidId: getUniqueIdentifierStr(),
26
+ bidder: bidder,
27
+ mediaTypes: {
28
+ [VIDEO]: {
29
+ playerSize: [[300, 300]],
30
+ minduration: 5,
31
+ maxduration: 60
32
+ }
33
+ },
34
+ params: {
35
+ placementId: 'testVideo',
36
+ }
37
+ },
38
+ {
39
+ bidId: getUniqueIdentifierStr(),
40
+ bidder: bidder,
41
+ mediaTypes: {
42
+ [NATIVE]: {
43
+ native: {
44
+ title: {
45
+ required: true
46
+ },
47
+ body: {
48
+ required: true
49
+ },
50
+ icon: {
51
+ required: true,
52
+ size: [64, 64]
53
+ }
54
+ }
55
+ }
56
+ },
57
+ params: {
58
+ placementId: 'testNative',
59
+ }
60
+ }
61
+ ];
62
+
63
+ const invalidBid = {
64
+ bidId: getUniqueIdentifierStr(),
65
+ bidder: bidder,
66
+ mediaTypes: {
67
+ [BANNER]: {
68
+ sizes: [[300, 250]]
69
+ }
70
+ },
71
+ params: {
72
+
73
+ }
74
+ }
75
+
76
+ const bidderRequest = {
77
+ uspConsent: '1---',
78
+ gdprConsent: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw',
79
+ refererInfo: {
80
+ referer: 'https://test.com'
81
+ }
82
+ };
83
+
84
+ describe('isBidRequestValid', function () {
85
+ it('Should return true if there are bidId, params and key parameters present', function () {
86
+ expect(spec.isBidRequestValid(bids[0])).to.be.true;
87
+ });
88
+ it('Should return false if at least one of parameters is not present', function () {
89
+ expect(spec.isBidRequestValid(invalidBid)).to.be.false;
90
+ });
91
+ });
92
+
93
+ describe('buildRequests', function () {
94
+ let serverRequest = spec.buildRequests(bids, bidderRequest);
95
+
96
+ it('Creates a ServerRequest object with method, URL and data', function () {
97
+ expect(serverRequest).to.exist;
98
+ expect(serverRequest.method).to.exist;
99
+ expect(serverRequest.url).to.exist;
100
+ expect(serverRequest.data).to.exist;
101
+ });
102
+
103
+ it('Returns POST method', function () {
104
+ expect(serverRequest.method).to.equal('POST');
105
+ });
106
+
107
+ it('Returns valid URL', function () {
108
+ expect(serverRequest.url).to.equal(adUrl);
109
+ });
110
+
111
+ it('Returns general data valid', function () {
112
+ let data = serverRequest.data;
113
+ expect(data).to.be.an('object');
114
+ expect(data).to.have.all.keys('deviceWidth',
115
+ 'deviceHeight',
116
+ 'language',
117
+ 'secure',
118
+ 'host',
119
+ 'page',
120
+ 'placements',
121
+ 'coppa',
122
+ 'ccpa',
123
+ 'gdpr',
124
+ 'tmax'
125
+ );
126
+ expect(data.deviceWidth).to.be.a('number');
127
+ expect(data.deviceHeight).to.be.a('number');
128
+ expect(data.language).to.be.a('string');
129
+ expect(data.secure).to.be.within(0, 1);
130
+ expect(data.host).to.be.a('string');
131
+ expect(data.page).to.be.a('string');
132
+ expect(data.coppa).to.be.a('number');
133
+ expect(data.gdpr).to.be.a('string');
134
+ expect(data.ccpa).to.be.a('string');
135
+ expect(data.tmax).to.be.a('number');
136
+ expect(data.placements).to.have.lengthOf(3);
137
+ });
138
+
139
+ it('Returns valid placements', function () {
140
+ const { placements } = serverRequest.data;
141
+ for (let i = 0, len = placements.length; i < len; i++) {
142
+ const placement = placements[i];
143
+ expect(placement.placementId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']);
144
+ expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]);
145
+ expect(placement.bidId).to.be.a('string');
146
+ expect(placement.schain).to.be.an('object');
147
+ expect(placement.bidfloor).to.exist.and.to.equal(0);
148
+ expect(placement.type).to.exist.and.to.equal('publisher');
149
+
150
+ if (placement.adFormat === BANNER) {
151
+ expect(placement.sizes).to.be.an('array');
152
+ }
153
+ switch (placement.adFormat) {
154
+ case BANNER:
155
+ expect(placement.sizes).to.be.an('array');
156
+ break;
157
+ case VIDEO:
158
+ expect(placement.playerSize).to.be.an('array');
159
+ expect(placement.minduration).to.be.an('number');
160
+ expect(placement.maxduration).to.be.an('number');
161
+ break;
162
+ case NATIVE:
163
+ expect(placement.native).to.be.an('object');
164
+ break;
165
+ }
166
+ }
167
+ });
168
+
169
+ it('Returns data with gdprConsent and without uspConsent', function () {
170
+ delete bidderRequest.uspConsent;
171
+ serverRequest = spec.buildRequests(bids, bidderRequest);
172
+ let data = serverRequest.data;
173
+ expect(data.gdpr).to.exist;
174
+ expect(data.gdpr).to.be.a('string');
175
+ expect(data.gdpr).to.equal(bidderRequest.gdprConsent);
176
+ expect(data.ccpa).to.not.exist;
177
+ delete bidderRequest.gdprConsent;
178
+ });
179
+
180
+ it('Returns data with uspConsent and without gdprConsent', function () {
181
+ bidderRequest.uspConsent = '1---';
182
+ delete bidderRequest.gdprConsent;
183
+ serverRequest = spec.buildRequests(bids, bidderRequest);
184
+ let data = serverRequest.data;
185
+ expect(data.ccpa).to.exist;
186
+ expect(data.ccpa).to.be.a('string');
187
+ expect(data.ccpa).to.equal(bidderRequest.uspConsent);
188
+ expect(data.gdpr).to.not.exist;
189
+ });
190
+
191
+ it('Returns empty data if no valid requests are passed', function () {
192
+ serverRequest = spec.buildRequests([], bidderRequest);
193
+ let data = serverRequest.data;
194
+ expect(data.placements).to.be.an('array').that.is.empty;
195
+ });
196
+ });
197
+
198
+ describe('interpretResponse', function () {
199
+ it('Should interpret banner response', function () {
200
+ const banner = {
201
+ body: [{
202
+ mediaType: 'banner',
203
+ width: 300,
204
+ height: 250,
205
+ cpm: 0.4,
206
+ ad: 'Test',
207
+ requestId: '23fhj33i987f',
208
+ ttl: 120,
209
+ creativeId: '2',
210
+ netRevenue: true,
211
+ currency: 'USD',
212
+ dealId: '1',
213
+ meta: {
214
+ advertiserDomains: ['google.com'],
215
+ advertiserId: 1234
216
+ }
217
+ }]
218
+ };
219
+ let bannerResponses = spec.interpretResponse(banner);
220
+ expect(bannerResponses).to.be.an('array').that.is.not.empty;
221
+ let dataItem = bannerResponses[0];
222
+ expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId',
223
+ 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta');
224
+ expect(dataItem.requestId).to.equal(banner.body[0].requestId);
225
+ expect(dataItem.cpm).to.equal(banner.body[0].cpm);
226
+ expect(dataItem.width).to.equal(banner.body[0].width);
227
+ expect(dataItem.height).to.equal(banner.body[0].height);
228
+ expect(dataItem.ad).to.equal(banner.body[0].ad);
229
+ expect(dataItem.ttl).to.equal(banner.body[0].ttl);
230
+ expect(dataItem.creativeId).to.equal(banner.body[0].creativeId);
231
+ expect(dataItem.netRevenue).to.be.true;
232
+ expect(dataItem.currency).to.equal(banner.body[0].currency);
233
+ expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains');
234
+ });
235
+ it('Should interpret video response', function () {
236
+ const video = {
237
+ body: [{
238
+ vastUrl: 'test.com',
239
+ mediaType: 'video',
240
+ cpm: 0.5,
241
+ requestId: '23fhj33i987f',
242
+ ttl: 120,
243
+ creativeId: '2',
244
+ netRevenue: true,
245
+ currency: 'USD',
246
+ dealId: '1',
247
+ meta: {
248
+ advertiserDomains: ['google.com'],
249
+ advertiserId: 1234
250
+ }
251
+ }]
252
+ };
253
+ let videoResponses = spec.interpretResponse(video);
254
+ expect(videoResponses).to.be.an('array').that.is.not.empty;
255
+
256
+ let dataItem = videoResponses[0];
257
+ expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId',
258
+ 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta');
259
+ expect(dataItem.requestId).to.equal('23fhj33i987f');
260
+ expect(dataItem.cpm).to.equal(0.5);
261
+ expect(dataItem.vastUrl).to.equal('test.com');
262
+ expect(dataItem.ttl).to.equal(120);
263
+ expect(dataItem.creativeId).to.equal('2');
264
+ expect(dataItem.netRevenue).to.be.true;
265
+ expect(dataItem.currency).to.equal('USD');
266
+ expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains');
267
+ });
268
+ it('Should interpret native response', function () {
269
+ const native = {
270
+ body: [{
271
+ mediaType: 'native',
272
+ native: {
273
+ clickUrl: 'test.com',
274
+ title: 'Test',
275
+ image: 'test.com',
276
+ impressionTrackers: ['test.com'],
277
+ },
278
+ ttl: 120,
279
+ cpm: 0.4,
280
+ requestId: '23fhj33i987f',
281
+ creativeId: '2',
282
+ netRevenue: true,
283
+ currency: 'USD',
284
+ meta: {
285
+ advertiserDomains: ['google.com'],
286
+ advertiserId: 1234
287
+ }
288
+ }]
289
+ };
290
+ let nativeResponses = spec.interpretResponse(native);
291
+ expect(nativeResponses).to.be.an('array').that.is.not.empty;
292
+
293
+ let dataItem = nativeResponses[0];
294
+ expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native', 'meta');
295
+ expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image')
296
+ expect(dataItem.requestId).to.equal('23fhj33i987f');
297
+ expect(dataItem.cpm).to.equal(0.4);
298
+ expect(dataItem.native.clickUrl).to.equal('test.com');
299
+ expect(dataItem.native.title).to.equal('Test');
300
+ expect(dataItem.native.image).to.equal('test.com');
301
+ expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty;
302
+ expect(dataItem.native.impressionTrackers[0]).to.equal('test.com');
303
+ expect(dataItem.ttl).to.equal(120);
304
+ expect(dataItem.creativeId).to.equal('2');
305
+ expect(dataItem.netRevenue).to.be.true;
306
+ expect(dataItem.currency).to.equal('USD');
307
+ expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains');
308
+ });
309
+ it('Should return an empty array if invalid banner response is passed', function () {
310
+ const invBanner = {
311
+ body: [{
312
+ width: 300,
313
+ cpm: 0.4,
314
+ ad: 'Test',
315
+ requestId: '23fhj33i987f',
316
+ ttl: 120,
317
+ creativeId: '2',
318
+ netRevenue: true,
319
+ currency: 'USD',
320
+ dealId: '1'
321
+ }]
322
+ };
323
+
324
+ let serverResponses = spec.interpretResponse(invBanner);
325
+ expect(serverResponses).to.be.an('array').that.is.empty;
326
+ });
327
+ it('Should return an empty array if invalid video response is passed', function () {
328
+ const invVideo = {
329
+ body: [{
330
+ mediaType: 'video',
331
+ cpm: 0.5,
332
+ requestId: '23fhj33i987f',
333
+ ttl: 120,
334
+ creativeId: '2',
335
+ netRevenue: true,
336
+ currency: 'USD',
337
+ dealId: '1'
338
+ }]
339
+ };
340
+ let serverResponses = spec.interpretResponse(invVideo);
341
+ expect(serverResponses).to.be.an('array').that.is.empty;
342
+ });
343
+ it('Should return an empty array if invalid native response is passed', function () {
344
+ const invNative = {
345
+ body: [{
346
+ mediaType: 'native',
347
+ clickUrl: 'test.com',
348
+ title: 'Test',
349
+ impressionTrackers: ['test.com'],
350
+ ttl: 120,
351
+ requestId: '23fhj33i987f',
352
+ creativeId: '2',
353
+ netRevenue: true,
354
+ currency: 'USD',
355
+ }]
356
+ };
357
+ let serverResponses = spec.interpretResponse(invNative);
358
+ expect(serverResponses).to.be.an('array').that.is.empty;
359
+ });
360
+ it('Should return an empty array if invalid response is passed', function () {
361
+ const invalid = {
362
+ body: [{
363
+ ttl: 120,
364
+ creativeId: '2',
365
+ netRevenue: true,
366
+ currency: 'USD',
367
+ dealId: '1'
368
+ }]
369
+ };
370
+ let serverResponses = spec.interpretResponse(invalid);
371
+ expect(serverResponses).to.be.an('array').that.is.empty;
372
+ });
373
+ });
374
+
375
+ describe('getUserSyncs', function() {
376
+ it('Should return array of objects with proper sync config , include GDPR', function() {
377
+ const syncData = spec.getUserSyncs({}, {}, {
378
+ consentString: 'ALL',
379
+ gdprApplies: true,
380
+ }, {});
381
+ expect(syncData).to.be.an('array').which.is.not.empty;
382
+ expect(syncData[0]).to.be.an('object')
383
+ expect(syncData[0].type).to.be.a('string')
384
+ expect(syncData[0].type).to.equal('image')
385
+ expect(syncData[0].url).to.be.a('string')
386
+ expect(syncData[0].url).to.equal(`${syncUrl}/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0`)
387
+ });
388
+ it('Should return array of objects with proper sync config , include CCPA', function() {
389
+ const syncData = spec.getUserSyncs({}, {}, {}, {
390
+ consentString: '1---'
391
+ });
392
+ expect(syncData).to.be.an('array').which.is.not.empty;
393
+ expect(syncData[0]).to.be.an('object')
394
+ expect(syncData[0].type).to.be.a('string')
395
+ expect(syncData[0].type).to.equal('image')
396
+ expect(syncData[0].url).to.be.a('string')
397
+ expect(syncData[0].url).to.equal(`${syncUrl}/image?pbjs=1&ccpa_consent=1---&coppa=0`)
398
+ });
399
+ });
400
+ });
@@ -224,12 +224,41 @@ describe('freewheelSSP BidAdapter Test', () => {
224
224
  let syncOptions = {
225
225
  'pixelEnabled': true
226
226
  }
227
- const userSyncs = spec.getUserSyncs(syncOptions, null, gdprConsent, null);
227
+ const userSyncs = spec.getUserSyncs(syncOptions, null, gdprConsent, null, null);
228
228
  expect(userSyncs).to.deep.equal([{
229
229
  type: 'image',
230
230
  url: 'https://ads.stickyadstv.com/auto-user-sync?gdpr=1&gdpr_consent=1FW-SSP-gdprConsent-'
231
231
  }]);
232
232
  });
233
+
234
+ it('should add gpp information to the request via bidderRequest.gppConsent', function () {
235
+ let consentString = 'abc1234';
236
+ let bidderRequest = {
237
+ 'gppConsent': {
238
+ 'gppString': consentString,
239
+ 'applicableSections': [8]
240
+ }
241
+ };
242
+
243
+ const request = spec.buildRequests(bidRequests, bidderRequest);
244
+ const payload = request[0].data;
245
+
246
+ expect(payload.gpp).to.equal(consentString);
247
+ expect(payload.gpp_sid).to.deep.equal([8]);
248
+
249
+ let gppConsent = {
250
+ 'applicableSections': [8],
251
+ 'gppString': consentString
252
+ }
253
+ let syncOptions = {
254
+ 'pixelEnabled': true
255
+ }
256
+ const userSyncs = spec.getUserSyncs(syncOptions, null, null, null, gppConsent);
257
+ expect(userSyncs).to.deep.equal([{
258
+ type: 'image',
259
+ url: 'https://ads.stickyadstv.com/auto-user-sync?gpp=abc1234&gpp_sid[]=8'
260
+ }]);
261
+ });
233
262
  })
234
263
 
235
264
  describe('buildRequestsForVideo', () => {
@@ -318,7 +347,7 @@ describe('freewheelSSP BidAdapter Test', () => {
318
347
  let syncOptions = {
319
348
  'pixelEnabled': true
320
349
  }
321
- const userSyncs = spec.getUserSyncs(syncOptions, null, gdprConsent, null);
350
+ const userSyncs = spec.getUserSyncs(syncOptions, null, gdprConsent, null, null);
322
351
  expect(userSyncs).to.deep.equal([{
323
352
  type: 'image',
324
353
  url: 'https://ads.stickyadstv.com/auto-user-sync?gdpr=1&gdpr_consent=1FW-SSP-gdprConsent-'