prebid.js 8.7.0 → 8.9.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 (350) hide show
  1. package/dist/1plusXRtdProvider.js +1 -1
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/33acrossIdSystem.js +1 -1
  4. package/dist/a1MediaRtdProvider.js +1 -1
  5. package/dist/adWMGAnalyticsAdapter.js +1 -1
  6. package/dist/adagioBidAdapter.js +1 -1
  7. package/dist/adbookpspBidAdapter.js +1 -1
  8. package/dist/adgenerationBidAdapter.js +1 -1
  9. package/dist/adkernelAdnAnalyticsAdapter.js +1 -1
  10. package/dist/adlooxAdServerVideo.js +1 -1
  11. package/dist/adlooxRtdProvider.js +1 -1
  12. package/dist/admaticBidAdapter.js +1 -1
  13. package/dist/admixerIdSystem.js +1 -1
  14. package/dist/adnuntiusRtdProvider.js +1 -1
  15. package/dist/adpartnerBidAdapter.js +1 -1
  16. package/dist/adqueryBidAdapter.js +1 -1
  17. package/dist/adqueryIdSystem.js +1 -1
  18. package/dist/adrelevantisBidAdapter.js +1 -1
  19. package/dist/adriverIdSystem.js +1 -1
  20. package/dist/adtelligentIdSystem.js +1 -1
  21. package/dist/adtrgtmeBidAdapter.js +1 -1
  22. package/dist/adxcgAnalyticsAdapter.js +1 -1
  23. package/dist/adxcgBidAdapter.js +1 -1
  24. package/dist/adxpremiumAnalyticsAdapter.js +1 -1
  25. package/dist/adyoulikeBidAdapter.js +1 -1
  26. package/dist/aidemBidAdapter.js +1 -1
  27. package/dist/ajaBidAdapter.js +1 -1
  28. package/dist/akamaiDapRtdProvider.js +1 -1
  29. package/dist/alkimiBidAdapter.js +1 -1
  30. package/dist/amxBidAdapter.js +1 -1
  31. package/dist/amxIdSystem.js +1 -1
  32. package/dist/analyticsAdapter.js +1 -1
  33. package/dist/appierAnalyticsAdapter.js +1 -1
  34. package/dist/appnexusBidAdapter.js +1 -1
  35. package/dist/asoBidAdapter.js +1 -1
  36. package/dist/atsAnalyticsAdapter.js +1 -1
  37. package/dist/automatadBidAdapter.js +1 -1
  38. package/dist/axonixBidAdapter.js +1 -1
  39. package/dist/bidViewability.js +1 -1
  40. package/dist/bidglassBidAdapter.js +1 -1
  41. package/dist/bidwatchAnalyticsAdapter.js +1 -1
  42. package/dist/big-richmediaBidAdapter.js +1 -1
  43. package/dist/brandmetricsRtdProvider.js +1 -1
  44. package/dist/bridBidAdapter.js +1 -1
  45. package/dist/bridgewellBidAdapter.js +1 -1
  46. package/dist/brightMountainMediaBidAdapter.js +1 -1
  47. package/dist/brightcomSSPBidAdapter.js +1 -1
  48. package/dist/britepoolIdSystem.js +1 -1
  49. package/dist/browsiRtdProvider.js +1 -1
  50. package/dist/byDataAnalyticsAdapter.js +1 -1
  51. package/dist/carodaBidAdapter.js +1 -1
  52. package/dist/categoryTranslation.js +1 -1
  53. package/dist/chtnwBidAdapter.js +1 -1
  54. package/dist/colossussspBidAdapter.js +1 -1
  55. package/dist/concertAnalyticsAdapter.js +1 -1
  56. package/dist/concertBidAdapter.js +1 -1
  57. package/dist/connectIdSystem.js +1 -1
  58. package/dist/connectadBidAdapter.js +1 -1
  59. package/dist/consumableBidAdapter.js +1 -1
  60. package/dist/conversantAnalyticsAdapter.js +1 -1
  61. package/dist/conversantBidAdapter.js +1 -1
  62. package/dist/craftBidAdapter.js +1 -1
  63. package/dist/criteoBidAdapter.js +1 -1
  64. package/dist/criteoIdSystem.js +1 -1
  65. package/dist/currency.js +1 -1
  66. package/dist/cwireBidAdapter.js +1 -1
  67. package/dist/dacIdSystem.js +1 -1
  68. package/dist/dailyhuntBidAdapter.js +1 -1
  69. package/dist/datablocksBidAdapter.js +1 -1
  70. package/dist/dependencies.json +4 -1
  71. package/dist/dgkeywordRtdProvider.js +1 -1
  72. package/dist/dmdIdSystem.js +1 -1
  73. package/dist/dspxBidAdapter.js +1 -1
  74. package/dist/eplanningAnalyticsAdapter.js +1 -1
  75. package/dist/eplanningBidAdapter.js +1 -1
  76. package/dist/euidIdSystem.js +1 -1
  77. package/dist/fabrickIdSystem.js +1 -1
  78. package/dist/feedadBidAdapter.js +1 -1
  79. package/dist/finativeBidAdapter.js +1 -1
  80. package/dist/fintezaAnalyticsAdapter.js +1 -1
  81. package/dist/fledgeForGpt.js +1 -1
  82. package/dist/freewheel-sspBidAdapter.js +1 -1
  83. package/dist/genericAnalyticsAdapter.js +1 -1
  84. package/dist/geoedgeRtdProvider.js +1 -1
  85. package/dist/gmosspBidAdapter.js +1 -1
  86. package/dist/gnetBidAdapter.js +1 -1
  87. package/dist/goldbachBidAdapter.js +1 -1
  88. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  89. package/dist/greenbidsRtdProvider.js +1 -1
  90. package/dist/gridBidAdapter.js +1 -1
  91. package/dist/growthCodeAnalyticsAdapter.js +1 -1
  92. package/dist/growthCodeIdSystem.js +1 -1
  93. package/dist/growthCodeRtdProvider.js +1 -1
  94. package/dist/gumgumBidAdapter.js +1 -1
  95. package/dist/h12mediaBidAdapter.js +1 -1
  96. package/dist/hadronAnalyticsAdapter.js +1 -1
  97. package/dist/hadronIdSystem.js +1 -1
  98. package/dist/hadronRtdProvider.js +1 -1
  99. package/dist/hypelabBidAdapter.js +1 -1
  100. package/dist/iasRtdProvider.js +1 -1
  101. package/dist/id5AnalyticsAdapter.js +1 -1
  102. package/dist/id5IdSystem.js +1 -1
  103. package/dist/idImportLibrary.js +1 -1
  104. package/dist/identityLinkIdSystem.js +1 -1
  105. package/dist/imRtdProvider.js +1 -1
  106. package/dist/imdsBidAdapter.js +1 -1
  107. package/dist/impactifyBidAdapter.js +1 -1
  108. package/dist/improvedigitalBidAdapter.js +1 -1
  109. package/dist/imuIdSystem.js +1 -1
  110. package/dist/insticatorBidAdapter.js +1 -1
  111. package/dist/intentIqIdSystem.js +1 -1
  112. package/dist/invisiblyAnalyticsAdapter.js +1 -1
  113. package/dist/ixBidAdapter.js +1 -1
  114. package/dist/jixieBidAdapter.js +1 -1
  115. package/dist/justpremiumBidAdapter.js +1 -1
  116. package/dist/jwplayerRtdProvider.js +1 -1
  117. package/dist/kargoAnalyticsAdapter.js +1 -1
  118. package/dist/kargoBidAdapter.js +1 -1
  119. package/dist/kinessoIdSystem.js +1 -1
  120. package/dist/konduitAnalyticsAdapter.js +1 -1
  121. package/dist/konduitWrapper.js +1 -1
  122. package/dist/kueezBidAdapter.js +1 -1
  123. package/dist/kueezRtbBidAdapter.js +1 -1
  124. package/dist/kulturemediaBidAdapter.js +1 -1
  125. package/dist/lassoBidAdapter.js +1 -1
  126. package/dist/lifestreetBidAdapter.js +1 -1
  127. package/dist/limelightDigitalBidAdapter.js +1 -1
  128. package/dist/liveIntentAnalyticsAdapter.js +1 -1
  129. package/dist/liveIntentIdSystem.js +1 -1
  130. package/dist/livewrappedAnalyticsAdapter.js +1 -1
  131. package/dist/logicadBidAdapter.js +1 -1
  132. package/dist/loglyliftBidAdapter.js +1 -1
  133. package/dist/lotamePanoramaIdSystem.js +1 -1
  134. package/dist/luponmediaBidAdapter.js +1 -1
  135. package/dist/magniteAnalyticsAdapter.js +1 -1
  136. package/dist/malltvAnalyticsAdapter.js +1 -1
  137. package/dist/mantisBidAdapter.js +1 -1
  138. package/dist/marsmediaAnalyticsAdapter.js +1 -1
  139. package/dist/marsmediaBidAdapter.js +1 -1
  140. package/dist/mediafuseBidAdapter.js +1 -1
  141. package/dist/medianetAnalyticsAdapter.js +1 -1
  142. package/dist/mediasquareBidAdapter.js +1 -1
  143. package/dist/merkleIdSystem.js +1 -1
  144. package/dist/mgidBidAdapter.js +1 -1
  145. package/dist/mgidRtdProvider.js +1 -1
  146. package/dist/minutemediaBidAdapter.js +1 -1
  147. package/dist/minutemediaplusBidAdapter.js +1 -1
  148. package/dist/mspa.js +1 -1
  149. package/dist/mwOpenLinkIdSystem.js +1 -1
  150. package/dist/nativoBidAdapter.js +1 -1
  151. package/dist/naveggIdSystem.js +1 -1
  152. package/dist/neuwoRtdProvider.js +1 -1
  153. package/dist/nexx360BidAdapter.js +1 -1
  154. package/dist/not-for-prod/prebid.js +248 -247
  155. package/dist/novatiqIdSystem.js +1 -1
  156. package/dist/oguryBidAdapter.js +1 -1
  157. package/dist/onetagBidAdapter.js +1 -1
  158. package/dist/ooloAnalyticsAdapter.js +1 -1
  159. package/dist/open8BidAdapter.js +1 -1
  160. package/dist/operaadsBidAdapter.js +1 -1
  161. package/dist/operaadsIdSystem.js +1 -0
  162. package/dist/optidigitalBidAdapter.js +1 -1
  163. package/dist/optimeraRtdProvider.js +1 -1
  164. package/dist/outbrainBidAdapter.js +1 -1
  165. package/dist/oxxionAnalyticsAdapter.js +1 -1
  166. package/dist/oxxionRtdProvider.js +1 -1
  167. package/dist/parrableIdSystem.js +1 -1
  168. package/dist/pixfutureBidAdapter.js +1 -1
  169. package/dist/prebid-core.js +2 -2
  170. package/dist/prebidServerBidAdapter.js +1 -1
  171. package/dist/prebidmanagerAnalyticsAdapter.js +1 -1
  172. package/dist/priceFloors.js +1 -1
  173. package/dist/prismaBidAdapter.js +1 -1
  174. package/dist/pubgeniusBidAdapter.js +1 -1
  175. package/dist/publinkIdSystem.js +1 -1
  176. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  177. package/dist/pubmaticBidAdapter.js +1 -1
  178. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  179. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  180. package/dist/pxyzBidAdapter.js +1 -1
  181. package/dist/quantcastBidAdapter.js +1 -1
  182. package/dist/qwarryBidAdapter.js +1 -1
  183. package/dist/readpeakBidAdapter.js +1 -1
  184. package/dist/reconciliationRtdProvider.js +1 -1
  185. package/dist/relaidoBidAdapter.js +1 -1
  186. package/dist/relevadRtdProvider.js +1 -1
  187. package/dist/retailspotBidAdapter.js +1 -1
  188. package/dist/rhythmoneBidAdapter.js +1 -1
  189. package/dist/riseBidAdapter.js +1 -1
  190. package/dist/rivrAnalyticsAdapter.js +1 -1
  191. package/dist/roxotAnalyticsAdapter.js +1 -1
  192. package/dist/rubiconBidAdapter.js +1 -1
  193. package/dist/scaleableAnalyticsAdapter.js +1 -1
  194. package/dist/seedingAllianceBidAdapter.js +1 -1
  195. package/dist/seedtagBidAdapter.js +1 -1
  196. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  197. package/dist/sharethroughBidAdapter.js +1 -1
  198. package/dist/shinezBidAdapter.js +1 -1
  199. package/dist/silverpushBidAdapter.js +1 -1
  200. package/dist/sirdataRtdProvider.js +1 -1
  201. package/dist/slimcutBidAdapter.js +1 -1
  202. package/dist/smaatoBidAdapter.js +1 -1
  203. package/dist/smartadserverBidAdapter.js +1 -1
  204. package/dist/smartxBidAdapter.js +1 -1
  205. package/dist/smartyadsBidAdapter.js +1 -1
  206. package/dist/smilewantedBidAdapter.js +1 -1
  207. package/dist/snigelBidAdapter.js +1 -1
  208. package/dist/sonobiAnalyticsAdapter.js +1 -1
  209. package/dist/sonobiBidAdapter.js +1 -1
  210. package/dist/sovrnAnalyticsAdapter.js +1 -1
  211. package/dist/sovrnBidAdapter.js +1 -1
  212. package/dist/sspBCBidAdapter.js +1 -1
  213. package/dist/staqAnalyticsAdapter.js +1 -1
  214. package/dist/stvBidAdapter.js +1 -1
  215. package/dist/sublimeBidAdapter.js +1 -1
  216. package/dist/taboolaBidAdapter.js +1 -1
  217. package/dist/talkadsBidAdapter.js +1 -1
  218. package/dist/tapadIdSystem.js +1 -1
  219. package/dist/targetVideoBidAdapter.js +1 -1
  220. package/dist/teadsBidAdapter.js +1 -1
  221. package/dist/teadsIdSystem.js +1 -1
  222. package/dist/terceptAnalyticsAdapter.js +1 -1
  223. package/dist/timeoutRtdProvider.js +1 -1
  224. package/dist/topicsFpdModule.js +1 -1
  225. package/dist/trionBidAdapter.js +1 -1
  226. package/dist/tripleliftBidAdapter.js +1 -1
  227. package/dist/ttdBidAdapter.js +1 -1
  228. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  229. package/dist/uid2IdSystem.js +1 -1
  230. package/dist/underdogmediaBidAdapter.js +1 -1
  231. package/dist/undertoneBidAdapter.js +1 -1
  232. package/dist/unifiedIdSystem.js +1 -1
  233. package/dist/verizonMediaIdSystem.js +1 -1
  234. package/dist/vidazooBidAdapter.js +1 -1
  235. package/dist/videobyteBidAdapter.js +1 -1
  236. package/dist/visxBidAdapter.js +1 -1
  237. package/dist/vrtcalBidAdapter.js +1 -1
  238. package/dist/vuukleBidAdapter.js +1 -1
  239. package/dist/weboramaRtdProvider.js +1 -1
  240. package/dist/widespaceBidAdapter.js +1 -1
  241. package/dist/winrBidAdapter.js +1 -1
  242. package/dist/yahoosspBidAdapter.js +1 -1
  243. package/dist/yieldmoBidAdapter.js +1 -1
  244. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  245. package/dist/yuktamediaAnalyticsAdapter.js +1 -1
  246. package/dist/zeta_global_sspAnalyticsAdapter.js +1 -1
  247. package/dist/zeta_global_sspBidAdapter.js +1 -1
  248. package/integrationExamples/gpt/growthcode.html +3 -12
  249. package/integrationExamples/topics/topics-server.js +72 -0
  250. package/libraries/mspa/activityControls.js +3 -1
  251. package/modules/.submodules.json +2 -1
  252. package/modules/a1MediaRtdProvider.js +1 -1
  253. package/modules/adagioBidAdapter.js +11 -3
  254. package/modules/admaticBidAdapter.js +5 -0
  255. package/modules/adqueryBidAdapter.js +23 -21
  256. package/modules/adqueryIdSystem.js +45 -30
  257. package/modules/adrelevantisBidAdapter.js +2 -0
  258. package/modules/bidViewability.js +7 -0
  259. package/modules/bidViewability.md +9 -8
  260. package/modules/brandmetricsRtdProvider.js +30 -27
  261. package/modules/concertBidAdapter.js +1 -0
  262. package/modules/criteoBidAdapter.js +66 -43
  263. package/modules/fledgeForGpt.js +17 -4
  264. package/modules/fledgeForGpt.md +17 -10
  265. package/modules/geoedgeRtdProvider.js +44 -18
  266. package/modules/geoedgeRtdProvider.md +2 -1
  267. package/modules/growthCodeAnalyticsAdapter.js +7 -4
  268. package/modules/growthCodeAnalyticsAdapter.md +1 -7
  269. package/modules/liveIntentIdSystem.js +16 -1
  270. package/modules/nativoBidAdapter.js +21 -3
  271. package/modules/nexx360BidAdapter.js +7 -1
  272. package/modules/onetagBidAdapter.js +3 -0
  273. package/modules/operaadsBidAdapter.js +5 -0
  274. package/modules/operaadsBidAdapter.md +5 -5
  275. package/modules/operaadsIdSystem.js +106 -0
  276. package/modules/operaadsIdSystem.md +52 -0
  277. package/modules/oxxionAnalyticsAdapter.js +22 -5
  278. package/modules/prebidServerBidAdapter/index.js +8 -2
  279. package/modules/pubmaticAnalyticsAdapter.js +16 -3
  280. package/modules/rubiconBidAdapter.js +2 -2
  281. package/modules/smartyadsBidAdapter.js +18 -1
  282. package/modules/snigelBidAdapter.js +69 -16
  283. package/modules/snigelBidAdapter.md +9 -3
  284. package/modules/topicsFpdModule.js +35 -9
  285. package/modules/visxBidAdapter.js +51 -1
  286. package/package.json +2 -2
  287. package/src/adapters/bidderFactory.js +14 -5
  288. package/src/adloader.js +1 -0
  289. package/src/ajax.js +126 -87
  290. package/src/constants.json +8 -2
  291. package/src/native.js +14 -3
  292. package/test/mocks/xhr.js +256 -9
  293. package/test/spec/libraries/mspa/activityControls_spec.js +6 -0
  294. package/test/spec/modules/adagioBidAdapter_spec.js +15 -0
  295. package/test/spec/modules/adlooxAdServerVideo_spec.js +1 -5
  296. package/test/spec/modules/adlooxRtdProvider_spec.js +1 -5
  297. package/test/spec/modules/admaticBidAdapter_spec.js +5 -0
  298. package/test/spec/modules/adqueryIdSystem_spec.js +13 -24
  299. package/test/spec/modules/bidViewability_spec.js +32 -1
  300. package/test/spec/modules/brandmetricsRtdProvider_spec.js +6 -0
  301. package/test/spec/modules/categoryTranslation_spec.js +7 -9
  302. package/test/spec/modules/concertBidAdapter_spec.js +1 -1
  303. package/test/spec/modules/conversantAnalyticsAdapter_spec.js +3 -5
  304. package/test/spec/modules/criteoBidAdapter_spec.js +228 -0
  305. package/test/spec/modules/currency_spec.js +2 -2
  306. package/test/spec/modules/dmdIdSystem_spec.js +2 -2
  307. package/test/spec/modules/eids_spec.js +48 -0
  308. package/test/spec/modules/euidIdSystem_spec.js +10 -9
  309. package/test/spec/modules/feedadBidAdapter_spec.js +1 -1
  310. package/test/spec/modules/fledge_spec.js +117 -43
  311. package/test/spec/modules/geoedgeRtdProvider_spec.js +52 -39
  312. package/test/spec/modules/greenbidsRtdProvider_spec.js +3 -12
  313. package/test/spec/modules/growthCodeAnalyticsAdapter_spec.js +0 -1
  314. package/test/spec/modules/hadronIdSystem_spec.js +1 -1
  315. package/test/spec/modules/id5AnalyticsAdapter_spec.js +1 -7
  316. package/test/spec/modules/id5IdSystem_spec.js +25 -25
  317. package/test/spec/modules/identityLinkIdSystem_spec.js +0 -2
  318. package/test/spec/modules/intentIqIdSystem_spec.js +0 -2
  319. package/test/spec/modules/invisiblyAnalyticsAdapter_spec.js +2 -6
  320. package/test/spec/modules/jwplayerRtdProvider_spec.js +26 -28
  321. package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +5 -0
  322. package/test/spec/modules/liveIntentIdSystem_spec.js +5 -0
  323. package/test/spec/modules/magniteAnalyticsAdapter_spec.js +2 -2
  324. package/test/spec/modules/mgidRtdProvider_spec.js +1 -5
  325. package/test/spec/modules/nativoBidAdapter_spec.js +6 -1
  326. package/test/spec/modules/nexx360BidAdapter_spec.js +48 -1
  327. package/test/spec/modules/oguryBidAdapter_spec.js +5 -19
  328. package/test/spec/modules/onetagBidAdapter_spec.js +69 -0
  329. package/test/spec/modules/ooloAnalyticsAdapter_spec.js +1 -1
  330. package/test/spec/modules/operaadsIdSystem_spec.js +53 -0
  331. package/test/spec/modules/oxxionAnalyticsAdapter_spec.js +6 -1
  332. package/test/spec/modules/prebidServerBidAdapter_spec.js +33 -2
  333. package/test/spec/modules/priceFloors_spec.js +33 -37
  334. package/test/spec/modules/publinkIdSystem_spec.js +1 -1
  335. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +102 -18
  336. package/test/spec/modules/pubwiseAnalyticsAdapter_spec.js +2 -8
  337. package/test/spec/modules/rubiconBidAdapter_spec.js +24 -0
  338. package/test/spec/modules/smartyadsBidAdapter_spec.js +49 -0
  339. package/test/spec/modules/snigelBidAdapter_spec.js +57 -6
  340. package/test/spec/modules/teadsIdSystem_spec.js +1 -1
  341. package/test/spec/modules/topicsFpdModule_spec.js +102 -1
  342. package/test/spec/modules/uid2IdSystem_helpers.js +5 -5
  343. package/test/spec/modules/uid2IdSystem_spec.js +24 -24
  344. package/test/spec/modules/userId_spec.js +1 -1
  345. package/test/spec/modules/visxBidAdapter_spec.js +151 -1
  346. package/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +2 -5
  347. package/test/spec/native_spec.js +20 -5
  348. package/test/spec/unit/core/ajax_spec.js +403 -0
  349. package/test/spec/unit/core/bidderFactory_spec.js +80 -8
  350. package/test/spec/videoCache_spec.js +4 -4
