prebid.js 7.23.0 → 7.24.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 (159) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/adagioBidAdapter.js +1 -1
  3. package/dist/adbookpspBidAdapter.js +1 -1
  4. package/dist/adgenerationBidAdapter.js +1 -1
  5. package/dist/admaticBidAdapter.js +1 -0
  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/audiencerunBidAdapter.js +1 -1
  17. package/dist/axonixBidAdapter.js +1 -1
  18. package/dist/bidglassBidAdapter.js +1 -1
  19. package/dist/big-richmediaBidAdapter.js +1 -1
  20. package/dist/bluebillywigBidAdapter.js +1 -1
  21. package/dist/bridgewellBidAdapter.js +1 -1
  22. package/dist/brightMountainMediaBidAdapter.js +1 -1
  23. package/dist/carodaBidAdapter.js +1 -1
  24. package/dist/chtnwBidAdapter.js +1 -1
  25. package/dist/concertBidAdapter.js +1 -1
  26. package/dist/connectIdSystem.js +1 -1
  27. package/dist/connectadBidAdapter.js +1 -1
  28. package/dist/consumableBidAdapter.js +1 -1
  29. package/dist/conversantBidAdapter.js +1 -1
  30. package/dist/craftBidAdapter.js +1 -1
  31. package/dist/criteoBidAdapter.js +1 -1
  32. package/dist/dspxBidAdapter.js +1 -1
  33. package/dist/eplanningBidAdapter.js +1 -1
  34. package/dist/finativeBidAdapter.js +1 -1
  35. package/dist/glimpseBidAdapter.js +1 -1
  36. package/dist/gmosspBidAdapter.js +1 -1
  37. package/dist/goldbachBidAdapter.js +1 -1
  38. package/dist/gridBidAdapter.js +1 -1
  39. package/dist/gridNMBidAdapter.js +1 -1
  40. package/dist/growthCodeIdSystem.js +1 -1
  41. package/dist/gumgumBidAdapter.js +1 -1
  42. package/dist/h12mediaBidAdapter.js +1 -1
  43. package/dist/id5IdSystem.js +1 -1
  44. package/dist/impactifyBidAdapter.js +1 -1
  45. package/dist/improvedigitalBidAdapter.js +1 -1
  46. package/dist/inmarBidAdapter.js +1 -1
  47. package/dist/insticatorBidAdapter.js +1 -1
  48. package/dist/ixBidAdapter.js +1 -1
  49. package/dist/jixieBidAdapter.js +1 -1
  50. package/dist/justpremiumBidAdapter.js +1 -1
  51. package/dist/konduitAnalyticsAdapter.js +1 -1
  52. package/dist/kueezBidAdapter.js +1 -1
  53. package/dist/kueezRtbBidAdapter.js +1 -0
  54. package/dist/lassoBidAdapter.js +1 -1
  55. package/dist/lifestreetBidAdapter.js +1 -1
  56. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  57. package/dist/logicadBidAdapter.js +1 -1
  58. package/dist/loglyliftBidAdapter.js +1 -1
  59. package/dist/magniteAnalyticsAdapter.js +1 -1
  60. package/dist/malltvAnalyticsAdapter.js +1 -1
  61. package/dist/marsmediaBidAdapter.js +1 -1
  62. package/dist/mediafuseBidAdapter.js +1 -1
  63. package/dist/mediakeysBidAdapter.js +1 -1
  64. package/dist/mediasquareBidAdapter.js +1 -1
  65. package/dist/mgidBidAdapter.js +1 -1
  66. package/dist/mgidRtdProvider.js +1 -0
  67. package/dist/minutemediaBidAdapter.js +1 -1
  68. package/dist/not-for-prod/prebid.js +122 -119
  69. package/dist/oguryBidAdapter.js +1 -1
  70. package/dist/onetagBidAdapter.js +1 -1
  71. package/dist/ooloAnalyticsAdapter.js +1 -1
  72. package/dist/outbrainBidAdapter.js +1 -1
  73. package/dist/parrableIdSystem.js +1 -1
  74. package/dist/pbsExtensions.js +1 -1
  75. package/dist/permutiveRtdProvider.js +1 -1
  76. package/dist/pixfutureBidAdapter.js +1 -1
  77. package/dist/prebid-core.js +1 -1
  78. package/dist/publinkIdSystem.js +1 -1
  79. package/dist/pubmaticBidAdapter.js +1 -1
  80. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  81. package/dist/pxyzBidAdapter.js +1 -1
  82. package/dist/quantcastBidAdapter.js +1 -1
  83. package/dist/readpeakBidAdapter.js +1 -1
  84. package/dist/relaidoBidAdapter.js +1 -1
  85. package/dist/rhythmoneBidAdapter.js +1 -1
  86. package/dist/riseBidAdapter.js +1 -1
  87. package/dist/rubiconAnalyticsAdapter.js +1 -1
  88. package/dist/rubiconBidAdapter.js +1 -1
  89. package/dist/seedingAllianceBidAdapter.js +1 -1
  90. package/dist/seedtagBidAdapter.js +1 -1
  91. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  92. package/dist/sharethroughBidAdapter.js +1 -1
  93. package/dist/shinezBidAdapter.js +1 -1
  94. package/dist/smaatoBidAdapter.js +1 -1
  95. package/dist/smartadserverBidAdapter.js +1 -1
  96. package/dist/smartxBidAdapter.js +1 -1
  97. package/dist/smilewantedBidAdapter.js +1 -1
  98. package/dist/sonobiBidAdapter.js +1 -1
  99. package/dist/sovrnAnalyticsAdapter.js +1 -1
  100. package/dist/sovrnBidAdapter.js +1 -1
  101. package/dist/sspBCBidAdapter.js +1 -1
  102. package/dist/sublimeBidAdapter.js +1 -1
  103. package/dist/synacormediaBidAdapter.js +1 -1
  104. package/dist/targetVideoBidAdapter.js +1 -1
  105. package/dist/teadsBidAdapter.js +1 -1
  106. package/dist/trionBidAdapter.js +1 -1
  107. package/dist/tripleliftBidAdapter.js +1 -1
  108. package/dist/ttdBidAdapter.js +1 -1
  109. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  110. package/dist/underdogmediaBidAdapter.js +1 -1
  111. package/dist/undertoneBidAdapter.js +1 -1
  112. package/dist/userId.js +1 -1
  113. package/dist/vidazooBidAdapter.js +1 -1
  114. package/dist/videobyteBidAdapter.js +1 -1
  115. package/dist/visxBidAdapter.js +1 -1
  116. package/dist/vuukleBidAdapter.js +1 -1
  117. package/dist/widespaceBidAdapter.js +1 -1
  118. package/dist/winrBidAdapter.js +1 -1
  119. package/dist/yahoosspBidAdapter.js +1 -1
  120. package/dist/yieldmoBidAdapter.js +1 -1
  121. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  122. package/integrationExamples/gpt/mgidRtdProvider_example.html +143 -0
  123. package/modules/.submodules.json +1 -0
  124. package/modules/admaticBidAdapter.js +147 -0
  125. package/modules/admaticBidAdapter.md +48 -0
  126. package/modules/amxBidAdapter.js +1 -0
  127. package/modules/connectIdSystem.js +36 -23
  128. package/modules/connectIdSystem.md +3 -2
  129. package/modules/growthCodeIdSystem.js +9 -5
  130. package/modules/gumgumBidAdapter.js +4 -0
  131. package/modules/ixBidAdapter.js +30 -7
  132. package/modules/kueezRtbBidAdapter.js +278 -0
  133. package/modules/kueezRtbBidAdapter.md +35 -0
  134. package/modules/magniteAnalyticsAdapter.js +6 -1
  135. package/modules/mgidRtdProvider.js +190 -0
  136. package/modules/mgidRtdProvider.md +51 -0
  137. package/modules/permutiveRtdProvider.js +2 -1
  138. package/modules/permutiveRtdProvider.md +36 -1
  139. package/modules/pubmaticBidAdapter.js +21 -29
  140. package/modules/tripleliftBidAdapter.js +1 -1
  141. package/modules/userId/eids.js +3 -10
  142. package/package.json +8 -8
  143. package/src/adRendering.js +1 -1
  144. package/src/adloader.js +1 -0
  145. package/src/auction.js +1 -1
  146. package/src/prebid.js +83 -79
  147. package/test/spec/auctionmanager_spec.js +9 -0
  148. package/test/spec/modules/admaticBidAdapter_spec.js +46 -0
  149. package/test/spec/modules/connectIdSystem_spec.js +175 -5
  150. package/test/spec/modules/eids_spec.js +10 -7
  151. package/test/spec/modules/ftrackIdSystem_spec.js +34 -22
  152. package/test/spec/modules/gumgumBidAdapter_spec.js +15 -0
  153. package/test/spec/modules/ixBidAdapter_spec.js +203 -0
  154. package/test/spec/modules/kueezRtbBidAdapter_spec.js +396 -0
  155. package/test/spec/modules/magniteAnalyticsAdapter_spec.js +26 -0
  156. package/test/spec/modules/mgidRtdProvider_spec.js +366 -0
  157. package/test/spec/modules/permutiveRtdProvider_spec.js +64 -5
  158. package/test/spec/modules/tripleliftBidAdapter_spec.js +14 -0
  159. package/test/spec/unit/pbjs_api_spec.js +17 -1
