prebid.js 8.2.0 → 8.4.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 (227) 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/admanBidAdapter.js +1 -1
  7. package/dist/adqueryBidAdapter.js +1 -1
  8. package/dist/adrelevantisBidAdapter.js +1 -1
  9. package/dist/adtelligentBidAdapter.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/beopBidAdapter.js +1 -1
  21. package/dist/bidglassBidAdapter.js +1 -1
  22. package/dist/big-richmediaBidAdapter.js +1 -1
  23. package/dist/brandmetricsRtdProvider.js +1 -1
  24. package/dist/bridBidAdapter.js +1 -1
  25. package/dist/bridgewellBidAdapter.js +1 -1
  26. package/dist/brightMountainMediaBidAdapter.js +1 -1
  27. package/dist/carodaBidAdapter.js +1 -1
  28. package/dist/chtnwBidAdapter.js +1 -1
  29. package/dist/concertBidAdapter.js +1 -1
  30. package/dist/connectadBidAdapter.js +1 -1
  31. package/dist/consumableBidAdapter.js +1 -1
  32. package/dist/conversantAnalyticsAdapter.js +1 -1
  33. package/dist/conversantBidAdapter.js +1 -1
  34. package/dist/craftBidAdapter.js +1 -1
  35. package/dist/criteoBidAdapter.js +1 -1
  36. package/dist/cwireBidAdapter.js +1 -1
  37. package/dist/dependencies.json +6 -0
  38. package/dist/discoveryBidAdapter.js +1 -1
  39. package/dist/dspxBidAdapter.js +1 -1
  40. package/dist/eplanningBidAdapter.js +1 -1
  41. package/dist/euidIdSystem.js +1 -1
  42. package/dist/feedadBidAdapter.js +1 -1
  43. package/dist/finativeBidAdapter.js +1 -1
  44. package/dist/freewheel-sspBidAdapter.js +1 -1
  45. package/dist/gdprEnforcement.js +1 -1
  46. package/dist/gmosspBidAdapter.js +1 -1
  47. package/dist/goldbachBidAdapter.js +1 -1
  48. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  49. package/dist/greenbidsRtdProvider.js +1 -1
  50. package/dist/gridBidAdapter.js +1 -1
  51. package/dist/gumgumBidAdapter.js +1 -1
  52. package/dist/h12mediaBidAdapter.js +1 -1
  53. package/dist/holidBidAdapter.js +1 -1
  54. package/dist/hypelabBidAdapter.js +1 -1
  55. package/dist/id5IdSystem.js +1 -1
  56. package/dist/imdsBidAdapter.js +1 -1
  57. package/dist/improvedigitalBidAdapter.js +1 -1
  58. package/dist/insticatorBidAdapter.js +1 -1
  59. package/dist/ixBidAdapter.js +1 -1
  60. package/dist/justpremiumBidAdapter.js +1 -1
  61. package/dist/kargoBidAdapter.js +1 -1
  62. package/dist/konduitAnalyticsAdapter.js +1 -1
  63. package/dist/kueezBidAdapter.js +1 -1
  64. package/dist/kueezRtbBidAdapter.js +1 -1
  65. package/dist/kulturemediaBidAdapter.js +1 -1
  66. package/dist/lassoBidAdapter.js +1 -1
  67. package/dist/lifestreetBidAdapter.js +1 -1
  68. package/dist/livewrappedAnalyticsAdapter.js +1 -1
  69. package/dist/logicadBidAdapter.js +1 -1
  70. package/dist/loglyliftBidAdapter.js +1 -1
  71. package/dist/magniteAnalyticsAdapter.js +1 -1
  72. package/dist/malltvAnalyticsAdapter.js +1 -1
  73. package/dist/marsmediaBidAdapter.js +1 -1
  74. package/dist/mediafuseBidAdapter.js +1 -1
  75. package/dist/mediagoBidAdapter.js +1 -1
  76. package/dist/mediasquareBidAdapter.js +1 -1
  77. package/dist/mgidBidAdapter.js +1 -1
  78. package/dist/minutemediaBidAdapter.js +1 -1
  79. package/dist/minutemediaplusBidAdapter.js +1 -1
  80. package/dist/nexx360BidAdapter.js +1 -1
  81. package/dist/not-for-prod/prebid.js +143 -143
  82. package/dist/oguryBidAdapter.js +1 -1
  83. package/dist/onetagBidAdapter.js +1 -1
  84. package/dist/ooloAnalyticsAdapter.js +1 -1
  85. package/dist/optidigitalBidAdapter.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 +2 -2
  90. package/dist/publinkIdSystem.js +1 -1
  91. package/dist/pubmaticBidAdapter.js +1 -1
  92. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  93. package/dist/pulsepointBidAdapter.js +1 -1
  94. package/dist/pxyzBidAdapter.js +1 -1
  95. package/dist/quantcastBidAdapter.js +1 -1
  96. package/dist/readpeakBidAdapter.js +1 -1
  97. package/dist/relaidoBidAdapter.js +1 -1
  98. package/dist/retailspotBidAdapter.js +1 -1
  99. package/dist/rhythmoneBidAdapter.js +1 -1
  100. package/dist/riseBidAdapter.js +1 -1
  101. package/dist/rubiconBidAdapter.js +1 -1
  102. package/dist/seedingAllianceBidAdapter.js +1 -1
  103. package/dist/seedtagBidAdapter.js +1 -1
  104. package/dist/sharedIdSystem.js +1 -1
  105. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  106. package/dist/sharethroughBidAdapter.js +1 -1
  107. package/dist/shinezBidAdapter.js +1 -1
  108. package/dist/smaatoBidAdapter.js +1 -1
  109. package/dist/smartadserverBidAdapter.js +1 -1
  110. package/dist/smartxBidAdapter.js +1 -1
  111. package/dist/smartyadsBidAdapter.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/stroeerCoreBidAdapter.js +1 -1
  118. package/dist/stvBidAdapter.js +1 -1
  119. package/dist/sublimeBidAdapter.js +1 -1
  120. package/dist/targetVideoBidAdapter.js +1 -1
  121. package/dist/teadsBidAdapter.js +1 -1
  122. package/dist/topicsFpdModule.js +1 -1
  123. package/dist/trafficgateBidAdapter.js +1 -1
  124. package/dist/trionBidAdapter.js +1 -1
  125. package/dist/tripleliftBidAdapter.js +1 -1
  126. package/dist/ttdBidAdapter.js +1 -1
  127. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  128. package/dist/uid2IdSystem.js +1 -1
  129. package/dist/underdogmediaBidAdapter.js +1 -1
  130. package/dist/undertoneBidAdapter.js +1 -1
  131. package/dist/userId.js +1 -1
  132. package/dist/vidazooBidAdapter.js +1 -1
  133. package/dist/videobyteBidAdapter.js +1 -1
  134. package/dist/visxBidAdapter.js +1 -1
  135. package/dist/voxBidAdapter.js +1 -1
  136. package/dist/vuukleBidAdapter.js +1 -1
  137. package/dist/widespaceBidAdapter.js +1 -1
  138. package/dist/winrBidAdapter.js +1 -1
  139. package/dist/yahoosspBidAdapter.js +1 -1
  140. package/dist/yandexBidAdapter.js +1 -1
  141. package/dist/yieldmoBidAdapter.js +1 -1
  142. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  143. package/integrationExamples/videoModule/jwplayer/bidMarkedAsUsed.html +1 -1
  144. package/integrationExamples/videoModule/jwplayer/eventListeners.html +2 -2
  145. package/integrationExamples/videoModule/jwplayer/eventsUI.html +1 -1
  146. package/integrationExamples/videoModule/jwplayer/gamAdServerMediation.html +1 -1
  147. package/integrationExamples/videoModule/jwplayer/mediaMetadata.html +1 -1
  148. package/integrationExamples/videoModule/jwplayer/playlist.html +1 -1
  149. package/integrationExamples/videoModule/videojs/bidMarkedAsUsed.html +1 -1
  150. package/integrationExamples/videoModule/videojs/bidRequestScheduling.html +1 -1
  151. package/integrationExamples/videoModule/videojs/eventListeners.html +1 -1
  152. package/integrationExamples/videoModule/videojs/eventsUI.html +1 -1
  153. package/integrationExamples/videoModule/videojs/gamAdServerMediation.html +1 -1
  154. package/integrationExamples/videoModule/videojs/mediaMetadata.html +1 -1
  155. package/integrationExamples/videoModule/videojs/playlist.html +1 -1
  156. package/modules/33acrossBidAdapter.js +24 -14
  157. package/modules/33acrossIdSystem.js +15 -4
  158. package/modules/adagioBidAdapter.js +2 -2
  159. package/modules/admanBidAdapter.js +4 -0
  160. package/modules/adtelligentBidAdapter.js +8 -0
  161. package/modules/beopBidAdapter.js +6 -6
  162. package/modules/beopBidAdapter.md +35 -1
  163. package/modules/brandmetricsRtdProvider.js +36 -2
  164. package/modules/brandmetricsRtdProvider.md +17 -2
  165. package/modules/cadentApertureMXBidAdapter.md +2 -2
  166. package/modules/discoveryBidAdapter.js +1 -1
  167. package/modules/gdprEnforcement.js +27 -22
  168. package/modules/gridBidAdapter.js +19 -0
  169. package/modules/holidBidAdapter.js +49 -30
  170. package/modules/ixBidAdapter.js +41 -2
  171. package/modules/kargoBidAdapter.js +4 -0
  172. package/modules/livewrappedAnalyticsAdapter.js +33 -33
  173. package/modules/mediagoBidAdapter.js +1 -0
  174. package/modules/minutemediaBidAdapter.js +17 -2
  175. package/modules/oguryBidAdapter.js +29 -16
  176. package/modules/pubmaticBidAdapter.js +16 -1
  177. package/modules/pulsepointBidAdapter.js +63 -424
  178. package/modules/pulsepointBidAdapter.md +39 -45
  179. package/modules/sharedIdSystem.js +1 -1
  180. package/modules/smartyadsBidAdapter.js +6 -3
  181. package/modules/sovrnBidAdapter.js +10 -1
  182. package/modules/stroeerCoreBidAdapter.js +2 -3
  183. package/modules/teadsBidAdapter.js +2 -0
  184. package/modules/topicsFpdModule.js +4 -1
  185. package/modules/topicsFpdModule.md +4 -0
  186. package/modules/trafficgateBidAdapter.js +126 -72
  187. package/modules/userId/index.js +2 -2
  188. package/modules/vidazooBidAdapter.js +69 -19
  189. package/modules/voxBidAdapter.js +16 -5
  190. package/modules/yahoosspBidAdapter.js +38 -33
  191. package/modules/yahoosspBidAdapter.md +96 -95
  192. package/modules/yandexBidAdapter.js +12 -15
  193. package/package.json +1 -1
  194. package/src/activities/redactor.js +1 -1
  195. package/src/auction.js +24 -2
  196. package/src/constants.json +3 -1
  197. package/src/fpd/sua.js +8 -2
  198. package/test/spec/auctionmanager_spec.js +29 -1
  199. package/test/spec/fpd/enrichment_spec.js +7 -1
  200. package/test/spec/fpd/sua_spec.js +12 -0
  201. package/test/spec/modules/33acrossBidAdapter_spec.js +188 -35
  202. package/test/spec/modules/33acrossIdSystem_spec.js +122 -27
  203. package/test/spec/modules/adagioBidAdapter_spec.js +2 -2
  204. package/test/spec/modules/adtelligentBidAdapter_spec.js +8 -0
  205. package/test/spec/modules/beopBidAdapter_spec.js +18 -2
  206. package/test/spec/modules/brandmetricsRtdProvider_spec.js +69 -7
  207. package/test/spec/modules/cadentApertureMXBidAdapter_spec.js +1 -1
  208. package/test/spec/modules/gdprEnforcement_spec.js +43 -2
  209. package/test/spec/modules/gridBidAdapter_spec.js +42 -0
  210. package/test/spec/modules/holidBidAdapter_spec.js +26 -6
  211. package/test/spec/modules/ixBidAdapter_spec.js +84 -6
  212. package/test/spec/modules/kargoBidAdapter_spec.js +121 -106
  213. package/test/spec/modules/minutemediaBidAdapter_spec.js +36 -5
  214. package/test/spec/modules/oguryBidAdapter_spec.js +208 -108
  215. package/test/spec/modules/pubmaticBidAdapter_spec.js +119 -0
  216. package/test/spec/modules/pulsepointBidAdapter_spec.js +225 -486
  217. package/test/spec/modules/smartyadsBidAdapter_spec.js +1 -1
  218. package/test/spec/modules/sovrnBidAdapter_spec.js +58 -4
  219. package/test/spec/modules/stroeerCoreBidAdapter_spec.js +8 -5
  220. package/test/spec/modules/teadsBidAdapter_spec.js +70 -21
  221. package/test/spec/modules/topicsFpdModule_spec.js +10 -4
  222. package/test/spec/modules/trafficgateBidAdapter_spec.js +1349 -199
  223. package/test/spec/modules/vidazooBidAdapter_spec.js +130 -4
  224. package/test/spec/modules/voxBidAdapter_spec.js +93 -0
  225. package/test/spec/modules/yahoosspBidAdapter_spec.js +402 -314
  226. package/test/spec/modules/yandexBidAdapter_spec.js +21 -3
  227. package/integrationExamples/gpt/inskin_example.html +0 -100
