prebid.js 8.0.0 → 8.2.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 (232) hide show
  1. package/.devcontainer/devcontainer.json +3 -1
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/33acrossIdSystem.js +1 -1
  4. package/dist/adagioBidAdapter.js +1 -1
  5. package/dist/adbookpspBidAdapter.js +1 -1
  6. package/dist/adgenerationBidAdapter.js +1 -1
  7. package/dist/admanBidAdapter.js +1 -1
  8. package/dist/adqueryBidAdapter.js +1 -1
  9. package/dist/adrelevantisBidAdapter.js +1 -1
  10. package/dist/adtrgtmeBidAdapter.js +1 -1
  11. package/dist/adxcgBidAdapter.js +1 -1
  12. package/dist/adyoulikeBidAdapter.js +1 -1
  13. package/dist/ajaBidAdapter.js +1 -1
  14. package/dist/amxBidAdapter.js +1 -1
  15. package/dist/amxIdSystem.js +1 -1
  16. package/dist/appierAnalyticsAdapter.js +1 -1
  17. package/dist/appnexusBidAdapter.js +1 -1
  18. package/dist/asoBidAdapter.js +1 -1
  19. package/dist/axonixBidAdapter.js +1 -1
  20. package/dist/bedigitechBidAdapter.js +1 -1
  21. package/dist/beopBidAdapter.js +1 -1
  22. package/dist/bidglassBidAdapter.js +1 -1
  23. package/dist/bidwatchAnalyticsAdapter.js +1 -1
  24. package/dist/big-richmediaBidAdapter.js +1 -1
  25. package/dist/bridBidAdapter.js +1 -0
  26. package/dist/bridgewellBidAdapter.js +1 -1
  27. package/dist/brightMountainMediaBidAdapter.js +1 -1
  28. package/dist/carodaBidAdapter.js +1 -1
  29. package/dist/categoryTranslation.js +1 -1
  30. package/dist/chtnwBidAdapter.js +1 -1
  31. package/dist/cmp.js +1 -0
  32. package/dist/colossussspBidAdapter.js +1 -1
  33. package/dist/conceptxBidAdapter.js +1 -1
  34. package/dist/concertBidAdapter.js +1 -1
  35. package/dist/connectadBidAdapter.js +1 -1
  36. package/dist/consentManagement.js +1 -1
  37. package/dist/consentManagementGpp.js +1 -1
  38. package/dist/consentManagementUsp.js +1 -1
  39. package/dist/consumableBidAdapter.js +1 -1
  40. package/dist/conversantAnalyticsAdapter.js +1 -1
  41. package/dist/conversantBidAdapter.js +1 -1
  42. package/dist/craftBidAdapter.js +1 -1
  43. package/dist/criteoBidAdapter.js +1 -1
  44. package/dist/cwireBidAdapter.js +1 -1
  45. package/dist/dependencies.json +15 -0
  46. package/dist/dspxBidAdapter.js +1 -1
  47. package/dist/eplanningBidAdapter.js +1 -1
  48. package/dist/euidIdSystem.js +1 -1
  49. package/dist/feedadBidAdapter.js +1 -1
  50. package/dist/finativeBidAdapter.js +1 -1
  51. package/dist/freepassBidAdapter.js +1 -0
  52. package/dist/freewheel-sspBidAdapter.js +1 -1
  53. package/dist/gmosspBidAdapter.js +1 -1
  54. package/dist/goldbachBidAdapter.js +1 -1
  55. package/dist/gppControl_usnat.js +1 -0
  56. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  57. package/dist/greenbidsRtdProvider.js +1 -1
  58. package/dist/gridBidAdapter.js +1 -1
  59. package/dist/gumgumBidAdapter.js +1 -1
  60. package/dist/h12mediaBidAdapter.js +1 -1
  61. package/dist/hypelabBidAdapter.js +1 -1
  62. package/dist/id5IdSystem.js +1 -1
  63. package/dist/imdsBidAdapter.js +1 -1
  64. package/dist/improvedigitalBidAdapter.js +1 -1
  65. package/dist/insticatorBidAdapter.js +1 -1
  66. package/dist/intentIqIdSystem.js +1 -1
  67. package/dist/ixBidAdapter.js +1 -1
  68. package/dist/justpremiumBidAdapter.js +1 -1
  69. package/dist/kargoBidAdapter.js +1 -1
  70. package/dist/kiviadsBidAdapter.js +1 -0
  71. package/dist/konduitAnalyticsAdapter.js +1 -1
  72. package/dist/kueezBidAdapter.js +1 -1
  73. package/dist/kueezRtbBidAdapter.js +1 -1
  74. package/dist/kulturemediaBidAdapter.js +1 -1
  75. package/dist/lassoBidAdapter.js +1 -1
  76. package/dist/lifestreetBidAdapter.js +1 -1
  77. package/dist/liveIntentIdSystem.js +1 -1
  78. package/dist/logicadBidAdapter.js +1 -1
  79. package/dist/loglyliftBidAdapter.js +1 -1
  80. package/dist/magniteAnalyticsAdapter.js +1 -1
  81. package/dist/malltvAnalyticsAdapter.js +1 -1
  82. package/dist/marsmediaBidAdapter.js +1 -1
  83. package/dist/mediafuseBidAdapter.js +1 -1
  84. package/dist/mediasquareBidAdapter.js +1 -1
  85. package/dist/mgidBidAdapter.js +1 -1
  86. package/dist/mgidXBidAdapter.js +1 -0
  87. package/dist/minutemediaBidAdapter.js +1 -1
  88. package/dist/minutemediaplusBidAdapter.js +1 -1
  89. package/dist/mspa.js +1 -0
  90. package/dist/nexx360BidAdapter.js +1 -1
  91. package/dist/not-for-prod/prebid.js +146 -139
  92. package/dist/oguryBidAdapter.js +1 -1
  93. package/dist/onetagBidAdapter.js +1 -1
  94. package/dist/ooloAnalyticsAdapter.js +1 -1
  95. package/dist/optidigitalBidAdapter.js +1 -1
  96. package/dist/outbrainBidAdapter.js +1 -1
  97. package/dist/oxxionAnalyticsAdapter.js +1 -1
  98. package/dist/oxxionRtdProvider.js +1 -1
  99. package/dist/parrableIdSystem.js +1 -1
  100. package/dist/pixfutureBidAdapter.js +1 -1
  101. package/dist/prebid-core.js +1 -1
  102. package/dist/publinkIdSystem.js +1 -1
  103. package/dist/pubmaticBidAdapter.js +1 -1
  104. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  105. package/dist/pxyzBidAdapter.js +1 -1
  106. package/dist/quantcastBidAdapter.js +1 -1
  107. package/dist/readpeakBidAdapter.js +1 -1
  108. package/dist/relaidoBidAdapter.js +1 -1
  109. package/dist/retailspotBidAdapter.js +1 -1
  110. package/dist/rhythmoneBidAdapter.js +1 -1
  111. package/dist/riseBidAdapter.js +1 -1
  112. package/dist/rtbhouseBidAdapter.js +1 -1
  113. package/dist/rubiconBidAdapter.js +1 -1
  114. package/dist/seedingAllianceBidAdapter.js +1 -1
  115. package/dist/seedtagBidAdapter.js +1 -1
  116. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  117. package/dist/sharethroughBidAdapter.js +1 -1
  118. package/dist/shinezBidAdapter.js +1 -1
  119. package/dist/smaatoBidAdapter.js +1 -1
  120. package/dist/smartadserverBidAdapter.js +1 -1
  121. package/dist/smartxBidAdapter.js +1 -1
  122. package/dist/smilewantedBidAdapter.js +1 -1
  123. package/dist/sonobiBidAdapter.js +1 -1
  124. package/dist/sovrnAnalyticsAdapter.js +1 -1
  125. package/dist/sovrnBidAdapter.js +1 -1
  126. package/dist/sspBCBidAdapter.js +1 -1
  127. package/dist/stvBidAdapter.js +1 -1
  128. package/dist/sublimeBidAdapter.js +1 -1
  129. package/dist/targetVideoBidAdapter.js +1 -1
  130. package/dist/teadsBidAdapter.js +1 -1
  131. package/dist/trionBidAdapter.js +1 -1
  132. package/dist/tripleliftBidAdapter.js +1 -1
  133. package/dist/ttdBidAdapter.js +1 -1
  134. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  135. package/dist/uid2IdSystem.js +1 -1
  136. package/dist/underdogmediaBidAdapter.js +1 -1
  137. package/dist/undertoneBidAdapter.js +1 -1
  138. package/dist/userId.js +1 -1
  139. package/dist/vidazooBidAdapter.js +1 -1
  140. package/dist/videobyteBidAdapter.js +1 -1
  141. package/dist/visxBidAdapter.js +1 -1
  142. package/dist/vuukleBidAdapter.js +1 -1
  143. package/dist/widespaceBidAdapter.js +1 -1
  144. package/dist/winrBidAdapter.js +1 -1
  145. package/dist/yahoosspBidAdapter.js +1 -1
  146. package/dist/yieldmoBidAdapter.js +1 -1
  147. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  148. package/libraries/cmp/cmpClient.js +139 -0
  149. package/libraries/mspa/activityControls.js +91 -0
  150. package/modules/admanBidAdapter.js +5 -0
  151. package/modules/amxBidAdapter.js +11 -12
  152. package/modules/bedigitechBidAdapter.js +15 -12
  153. package/modules/bedigitechBidAdapter.md +2 -2
  154. package/modules/beopBidAdapter.js +0 -4
  155. package/modules/bidwatchAnalyticsAdapter.js +33 -5
  156. package/modules/bridBidAdapter.js +223 -0
  157. package/modules/categoryTranslation.js +3 -2
  158. package/modules/colossussspBidAdapter.js +9 -0
  159. package/modules/conceptxBidAdapter.js +6 -3
  160. package/modules/consentManagement.js +12 -86
  161. package/modules/consentManagementGpp.js +47 -126
  162. package/modules/consentManagementUsp.js +19 -97
  163. package/modules/freepassBidAdapter.js +98 -0
  164. package/modules/freepassBidAdapter.md +31 -0
  165. package/modules/freepassIdSystem.md +1 -1
  166. package/modules/gppControl_usnat.js +11 -0
  167. package/modules/greenbidsAnalyticsAdapter.js +7 -13
  168. package/modules/gridBidAdapter.js +3 -4
  169. package/modules/intentIqIdSystem.js +11 -9
  170. package/modules/ixBidAdapter.js +284 -55
  171. package/modules/kiviadsBidAdapter.js +212 -0
  172. package/modules/kiviadsBidAdapter.md +79 -0
  173. package/modules/liveIntentIdSystem.js +8 -3
  174. package/modules/mediasquareBidAdapter.js +19 -23
  175. package/modules/mgidXBidAdapter.js +263 -0
  176. package/modules/mgidXBidAdapter.md +79 -0
  177. package/modules/oxxionAnalyticsAdapter.js +33 -5
  178. package/modules/oxxionRtdProvider.js +124 -11
  179. package/modules/oxxionRtdProvider.md +19 -4
  180. package/modules/pubmaticBidAdapter.js +18 -2
  181. package/modules/rtbhouseBidAdapter.js +9 -2
  182. package/modules/rtbhouseBidAdapter.md +27 -8
  183. package/modules/rubiconBidAdapter.js +13 -1
  184. package/modules/sharethroughBidAdapter.js +14 -0
  185. package/modules/sonobiBidAdapter.js +4 -7
  186. package/modules/tripleliftBidAdapter.js +21 -1
  187. package/modules/userId/eids.js +29 -0
  188. package/modules/userId/eids.md +19 -2
  189. package/modules/userId/index.js +78 -29
  190. package/modules/userId/userId.md +3 -0
  191. package/package.json +1 -1
  192. package/src/activities/params.js +4 -1
  193. package/test/spec/libraries/cmp/cmpClient_spec.js +233 -0
  194. package/test/spec/libraries/mspa/activityControls_spec.js +315 -0
  195. package/test/spec/modules/admanBidAdapter_spec.js +8 -2
  196. package/test/spec/modules/adqueryBidAdapter_spec.js +5 -1
  197. package/test/spec/modules/amxBidAdapter_spec.js +6 -3
  198. package/test/spec/modules/bedigitechBidAdapter_spec.js +25 -36
  199. package/test/spec/modules/bidwatchAnalyticsAdapter_spec.js +21 -1
  200. package/test/spec/modules/bridBidAdapter_spec.js +129 -0
  201. package/test/spec/modules/byDataAnalyticsAdapter_spec.js +9 -7
  202. package/test/spec/modules/chtnwBidAdapter_spec.js +4 -1
  203. package/test/spec/modules/colossussspBidAdapter_spec.js +29 -0
  204. package/test/spec/modules/consentManagementGpp_spec.js +84 -7
  205. package/test/spec/modules/consentManagement_spec.js +8 -18
  206. package/test/spec/modules/datablocksBidAdapter_spec.js +7 -3
  207. package/test/spec/modules/eids_spec.js +87 -0
  208. package/test/spec/modules/freepassBidAdapter_spec.js +161 -0
  209. package/test/spec/modules/greenbidsAnalyticsAdapter_spec.js +0 -15
  210. package/test/spec/modules/gridBidAdapter_spec.js +29 -28
  211. package/test/spec/modules/insticatorBidAdapter_spec.js +6 -2
  212. package/test/spec/modules/intentIqIdSystem_spec.js +36 -2
  213. package/test/spec/modules/ixBidAdapter_spec.js +785 -15
  214. package/test/spec/modules/kiviadsBidAdapter_spec.js +404 -0
  215. package/test/spec/modules/lassoBidAdapter_spec.js +6 -4
  216. package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +17 -2
  217. package/test/spec/modules/liveIntentIdSystem_spec.js +11 -6
  218. package/test/spec/modules/mediasquareBidAdapter_spec.js +3 -0
  219. package/test/spec/modules/mgidXBidAdapter_spec.js +426 -0
  220. package/test/spec/modules/onetagBidAdapter_spec.js +81 -75
  221. package/test/spec/modules/orbidderBidAdapter_spec.js +6 -3
  222. package/test/spec/modules/oxxionAnalyticsAdapter_spec.js +21 -2
  223. package/test/spec/modules/oxxionRtdProvider_spec.js +113 -1
  224. package/test/spec/modules/pubmaticBidAdapter_spec.js +25 -0
  225. package/test/spec/modules/relaidoBidAdapter_spec.js +4 -3
  226. package/test/spec/modules/rtbhouseBidAdapter_spec.js +35 -0
  227. package/test/spec/modules/rubiconBidAdapter_spec.js +41 -0
  228. package/test/spec/modules/sharethroughBidAdapter_spec.js +75 -0
  229. package/test/spec/modules/sonobiBidAdapter_spec.js +15 -15
  230. package/test/spec/modules/tripleliftBidAdapter_spec.js +20 -1
  231. package/test/spec/modules/ucfunnelBidAdapter_spec.js +37 -16
  232. package/test/spec/modules/userId_spec.js +393 -6
