prebid.js 6.6.0 → 6.10.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 (271) hide show
  1. package/.eslintrc.js +8 -1
  2. package/allowedModules.js +4 -7
  3. package/integrationExamples/gpt/amp/creative.html +11 -33
  4. package/integrationExamples/gpt/{haloRtdProvider_example.html → hadronRtdProvider_example.html} +9 -9
  5. package/integrationExamples/gpt/idImportLibrary_example.html +2 -2
  6. package/integrationExamples/gpt/userId_example.html +2 -2
  7. package/integrationExamples/gpt/weboramaRtdProvider_example.html +154 -115
  8. package/integrationExamples/gpt/x-domain/creative.html +63 -29
  9. package/modules/.submodules.json +3 -0
  10. package/modules/adagioBidAdapter.js +1 -9
  11. package/modules/adagioBidAdapter.md +1 -1
  12. package/modules/adbookpspBidAdapter.js +29 -12
  13. package/modules/adhashBidAdapter.js +4 -4
  14. package/modules/adkernelBidAdapter.js +2 -2
  15. package/modules/adlooxAnalyticsAdapter.js +1 -1
  16. package/modules/adlooxRtdProvider.js +1 -1
  17. package/modules/adnowBidAdapter.js +1 -1
  18. package/modules/adnuntiusRtdProvider.js +96 -0
  19. package/modules/adnuntiusRtdProvider.md +41 -0
  20. package/modules/adomikAnalyticsAdapter.js +2 -2
  21. package/modules/adotBidAdapter.js +1 -1
  22. package/modules/adpod.js +14 -17
  23. package/modules/adrelevantisBidAdapter.js +2 -2
  24. package/modules/adtargetBidAdapter.js +1 -1
  25. package/modules/adtelligentBidAdapter.js +1 -1
  26. package/modules/advangelistsBidAdapter.js +2 -2
  27. package/modules/adxpremiumAnalyticsAdapter.js +1 -1
  28. package/modules/adyoulikeBidAdapter.js +1 -1
  29. package/modules/afpBidAdapter.js +1 -1
  30. package/modules/appnexusBidAdapter.js +16 -4
  31. package/modules/asealBidAdapter.js +58 -0
  32. package/modules/asealBidAdapter.md +52 -0
  33. package/modules/beachfrontBidAdapter.js +2 -2
  34. package/modules/betweenBidAdapter.js +1 -1
  35. package/modules/bidViewability.js +1 -1
  36. package/modules/bluebillywigBidAdapter.js +1 -1
  37. package/modules/brandmetricsRtdProvider.js +168 -0
  38. package/modules/brandmetricsRtdProvider.md +40 -0
  39. package/modules/bridgewellBidAdapter.js +1 -1
  40. package/modules/browsiRtdProvider.js +2 -2
  41. package/modules/cleanmedianetBidAdapter.js +1 -1
  42. package/modules/colossussspBidAdapter.js +12 -8
  43. package/modules/colossussspBidAdapter.md +15 -1
  44. package/modules/compassBidAdapter.js +1 -1
  45. package/modules/connectIdSystem.js +1 -1
  46. package/modules/consentManagement.js +2 -3
  47. package/modules/consumableBidAdapter.md +1 -1
  48. package/modules/conversantBidAdapter.js +7 -0
  49. package/modules/craftBidAdapter.js +2 -2
  50. package/modules/criteoBidAdapter.js +10 -1
  51. package/modules/currency.js +27 -5
  52. package/modules/cwireBidAdapter.js +1 -1
  53. package/modules/dailyhuntBidAdapter.js +1 -1
  54. package/modules/dchain.js +1 -1
  55. package/modules/displayioBidAdapter.js +157 -0
  56. package/modules/displayioBidAdapter.md +148 -0
  57. package/modules/dspxBidAdapter.js +69 -29
  58. package/modules/dspxBidAdapter.md +2 -1
  59. package/modules/e_volutionBidAdapter.js +158 -0
  60. package/modules/emx_digitalBidAdapter.js +2 -2
  61. package/modules/fluctBidAdapter.js +0 -1
  62. package/modules/gamoshiBidAdapter.js +1 -1
  63. package/modules/gdprEnforcement.js +2 -2
  64. package/modules/glomexBidAdapter.js +1 -1
  65. package/modules/gnetBidAdapter.js +3 -3
  66. package/modules/gnetBidAdapter.md +4 -4
  67. package/modules/goldbachBidAdapter.js +2 -2
  68. package/modules/gptPreAuction.js +1 -1
  69. package/modules/gridBidAdapter.js +15 -1
  70. package/modules/gumgumBidAdapter.js +57 -43
  71. package/modules/hadronIdSystem.js +96 -0
  72. package/modules/hadronIdSystem.md +35 -0
  73. package/modules/hadronRtdProvider.js +254 -0
  74. package/modules/hadronRtdProvider.md +126 -0
  75. package/modules/haloIdSystem.md +4 -35
  76. package/modules/haloRtdProvider.md +3 -126
  77. package/modules/hybridBidAdapter.js +1 -1
  78. package/modules/improvedigitalBidAdapter.js +6 -1
  79. package/modules/insticatorBidAdapter.js +1 -1
  80. package/modules/interactiveOffersBidAdapter.js +9 -6
  81. package/modules/intersectionRtdProvider.js +1 -1
  82. package/modules/ixBidAdapter.js +2 -2
  83. package/modules/jwplayerRtdProvider.js +72 -7
  84. package/modules/jwplayerRtdProvider.md +27 -11
  85. package/modules/kargoBidAdapter.js +2 -2
  86. package/modules/livewrappedBidAdapter.js +1 -1
  87. package/modules/lunamediahbBidAdapter.js +32 -4
  88. package/modules/malltvBidAdapter.js +7 -3
  89. package/modules/malltvBidAdapter.md +64 -51
  90. package/modules/mass.js +3 -5
  91. package/modules/mediakeysBidAdapter.js +2 -2
  92. package/modules/medianetAnalyticsAdapter.js +2 -2
  93. package/modules/medianetRtdProvider.js +1 -1
  94. package/modules/mediasquareBidAdapter.js +1 -0
  95. package/modules/nextMillenniumBidAdapter.js +1 -0
  96. package/modules/nextrollBidAdapter.js +1 -1
  97. package/modules/oguryBidAdapter.js +7 -14
  98. package/modules/onetagBidAdapter.js +1 -1
  99. package/modules/openwebBidAdapter.js +1 -1
  100. package/modules/openxAnalyticsAdapter.js +2 -2
  101. package/modules/openxBidAdapter.js +1 -1
  102. package/modules/parrableIdSystem.js +1 -1
  103. package/modules/permutiveRtdProvider.js +1 -1
  104. package/modules/pilotxBidAdapter.js +147 -0
  105. package/modules/pilotxBidAdapter.md +50 -0
  106. package/modules/pixfutureBidAdapter.js +2 -2
  107. package/modules/prebidServerBidAdapter/index.js +63 -41
  108. package/modules/priceFloors.js +15 -14
  109. package/modules/pubmaticBidAdapter.js +1 -1
  110. package/modules/quantcastBidAdapter.js +1 -1
  111. package/modules/reconciliationRtdProvider.js +1 -1
  112. package/modules/richaudienceBidAdapter.js +7 -2
  113. package/modules/riseBidAdapter.js +17 -6
  114. package/modules/roxotAnalyticsAdapter.js +1 -1
  115. package/modules/rtbhouseBidAdapter.js +1 -1
  116. package/modules/rtdModule/index.js +9 -11
  117. package/modules/rubiconAnalyticsAdapter.js +8 -2
  118. package/modules/rubiconBidAdapter.js +1 -1
  119. package/modules/saambaaBidAdapter.js +420 -420
  120. package/modules/seedingAllianceBidAdapter.js +3 -3
  121. package/modules/sharethroughBidAdapter.js +12 -17
  122. package/modules/sigmoidAnalyticsAdapter.js +1 -1
  123. package/modules/sirdataRtdProvider.js +1 -1
  124. package/modules/sizeMappingV2.js +2 -9
  125. package/modules/smarticoBidAdapter.js +1 -1
  126. package/modules/sortableAnalyticsAdapter.js +5 -4
  127. package/modules/sovrnAnalyticsAdapter.js +2 -2
  128. package/modules/sovrnBidAdapter.js +93 -18
  129. package/modules/sovrnBidAdapter.md +80 -2
  130. package/modules/sspBCBidAdapter.js +54 -21
  131. package/modules/synacormediaBidAdapter.js +32 -11
  132. package/modules/targetVideoBidAdapter.js +1 -1
  133. package/modules/telariaBidAdapter.js +22 -29
  134. package/modules/trustpidSystem.js +197 -0
  135. package/modules/trustpidSystem.md +45 -0
  136. package/modules/undertoneBidAdapter.js +17 -1
  137. package/modules/userId/eids.js +16 -1
  138. package/modules/userId/eids.md +10 -2
  139. package/modules/userId/index.js +2 -2
  140. package/modules/userId/userId.md +17 -2
  141. package/modules/ventesBidAdapter.js +1 -1
  142. package/modules/verizonMediaIdSystem.js +1 -1
  143. package/modules/vibrantmediaBidAdapter.js +220 -0
  144. package/modules/vibrantmediaBidAdapter.md +92 -0
  145. package/modules/viewability.js +177 -0
  146. package/modules/viewability.md +87 -0
  147. package/modules/viewdeosDXBidAdapter.js +1 -1
  148. package/modules/voxBidAdapter.js +1 -1
  149. package/modules/waardexBidAdapter.js +1 -1
  150. package/modules/weboramaRtdProvider.js +264 -34
  151. package/modules/weboramaRtdProvider.md +110 -40
  152. package/modules/widespaceBidAdapter.js +2 -2
  153. package/modules/winrBidAdapter.js +7 -7
  154. package/modules/yahoosspBidAdapter.js +3 -1
  155. package/modules/yieldlabBidAdapter.js +1 -1
  156. package/modules/yieldmoBidAdapter.js +2 -2
  157. package/modules/yieldoneBidAdapter.js +6 -0
  158. package/modules/yuktamediaAnalyticsAdapter.js +1 -1
  159. package/package.json +3 -1
  160. package/plugins/poly/arrayFrom.js +3 -0
  161. package/plugins/poly/find.js +3 -0
  162. package/plugins/poly/findIndex.js +3 -0
  163. package/plugins/poly/includes.js +3 -0
  164. package/plugins/poly/package.json +8 -0
  165. package/src/Renderer.js +1 -1
  166. package/src/adRendering.js +38 -0
  167. package/src/adapterManager.js +33 -28
  168. package/src/adapters/bidderFactory.js +13 -11
  169. package/src/adloader.js +3 -2
  170. package/src/auction.js +140 -117
  171. package/src/auctionIndex.js +85 -0
  172. package/src/auctionManager.js +4 -1
  173. package/src/bidderSettings.js +69 -0
  174. package/src/bidfactory.js +18 -6
  175. package/src/config.js +3 -4
  176. package/src/cpmBucketManager.js +1 -1
  177. package/src/native.js +30 -22
  178. package/src/prebid.js +4 -20
  179. package/src/secureCreatives.js +133 -49
  180. package/src/sizeMapping.js +1 -1
  181. package/src/storageManager.js +1 -1
  182. package/src/targeting.js +13 -4
  183. package/src/userSync.js +1 -1
  184. package/src/utils.js +16 -19
  185. package/src/video.js +11 -12
  186. package/src/videoCache.js +10 -9
  187. package/test/fixtures/fixtures.js +2 -1
  188. package/test/helpers/indexStub.js +28 -0
  189. package/test/helpers/syncPromise.js +71 -0
  190. package/test/spec/auctionmanager_spec.js +269 -90
  191. package/test/spec/config_spec.js +24 -1
  192. package/test/spec/e2e/longform/basic_w_bidderSettings.spec.js +1 -1
  193. package/test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js +1 -1
  194. package/test/spec/e2e/longform/basic_w_priceGran.spec.js +1 -1
  195. package/test/spec/e2e/longform/basic_w_requireExactDuration.spec.js +1 -1
  196. package/test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js +1 -1
  197. package/test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js +1 -1
  198. package/test/spec/modules/adagioBidAdapter_spec.js +0 -10
  199. package/test/spec/modules/adbookpspBidAdapter_spec.js +17 -3
  200. package/test/spec/modules/adhashBidAdapter_spec.js +2 -2
  201. package/test/spec/modules/adnuntiusRtdProvider_spec.js +145 -0
  202. package/test/spec/modules/adpod_spec.js +91 -156
  203. package/test/spec/modules/afpBidAdapter_spec.js +1 -1
  204. package/test/spec/modules/appnexusBidAdapter_spec.js +27 -0
  205. package/test/spec/modules/asealBidAdapter_spec.js +144 -0
  206. package/test/spec/modules/brandmetricsRtdProvider_spec.js +191 -0
  207. package/test/spec/modules/colossussspBidAdapter_spec.js +5 -2
  208. package/test/spec/modules/conversantBidAdapter_spec.js +54 -2
  209. package/test/spec/modules/criteoBidAdapter_spec.js +21 -0
  210. package/test/spec/modules/currency_spec.js +36 -15
  211. package/test/spec/modules/deepintentDpesIdsystem_spec.js +1 -1
  212. package/test/spec/modules/displayioBidAdapter_spec.js +239 -0
  213. package/test/spec/modules/dspxBidAdapter_spec.js +20 -15
  214. package/test/spec/modules/e_volutionBidAdapter_spec.js +242 -0
  215. package/test/spec/modules/eids_spec.js +2 -2
  216. package/test/spec/modules/eplanningAnalyticsAdapter_spec.js +1 -1
  217. package/test/spec/modules/fintezaAnalyticsAdapter_spec.js +1 -1
  218. package/test/spec/modules/gnetBidAdapter_spec.js +6 -6
  219. package/test/spec/modules/gridBidAdapter_spec.js +18 -0
  220. package/test/spec/modules/gumgumBidAdapter_spec.js +49 -3
  221. package/test/spec/modules/hadronIdSystem_spec.js +57 -0
  222. package/test/spec/modules/hadronRtdProvider_spec.js +762 -0
  223. package/test/spec/modules/idxIdSystem_spec.js +1 -1
  224. package/test/spec/modules/improvedigitalBidAdapter_spec.js +19 -0
  225. package/test/spec/modules/jwplayerRtdProvider_spec.js +195 -2
  226. package/test/spec/modules/kargoBidAdapter_spec.js +1 -1
  227. package/test/spec/modules/lunamediahbBidAdapter_spec.js +27 -1
  228. package/test/spec/modules/mass_spec.js +2 -14
  229. package/test/spec/modules/mediakeysBidAdapter_spec.js +1 -1
  230. package/test/spec/modules/multibid_spec.js +1 -1
  231. package/test/spec/modules/oguryBidAdapter_spec.js +63 -5
  232. package/test/spec/modules/onetagBidAdapter_spec.js +1 -1
  233. package/test/spec/modules/openxAnalyticsAdapter_spec.js +1 -1
  234. package/test/spec/modules/parrableIdSystem_spec.js +1 -1
  235. package/test/spec/modules/pilotxBidAdapter_spec.js +244 -0
  236. package/test/spec/modules/prebidServerBidAdapter_spec.js +43 -6
  237. package/test/spec/modules/priceFloors_spec.js +37 -24
  238. package/test/spec/modules/pubmaticBidAdapter_spec.js +40 -0
  239. package/test/spec/modules/realTimeDataModule_spec.js +51 -2
  240. package/test/spec/modules/riseBidAdapter_spec.js +30 -4
  241. package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +61 -1
  242. package/test/spec/modules/rubiconBidAdapter_spec.js +1 -1
  243. package/test/spec/modules/sharethroughBidAdapter_spec.js +91 -6
  244. package/test/spec/modules/sortableAnalyticsAdapter_spec.js +2 -3
  245. package/test/spec/modules/sovrnBidAdapter_spec.js +413 -333
  246. package/test/spec/modules/sspBCBidAdapter_spec.js +7 -7
  247. package/test/spec/modules/stroeerCoreBidAdapter_spec.js +1 -1
  248. package/test/spec/modules/synacormediaBidAdapter_spec.js +70 -0
  249. package/test/spec/modules/telariaBidAdapter_spec.js +1 -3
  250. package/test/spec/modules/trustpidSystem_spec.js +232 -0
  251. package/test/spec/modules/undertoneBidAdapter_spec.js +55 -2
  252. package/test/spec/modules/userId_spec.js +40 -40
  253. package/test/spec/modules/vibrantmediaBidAdapter_spec.js +1237 -0
  254. package/test/spec/modules/viewability_spec.js +280 -0
  255. package/test/spec/modules/weboramaRtdProvider_spec.js +536 -20
  256. package/test/spec/modules/widespaceBidAdapter_spec.js +1 -1
  257. package/test/spec/modules/yahoosspBidAdapter_spec.js +10 -0
  258. package/test/spec/modules/yieldoneBidAdapter_spec.js +33 -0
  259. package/test/spec/modules/zeotapIdPlusIdSystem_spec.js +1 -1
  260. package/test/spec/native_spec.js +62 -40
  261. package/test/spec/sizeMapping_spec.js +1 -1
  262. package/test/spec/unit/core/adapterManager_spec.js +24 -2
  263. package/test/spec/unit/core/auctionIndex_spec.js +129 -0
  264. package/test/spec/unit/core/bidderFactory_spec.js +65 -12
  265. package/test/spec/unit/core/bidderSettings_spec.js +123 -0
  266. package/test/spec/unit/core/targeting_spec.js +93 -0
  267. package/test/spec/unit/pbjs_api_spec.js +81 -43
  268. package/test/spec/unit/secureCreatives_spec.js +143 -24
  269. package/test/spec/videoCache_spec.js +18 -19
  270. package/test/spec/video_spec.js +51 -61
  271. package/webpack.conf.js +1 -1