@@ -0,0 +1,403 @@
1
+ import {dep, attachCallbacks, fetcherFactory, toFetchRequest} from '../../../../src/ajax.js';
2
+ import {config} from 'src/config.js';
3
+ import {server} from '../../../mocks/xhr.js';
4
+ import {sandbox} from 'sinon';
5
+
6
+ const EXAMPLE_URL = 'https://www.example.com';
7
+
8
+ describe('fetcherFactory', () => {
9
+ let clock;
10
+
11
+ beforeEach(() => {
12
+ clock = sinon.useFakeTimers();
13
+ server.autoTimeout = true;
14
+ });
15
+
16
+ afterEach(() => {
17
+ clock.runAll();
18
+ clock.restore();
19
+ config.resetConfig();
20
+ });
21
+
22
+ Object.entries({
23
+ 'URL': EXAMPLE_URL,
24
+ 'request object': new Request(EXAMPLE_URL)
25
+ }).forEach(([t, resource]) => {
26
+ it(`times out after timeout when fetching ${t}`, (done) => {
27
+ const fetch = fetcherFactory(1000);
28
+ const resp = fetch(resource);
29
+ clock.tick(900);
30
+ expect(server.requests[0].fetch.request.signal.aborted).to.be.false;
31
+ clock.tick(100);
32
+ expect(server.requests[0].fetch.request.signal.aborted).to.be.true;
33
+ resp.catch(() => done());
34
+ });
35
+ });
36
+
37
+ it('does not timeout after it completes', () => {
38
+ const fetch = fetcherFactory(1000);
39
+ const resp = fetch(EXAMPLE_URL);
40
+ server.requests[0].respond();
41
+ return resp.then(() => {
42
+ clock.tick(2000);
43
+ expect(server.requests[0].fetch.request.signal.aborted).to.be.false;
44
+ });
45
+ });
46
+
47
+ Object.entries({
48
+ 'disableAjaxTimeout is set'() {
49
+ const fetcher = fetcherFactory(1000);
50
+ config.setConfig({disableAjaxTimeout: true});
51
+ return fetcher;
52
+ },
53
+ 'timeout is null'() {
54
+ return fetcherFactory(null);
55
+ },
56
+ }).forEach(([t, mkFetcher]) => {
57
+ it(`does not timeout if ${t}`, (done) => {
58
+ const fetch = mkFetcher();
59
+ const pm = fetch(EXAMPLE_URL);
60
+ clock.tick(2000);
61
+ server.requests[0].respond();
62
+ pm.then(() => done());
63
+ });
64
+ });
65
+
66
+ Object.entries({
67
+ 'local URL': ['/local.html', window.origin],
68
+ 'remote URL': [EXAMPLE_URL + '/remote.html', EXAMPLE_URL],
69
+ 'request with local URL': [new Request('/local.html'), window.origin],
70
+ 'request with remote URL': [new Request(EXAMPLE_URL + '/remote.html'), EXAMPLE_URL]
71
+ }).forEach(([t, [resource, expectedOrigin]]) => {
72
+ describe(`using ${t}`, () => {
73
+ it('calls request, passing origin', () => {
74
+ const request = sinon.stub();
75
+ const fetch = fetcherFactory(1000, {request});
76
+ fetch(resource);
77
+ sinon.assert.calledWith(request, expectedOrigin);
78
+ });
79
+
80
+ Object.entries({
81
+ success: 'respond',
82
+ error: 'error'
83
+ }).forEach(([t, method]) => {
84
+ it(`calls done on ${t}, passing origin`, () => {
85
+ const done = sinon.stub();
86
+ const fetch = fetcherFactory(1000, {done});
87
+ const req = fetch(resource).catch(() => null).then(() => {
88
+ sinon.assert.calledWith(done, expectedOrigin);
89
+ });
90
+ server.requests[0][method]();
91
+ return req;
92
+ });
93
+ });
94
+ });
95
+ });
96
+ });
97
+
98
+ describe('toFetchRequest', () => {
99
+ Object.entries({
100
+ 'simple POST': {
101
+ url: EXAMPLE_URL,
102
+ data: 'data',
103
+ expect: {
104
+ request: {
105
+ url: EXAMPLE_URL + '/',
106
+ method: 'POST',
107
+ },
108
+ text: 'data',
109
+ headers: {
110
+ 'content-type': 'text/plain'
111
+ }
112
+ }
113
+ },
114
+ 'POST with headers': {
115
+ url: EXAMPLE_URL,
116
+ data: '{"json": "body"}',
117
+ options: {
118
+ contentType: 'application/json',
119
+ customHeaders: {
120
+ 'x-custom': 'value'
121
+ }
122
+ },
123
+ expect: {
124
+ request: {
125
+ url: EXAMPLE_URL + '/',
126
+ method: 'POST',
127
+ },
128
+ text: '{"json": "body"}',
129
+ headers: {
130
+ 'content-type': 'application/json',
131
+ 'X-Custom': 'value'
132
+ }
133
+ }
134
+ },
135
+ 'simple GET': {
136
+ url: EXAMPLE_URL,
137
+ data: {p1: 'v1', p2: 'v2'},
138
+ options: {
139
+ method: 'GET',
140
+ },
141
+ expect: {
142
+ request: {
143
+ url: EXAMPLE_URL + '/?p1=v1&p2=v2',
144
+ method: 'GET'
145
+ },
146
+ text: '',
147
+ headers: {
148
+ 'content-type': 'text/plain'
149
+ }
150
+ }
151
+ },
152
+ 'GET with credentials': {
153
+ url: EXAMPLE_URL,
154
+ data: null,
155
+ options: {
156
+ method: 'GET',
157
+ withCredentials: true,
158
+ },
159
+ expect: {
160
+ request: {
161
+ url: EXAMPLE_URL + '/',
162
+ method: 'GET',
163
+ credentials: 'include'
164
+ },
165
+ text: '',
166
+ headers: {
167
+ 'content-type': 'text/plain'
168
+ }
169
+ }
170
+ }
171
+ }).forEach(([t, {url, data, options, expect: {request, text, headers}}]) => {
172
+ it(`can build ${t}`, () => {
173
+ const req = toFetchRequest(url, data, options);
174
+ return req.text().then(body => {
175
+ Object.entries(request).forEach(([prop, val]) => {
176
+ expect(req[prop]).to.eql(val);
177
+ });
178
+ const hdr = new Headers(headers);
179
+ Array.from(req.headers.entries()).forEach(([name, val]) => {
180
+ expect(hdr.get(name)).to.eql(val);
181
+ });
182
+ expect(body).to.eql(text);
183
+ });
184
+ });
185
+ });
186
+
187
+ describe('browsingTopics', () => {
188
+ Object.entries({
189
+ 'browsingTopics = true': [{browsingTopics: true}, true],
190
+ 'browsingTopics = false': [{browsingTopics: false}, false],
191
+ 'browsingTopics is undef': [{}, false]
192
+ }).forEach(([t, [opts, shouldBeSet]]) => {
193
+ describe(`when options has ${t}`, () => {
194
+ const sandbox = sinon.createSandbox();
195
+ afterEach(() => {
196
+ sandbox.restore();
197
+ });
198
+
199
+ it(`should ${!shouldBeSet ? 'not ' : ''}be set when in a secure context`, () => {
200
+ sandbox.stub(window, 'isSecureContext').get(() => true);
201
+ toFetchRequest(EXAMPLE_URL, null, opts);
202
+ sinon.assert.calledWithMatch(dep.makeRequest, sinon.match.any, {browsingTopics: shouldBeSet ? true : undefined});
203
+ });
204
+ it(`should not be set when not in a secure context`, () => {
205
+ sandbox.stub(window, 'isSecureContext').get(() => false);
206
+ toFetchRequest(EXAMPLE_URL, null, opts);
207
+ sinon.assert.calledWithMatch(dep.makeRequest, sinon.match.any, {browsingTopics: undefined});
208
+ });
209
+ })
210
+ })
211
+ })
212
+ });
213
+
214
+ describe('attachCallbacks', () => {
215
+ const sampleHeaders = new Headers({
216
+ 'x-1': 'v1',
217
+ 'x-2': 'v2'
218
+ });
219
+
220
+ function responseFactory(body, props) {
221
+ props = Object.assign({headers: sampleHeaders, url: EXAMPLE_URL}, props);
222
+ return function () {
223
+ return {
224
+ response: Object.defineProperties(new Response(body, props), {
225
+ url: {
226
+ get: () => props.url
227
+ }
228
+ }),
229
+ body: body || ''
230
+ };
231
+ };
232
+ }
233
+
234
+ function expectNullXHR(response) {
235
+ return new Promise((resolve, reject) => {
236
+ attachCallbacks(Promise.resolve(response), {
237
+ success: () => {
238
+ reject(new Error('should not succeed'));
239
+ },
240
+ error(statusText, xhr) {
241
+ expect(statusText).to.eql('');
242
+ sinon.assert.match(xhr, {
243
+ readyState: XMLHttpRequest.DONE,
244
+ status: 0,
245
+ statusText: '',
246
+ responseText: '',
247
+ response: '',
248
+ responseXML: null
249
+ });
250
+ expect(xhr.getResponseHeader('any')).to.be.null;
251
+ resolve();
252
+ }
253
+ });
254
+ });
255
+ }
256
+
257
+ it('runs error callback on rejections', () => {
258
+ return expectNullXHR(Promise.reject(new Error()));
259
+ });
260
+
261
+ Object.entries({
262
+ '2xx response': {
263
+ success: true,
264
+ makeResponse: responseFactory('body', {status: 200, statusText: 'OK'})
265
+ },
266
+ '2xx response with no body': {
267
+ success: true,
268
+ makeResponse: responseFactory(null, {status: 204, statusText: 'No content'})
269
+ },
270
+ '2xx response with XML': {
271
+ success: true,
272
+ xml: true,
273
+ makeResponse: responseFactory('<?xml><root><tag /></root>', {
274
+ status: 200,
275
+ statusText: 'OK',
276
+ headers: {'content-type': 'application/xml;charset=UTF8'}
277
+ })
278
+ },
279
+ '2xx response with HTML': {
280
+ success: true,
281
+ xml: true,
282
+ makeResponse: responseFactory('<html lang="en"><p></p></html>', {
283
+ status: 200,
284
+ statusText: 'OK',
285
+ headers: {'content-type': 'text/html;charset=UTF-8'}
286
+ })
287
+ },
288
+ '304 response': {
289
+ success: true,
290
+ makeResponse: responseFactory(null, {status: 304, statusText: 'Moved permanently'})
291
+ },
292
+ '4xx response': {
293
+ success: false,
294
+ makeResponse: responseFactory('body', {status: 400, statusText: 'Invalid request'})
295
+ },
296
+ '5xx response': {
297
+ success: false,
298
+ makeResponse: responseFactory('body', {status: 503, statusText: 'Gateway error'})
299
+ },
300
+ '4xx response with XML': {
301
+ success: false,
302
+ xml: true,
303
+ makeResponse: responseFactory('<?xml><root></root>', {
304
+ status: 404,
305
+ statusText: 'Not found',
306
+ headers: {
307
+ 'content-type': 'application/xml'
308
+ }
309
+ })
310
+ }
311
+ }).forEach(([t, {success, makeResponse, xml}]) => {
312
+ const cbType = success ? 'success' : 'error';
313
+
314
+ describe(`for ${t}`, () => {
315
+ let response, body;
316
+ beforeEach(() => {
317
+ ({response, body} = makeResponse());
318
+ });
319
+
320
+ function checkXHR(xhr) {
321
+ sinon.assert.match(xhr, {
322
+ readyState: XMLHttpRequest.DONE,
323
+ status: response.status,
324
+ statusText: response.statusText,
325
+ responseType: '',
326
+ responseURL: response.url,
327
+ response: body,
328
+ responseText: body,
329
+ });
330
+ if (xml) {
331
+ expect(xhr.responseXML.querySelectorAll('*').length > 0).to.be.true;
332
+ } else {
333
+ expect(xhr.responseXML).to.not.exist;
334
+ }
335
+ Array.from(response.headers.entries()).forEach(([name, value]) => {
336
+ expect(xhr.getResponseHeader(name)).to.eql(value);
337
+ });
338
+ expect(xhr.getResponseHeader('$$missing-header')).to.be.null;
339
+ }
340
+
341
+ it(`runs ${cbType} callback`, (done) => {
342
+ attachCallbacks(Promise.resolve(response), {
343
+ success(payload, xhr) {
344
+ expect(success).to.be.true;
345
+ expect(payload).to.eql(body);
346
+ checkXHR(xhr);
347
+ done();
348
+ },
349
+ error(statusText, xhr) {
350
+ expect(success).to.be.false;
351
+ expect(statusText).to.eql(response.statusText);
352
+ checkXHR(xhr);
353
+ done();
354
+ }
355
+ });
356
+ });
357
+
358
+ it(`runs error callback if body cannot be retrieved`, () => {
359
+ response.text = () => Promise.reject(new Error());
360
+ return expectNullXHR(response);
361
+ });
362
+
363
+ if (success) {
364
+ it('accepts a single function as success callback', (done) => {
365
+ attachCallbacks(Promise.resolve(response), function (payload, xhr) {
366
+ expect(payload).to.eql(body);
367
+ checkXHR(xhr);
368
+ done();
369
+ })
370
+ })
371
+ }
372
+ });
373
+ });
374
+
375
+ describe('callback exceptions', () => {
376
+ Object.entries({
377
+ success: responseFactory(null, {status: 204}),
378
+ error: responseFactory('', {status: 400}),
379
+ }).forEach(([cbType, makeResponse]) => {
380
+ it(`do not choke ${cbType} callbacks`, () => {
381
+ const {response} = makeResponse();
382
+ return new Promise((resolve) => {
383
+ const result = {success: false, error: false};
384
+ attachCallbacks(Promise.resolve(response), {
385
+ success() {
386
+ result.success = true;
387
+ throw new Error();
388
+ },
389
+ error() {
390
+ result.error = true;
391
+ throw new Error();
392
+ }
393
+ });
394
+ setTimeout(() => resolve(result), 20);
395
+ }).then(result => {
396
+ Object.entries(result).forEach(([typ, ran]) => {
397
+ expect(ran).to.be[typ === cbType ? 'true' : 'false']
398
+ })
399
+ });
400
+ });
401
+ });
402
+ });
403
+ });
@@ -14,7 +14,7 @@ import {bidderSettings} from '../../../../src/bidderSettings.js';
14
14
  import {decorateAdUnitsWithNativeParams} from '../../../../src/native.js';
