prebid.js 9.53.3 → 9.53.4

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 (208) hide show
  1. package/dist/33acrossAnalyticsAdapter.js +1 -1
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/33acrossIdSystem.js +1 -1
  4. package/dist/BTBidAdapter.js +1 -1
  5. package/dist/adagioAnalyticsAdapter.js +1 -1
  6. package/dist/adagioBidAdapter.js +1 -1
  7. package/dist/adagioUtils.js +1 -1
  8. package/dist/addefendBidAdapter.js +1 -1
  9. package/dist/adgenerationBidAdapter.js +1 -1
  10. package/dist/adlooxRtdProvider.js +1 -1
  11. package/dist/adqueryBidAdapter.js +1 -1
  12. package/dist/adrelevantisBidAdapter.js +1 -1
  13. package/dist/adstirBidAdapter.js +1 -1
  14. package/dist/adtrgtmeBidAdapter.js +1 -1
  15. package/dist/adxcgAnalyticsAdapter.js +1 -1
  16. package/dist/adxcgBidAdapter.js +1 -1
  17. package/dist/adyoulikeBidAdapter.js +1 -1
  18. package/dist/agmaAnalyticsAdapter.js +1 -1
  19. package/dist/ajaBidAdapter.js +1 -1
  20. package/dist/amxBidAdapter.js +1 -1
  21. package/dist/amxIdSystem.js +1 -1
  22. package/dist/aniviewBidAdapter.js +1 -1
  23. package/dist/appierAnalyticsAdapter.js +1 -1
  24. package/dist/appnexusBidAdapter.js +1 -1
  25. package/dist/asoBidAdapter.js +1 -1
  26. package/dist/axonixBidAdapter.js +1 -1
  27. package/dist/beopBidAdapter.js +1 -1
  28. package/dist/bidderTimeoutUtils.js +1 -0
  29. package/dist/bidglassBidAdapter.js +1 -1
  30. package/dist/big-richmediaBidAdapter.js +1 -1
  31. package/dist/bitmediaBidAdapter.js +1 -1
  32. package/dist/bridBidAdapter.js +1 -1
  33. package/dist/bridgeuppBidAdapter.js +1 -1
  34. package/dist/bridgewellBidAdapter.js +1 -1
  35. package/dist/brightMountainMediaBidAdapter.js +1 -1
  36. package/dist/carodaBidAdapter.js +1 -1
  37. package/dist/chtnwBidAdapter.js +1 -1
  38. package/dist/chunk-core.js +1 -1
  39. package/dist/concertBidAdapter.js +1 -1
  40. package/dist/connectadBidAdapter.js +1 -1
  41. package/dist/consumableBidAdapter.js +1 -1
  42. package/dist/contxtfulBidAdapter.js +1 -1
  43. package/dist/conversantAnalyticsAdapter.js +1 -1
  44. package/dist/conversantBidAdapter.js +1 -1
  45. package/dist/craftBidAdapter.js +1 -1
  46. package/dist/criteoBidAdapter.js +1 -1
  47. package/dist/cwireBidAdapter.js +1 -1
  48. package/dist/dailymotionBidAdapter.js +1 -1
  49. package/dist/dependencies.json +10 -1
  50. package/dist/dspxBidAdapter.js +1 -1
  51. package/dist/dxkultureBidAdapter.js +1 -1
  52. package/dist/eplanningBidAdapter.js +1 -1
  53. package/dist/equativBidAdapter.js +1 -1
  54. package/dist/eskimiBidAdapter.js +1 -1
  55. package/dist/euidIdSystem.js +1 -1
  56. package/dist/exadsBidAdapter.js +1 -1
  57. package/dist/excoBidAdapter.js +1 -1
  58. package/dist/feedadBidAdapter.js +1 -1
  59. package/dist/finativeBidAdapter.js +1 -1
  60. package/dist/freewheel-sspBidAdapter.js +1 -1
  61. package/dist/fwsspBidAdapter.js +1 -1
  62. package/dist/gmosspBidAdapter.js +1 -1
  63. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  64. package/dist/greenbidsBidAdapter.js +1 -1
  65. package/dist/greenbidsRtdProvider.js +1 -1
  66. package/dist/gridBidAdapter.js +1 -1
  67. package/dist/gumgumBidAdapter.js +1 -1
  68. package/dist/h12mediaBidAdapter.js +1 -1
  69. package/dist/hypelabBidAdapter.js +1 -1
  70. package/dist/id5AnalyticsAdapter.js +1 -1
  71. package/dist/id5IdSystem.js +1 -1
  72. package/dist/imdsBidAdapter.js +1 -1
  73. package/dist/improvedigitalBidAdapter.js +1 -1
  74. package/dist/inmobiBidAdapter.js +1 -1
  75. package/dist/insticatorBidAdapter.js +1 -1
  76. package/dist/intentIqAnalyticsAdapter.js +1 -1
  77. package/dist/ixBidAdapter.js +1 -1
  78. package/dist/jixieBidAdapter.js +1 -1
  79. package/dist/justpremiumBidAdapter.js +1 -1
  80. package/dist/kargoBidAdapter.js +1 -1
  81. package/dist/kimberliteBidAdapter.js +1 -1
  82. package/dist/konduitAnalyticsAdapter.js +1 -1
  83. package/dist/kueezBidAdapter.js +1 -1
  84. package/dist/lassoBidAdapter.js +1 -1
  85. package/dist/lifestreetBidAdapter.js +1 -1
  86. package/dist/liveIntentId.js +1 -1
  87. package/dist/logicadBidAdapter.js +1 -1
  88. package/dist/loglyliftBidAdapter.js +1 -1
  89. package/dist/luceadBidAdapter.js +1 -1
  90. package/dist/mabidderBidAdapter.js +1 -1
  91. package/dist/madsenseBidAdapter.js +1 -1
  92. package/dist/magniteAnalyticsAdapter.js +1 -1
  93. package/dist/malltvAnalyticsAdapter.js +1 -1
  94. package/dist/marsmediaBidAdapter.js +1 -1
  95. package/dist/mediafuseBidAdapter.js +1 -1
  96. package/dist/medianetBidAdapter.js +1 -1
  97. package/dist/medianetUtils.js +1 -1
  98. package/dist/mediasquareBidAdapter.js +1 -1
  99. package/dist/mgidBidAdapter.js +1 -1
  100. package/dist/missenaBidAdapter.js +1 -1
  101. package/dist/mobilefuseBidAdapter.js +1 -1
  102. package/dist/nextMillenniumBidAdapter.js +1 -1
  103. package/dist/nexx360Utils.js +1 -1
  104. package/dist/nobidAnalyticsAdapter.js +1 -1
  105. package/dist/nobidBidAdapter.js +1 -1
  106. package/dist/nodalsAiRtdProvider.js +1 -1
  107. package/dist/not-for-prod/prebid.js +175 -172
  108. package/dist/objectGuard.js +1 -1
  109. package/dist/oguryBidAdapter.js +1 -1
  110. package/dist/onetagBidAdapter.js +1 -1
  111. package/dist/ooloAnalyticsAdapter.js +1 -1
  112. package/dist/openxBidAdapter.js +1 -1
  113. package/dist/optableRtdProvider.js +1 -1
  114. package/dist/optidigitalBidAdapter.js +1 -1
  115. package/dist/orbidderBidAdapter.js +1 -1
  116. package/dist/outbrainBidAdapter.js +1 -1
  117. package/dist/pixfutureBidAdapter.js +1 -1
  118. package/dist/publinkIdSystem.js +1 -1
  119. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  120. package/dist/pubmaticBidAdapter.js +1 -1
  121. package/dist/pubmaticRtdProvider.js +1 -1
  122. package/dist/pubmaticUtils.js +1 -0
  123. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  124. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  125. package/dist/pxyzBidAdapter.js +1 -1
  126. package/dist/quantcastBidAdapter.js +1 -1
  127. package/dist/readpeakBidAdapter.js +1 -1
  128. package/dist/relaidoBidAdapter.js +1 -1
  129. package/dist/retailspotBidAdapter.js +1 -1
  130. package/dist/rhythmoneBidAdapter.js +1 -1
  131. package/dist/riseUtils.js +1 -1
  132. package/dist/rtdModule.js +1 -1
  133. package/dist/rubiconBidAdapter.js +1 -1
  134. package/dist/seedingAllianceBidAdapter.js +1 -1
  135. package/dist/seedtagBidAdapter.js +1 -1
  136. package/dist/sevioBidAdapter.js +1 -0
  137. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  138. package/dist/sharethroughBidAdapter.js +1 -1
  139. package/dist/showheroes-bsBidAdapter.js +1 -1
  140. package/dist/smaatoBidAdapter.js +1 -1
  141. package/dist/smartadserverBidAdapter.js +1 -1
  142. package/dist/smartxBidAdapter.js +1 -1
  143. package/dist/smilewantedBidAdapter.js +1 -1
  144. package/dist/snigelBidAdapter.js +1 -1
  145. package/dist/sonobiBidAdapter.js +1 -1
  146. package/dist/sovrnBidAdapter.js +1 -1
  147. package/dist/sparteoBidAdapter.js +1 -1
  148. package/dist/sspBCBidAdapter.js +1 -1
  149. package/dist/stvBidAdapter.js +1 -1
  150. package/dist/sublimeBidAdapter.js +1 -1
  151. package/dist/taboolaBidAdapter.js +1 -1
  152. package/dist/tappxBidAdapter.js +1 -1
  153. package/dist/targetVideoBidAdapter.js +1 -1
  154. package/dist/teadsBidAdapter.js +1 -1
  155. package/dist/terceptAnalyticsAdapter.js +1 -1
  156. package/dist/themoneytizerBidAdapter.js +1 -1
  157. package/dist/timeoutRtdProvider.js +1 -1
  158. package/dist/trionBidAdapter.js +1 -1
  159. package/dist/tripleliftBidAdapter.js +1 -1
  160. package/dist/ttdBidAdapter.js +1 -1
  161. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  162. package/dist/uid2IdSystem.js +1 -1
  163. package/dist/underdogmediaBidAdapter.js +1 -1
  164. package/dist/undertoneBidAdapter.js +1 -1
  165. package/dist/unrulyBidAdapter.js +1 -1
  166. package/dist/vidazooUtils.js +1 -1
  167. package/dist/videobyteBidAdapter.js +1 -1
  168. package/dist/visxBidAdapter.js +1 -1
  169. package/dist/vuukleBidAdapter.js +1 -1
  170. package/dist/widespaceBidAdapter.js +1 -1
  171. package/dist/winrBidAdapter.js +1 -1
  172. package/dist/yahooAdsBidAdapter.js +1 -1
  173. package/dist/yandexBidAdapter.js +1 -1
  174. package/dist/yieldmoBidAdapter.js +1 -1
  175. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  176. package/integrationExamples/gpt/pubmaticRtdProvider_Example.html +161 -0
  177. package/libraries/bidderTimeoutUtils/bidderTimeoutUtils.js +119 -0
  178. package/libraries/objectGuard/objectGuard.js +36 -15
  179. package/libraries/pubmaticUtils/plugins/dynamicTimeout.js +209 -0
  180. package/libraries/pubmaticUtils/plugins/floorProvider.js +168 -0
  181. package/libraries/pubmaticUtils/plugins/pluginManager.js +106 -0
  182. package/libraries/pubmaticUtils/plugins/unifiedPricingRule.js +375 -0
  183. package/libraries/pubmaticUtils/pubmaticUtils.js +76 -0
  184. package/modules/fwsspBidAdapter.js +134 -69
  185. package/modules/fwsspBidAdapter.md +121 -26
  186. package/modules/optableRtdProvider.js +33 -12
  187. package/modules/pubmaticAnalyticsAdapter.js +5 -1
  188. package/modules/pubmaticRtdProvider.js +105 -565
  189. package/modules/rtdModule/index.js +23 -2
  190. package/modules/sevioBidAdapter.js +413 -0
  191. package/modules/sevioBidAdapter.md +29 -0
  192. package/modules/sparteoBidAdapter.js +122 -10
  193. package/modules/timeoutRtdProvider.js +2 -105
  194. package/package.json +1 -1
  195. package/test/spec/activities/objectGuard_spec.js +49 -16
  196. package/test/spec/libraries/bidderTimeoutUtils/bidderTimeoutUtils_spec.js +213 -0
  197. package/test/spec/libraries/pubmaticUtils/plugins/dynamicTimeout_spec.js +746 -0
  198. package/test/spec/libraries/pubmaticUtils/plugins/floorProvider_spec.js +184 -0
  199. package/test/spec/libraries/pubmaticUtils/plugins/pluginManager_spec.js +489 -0
  200. package/test/spec/libraries/pubmaticUtils/plugins/unifiedPricingRule_spec.js +359 -0
  201. package/test/spec/libraries/pubmaticUtils/pubmaticUtils_spec.js +236 -0
  202. package/test/spec/modules/fwsspBidAdapter_spec.js +513 -78
  203. package/test/spec/modules/optableRtdProvider_spec.js +55 -5
  204. package/test/spec/modules/pubmaticRtdProvider_spec.js +252 -1183
  205. package/test/spec/modules/realTimeDataModule_spec.js +58 -8
  206. package/test/spec/modules/sevioBidAdapter_spec.js +513 -0
  207. package/test/spec/modules/sparteoBidAdapter_spec.js +528 -43
  208. package/test/spec/modules/timeoutRtdProvider_spec.js +1 -201