@@ -2,7 +2,7 @@ import * as utils from 'src/utils.js';
2
2
  import { config } from 'src/config.js';
3
3
  import { expect } from 'chai';
4
4
  import { newBidder } from 'src/adapters/bidderFactory.js';
5
- import { spec, storage, ERROR_CODES, FEATURE_TOGGLES, LOCAL_STORAGE_FEATURE_TOGGLES_KEY, REQUESTED_FEATURE_TOGGLES } from '../../../modules/ixBidAdapter.js';
5
+ import { spec, storage, ERROR_CODES, FEATURE_TOGGLES, LOCAL_STORAGE_FEATURE_TOGGLES_KEY, REQUESTED_FEATURE_TOGGLES, combineImps, bidToVideoImp, bidToNativeImp, deduplicateImpExtFields, removeSiteIDs } from '../../../modules/ixBidAdapter.js';
6
6
  import { createEidsArray } from 'modules/userId/eids.js';
7
7
  import { deepAccess, deepClone } from '../../../src/utils.js';
8
8
 
@@ -387,7 +387,7 @@ describe('IndexexchangeAdapter', function () {
387
387
  },
388
388
  ortb2Imp: {
389
389
  ext: {
390
- tid: '173f49a8-7549-4218-a23c-e7ba59b47230',
390
+ tid: '273f49a8-7549-4218-a23c-e7ba59b47230',
391
391
  data: {
392
392
  pbadslot: 'div-gpt-ad-1460505748562-1'
393
393
  }
@@ -456,7 +456,7 @@ describe('IndexexchangeAdapter', function () {
456
456
  },
457
457
  ortb2Imp: {
458
458
  ext: {
459
- tid: '173f49a8-7549-4218-a23c-e7ba59b47230',
459
+ tid: '273f49a8-7549-4218-a23c-e7ba59b47230',
460
460
  data: {
461
461
  pbadslot: 'div-gpt-ad-1460505748562-0'
462
462
  }
@@ -832,6 +832,18 @@ describe('IndexexchangeAdapter', function () {
832
832
  });
833
833
 
834
834
  describe('getUserSync tests', function () {
835
+ before(() => {
836
+ // TODO (dgirardi): the assertions in this block rely on
837
+ // global state (consent and siteId) set up in the SOT
838
+ // this is an outsider's attempt to recreate that state more explicitly after shuffling around setup code
839
+ // in this test suite
840
+
841
+ // please make your preconditions explicit;
842
+ // also, please, avoid global state if possible.
843
+
844
+ spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION);
845
+ })
846
+
835
847
  it('UserSync test : check type = iframe, check usermatch URL', function () {
836
848
  const syncOptions = {
837
849
  'iframeEnabled': true
@@ -1771,16 +1783,19 @@ describe('IndexexchangeAdapter', function () {
1771
1783
  });
1772
1784
 
1773
1785
  describe('buildRequests', function () {
1774
- let request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0];
1775
- const requestUrl = request.url;
1776
- const requestMethod = request.method;
1777
- const payloadData = request.data;
1778
-
1779
1786
  const bidWithoutSchain = utils.deepClone(DEFAULT_BANNER_VALID_BID);
1780
1787
  delete bidWithoutSchain[0].schain;
1781
- const requestWithoutSchain = spec.buildRequests(bidWithoutSchain, DEFAULT_OPTION)[0];
1782
- const payloadWithoutSchain = extractPayload(requestWithoutSchain);
1783
1788
  const GPID = '/19968336/some-adunit-path';
1789
+ let request, requestUrl, requestMethod, payloadData, requestWithoutSchain, payloadWithoutSchain;
1790
+
1791
+ before(() => {
1792
+ request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0];
1793
+ requestUrl = request.url;
1794
+ requestMethod = request.method;
1795
+ payloadData = request.data;
1796
+ requestWithoutSchain = spec.buildRequests(bidWithoutSchain, DEFAULT_OPTION)[0];
1797
+ payloadWithoutSchain = extractPayload(requestWithoutSchain);
1798
+ });
1784
1799
 
1785
1800
  it('request should be made to IX endpoint with POST method and siteId in query param', function () {
1786
1801
  expect(requestMethod).to.equal('POST');
@@ -2302,7 +2317,11 @@ describe('IndexexchangeAdapter', function () {
2302
2317
  });
2303
2318
 
2304
2319
  describe('request should contain both banner and video requests', function () {
2305
- const request = spec.buildRequests([DEFAULT_BANNER_VALID_BID[0], DEFAULT_VIDEO_VALID_BID[0]], {});
2320
+ let request;
2321
+ before(() => {
2322
+ request = spec.buildRequests([DEFAULT_BANNER_VALID_BID[0], DEFAULT_VIDEO_VALID_BID[0]], {});
2323
+ });
2324
+
2306
2325
  it('should have banner request', () => {
2307
2326
  const bannerImpression = extractPayload(request[0]).imp[0];
2308
2327
  const sidValue = DEFAULT_BANNER_VALID_BID[0].params.id;
@@ -2333,7 +2352,10 @@ describe('IndexexchangeAdapter', function () {
2333
2352
  });
2334
2353
 
2335
2354
  describe('request should contain both banner and native requests', function () {
2336
- const request = spec.buildRequests([DEFAULT_BANNER_VALID_BID[0], DEFAULT_NATIVE_VALID_BID[0]]);
2355
+ let request;
2356
+ before(() => {
2357
+ request = spec.buildRequests([DEFAULT_BANNER_VALID_BID[0], DEFAULT_NATIVE_VALID_BID[0]]);
2358
+ })
2337
2359
 
2338
2360
  it('should have banner request', () => {
2339
2361
  const bannerImpression = extractPayload(request[0]).imp[0];
@@ -2541,8 +2563,11 @@ describe('IndexexchangeAdapter', function () {
2541
2563
  });
2542
2564
 
2543
2565
  describe('buildRequestVideo', function () {
2544
- const request = spec.buildRequests(DEFAULT_VIDEO_VALID_BID, DEFAULT_OPTION);
2545
- const payloadData = request[0].data;
2566
+ let request, payloadData;
2567
+ before(() => {
2568
+ request = spec.buildRequests(DEFAULT_VIDEO_VALID_BID, DEFAULT_OPTION);
2569
+ payloadData = request[0].data;
2570
+ })
2546
2571
 
2547
2572
  it('auction type should be set correctly', function () {
2548
2573
  const at = payloadData.at;
@@ -2922,7 +2947,10 @@ describe('IndexexchangeAdapter', function () {
2922
2947
 
2923
2948
  describe('both banner and video bidder params set', function () {
2924
2949
  const bids = [DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0], DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0]];
2925
- const request = spec.buildRequests(bids, {});
2950
+ let request;
2951
+ before(() => {
2952
+ request = spec.buildRequests(bids, {});
2953
+ })
2926
2954
 
2927
2955
  it('should return valid banner requests', function () {
2928
2956
  const impressions = extractPayload(request[0]).imp;
@@ -3885,6 +3913,224 @@ describe('IndexexchangeAdapter', function () {
3885
3913
  [FEATURE_TOGGLES.REQUESTED_FEATURE_TOGGLES[0]]: { activated: false }
3886
3914
  });
3887
3915
  });
3916
+
3917
+ describe('multiformat tests with enable multiformat ft enabled', () => {
3918
+ let ftStub;
3919
+ let validBids;
3920
+ beforeEach(() => {
3921
+ ftStub = sinon.stub(FEATURE_TOGGLES, 'isFeatureEnabled').callsFake((ftName) => {
3922
+ if (ftName == 'pbjs_enable_multiformat') {
3923
+ return true;
3924
+ }
3925
+ return false;
3926
+ });
3927
+ validBids = DEFAULT_MULTIFORMAT_VALID_BID;
3928
+ });
3929
+
3930
+ afterEach(() => {
3931
+ ftStub.restore();
3932
+ validBids = DEFAULT_MULTIFORMAT_VALID_BID;
3933
+ });
3934
+
3935
+ it('banner multiformat request, should generate banner imp', () => {
3936
+ const request = spec.buildRequests(DEFAULT_MULTIFORMAT_BANNER_VALID_BID, {})
3937
+ const imp = extractPayload(request[0]).imp[0];
3938
+ const bannerImpression = imp.banner
3939
+ expect(request).to.have.lengthOf(1);
3940
+ expect(extractPayload(request[0]).imp).to.have.lengthOf(1);
3941
+ expect(imp.id).to.equal(DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0].bidId);
3942
+ expect(bannerImpression.format[0].w).to.equal(DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0].params.size[0]);
3943
+ expect(bannerImpression.format[0].h).to.equal(DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0].params.size[1]);
3944
+ });
3945
+ it('should generate video impression', () => {
3946
+ const request = spec.buildRequests(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID, {});
3947
+ const imp = extractPayload(request[0]).imp[0];
3948
+ const videoImp = imp.video
3949
+ expect(request).to.have.lengthOf(1);
3950
+ expect(extractPayload(request[0]).imp).to.have.lengthOf(1);
3951
+ expect(imp.id).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].bidId);
3952
+ expect(videoImp.w).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].params.size[0]);
3953
+ expect(videoImp.h).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].params.size[1]);
3954
+ });
3955
+ it('different ad units, should only have 1 request', () => {
3956
+ const bids = [DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0], DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0]];
3957
+ const request = spec.buildRequests(bids, {});
3958
+ expect(request).to.have.lengthOf(1);
3959
+ });
3960
+ it('should return valid banner requests', function () {
3961
+ const bids = [DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0], DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0]];
3962
+ const request = spec.buildRequests(bids, {});
3963
+ const impressions = extractPayload(request[0]).imp;
3964
+ expect(impressions).to.have.lengthOf(2);
3965
+
3966
+ expect(impressions[0].id).to.equal(bids[0].bidId);
3967
+ expect(impressions[0].banner.format).to.be.length(bids[0].mediaTypes.banner.sizes.length);
3968
+ expect(impressions[0].banner.topframe).to.be.oneOf([0, 1]);
3969
+ expect(impressions[0].ext.siteID).to.equal('123');
3970
+ expect(impressions[1].ext.siteID).to.equal('456');
3971
+ impressions[0].banner.format.map(({ w, h, ext }, index) => {
3972
+ const size = bids[0].mediaTypes.banner.sizes[index];
3973
+
3974
+ expect(w).to.equal(size[0]);
3975
+ expect(h).to.equal(size[1]);
3976
+ expect(ext.siteID).to.be.undefined;
3977
+ });
3978
+
3979
+ impressions[1].banner.format.map(({ w, h, ext }, index) => {
3980
+ const size = bids[1].mediaTypes.banner.sizes[index];
3981
+
3982
+ expect(w).to.equal(size[0]);
3983
+ expect(h).to.equal(size[1]);
3984
+ expect(ext.siteID).to.be.undefined;
3985
+ });
3986
+ });
3987
+ it('banner / native multiformat request, only 1 request expect 1 imp', () => {
3988
+ const request = spec.buildRequests(DEFAULT_MULTIFORMAT_NATIVE_VALID_BID, {});
3989
+ expect(request).to.have.lengthOf(1);
3990
+ const imp = extractPayload(request[0]).imp[0];
3991
+ expect(extractPayload(request[0]).imp).to.have.lengthOf(1);
3992
+ expect(imp.banner).to.exist;
3993
+ expect(imp.native).to.exist;
3994
+ });
3995
+
3996
+ it('should return valid banner and video requests', function () {
3997
+ const bids = [DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0], DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0]];
3998
+ const request = spec.buildRequests(bids, {});
3999
+ const videoImpression = extractPayload(request[0]).imp[1];
4000
+
4001
+ expect(extractPayload(request[0]).imp).to.have.lengthOf(2);
4002
+ expect(videoImpression.id).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].bidId);
4003
+ expect(videoImpression.video.w).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].mediaTypes.video.playerSize[0][0]);
4004
+ expect(videoImpression.video.h).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].mediaTypes.video.playerSize[0][1]);
4005
+ });
4006
+
4007
+ it('multiformat banner / video - bid floors', function () {
4008
+ const bids = [DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0], DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0]];
4009
+ bids[0].params.bidFloor = 2.35;
4010
+ bids[0].params.bidFloorCur = 'USD';
4011
+ let adunitcode = bids[1].adUnitCode;
4012
+ bids[1].adUnitCode = bids[0].adUnitCode;
4013
+ bids[1].params.bidFloor = 2.05;
4014
+ bids[1].params.bidFloorCur = 'USD';
4015
+ const request = spec.buildRequests(bids, {});
4016
+
4017
+ expect(extractPayload(request[0]).imp).to.have.lengthOf(1);
4018
+ expect(extractPayload(request[0]).imp[0].bidfloor).to.equal(2.05);
4019
+ expect(extractPayload(request[0]).imp[0].bidfloorcur).to.equal('USD');
4020
+ expect(extractPayload(request[0]).imp[0].video.ext.bidfloor).to.equal(2.05);
4021
+ expect(extractPayload(request[0]).imp[0].banner.format[0].ext.bidfloor).to.equal(2.35);
4022
+ bids[1].adUnitCode = adunitcode;
4023
+ });
4024
+
4025
+ it('multiformat banner / native - bid floors', function () {
4026
+ const bids = [DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0], DEFAULT_MULTIFORMAT_NATIVE_VALID_BID[0]];
4027
+ bids[0].params.bidFloor = 2.35;
4028
+ bids[0].params.bidFloorCur = 'USD';
4029
+ let adunitcode = bids[1].adUnitCode;
4030
+ bids[1].adUnitCode = bids[0].adUnitCode;
4031
+ bids[1].params.bidFloor = 2.05;
4032
+ bids[1].params.bidFloorCur = 'USD';
4033
+ const request = spec.buildRequests(bids, {});
4034
+
4035
+ expect(extractPayload(request[0]).imp).to.have.lengthOf(1);
4036
+ expect(extractPayload(request[0]).imp[0].bidfloor).to.equal(2.05);
4037
+ expect(extractPayload(request[0]).imp[0].bidfloorcur).to.equal('USD');
4038
+ expect(extractPayload(request[0]).imp[0].native.ext.bidfloor).to.equal(2.05);
4039
+ bids[1].adUnitCode = adunitcode;
4040
+ });
4041
+
4042
+ it('multiformat banner / native - bid floors, banner imp less', function () {
4043
+ const bids = [DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0], DEFAULT_MULTIFORMAT_NATIVE_VALID_BID[0]];
4044
+ bids[0].params.bidFloor = 2.05;
4045
+ bids[0].params.bidFloorCur = 'USD';
4046
+ let tid = bids[1].transactionId;
4047
+ bids[1].transactionId = bids[0].transactionId;
4048
+ bids[1].params.bidFloor = 2.35;
4049
+ bids[1].params.bidFloorCur = 'USD';
4050
+ const request = spec.buildRequests(bids, {});
4051
+
4052
+ expect(extractPayload(request[0]).imp).to.have.lengthOf(1);
4053
+ expect(extractPayload(request[0]).imp[0].bidfloor).to.equal(2.05);
4054
+ expect(extractPayload(request[0]).imp[0].bidfloorcur).to.equal('USD');
4055
+ expect(extractPayload(request[0]).imp[0].native.ext.bidfloor).to.equal(2.35);
4056
+ bids[1].transactionId = tid;
4057
+ });
4058
+
4059
+ it('should return valid banner and video requests, different adunit, creates multiimp request', function () {
4060
+ let bid = DEFAULT_MULTIFORMAT_VALID_BID[0]
4061
+ bid.bidId = '1abcdef'
4062
+ const bids = [DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0], bid];
4063
+ const request = spec.buildRequests(bids, {});
4064
+ expect(request).to.have.lengthOf(1);
4065
+ expect(extractPayload(request[0]).imp).to.have.lengthOf(2);
4066
+ });
4067
+
4068
+ it('should return valid video requests, different adunit, creates multiimp request', function () {
4069
+ let bid = DEFAULT_BANNER_VALID_BID[0]
4070
+ bid.bidId = '1abcdef'
4071
+ const bids = [DEFAULT_VIDEO_VALID_BID[0], bid];
4072
+ const request = spec.buildRequests(bids, {});
4073
+ expect(request).to.have.lengthOf(1);
4074
+ expect(extractPayload(request[0]).imp).to.have.lengthOf(2);
4075
+ });
4076
+
4077
+ it('should contain all correct IXdiag properties', function () {
4078
+ const bids = [DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0], DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0]];
4079
+ const request = spec.buildRequests(bids, {});
4080
+ const diagObj = extractPayload(request[0]).ext.ixdiag;
4081
+ expect(diagObj.iu).to.equal(0);
4082
+ expect(diagObj.nu).to.equal(0);
4083
+ expect(diagObj.ou).to.equal(2);
4084
+ expect(diagObj.ren).to.equal(true);
4085
+ expect(diagObj.mfu).to.equal(2);
4086
+ expect(diagObj.allu).to.equal(2);
4087
+ expect(diagObj.version).to.equal('$prebid.version$');
4088
+ expect(diagObj.url).to.equal('http://localhost:9876/context.html')
4089
+ expect(diagObj.pbadslot).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].ortb2Imp.ext.data.pbadslot)
4090
+ expect(diagObj.tagid).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].params.tagId)
4091
+ expect(diagObj.adunitcode).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].adUnitCode)
4092
+ });
4093
+
4094
+ it('should use siteId override for multiformat', function () {
4095
+ validBids[0].params = {
4096
+ tagId: '123',
4097
+ siteId: '456',
4098
+ size: [300, 250],
4099
+ video: {
4100
+ siteId: '1111'
4101
+ },
4102
+ banner: {
4103
+ siteId: '2222'
4104
+ },
4105
+ native: {
4106
+ siteId: '3333'
4107
+ }
4108
+ }
4109
+ const request = spec.buildRequests(validBids, {});
4110
+ const imp = request[0].data.imp[0];
4111
+ expect(imp.ext.siteID).to.equal('2222');
4112
+ expect(imp.video.ext.siteID).to.be.undefined;
4113
+ imp.banner.format.map(({ ext }) => {
4114
+ expect(ext.siteID).to.be.undefined;
4115
+ });
4116
+ expect(imp.native.ext.siteID).to.be.undefined;
4117
+ });
4118
+
4119
+ it('should use default siteId if overrides are not provided for multiformat', function () {
4120
+ const bids = validBids;
4121
+ delete bids[0].params.banner;
4122
+ delete bids[0].params.video;
4123
+ delete bids[0].params.native;
4124
+ const request = spec.buildRequests(bids, {});
4125
+ const imp = request[0].data.imp[0]
4126
+ expect(imp.video.ext.siteID).to.be.undefined;
4127
+ imp.banner.format.map(({ ext }) => {
4128
+ expect(ext.siteID).to.be.undefined;
4129
+ });
4130
+ expect(imp.native.ext.siteID).to.be.undefined;
4131
+ expect(imp.ext.siteID).to.equal('456');
4132
+ });
4133
+ });
3888
4134
  });
