prebid.js 9.7.0 → 9.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 (255) hide show
  1. package/.github/codeql/codeql-config.yml +3 -0
  2. package/.github/codeql/queries/deviceMemory.ql +14 -0
  3. package/.github/codeql/queries/hardwareConcurrency.ql +14 -0
  4. package/.github/codeql/queries/prebid.qll +36 -0
  5. package/.github/codeql/queries/qlpack.yml +8 -0
  6. package/.github/workflows/jscpd.yml +1 -1
  7. package/dist/33acrossAnalyticsAdapter.js +1 -1
  8. package/dist/33acrossBidAdapter.js +1 -1
  9. package/dist/33acrossIdSystem.js +1 -1
  10. package/dist/BTBidAdapter.js +1 -1
  11. package/dist/adagioAnalyticsAdapter.js +1 -1
  12. package/dist/adagioBidAdapter.js +1 -1
  13. package/dist/adagioUtils.js +1 -1
  14. package/dist/addefendBidAdapter.js +1 -1
  15. package/dist/adgenerationBidAdapter.js +1 -1
  16. package/dist/adlooxRtdProvider.js +1 -1
  17. package/dist/admixerBidAdapter.js +1 -1
  18. package/dist/adqueryBidAdapter.js +1 -1
  19. package/dist/adrelevantisBidAdapter.js +1 -1
  20. package/dist/adstirBidAdapter.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/adyoulikeBidAdapter.js +1 -1
  25. package/dist/agmaAnalyticsAdapter.js +1 -1
  26. package/dist/ajaBidAdapter.js +1 -1
  27. package/dist/amxBidAdapter.js +1 -1
  28. package/dist/amxIdSystem.js +1 -1
  29. package/dist/appierAnalyticsAdapter.js +1 -1
  30. package/dist/appnexusBidAdapter.js +1 -1
  31. package/dist/asoBidAdapter.js +1 -1
  32. package/dist/axonixBidAdapter.js +1 -1
  33. package/dist/bidglassBidAdapter.js +1 -1
  34. package/dist/big-richmediaBidAdapter.js +1 -1
  35. package/dist/bridBidAdapter.js +1 -1
  36. package/dist/bridgewellBidAdapter.js +1 -1
  37. package/dist/brightMountainMediaBidAdapter.js +1 -1
  38. package/dist/carodaBidAdapter.js +1 -1
  39. package/dist/ccxBidAdapter.js +1 -1
  40. package/dist/chtnwBidAdapter.js +1 -1
  41. package/dist/chunk-core.js +1 -1
  42. package/dist/concertBidAdapter.js +1 -1
  43. package/dist/connectadBidAdapter.js +1 -1
  44. package/dist/consumableBidAdapter.js +1 -1
  45. package/dist/contxtfulRtdProvider.js +1 -1
  46. package/dist/conversantAnalyticsAdapter.js +1 -1
  47. package/dist/conversantBidAdapter.js +1 -1
  48. package/dist/craftBidAdapter.js +1 -1
  49. package/dist/criteoBidAdapter.js +1 -1
  50. package/dist/cwireBidAdapter.js +1 -1
  51. package/dist/dailymotionBidAdapter.js +1 -1
  52. package/dist/dependencies.json +19 -4
  53. package/dist/discoveryBidAdapter.js +1 -1
  54. package/dist/docereeAdManagerBidAdapter.js +1 -1
  55. package/dist/dspxBidAdapter.js +1 -1
  56. package/dist/dxkultureBidAdapter.js +1 -1
  57. package/dist/eclickadsBidAdapter.js +1 -0
  58. package/dist/eightPodAnalyticsAdapter.js +1 -1
  59. package/dist/eplanningBidAdapter.js +1 -1
  60. package/dist/euidIdSystem.js +1 -1
  61. package/dist/exadsBidAdapter.js +1 -1
  62. package/dist/feedadBidAdapter.js +1 -1
  63. package/dist/finativeBidAdapter.js +1 -1
  64. package/dist/freewheel-sspBidAdapter.js +1 -1
  65. package/dist/gmosspBidAdapter.js +1 -1
  66. package/dist/goldbachBidAdapter.js +1 -1
  67. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  68. package/dist/greenbidsRtdProvider.js +1 -1
  69. package/dist/gridBidAdapter.js +1 -1
  70. package/dist/gumgumBidAdapter.js +1 -1
  71. package/dist/h12mediaBidAdapter.js +1 -1
  72. package/dist/hypelabBidAdapter.js +1 -1
  73. package/dist/id5AnalyticsAdapter.js +1 -1
  74. package/dist/id5IdSystem.js +1 -1
  75. package/dist/imdsBidAdapter.js +1 -1
  76. package/dist/improvedigitalBidAdapter.js +1 -1
  77. package/dist/insticatorBidAdapter.js +1 -1
  78. package/dist/intentIqAnalyticsAdapter.js +1 -1
  79. package/dist/ixBidAdapter.js +1 -1
  80. package/dist/jixieBidAdapter.js +1 -1
  81. package/dist/justpremiumBidAdapter.js +1 -1
  82. package/dist/kargoBidAdapter.js +1 -1
  83. package/dist/kimberliteBidAdapter.js +1 -1
  84. package/dist/konduitAnalyticsAdapter.js +1 -1
  85. package/dist/kueezBidAdapter.js +1 -1
  86. package/dist/lassoBidAdapter.js +1 -1
  87. package/dist/lifestreetBidAdapter.js +1 -1
  88. package/dist/limelightDigitalBidAdapter.js +1 -1
  89. package/dist/liveIntentIdSystem.js +1 -1
  90. package/dist/logicadBidAdapter.js +1 -1
  91. package/dist/loglyliftBidAdapter.js +1 -1
  92. package/dist/luceadBidAdapter.js +1 -1
  93. package/dist/mabidderBidAdapter.js +1 -1
  94. package/dist/magniteAnalyticsAdapter.js +1 -1
  95. package/dist/malltvAnalyticsAdapter.js +1 -1
  96. package/dist/marsmediaBidAdapter.js +1 -1
  97. package/dist/mediafuseBidAdapter.js +1 -1
  98. package/dist/mediagoBidAdapter.js +1 -1
  99. package/dist/medianetAnalyticsAdapter.js +1 -1
  100. package/dist/medianetBidAdapter.js +1 -1
  101. package/dist/mediasquareBidAdapter.js +1 -1
  102. package/dist/mgidBidAdapter.js +1 -1
  103. package/dist/mgidUtils.js +1 -0
  104. package/dist/mgidXBidAdapter.js +1 -1
  105. package/dist/missenaBidAdapter.js +1 -1
  106. package/dist/mobianRtdProvider.js +1 -1
  107. package/dist/naveggIdSystem.js +1 -1
  108. package/dist/navigatorData.js +1 -0
  109. package/dist/nexx360BidAdapter.js +1 -1
  110. package/dist/nobidAnalyticsAdapter.js +1 -1
  111. package/dist/nobidBidAdapter.js +1 -1
  112. package/dist/not-for-prod/prebid.js +174 -169
  113. package/dist/oguryBidAdapter.js +1 -1
  114. package/dist/omsBidAdapter.js +1 -1
  115. package/dist/onetagBidAdapter.js +1 -1
  116. package/dist/ooloAnalyticsAdapter.js +1 -1
  117. package/dist/openxBidAdapter.js +1 -1
  118. package/dist/optidigitalBidAdapter.js +1 -1
  119. package/dist/orbidderBidAdapter.js +1 -1
  120. package/dist/outbrainBidAdapter.js +1 -1
  121. package/dist/pixfutureBidAdapter.js +1 -1
  122. package/dist/pstudioBidAdapter.js +1 -1
  123. package/dist/publinkIdSystem.js +1 -1
  124. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  125. package/dist/pubmaticBidAdapter.js +1 -1
  126. package/dist/pubriseBidAdapter.js +1 -0
  127. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  128. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  129. package/dist/pubxaiRtdProvider.js +1 -1
  130. package/dist/pxyzBidAdapter.js +1 -1
  131. package/dist/quantcastBidAdapter.js +1 -1
  132. package/dist/readpeakBidAdapter.js +1 -1
  133. package/dist/redtramBidAdapter.js +1 -1
  134. package/dist/relaidoBidAdapter.js +1 -1
  135. package/dist/retailspotBidAdapter.js +1 -1
  136. package/dist/rhythmoneBidAdapter.js +1 -1
  137. package/dist/richaudienceBidAdapter.js +1 -1
  138. package/dist/riseUtils.js +1 -1
  139. package/dist/rubiconBidAdapter.js +1 -1
  140. package/dist/seedingAllianceBidAdapter.js +1 -1
  141. package/dist/seedtagBidAdapter.js +1 -1
  142. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  143. package/dist/sharethroughBidAdapter.js +1 -1
  144. package/dist/smaatoBidAdapter.js +1 -1
  145. package/dist/smartadserverBidAdapter.js +1 -1
  146. package/dist/smarthubBidAdapter.js +1 -1
  147. package/dist/smartxBidAdapter.js +1 -1
  148. package/dist/smilewantedBidAdapter.js +1 -1
  149. package/dist/snigelBidAdapter.js +1 -1
  150. package/dist/sonobiBidAdapter.js +1 -1
  151. package/dist/sovrnBidAdapter.js +1 -1
  152. package/dist/sspBCBidAdapter.js +1 -1
  153. package/dist/stvBidAdapter.js +1 -1
  154. package/dist/sublimeBidAdapter.js +1 -1
  155. package/dist/taboolaBidAdapter.js +1 -1
  156. package/dist/tappxBidAdapter.js +1 -1
  157. package/dist/targetVideoAdServerVideo.js +1 -0
  158. package/dist/targetVideoBidAdapter.js +1 -1
  159. package/dist/teadsBidAdapter.js +1 -1
  160. package/dist/teqblazeUtils.js +1 -1
  161. package/dist/terceptAnalyticsAdapter.js +1 -1
  162. package/dist/themoneytizerBidAdapter.js +1 -1
  163. package/dist/trionBidAdapter.js +1 -1
  164. package/dist/tripleliftBidAdapter.js +1 -1
  165. package/dist/ttdBidAdapter.js +1 -1
  166. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  167. package/dist/uid2IdSystem.js +1 -1
  168. package/dist/underdogmediaBidAdapter.js +1 -1
  169. package/dist/undertoneBidAdapter.js +1 -1
  170. package/dist/unrulyBidAdapter.js +1 -1
  171. package/dist/userId.js +1 -1
  172. package/dist/vidazooUtils.js +1 -1
  173. package/dist/videobyteBidAdapter.js +1 -1
  174. package/dist/visxBidAdapter.js +1 -1
  175. package/dist/vuukleBidAdapter.js +1 -1
  176. package/dist/widespaceBidAdapter.js +1 -1
  177. package/dist/winrBidAdapter.js +1 -1
  178. package/dist/yahooAdsBidAdapter.js +1 -1
  179. package/dist/yieldmoBidAdapter.js +1 -1
  180. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  181. package/libraries/mgidUtils/mgidUtils.js +73 -0
  182. package/{src/fpd/navigator.js → libraries/navigatorData/navigatorData.js} +1 -1
  183. package/libraries/riseUtils/index.js +1 -1
  184. package/libraries/teqblazeUtils/bidderUtils.js +1 -1
  185. package/modules/admixerBidAdapter.js +12 -5
  186. package/modules/appnexusBidAdapter.js +1 -1
  187. package/modules/ccxBidAdapter.js +6 -2
  188. package/modules/contxtfulRtdProvider.js +15 -12
  189. package/modules/cwireBidAdapter.js +13 -9
  190. package/modules/cwireBidAdapter.md +29 -10
  191. package/modules/dailymotionBidAdapter.js +1 -1
  192. package/modules/dailymotionBidAdapter.md +11 -7
  193. package/modules/discoveryBidAdapter.js +1 -3
  194. package/modules/docereeAdManagerBidAdapter.js +14 -8
  195. package/modules/eclickadsBidAdapter.js +80 -0
  196. package/modules/eclickadsBidAdapter.md +55 -0
  197. package/modules/eightPodAnalyticsAdapter.js +13 -1
  198. package/modules/gumgumBidAdapter.js +6 -2
  199. package/modules/ixBidAdapter.js +0 -1
  200. package/modules/limelightDigitalBidAdapter.js +1 -1
  201. package/modules/mediagoBidAdapter.js +2 -4
  202. package/modules/mgidBidAdapter.js +30 -109
  203. package/modules/mgidXBidAdapter.js +2 -66
  204. package/modules/mobianRtdProvider.js +12 -8
  205. package/modules/naveggIdSystem.js +62 -58
  206. package/modules/naveggIdSystem.md +8 -0
  207. package/modules/oguryBidAdapter.js +5 -2
  208. package/modules/omsBidAdapter.js +1 -1
  209. package/modules/openxBidAdapter.js +1 -6
  210. package/modules/pstudioBidAdapter.js +5 -8
  211. package/modules/pstudioBidAdapter.md +6 -4
  212. package/modules/pubriseBidAdapter.js +19 -0
  213. package/modules/pubriseBidAdapter.md +79 -0
  214. package/modules/pubxaiAnalyticsAdapter.js +9 -4
  215. package/modules/pubxaiRtdProvider.js +38 -18
  216. package/modules/pubxaiRtdProvider.md +2 -2
  217. package/modules/redtramBidAdapter.js +2 -6
  218. package/modules/richaudienceBidAdapter.js +8 -1
  219. package/modules/rubiconBidAdapter.js +3 -3
  220. package/modules/smarthubBidAdapter.js +2 -0
  221. package/modules/targetVideoAdServerVideo.js +96 -0
  222. package/modules/targetVideoAdServerVideo.md +26 -0
  223. package/modules/teadsBidAdapter.js +4 -3
  224. package/modules/undertoneBidAdapter.js +1 -19
  225. package/modules/userId/index.js +1 -1
  226. package/package.json +1 -1
  227. package/src/adRendering.js +3 -0
  228. package/src/adapterManager.js +4 -0
  229. package/src/utils/focusTimeout.js +17 -6
  230. package/src/utils/ttlCollection.js +1 -1
  231. package/src/utils.js +28 -0
  232. package/test/spec/modules/admixerBidAdapter_spec.js +2 -2
  233. package/test/spec/modules/ccxBidAdapter_spec.js +81 -0
  234. package/test/spec/modules/contxtfulRtdProvider_spec.js +19 -19
  235. package/test/spec/modules/dailymotionBidAdapter_spec.js +12 -12
  236. package/test/spec/modules/discoveryBidAdapter_spec.js +1 -47
  237. package/test/spec/modules/docereeAdManagerBidAdapter_spec.js +87 -9
  238. package/test/spec/modules/eclickadsBidAdapter_spec.js +214 -0
  239. package/test/spec/modules/ixBidAdapter_spec.js +8 -1
  240. package/test/spec/modules/mobianRtdProvider_spec.js +32 -15
  241. package/test/spec/modules/naveggIdSystem_spec.js +141 -31
  242. package/test/spec/modules/oguryBidAdapter_spec.js +50 -4
  243. package/test/spec/modules/openxBidAdapter_spec.js +16 -49
  244. package/test/spec/modules/pstudioBidAdapter_spec.js +5 -5
  245. package/test/spec/modules/pubriseBidAdapter_spec.js +514 -0
  246. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +9 -4
  247. package/test/spec/modules/pubxaiRtdProvider_spec.js +37 -5
  248. package/test/spec/modules/richaudienceBidAdapter_spec.js +62 -0
  249. package/test/spec/modules/rubiconBidAdapter_spec.js +10 -0
  250. package/test/spec/modules/targetVideoAdServerVideo_spec.js +179 -0
  251. package/test/spec/modules/trafficgateBidAdapter_spec.js +1 -1
  252. package/test/spec/ortbConverter/userId_spec.js +23 -2
  253. package/test/spec/unit/adRendering_spec.js +27 -1
  254. package/test/spec/unit/core/adapterManager_spec.js +10 -0
  255. package/test/spec/unit/utils/focusTimeout_spec.js +33 -6
