prebid.js 7.46.0 → 7.47.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 (142) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/33acrossIdSystem.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/adrelevantisBidAdapter.js +1 -1
  7. package/dist/adtrgtmeBidAdapter.js +1 -1
  8. package/dist/adxcgBidAdapter.js +1 -1
  9. package/dist/adyoulikeBidAdapter.js +1 -1
  10. package/dist/ajaBidAdapter.js +1 -1
  11. package/dist/amxBidAdapter.js +1 -1
  12. package/dist/amxIdSystem.js +1 -1
  13. package/dist/appierAnalyticsAdapter.js +1 -1
  14. package/dist/appnexusBidAdapter.js +1 -1
  15. package/dist/asoBidAdapter.js +1 -1
  16. package/dist/axonixBidAdapter.js +1 -1
  17. package/dist/bidglassBidAdapter.js +1 -1
  18. package/dist/big-richmediaBidAdapter.js +1 -1
  19. package/dist/bridgewellBidAdapter.js +1 -1
  20. package/dist/brightMountainMediaBidAdapter.js +1 -1
  21. package/dist/carodaBidAdapter.js +1 -1
  22. package/dist/chtnwBidAdapter.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/conversantAnalyticsAdapter.js +1 -1
  27. package/dist/conversantBidAdapter.js +1 -1
  28. package/dist/craftBidAdapter.js +1 -1
  29. package/dist/criteoBidAdapter.js +1 -1
  30. package/dist/criteoIdSystem.js +1 -1
  31. package/dist/cwireBidAdapter.js +1 -1
  32. package/dist/dspxBidAdapter.js +1 -1
  33. package/dist/emtvBidAdapter.js +1 -0
  34. package/dist/eplanningBidAdapter.js +1 -1
  35. package/dist/feedadBidAdapter.js +1 -1
  36. package/dist/finativeBidAdapter.js +1 -1
  37. package/dist/freewheel-sspBidAdapter.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/greenbidsAnalyticsAdapter.js +1 -1
  42. package/dist/gridBidAdapter.js +1 -1
  43. package/dist/gumgumBidAdapter.js +1 -1
  44. package/dist/h12mediaBidAdapter.js +1 -1
  45. package/dist/id5IdSystem.js +1 -1
  46. package/dist/improvedigitalBidAdapter.js +1 -1
  47. package/dist/inmarBidAdapter.js +1 -1
  48. package/dist/insticatorBidAdapter.js +1 -1
  49. package/dist/ixBidAdapter.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/kueezBidAdapter.js +1 -1
  54. package/dist/kueezRtbBidAdapter.js +1 -1
  55. package/dist/kulturemediaBidAdapter.js +1 -1
  56. package/dist/lassoBidAdapter.js +1 -1
  57. package/dist/lifestreetBidAdapter.js +1 -1
  58. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  59. package/dist/logicadBidAdapter.js +1 -1
  60. package/dist/loglyliftBidAdapter.js +1 -1
  61. package/dist/magniteAnalyticsAdapter.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/minutemediaplusBidAdapter.js +1 -1
  69. package/dist/missenaBidAdapter.js +1 -1
  70. package/dist/nextMillenniumBidAdapter.js +1 -1
  71. package/dist/nexx360BidAdapter.js +1 -1
  72. package/dist/not-for-prod/prebid.js +128 -127
  73. package/dist/oguryBidAdapter.js +1 -1
  74. package/dist/onetagBidAdapter.js +1 -1
  75. package/dist/ooloAnalyticsAdapter.js +1 -1
  76. package/dist/optidigitalBidAdapter.js +1 -1
  77. package/dist/outbrainBidAdapter.js +1 -1
  78. package/dist/parrableIdSystem.js +1 -1
  79. package/dist/pixfutureBidAdapter.js +1 -1
  80. package/dist/prebid-core.js +1 -1
  81. package/dist/publinkIdSystem.js +1 -1
  82. package/dist/pubmaticBidAdapter.js +1 -1
  83. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  84. package/dist/pxyzBidAdapter.js +1 -1
  85. package/dist/quantcastBidAdapter.js +1 -1
  86. package/dist/readpeakBidAdapter.js +1 -1
  87. package/dist/relaidoBidAdapter.js +1 -1
  88. package/dist/rhythmoneBidAdapter.js +1 -1
  89. package/dist/riseBidAdapter.js +1 -1
  90. package/dist/rtbhouseBidAdapter.js +1 -1
  91. package/dist/rubiconAnalyticsAdapter.js +1 -1
  92. package/dist/rubiconBidAdapter.js +1 -1
  93. package/dist/seedingAllianceBidAdapter.js +1 -1
  94. package/dist/seedtagBidAdapter.js +1 -1
  95. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  96. package/dist/sharethroughBidAdapter.js +1 -1
  97. package/dist/shinezBidAdapter.js +1 -1
  98. package/dist/smaatoBidAdapter.js +1 -1
  99. package/dist/smartadserverBidAdapter.js +1 -1
  100. package/dist/smartxBidAdapter.js +1 -1
  101. package/dist/smilewantedBidAdapter.js +1 -1
  102. package/dist/sonobiBidAdapter.js +1 -1
  103. package/dist/sovrnAnalyticsAdapter.js +1 -1
  104. package/dist/sovrnBidAdapter.js +1 -1
  105. package/dist/sspBCBidAdapter.js +1 -1
  106. package/dist/stvBidAdapter.js +1 -1
  107. package/dist/sublimeBidAdapter.js +1 -1
  108. package/dist/synacormediaBidAdapter.js +1 -1
  109. package/dist/targetVideoBidAdapter.js +1 -1
  110. package/dist/teadsBidAdapter.js +1 -1
  111. package/dist/trionBidAdapter.js +1 -1
  112. package/dist/tripleliftBidAdapter.js +1 -1
  113. package/dist/ttdBidAdapter.js +1 -1
  114. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  115. package/dist/uid2IdSystem.js +1 -1
  116. package/dist/underdogmediaBidAdapter.js +1 -1
  117. package/dist/undertoneBidAdapter.js +1 -1
  118. package/dist/vidazooBidAdapter.js +1 -1
  119. package/dist/videobyteBidAdapter.js +1 -1
  120. package/dist/vidoomyBidAdapter.js +1 -1
  121. package/dist/visxBidAdapter.js +1 -1
  122. package/dist/vuukleBidAdapter.js +1 -1
  123. package/dist/widespaceBidAdapter.js +1 -1
  124. package/dist/winrBidAdapter.js +1 -1
  125. package/dist/yahoosspBidAdapter.js +1 -1
  126. package/dist/yieldmoBidAdapter.js +1 -1
  127. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  128. package/modules/criteoIdSystem.js +27 -14
  129. package/modules/emtvBidAdapter.js +211 -0
  130. package/modules/emtvBidAdapter.md +79 -0
  131. package/modules/missenaBidAdapter.js +1 -1
  132. package/modules/nextMillenniumBidAdapter.js +2 -0
  133. package/modules/rtbhouseBidAdapter.js +3 -3
  134. package/modules/vidoomyBidAdapter.js +19 -6
  135. package/modules/vidoomyBidAdapter.md +12 -2
  136. package/modules/yieldmoBidAdapter.js +2 -2
  137. package/package.json +1 -1
  138. package/test/spec/modules/criteoIdSystem_spec.js +99 -9
  139. package/test/spec/modules/emtvBidAdapter_spec.js +400 -0
  140. package/test/spec/modules/rtbhouseBidAdapter_spec.js +2 -2
  141. package/test/spec/modules/vidoomyBidAdapter_spec.js +49 -0
  142. package/test/spec/modules/yieldmoBidAdapter_spec.js +2 -2