15
15
  import * as activityRules from 'src/activities/rules.js';
16
16
  import {MODULE_TYPE_BIDDER} from '../../../../src/activities/modules.js';
17
- import {ACTIVITY_TRANSMIT_TID} from '../../../../src/activities/activities.js';
17
+ import {ACTIVITY_TRANSMIT_TID, ACTIVITY_TRANSMIT_UFPD} from '../../../../src/activities/activities.js';
18
18
 
19
19
  const CODE = 'sampleBidder';
20
20
  const MOCK_BIDS_REQUEST = {
@@ -319,7 +319,7 @@ describe('bidders created by newBidder', function () {
319
319
  expect(ajaxStub.calledOnce).to.equal(true);
320
320
  expect(ajaxStub.firstCall.args[0]).to.equal(url);
321
321
  expect(ajaxStub.firstCall.args[2]).to.equal(JSON.stringify(data));
322
- expect(ajaxStub.firstCall.args[3]).to.deep.equal({
322
+ sinon.assert.match(ajaxStub.firstCall.args[3], {
323
323
  method: 'POST',
324
324
  contentType: 'text/plain',
325
325
  withCredentials: true
@@ -344,11 +344,11 @@ describe('bidders created by newBidder', function () {
344
344
  expect(ajaxStub.calledOnce).to.equal(true);
345
345
  expect(ajaxStub.firstCall.args[0]).to.equal(url);
346
346
  expect(ajaxStub.firstCall.args[2]).to.equal(JSON.stringify(data));
347
- expect(ajaxStub.firstCall.args[3]).to.deep.equal({
347
+ sinon.assert.match(ajaxStub.firstCall.args[3], {
348
348
  method: 'POST',
349
349
  contentType: 'application/json',
350
350
  withCredentials: true
351
- });
351
+ })
352
352
  });
353
353
 
354
354
  it('should make the appropriate GET request', function () {
@@ -367,10 +367,10 @@ describe('bidders created by newBidder', function () {
367
367
  expect(ajaxStub.calledOnce).to.equal(true);
368
368
  expect(ajaxStub.firstCall.args[0]).to.equal(`${url}?arg=2`);
369
369
  expect(ajaxStub.firstCall.args[2]).to.be.undefined;
370
- expect(ajaxStub.firstCall.args[3]).to.deep.equal({
370
+ sinon.assert.match(ajaxStub.firstCall.args[3], {
371
371
  method: 'GET',
372
372
  withCredentials: true
373
- });
373
+ })
374
374
  });
375
375
 
376
376
  it('should make the appropriate GET request when options are passed', function () {
@@ -391,10 +391,10 @@ describe('bidders created by newBidder', function () {
391
391
  expect(ajaxStub.calledOnce).to.equal(true);
392
392
  expect(ajaxStub.firstCall.args[0]).to.equal(`${url}?arg=2`);
393
393
  expect(ajaxStub.firstCall.args[2]).to.be.undefined;
394
- expect(ajaxStub.firstCall.args[3]).to.deep.equal({
394
+ sinon.assert.match(ajaxStub.firstCall.args[3], {
395
395
  method: 'GET',
396
396
  withCredentials: false
397
- });
397
+ })
398
398
  });
399
399
 
400
400
  it('should make multiple calls if the spec returns them', function () {
@@ -420,6 +420,78 @@ describe('bidders created by newBidder', function () {
420
420
  expect(ajaxStub.calledTwice).to.equal(true);
421
421
  });
422
422
 
423
+ describe('browsingTopics ajax option', () => {
424
+ let transmitUfpdAllowed, bidder;
425
+ beforeEach(() => {
426
+ activityRules.isActivityAllowed.reset();
427
+ activityRules.isActivityAllowed.callsFake((activity) => activity === ACTIVITY_TRANSMIT_UFPD ? transmitUfpdAllowed : true);
428
+ bidder = newBidder(spec);
429
+ spec.isBidRequestValid.returns(true);
430
+ });
431
+
432
+ it(`should be set to false when adapter sets browsingTopics = false`, () => {
433
+ transmitUfpdAllowed = true;
434
+ spec.buildRequests.returns([
435
+ {
436
+ method: 'GET',
437
+ url: 'url',
438
+ options: {
439
+ browsingTopics: false
440
+ }
441
+ }
442
+ ]);
443
+ bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
444
+ sinon.assert.calledWith(ajaxStub, 'url', sinon.match.any, sinon.match.any, sinon.match({
445
+ browsingTopics: false
446
+ }));
447
+ });
448
+
449
+ Object.entries({
450
+ 'allowed': true,
451
+ 'not allowed': false
452
+ }).forEach(([t, allow]) => {
453
+ it(`should be set to ${allow} when transmitUfpd is ${t}`, () => {
454
+ transmitUfpdAllowed = allow;
455
+ spec.buildRequests.returns([
456
+ {
457
+ method: 'GET',
458
+ url: '1',
459
+ },
460
+ {
461
+ method: 'POST',
462
+ url: '2',
463
+ data: {}
464
+ },
465
+ {
466
+ method: 'GET',
467
+ url: '3',
468
+ options: {
469
+ browsingTopics: true
470
+ }
471
+ },
472
+ {
473
+ method: 'POST',
474
+ url: '4',
475
+ data: {},
476
+ options: {
477
+ browsingTopics: true
478
+ }
479
+ }
480
+ ]);
481
+ bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
482
+ ['1', '2', '3', '4'].forEach(url => {
483
+ sinon.assert.calledWith(
484
+ ajaxStub,
485
+ url,
486
+ sinon.match.any,
487
+ sinon.match.any,
488
+ sinon.match({browsingTopics: allow})
489
+ );
490
+ });
491
+ });
492
+ });
493
+ });
494
+
423
495
  it('should not add bids for each placement code if no requests are given', function () {
424
496
  const bidder = newBidder(spec);
425
497
 
@@ -174,7 +174,7 @@ describe('The video cache', function () {
174
174
  const request = server.requests[0];
175
175
  request.method.should.equal('POST');
176
176
  request.url.should.equal('https://prebid.adnxs.com/pbc/v1/cache');
177
- request.requestHeaders['Content-Type'].should.equal('text/plain;charset=utf-8');
177
+ request.requestHeaders['Content-Type'].should.equal('text/plain');
178
178
  let payload = {
179
179
  puts: [{
180
180
  type: 'xml',
@@ -224,7 +224,7 @@ describe('The video cache', function () {
224
224
  const request = server.requests[0];
225
225
  request.method.should.equal('POST');
226
226
  request.url.should.equal('https://prebid.adnxs.com/pbc/v1/cache');
227
- request.requestHeaders['Content-Type'].should.equal('text/plain;charset=utf-8');
227
+ request.requestHeaders['Content-Type'].should.equal('text/plain');
228
228
  let payload = {
229
229
  puts: [{
230
230
  type: 'xml',
@@ -295,7 +295,7 @@ describe('The video cache', function () {
295
295
  const request = server.requests[0];
296
296
  request.method.should.equal('POST');
297
297
  request.url.should.equal('https://prebid.adnxs.com/pbc/v1/cache');
298
- request.requestHeaders['Content-Type'].should.equal('text/plain;charset=utf-8');
298
+ request.requestHeaders['Content-Type'].should.equal('text/plain');
299
299
  let payload = {
300
300
  puts: [{
301
301
  type: 'xml',
@@ -356,7 +356,7 @@ describe('The video cache', function () {
356
356
  const request = server.requests[0];
357
357
  request.method.should.equal('POST');
358
358
  request.url.should.equal('https://prebid.adnxs.com/pbc/v1/cache');
359
- request.requestHeaders['Content-Type'].should.equal('text/plain;charset=utf-8');
359
+ request.requestHeaders['Content-Type'].should.equal('text/plain');
360
360
 
361
361
  JSON.parse(request.requestBody).should.deep.equal({
362
362
  puts: [{