@@ -0,0 +1,239 @@
1
+ import { expect } from 'chai'
2
+ import {spec} from 'modules/displayioBidAdapter.js'
3
+
4
+ describe('Displayio adapter', function () {
5
+ const BIDDER = 'displayio'
6
+ const bidRequests = [{
7
+ bidId: 'bidId_001',
8
+ bidder: BIDDER,
9
+ adUnitCode: 'adUnit_001',
10
+ auctionId: 'auctionId_001',
11
+ bidderRequestId: 'bidderRequestId_001',
12
+ mediaTypes: {
13
+ banner: {
14
+ sizes: [[320, 480]]
15
+ },
16
+ video: {
17
+ sizes: [[360, 640]]
18
+ },
19
+ },
20
+ params: {
21
+ siteId: 1,
22
+ placementId: 1,
23
+ adsSrvDomain: 'adsSrvDomain',
24
+ cdnDomain: 'cdnDomain',
25
+ }
26
+ }]
27
+ const bidderRequest = {
28
+ refererInfo: {
29
+ referer: 'testprebid.com'
30
+ }
31
+ }
32
+
33
+ describe('isBidRequestValid', function () {
34
+ it('should return true when required params found', function() {
35
+ const validBid = spec.isBidRequestValid(bidRequests[0])
36
+ expect(validBid).to.be.true
37
+ })
38
+
39
+ const bidRequestsNoParams = [{
40
+ bidder: BIDDER,
41
+ }]
42
+ it('should not validate without params', function () {
43
+ const request = spec.isBidRequestValid(bidRequestsNoParams, bidderRequest)
44
+ expect(request).to.be.false
45
+ })
46
+
47
+ const noSiteId = {
48
+ bidder: BIDDER,
49
+ params: {
50
+ placementId: 1,
51
+ adsSrvDomain: 'adsSrvDomain',
52
+ cdnDomain: 'cdnDomain',
53
+ }
54
+ }
55
+ it('should not validate without siteId', function() {
56
+ const invalidBid = spec.isBidRequestValid(noSiteId)
57
+ expect(invalidBid).to.be.false
58
+ })
59
+
60
+ const noPlacementId = {
61
+ bidder: BIDDER,
62
+ params: {
63
+ siteId: 1,
64
+ adsSrvDomain: 'adsSrvDomain',
65
+ cdnDomain: 'cdnDomain',
66
+ }
67
+ }
68
+ it('should not validate without placementId', function() {
69
+ const invalidBid = spec.isBidRequestValid(noPlacementId)
70
+ expect(invalidBid).to.be.false
71
+ })
72
+
73
+ const noAdsSrvDomain = {
74
+ bidder: BIDDER,
75
+ params: {
76
+ siteId: 1,
77
+ placementId: 1,
78
+ cdnDomain: 'cdnDomain',
79
+ }
80
+ }
81
+ it('should not validate without adsSrvDomain', function() {
82
+ const invalidBid = spec.isBidRequestValid(noAdsSrvDomain)
83
+ expect(invalidBid).to.be.false
84
+ })
85
+
86
+ const noCdnDomain = {
87
+ bidder: BIDDER,
88
+ params: {
89
+ siteId: 1,
90
+ placementId: 1,
91
+ adsSrvDomain: 'adsSrvDomain',
92
+ }
93
+ }
94
+ it('should not validate without cdnDomain', function() {
95
+ const invalidBid = spec.isBidRequestValid(noCdnDomain)
96
+ expect(invalidBid).to.be.false
97
+ })
98
+ })
99
+
100
+ describe('buildRequests', function () {
101
+ it('should build request', function() {
102
+ const request = spec.buildRequests(bidRequests, bidderRequest)
103
+ expect(request).to.not.be.empty
104
+ })
105
+
106
+ it('sends bid request to the endpoint via POST', function () {
107
+ const request = spec.buildRequests(bidRequests, bidderRequest)
108
+ expect(request[0].method).to.equal('POST')
109
+ })
110
+
111
+ it('sends all bid parameters', function () {
112
+ const request = spec.buildRequests(bidRequests, bidderRequest)
113
+ expect(request[0]).to.have.keys(['headers', 'data', 'method', 'url'])
114
+ })
115
+
116
+ it('should not crash when there is no media types', function () {
117
+ const bidRequestsNoMediaTypes = [{
118
+ bidder: BIDDER,
119
+ params: {
120
+ siteId: 1,
121
+ placementId: 1,
122
+ adsSrvDomain: 'adsSrvDomain',
123
+ cdnDomain: 'cdnDomain',
124
+ }
125
+ }]
126
+ const request = spec.buildRequests(bidRequestsNoMediaTypes, bidderRequest)
127
+ expect(request[0]).to.have.keys(['headers', 'data', 'method', 'url'])
128
+ })
129
+ })
130
+
131
+ describe('_getPayload', function () {
132
+ const payload = spec._getPayload(bidRequests[0], bidderRequest)
133
+ it('should not be empty', function() {
134
+ expect(payload).to.not.be.empty
135
+ })
136
+
137
+ it('should have userSession', function() {
138
+ expect(payload.userSession).to.be.a('string')
139
+ })
140
+
141
+ it('should have data object', function() {
142
+ expect(payload.data).to.be.a('object')
143
+ })
144
+
145
+ it('should have complianceData object', function() {
146
+ expect(payload.data.complianceData).to.be.a('object')
147
+ })
148
+
149
+ it('should have device object', function() {
150
+ expect(payload.data.device).to.be.a('object')
151
+ })
152
+
153
+ it('should have omidpn', function() {
154
+ expect(payload.data.omidpn).to.be.a('string')
155
+ })
156
+
157
+ it('should have integration', function() {
158
+ expect(payload.data.integration).to.be.a('string')
159
+ })
160
+
161
+ it('should have bidId', function() {
162
+ expect(payload.data.id).to.not.be.empty
163
+ })
164
+
165
+ it('should have action getPlacement', function() {
166
+ expect(payload.data.action).to.be.equal('getPlacement')
167
+ })
168
+
169
+ it('should have app parameter', function() {
170
+ expect(payload.data.app).to.be.a('number')
171
+ })
172
+
173
+ it('should have placement parameter', function() {
174
+ expect(payload.data.placement).to.be.a('number')
175
+ })
176
+ })
177
+
178
+ describe('interpretResponse', function () {
179
+ const response = {
180
+ body: {
181
+ status: 'ok',
182
+ data: {
183
+ ads: [{
184
+ ad: {
185
+ data: {
186
+ id: '001',
187
+ ecpm: 100,
188
+ w: 32,
189
+ h: 480,
190
+ markup: 'test ad'
191
+ }
192
+ },
193
+ subtype: 'html'
194
+ }],
195
+ }
196
+ }
197
+ }
198
+ const serverRequest = {
199
+ data: {
200
+ data: {
201
+ id: 'id_001',
202
+ data: {
203
+ ref: 'testprebid.com'
204
+ }
205
+ }
206
+ }
207
+ }
208
+
209
+ let ir = spec.interpretResponse(response, serverRequest)
210
+
211
+ expect(ir.length).to.equal(1)
212
+
213
+ ir = ir[0]
214
+
215
+ it('should have requestId', function() {
216
+ expect(ir.requestId).to.be.a('string')
217
+ })
218
+
219
+ it('should have cpm', function() {
220
+ expect(ir.cpm).to.be.a('number')
221
+ })
222
+
223
+ it('should have width', function() {
224
+ expect(ir.width).to.be.a('number')
225
+ })
226
+
227
+ it('should have height', function() {
228
+ expect(ir.height).to.be.a('number')
229
+ })
230
+
231
+ it('should have creativeId', function() {
232
+ expect(ir.creativeId).to.be.a('number')
233
+ })
234
+
235
+ it('should have ad', function() {
236
+ expect(ir.ad).to.be.a('string')
237
+ })
238
+ })
239
+ })
@@ -62,6 +62,7 @@ describe('dspxAdapter', function () {
62
62
  'bidId': '30b31c1838de1e1',
63
63
  'bidderRequestId': '22edbae2733bf61',
64
64
  'auctionId': '1d1a030790a475',
65
+ 'adUnitCode': 'testDiv1',
65
66
  'userId': {
66
67
  'netId': '123',
67
68
  'uid2': '456'
@@ -98,7 +99,8 @@ describe('dspxAdapter', function () {
98
99
  ],
99
100
  'bidId': '30b31c1838de1e3',
100
101
  'bidderRequestId': '22edbae2733bf69',
101
- 'auctionId': '1d1a030790a477'
102
+ 'auctionId': '1d1a030790a477',
103
+ 'adUnitCode': 'testDiv2'
102
104
  },
103
105
  {
104
106
  'bidder': 'dspx',
@@ -120,13 +122,15 @@ describe('dspxAdapter', function () {
120
122
 
121
123
  'bidId': '30b31c1838de1e4',
122
124
  'bidderRequestId': '22edbae2733bf67',
123
- 'auctionId': '1d1a030790a478'
125
+ 'auctionId': '1d1a030790a478',
126
+ 'adUnitCode': 'testDiv3'
124
127
  },
125
128
  {
126
129
  'bidder': 'dspx',
127
130
  'params': {
128
131
  'placement': '101',
129
- 'devMode': true
132
+ 'devMode': true,
133
+ 'vastFormat': 'vast4'
130
134
  },
131
135
  'mediaTypes': {
132
136
  'video': {
@@ -136,7 +140,8 @@ describe('dspxAdapter', function () {
136
140
  },
137
141
  'bidId': '30b31c1838de1e41',
138
142
  'bidderRequestId': '22edbae2733bf67',
139
- 'auctionId': '1d1a030790a478'
143
+ 'auctionId': '1d1a030790a478',
144
+ 'adUnitCode': 'testDiv4'
140
145
  }
141
146
 
142
147
  ];
@@ -157,16 +162,16 @@ describe('dspxAdapter', function () {
157
162
  it('sends bid request to our endpoint via GET', function () {
158
163
  expect(request1.method).to.equal('GET');
159
164
  expect(request1.url).to.equal(ENDPOINT_URL);
160
- let data = request1.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid');
161
- expect(data).to.equal('_f=html&alternative=prebid_js&inventory_item_id=6682&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e1&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bprivate_auction%5D=0&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&bcat=IAB2%2CIAB4&dvt=desktop&did_netid=123&did_uid2=456');
165
+ let data = request1.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid').replace(/pbver=.*?&/g, 'pbver=test&');
166
+ expect(data).to.equal('_f=auto&alternative=prebid_js&inventory_item_id=6682&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e1&pbver=test&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bprivate_auction%5D=0&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&bcat=IAB2%2CIAB4&dvt=desktop&did_netid=123&did_uid2=456&auctionId=1d1a030790a475&pbcode=testDiv1&media_types%5Bbanner%5D=300x250');
162
167
  });
163
168
 
164
169
  var request2 = spec.buildRequests([bidRequests[1]], bidderRequest)[0];
165
170
  it('sends bid request to our DEV endpoint via GET', function () {
166
171
  expect(request2.method).to.equal('GET');
167
172
  expect(request2.url).to.equal(ENDPOINT_URL_DEV);
168
- let data = request2.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid');
169
- expect(data).to.equal('_f=html&alternative=prebid_js&inventory_item_id=101&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e2&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&prebidDevMode=1');
173
+ let data = request2.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid').replace(/pbver=.*?&/g, 'pbver=test&');
174
+ expect(data).to.equal('_f=auto&alternative=prebid_js&inventory_item_id=101&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e2&pbver=test&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&prebidDevMode=1&auctionId=1d1a030790a476&media_types%5Bbanner%5D=300x250');
170
175
  });
171
176
 
172
177
  // Without gdprConsent
@@ -179,23 +184,23 @@ describe('dspxAdapter', function () {
179
184
  it('sends bid request without gdprConsent to our endpoint via GET', function () {
180
185
  expect(request3.method).to.equal('GET');
181
186
  expect(request3.url).to.equal(ENDPOINT_URL);
182
- let data = request3.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid');
183
- expect(data).to.equal('_f=html&alternative=prebid_js&inventory_item_id=6682&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e3&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bprivate_auction%5D=0&pfilter%5Bgeo%5D%5Bcountry%5D=DE&bcat=IAB2%2CIAB4&dvt=desktop');
187
+ let data = request3.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid').replace(/pbver=.*?&/g, 'pbver=test&');
188
+ expect(data).to.equal('_f=auto&alternative=prebid_js&inventory_item_id=6682&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e3&pbver=test&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bprivate_auction%5D=0&pfilter%5Bgeo%5D%5Bcountry%5D=DE&bcat=IAB2%2CIAB4&dvt=desktop&auctionId=1d1a030790a477&pbcode=testDiv2&media_types%5Bbanner%5D=300x250');
184
189
  });
185
190
 
186
191
  var request4 = spec.buildRequests([bidRequests[3]], bidderRequestWithoutGdpr)[0];
187
192
  it('sends bid request without gdprConsent to our DEV endpoint via GET', function () {
188
193
  expect(request4.method).to.equal('GET');
189
194
  expect(request4.url).to.equal(ENDPOINT_URL_DEV);
190
- let data = request4.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid');
191
- expect(data).to.equal('_f=html&alternative=prebid_js&inventory_item_id=101&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e4&prebidDevMode=1');
195
+ let data = request4.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid').replace(/pbver=.*?&/g, 'pbver=test&');
196
+ expect(data).to.equal('_f=auto&alternative=prebid_js&inventory_item_id=101&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e4&pbver=test&prebidDevMode=1&auctionId=1d1a030790a478&pbcode=testDiv3&media_types%5Bvideo%5D=640x480&media_types%5Bbanner%5D=300x250');
192
197
  });
193
198
 
194
199
  var request5 = spec.buildRequests([bidRequests[4]], bidderRequestWithoutGdpr)[0];
195
- it('sends bid video request to our rads endpoint via GET', function () {
200
+ it('sends bid video request to our endpoint via GET', function () {
196
201
  expect(request5.method).to.equal('GET');
197
- let data = request5.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid');
198
- expect(data).to.equal('_f=vast2&alternative=prebid_js&inventory_item_id=101&srw=640&srh=480&idt=100&bid_id=30b31c1838de1e41&prebidDevMode=1');
202
+ let data = request5.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid').replace(/pbver=.*?&/g, 'pbver=test&');
203
+ expect(data).to.equal('_f=auto&alternative=prebid_js&inventory_item_id=101&srw=640&srh=480&idt=100&bid_id=30b31c1838de1e41&pbver=test&vf=vast4&prebidDevMode=1&auctionId=1d1a030790a478&pbcode=testDiv4&media_types%5Bvideo%5D=640x480');
199
204
  });
200
205
  });
201
206
 
@@ -0,0 +1,242 @@
1
+ import {expect} from 'chai';
2
+ import {spec} from '../../../modules/e_volutionBidAdapter.js';
3
+
4
+ describe('EvolutionTechBidAdapter', function () {
5
+ let bid = {
6
+ bidId: '23fhj33i987f',
7
+ bidder: 'e_volution',
8
+ params: {
9
+ placementId: 0
10
+ },
11
+ mediaTypes: {
12
+ banner: {
13
+ sizes: [[300, 250]],
14
+ }
15
+ }
16
+ };
17
+
18
+ describe('isBidRequestValid', function () {
19
+ it('Should return true if there are bidId, params and placementId parameters present', function () {
20
+ expect(spec.isBidRequestValid(bid)).to.be.true;
21
+ });
22
+ it('Should return false if at least one of parameters is not present', function () {
23
+ delete bid.params.placementId;
24
+ expect(spec.isBidRequestValid(bid)).to.be.false;
25
+ });
26
+ });
27
+
28
+ describe('buildRequests', function () {
29
+ let serverRequest = spec.buildRequests([bid]);
30
+ it('Creates a ServerRequest object with method, URL and data', function () {
31
+ expect(serverRequest).to.exist;
32
+ expect(serverRequest.method).to.exist;
33
+ expect(serverRequest.url).to.exist;
34
+ expect(serverRequest.data).to.exist;
35
+ });
36
+ it('Returns POST method', function () {
37
+ expect(serverRequest.method).to.equal('POST');
38
+ });
39
+ it('Returns valid URL', function () {
40
+ expect(serverRequest.url).to.equal('https://service.e-volution.ai/?c=o&m=multi');
41
+ });
42
+ it('Returns valid data if array of bids is valid', function () {
43
+ let data = serverRequest.data;
44
+ expect(data).to.be.an('object');
45
+ expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements');
46
+ expect(data.deviceWidth).to.be.a('number');
47
+ expect(data.deviceHeight).to.be.a('number');
48
+ expect(data.language).to.be.a('string');
49
+ expect(data.secure).to.be.within(0, 1);
50
+ expect(data.host).to.be.a('string');
51
+ expect(data.page).to.be.a('string');
52
+ let placement = data['placements'][0];
53
+ expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes', 'bidfloor');
54
+ expect(placement.placementId).to.equal(0);
55
+ expect(placement.bidId).to.equal('23fhj33i987f');
56
+ expect(placement.traffic).to.equal('banner');
57
+ });
58
+ it('Returns empty data if no valid requests are passed', function () {
59
+ serverRequest = spec.buildRequests([]);
60
+ let data = serverRequest.data;
61
+ expect(data.placements).to.be.an('array').that.is.empty;
62
+ });
63
+ });
64
+ describe('interpretResponse', function () {
65
+ it('Should interpret banner response', function () {
66
+ const banner = {
67
+ body: [{
68
+ mediaType: 'banner',
69
+ width: 300,
70
+ height: 250,
71
+ cpm: 0.4,
72
+ ad: 'Test',
73
+ requestId: '23fhj33i987f',
74
+ ttl: 120,
75
+ creativeId: '2',
76
+ netRevenue: true,
77
+ currency: 'USD',
78
+ dealId: '1',
79
+ meta: {}
80
+ }]
81
+ };
82
+ let bannerResponses = spec.interpretResponse(banner);
83
+ expect(bannerResponses).to.be.an('array').that.is.not.empty;
84
+ let dataItem = bannerResponses[0];
85
+ expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId',
86
+ 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta');
87
+ expect(dataItem.requestId).to.equal('23fhj33i987f');
88
+ expect(dataItem.cpm).to.equal(0.4);
89
+ expect(dataItem.width).to.equal(300);
90
+ expect(dataItem.height).to.equal(250);
91
+ expect(dataItem.ad).to.equal('Test');
92
+ expect(dataItem.ttl).to.equal(120);
93
+ expect(dataItem.creativeId).to.equal('2');
94
+ expect(dataItem.netRevenue).to.be.true;
95
+ expect(dataItem.currency).to.equal('USD');
96
+ });
97
+ it('Should interpret video response', function () {
98
+ const video = {
99
+ body: [{
100
+ vastUrl: 'test.com',
101
+ mediaType: 'video',
102
+ cpm: 0.5,
103
+ requestId: '23fhj33i987f',
104
+ ttl: 120,
105
+ creativeId: '2',
106
+ netRevenue: true,
107
+ currency: 'USD',
108
+ dealId: '1',
109
+ meta: {}
110
+ }]
111
+ };
112
+ let videoResponses = spec.interpretResponse(video);
113
+ expect(videoResponses).to.be.an('array').that.is.not.empty;
114
+
115
+ let dataItem = videoResponses[0];
116
+ expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId',
117
+ 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta');
118
+ expect(dataItem.requestId).to.equal('23fhj33i987f');
119
+ expect(dataItem.cpm).to.equal(0.5);
120
+ expect(dataItem.vastUrl).to.equal('test.com');
121
+ expect(dataItem.ttl).to.equal(120);
122
+ expect(dataItem.creativeId).to.equal('2');
123
+ expect(dataItem.netRevenue).to.be.true;
124
+ expect(dataItem.currency).to.equal('USD');
125
+ });
126
+ it('Should interpret native response', function () {
127
+ const native = {
128
+ body: [{
129
+ mediaType: 'native',
130
+ native: {
131
+ clickUrl: 'test.com',
132
+ title: 'Test',
133
+ image: 'test.com',
134
+ impressionTrackers: ['test.com'],
135
+ },
136
+ ttl: 120,
137
+ cpm: 0.4,
138
+ requestId: '23fhj33i987f',
139
+ creativeId: '2',
140
+ netRevenue: true,
141
+ currency: 'USD',
142
+ meta: {}
143
+ }]
144
+ };
145
+ let nativeResponses = spec.interpretResponse(native);
146
+ expect(nativeResponses).to.be.an('array').that.is.not.empty;
147
+
148
+ let dataItem = nativeResponses[0];
149
+ expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native', 'meta');
150
+ expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image')
151
+ expect(dataItem.requestId).to.equal('23fhj33i987f');
152
+ expect(dataItem.cpm).to.equal(0.4);
153
+ expect(dataItem.native.clickUrl).to.equal('test.com');
154
+ expect(dataItem.native.title).to.equal('Test');
155
+ expect(dataItem.native.image).to.equal('test.com');
156
+ expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty;
157
+ expect(dataItem.native.impressionTrackers[0]).to.equal('test.com');
158
+ expect(dataItem.ttl).to.equal(120);
159
+ expect(dataItem.creativeId).to.equal('2');
160
+ expect(dataItem.netRevenue).to.be.true;
161
+ expect(dataItem.currency).to.equal('USD');
162
+ });
163
+ it('Should return an empty array if invalid banner response is passed', function () {
164
+ const invBanner = {
165
+ body: [{
166
+ width: 300,
167
+ cpm: 0.4,
168
+ ad: 'Test',
169
+ requestId: '23fhj33i987f',
170
+ ttl: 120,
171
+ creativeId: '2',
172
+ netRevenue: true,
173
+ currency: 'USD',
174
+ dealId: '1'
175
+ }]
176
+ };
177
+
178
+ let serverResponses = spec.interpretResponse(invBanner);
179
+ expect(serverResponses).to.be.an('array').that.is.empty;
180
+ });
181
+ it('Should return an empty array if invalid video response is passed', function () {
182
+ const invVideo = {
183
+ body: [{
184
+ mediaType: 'video',
185
+ cpm: 0.5,
186
+ requestId: '23fhj33i987f',
187
+ ttl: 120,
188
+ creativeId: '2',
189
+ netRevenue: true,
190
+ currency: 'USD',
191
+ dealId: '1'
192
+ }]
193
+ };
194
+ let serverResponses = spec.interpretResponse(invVideo);
195
+ expect(serverResponses).to.be.an('array').that.is.empty;
196
+ });
197
+ it('Should return an empty array if invalid native response is passed', function () {
198
+ const invNative = {
199
+ body: [{
200
+ mediaType: 'native',
201
+ clickUrl: 'test.com',
202
+ title: 'Test',
203
+ impressionTrackers: ['test.com'],
204
+ ttl: 120,
205
+ requestId: '23fhj33i987f',
206
+ creativeId: '2',
207
+ netRevenue: true,
208
+ currency: 'USD',
209
+ }]
210
+ };
211
+ let serverResponses = spec.interpretResponse(invNative);
212
+ expect(serverResponses).to.be.an('array').that.is.empty;
213
+ });
214
+ it('Should return an empty array if invalid response is passed', function () {
215
+ const invalid = {
216
+ body: [{
217
+ ttl: 120,
218
+ creativeId: '2',
219
+ netRevenue: true,
220
+ currency: 'USD',
221
+ dealId: '1'
222
+ }]
223
+ };
224
+ let serverResponses = spec.interpretResponse(invalid);
225
+ expect(serverResponses).to.be.an('array').that.is.empty;
226
+ });
227
+ });
228
+ describe('getUserSyncs', function () {
229
+ let userSync = spec.getUserSyncs();
230
+ it('Returns valid URL and type', function () {
231
+ if (spec.noSync) {
232
+ expect(userSync).to.be.equal(false);
233
+ } else {
234
+ expect(userSync).to.be.an('array').with.lengthOf(1);
235
+ expect(userSync[0].type).to.exist;
236
+ expect(userSync[0].url).to.exist;
237
+ expect(userSync[0].type).to.be.equal('image');
238
+ expect(userSync[0].url).to.be.equal('https://service.e-volution.ai/?c=o&m=sync');
239
+ }
240
+ });
241
+ });
242
+ });
@@ -240,9 +240,9 @@ describe('eids array generation for known sub-modules', function() {
240
240
  });
241
241
  });
242
242
 
243
- it('haloId', function() {
243
+ it('hadronId', function() {
244
244
  const userId = {
245
- haloId: 'some-random-id-value'
245
+ hadronId: 'some-random-id-value'
246
246
  };
247
247
  const newEids = createEidsArray(userId);
248
248
  expect(newEids.length).to.equal(1);
@@ -1,5 +1,5 @@
1
1
  import eplAnalyticsAdapter from 'modules/eplanningAnalyticsAdapter.js';
2
- import includes from 'core-js-pure/features/array/includes.js';
2
+ import includes from 'prebidjs-polyfill/includes.js';
3
3
  import { expect } from 'chai';
4
4
  import { parseUrl } from 'src/utils.js';
5
5
  import { server } from 'test/mocks/xhr.js';
@@ -1,5 +1,5 @@
1
1
  import fntzAnalyticsAdapter from 'modules/fintezaAnalyticsAdapter.js';
2
- import includes from 'core-js-pure/features/array/includes.js';
2
+ import includes from 'prebidjs-polyfill/includes.js';
3
3
  import { expect } from 'chai';
4
4
  import { parseUrl } from 'src/utils.js';
5
5
  import { server } from 'test/mocks/xhr.js';
@@ -8,7 +8,7 @@ import {
8
8
  newBidder
9
9
  } from 'src/adapters/bidderFactory.js';
10
10
 
11
- const ENDPOINT = 'https://adserver.gnetproject.com/prebid.php';
11
+ const ENDPOINT = 'https://service.gnetrtb.com/api/adrequest';
12
12
 
13
13
  describe('gnetAdapter', function () {
14
14
  const adapter = newBidder(spec);
@@ -23,7 +23,7 @@ describe('gnetAdapter', function () {
23
23
  let bid = {
24
24
  bidder: 'gnet',
25
25
  params: {
26
- websiteId: '4'
26
+ websiteId: '1', adunitId: '1'
27
27
  }
28
28
  };
29
29
 
@@ -43,7 +43,7 @@ describe('gnetAdapter', function () {
43
43
  const bidRequests = [{
44
44
  bidder: 'gnet',
45
45
  params: {
46
- websiteId: '4'
46
+ websiteId: '1', adunitId: '1'
47
47
  },
48
48
  adUnitCode: '/150790500/4_ZONA_IAB_300x250_5',
49
49
  sizes: [
@@ -57,7 +57,7 @@ describe('gnetAdapter', function () {
57
57
 
58
58
  const bidderRequest = {
59
59
  refererInfo: {
60
- referer: 'https://gnetproject.com/'
60
+ referer: 'https://gnetrtb.com'
61
61
  }
62
62
  };
63
63
 
@@ -66,13 +66,13 @@ describe('gnetAdapter', function () {
66
66
  expect(requests[0].url).to.equal(ENDPOINT);
67
67
  expect(requests[0].method).to.equal('POST');
68
68
  expect(requests[0].data).to.equal(JSON.stringify({
69
- 'referer': 'https://gnetproject.com/',
69
+ 'referer': 'https://gnetrtb.com',
70
70
  'adUnitCode': '/150790500/4_ZONA_IAB_300x250_5',
71
71
  'bidId': '2a19afd5173318',
72
72
  'transactionId': '894bdff6-61ec-4bec-a5a9-f36a5bfccef5',
73
73
  'sizes': ['300x250'],
74
74
  'params': {
75
- 'websiteId': '4'
75
+ 'websiteId': '1', 'adunitId': '1'
76
76
  }
77
77
  }));
78
78
  });
@@ -381,6 +381,24 @@ describe('TheMediaGrid Adapter', function () {
381
381
  expect(payload.user.ext.eids).to.deep.equal(eids);
382
382
  });
383
383
 
384
+ it('if userId is present payload must have user.ext param with right keys', function () {
385
+ const ortb2UserExtDevice = {
386
+ screenWidth: 1200,
387
+ screenHeight: 800,
388
+ language: 'ru'
389
+ };
390
+ const getConfigStub = sinon.stub(config, 'getConfig').callsFake(
391
+ arg => arg === 'ortb2.user.ext.device' ? ortb2UserExtDevice : null);
392
+
393
+ const request = spec.buildRequests(bidRequests, bidderRequest);
394
+ expect(request.data).to.be.an('string');
395
+ const payload = parseRequest(request.data);
396
+ expect(payload).to.have.property('user');
397
+ expect(payload.user).to.have.property('ext');
398
+ expect(payload.user.ext.device).to.deep.equal(ortb2UserExtDevice);
399
+ getConfigStub.restore();
400
+ });
401
+
384
402
  it('if schain is present payload must have source.ext.schain param', function () {
385
403
  const schain = {
386
404
  complete: 1,