3889
4135
 
3890
4136
  describe('LocalStorage error codes', () => {
@@ -4059,4 +4305,528 @@ describe('IndexexchangeAdapter', function () {
4059
4305
  expect(localStorageValues[key]).to.be.undefined;
4060
4306
  });
4061
4307
  });
4308
+ describe('combine imps test', function () {
4309
+ it('base test', function () {
4310
+ const imps = [
4311
+ {
4312
+ 'b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7': {
4313
+ 'tid': 'b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7',
4314
+ 'adUnitCode': 'div-gpt-v1',
4315
+ 'missingImps': [
4316
+ {
4317
+ 'id': '2e46cbd7d4e046',
4318
+ 'ext': {
4319
+ 'siteID': '12345'
4320
+ },
4321
+ 'banner': {
4322
+ 'w': 300,
4323
+ 'h': 250,
4324
+ 'topframe': 1
4325
+ }
4326
+ }
4327
+ ],
4328
+ 'missingCount': 1
4329
+ }
4330
+ },
4331
+ {
4332
+ 'b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7': {
4333
+ 'ixImps': [
4334
+ {
4335
+ 'id': '2e46cbd7d4e046',
4336
+ 'ext': {
4337
+ 'siteID': '12345',
4338
+ 'tid': 'b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7'
4339
+ },
4340
+ 'video': {
4341
+ 'skipppable': false,
4342
+ 'playback_methods': [
4343
+ 'auto_play_sound_off'
4344
+ ],
4345
+ 'minduration': 0,
4346
+ 'maxduration': 30,
4347
+ 'mimes': [
4348
+ 'video/mp4',
4349
+ 'video/x-flv'
4350
+ ],
4351
+ 'placement': 1,
4352
+ 'playerSize': [
4353
+ [
4354
+ 640,
4355
+ 480
4356
+ ]
4357
+ ],
4358
+ 'protocols': [
4359
+ 6
4360
+ ],
4361
+ 'w': 640,
4362
+ 'h': 480,
4363
+ 'ext': {
4364
+ 'siteID': '12345',
4365
+ 'tid': 'b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7'
4366
+ }
4367
+ }
4368
+ },
4369
+ ],
4370
+ 'adUnitCode': 'div-gpt-v1'
4371
+ }
4372
+ },
4373
+ {
4374
+ 'b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7': {
4375
+ 'tid': 'b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7',
4376
+ 'adUnitCode': 'div-gpt-v1',
4377
+ 'missingImps': [
4378
+ {
4379
+ 'id': '2e46cbd7d4e046',
4380
+ 'ext': {
4381
+ 'siteID': '12345'
4382
+ },
4383
+ 'banner': {
4384
+ 'w': 300,
4385
+ 'h': 250,
4386
+ 'topframe': 1
4387
+ }
4388
+ }
4389
+ ],
4390
+ 'missingCount': 1
4391
+ }
4392
+ }
4393
+ ]
4394
+ const result = combineImps(imps);
4395
+ expect(result['b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7'].ixImps.length).to.equal(1)
4396
+ expect(result['b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7'].missingImps.length).to.equal(2);
4397
+ });
4398
+ it('switch order', function () {
4399
+ const imps = [
4400
+ {
4401
+ 'b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7': {
4402
+ 'ixImps': [
4403
+ {
4404
+ 'id': '2e46cbd7d4e046',
4405
+ 'ext': {
4406
+ 'siteID': '12345',
4407
+ 'tid': 'b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7'
4408
+ },
4409
+ 'video': {
4410
+ 'skipppable': false,
4411
+ 'playback_methods': [
4412
+ 'auto_play_sound_off'
4413
+ ],
4414
+ 'minduration': 0,
4415
+ 'maxduration': 30,
4416
+ 'mimes': [
4417
+ 'video/mp4',
4418
+ 'video/x-flv'
4419
+ ],
4420
+ 'placement': 1,
4421
+ 'playerSize': [
4422
+ [
4423
+ 640,
4424
+ 480
4425
+ ]
4426
+ ],
4427
+ 'protocols': [
4428
+ 6
4429
+ ],
4430
+ 'w': 640,
4431
+ 'h': 480,
4432
+ 'ext': {
4433
+ 'siteID': '12345',
4434
+ 'tid': 'b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7'
4435
+ }
4436
+ }
4437
+ },
4438
+ ],
4439
+ 'adUnitCode': 'div-gpt-v1'
4440
+ }
4441
+ },
4442
+ {
4443
+ 'b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7': {
4444
+ 'tid': 'b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7',
4445
+ 'adUnitCode': 'div-gpt-v1',
4446
+ 'missingImps': [
4447
+ {
4448
+ 'id': '2e46cbd7d4e046',
4449
+ 'ext': {
4450
+ 'siteID': '12345'
4451
+ },
4452
+ 'banner': {
4453
+ 'w': 300,
4454
+ 'h': 250,
4455
+ 'topframe': 1
4456
+ }
4457
+ }
4458
+ ],
4459
+ 'missingCount': 1
4460
+ }
4461
+ }
4462
+ ]
4463
+ const result = combineImps(imps)
4464
+ expect(result['b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7'].missingImps.length).to.equal(1);
4465
+ expect(result['b8c6b5d5-76a1-4a90-b635-0c7eae1bfaa7'].ixImps.length).to.equal(1);
4466
+ });
4467
+ });
4468
+ describe('apply floors test', function () {
4469
+ it('video test', function() {
4470
+ const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]);
4471
+ bid.params.bidFloor = 50;
4472
+ bid.params.bidFloorCur = 'USD';
4473
+ const imp = bidToVideoImp(bid);
4474
+ expect(imp.video.ext.bidfloor).to.equal(50);
4475
+ expect(imp.bidfloor).to.equal(50);
4476
+ expect(imp.bidfloorcur).to.equal('USD');
4477
+ expect(imp.video.ext.fl).to.equal('x');
4478
+ });
4479
+ it('native test', function() {
4480
+ const bid = utils.deepClone(DEFAULT_NATIVE_VALID_BID[0]);
4481
+ bid.params.bidFloor = 50;
4482
+ bid.params.bidFloorCur = 'USD';
4483
+ const imp = bidToNativeImp(bid);
4484
+ expect(imp.native.ext.bidfloor).to.equal(50);
4485
+ expect(imp.bidfloor).to.equal(50);
4486
+ expect(imp.bidfloorcur).to.equal('USD');
4487
+ expect(imp.native.ext.fl).to.equal('x');
4488
+ });
4489
+ });
4490
+
4491
+ describe('deduplicateImpExtFields', () => {
4492
+ it('should remove duplicate keys from banner.ext', () => {
4493
+ const input = {
4494
+ imp: [
4495
+ {
4496
+ banner: {
4497
+ ext: {
4498
+ key1: 'value1',
4499
+ key2: 'value2',
4500
+ key3: 'value3',
4501
+ key4: 'value4', // duplicate value
4502
+ },
4503
+ },
4504
+ video: {
4505
+ ext: {
4506
+ key4: 'value4', // duplicate value
4507
+ }
4508
+ },
4509
+ ext: {
4510
+ key4: 'value4'
4511
+ }
4512
+ },
4513
+ ],
4514
+ };
4515
+
4516
+ const expectedOutput = {
4517
+ imp: [
4518
+ {
4519
+ banner: {
4520
+ ext: {
4521
+ key1: 'value1',
4522
+ key2: 'value2',
4523
+ key3: 'value3',
4524
+ },
4525
+ },
4526
+ ext: {
4527
+ key4: 'value4'
4528
+ },
4529
+ video: {
4530
+ ext: {}
4531
+ },
4532
+ },
4533
+ ],
4534
+ };
4535
+
4536
+ const result = deduplicateImpExtFields(input);
4537
+ expect(result).to.deep.equal(expectedOutput);
4538
+ });
4539
+
4540
+ it('should remove duplicate keys from banner.format[].ext', () => {
4541
+ const input = {
4542
+ imp: [
4543
+ {
4544
+ banner: {
4545
+ format: [
4546
+ {
4547
+ ext: {
4548
+ key1: 'value1',
4549
+ key2: 'value2',
4550
+ key3: 'value3',
4551
+ key4: 'value4', // duplicate value
4552
+ },
4553
+ },
4554
+ ],
4555
+ },
4556
+ video: {
4557
+ ext: {
4558
+ key4: 'value4', // duplicate value
4559
+ }
4560
+ },
4561
+ ext: {
4562
+ key4: 'value4'
4563
+ }
4564
+ },
4565
+ ],
4566
+ };
4567
+
4568
+ const expectedOutput = {
4569
+ imp: [
4570
+ {
4571
+ banner: {
4572
+ format: [
4573
+ {
4574
+ ext: {
4575
+ key1: 'value1',
4576
+ key2: 'value2',
4577
+ key3: 'value3',
4578
+ },
4579
+ },
4580
+ ],
4581
+ },
4582
+ video: {
4583
+ ext: {}
4584
+ },
4585
+ ext: {
4586
+ key4: 'value4'
4587
+ }
4588
+ },
4589
+ ],
4590
+ };
4591
+
4592
+ const result = deduplicateImpExtFields(input);
4593
+ expect(result).to.deep.equal(expectedOutput);
4594
+ });
4595
+
4596
+ it('should remove duplicate keys from video.ext', () => {
4597
+ const input = {
4598
+ imp: [
4599
+ {
4600
+ video: {
4601
+ ext: {
4602
+ key1: 'value1',
4603
+ key2: 'value2',
4604
+ key3: 'value3',
4605
+ key4: 'value4', // duplicate value
4606
+ },
4607
+ },
4608
+ banner: {
4609
+ ext: {
4610
+ key1: 'value1',
4611
+ }
4612
+ },
4613
+ ext: {
4614
+ key4: 'value4'
4615
+ }
4616
+ },
4617
+ ],
4618
+ };
4619
+
4620
+ const expectedOutput = {
4621
+ imp: [
4622
+ {
4623
+ video: {
4624
+ ext: {
4625
+ key1: 'value1',
4626
+ key2: 'value2',
4627
+ key3: 'value3',
4628
+ },
4629
+ },
4630
+ banner: {
4631
+ ext: {
4632
+ key1: 'value1',
4633
+ }
4634
+ },
4635
+ ext: {
4636
+ key4: 'value4'
4637
+ }
4638
+ },
4639
+ ],
4640
+ };
4641
+
4642
+ const result = deduplicateImpExtFields(input);
4643
+ expect(result).to.deep.equal(expectedOutput);
4644
+ });
4645
+
4646
+ it('should remove duplicate keys from native.ext', () => {
4647
+ const input = {
4648
+ imp: [
4649
+ {
4650
+ native: {
4651
+ ext: {
4652
+ key1: 'value1',
4653
+ key2: 'value2',
4654
+ key3: 'value3',
4655
+ key4: 'value4', // duplicate value
4656
+ },
4657
+ },
4658
+ banner: {
4659
+ ext: {
4660
+ key1: 'value1',
4661
+ }
4662
+ },
4663
+ ext: {
4664
+ key4: 'value4'
4665
+ }
4666
+ },
4667
+ ],
4668
+ };
4669
+
4670
+ const expectedOutput = {
4671
+ imp: [
4672
+ {
4673
+ native: {
4674
+ ext: {
4675
+ key1: 'value1',
4676
+ key2: 'value2',
4677
+ key3: 'value3',
4678
+ },
4679
+ },
4680
+ banner: {
4681
+ ext: {
4682
+ key1: 'value1',
4683
+ }
4684
+ },
4685
+ ext: {
4686
+ key4: 'value4'
4687
+ }
4688
+ }
4689
+ ],
4690
+ };
4691
+
4692
+ const result = deduplicateImpExtFields(input);
4693
+ expect(result).to.deep.equal(expectedOutput);
4694
+ });
4695
+
4696
+ it('should return the input unchanged when there is no imp.ext', () => {
4697
+ const input = {
4698
+ imp: [
4699
+ {
4700
+ banner: {
4701
+ ext: {
4702
+ key1: 'value1',
4703
+ key2: 'value2',
4704
+ key3: 'value3',
4705
+ },
4706
+ },
4707
+ video: {
4708
+ ext: {
4709
+ key4: 'value4',
4710
+ key5: 'value5',
4711
+ key6: 'value6',
4712
+ },
4713
+ },
4714
+ native: {
4715
+ ext: {
4716
+ key7: 'value7',
4717
+ key8: 'value8',
4718
+ key9: 'value9',
4719
+ },
4720
+ },
4721
+ },
4722
+ ],
4723
+ };
4724
+
4725
+ const result = deduplicateImpExtFields(input);
4726
+ expect(result).to.deep.equal(input);
4727
+ });
4728
+ });
4729
+
4730
+ describe('removeSiteIDs', () => {
4731
+ it('should remove siteIDs from banner / video / native format', () => {
4732
+ const request = {
4733
+ imp: [
4734
+ {
4735
+ banner: {
4736
+ format: [
4737
+ {
4738
+ ext: {
4739
+ siteID: '123'
4740
+ }
4741
+ },
4742
+ {
4743
+ ext: {
4744
+ siteID: '123'
4745
+ }
4746
+ }
4747
+ ],
4748
+ ext: {
4749
+ siteID: '123'
4750
+ }
4751
+ },
4752
+ video: {
4753
+ ext: {
4754
+ siteID: '123'
4755
+ }
4756
+ },
4757
+ native: {
4758
+ ext: {
4759
+ siteID: '123'
4760
+ }
4761
+ },
4762
+ ext: {
4763
+ siteID: '123'
4764
+ }
4765
+ }
4766
+ ]
4767
+ };
4768
+
4769
+ const expected = {
4770
+ ext: {
4771
+ ixdiag: {
4772
+ usid: true
4773
+ }
4774
+ },
4775
+ imp: [
4776
+ {
4777
+ banner: {
4778
+ format: [
4779
+ {
4780
+ ext: {}
4781
+ },
4782
+ {
4783
+ ext: {}
4784
+ }
4785
+ ],
4786
+ ext: {}
4787
+ },
4788
+ video: {
4789
+ ext: {}
4790
+ },
4791
+ native: {
4792
+ ext: {}
4793
+ },
4794
+ ext: {
4795
+ 'siteID': '123'
4796
+ }
4797
+ }
4798
+ ]
4799
+ };
4800
+
4801
+ expect(removeSiteIDs(request)).to.deep.equal(expected);
4802
+ });
4803
+
4804
+ it('should not modify the request when imp.ext is not present', () => {
4805
+ const request = {
4806
+ imp: [
4807
+ {
4808
+ banner: {
4809
+ ext: {
4810
+ siteID: '123'
4811
+ }
4812
+ }
4813
+ }
4814
+ ]
4815
+ };
4816
+
4817
+ const expected = {
4818
+ imp: [
4819
+ {
4820
+ banner: {
4821
+ ext: {
4822
+ siteID: '123'
4823
+ }
4824
+ },
4825
+ }
4826
+ ]
4827
+ };
4828
+
4829
+ expect(removeSiteIDs(request)).to.deep.equal(expected);
4830
+ });
4831
+ });
4062
4832
  });