@@ -1,5 +1,5 @@
1
1
  const { expect } = require('chai');
2
- const { spec, getSDKVersion, formatAdHTML } = require('modules/fwsspBidAdapter');
2
+ const { spec, getSDKVersion, formatAdHTML, getBidFloor } = require('modules/fwsspBidAdapter');
3
3
 
4
4
  describe('fwsspBidAdapter', () => {
5
5
  describe('isBidRequestValid', () => {
@@ -10,7 +10,6 @@ describe('fwsspBidAdapter', () => {
10
10
  networkId: '42015',
11
11
  profile: '42015:js_allinone_profile',
12
12
  siteSectionId: 'js_allinone_demo_site_section',
13
- videoAssetId: '0'
14
13
  }
15
14
  };
16
15
  expect(spec.isBidRequestValid(bid)).to.be.true;
@@ -22,7 +21,6 @@ describe('fwsspBidAdapter', () => {
22
21
  networkId: '42015',
23
22
  profile: '42015:js_allinone_profile',
24
23
  siteSectionId: 'js_allinone_demo_site_section',
25
- videoAssetId: '0'
26
24
  }
27
25
  };
28
26
  expect(spec.isBidRequestValid(bid)).to.be.false;
@@ -34,7 +32,6 @@ describe('fwsspBidAdapter', () => {
34
32
  serverUrl: 'https://example.com/ad/g/1',
35
33
  profile: '42015:js_allinone_profile',
36
34
  siteSectionId: 'js_allinone_demo_site_section',
37
- videoAssetId: '0'
38
35
  }
39
36
  };
40
37
  expect(spec.isBidRequestValid(bid)).to.be.false;
@@ -46,7 +43,6 @@ describe('fwsspBidAdapter', () => {
46
43
  serverUrl: 'https://example.com/ad/g/1',
47
44
  networkId: '42015',
48
45
  siteSectionId: 'js_allinone_demo_site_section',
49
- videoAssetId: '0'
50
46
  }
51
47
  };
52
48
  expect(spec.isBidRequestValid(bid)).to.be.false;
@@ -58,19 +54,6 @@ describe('fwsspBidAdapter', () => {
58
54
  serverUrl: 'https://example.com/ad/g/1',
59
55
  networkId: '42015',
60
56
  profile: '42015:js_allinone_profile',
61
- videoAssetId: '0'
62
- }
63
- };
64
- expect(spec.isBidRequestValid(bid)).to.be.false;
65
- });
66
-
67
- it('should return false when videoAssetId is missing', () => {
68
- const bid = {
69
- params: {
70
- serverUrl: 'https://example.com/ad/g/1',
71
- networkId: '42015',
72
- profile: '42015:js_allinone_profile',
73
- siteSectionId: 'js_allinone_demo_site_section'
74
57
  }
75
58
  };
76
59
  expect(spec.isBidRequestValid(bid)).to.be.false;
@@ -83,11 +66,11 @@ describe('fwsspBidAdapter', () => {
83
66
  'bidder': 'fwssp',
84
67
  'adUnitCode': 'adunit-code',
85
68
  'mediaTypes': {
86
- 'banner': {
87
- 'sizes': [
88
- [300, 250], [300, 600]
89
- ]
90
- }
69
+ 'banner': {
70
+ 'sizes': [
71
+ [300, 250], [300, 600]
72
+ ]
73
+ }
91
74
  },
92
75
  'sizes': [[300, 250], [300, 600]],
93
76
  'bidId': '30b31c1838de1e',
@@ -106,12 +89,12 @@ describe('fwsspBidAdapter', () => {
106
89
  },
107
90
  'params': {
108
91
  'bidfloor': 2.00,
92
+ 'bidfloorcur': 'EUR',
109
93
  'serverUrl': 'https://example.com/ad/g/1',
110
94
  'networkId': '42015',
111
95
  'profile': '42015:js_allinone_profile',
112
96
  'siteSectionId': 'js_allinone_demo_site_section',
113
97
  'flags': '+play',
114
- 'videoAssetId': '0',
115
98
  'timePosition': 120,
116
99
  'adRequestKeyValues': {
117
100
  '_fw_player_width': '1920',
@@ -136,7 +119,7 @@ describe('fwsspBidAdapter', () => {
136
119
  }
137
120
  };
138
121
 
139
- it('should build a valid server request', () => {
122
+ it('should build a valid server request with default caid of 0', () => {
140
123
  const requests = spec.buildRequests(getBidRequests(), bidderRequest);
141
124
  expect(requests).to.be.an('array').that.is.not.empty;
142
125
  const request = requests[0];
@@ -153,7 +136,7 @@ describe('fwsspBidAdapter', () => {
153
136
  expect(actualDataString).to.include('vprn=');
154
137
  expect(actualDataString).to.include('flag=%2Bplay%2Bfwssp%2Bemcr%2Bnucr%2Baeti%2Brema%2Bexvt%2Bfwpbjs');
155
138
  expect(actualDataString).to.include('mode=on-demand');
156
- expect(actualDataString).to.include(`vclr=js-7.10.0-prebid-${pbjs.version};`);
139
+ expect(actualDataString).to.include(`vclr=js-7.11.0-prebid-${pbjs.version};`);
157
140
  expect(actualDataString).to.include('_fw_player_width=1920');
158
141
  expect(actualDataString).to.include('_fw_player_height=1080');
159
142
  expect(actualDataString).to.include('_fw_gdpr_consent=consentString');
@@ -168,7 +151,7 @@ describe('fwsspBidAdapter', () => {
168
151
  expect(actualDataString).to.not.include('mind');
169
152
  expect(actualDataString).to.not.include('maxd;');
170
153
  // schain check
171
- const expectedEncodedSchainString = encodeURIComponent('{"ver":"1.0","complete":1,"nodes":[{"asi":"example.com","sid":"0","hp":1,"rid":"bidrequestid","domain":"example.com"}]}');
154
+ const expectedEncodedSchainString = '1.0,1!example.com,0,1,bidrequestid,,example.com';
172
155
  expect(actualDataString).to.include(expectedEncodedSchainString);
173
156
  });
174
157
 
@@ -176,13 +159,23 @@ describe('fwsspBidAdapter', () => {
176
159
  const requests = spec.buildRequests(getBidRequests(), bidderRequest);
177
160
  expect(requests).to.be.an('array').that.is.not.empty;
178
161
  const request = requests[0];
179
- const expectedUrl = `https://example.com/ad/g/1?nw=42015&resp=vast4&prof=42015%3Ajs_allinone_profile&csid=js_allinone_demo_site_section&caid=0&flag=%2Bplay%2Bfwssp%2Bemcr%2Bnucr%2Baeti%2Brema%2Bexvt%2Bfwpbjs&mode=on-demand&vclr=js-7.10.0-prebid-${pbjs.version};_fw_player_width=1920&_fw_player_height=1080&_fw_bidfloor=2&_fw_bidfloorcur=USD&_fw_gdpr_consent=consentString&_fw_gdpr=true&_fw_us_privacy=uspConsentString&gpp=gppString&gpp_sid=8&schain=%7B%22ver%22%3A%221.0%22%2C%22complete%22%3A1%2C%22nodes%22%3A%5B%7B%22asi%22%3A%22example.com%22%2C%22sid%22%3A%220%22%2C%22hp%22%3A1%2C%22rid%22%3A%22bidrequestid%22%2C%22domain%22%3A%22example.com%22%7D%5D%7D;tpos=0&ptgt=a&slid=Preroll_1&slau=preroll;`;
162
+ const expectedUrl = `https://example.com/ad/g/1?nw=42015&resp=vast4&prof=42015%3Ajs_allinone_profile&csid=js_allinone_demo_site_section&caid=0&flag=%2Bplay%2Bfwssp%2Bemcr%2Bnucr%2Baeti%2Brema%2Bexvt%2Bfwpbjs&mode=on-demand&vclr=js-7.11.0-prebid-${pbjs.version};_fw_player_width=1920&_fw_player_height=1080&_fw_bidfloor=2&_fw_bidfloorcur=EUR&_fw_gdpr_consent=consentString&_fw_gdpr=true&_fw_us_privacy=uspConsentString&gpp=gppString&gpp_sid=8&schain=1.0,1!example.com,0,1,bidrequestid,,example.com;tpos=0&ptgt=a&slid=Preroll_1&slau=preroll;`;
180
163
  const actualUrl = `${request.url}?${request.data}`;
181
164
  // Remove pvrn and vprn from both URLs before comparing
182
165
  const cleanUrl = (url) => url.replace(/&pvrn=[^&]*/g, '').replace(/&vprn=[^&]*/g, '');
183
166
  expect(cleanUrl(actualUrl)).to.equal(cleanUrl(expectedUrl));
184
167
  });
185
168
 
169
+ it('should use params.videoAssetId as caid', () => {
170
+ const bidRequests = getBidRequests();
171
+ bidRequests[0].params.videoAssetId = 10;
172
+ const requests = spec.buildRequests(bidRequests, bidderRequest);
173
+ expect(requests).to.be.an('array').that.is.not.empty;
174
+ const request = requests[0];
175
+ const actualDataString = request.data;
176
+ expect(actualDataString).to.include('caid=10');
177
+ });
178
+
186
179
  it('should return the correct width and height when _fw_player_width and _fw_player_height are not present in adRequestKeyValues', () => {
187
180
  const bidRequests = [{
188
181
  'bidder': 'fwssp',
@@ -212,31 +205,6 @@ describe('fwsspBidAdapter', () => {
212
205
  expect(payload).to.include('_fw_player_height=600');
213
206
  });
214
207
 
215
- it('should get bidfloor value from params if no getFloor method', () => {
216
- const request = spec.buildRequests(getBidRequests());
217
- const payload = request[0].data;
218
- expect(payload).to.include('_fw_bidfloor=2');
219
- expect(payload).to.include('_fw_bidfloorcur=USD');
220
- });
221
-
222
- it('should get bidfloor value from getFloor method if available', () => {
223
- const bidRequests = getBidRequests();
224
- bidRequests[0].getFloor = () => ({ currency: 'USD', floor: 1.16 });
225
- const request = spec.buildRequests(bidRequests);
226
- const payload = request[0].data;
227
- expect(payload).to.include('_fw_bidfloor=1.16');
228
- expect(payload).to.include('_fw_bidfloorcur=USD');
229
- });
230
-
231
- it('should return empty bidFloorCurrency when bidfloor <= 0', () => {
232
- const bidRequests = getBidRequests();
233
- bidRequests[0].getFloor = () => ({ currency: 'USD', floor: -1 });
234
- const request = spec.buildRequests(bidRequests);
235
- const payload = request[0].data;
236
- expect(payload).to.include('_fw_bidfloor=0');
237
- expect(payload).to.include('_fw_bidfloorcur=');
238
- });
239
-
240
208
  it('should return image type userSyncs with gdprConsent', () => {
241
209
  const syncOptions = {
242
210
  'pixelEnabled': true
@@ -244,7 +212,7 @@ describe('fwsspBidAdapter', () => {
244
212
  const userSyncs = spec.getUserSyncs(syncOptions, null, bidderRequest.gdprConsent, null, null);
245
213
  expect(userSyncs).to.deep.equal([{
246
214
  type: 'image',
247
- url: 'https://ads.stickyadstv.com/auto-user-sync?gdpr=1&gdpr_consent=consentString'
215
+ url: 'https://user-sync.fwmrm.net/ad/u?mode=auto-user-sync&gdpr=1&gdpr_consent=consentString'
248
216
  }]);
249
217
  });
250
218
 
@@ -255,9 +223,140 @@ describe('fwsspBidAdapter', () => {
255
223
  const userSyncs = spec.getUserSyncs(syncOptions, null, bidderRequest.gdprConsent, bidderRequest.uspConsent, bidderRequest.gppConsent);
256
224
  expect(userSyncs).to.deep.equal([{
257
225
  type: 'iframe',
258
- url: 'https://ads.stickyadstv.com/auto-user-sync?gdpr=1&gdpr_consent=consentString&us_privacy=uspConsentString&gpp=gppString&gpp_sid[]=8'
226
+ url: 'https://user-sync.fwmrm.net/ad/u?mode=auto-user-sync&gdpr=1&gdpr_consent=consentString&us_privacy=uspConsentString&gpp=gppString&gpp_sid=8'
259
227
  }]);
260
228
  });
229
+
230
+ it('should add privacy values to ad request and user sync url when present in keyValues', () => {
231
+ const bidRequests = getBidRequests();
232
+
233
+ bidRequests[0].params.adRequestKeyValues._fw_coppa = 1;
234
+ bidRequests[0].params.adRequestKeyValues._fw_atts = 1;
235
+ bidRequests[0].params.adRequestKeyValues._fw_is_lat = 1;
236
+ const requests = spec.buildRequests(bidRequests, bidderRequest);
237
+ const request = requests[0];
238
+ const expectedUrl = `https://example.com/ad/g/1?nw=42015&resp=vast4&prof=42015%3Ajs_allinone_profile&csid=js_allinone_demo_site_section&caid=0&flag=%2Bplay%2Bfwssp%2Bemcr%2Bnucr%2Baeti%2Brema%2Bexvt%2Bfwpbjs&mode=on-demand&vclr=js-7.11.0-prebid-${pbjs.version};_fw_player_width=1920&_fw_player_height=1080&_fw_coppa=1&_fw_atts=1&_fw_is_lat=1&_fw_bidfloor=2&_fw_bidfloorcur=EUR&_fw_gdpr_consent=consentString&_fw_gdpr=true&_fw_us_privacy=uspConsentString&gpp=gppString&gpp_sid=8&schain=1.0,1!example.com,0,1,bidrequestid,,example.com;tpos=0&ptgt=a&slid=Preroll_1&slau=preroll;`;
239
+ const actualUrl = `${request.url}?${request.data}`;
240
+ // Remove pvrn and vprn from both URLs before comparing
241
+ const cleanUrl = (url) => url.replace(/&pvrn=[^&]*/g, '').replace(/&vprn=[^&]*/g, '');
242
+ expect(cleanUrl(actualUrl)).to.equal(cleanUrl(expectedUrl));
243
+
244
+ const syncOptions = {
245
+ 'iframeEnabled': true
246
+ }
247
+ const userSyncs = spec.getUserSyncs(syncOptions, null, bidderRequest.gdprConsent, bidderRequest.uspConsent, bidderRequest.gppConsent);
248
+ expect(userSyncs).to.deep.equal([{
249
+ type: 'iframe',
250
+ url: 'https://user-sync.fwmrm.net/ad/u?mode=auto-user-sync&_fw_coppa=1&_fw_atts=1&_fw_is_lat=1&gdpr=1&gdpr_consent=consentString&us_privacy=uspConsentString&gpp=gppString&gpp_sid=8'
251
+ }]);
252
+ });
253
+
254
+ it('ortb2 values should take precedence over keyValues when present and be added to ad request and user sync url', () => {
255
+ const bidRequests = getBidRequests();
256
+ bidRequests[0].params.adRequestKeyValues._fw_coppa = 1;
257
+ bidRequests[0].params.adRequestKeyValues._fw_atts = 1;
258
+ bidRequests[0].params.adRequestKeyValues._fw_is_lat = 1;
259
+
260
+ const bidderRequest2 = { ...bidderRequest }
261
+ bidderRequest2.ortb2 = {
262
+ regs: { coppa: 0 },
263
+ device: {
264
+ lmt: 0,
265
+ ext: { atts: 0 }
266
+ }
267
+ }
268
+
269
+ const requests = spec.buildRequests(bidRequests, bidderRequest2);
270
+ const request = requests[0];
271
+ const expectedUrl = `https://example.com/ad/g/1?nw=42015&resp=vast4&prof=42015%3Ajs_allinone_profile&csid=js_allinone_demo_site_section&caid=0&flag=%2Bplay%2Bfwssp%2Bemcr%2Bnucr%2Baeti%2Brema%2Bexvt%2Bfwpbjs&mode=on-demand&vclr=js-7.11.0-prebid-${pbjs.version};_fw_player_width=1920&_fw_player_height=1080&_fw_coppa=0&_fw_atts=0&_fw_is_lat=0&_fw_bidfloor=2&_fw_bidfloorcur=EUR&_fw_gdpr_consent=consentString&_fw_gdpr=true&_fw_us_privacy=uspConsentString&gpp=gppString&gpp_sid=8&schain=1.0,1!example.com,0,1,bidrequestid,,example.com;tpos=0&ptgt=a&slid=Preroll_1&slau=preroll;`;
272
+ const actualUrl = `${request.url}?${request.data}`;
273
+ // Remove pvrn and vprn from both URLs before comparing
274
+ const cleanUrl = (url) => url.replace(/&pvrn=[^&]*/g, '').replace(/&vprn=[^&]*/g, '');
275
+ expect(cleanUrl(actualUrl)).to.equal(cleanUrl(expectedUrl));
276
+
277
+ const syncOptions = {
278
+ 'iframeEnabled': true
279
+ }
280
+ const userSyncs = spec.getUserSyncs(syncOptions, null, bidderRequest2.gdprConsent, bidderRequest2.uspConsent, bidderRequest2.gppConsent);
281
+ expect(userSyncs).to.deep.equal([{
282
+ type: 'iframe',
283
+ url: 'https://user-sync.fwmrm.net/ad/u?mode=auto-user-sync&_fw_coppa=0&_fw_atts=0&_fw_is_lat=0&gdpr=1&gdpr_consent=consentString&us_privacy=uspConsentString&gpp=gppString&gpp_sid=8'
284
+ }]);
285
+ });
286
+
287
+ it('should use schain from ortb2, prioritizing source.schain', () => {
288
+ const bidRequests = getBidRequests();
289
+ const bidderRequest2 = { ...bidderRequest }
290
+ const schain1 = {
291
+ ver: '1.0',
292
+ complete: 1,
293
+ nodes: [{
294
+ asi: 'test1.com',
295
+ sid: '0',
296
+ hp: 1,
297
+ rid: 'bidrequestid1',
298
+ domain: 'test1.com'
299
+ }]
300
+ };
301
+ const schain2 = {
302
+ ver: '1.0',
303
+ complete: 1,
304
+ nodes: [{
305
+ asi: 'test2.com',
306
+ sid: '0',
307
+ hp: 2,
308
+ rid: 'bidrequestid2',
309
+ domain: 'test2.com'
310
+ }]
311
+ };
312
+
313
+ bidderRequest2.ortb2 = {
314
+ source: {
315
+ schain: schain1,
316
+ ext: {
317
+ schain: schain2
318
+ }
319
+ }
320
+ };
321
+
322
+ const requests = spec.buildRequests(bidRequests, bidderRequest2);
323
+ const request = requests[0];
324
+
325
+ // schain check
326
+ const expectedEncodedSchainString = '1.0,1!test1.com,0,1,bidrequestid1,,test1.com';
327
+ expect(request.data).to.include(expectedEncodedSchainString);
328
+ });
329
+
330
+ it('should use schain from ortb2.source.ext, if source.schain is not available', () => {
331
+ const bidRequests = getBidRequests();
332
+ const bidderRequest2 = { ...bidderRequest }
333
+ const schain2 = {
334
+ ver: '1.0',
335
+ complete: 1,
336
+ nodes: [{
337
+ asi: 'test2.com',
338
+ sid: '0',
339
+ hp: 2,
340
+ rid: 'bidrequestid2',
341
+ domain: 'test2.com'
342
+ }]
343
+ };
344
+
345
+ bidderRequest2.ortb2 = {
346
+ source: {
347
+ ext: {
348
+ schain: schain2
349
+ }
350
+ }
351
+ };
352
+
353
+ const requests = spec.buildRequests(bidRequests, bidderRequest2);
354
+ const request = requests[0];
355
+
356
+ // schain check
357
+ const expectedEncodedSchainString = '1.0,1!test2.com,0,2,bidrequestid2,,test2.com';
358
+ expect(request.data).to.include(expectedEncodedSchainString);
359
+ });
261
360
  });
262
361
 
263
362
  describe('buildRequestsForVideo', () => {
@@ -268,6 +367,8 @@ describe('fwsspBidAdapter', () => {
268
367
  'mediaTypes': {
269
368
  'video': {
270
369
  'playerSize': [300, 600],
370
+ 'minduration': 30,
371
+ 'maxduration': 60,
271
372
  }
272
373
  },
273
374
  'sizes': [[300, 250], [300, 600]],
@@ -292,14 +393,11 @@ describe('fwsspBidAdapter', () => {
292
393
  'profile': '42015:js_allinone_profile',
293
394
  'siteSectionId': 'js_allinone_demo_site_section',
294
395
  'flags': '+play',
295
- 'videoAssetId': '0',
296
396
  'mode': 'live',
297
397
  'timePosition': 120,
298
398
  'tpos': 300,
299
399
  'slid': 'Midroll',
300
400
  'slau': 'midroll',
301
- 'minD': 30,
302
- 'maxD': 60,
303
401
  'adRequestKeyValues': {
304
402
  '_fw_player_width': '1920',
305
403
  '_fw_player_height': '1080'
@@ -339,9 +437,9 @@ describe('fwsspBidAdapter', () => {
339
437
  it('should return context and placement with default values', () => {
340
438
  const request = spec.buildRequests(getBidRequests());
341
439
  const payload = request[0].data;
342
- expect(payload).to.include('_fw_video_context=&'); ;
440
+ expect(payload).to.include('_fw_video_context=&');
343
441
  expect(payload).to.include('_fw_placement_type=null&');
344
- expect(payload).to.include('_fw_plcmt_type=null;');
442
+ expect(payload).to.include('_fw_plcmt_type=null&');
345
443
  });
346
444
 
347
445
  it('should assign placement and context when format is inbanner', () => {
@@ -350,9 +448,9 @@ describe('fwsspBidAdapter', () => {
350
448
  bidRequest.mediaTypes.video.plcmt = 'test-plcmt-type';
351
449
  const request = spec.buildRequests([bidRequest]);
352
450
  const payload = request[0].data;
353
- expect(payload).to.include('_fw_video_context=In-Banner&'); ;
451
+ expect(payload).to.include('_fw_video_context=In-Banner&');
354
452
  expect(payload).to.include('_fw_placement_type=2&');
355
- expect(payload).to.include('_fw_plcmt_type=test-plcmt-type;');
453
+ expect(payload).to.include('_fw_plcmt_type=test-plcmt-type&');
356
454
  });
357
455
 
358
456
  it('should build a valid server request', () => {
@@ -373,7 +471,7 @@ describe('fwsspBidAdapter', () => {
373
471
  expect(actualDataString).to.include('vprn=');
374
472
  expect(actualDataString).to.include('flag=%2Bplay%2Bfwssp%2Bemcr%2Bnucr%2Baeti%2Brema%2Bexvt%2Bfwpbjs');
375
473
  expect(actualDataString).to.include('mode=live');
376
- expect(actualDataString).to.include(`vclr=js-7.10.0-prebid-${pbjs.version};`);
474
+ expect(actualDataString).to.include(`vclr=js-7.11.0-prebid-${pbjs.version};`);
377
475
  expect(actualDataString).to.include('_fw_player_width=1920');
378
476
  expect(actualDataString).to.include('_fw_player_height=1080');
379
477
  expect(actualDataString).to.include('_fw_gdpr_consent=consentString');
@@ -390,7 +488,7 @@ describe('fwsspBidAdapter', () => {
390
488
  expect(actualDataString).to.include('mind=30');
391
489
  expect(actualDataString).to.include('maxd=60;');
392
490
  // schain check
393
- const expectedEncodedSchainString = encodeURIComponent('{"ver":"1.0","complete":1,"nodes":[{"asi":"example.com","sid":"0","hp":1,"rid":"bidrequestid","domain":"example.com"}]}');
491
+ const expectedEncodedSchainString = '1.0,1!example.com,0,1,bidrequestid,,example.com';
394
492
  expect(actualDataString).to.include(expectedEncodedSchainString);
395
493
  });
396
494
 
@@ -399,7 +497,7 @@ describe('fwsspBidAdapter', () => {
399
497
  expect(requests).to.be.an('array').that.is.not.empty;
400
498
  const request = requests[0];
401
499
 
402
- const expectedUrl = `https://example.com/ad/g/1?nw=42015&resp=vast4&prof=42015%3Ajs_allinone_profile&csid=js_allinone_demo_site_section&caid=0&flag=%2Bplay%2Bfwssp%2Bemcr%2Bnucr%2Baeti%2Brema%2Bexvt%2Bfwpbjs&mode=live&vclr=js-7.10.0-prebid-${pbjs.version};_fw_player_width=1920&_fw_player_height=1080&_fw_bidfloor=2&_fw_bidfloorcur=USD&_fw_gdpr_consent=consentString&_fw_gdpr=true&_fw_gdpr_consented_providers=test_providers&_fw_us_privacy=uspConsentString&gpp=gppString&gpp_sid=8&_fw_prebid_content=%7B%22id%22%3A%22test_content_id%22%2C%22title%22%3A%22test_content_title%22%7D&schain=%7B%22ver%22%3A%221.0%22%2C%22complete%22%3A1%2C%22nodes%22%3A%5B%7B%22asi%22%3A%22example.com%22%2C%22sid%22%3A%220%22%2C%22hp%22%3A1%2C%22rid%22%3A%22bidrequestid%22%2C%22domain%22%3A%22example.com%22%7D%5D%7D&loc=http%3A%2F%2Fwww.test.com&_fw_video_context=&_fw_placement_type=null&_fw_plcmt_type=null;tpos=300&ptgt=a&slid=Midroll&slau=midroll&mind=30&maxd=60;`;
500
+ const expectedUrl = `https://example.com/ad/g/1?nw=42015&resp=vast4&prof=42015%3Ajs_allinone_profile&csid=js_allinone_demo_site_section&caid=0&flag=%2Bplay%2Bfwssp%2Bemcr%2Bnucr%2Baeti%2Brema%2Bexvt%2Bfwpbjs&mode=live&vclr=js-7.11.0-prebid-${pbjs.version};_fw_player_width=1920&_fw_player_height=1080&_fw_bidfloor=2&_fw_bidfloorcur=USD&_fw_gdpr_consent=consentString&_fw_gdpr=true&_fw_gdpr_consented_providers=test_providers&_fw_us_privacy=uspConsentString&gpp=gppString&gpp_sid=8&_fw_prebid_content=%7B%22id%22%3A%22test_content_id%22%2C%22title%22%3A%22test_content_title%22%7D&loc=http%3A%2F%2Fwww.test.com&_fw_video_context=&_fw_placement_type=null&_fw_plcmt_type=null&schain=1.0,1!example.com,0,1,bidrequestid,,example.com;tpos=300&ptgt=a&slid=Midroll&slau=midroll&mind=30&maxd=60;`;
403
501
  const actualUrl = `${request.url}?${request.data}`;
404
502
  // Remove pvrn and vprn from both URLs before comparing
405
503
  const cleanUrl = (url) => url.replace(/&pvrn=[^&]*/g, '').replace(/&vprn=[^&]*/g, '');
@@ -425,7 +523,7 @@ describe('fwsspBidAdapter', () => {
425
523
  const requests = spec.buildRequests(getBidRequests(), bidderRequest2);
426
524
  expect(requests).to.be.an('array').that.is.not.empty;
427
525
  const request = requests[0];
428
- const expectedUrl = `https://example.com/ad/g/1?nw=42015&resp=vast4&prof=42015%3Ajs_allinone_profile&csid=js_allinone_demo_site_section&caid=0&flag=%2Bplay%2Bfwssp%2Bemcr%2Bnucr%2Baeti%2Brema%2Bexvt%2Bfwpbjs&mode=live&vclr=js-7.10.0-prebid-${pbjs.version};_fw_player_width=1920&_fw_player_height=1080&_fw_bidfloor=2&_fw_bidfloorcur=USD&_fw_gdpr_consented_providers=test_providers&gpp=test_ortb2_gpp&gpp_sid=test_ortb2_gpp_sid&_fw_prebid_content=%7B%22id%22%3A%22test_content_id%22%2C%22title%22%3A%22test_content_title%22%7D&schain=%7B%22ver%22%3A%221.0%22%2C%22complete%22%3A1%2C%22nodes%22%3A%5B%7B%22asi%22%3A%22example.com%22%2C%22sid%22%3A%220%22%2C%22hp%22%3A1%2C%22rid%22%3A%22bidrequestid%22%2C%22domain%22%3A%22example.com%22%7D%5D%7D&_fw_video_context=&_fw_placement_type=null&_fw_plcmt_type=null;tpos=300&ptgt=a&slid=Midroll&slau=midroll&mind=30&maxd=60;`;
526
+ const expectedUrl = `https://example.com/ad/g/1?nw=42015&resp=vast4&prof=42015%3Ajs_allinone_profile&csid=js_allinone_demo_site_section&caid=0&flag=%2Bplay%2Bfwssp%2Bemcr%2Bnucr%2Baeti%2Brema%2Bexvt%2Bfwpbjs&mode=live&vclr=js-7.11.0-prebid-${pbjs.version};_fw_player_width=1920&_fw_player_height=1080&_fw_bidfloor=2&_fw_bidfloorcur=USD&_fw_gdpr_consented_providers=test_providers&gpp=test_ortb2_gpp&gpp_sid=test_ortb2_gpp_sid&_fw_prebid_content=%7B%22id%22%3A%22test_content_id%22%2C%22title%22%3A%22test_content_title%22%7D&_fw_video_context=&_fw_placement_type=null&_fw_plcmt_type=null&schain=1.0,1!example.com,0,1,bidrequestid,,example.com;tpos=300&ptgt=a&slid=Midroll&slau=midroll&mind=30&maxd=60;`;
429
527
  const actualUrl = `${request.url}?${request.data}`;
430
528
  // Remove pvrn and vprn from both URLs before comparing
431
529
  const cleanUrl = (url) => url.replace(/&pvrn=[^&]*/g, '').replace(/&vprn=[^&]*/g, '');
@@ -446,7 +544,7 @@ describe('fwsspBidAdapter', () => {
446
544
  const userSyncs = spec.getUserSyncs(syncOptions, null, bidderRequest.gdprConsent, null, null);
447
545
  expect(userSyncs).to.deep.equal([{
448
546
  type: 'image',
449
- url: 'https://ads.stickyadstv.com/auto-user-sync?gdpr=1&gdpr_consent=consentString'
547
+ url: 'https://user-sync.fwmrm.net/ad/u?mode=auto-user-sync&gdpr=1&gdpr_consent=consentString'
450
548
  }]);
451
549
  });
452
550
 
@@ -457,7 +555,7 @@ describe('fwsspBidAdapter', () => {
457
555
  const userSyncs = spec.getUserSyncs(syncOptions, null, bidderRequest.gdprConsent, bidderRequest.uspConsent, bidderRequest.gppConsent);
458
556
  expect(userSyncs).to.deep.equal([{
459
557
  type: 'iframe',
460
- url: 'https://ads.stickyadstv.com/auto-user-sync?gdpr=1&gdpr_consent=consentString&us_privacy=uspConsentString&gpp=gppString&gpp_sid[]=8'
558
+ url: 'https://user-sync.fwmrm.net/ad/u?mode=auto-user-sync&gdpr=1&gdpr_consent=consentString&us_privacy=uspConsentString&gpp=gppString&gpp_sid=8'
461
559
  }]);
462
560
  });
463
561
  });
@@ -473,6 +571,8 @@ describe('fwsspBidAdapter', () => {
473
571
  'placement': 2,
474
572
  'plcmt': 3,
475
573
  'playerSize': [300, 600],
574
+ 'minduration': 30,
575
+ 'maxduration': 60,
476
576
  }
477
577
  },
478
578
  'sizes': [[300, 250], [300, 600]],
@@ -486,12 +586,9 @@ describe('fwsspBidAdapter', () => {
486
586
  'profile': '42015:js_allinone_profile',
487
587
  'siteSectionId': 'js_allinone_demo_site_section',
488
588
  'flags': '+play',
489
- 'videoAssetId': '0',
490
589
  'mode': 'live',
491
- 'vclr': 'js-7.10.0-prebid-',
590
+ 'vclr': 'js-7.11.0-prebid-',
492
591
  'timePosition': 120,
493
- 'minD': 30,
494
- 'maxD': 60,
495
592
  }
496
593
  }];
497
594
  const request = spec.buildRequests(bidRequests);
@@ -509,7 +606,7 @@ describe('fwsspBidAdapter', () => {
509
606
  sdkVersion: ''
510
607
  }
511
608
  };
512
- expect(getSDKVersion(bid)).to.equal('7.10.0');
609
+ expect(getSDKVersion(bid)).to.equal('7.11.0');
513
610
  });
514
611
 
515
612
  it('should return the correct sdk version when sdkVersion is higher than the default', () => {
@@ -527,7 +624,7 @@ describe('fwsspBidAdapter', () => {
527
624
  sdkVersion: '7.9.0'
528
625
  }
529
626
  };
530
- expect(getSDKVersion(bid)).to.equal('7.10.0');
627
+ expect(getSDKVersion(bid)).to.equal('7.11.0');
531
628
  });
532
629
 
533
630
  it('should return the default sdk version when sdkVersion is an invalid string', () => {
@@ -536,7 +633,7 @@ describe('fwsspBidAdapter', () => {
536
633
  sdkVersion: 'abcdef'
537
634
  }
538
635
  };
539
- expect(getSDKVersion(bid)).to.equal('7.10.0');
636
+ expect(getSDKVersion(bid)).to.equal('7.11.0');
540
637
  });
541
638
 
542
639
  it('should return the correct sdk version when sdkVersion starts with v', () => {
@@ -555,7 +652,7 @@ describe('fwsspBidAdapter', () => {
555
652
  `<div id='fwssp_display_base' class='ad-container' style='width:640px;height:480px;'>
556
653
  <script type='text/javascript'>
557
654
  const script = document.createElement('script');
558
- script.src = 'https://mssl.fwmrm.net/libs/adm/7.10.0/AdManager-prebid.js';
655
+ script.src = 'https://mssl.fwmrm.net/libs/adm/7.11.0/AdManager-prebid.js';
559
656
  script.async = true;
560
657
 
561
658
  const topWindow = function() {
@@ -624,7 +721,7 @@ describe('fwsspBidAdapter', () => {
624
721
  `<div id='fwssp_display_base' class='ad-container' style='width:640px;height:480px;'>
625
722
  <script type='text/javascript'>
626
723
  const script = document.createElement('script');
627
- script.src = 'https://mssl.fwmrm.net/libs/adm/7.10.0/AdManager-prebid.js';
724
+ script.src = 'https://mssl.fwmrm.net/libs/adm/7.11.0/AdManager-prebid.js';
628
725
  script.async = true;
629
726
 
630
727
  const topWindow = function() {
@@ -697,7 +794,7 @@ describe('fwsspBidAdapter', () => {
697
794
  `<div id='fwssp_display_base' class='ad-container' style='width:640px;height:480px;'>
698
795
  <script type='text/javascript'>
699
796
  const script = document.createElement('script');
700
- script.src = 'https://adm.stg.fwmrm.net/libs/adm/7.10.0/AdManager-prebid.js';
797
+ script.src = 'https://adm.stg.fwmrm.net/libs/adm/7.11.0/AdManager-prebid.js';
701
798
  script.async = true;
702
799
 
703
800
  const topWindow = function() {
@@ -910,4 +1007,342 @@ describe('fwsspBidAdapter', () => {
910
1007
  expect(result.length).to.equal(0);
911
1008
  });
912
1009
  });
1010
+
1011
+ describe('getBidFloor function tests', () => {
1012
+ const mockConfig = {
1013
+ getConfig: (key) => {
1014
+ if (key === 'floors.data.currency') return 'EUR';
1015
+ return null;
1016
+ }
1017
+ };
1018
+
1019
+ it('should use params.bidfloor and params.bidfloorcur when getFloor method is not available', () => {
1020
+ const bidRequest = {
1021
+ params: {
1022
+ bidfloor: 1.5,
1023
+ bidfloorcur: 'GBP'
1024
+ }
1025
+ };
1026
+ const result = getBidFloor(bidRequest, mockConfig);
1027
+ expect(result.floor).to.equal(1.5);
1028
+ expect(result.currency).to.equal('GBP');
1029
+ });
1030
+
1031
+ it('should use default values when params are missing and no getFloor method', () => {
1032
+ const bidRequest = {
1033
+ params: {}
1034
+ };
1035
+ const result = getBidFloor(bidRequest, mockConfig);
1036
+ expect(result.floor).to.equal(0);
1037
+ expect(result.currency).to.equal('USD');
1038
+ });
1039
+
1040
+ it('should use getFloor method when available for banner mediaType', () => {
1041
+ const bidRequest = {
1042
+ params: {
1043
+ bidfloor: 1.0,
1044
+ bidfloorcur: 'USD'
1045
+ },
1046
+ mediaTypes: {
1047
+ banner: {
1048
+ sizes: [[300, 250]]
1049
+ }
1050
+ },
1051
+ getFloor: () => ({
1052
+ floor: 2.5,
1053
+ currency: 'EUR'
1054
+ })
1055
+ };
1056
+ const result = getBidFloor(bidRequest, mockConfig);
1057
+ expect(result.floor).to.equal(2.5);
1058
+ expect(result.currency).to.equal('EUR');
1059
+ });
1060
+
1061
+ it('should use getFloor method when available for video mediaType', () => {
1062
+ const bidRequest = {
1063
+ params: {
1064
+ bidfloor: 1.0,
1065
+ bidfloorcur: 'USD'
1066
+ },
1067
+ mediaTypes: {
1068
+ video: {
1069
+ playerSize: [640, 480]
1070
+ }
1071
+ },
1072
+ getFloor: () => ({
1073
+ floor: 3.0,
1074
+ currency: 'JPY'
1075
+ })
1076
+ };
1077
+ const result = getBidFloor(bidRequest, mockConfig);
1078
+ expect(result.floor).to.equal(3.0);
1079
+ expect(result.currency).to.equal('JPY');
1080
+ });
1081
+
1082
+ it('should fallback to params when getFloor throws an error', () => {
1083
+ const bidRequest = {
1084
+ params: {
1085
+ bidfloor: 1.75,
1086
+ bidfloorcur: 'CAD'
1087
+ },
1088
+ getFloor: () => {
1089
+ throw new Error('getFloor error');
1090
+ }
1091
+ };
1092
+ const result = getBidFloor(bidRequest, mockConfig);
1093
+ expect(result.floor).to.equal(1.75);
1094
+ expect(result.currency).to.equal('CAD');
1095
+ });
1096
+
1097
+ it('should fallback to params when getFloor returns invalid floor value', () => {
1098
+ const bidRequest = {
1099
+ params: {
1100
+ bidfloor: 2.0,
1101
+ bidfloorcur: 'AUD'
1102
+ },
1103
+ getFloor: () => ({
1104
+ floor: 'invalid',
1105
+ currency: 'EUR'
1106
+ })
1107
+ };
1108
+ const result = getBidFloor(bidRequest, mockConfig);
1109
+ expect(result.floor).to.equal(2.0);
1110
+ expect(result.currency).to.equal('AUD');
1111
+ });
1112
+
1113
+ it('should use getFloor currency when floor is valid but currency is from getFloor', () => {
1114
+ const bidRequest = {
1115
+ params: {
1116
+ bidfloor: 1.0
1117
+ },
1118
+ mediaTypes: {
1119
+ banner: {
1120
+ sizes: [[300, 250]]
1121
+ }
1122
+ },
1123
+ getFloor: () => ({
1124
+ floor: 2.25,
1125
+ currency: 'CHF'
1126
+ })
1127
+ };
1128
+ const result = getBidFloor(bidRequest, mockConfig);
1129
+ expect(result.floor).to.equal(2.25);
1130
+ expect(result.currency).to.equal('CHF');
1131
+ });
1132
+ });
1133
+
1134
+ describe('bidfloor integration in buildRequests', () => {
1135
+ it('should include bidfloor values from getBidFloor in banner requests', () => {
1136
+ const bidRequests = [{
1137
+ 'bidder': 'fwssp',
1138
+ 'adUnitCode': 'adunit-code',
1139
+ 'mediaTypes': {
1140
+ 'banner': {
1141
+ 'sizes': [[300, 250]]
1142
+ }
1143
+ },
1144
+ 'bidId': '30b31c1838de1e',
1145
+ 'params': {
1146
+ 'serverUrl': 'https://example.com/ad/g/1',
1147
+ 'networkId': '42015',
1148
+ 'profile': '42015:js_allinone_profile',
1149
+ 'siteSectionId': 'js_allinone_demo_site_section',
1150
+ 'bidfloor': 1.25,
1151
+ 'bidfloorcur': 'GBP'
1152
+ }
1153
+ }];
1154
+
1155
+ const request = spec.buildRequests(bidRequests);
1156
+ const payload = request[0].data;
1157
+ expect(payload).to.include('_fw_bidfloor=1.25');
1158
+ expect(payload).to.include('_fw_bidfloorcur=GBP');
1159
+ });
1160
+
1161
+ it('should include bidfloor values from getFloor method when available', () => {
1162
+ const bidRequests = [{
1163
+ 'bidder': 'fwssp',
1164
+ 'adUnitCode': 'adunit-code',
1165
+ 'mediaTypes': {
1166
+ 'video': {
1167
+ 'playerSize': [640, 480]
1168
+ }
1169
+ },
1170
+ 'bidId': '30b31c1838de1e',
1171
+ 'params': {
1172
+ 'serverUrl': 'https://example.com/ad/g/1',
1173
+ 'networkId': '42015',
1174
+ 'profile': '42015:js_allinone_profile',
1175
+ 'siteSectionId': 'js_allinone_demo_site_section',
1176
+ 'bidfloor': 1.0,
1177
+ 'bidfloorcur': 'USD'
1178
+ },
1179
+ getFloor: () => ({
1180
+ floor: 2.75,
1181
+ currency: 'EUR'
1182
+ })
1183
+ }];
1184
+
1185
+ const request = spec.buildRequests(bidRequests);
1186
+ const payload = request[0].data;
1187
+ expect(payload).to.include('_fw_bidfloor=2.75');
1188
+ expect(payload).to.include('_fw_bidfloorcur=EUR');
1189
+ });
1190
+
1191
+ it('should handle zero bidfloor values correctly', () => {
1192
+ const bidRequests = [{
1193
+ 'bidder': 'fwssp',
1194
+ 'adUnitCode': 'adunit-code',
1195
+ 'mediaTypes': {
1196
+ 'banner': {
1197
+ 'sizes': [[300, 250]]
1198
+ }
1199
+ },
1200
+ 'bidId': '30b31c1838de1e',
1201
+ 'params': {
1202
+ 'serverUrl': 'https://example.com/ad/g/1',
1203
+ 'networkId': '42015',
1204
+ 'profile': '42015:js_allinone_profile',
1205
+ 'siteSectionId': 'js_allinone_demo_site_section',
1206
+ },
1207
+ getFloor: () => ({
1208
+ floor: 0,
1209
+ currency: 'USD'
1210
+ })
1211
+ }];
1212
+
1213
+ const request = spec.buildRequests(bidRequests);
1214
+ const payload = request[0].data;
1215
+ expect(payload).to.include('_fw_bidfloor=0');
1216
+ expect(payload).to.include('_fw_bidfloorcur=USD');
1217
+ });
1218
+
1219
+ it('should include default bidfloor values when no floor configuration exists', () => {
1220
+ const bidRequests = [{
1221
+ 'bidder': 'fwssp',
1222
+ 'adUnitCode': 'adunit-code',
1223
+ 'mediaTypes': {
1224
+ 'banner': {
1225
+ 'sizes': [[300, 250]]
1226
+ }
1227
+ },
1228
+ 'bidId': '30b31c1838de1e',
1229
+ 'params': {
1230
+ 'serverUrl': 'https://example.com/ad/g/1',
1231
+ 'networkId': '42015',
1232
+ 'profile': '42015:js_allinone_profile',
1233
+ 'siteSectionId': 'js_allinone_demo_site_section',
1234
+ }
1235
+ }];
1236
+
1237
+ const request = spec.buildRequests(bidRequests);
1238
+ const payload = request[0].data;
1239
+ expect(payload).to.include('_fw_bidfloor=0');
1240
+ expect(payload).to.include('_fw_bidfloorcur=USD');
1241
+ });
1242
+ });
1243
+
1244
+ describe('schain tests', () => {
1245
+ const getBidRequests = () => {
1246
+ return [{
1247
+ 'bidder': 'fwssp',
1248
+ 'adUnitCode': 'adunit-code',
1249
+ 'mediaTypes': {
1250
+ 'video': {
1251
+ 'playerSize': [300, 600],
1252
+ 'minduration': 30,
1253
+ 'maxduration': 60,
1254
+ }
1255
+ },
1256
+ 'sizes': [[300, 250], [300, 600]],
1257
+ 'bidId': '30b31c1838de1e',
1258
+ 'bidderRequestId': '22edbae2733bf6',
1259
+ 'auctionId': '1d1a030790a475',
1260
+ 'params': {
1261
+ 'bidfloor': 2.00,
1262
+ 'serverUrl': 'https://example.com/ad/g/1',
1263
+ 'networkId': '42015',
1264
+ 'profile': '42015:js_allinone_profile',
1265
+ 'siteSectionId': 'js_allinone_demo_site_section',
1266
+ 'flags': '+play',
1267
+ 'videoAssetId': '0',
1268
+ 'mode': 'live',
1269
+ 'timePosition': 120,
1270
+ 'tpos': 300,
1271
+ 'slid': 'Midroll',
1272
+ 'slau': 'midroll',
1273
+ 'adRequestKeyValues': {
1274
+ '_fw_player_width': '1920',
1275
+ '_fw_player_height': '1080'
1276
+ },
1277
+ 'gdpr_consented_providers': 'test_providers'
1278
+ }
1279
+ }]
1280
+ };
1281
+
1282
+ const bidderRequest = {
1283
+ gdprConsent: {
1284
+ consentString: 'consentString',
1285
+ gdprApplies: true
1286
+ },
1287
+ uspConsent: 'uspConsentString',
1288
+ gppConsent: {
1289
+ gppString: 'gppString',
1290
+ applicableSections: [8]
1291
+ },
1292
+ ortb2: {
1293
+ regs: {
1294
+ gpp: 'test_ortb2_gpp',
1295
+ gpp_sid: 'test_ortb2_gpp_sid'
1296
+ },
1297
+ site: {
1298
+ content: {
1299
+ id: 'test_content_id',
1300
+ title: 'test_content_title'
1301
+ }
1302
+ }
1303
+ },
1304
+ refererInfo: {
1305
+ page: 'http://www.test.com'
1306
+ }
1307
+ };
1308
+
1309
+ it('should not include schain in the adrequest URL if schain is missing from bidrequest', () => {
1310
+ const requests = spec.buildRequests(getBidRequests(), bidderRequest);
1311
+ expect(requests).to.be.an('array').that.is.not.empty;
1312
+ const request = requests[0];
1313
+ const expectedUrl = `https://example.com/ad/g/1?nw=42015&resp=vast4&prof=42015%3Ajs_allinone_profile&csid=js_allinone_demo_site_section&caid=0&flag=%2Bplay%2Bfwssp%2Bemcr%2Bnucr%2Baeti%2Brema%2Bexvt%2Bfwpbjs&mode=live&vclr=js-7.11.0-prebid-${pbjs.version};_fw_player_width=1920&_fw_player_height=1080&_fw_bidfloor=2&_fw_bidfloorcur=USD&_fw_gdpr_consent=consentString&_fw_gdpr=true&_fw_gdpr_consented_providers=test_providers&_fw_us_privacy=uspConsentString&gpp=gppString&gpp_sid=8&_fw_prebid_content=%7B%22id%22%3A%22test_content_id%22%2C%22title%22%3A%22test_content_title%22%7D&loc=http%3A%2F%2Fwww.test.com&_fw_video_context=&_fw_placement_type=null&_fw_plcmt_type=null;tpos=300&ptgt=a&slid=Midroll&slau=midroll&mind=30&maxd=60;`;
1314
+ const actualUrl = `${request.url}?${request.data}`;
1315
+ // Remove pvrn and vprn from both URLs before comparing
1316
+ const cleanUrl = (url) => url.replace(/&pvrn=[^&]*/g, '').replace(/&vprn=[^&]*/g, '');
1317
+ expect(cleanUrl(actualUrl)).to.equal(cleanUrl(expectedUrl));
1318
+ });
1319
+
1320
+ it('should only encode comma within attribute value', () => {
1321
+ const bidRequests = getBidRequests();
1322
+ const bidderRequest2 = { ...bidderRequest }
1323
+ const schain1 = {
1324
+ ver: '1.0',
1325
+ complete: 1,
1326
+ nodes: [{
1327
+ asi: 'test1.com',
1328
+ sid: '123,B',
1329
+ hp: 1,
1330
+ rid: 'bidrequestid1',
1331
+ domain: 'test1.com'
1332
+ }]
1333
+ };
1334
+
1335
+ bidderRequest2.ortb2 = {
1336
+ source: {
1337
+ schain: schain1,
1338
+ }
1339
+ };
1340
+ const requests = spec.buildRequests(bidRequests, bidderRequest2);
1341
+ const request = requests[0];
1342
+
1343
+ // schain check
1344
+ const expectedEncodedSchainString = '1.0,1!test1.com,123%2CB,1,bidrequestid1,,test1.com';
1345
+ expect(request.data).to.include(expectedEncodedSchainString);
1346
+ });
1347
+ });
913
1348
  });