@@ -27,7 +27,12 @@ var adUnits = [
27
27
  params: {
28
28
  id: '123123',
29
29
  pid: '123123',
30
- bidfloor: 0.5 // This is optional
30
+ bidfloor: 0.5, // This is optional
31
+ bcat: ['IAB1-1'], // Optional - default is []
32
+ badv: ['example.com'], // Optional - default is []
33
+ bapp: ['app.com'], // Optional - default is []
34
+ btype: [1, 2, 3], // Optional - default is []
35
+ battr: [1, 2, 3] // Optional - default is []
31
36
  }
32
37
  }
33
38
  ]
@@ -52,7 +57,12 @@ var adUnits = [
52
57
  params: {
53
58
  id: '123123',
54
59
  pid: '123123',
55
- bidfloor: 0.5 // This is optional
60
+ bidfloor: 0.5, // This is optional
61
+ bcat: ['IAB1-1'], // Optional - default is []
62
+ badv: ['example.com'], // Optional - default is []
63
+ bapp: ['app.com'], // Optional - default is []
64
+ btype: [1, 2, 3], // Optional - default is []
65
+ battr: [1, 2, 3] // Optional - default is []
56
66
  }
57
67
  }
58
68
  ]
@@ -83,7 +83,7 @@ export const spec = {
83
83
  gdprApplies: deepAccess(bidderRequest, 'gdprConsent.gdprApplies') || '',
84
84
  cmp: deepAccess(bidderRequest, 'gdprConsent.consentString') || '',
85
85
  gpp: deepAccess(bidderRequest, 'gppConsent.gppString') || '',
86
- gpp_sid: deepAccess(bidderRequest, 'gppConsent.applicableSections') || ''
86
+ gpp_sid: deepAccess(bidderRequest, 'gppConsent.applicableSections') || []
87
87
  }),