@@ -2,7 +2,7 @@ import { thirthyThreeAcrossIdSubmodule } from 'modules/33acrossIdSystem.js';
2
2
  import * as utils from 'src/utils.js';
3
3
 
4
4
  import { server } from 'test/mocks/xhr.js';
5
- import { uspDataHandler } from 'src/adapterManager.js';
5
+ import { uspDataHandler, coppaDataHandler, gppDataHandler } from 'src/adapterManager.js';
6
6
 
7
7
  describe('33acrossIdSystem', () => {
8
8
  describe('name', () => {
@@ -67,41 +67,35 @@ describe('33acrossIdSystem', () => {
67
67
 
68
68
  expect(request.url).to.contain('gdpr=1');
69
69
  });
70
+ });
70
71
 
71
- context('and the consent string is given', () => {
72
- it('should call endpoint with the GDPR consent string', () => {
73
- [
74
- { consentString: '', expected: '' },
75
- { consentString: undefined, expected: '' },
76
- { consentString: 'foo', expected: 'foo' }
77
- ].forEach(({ consentString, expected }, index) => {
78
- const completeCallback = () => {};
79
- const { callback } = thirthyThreeAcrossIdSubmodule.getId({
80
- params: {
81
- pid: '12345'
82
- }
83
- }, {
84
- gdprApplies: true,
85
- consentString
86
- });
87
-
88
- callback(completeCallback);
89
-
90
- expect(server.requests[index].url).to.contain(`gdpr_consent=${expected}`);
91
- });
72
+ context('when GDPR doesn\'t apply', () => {
73
+ it('should call endpoint with \'gdpr=0\'', () => {
74
+ const completeCallback = () => {};
75
+ const { callback } = thirthyThreeAcrossIdSubmodule.getId({
76
+ params: {
77
+ pid: '12345'
78
+ }
79
+ }, {
80
+ gdprApplies: false
92
81
  });
82
+
83
+ callback(completeCallback);
84
+
85
+ const [request] = server.requests;
86
+
87
+ expect(request.url).to.contain('gdpr=0');
93
88
  });
94
89
  });
95
90
 
96
- context('when GDPR doesn\'t apply', () => {
97
- it('should call endpoint with \'gdpr=0\' and no GDPR consent string parameter', () => {
91
+ context('when the GDPR consent string is given', () => {
92
+ it('should call endpoint with the GDPR consent string', () => {
98
93
  const completeCallback = () => {};
99
94
  const { callback } = thirthyThreeAcrossIdSubmodule.getId({
100
95
  params: {
101
96
  pid: '12345'
102
97
  }
103
98
  }, {
104
- gdprApplies: false,
105
99
  consentString: 'foo'
106
100
  });
107
101
 
@@ -109,8 +103,7 @@ describe('33acrossIdSystem', () => {
109
103
 
110
104
  const [request] = server.requests;
111
105
 
112
- expect(request.url).to.contain('gdpr=0');
113
- expect(request.url).not.to.contain('gdpr_consent');
106
+ expect(request.url).to.contain('gdpr_consent=foo');
114
107
  });
115
108
  });
116
109
 
@@ -157,6 +150,108 @@ describe('33acrossIdSystem', () => {
157
150
  });
158
151
  });
159
152
 
153
+ context('when coppa is enabled', () => {
154
+ it('should call endpoint with an enabled coppa signal', () => {
155
+ const completeCallback = () => {};
156
+ const { callback } = thirthyThreeAcrossIdSubmodule.getId({
157
+ params: {
158
+ pid: '12345'
159
+ }
160
+ });
161
+
162
+ sinon.stub(coppaDataHandler, 'getCoppa').returns(true);
163
+
164
+ callback(completeCallback);
165
+
166
+ const [request] = server.requests;
167
+
168
+ expect(request.url).to.contain('coppa=1');
169
+
170
+ coppaDataHandler.getCoppa.restore();
171
+ });
172
+ });
173
+
174
+ context('when coppa is not enabled', () => {
175
+ it('should call endpoint with coppa signal not enabled', () => {
176
+ const completeCallback = () => {};
177
+ const { callback } = thirthyThreeAcrossIdSubmodule.getId({
178
+ params: {
179
+ pid: '12345'
180
+ }
181
+ });
182
+
183
+ sinon.stub(coppaDataHandler, 'getCoppa').returns(false);
184
+
185
+ callback(completeCallback);
186
+
187
+ const [request] = server.requests;
188
+
189
+ expect(request.url).to.contain('coppa=0');
190
+
191
+ coppaDataHandler.getCoppa.restore();
192
+ });
193
+ });
194
+
195
+ context('when a GPP consent string is given', () => {
196
+ beforeEach(() => {
197
+ sinon.stub(gppDataHandler, 'getConsentData');
198
+ });
199
+
200
+ afterEach(() => {
201
+ gppDataHandler.getConsentData.restore();
202
+ });
203
+
204
+ it('should call endpoint with the GPP consent string', () => {
205
+ [
206
+ { gppString: '', expected: '' },
207
+ { gppString: undefined, expected: '' },
208
+ { gppString: 'foo', expected: 'foo' },
209
+ ].forEach(({ gppString, expected }, index) => {
210
+ const completeCallback = () => {};
211
+ const { callback } = thirthyThreeAcrossIdSubmodule.getId({
212
+ params: {
213
+ pid: '12345'
214
+ }
215
+ });
216
+
217
+ gppDataHandler.getConsentData.onCall(index).returns({
218
+ gppString
219
+ });
220
+
221
+ callback(completeCallback);
222
+
223
+ expect(server.requests[index].url).to.contain(`gpp=${expected}`);
224
+ });
225
+ });
226
+
227
+ it('should call endpoint with the GPP applicable sections', () => {
228
+ const gppString = 'foo';
229
+
230
+ [
231
+ { applicableSections: [], expected: '' },
232
+ { applicableSections: undefined, expected: '' },
233
+ { applicableSections: ['1'], expected: '1' },
234
+ { applicableSections: ['1', '2'], expected: '1%2C2' },
235
+ ].forEach(({ applicableSections, expected }, index) => {
236
+ const completeCallback = () => {};
237
+ const { callback } = thirthyThreeAcrossIdSubmodule.getId({
238
+ params: {
239
+ pid: '12345'
240
+ }
241
+ });
242
+
243
+ gppDataHandler.getConsentData.onCall(index).returns({
244
+ gppString: 'foo',
245
+ applicableSections
246
+ });
247
+
248
+ callback(completeCallback);
249
+
250
+ expect(server.requests[index].url).to.contain(`gpp_sid=${expected}`);
251
+ });
252
+ });
253
+ });
254
+
160
255
  context('when the partner ID is not given', () => {
161
256
  it('should log an error', () => {
162
257
  const logErrorSpy = sinon.spy(utils, 'logError');
@@ -256,7 +256,6 @@ describe('Adagio bid adapter', () => {
256
256
 
257
257
  describe('buildRequests()', function() {
258
258
  const expectedDataKeys = [
259
- 'id',
260
259
  'organizationId',
261
260
  'secure',
262
261
  'device',
@@ -269,7 +268,8 @@ describe('Adagio bid adapter', () => {
269
268
  'prebidVersion',
270
269
  'featuresVersion',
271
270
  'data',
272
- 'usIfr'
271
+ 'usIfr',
272
+ 'adgjs',
273
273
  ];
274
274
 
275
275
  it('groups requests by organizationId', function() {
@@ -156,6 +156,10 @@ const displayBidderRequestWithConsents = {
156
156
  gdprApplies: true,
157
157
  consentString: 'test'
158
158
  },
159
+ gppConsent: {
160
+ gppString: 'abc12345234',
161
+ applicableSections: [7, 8]
162
+ },
159
163
  uspConsent: 'iHaveIt'
160
164
  };
161
165
 
@@ -364,6 +368,10 @@ describe('adtelligentBidAdapter', () => {
364
368
  expect(bidRequestWithPubSettingsData.GDPR).to.be.equal(1);
365
369
  expect(bidRequestWithPubSettingsData.GDPRConsent).to.be.equal(displayBidderRequestWithConsents.gdprConsent.consentString);
366
370
  });
371
+ it('sets GPP flags', () => {
372
+ expect(bidRequestWithPubSettingsData.GPP).to.be.equal(displayBidderRequestWithConsents.gppConsent.gppString);
373
+ expect(bidRequestWithPubSettingsData.GPPSid).to.be.equal('7,8');
374
+ });
367
375
  it('sets USP', () => {
368
376
  expect(bidRequestWithPubSettingsData.USP).to.be.equal(displayBidderRequestWithConsents.uspConsent);
369
377
  })
@@ -130,15 +130,15 @@ describe('BeOp Bid Adapter tests', () => {
130
130
  expect(payload.url).to.exist;
131
131
  // check that the protocol is added correctly
132
132
  expect(payload.url).to.equal('http://test.te');
133
- expect(payload.psegs).to.not.exist;
134
133
  });
135
134
 
136
- it('should call the endpoint with psegs data if any', function () {
135
+ it('should call the endpoint with psegs and bpsegs (stringified) data if any or [] if none', function () {
137
136
  let bidderRequest =
138
137
  {
139
138
  'ortb2': {
140
139
  'user': {
141
140
  'ext': {
141
+ 'bpsegs': ['axed', 'axec', 1234],
142
142
  'data': {
143
143
  'permutive': [1234, 5678, 910]
144
144
  }
@@ -154,6 +154,22 @@ describe('BeOp Bid Adapter tests', () => {
154
154
  expect(payload.psegs).to.include(5678);
155
155
  expect(payload.psegs).to.include(910);
156
156
  expect(payload.psegs).to.not.include(1);
157
+ expect(payload.bpsegs).to.exist;
158
+ expect(payload.bpsegs).to.include('axed');
159
+ expect(payload.bpsegs).to.include('axec');
160
+ expect(payload.bpsegs).to.include('1234');
161
+
162
+ let bidderRequest2 =
163
+ {
164
+ 'ortb2': {}
165
+ };
166
+
167
+ const request2 = spec.buildRequests(bidRequests, bidderRequest2);
168
+ const payload2 = JSON.parse(request2.data);
169
+ expect(payload2.psegs).to.exist;
170
+ expect(payload2.psegs).to.be.empty;
171
+ expect(payload2.bpsegs).to.exist;
172
+ expect(payload2.bpsegs).to.be.empty;
157
173
  });
158
174
 
159
175
  it('should not prepend the protocol in page url if already present', function () {
@@ -1,5 +1,7 @@
1
1
  import * as brandmetricsRTD from '../../../modules/brandmetricsRtdProvider.js';
2
2
  import {config} from 'src/config.js';
3
+ import * as events from '../../../src/events';
4
+ import * as sinon from 'sinon';
3
5
 
4
6
  const VALID_CONFIG = {
5
7
  name: 'brandmetrics',
@@ -77,14 +79,16 @@ function mockSurveyLoaded(surveyConf) {
77
79
  });
78
80
  }
79
81
 
80
- function scriptTagExists(url) {
81
- const tags = document.getElementsByTagName('script');
82
- for (let i = 0; i < tags.length; i++) {
83
- if (tags[i].src === url) {
84
- return true;
82
+ function mockCreativeInView(creativeInViewConf) {
83
+ const commands = window._brandmetrics || [];
84
+ commands.forEach(command => {
85
+ if (command.cmd === '_addeventlistener') {
86
+ const conf = command.val;
87
+ if (conf.event === 'creative_in_view') {
88
+ conf.handler(creativeInViewConf);
89
+ }
85
90
  }
86
- }
87
- return false;
91
+ })
88
92
  }
89
93
 
90
94
  describe('BrandmetricsRTD module', () => {
@@ -188,4 +192,62 @@ describe('getBidRequestData', () => {
188
192
  expect(bidderOrtb2[exp].user.ext.data.brandmetrics_survey).to.equal('mockMeasurementId')
189
193
  })
190
194
  });
195
+
196
+ describe('billable events', () => {
197
+ let sandbox;
198
+ let eventsEmitSpy;
199
+
200
+ before(() => {
201
+ sandbox = sinon.sandbox.create();
202
+ eventsEmitSpy = sandbox.spy(events, ['emit']);
203
+ });
204
+
205
+ beforeEach(() => {
206
+ eventsEmitSpy.resetHistory();
207
+ })
208
+
209
+ afterEach(() => {
210
+ sandbox.restore();
211
+ });
212
+
213
+ it('should emit billable event from prebid events', () => {
214
+ const expectedEvent = {
215
+ vendor: 'brandmetrics',
216
+ type: 'creative_in_view',
217
+ measurementId: 'mockMeasurementId',
218
+ auctionId: 'mockAuctionId',
219
+ transactionId: 'mockTransactionId'
220
+ };
221
+
222
+ mockCreativeInView({
223
+ mid: expectedEvent.measurementId,
224
+ source: {
225
+ type: 'pbj',
226
+ data: {
227
+ auctionId: expectedEvent.auctionId,
228
+ transactionId: expectedEvent.transactionId
229
+ },
230
+ }
231
+ });
232
+
233
+ expect(eventsEmitSpy.callCount).to.equal(1);
234
+
235
+ const event = eventsEmitSpy.getCalls()[0].args[1];
236
+ delete event['billingId'];
237
+
238
+ expect(event).to.deep.equal(expectedEvent);
239
+ });
240
+
241
+ it('should not emit billable event from non prebid- sources', () => {
242
+ mockCreativeInView({
243
+ mid: 'mockMeasurementId',
244
+ source: {
245
+ type: 'gpt',
246
+ data: {},
247
+ }
248
+ });
249
+
250
+ expect(eventsEmitSpy.callCount).to.equal(0);
251
+ });
252
+ });
191
253
  });
@@ -699,7 +699,7 @@ describe('cadent_aperture_mx Adapter', function () {
699
699
 
700
700
  it('should not throw an error when decoding an improperly encoded adm', function () {
701
701
  const badAdmServerResponse = utils.deepClone(serverResponse);
702
- badAdmServerResponse.seatbid[0].bid[0].adm = '<script\\ src\\=\\\"https\\:\\/\\/nym1\\-ib\\.adnxs\\.com\\/ab\\?an_audit\\=0\\&referrer=https%3A%2F%2Fwww.emxdigital.com%3Ftest%3DhAiE3%VVl%26prebid%3D%25123%25\\&e\\=wqT_3QLPCfBDzwQAAAMA1gAFAQj2iaPtBRCdw\\-qeto72gkEYlNWN2smGoJhTKjYJzGJi83G9KkARzGJi83G9KkAZAAAAgD0KEkAhzGIJGwApESTIMQAAAGBmZu4_MMvWgAc4zApAzApIAlDo\\-YEUWNbsR2AAaIrFCnjOpQWAAQGKAQNVU0SSBQbwQJgB2AWgAVqoAQGwAQC4AQLAAQTIAQLQAQnYAQDgAQDwAQCKAjp1ZignYScsIDI4OTEwMSwgMTU3MTM0MTU1OCk7ARwscicsIDQxOTc1MDE2Nh4A9DQBkgLhAiE3VVlCWndpQmpwOEpFT2o1Z1JRWUFDRFc3RWN3QURnQVFBUkl6QXBReTlhQUIxZ0FZTHdFYUFCd0NuZ0FnQUZFaUFFQWtBRUFtQUVBb0FFQnFBRURzQUVBdVFGS1I2cF9jYjBxUU1FQlNrZXFmM0c5S2tESkFaR1JfRy1UVnRNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFJQUNBSWdDcVlMWEJaQUNBWmdDQUtBQ0FLZ0NBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEZ1k2ZkNib0RDVTVaVFRJNk5ESTRNdUFEOHhQNEE0NnV2Z3lJQkFDUUJBQ1lCQUd5QkFvSXFZTFhCUkNPcnI0TXdRUUFBQUFBQUFBQUFNa0VBQUFBBXgMQURSQgkJLEF3Q0ZBMkFRQThRUQ0SYEFBQVBnRUFJZ0Z1aUUumgKJASE2eElrelE2ZQGgMXV4SElBUW9BREU5Q3RlamNMMHFRRG9KVGxsTk1qbzBNamd5UVBNVFMRWAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYw0MAaXwi2VBQS7YAqwD4AK30UbqAlxodHRwczovL3d3dy5jZWxlYnV6ei5jb20vZy90YXlsb3Itc3dpZnQtZGVidXRzLXJlZC1oYWlyLWluLXN1Z2FybGFuZC12aWRlby8_YmlkZHJfZGVidWc9dHJ1ZfICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPERY8TEVBRl9OQU1FEgDyAh4KGjYdAPQqAUFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMUoAMBqgMAwAOsAsgDANgDlCHgAwDoAwD4AwOABACSBAkvb3BlbnJ0YjKYBACiBA8xNDQuMTIxLjIzMy4yMzeoBIkWsgQMCAAQABgAIAAwADgAuAQAwAQAyASxgoIB0gQOMTM1NiNOWU0yOjQyODLaBAIIAeAEAPAE6PmBFPoEEgkAAAAAZqdHQBEAAAAgWpRewIgFAZgFAKAF____________AaoFFjQ5MTgxNTcxMzQxNTU2NTI2OTQ5ZTHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXW7gr6BQQIABAAkAYAmAYAuAYAwQYAAAAAAADwP8gGANAGwgTaBhYKEAAAAAAAAAAAAAAABQpQEAAYAOAGAfIGAggAgAcBiAcAoAcB\\&s\\=630dbbd55f593c7bfd9e7bccc4dbaa28203daaed\\&pp\\=\\$\\{EMX_MACRO\\}\\\"\\>\\<\\/script\\>';
702
+ badAdmServerResponse.seatbid[0].bid[0].adm = '<script\\ src\\=\\\"https\\:\\/\\/nym1\\-ib\\.adnxs\\.com\\/ab\\?an_audit\\=0\\&referrer=https%3A%2F%2Fwww.cadent.tv%3Ftest%3DhAiE3%VVl%26prebid%3D%25123%25\\&e\\=wqT_3QLPCfBDzwQAAAMA1gAFAQj2iaPtBRCdw\\-qeto72gkEYlNWN2smGoJhTKjYJzGJi83G9KkARzGJi83G9KkAZAAAAgD0KEkAhzGIJGwApESTIMQAAAGBmZu4_MMvWgAc4zApAzApIAlDo\\-YEUWNbsR2AAaIrFCnjOpQWAAQGKAQNVU0SSBQbwQJgB2AWgAVqoAQGwAQC4AQLAAQTIAQLQAQnYAQDgAQDwAQCKAjp1ZignYScsIDI4OTEwMSwgMTU3MTM0MTU1OCk7ARwscicsIDQxOTc1MDE2Nh4A9DQBkgLhAiE3VVlCWndpQmpwOEpFT2o1Z1JRWUFDRFc3RWN3QURnQVFBUkl6QXBReTlhQUIxZ0FZTHdFYUFCd0NuZ0FnQUZFaUFFQWtBRUFtQUVBb0FFQnFBRURzQUVBdVFGS1I2cF9jYjBxUU1FQlNrZXFmM0c5S2tESkFaR1JfRy1UVnRNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFJQUNBSWdDcVlMWEJaQUNBWmdDQUtBQ0FLZ0NBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEZ1k2ZkNib0RDVTVaVFRJNk5ESTRNdUFEOHhQNEE0NnV2Z3lJQkFDUUJBQ1lCQUd5QkFvSXFZTFhCUkNPcnI0TXdRUUFBQUFBQUFBQUFNa0VBQUFBBXgMQURSQgkJLEF3Q0ZBMkFRQThRUQ0SYEFBQVBnRUFJZ0Z1aUUumgKJASE2eElrelE2ZQGgMXV4SElBUW9BREU5Q3RlamNMMHFRRG9KVGxsTk1qbzBNamd5UVBNVFMRWAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYw0MAaXwi2VBQS7YAqwD4AK30UbqAlxodHRwczovL3d3dy5jZWxlYnV6ei5jb20vZy90YXlsb3Itc3dpZnQtZGVidXRzLXJlZC1oYWlyLWluLXN1Z2FybGFuZC12aWRlby8_YmlkZHJfZGVidWc9dHJ1ZfICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPERY8TEVBRl9OQU1FEgDyAh4KGjYdAPQqAUFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMUoAMBqgMAwAOsAsgDANgDlCHgAwDoAwD4AwOABACSBAkvb3BlbnJ0YjKYBACiBA8xNDQuMTIxLjIzMy4yMzeoBIkWsgQMCAAQABgAIAAwADgAuAQAwAQAyASxgoIB0gQOMTM1NiNOWU0yOjQyODLaBAIIAeAEAPAE6PmBFPoEEgkAAAAAZqdHQBEAAAAgWpRewIgFAZgFAKAF____________AaoFFjQ5MTgxNTcxMzQxNTU2NTI2OTQ5ZTHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXW7gr6BQQIABAAkAYAmAYAuAYAwQYAAAAAAADwP8gGANAGwgTaBhYKEAAAAAAAAAAAAAAABQpQEAAYAOAGAfIGAggAgAcBiAcAoAcB\\&s\\=630dbbd55f593c7bfd9e7bccc4dbaa28203daaed\\&pp\\=\\$\\{EMX_MACRO\\}\\\"\\>\\<\\/script\\>';
703
703
  badAdmServerResponse.seatbid[1].bid[0].adm = '%3F%%3Dcadent%3C3prebid';
704
704
 
705
705
  assert.doesNotThrow(() => spec.interpretResponse({
@@ -11,7 +11,7 @@ import {
11
11
  reportAnalyticsRule,
12
12
  setEnforcementConfig,
13
13
  STRICT_STORAGE_ENFORCEMENT,
14
- syncUserRule,
14
+ syncUserRule, ufpdRule,
15
15
  validateRules
16
16
  } from 'modules/gdprEnforcement.js';
17
17
  import {config} from 'src/config.js';
@@ -462,6 +462,46 @@ describe('gdpr enforcement', function () {
462
462
  });
463
463
  });
464
464
 
465
+ describe('transmitUfpdRule', () => {
466
+ it('should allow when purpose 3 consent is given', () => {
467
+ setEnforcementConfig({
468
+ gdpr: {
469
+ rules: [{
470
+ purpose: 'personalizedAds',
471
+ enforcePurpose: true,
472
+ enforceVendor: true,
473
+ }]
474
+ }
475
+ });
476
+ Object.assign(gvlids, {
477
+ mockBidder: 123
478
+ });
479
+ const consent = setupConsentData();
480
+ consent.vendorData.purpose.consents[4] = true;
481
+ consent.vendorData.vendor.consents[123] = true;
482
+ expectAllow(true, ufpdRule(activityParams(MODULE_TYPE_BIDDER, 'mockBidder')));
483
+ });
484
+
485
+ it('should return deny when purpose 4 consent is withheld', () => {
486
+ setEnforcementConfig({
487
+ gdpr: {
488
+ rules: [{
489
+ purpose: 'personalizedAds',
490
+ enforcePurpose: true,
491
+ enforceVendor: true,
492
+ }]
493
+ }
494
+ });
495
+ Object.assign(gvlids, {
496
+ mockBidder: 123
497
+ });
498
+ const consent = setupConsentData();
499
+ consent.vendorData.purpose.consents[4] = true;
500
+ consent.vendorData.vendor.consents[123] = false;
501
+ expectAllow(false, ufpdRule(activityParams(MODULE_TYPE_BIDDER, 'mockBidder')))
502
+ });
503
+ });
504
+
465
505
  describe('validateRules', function () {
466
506
  const createGdprRule = (purposeName = 'storage', enforcePurpose = true, enforceVendor = true, vendorExceptions = [], softVendorExceptions = []) => ({
467
507
  purpose: purposeName,
@@ -599,7 +639,8 @@ describe('gdpr enforcement', function () {
599
639
  Object.entries({
600
640
  'storage': 1,
601
641
  'basicAds': 2,
602
- 'measurement': 7
642
+ 'measurement': 7,
643
+ 'personalizedAds': 4,
603
644
  }).forEach(([purpose, purposeNo]) => {
604
645
  describe(`for purpose ${purpose}`, () => {
605
646
  const rule = createGdprRule(purpose);
@@ -2,6 +2,7 @@ import { expect } from 'chai';
2
2
  import { spec, resetUserSync, getSyncUrl, storage } from 'modules/gridBidAdapter.js';
3
3
  import { newBidder } from 'src/adapters/bidderFactory.js';
4
4
  import { config } from 'src/config.js';
5
+ import {ENDPOINT_DOMAIN, ENDPOINT_PROTOCOL} from '../../../modules/adpartnerBidAdapter';
5
6
 
6
7
  describe('TheMediaGrid Adapter', function () {
7
8
  const adapter = newBidder(spec);
@@ -1465,6 +1466,47 @@ describe('TheMediaGrid Adapter', function () {
1465
1466
  });
1466
1467
  });
1467
1468
 
1469
+ describe('onDataDeletionRequest', function() {
1470
+ let ajaxStub;
1471
+ beforeEach(function() {
1472
+ ajaxStub = sinon.stub(spec, 'ajaxCall');
1473
+ });
1474
+
1475
+ it('should send right request on onDataDeletionRequest call', function() {
1476
+ spec.onDataDeletionRequest([{
1477
+ bids: [
1478
+ {
1479
+ bidder: 'grid',
1480
+ params: {
1481
+ uid: 1
1482
+ }
1483
+ },
1484
+ {
1485
+ bidder: 'grid',
1486
+ params: {
1487
+ uid: 2
1488
+ }
1489
+ },
1490
+ {
1491
+ bidder: 'another',
1492
+ params: {
1493
+ uid: 3
1494
+ }
1495
+ },
1496
+ {
1497
+ bidder: 'gridNM',
1498
+ params: {
1499
+ uid: 4
1500
+ }
1501
+ }
1502
+ ],
1503
+ }]);
1504
+ expect(ajaxStub.calledOnce).to.equal(true);
1505
+ expect(ajaxStub.firstCall.args[0]).to.equal('https://media.grid.bidswitch.net/uspapi_delete');
1506
+ expect(ajaxStub.firstCall.args[2]).to.equal('{"uids":[1,2,4]}');
1507
+ });
1508
+ });
1509
+
1468
1510
  describe('user sync', function () {
1469
1511
  const syncUrl = getSyncUrl();
1470
1512
 
@@ -2,11 +2,14 @@ import { expect } from 'chai'
2
2
  import { spec } from 'modules/holidBidAdapter.js'
3
3
 
4
4
  describe('holidBidAdapterTests', () => {
5
+ const bidderRequest = {
6
+ bidderRequestId: 'test-id'
7
+ }
8
+
5
9
  const bidRequestData = {
6
10
  bidder: 'holid',
7
11
  adUnitCode: 'test-div',
8
12
  bidId: 'bid-id',
9
- auctionId: 'test-id',
10
13
  params: { adUnitID: '12345' },
11
14
  mediaTypes: { banner: {} },
12
15
  sizes: [[300, 250]],
@@ -48,18 +51,26 @@ describe('holidBidAdapterTests', () => {
48
51
 
49
52
  describe('buildRequests', () => {
50
53
  const bid = JSON.parse(JSON.stringify(bidRequestData))
51
- const request = spec.buildRequests([bid], bid)
54
+ const request = spec.buildRequests([bid], bidderRequest)
52
55
  const payload = JSON.parse(request[0].data)
53
56
 
57
+ it('should include id in request', () => {
58
+ expect(payload.id).to.equal('test-id')
59
+ })
60
+
54
61
  it('should include ext in imp', () => {
55
- expect(payload.imp[0].ext).to.exist
56
62
  expect(payload.imp[0].ext).to.deep.equal({
57
63
  prebid: { storedrequest: { id: '12345' } },
58
64
  })
59
65
  })
60
66
 
67
+ it('should include ext in request', () => {
68
+ expect(payload.ext).to.deep.equal({
69
+ prebid: { storedrequest: { id: '12345' } },
70
+ })
71
+ })
72
+
61
73
  it('should include banner format in imp', () => {
62
- expect(payload.imp[0].banner).to.exist
63
74
  expect(payload.imp[0].banner).to.deep.equal({
64
75
  format: [{ w: 300, h: 250 }],
65
76
  })
@@ -146,6 +157,10 @@ describe('holidBidAdapterTests', () => {
146
157
  }
147
158
  const uspConsent = 'mkjvbiniwot4827obfoy8sdg8203gb'
148
159
  const expectedUserSyncs = [
160
+ {
161
+ type: 'image',
162
+ url: 'https://track.adform.net/Serving/TrackPoint/?pm=2992097&lid=132720821',
163
+ },
149
164
  {
150
165
  type: 'iframe',
151
166
  url: 'https://null.holid.io/sync.html?bidders=%5B%22test%20seat%201%22%2C%22test%20seat%202%22%5D&gdpr=1&gdpr_consent=dkj49Sjmfjuj34as:12jaf90123hufabidfy9u23brfpoig&usp_consent=mkjvbiniwot4827obfoy8sdg8203gb&type=iframe',
@@ -162,7 +177,7 @@ describe('holidBidAdapterTests', () => {
162
177
  expect(userSyncs).to.deep.equal(expectedUserSyncs)
163
178
  })
164
179
 
165
- it('should return empty user syncs when responsetimemillis is not defined', () => {
180
+ it('should return base user syncs when responsetimemillis is not defined', () => {
166
181
  const optionsType = {
167
182
  iframeEnabled: true,
168
183
  pixelEnabled: true,
@@ -179,7 +194,12 @@ describe('holidBidAdapterTests', () => {
179
194
  consentString: 'dkj49Sjmfjuj34as:12jaf90123hufabidfy9u23brfpoig',
180
195
  }
181
196
  const uspConsent = 'mkjvbiniwot4827obfoy8sdg8203gb'
182
- const expectedUserSyncs = []
197
+ const expectedUserSyncs = [
198
+ {
199
+ type: 'image',
200
+ url: 'https://track.adform.net/Serving/TrackPoint/?pm=2992097&lid=132720821',
201
+ }
202
+ ]
183
203
 
184
204
  const userSyncs = spec.getUserSyncs(
185
205
  optionsType,