@@ -0,0 +1,366 @@
1
+ import { mgidSubmodule, storage } from '../../../modules/mgidRtdProvider.js';
2
+ import {expect} from 'chai';
3
+ import * as refererDetection from '../../../src/refererDetection';
4
+
5
+ describe('Mgid RTD submodule', () => {
6
+ let server;
7
+ let clock;
8
+ let getRefererInfoStub;
9
+ let getDataFromLocalStorageStub;
10
+
11
+ beforeEach(() => {
12
+ server = sinon.fakeServer.create();
13
+
14
+ clock = sinon.useFakeTimers();
15
+
16
+ getRefererInfoStub = sinon.stub(refererDetection, 'getRefererInfo');
17
+ getRefererInfoStub.returns({
18
+ canonicalUrl: 'https://www.test.com/abc'
19
+ });
20
+
21
+ getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage').returns('qwerty654321');
22
+ });
23
+
24
+ afterEach(() => {
25
+ server.restore();
26
+ clock.restore();
27
+ getRefererInfoStub.restore();
28
+ getDataFromLocalStorageStub.restore();
29
+ });
30
+
31
+ it('init is successfull, when clientSiteId is defined', () => {
32
+ expect(mgidSubmodule.init({params: {clientSiteId: 123}})).to.be.true;
33
+ });
34
+
35
+ it('init is unsuccessfull, when clientSiteId is not defined', () => {
36
+ expect(mgidSubmodule.init({})).to.be.false;
37
+ });
38
+
39
+ it('getBidRequestData send all params to our endpoint and succesfully modifies ortb2', () => {
40
+ const responseObj = {
41
+ userSegments: ['100', '200'],
42
+ userSegtax: 5,
43
+ siteSegments: ['300', '400'],
44
+ siteSegtax: 7,
45
+ muid: 'qwerty654321',
46
+ };
47
+
48
+ let reqBidsConfigObj = {
49
+ ortb2Fragments: {
50
+ global: {
51
+ site: {
52
+ content: {
53
+ language: 'en',
54
+ }
55
+ }
56
+ },
57
+ }
58
+ };
59
+
60
+ let onDone = sinon.stub();
61
+
62
+ mgidSubmodule.getBidRequestData(
63
+ reqBidsConfigObj,
64
+ onDone,
65
+ {params: {clientSiteId: 123}},
66
+ {
67
+ gdpr: {
68
+ gdprApplies: true,
69
+ consentString: 'testConsent',
70
+ },
71
+ usp: '1YYY',
72
+ }
73
+ );
74
+
75
+ server.requests[0].respond(
76
+ 200,
77
+ {'Content-Type': 'application/json'},
78
+ JSON.stringify(responseObj)
79
+ );
80
+
81
+ const requestUrl = new URL(server.requests[0].url);
82
+ expect(requestUrl.host).to.be.eq('servicer.mgid.com');
83
+ expect(requestUrl.searchParams.get('gdprApplies')).to.be.eq('true');
84
+ expect(requestUrl.searchParams.get('consentData')).to.be.eq('testConsent');
85
+ expect(requestUrl.searchParams.get('uspString')).to.be.eq('1YYY');
86
+ expect(requestUrl.searchParams.get('muid')).to.be.eq('qwerty654321');
87
+ expect(requestUrl.searchParams.get('clientSiteId')).to.be.eq('123');
88
+ expect(requestUrl.searchParams.get('cxurl')).to.be.eq('https://www.test.com/abc');
89
+ expect(requestUrl.searchParams.get('cxlang')).to.be.eq('en');
90
+
91
+ assert.deepInclude(
92
+ reqBidsConfigObj.ortb2Fragments.global,
93
+ {
94
+ site: {
95
+ content: {
96
+ language: 'en',
97
+ data: [
98
+ {
99
+ name: 'www.mgid.com',
100
+ ext: {
101
+ segtax: 7
102
+ },
103
+ segment: [
104
+ { id: '300' },
105
+ { id: '400' },
106
+ ]
107
+ }
108
+ ],
109
+ }
110
+ },
111
+ user: {
112
+ data: [
113
+ {
114
+ name: 'www.mgid.com',
115
+ ext: {
116
+ segtax: 5
117
+ },
118
+ segment: [
119
+ { id: '100' },
120
+ { id: '200' },
121
+ ]
122
+ }
123
+ ],
124
+ },
125
+ });
126
+ });
127
+
128
+ it('getBidRequestData doesn\'t send params (consent and cxlang), if we haven\'t received them', () => {
129
+ let reqBidsConfigObj = {
130
+ ortb2Fragments: {
131
+ global: {},
132
+ }
133
+ };
134
+
135
+ let onDone = sinon.stub();
136
+
137
+ mgidSubmodule.getBidRequestData(
138
+ reqBidsConfigObj,
139
+ onDone,
140
+ {params: {clientSiteId: 123}},
141
+ {}
142
+ );
143
+
144
+ server.requests[0].respond(
145
+ 200,
146
+ {'Content-Type': 'application/json'},
147
+ JSON.stringify({})
148
+ );
149
+
150
+ const requestUrl = new URL(server.requests[0].url);
151
+ expect(requestUrl.host).to.be.eq('servicer.mgid.com');
152
+ expect(requestUrl.searchParams.get('gdprApplies')).to.be.null;
153
+ expect(requestUrl.searchParams.get('consentData')).to.be.null;
154
+ expect(requestUrl.searchParams.get('uspString')).to.be.null;
155
+ expect(requestUrl.searchParams.get('muid')).to.be.eq('qwerty654321');
156
+ expect(requestUrl.searchParams.get('clientSiteId')).to.be.eq('123');
157
+ expect(requestUrl.searchParams.get('cxurl')).to.be.eq('https://www.test.com/abc');
158
+ expect(requestUrl.searchParams.get('cxlang')).to.be.null;
159
+ expect(onDone.calledOnce).to.be.true;
160
+ });
161
+
162
+ it('getBidRequestData send gdprApplies event if it is false', () => {
163
+ let reqBidsConfigObj = {
164
+ ortb2Fragments: {
165
+ global: {},
166
+ }
167
+ };
168
+
169
+ let onDone = sinon.stub();
170
+
171
+ mgidSubmodule.getBidRequestData(
172
+ reqBidsConfigObj,
173
+ onDone,
174
+ {params: {clientSiteId: 123}},
175
+ {
176
+ gdpr: {
177
+ gdprApplies: false,
178
+ consentString: 'testConsent',
179
+ },
180
+ usp: '1YYY',
181
+ }
182
+ );
183
+
184
+ server.requests[0].respond(
185
+ 200,
186
+ {'Content-Type': 'application/json'},
187
+ JSON.stringify({})
188
+ );
189
+
190
+ const requestUrl = new URL(server.requests[0].url);
191
+ expect(requestUrl.host).to.be.eq('servicer.mgid.com');
192
+ expect(requestUrl.searchParams.get('gdprApplies')).to.be.eq('false');
193
+ expect(requestUrl.searchParams.get('consentData')).to.be.eq('testConsent');
194
+ expect(requestUrl.searchParams.get('uspString')).to.be.eq('1YYY');
195
+ expect(requestUrl.searchParams.get('muid')).to.be.eq('qwerty654321');
196
+ expect(requestUrl.searchParams.get('clientSiteId')).to.be.eq('123');
197
+ expect(requestUrl.searchParams.get('cxurl')).to.be.eq('https://www.test.com/abc');
198
+ expect(requestUrl.searchParams.get('cxlang')).to.be.null;
199
+ expect(onDone.calledOnce).to.be.true;
200
+ });
201
+
202
+ it('getBidRequestData use og:url for cxurl, if it is available', () => {
203
+ let reqBidsConfigObj = {
204
+ ortb2Fragments: {
205
+ global: {},
206
+ }
207
+ };
208
+
209
+ let onDone = sinon.stub();
210
+
211
+ let metaStub = sinon.stub(document, 'getElementsByTagName').returns([
212
+ { getAttribute: () => 'og:test', content: 'fake' },
213
+ { getAttribute: () => 'og:url', content: 'https://realOgUrl.com/' }
214
+ ]);
215
+
216
+ mgidSubmodule.getBidRequestData(
217
+ reqBidsConfigObj,
218
+ onDone,
219
+ {params: {clientSiteId: 123}},
220
+ {}
221
+ );
222
+
223
+ server.requests[0].respond(
224
+ 200,
225
+ {'Content-Type': 'application/json'},
226
+ JSON.stringify({})
227
+ );
228
+
229
+ const requestUrl = new URL(server.requests[0].url);
230
+ expect(requestUrl.searchParams.get('cxurl')).to.be.eq('https://realOgUrl.com/');
231
+ expect(onDone.calledOnce).to.be.true;
232
+
233
+ metaStub.restore();
234
+ });
235
+
236
+ it('getBidRequestData use topMostLocation for cxurl, if nothing else left', () => {
237
+ let reqBidsConfigObj = {
238
+ ortb2Fragments: {
239
+ global: {},
240
+ }
241
+ };
242
+
243
+ let onDone = sinon.stub();
244
+
245
+ getRefererInfoStub.returns({
246
+ topmostLocation: 'https://www.test.com/topMost'
247
+ });
248
+
249
+ mgidSubmodule.getBidRequestData(
250
+ reqBidsConfigObj,
251
+ onDone,
252
+ {params: {clientSiteId: 123}},
253
+ {}
254
+ );
255
+
256
+ server.requests[0].respond(
257
+ 200,
258
+ {'Content-Type': 'application/json'},
259
+ JSON.stringify({})
260
+ );
261
+
262
+ const requestUrl = new URL(server.requests[0].url);
263
+ expect(requestUrl.searchParams.get('cxurl')).to.be.eq('https://www.test.com/topMost');
264
+ expect(onDone.calledOnce).to.be.true;
265
+ });
266
+
267
+ it('getBidRequestData won\'t modify ortb2 if response is broken', () => {
268
+ let reqBidsConfigObj = {
269
+ ortb2Fragments: {
270
+ global: {},
271
+ }
272
+ };
273
+
274
+ let onDone = sinon.stub();
275
+
276
+ mgidSubmodule.getBidRequestData(
277
+ reqBidsConfigObj,
278
+ onDone,
279
+ {params: {clientSiteId: 123}},
280
+ {}
281
+ );
282
+
283
+ server.requests[0].respond(
284
+ 200,
285
+ {'Content-Type': 'application/json'},
286
+ '{'
287
+ );
288
+
289
+ assert.deepEqual(reqBidsConfigObj.ortb2Fragments.global, {});
290
+ expect(onDone.calledOnce).to.be.true;
291
+ });
292
+
293
+ it('getBidRequestData won\'t modify ortb2 if response status is not 200', () => {
294
+ let reqBidsConfigObj = {
295
+ ortb2Fragments: {
296
+ global: {},
297
+ }
298
+ };
299
+
300
+ let onDone = sinon.stub();
301
+
302
+ mgidSubmodule.getBidRequestData(
303
+ reqBidsConfigObj,
304
+ onDone,
305
+ {params: {clientSiteId: 123}},
306
+ {}
307
+ );
308
+
309
+ server.requests[0].respond(
310
+ 204,
311
+ {'Content-Type': 'application/json'},
312
+ '{}'
313
+ );
314
+
315
+ assert.deepEqual(reqBidsConfigObj.ortb2Fragments.global, {});
316
+ expect(onDone.calledOnce).to.be.true;
317
+ });
318
+
319
+ it('getBidRequestData won\'t modify ortb2 if response results in error', () => {
320
+ let reqBidsConfigObj = {
321
+ ortb2Fragments: {
322
+ global: {},
323
+ }
324
+ };
325
+
326
+ let onDone = sinon.stub();
327
+
328
+ mgidSubmodule.getBidRequestData(
329
+ reqBidsConfigObj,
330
+ onDone,
331
+ {params: {clientSiteId: 123}},
332
+ {}
333
+ );
334
+
335
+ server.requests[0].respond(
336
+ 500,
337
+ {'Content-Type': 'application/json'},
338
+ '{}'
339
+ );
340
+
341
+ assert.deepEqual(reqBidsConfigObj.ortb2Fragments.global, {});
342
+ expect(onDone.calledOnce).to.be.true;
343
+ });
344
+
345
+ it('getBidRequestData won\'t modify ortb2 if response time hits timeout', () => {
346
+ let reqBidsConfigObj = {
347
+ ortb2Fragments: {
348
+ global: {},
349
+ }
350
+ };
351
+
352
+ let onDone = sinon.stub();
353
+
354
+ mgidSubmodule.getBidRequestData(
355
+ reqBidsConfigObj,
356
+ onDone,
357
+ {params: {clientSiteId: 123, timeout: 500}},
358
+ {}
359
+ );
360
+
361
+ clock.tick(510);
362
+
363
+ assert.deepEqual(reqBidsConfigObj.ortb2Fragments.global, {});
364
+ expect(onDone.calledOnce).to.be.true;
365
+ });
366
+ });
@@ -13,13 +13,13 @@ import { deepAccess, deepSetValue, mergeDeep } from '../../../src/utils.js'
13
13
  import { config } from 'src/config.js'