88
88
  us_privacy: deepAccess(bidderRequest, 'uspConsent') || ''
89
89
  };
@@ -525,7 +525,7 @@ function populateOpenRtbGdpr(openRtbRequest, bidderRequest) {
525
525
  deepSetValue(openRtbRequest, 'regs.ext.gdpr', gdpr && gdpr.gdprApplies ? 1 : 0);
526
526
  deepSetValue(openRtbRequest, 'user.ext.consent', gdpr && gdpr.consentString ? gdpr.consentString : '');
527
527
  }
528
- if (gppsid) {
528
+ if (gppsid && gppsid.length > 0) {
529
529
  deepSetValue(openRtbRequest, 'regs.ext.gpp_sid', gppsid);
530
530
  }
531
531
  const uspConsent = deepAccess(bidderRequest, 'uspConsent');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prebid.js",
3
- "version": "7.46.0",
3
+ "version": "7.47.0",
4
4
  "description": "Header Bidding Management Library",
5
5
  "main": "src/prebid.js",
6
6
  "scripts": {
@@ -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
+ });
@@ -631,10 +631,10 @@ describe('RTBHouseAdapter', () => {
631
631
  expect(bids[0].meta.advertiserDomains).to.deep.equal(['rtbhouse.com']);
632
632
  expect(bids[0].native).to.deep.equal({
633
633
  title: 'Title text',
634
- clickUrl: encodeURIComponent('https://example.com'),
634
+ clickUrl: encodeURI('https://example.com'),
635
635
  impressionTrackers: ['https://example.com/imptracker'],
636
636
  image: {
637
- url: encodeURIComponent('https://example.com/image.jpg'),
637
+ url: encodeURI('https://example.com/image.jpg'),
638
638
  width: 150,
639
639
  height: 50
640
640
  },
@@ -219,6 +219,55 @@ describe('vidoomyBidAdapter', function() {
219
219
  expect(bidRequest.data.bidfloor).to.equal(bidfloor);
220
220
  });
221
221
  });
222
+
223
+ describe('badv, bcat, bapp, btype, battr', function () {
224
+ const bidderRequestNew = {
225
+ ...bidderRequest,
226
+ bcat: ['EX1', 'EX2', 'EX3'],
227
+ badv: ['site.com'],
228
+ bapp: ['app.com'],
229
+ btype: [1, 2, 3],
230
+ battr: [1, 2, 3]
231
+ }
232
+ const request = spec.buildRequests(bidRequests, bidderRequestNew);
233
+ it('should have badv, bcat, bapp, btype, battr in request', function () {
234
+ expect(request[0].data).to.include.any.keys('badv');
235
+ expect(request[0].data).to.include.any.keys('bcat');
236
+ expect(request[0].data).to.include.any.keys('bapp');
237
+ expect(request[0].data).to.include.any.keys('btype');
238
+ expect(request[0].data).to.include.any.keys('battr');
239
+ })
240
+
241
+ it('should have equal badv, bcat, bapp, btype, battr in request', function () {
242
+ expect(request[0].badv).to.deep.equal(bidderRequest.refererInfo.badv);
243
+ expect(request[0].bcat).to.deep.equal(bidderRequest.refererInfo.bcat);
244
+ expect(request[0].bapp).to.deep.equal(bidderRequest.refererInfo.bapp);
245
+ expect(request[0].btype).to.deep.equal(bidderRequest.refererInfo.btype);
246
+ expect(request[0].battr).to.deep.equal(bidderRequest.refererInfo.battr);
247
+ })
248
+ })
249
+
250
+ describe('first party data', function () {
251
+ const bidderRequest2 = {
252
+ ...bidderRequest,
253
+ ortb2: {
254
+ bcat: ['EX1', 'EX2', 'EX3'],
255
+ badv: ['site.com'],
256
+ bapp: ['app.com'],
257
+ btype: [1, 2, 3],
258
+ battr: [1, 2, 3]
259
+ }
260
+ }
261
+ const request = spec.buildRequests(bidRequests, bidderRequest2);
262
+
263
+ it('should have badv, bcat, bapp, btype, battr in request and equal to bidderRequest.ortb2', function () {
264
+ expect(request[0].data.bcat).to.deep.equal(bidderRequest2.ortb2.bcat)
265
+ expect(request[0].data.badv).to.deep.equal(bidderRequest2.ortb2.badv)
266
+ expect(request[0].data.bapp).to.deep.equal(bidderRequest2.ortb2.bapp);
267
+ expect(request[0].data.btype).to.deep.equal(bidderRequest2.ortb2.btype);
268
+ expect(request[0].data.battr).to.deep.equal(bidderRequest2.ortb2.battr);
269
+ });
270
+ });
222
271
  });
223
272
 
224
273
  describe('interpretResponse', function () {