@@ -35,6 +35,53 @@ describe('Richaudience adapter tests', function () {
35
35
  user: {}
36
36
  }];
37
37
 
38
+ var DEFAULT_PARAMS_NEW_DSA = [{
39
+ adUnitCode: 'test-div',
40
+ bidId: '2c7c8e9c900244',
41
+ mediaTypes: {
42
+ banner: {
43
+ sizes: [
44
+ [300, 250], [300, 600], [728, 90], [970, 250]]
45
+ }
46
+ },
47
+ bidder: 'richaudience',
48
+ params: {
49
+ bidfloor: 0.5,
50
+ pid: 'ADb1f40rmi',
51
+ supplyType: 'site',
52
+ keywords: 'key1=value1;key2=value2'
53
+ },
54
+ auctionId: '0cb3144c-d084-4686-b0d6-f5dbe917c563',
55
+ bidRequestsCount: 1,
56
+ bidderRequestId: '1858b7382993ca',
57
+ ortb2: {
58
+ regs: {
59
+ ext: {
60
+ dsa: {
61
+ dsarequired: 2,
62
+ pubrender: 1,
63
+ datatopub: 1,
64
+ transparency: [
65
+ {
66
+ domain: 'richaudience.com',
67
+ dsaparams: [1, 3, 6]
68
+ },
69
+ {
70
+ domain: 'adpone.com',
71
+ dsaparams: [8, 10, 12]
72
+ },
73
+ {
74
+ domain: 'sunmedia.com',
75
+ dsaparams: [14, 16, 18]
76
+ }
77
+ ]
78
+ }
79
+ }
80
+ }
81
+ },
82
+ user: {}
83
+ }];
84
+
38
85
  var DEFAULT_PARAMS_NEW_SIZES_GPID = [{
39
86
  adUnitCode: 'test-div',
40
87
  bidId: '2c7c8e9c900244',
@@ -893,6 +940,21 @@ describe('Richaudience adapter tests', function () {
893
940
  expect(requestContent).to.have.property('schain').to.deep.equal(schain);
894
941
  })
895
942
 
943
+ it('should pass DSA', function() {
944
+ const request = spec.buildRequests(DEFAULT_PARAMS_NEW_DSA, {
945
+ gdprConsent: {
946
+ consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA',
947
+ gdprApplies: true
948
+ },
949
+ refererInfo: {}
950
+ })
951
+ const requestContent = JSON.parse(request[0].data);
952
+ expect(requestContent).to.have.property('dsa').property('dsarequired').and.to.equal(2)
953
+ expect(requestContent).to.have.property('dsa').property('pubrender').and.to.equal(1);
954
+ expect(requestContent).to.have.property('dsa').property('datatopub').and.to.equal(1);
955
+ expect(requestContent.dsa.transparency[0]).to.have.property('domain').and.to.equal('richaudience.com');
956
+ })
957
+
896
958
  it('should pass gpid', function() {
897
959
  const request = spec.buildRequests(DEFAULT_PARAMS_NEW_SIZES_GPID, {
898
960
  gdprConsent: {
@@ -3987,6 +3987,16 @@ describe('the rubicon adapter', function () {
3987
3987
  let bids = spec.interpretResponse({body: response}, {data: request});
3988
3988
  expect(bids).to.have.nested.property('[0].native');
3989
3989
  });
3990
+ it('should set 0 to bids width and height if `w` and `h` in response object not defined', () => {
3991
+ const nativeBidderRequest = addNativeToBidRequest(bidderRequest);
3992
+ const request = converter.toORTB({bidderRequest: nativeBidderRequest, bidRequests: nativeBidderRequest.bids});
3993
+ let response = getNativeResponse({impid: request.imp[0].id});
3994
+ delete response.seatbid[0].bid[0].w;
3995
+ delete response.seatbid[0].bid[0].h
3996
+ let bids = spec.interpretResponse({body: response}, {data: request});
3997
+ expect(bids[0].width).to.equal(0);
3998
+ expect(bids[0].height).to.equal(0);
3999
+ })
3990
4000
  });
3991
4001
  }
3992
4002
 
@@ -0,0 +1,179 @@
1
+ import {expect} from 'chai';
2
+ import {buildVideoUrl} from 'modules/targetVideoAdServerVideo.js';
3
+ import {targeting} from 'src/targeting.js';
4
+ import * as utils from 'src/utils.js';
5
+ import {hook} from '../../../src/hook.js';
6
+ import AD_UNIT from 'test/fixtures/video/adUnit.json';
7
+
8
+ describe('TargetVideo Ad Server Video', function() {
9
+ before(() => {
10
+ hook.ready();
11
+ });
12
+
13
+ let sandbox, bid, adUnit;
14
+ const unitUrl = { iu: 'https://example.com/ads/bid?iu=/video' };
15
+ const unitId = { iu: '/video' };
16
+ const allTargeting = {
17
+ 'hb_format': 'video',
18
+ 'hb_source': 'client',
19
+ 'hb_size': '640x480',
20
+ 'hb_pb': '5.00',
21
+ 'hb_adid': '2c4f6cc3ba128a',
22
+ 'hb_bidder': 'testBidder2',
23
+ 'hb_format_testBidder2': 'video',
24
+ 'hb_source_testBidder2': 'client',
25
+ 'hb_size_testBidder2': '640x480',
26
+ 'hb_pb_testBidder2': '5.00',
27
+ 'hb_adid_testBidder2': '2c4f6cc3ba128a',
28
+ 'hb_bidder_testBidder2': 'testBidder2',
29
+ 'hb_format_targetVideo': 'video',
30
+ 'hb_source_targetVideo': 'client',
31
+ 'hb_size_targetVideo': '640x480',
32
+ 'hb_pb_targetVideo': '5.00',
33
+ 'hb_adid_targetVideo': '44e0b5f2e5cace',
34
+ 'hb_bidder_targetVideo': 'targetVideo'
35
+ };
36
+
37
+ beforeEach(() => {
38
+ sandbox = sinon.sandbox.create();
39
+ bid = {
40
+ videoCacheKey: '123',
41
+ adserverTargeting: {
42
+ hb_adid: 'ad_id',
43
+ hb_cache_id: '123',
44
+ hb_uuid: '123',
45
+ },
46
+ };
47
+ adUnit = utils.deepClone(AD_UNIT);
48
+ });
49
+
50
+ afterEach(() => {
51
+ sandbox.restore();
52
+ });
53
+
54
+ it('should return undefined if required properties are missing', () => {
55
+ const url1 = buildVideoUrl({ params: {} });
56
+ const url2 = buildVideoUrl({ adUnit: {} });
57
+ const url3 = buildVideoUrl({ bid: {} });
58
+
59
+ expect(url1).to.be.undefined;
60
+ expect(url2).to.be.undefined;
61
+ expect(url3).to.be.undefined;
62
+ });
63
+
64
+ it('should require options.adUnit or options.bid', () => {
65
+ const options = {
66
+ params: { ...unitUrl }
67
+ };
68
+
69
+ const getWinningBidsStub = sandbox.stub(targeting, 'getWinningBids').returns([bid]);
70
+ const getAllTargetingDataStub = sandbox.stub(targeting, 'getAllTargeting').returns(allTargeting);
71
+
72
+ const url1 = buildVideoUrl(options);
73
+ expect(url1).to.be.undefined;
74
+
75
+ const url2 = buildVideoUrl(Object.assign(options, { adUnit }));
76
+ expect(url2).to.be.string;
77
+
78
+ const url3 = buildVideoUrl(Object.assign(options, { bid }));
79
+ expect(url3).to.be.string;
80
+
81
+ getWinningBidsStub.restore();
82
+ getAllTargetingDataStub.restore();
83
+ });
84
+
85
+ it('should build URL correctly with valid parameters', () => {
86
+ const optionsUrl = {
87
+ params: { ...unitUrl }
88
+ };
89
+
90
+ const optionsId = {
91
+ params: { ...unitId }
92
+ };
93
+
94
+ const getWinningBidsStub = sandbox.stub(targeting, 'getWinningBids').returns([bid]);
95
+ const getAllTargetingDataStub = sandbox.stub(targeting, 'getAllTargeting').returns(allTargeting);
96
+
97
+ const url1 = buildVideoUrl(Object.assign(optionsUrl, { bid, adUnit }));
98
+ const url2 = buildVideoUrl(Object.assign(optionsId, { bid, adUnit }));
99
+
100
+ expect(url1).to.include('https://example.com/ads/bid?iu=/video');
101
+ expect(url1).to.include('hb_adid=ad_id');
102
+ expect(url1).to.include('hb_cache_id=123');
103
+ expect(url1).to.include('hb_uuid=123');
104
+
105
+ expect(url2).to.include('https://vid.tvserve.io/ads/bid?iu=/video');
106
+ expect(url2).to.include('hb_adid=ad_id');
107
+ expect(url2).to.include('hb_cache_id=123');
108
+ expect(url2).to.include('hb_uuid=123');
109
+
110
+ getWinningBidsStub.restore();
111
+ getAllTargetingDataStub.restore();
112
+ });
113
+
114
+ it('should include default query parameters', () => {
115
+ const options = {
116
+ params: { ...unitUrl }
117
+ };
118
+
119
+ const getWinningBidsStub = sandbox.stub(targeting, 'getWinningBids').returns([bid]);
120
+ const getAllTargetingDataStub = sandbox.stub(targeting, 'getAllTargeting').returns(allTargeting);
121
+
122
+ const url = buildVideoUrl(Object.assign(options, { bid, adUnit }));
123
+
124
+ expect(url).to.include('autoplay=[autoplay]');
125
+ expect(url).to.include('mute=[vpmute]');
126
+ expect(url).to.include('page_url=[page_url]');
127
+ expect(url).to.include('cachebuster=[timestamp]');
128
+ expect(url).to.include('consent=[consent]');
129
+
130
+ getWinningBidsStub.restore();
131
+ getAllTargetingDataStub.restore();
132
+ });
133
+
134
+ it('should add cust_params correctly', () => {
135
+ const optionsUrl = {
136
+ params: {
137
+ ...unitUrl,
138
+ cust_params: {
139
+ targeting_1: 'foo',
140
+ targeting_2: 'bar'
141
+ }
142
+ }
143
+ };
144
+
145
+ const optionsId = {
146
+ params: {
147
+ ...unitId,
148
+ cust_params: {
149
+ targeting_1: 'foo',
150
+ targeting_2: 'bar'
151
+ }
152
+ }
153
+ };
154
+
155
+ const optionsToMergeCustParams = {
156
+ params: {
157
+ iu: 'https://example.com/ads/bid?iu=/video&cust_params=targeting_1%3Dbaz',
158
+ cust_params: {
159
+ targeting_1: 'foo',
160
+ targeting_2: 'bar'
161
+ }
162
+ }
163
+ };
164
+
165
+ const getWinningBidsStub = sandbox.stub(targeting, 'getWinningBids').returns([bid]);
166
+ const getAllTargetingDataStub = sandbox.stub(targeting, 'getAllTargeting').returns(allTargeting);
167
+
168
+ const url1 = buildVideoUrl(Object.assign(optionsUrl, { bid, adUnit }));
169
+ const url2 = buildVideoUrl(Object.assign(optionsId, { bid, adUnit }));
170
+ const url3 = buildVideoUrl(Object.assign(optionsToMergeCustParams, { bid, adUnit }));
171
+
172
+ expect(url1).to.include('cust_params=targeting_1%3Dfoo%26targeting_2%3Dbar');
173
+ expect(url2).to.include('cust_params=targeting_1%3Dfoo%26targeting_2%3Dbar');
174
+ expect(url3).to.include('cust_params=targeting_1%3Dbaz%26targeting_2%3Dbar');
175
+
176
+ getWinningBidsStub.restore();
177
+ getAllTargetingDataStub.restore();
178
+ });
179
+ });
@@ -1006,7 +1006,7 @@ describe('TrafficgateOpenxRtbAdapter', function () {
1006
1006
  // enrich bid request with userId key/value
1007
1007
 
1008
1008
  const request = spec.buildRequests(bidRequestsWithUserId, mockBidderRequest);
1009
- expect(request[0].data.user.ext.eids).to.equal(userIdAsEids);
1009
+ expect(request[0].data.user.ext.eids).to.eql(userIdAsEids);
1010
1010
  });
1011
1011
 
1012
1012
  it(`when no user ids are available, it should not send any extended ids`, function () {
@@ -6,13 +6,34 @@ describe('pbjs - ortb user eids', () => {
6
6
  setOrtbUserExtEids(req, {}, {
7
7
  bidRequests: [
8
8
  {
9
- userIdAsEids: {e: 'id'}
9
+ userIdAsEids: [{e: 'id'}]
10
10
  }
11
11
  ]
12
12
  });
13
- expect(req.user.ext.eids).to.eql({e: 'id'});
13
+ expect(req.user.ext.eids).to.eql([{e: 'id'}]);
14
14
  });
15
15
 
16
+ it('should not override eids from fpd', () => {
17
+ const req = {
18
+ user: {
19
+ ext: {
20
+ eids: [{existing: 'id'}]
21
+ }
22
+ }
23
+ };
24
+ setOrtbUserExtEids(req, {}, {
25
+ bidRequests: [
26
+ {
27
+ userIdAsEids: [{nw: 'id'}]
28
+ }
29
+ ]
30
+ });
31
+ expect(req.user.ext.eids).to.eql([
32
+ {nw: 'id'},
33
+ {existing: 'id'},
34
+ ])
35
+ })
36
+
16
37
  it('has no effect if requests have no eids', () => {
17
38
  const req = {};
18
39
  setOrtbUserExtEids(req, {}, [{}]);
@@ -1,7 +1,7 @@
1
1
  import * as events from 'src/events.js';
2
2
  import * as utils from 'src/utils.js';
3
3
  import {
4
- doRender, getBidToRender,
4
+ doRender, emitAdRenderSucceeded, getBidToRender,
5
5
  getRenderingData,
6
6
  handleCreativeEvent,
7
7
  handleNativeMessage,
@@ -12,6 +12,7 @@ import {expect} from 'chai/index.mjs';
12
12
  import {config} from 'src/config.js';
13
13
  import {VIDEO} from '../../../src/mediaTypes.js';
14
14
  import {auctionManager} from '../../../src/auctionManager.js';
15
+ import adapterManager from '../../../src/adapterManager.js';
15
16
 
16
17
  describe('adRendering', () => {
17
18
  let sandbox;
@@ -267,4 +268,29 @@ describe('adRendering', () => {
267
268
  sinon.assert.calledWith(fireTrackers, data, bid);
268
269
  })
269
270
  })
271
+
272
+ describe('onAdRenderSucceeded', () => {
273
+ let mockAdapterSpec, bids;
274
+ beforeEach(() => {
275
+ mockAdapterSpec = {
276
+ onAdRenderSucceeded: sinon.stub()
277
+ };
278
+ adapterManager.bidderRegistry['mockBidder'] = {
279
+ bidder: 'mockBidder',
280
+ getSpec: function () { return mockAdapterSpec; },
281
+ };
282
+ bids = [
283
+ { bidder: 'mockBidder', params: { placementId: 'id' } },
284
+ ];
285
+ });
286
+
287
+ afterEach(function () {
288
+ delete adapterManager.bidderRegistry['mockBidder'];
289
+ });
290
+
291
+ it('should invoke onAddRenderSucceeded on emitAdRenderSucceeded', () => {
292
+ emitAdRenderSucceeded({ bid: bids[0] });
293
+ sinon.assert.called(mockAdapterSpec.onAdRenderSucceeded);
294
+ });
295
+ });
270
296
  });
@@ -428,6 +428,16 @@ describe('adapterManager tests', function () {
428
428
  sinon.assert.notCalled(criteoSpec.onBidViewable);
429
429
  })
430
430
  });
431
+
432
+ describe('onAdRenderSucceeded', function () {
433
+ beforeEach(() => {
434
+ criteoSpec.onAdRenderSucceeded = sinon.stub()
435
+ });
436
+ it('should call spec\'s onAdRenderSucceeded callback', function () {
437
+ adapterManager.callAdRenderSucceededBidder(bids[0].bidder, bids[0]);
438
+ sinon.assert.called(criteoSpec.onAdRenderSucceeded);
439
+ });
440
+ });
431
441
  })
432
442
  describe('onBidderError', function () {
433
443
  const bidder = 'appnexus';
@@ -1,4 +1,4 @@
1
- import setFocusTimeout from '../../../../src/utils/focusTimeout';
1
+ import {setFocusTimeout, reset} from '../../../../src/utils/focusTimeout';
2
2
 
3
3
  export const setDocumentHidden = (hidden) => {
4
4
  Object.defineProperty(document, 'hidden', {
@@ -9,10 +9,12 @@ export const setDocumentHidden = (hidden) => {
9
9
  };
10
10
 
11
11
  describe('focusTimeout', () => {
12
- let clock;
12
+ let clock, callback;
13
13
 
14
14
  beforeEach(() => {
15
+ reset()
15
16
  clock = sinon.useFakeTimers();
17
+ callback = sinon.spy();
16
18
  });
17
19
 
18
20
  afterEach(() => {
@@ -20,14 +22,21 @@ describe('focusTimeout', () => {
20
22
  })
21
23
 
22
24
  it('should invoke callback when page is visible', () => {
23
- let callback = sinon.stub();
24
25
  setFocusTimeout(callback, 2000);
25
26
  clock.tick(2000);
26
27
  expect(callback.called).to.be.true;
27
28
  });
28
29
 
30
+ it('should not choke if page starts hidden', () => {
31
+ setDocumentHidden(true);
32
+ reset();
33
+ setDocumentHidden(false);
34
+ setFocusTimeout(callback, 1000);
35
+ clock.tick(1000);
36
+ sinon.assert.called(callback);
37
+ })
38
+
29
39
  it('should not invoke callback if page was hidden', () => {
30
- let callback = sinon.stub();
31
40
  setFocusTimeout(callback, 2000);
32
41
  setDocumentHidden(true);
33
42
  clock.tick(3000);
@@ -35,7 +44,6 @@ describe('focusTimeout', () => {
35
44
  });
36
45
 
37
46
  it('should defer callback execution when page is hidden', () => {
38
- let callback = sinon.stub();
39
47
  setFocusTimeout(callback, 4000);
40
48
  clock.tick(2000);
41
49
  setDocumentHidden(true);
@@ -46,8 +54,27 @@ describe('focusTimeout', () => {
46
54
  expect(callback.called).to.be.true;
47
55
  });
48
56
 
57
+ it('should not execute deferred callbacks again', () => {
58
+ setDocumentHidden(true);
59
+ setFocusTimeout(callback, 1000);
60
+ clock.tick(2000);
61
+ [false, true, false].forEach(setDocumentHidden);
62
+ clock.tick(2000);
63
+ sinon.assert.calledOnce(callback);
64
+ });
65
+
66
+ it('should run callbacks that expire while page is hidden', () => {
67
+ setFocusTimeout(callback, 1000);
68
+ clock.tick(500);
69
+ setDocumentHidden(true);
70
+ clock.tick(1000);
71
+ setDocumentHidden(false);
72
+ sinon.assert.notCalled(callback);
73
+ clock.tick(1000);
74
+ sinon.assert.called(callback);
75
+ })
76
+
49
77
  it('should return updated timerId after page was showed again', () => {
50
- let callback = sinon.stub();
51
78
  const getCurrentTimerId = setFocusTimeout(callback, 4000);
52
79
  const oldTimerId = getCurrentTimerId();
53
80
  clock.tick(2000);