14
14
 
15
15
  describe('permutiveRtdProvider', function () {
16
- before(function () {
16
+ beforeEach(function () {
17
17
  const data = getTargetingData()
18
18
  setLocalStorage(data)
19
19
  config.resetConfig()
20
20
  })
21
21
 
22
- after(function () {
22
+ afterEach(function () {
23
23
  const data = getTargetingData()
24
24
  removeLocalStorage(data)
25
25
  config.resetConfig()
@@ -317,6 +317,7 @@ describe('permutiveRtdProvider', function () {
317
317
  })
318
318
  }
319
319
  })
320
+
320
321
  it('sets segment targeting for Magnite', function () {
321
322
  const data = transformedTargeting()
322
323
  const adUnits = getAdUnits()
@@ -337,6 +338,38 @@ describe('permutiveRtdProvider', function () {
337
338
  })
338
339
  }
339
340
  })
341
+
342
+ it('sets segment targeting for Magnite video', function () {
343
+ const targetingData = getTargetingData()
344
+ targetingData._prubicons.push(321)
345
+
346
+ setLocalStorage(targetingData)
347
+
348
+ const data = transformedTargeting(targetingData)
349
+ const config = getConfig()
350
+
351
+ const adUnits = getAdUnits().filter(adUnit => adUnit.mediaTypes.video)
352
+ expect(adUnits).to.have.lengthOf(1)
353
+
354
+ initSegments({ adUnits }, callback, config)
355
+
356
+ function callback() {
357
+ adUnits.forEach(adUnit => {
358
+ adUnit.bids.forEach(bid => {
359
+ const { bidder, params } = bid
360
+
361
+ if (bidder === 'rubicon') {
362
+ expect(
363
+ deepAccess(params, 'visitor.permutive'),
364
+ 'Should map all targeting values to a string',
365
+ ).to.eql(data.rubicon.map(String))
366
+ expect(deepAccess(params, 'visitor.p_standard')).to.eql(data.ac)
367
+ }
368
+ })
369
+ })
370
+ }
371
+ })
372
+
340
373
  it('sets segment targeting for Ozone', function () {
341
374
  const data = transformedTargeting()
342
375
  const adUnits = getAdUnits()
@@ -516,9 +549,7 @@ function getConfig () {
516
549
  }
517
550
  }
518
551
 
519
- function transformedTargeting () {
520
- const data = getTargetingData()
521
-
552
+ function transformedTargeting (data = getTargetingData()) {
522
553
  return {
523
554
  ac: [...data._pcrprs, ...data._ppam, ...data._psegs.filter(seg => seg >= 1000000)],
524
555
  appnexus: data._papns,
@@ -640,6 +671,34 @@ function getAdUnits () {
640
671
  }
641
672
  }
642
673
  ]
674
+ },
675
+ {
676
+ code: 'myVideoAdUnit',
677
+ mediaTypes: {
678
+ video: {
679
+ context: 'instream',
680
+ playerSize: [640, 480],
681
+ mimes: ['video/mp4', 'video/x-ms-wmv'],
682
+ protocols: [2, 3, 5, 6],
683
+ api: [2],
684
+ maxduration: 30,
685
+ linearity: 1
686
+ }
687
+ },
688
+ bids: [{
689
+ bidder: 'rubicon',
690
+ params: {
691
+ accountId: '9840',
692
+ siteId: '123564',
693
+ zoneId: '583584',
694
+ video: {
695
+ language: 'en'
696
+ },
697
+ visitor: {
698
+ test_kv: ['true']
699
+ }
700
+ }
701
+ }]
643
702
  }
644
703
  ]
645
704
  }
@@ -979,6 +979,20 @@ describe('triplelift adapter', function () {
979
979
  expect(url).to.match(new RegExp('(?:' + prebid.version + ')'))
980
980
  expect(url).to.match(/(?:referrer)/);
981
981
  });
982
+ it('should prioritize topmostLocation for referrer', function () {
983
+ bidderRequest.refererInfo.topmostLocation = 'https://topmostlocation.com?foo=bar'
984
+ const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
985
+ const url = request.url;
986
+ expect(url).to.match(/(\?|&)referrer=https%3A%2F%2Ftopmostlocation.com%3Ffoo%3Dbar/);
987
+ delete bidderRequest.refererInfo.topmostLocation
988
+ });
989
+ it('should fall back to page for referrer if topmostLocation is unavailable', function () {
990
+ bidderRequest.refererInfo.topmostLocation = null
991
+ const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
992
+ const url = request.url;
993
+ expect(url).to.match(/(\?|&)referrer=https%3A%2F%2Fexamplereferer.com/);
994
+ delete bidderRequest.refererInfo.topmostLocation
995
+ });
982
996
  it('should return us_privacy param when CCPA info is available', function() {
983
997
  bidderRequest.uspConsent = '1YYY';
984
998
  const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
@@ -1615,6 +1615,19 @@ describe('Unit: Prebid Module', function () {
1615
1615
  });
1616
1616
 
1617
1617
  describe('returns a promise that resolves', () => {
1618
+ function delayHook(next, ...args) {
1619
+ setTimeout(() => next(...args))
1620
+ }
1621
+
1622
+ beforeEach(() => {
1623
+ // make sure the return value works correctly when hooks give up priority
1624
+ $$PREBID_GLOBAL$$.requestBids.before(delayHook)
1625
+ });
1626
+
1627
+ afterEach(() => {
1628
+ $$PREBID_GLOBAL$$.requestBids.getHooks({hook: delayHook}).remove();
1629
+ });
1630
+
1618
1631
  Object.entries({
1619
1632
  'immediately, without bidsBackHandler': (req) => $$PREBID_GLOBAL$$.requestBids(req),
1620
1633
  'after bidsBackHandler': (() => {
@@ -1665,7 +1678,10 @@ describe('Unit: Prebid Module', function () {
1665
1678
  sinon.assert.match(bids[bid.adUnitCode].bids[0], bid)
1666
1679
  done();
1667
1680
  });
1668
- completeAuction([bid]);
1681
+ // `completeAuction` won't work until we're out of `delayHook`
1682
+ // and the mocked auction has been set up;
1683
+ // setTimeout here takes us after the setTimeout in `delayHook`
1684
+ setTimeout(() => completeAuction([bid]));
1669
1685
  })
1670
1686
  })
1671
1687
  })