prebid.js 8.40.0 → 8.41.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 (199) hide show
  1. package/dist/33acrossAnalyticsAdapter.js +1 -1
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/33acrossIdSystem.js +1 -1
  4. package/dist/BTBidAdapter.js +1 -1
  5. package/dist/adagioAnalyticsAdapter.js +1 -1
  6. package/dist/adagioBidAdapter.js +1 -1
  7. package/dist/adbookpspBidAdapter.js +1 -1
  8. package/dist/adgenerationBidAdapter.js +1 -1
  9. package/dist/adkernelBidAdapter.js +1 -1
  10. package/dist/adqueryBidAdapter.js +1 -1
  11. package/dist/adrelevantisBidAdapter.js +1 -1
  12. package/dist/adstirBidAdapter.js +1 -1
  13. package/dist/adtrgtmeBidAdapter.js +1 -1
  14. package/dist/adxcgBidAdapter.js +1 -1
  15. package/dist/adyoulikeBidAdapter.js +1 -1
  16. package/dist/agmaAnalyticsAdapter.js +1 -1
  17. package/dist/ajaBidAdapter.js +1 -1
  18. package/dist/amxBidAdapter.js +1 -1
  19. package/dist/amxIdSystem.js +1 -1
  20. package/dist/appierAnalyticsAdapter.js +1 -1
  21. package/dist/appnexusBidAdapter.js +1 -1
  22. package/dist/asoBidAdapter.js +1 -1
  23. package/dist/automatadAnalyticsAdapter.js +1 -1
  24. package/dist/axonixBidAdapter.js +1 -1
  25. package/dist/bidglassBidAdapter.js +1 -1
  26. package/dist/big-richmediaBidAdapter.js +1 -1
  27. package/dist/bridBidAdapter.js +1 -1
  28. package/dist/bridgewellBidAdapter.js +1 -1
  29. package/dist/brightMountainMediaBidAdapter.js +1 -1
  30. package/dist/carodaBidAdapter.js +1 -1
  31. package/dist/chtnwBidAdapter.js +1 -1
  32. package/dist/concertBidAdapter.js +1 -1
  33. package/dist/connectadBidAdapter.js +1 -1
  34. package/dist/consumableBidAdapter.js +1 -1
  35. package/dist/conversantAnalyticsAdapter.js +1 -1
  36. package/dist/conversantBidAdapter.js +1 -1
  37. package/dist/craftBidAdapter.js +1 -1
  38. package/dist/criteoBidAdapter.js +1 -1
  39. package/dist/cwireBidAdapter.js +1 -1
  40. package/dist/discoveryBidAdapter.js +1 -1
  41. package/dist/dspxBidAdapter.js +1 -1
  42. package/dist/dxkultureBidAdapter.js +1 -1
  43. package/dist/eplanningBidAdapter.js +1 -1
  44. package/dist/euidIdSystem.js +1 -1
  45. package/dist/feedadBidAdapter.js +1 -1
  46. package/dist/finativeBidAdapter.js +1 -1
  47. package/dist/freewheel-sspBidAdapter.js +1 -1
  48. package/dist/gmosspBidAdapter.js +1 -1
  49. package/dist/goldbachBidAdapter.js +1 -1
  50. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  51. package/dist/greenbidsRtdProvider.js +1 -1
  52. package/dist/gridBidAdapter.js +1 -1
  53. package/dist/gumgumBidAdapter.js +1 -1
  54. package/dist/h12mediaBidAdapter.js +1 -1
  55. package/dist/hypelabBidAdapter.js +1 -1
  56. package/dist/id5IdSystem.js +1 -1
  57. package/dist/illuminBidAdapter.js +1 -1
  58. package/dist/imdsBidAdapter.js +1 -1
  59. package/dist/improvedigitalBidAdapter.js +1 -1
  60. package/dist/insticatorBidAdapter.js +1 -1
  61. package/dist/ixBidAdapter.js +1 -1
  62. package/dist/jixieBidAdapter.js +1 -1
  63. package/dist/justpremiumBidAdapter.js +1 -1
  64. package/dist/kargoBidAdapter.js +1 -1
  65. package/dist/kimberliteBidAdapter.js +1 -1
  66. package/dist/konduitAnalyticsAdapter.js +1 -1
  67. package/dist/kueezBidAdapter.js +1 -1
  68. package/dist/kueezRtbBidAdapter.js +1 -1
  69. package/dist/lassoBidAdapter.js +1 -1
  70. package/dist/lifestreetBidAdapter.js +1 -1
  71. package/dist/liveIntentIdSystem.js +1 -1
  72. package/dist/logicadBidAdapter.js +1 -1
  73. package/dist/loglyliftBidAdapter.js +1 -1
  74. package/dist/luceadBidAdapter.js +1 -1
  75. package/dist/magniteAnalyticsAdapter.js +1 -1
  76. package/dist/malltvAnalyticsAdapter.js +1 -1
  77. package/dist/marsmediaBidAdapter.js +1 -1
  78. package/dist/mediafuseBidAdapter.js +1 -1
  79. package/dist/mediasquareBidAdapter.js +1 -1
  80. package/dist/mgidBidAdapter.js +1 -1
  81. package/dist/minutemediaBidAdapter.js +1 -1
  82. package/dist/minutemediaplusBidAdapter.js +1 -1
  83. package/dist/missenaBidAdapter.js +1 -1
  84. package/dist/nextMillenniumBidAdapter.js +1 -1
  85. package/dist/nexx360BidAdapter.js +1 -1
  86. package/dist/not-for-prod/prebid.js +155 -153
  87. package/dist/oguryBidAdapter.js +1 -1
  88. package/dist/onetagBidAdapter.js +1 -1
  89. package/dist/ooloAnalyticsAdapter.js +1 -1
  90. package/dist/openxBidAdapter.js +1 -1
  91. package/dist/optidigitalBidAdapter.js +1 -1
  92. package/dist/outbrainBidAdapter.js +1 -1
  93. package/dist/parrableIdSystem.js +1 -1
  94. package/dist/pixfutureBidAdapter.js +1 -1
  95. package/dist/prebid-core.js +1 -1
  96. package/dist/pstudioBidAdapter.js +1 -0
  97. package/dist/publinkIdSystem.js +1 -1
  98. package/dist/publirBidAdapter.js +1 -0
  99. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  100. package/dist/pubmaticBidAdapter.js +1 -1
  101. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  102. package/dist/pxyzBidAdapter.js +1 -1
  103. package/dist/quantcastBidAdapter.js +1 -1
  104. package/dist/rasBidAdapter.js +1 -1
  105. package/dist/readpeakBidAdapter.js +1 -1
  106. package/dist/relaidoBidAdapter.js +1 -1
  107. package/dist/retailspotBidAdapter.js +1 -1
  108. package/dist/rhythmoneBidAdapter.js +1 -1
  109. package/dist/riseBidAdapter.js +1 -1
  110. package/dist/rtbhouseBidAdapter.js +1 -1
  111. package/dist/rubiconBidAdapter.js +1 -1
  112. package/dist/seedingAllianceBidAdapter.js +1 -1
  113. package/dist/seedtagBidAdapter.js +1 -1
  114. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  115. package/dist/sharethroughBidAdapter.js +1 -1
  116. package/dist/shinezBidAdapter.js +1 -1
  117. package/dist/shinezRtbBidAdapter.js +1 -1
  118. package/dist/smaatoBidAdapter.js +1 -1
  119. package/dist/smartadserverBidAdapter.js +1 -1
  120. package/dist/smartxBidAdapter.js +1 -1
  121. package/dist/smartyadsBidAdapter.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/stnBidAdapter.js +1 -1
  128. package/dist/stvBidAdapter.js +1 -1
  129. package/dist/sublimeBidAdapter.js +1 -1
  130. package/dist/taboolaBidAdapter.js +1 -1
  131. package/dist/tagorasBidAdapter.js +1 -1
  132. package/dist/targetVideoBidAdapter.js +1 -1
  133. package/dist/teadsBidAdapter.js +1 -1
  134. package/dist/themoneytizerBidAdapter.js +1 -1
  135. package/dist/trionBidAdapter.js +1 -1
  136. package/dist/tripleliftBidAdapter.js +1 -1
  137. package/dist/ttdBidAdapter.js +1 -1
  138. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  139. package/dist/uid2IdSystem.js +1 -1
  140. package/dist/underdogmediaBidAdapter.js +1 -1
  141. package/dist/undertoneBidAdapter.js +1 -1
  142. package/dist/unrulyBidAdapter.js +1 -1
  143. package/dist/userId.js +1 -1
  144. package/dist/vidazooBidAdapter.js +1 -1
  145. package/dist/videobyteBidAdapter.js +1 -1
  146. package/dist/visxBidAdapter.js +1 -1
  147. package/dist/vuukleBidAdapter.js +1 -1
  148. package/dist/weboramaRtdProvider.js +1 -1
  149. package/dist/widespaceBidAdapter.js +1 -1
  150. package/dist/winrBidAdapter.js +1 -1
  151. package/dist/yahoosspBidAdapter.js +1 -1
  152. package/dist/yieldmoBidAdapter.js +1 -1
  153. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  154. package/dist/zeta_global_sspBidAdapter.js +1 -1
  155. package/integrationExamples/gpt/publir_hello_world.html +84 -0
  156. package/modules/adkernelBidAdapter.js +2 -1
  157. package/modules/automatadAnalyticsAdapter.js +31 -22
  158. package/modules/discoveryBidAdapter.js +5 -4
  159. package/modules/hypelabBidAdapter.js +31 -5
  160. package/modules/kargoBidAdapter.js +25 -13
  161. package/modules/kueezRtbBidAdapter.js +1 -1
  162. package/modules/nextMillenniumBidAdapter.js +52 -33
  163. package/modules/nexx360BidAdapter.js +2 -3
  164. package/modules/onetagBidAdapter.js +2 -1
  165. package/modules/pstudioBidAdapter.js +435 -0
  166. package/modules/pstudioBidAdapter.md +148 -0
  167. package/modules/publirBidAdapter.js +391 -0
  168. package/modules/publirBidAdapter.md +47 -0
  169. package/modules/pubmaticAnalyticsAdapter.js +7 -2
  170. package/modules/rasBidAdapter.js +178 -22
  171. package/modules/rasBidAdapter.md +2 -2
  172. package/modules/rtbhouseBidAdapter.js +2 -1
  173. package/modules/sharethroughBidAdapter.js +4 -0
  174. package/modules/smartyadsBidAdapter.js +10 -2
  175. package/modules/sovrnBidAdapter.js +15 -8
  176. package/modules/sspBCBidAdapter.js +22 -17
  177. package/modules/taboolaBidAdapter.js +1 -1
  178. package/modules/userId/index.js +1 -1
  179. package/modules/weboramaRtdProvider.js +99 -36
  180. package/modules/weboramaRtdProvider.md +13 -4
  181. package/modules/zeta_global_sspBidAdapter.js +26 -1
  182. package/package.json +1 -1
  183. package/test/spec/modules/automatadAnalyticsAdapter_spec.js +102 -15
  184. package/test/spec/modules/discoveryBidAdapter_spec.js +1 -1
  185. package/test/spec/modules/hypelabBidAdapter_spec.js +5 -1
  186. package/test/spec/modules/kargoBidAdapter_spec.js +29 -11
  187. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +34 -3
  188. package/test/spec/modules/nexx360BidAdapter_spec.js +5 -5
  189. package/test/spec/modules/onetagBidAdapter_spec.js +4 -1
  190. package/test/spec/modules/pstudioBidAdapter_spec.js +514 -0
  191. package/test/spec/modules/publirBidAdapter_spec.js +488 -0
  192. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +12 -1
  193. package/test/spec/modules/rasBidAdapter_spec.js +364 -2
  194. package/test/spec/modules/sharethroughBidAdapter_spec.js +35 -0
  195. package/test/spec/modules/sovrnBidAdapter_spec.js +39 -0
  196. package/test/spec/modules/sspBCBidAdapter_spec.js +1 -1
  197. package/test/spec/modules/taboolaBidAdapter_spec.js +1 -1
  198. package/test/spec/modules/weboramaRtdProvider_spec.js +114 -0
  199. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +4 -4
@@ -0,0 +1,514 @@
1
+ import { assert } from 'chai';
2
+ import sinon from 'sinon';
3
+ import { spec, storage } from 'modules/pstudioBidAdapter.js';
4
+ import { deepClone } from '../../../src/utils.js';
5
+
6
+ describe('PStudioAdapter', function () {
7
+ let sandbox;
8
+
9
+ beforeEach(function () {
10
+ sandbox = sinon.createSandbox();
11
+ });
12
+
13
+ afterEach(function () {
14
+ sandbox.restore();
15
+ });
16
+
17
+ const bannerBid = {
18
+ bidder: 'pstudio',
19
+ params: {
20
+ pubid: '258c2a8d-d2ad-4c31-a2a5-e63001186456',
21
+ floorPrice: 1.15,
22
+ },
23
+ adUnitCode: 'test-div-1',
24
+ mediaTypes: {
25
+ banner: {
26
+ sizes: [
27
+ [300, 250],
28
+ [300, 600],
29
+ ],
30
+ pos: 0,
31
+ name: 'some-name',
32
+ },
33
+ },
34
+ bidId: '30b31c1838de1e',
35
+ };
36
+
37
+ const videoBid = {
38
+ bidder: 'pstudio',
39
+ params: {
40
+ pubid: '258c2a8d-d2ad-4c31-a2a5-e63001186456',
41
+ floorPrice: 1.15,
42
+ },
43
+ adUnitCode: 'test-div-1',
44
+ mediaTypes: {
45
+ video: {
46
+ playerSize: [[300, 250]],
47
+ mimes: ['video/mp4'],
48
+ minduration: 5,
49
+ maxduration: 30,
50
+ protocols: [2, 3],
51
+ startdelay: 5,
52
+ placement: 2,
53
+ skip: 1,
54
+ skipafter: 1,
55
+ minbitrate: 10,
56
+ maxbitrate: 10,
57
+ delivery: 1,
58
+ playbackmethod: [1, 3],
59
+ api: [2],
60
+ linearity: 1,
61
+ },
62
+ },
63
+ bidId: '30b31c1838de1e',
64
+ };
65
+
66
+ const bidWithOptionalParams = deepClone(bannerBid);
67
+ bidWithOptionalParams.params['bcat'] = ['IAB17-18', 'IAB7-42'];
68
+ bidWithOptionalParams.params['badv'] = ['ford.com'];
69
+ bidWithOptionalParams.params['bapp'] = ['com.foo.mygame'];
70
+ bidWithOptionalParams.params['regs'] = {
71
+ coppa: 1,
72
+ };
73
+
74
+ bidWithOptionalParams.userId = {
75
+ uid2: {
76
+ id: '7505e78e-4a9b-4011-8901-0e00c3f55ea9',
77
+ },
78
+ };
79
+
80
+ const emptyOrtb2BidderRequest = { ortb2: {} };
81
+
82
+ const baseBidderRequest = {
83
+ ortb2: {
84
+ device: {
85
+ w: 1680,
86
+ h: 342,
87
+ },
88
+ },
89
+ };
90
+
91
+ const extendedBidderRequest = deepClone(baseBidderRequest);
92
+ extendedBidderRequest.ortb2['device'] = {
93
+ dnt: 0,
94
+ ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36',
95
+ lmt: 0,
96
+ ip: '192.0.0.1',
97
+ ipv6: '2001:0000:130F:0000:0000:09C0:876A:130B',
98
+ devicetype: 2,
99
+ make: 'some_producer',
100
+ model: 'some_model',
101
+ os: 'some_os',
102
+ osv: 'some_version',
103
+ js: 1,
104
+ language: 'en',
105
+ carrier: 'WiFi',
106
+ connectiontype: 0,
107
+ ifa: 'some_ifa',
108
+ geo: {
109
+ lat: 50.4,
110
+ lon: 40.2,
111
+ country: 'some_country_code',
112
+ region: 'some_region_code',
113
+ regionfips104: 'some_fips_code',
114
+ metro: 'metro_code',
115
+ city: 'city_code',
116
+ zip: 'zip_code',
117
+ type: 2,
118
+ },
119
+ ext: {
120
+ ifatype: 'dpid',
121
+ },
122
+ };
123
+ extendedBidderRequest.ortb2['site'] = {
124
+ id: 'some_id',
125
+ name: 'example',
126
+ domain: 'page.example.com',
127
+ cat: ['IAB2'],
128
+ sectioncat: ['IAB2-2'],
129
+ pagecat: ['IAB2-2'],
130
+ page: 'https://page.example.com/here.html',
131
+ ref: 'https://ref.example.com',
132
+ publisher: {
133
+ name: 'some_name',
134
+ cat: ['IAB2'],
135
+ domain: 'https://page.example.com/here.html',
136
+ },
137
+ content: {
138
+ id: 'some_id',
139
+ episode: 22,
140
+ title: 'New episode.',
141
+ series: 'New series.',
142
+ artist: 'New artist',
143
+ genre: 'some genre',
144
+ album: 'New album',
145
+ isrc: 'AA-6Q7-20-00047',
146
+ season: 'New season',
147
+ },
148
+ mobile: 0,
149
+ };
150
+ extendedBidderRequest.ortb2['app'] = {
151
+ id: 'some_id',
152
+ name: 'example',
153
+ bundle: 'some_bundle',
154
+ domain: 'page.example.com',
155
+ storeurl: 'https://store.example.com',
156
+ cat: ['IAB2'],
157
+ sectioncat: ['IAB2-2'],
158
+ pagecat: ['IAB2-2'],
159
+ ver: 'some_version',
160
+ privacypolicy: 0,
161
+ paid: 0,
162
+ keywords: 'some, example, keywords',
163
+ publisher: {
164
+ name: 'some_name',
165
+ cat: ['IAB2'],
166
+ domain: 'https://page.example.com/here.html',
167
+ },
168
+ content: {
169
+ id: 'some_id',
170
+ episode: 22,
171
+ title: 'New episode.',
172
+ series: 'New series.',
173
+ artist: 'New artist',
174
+ genre: 'some genre',
175
+ album: 'New album',
176
+ isrc: 'AA-6Q7-20-00047',
177
+ season: 'New season',
178
+ },
179
+ };
180
+ extendedBidderRequest.ortb2['user'] = {
181
+ yob: 1992,
182
+ gender: 'M',
183
+ };
184
+ extendedBidderRequest.ortb2['regs'] = {
185
+ coppa: 0,
186
+ };
187
+
188
+ describe('isBidRequestValid', function () {
189
+ it('should return true when publisher id found', function () {
190
+ expect(spec.isBidRequestValid(bannerBid)).to.equal(true);
191
+ });
192
+
193
+ it('should return true for video bid', () => {
194
+ expect(spec.isBidRequestValid(videoBid)).to.equal(true);
195
+ });
196
+
197
+ it('should return false when publisher id not found', function () {
198
+ const localBid = deepClone(bannerBid);
199
+ delete localBid.params.pubid;
200
+ delete localBid.params.floorPrice;
201
+
202
+ expect(spec.isBidRequestValid(localBid)).to.equal(false);
203
+ });
204
+
205
+ it('should return false when playerSize in video not found', () => {
206
+ const localBid = deepClone(videoBid);
207
+ delete localBid.mediaTypes.video.playerSize;
208
+
209
+ expect(spec.isBidRequestValid(localBid)).to.equal(false);
210
+ });
211
+
212
+ it('should return false when mimes in video not found', () => {
213
+ const localBid = deepClone(videoBid);
214
+ delete localBid.mediaTypes.video.mimes;
215
+
216
+ expect(spec.isBidRequestValid(localBid)).to.equal(false);
217
+ });
218
+
219
+ it('should return false when protocols in video not found', () => {
220
+ const localBid = deepClone(videoBid);
221
+ delete localBid.mediaTypes.video.protocols;
222
+
223
+ expect(spec.isBidRequestValid(localBid)).to.equal(false);
224
+ });
225
+ });
226
+
227
+ describe('buildRequests', function () {
228
+ const bannerRequest = spec.buildRequests([bannerBid], baseBidderRequest);
229
+ const bannerPayload = JSON.parse(bannerRequest[0].data);
230
+ const videoRequest = spec.buildRequests([videoBid], baseBidderRequest);
231
+ const videoPayload = JSON.parse(videoRequest[0].data);
232
+
233
+ it('should properly map ids in request payload', function () {
234
+ expect(bannerPayload.id).to.equal(bannerBid.bidId);
235
+ expect(bannerPayload.adtagid).to.equal(bannerBid.adUnitCode);
236
+ });
237
+
238
+ it('should properly map banner mediaType in request payload', function () {
239
+ expect(bannerPayload.banner_properties).to.deep.equal({
240
+ name: bannerBid.mediaTypes.banner.name,
241
+ sizes: bannerBid.mediaTypes.banner.sizes,
242
+ pos: bannerBid.mediaTypes.banner.pos,
243
+ });
244
+ });
245
+
246
+ it('should properly map video mediaType in request payload', () => {
247
+ expect(videoPayload.video_properties).to.deep.equal({
248
+ w: videoBid.mediaTypes.video.playerSize[0][0],
249
+ h: videoBid.mediaTypes.video.playerSize[0][1],
250
+ mimes: videoBid.mediaTypes.video.mimes,
251
+ minduration: videoBid.mediaTypes.video.minduration,
252
+ maxduration: videoBid.mediaTypes.video.maxduration,
253
+ protocols: videoBid.mediaTypes.video.protocols,
254
+ startdelay: videoBid.mediaTypes.video.startdelay,
255
+ placement: videoBid.mediaTypes.video.placement,
256
+ skip: videoBid.mediaTypes.video.skip,
257
+ skipafter: videoBid.mediaTypes.video.skipafter,
258
+ minbitrate: videoBid.mediaTypes.video.minbitrate,
259
+ maxbitrate: videoBid.mediaTypes.video.maxbitrate,
260
+ delivery: videoBid.mediaTypes.video.delivery,
261
+ playbackmethod: videoBid.mediaTypes.video.playbackmethod,
262
+ api: videoBid.mediaTypes.video.api,
263
+ linearity: videoBid.mediaTypes.video.linearity,
264
+ });
265
+ });
266
+
267
+ it('should properly set required bidder params in request payload', function () {
268
+ expect(bannerPayload.pubid).to.equal(bannerBid.params.pubid);
269
+ expect(bannerPayload.floor_price).to.equal(bannerBid.params.floorPrice);
270
+ });
271
+
272
+ it('should omit optional bidder params or first-party data from bid request if they are not provided', function () {
273
+ assert.isUndefined(bannerPayload.bcat);
274
+ assert.isUndefined(bannerPayload.badv);
275
+ assert.isUndefined(bannerPayload.bapp);
276
+ assert.isUndefined(bannerPayload.user);
277
+ assert.isUndefined(bannerPayload.device);
278
+ assert.isUndefined(bannerPayload.site);
279
+ assert.isUndefined(bannerPayload.app);
280
+ assert.isUndefined(bannerPayload.user_ids);
281
+ assert.isUndefined(bannerPayload.regs);
282
+ });
283
+
284
+ it('should properly set optional bidder parameters', function () {
285
+ const request = spec.buildRequests(
286
+ [bidWithOptionalParams],
287
+ baseBidderRequest
288
+ );
289
+ const payload = JSON.parse(request[0].data);
290
+
291
+ expect(payload.bcat).to.deep.equal(['IAB17-18', 'IAB7-42']);
292
+ expect(payload.badv).to.deep.equal(['ford.com']);
293
+ expect(payload.bapp).to.deep.equal(['com.foo.mygame']);
294
+ });
295
+
296
+ it('should properly set optional user_ids', function () {
297
+ const request = spec.buildRequests(
298
+ [bidWithOptionalParams],
299
+ baseBidderRequest
300
+ );
301
+ const {
302
+ user: { uid2_token },
303
+ } = JSON.parse(request[0].data);
304
+ const expectedUID = '7505e78e-4a9b-4011-8901-0e00c3f55ea9';
305
+
306
+ expect(uid2_token).to.equal(expectedUID);
307
+ });
308
+
309
+ it('should properly set optional user_ids when no first party data is provided', function () {
310
+ const request = spec.buildRequests(
311
+ [bidWithOptionalParams],
312
+ emptyOrtb2BidderRequest
313
+ );
314
+ const {
315
+ user: { uid2_token },
316
+ } = JSON.parse(request[0].data);
317
+ const expectedUID = '7505e78e-4a9b-4011-8901-0e00c3f55ea9';
318
+
319
+ expect(uid2_token).to.equal(expectedUID);
320
+ });
321
+
322
+ it('should properly handle first-party data', function () {
323
+ const request = spec.buildRequests([bannerBid], extendedBidderRequest);
324
+ const payload = JSON.parse(request[0].data);
325
+
326
+ expect(payload.user).to.deep.equal(extendedBidderRequest.ortb2.user);
327
+ expect(payload.device).to.deep.equal(extendedBidderRequest.ortb2.device);
328
+ expect(payload.site).to.deep.equal(extendedBidderRequest.ortb2.site);
329
+ expect(payload.app).to.deep.equal(extendedBidderRequest.ortb2.app);
330
+ expect(payload.regs).to.deep.equal(extendedBidderRequest.ortb2.regs);
331
+ });
332
+
333
+ it('should not set first-party data if nothing is provided in ORTB2 param', function () {
334
+ const request = spec.buildRequests([bannerBid], emptyOrtb2BidderRequest);
335
+ const payload = JSON.parse(request[0].data);
336
+
337
+ expect(payload).not.to.haveOwnProperty('user');
338
+ expect(payload).not.to.haveOwnProperty('device');
339
+ expect(payload).not.to.haveOwnProperty('site');
340
+ expect(payload).not.to.haveOwnProperty('app');
341
+ expect(payload).not.to.haveOwnProperty('regs');
342
+ });
343
+
344
+ it('should set user id if proper cookie is present', function () {
345
+ const cookie = '157bc918-b961-4216-ac72-29fc6363edcb';
346
+ sandbox.stub(storage, 'getCookie').returns(cookie);
347
+
348
+ const request = spec.buildRequests([bannerBid], emptyOrtb2BidderRequest);
349
+ const payload = JSON.parse(request[0].data);
350
+
351
+ expect(payload.user.id).to.equal(cookie);
352
+ });
353
+
354
+ it('should not set user id if proper cookie not present', function () {
355
+ const request = spec.buildRequests([bannerBid], emptyOrtb2BidderRequest);
356
+ const payload = JSON.parse(request[0].data);
357
+
358
+ expect(payload).not.to.haveOwnProperty('user');
359
+ });
360
+ });
361
+
362
+ describe('interpretResponse', function () {
363
+ const serverResponse = {
364
+ body: {
365
+ id: '123141241231',
366
+ bids: [
367
+ {
368
+ cpm: 1.02,
369
+ width: 300,
370
+ height: 600,
371
+ currency: 'USD',
372
+ ad: '<h1>Hello ad</h1>',
373
+ creative_id: 'crid12345',
374
+ net_revenue: true,
375
+ meta: {
376
+ advertiser_domains: ['https://advertiser.com'],
377
+ },
378
+ },
379
+ ],
380
+ },
381
+ };
382
+
383
+ const serverVideoResponse = {
384
+ body: {
385
+ id: '123141241231',
386
+ bids: [
387
+ {
388
+ vast_url: 'https://v.a/st.xml',
389
+ cpm: 5,
390
+ width: 640,
391
+ height: 480,
392
+ currency: 'USD',
393
+ creative_id: 'crid12345',
394
+ net_revenue: true,
395
+ meta: {
396
+ advertiser_domains: ['https://advertiser.com'],
397
+ },
398
+ },
399
+ ],
400
+ },
401
+ };
402
+
403
+ const bidRequest = {
404
+ method: 'POST',
405
+ url: 'test-url',
406
+ data: JSON.stringify({
407
+ id: '12345',
408
+ pubid: 'somepubid',
409
+ }),
410
+ };
411
+
412
+ it('should properly parse response from server', function () {
413
+ const expectedResponse = {
414
+ requestId: JSON.parse(bidRequest.data).id,
415
+ cpm: serverResponse.body.bids[0].cpm,
416
+ width: serverResponse.body.bids[0].width,
417
+ height: serverResponse.body.bids[0].height,
418
+ ad: serverResponse.body.bids[0].ad,
419
+ currency: serverResponse.body.bids[0].currency,
420
+ creativeId: serverResponse.body.bids[0].creative_id,
421
+ netRevenue: serverResponse.body.bids[0].net_revenue,
422
+ meta: {
423
+ advertiserDomains:
424
+ serverResponse.body.bids[0].meta.advertiser_domains,
425
+ },
426
+ ttl: 300,
427
+ };
428
+ const parsedResponse = spec.interpretResponse(serverResponse, bidRequest);
429
+
430
+ expect(parsedResponse[0]).to.deep.equal(expectedResponse);
431
+ });
432
+
433
+ it('should properly parse video response from server', function () {
434
+ const expectedResponse = {
435
+ requestId: JSON.parse(bidRequest.data).id,
436
+ cpm: serverVideoResponse.body.bids[0].cpm,
437
+ width: serverVideoResponse.body.bids[0].width,
438
+ height: serverVideoResponse.body.bids[0].height,
439
+ currency: serverVideoResponse.body.bids[0].currency,
440
+ creativeId: serverVideoResponse.body.bids[0].creative_id,
441
+ netRevenue: serverVideoResponse.body.bids[0].net_revenue,
442
+ mediaType: 'video',
443
+ vastUrl: serverVideoResponse.body.bids[0].vast_url,
444
+ vastXml: undefined,
445
+ meta: {
446
+ advertiserDomains:
447
+ serverVideoResponse.body.bids[0].meta.advertiser_domains,
448
+ },
449
+ ttl: 300,
450
+ };
451
+ const parsedResponse = spec.interpretResponse(
452
+ serverVideoResponse,
453
+ bidRequest
454
+ );
455
+
456
+ expect(parsedResponse[0]).to.deep.equal(expectedResponse);
457
+ });
458
+
459
+ it('should return empty array if no bids are returned', function () {
460
+ const emptyResponse = deepClone(serverResponse);
461
+ emptyResponse.body.bids = undefined;
462
+
463
+ const parsedResponse = spec.interpretResponse(emptyResponse, bidRequest);
464
+
465
+ expect(parsedResponse).to.deep.equal([]);
466
+ });
467
+ });
468
+
469
+ describe('getUserSyncs', function () {
470
+ it('should return sync object with correctly injected user id', function () {
471
+ sandbox.stub(storage, 'getCookie').returns('testid');
472
+
473
+ const result = spec.getUserSyncs({}, {}, {}, {});
474
+
475
+ expect(result).to.deep.equal([
476
+ {
477
+ type: 'image',
478
+ url: 'https://match.adsrvr.org/track/cmf/generic?ttd_pid=k1on5ig&ttd_tpi=1&ttd_puid=testid&dsp=ttd',
479
+ },
480
+ {
481
+ type: 'image',
482
+ url: 'https://dsp.myads.telkomsel.com/api/v1/pixel?uid=testid',
483
+ },
484
+ ]);
485
+ });
486
+
487
+ it('should generate user id and put the same uuid it into sync object', function () {
488
+ sandbox.stub(storage, 'getCookie').returns(undefined);
489
+
490
+ const result = spec.getUserSyncs({}, {}, {}, {});
491
+ const url1 = result[0].url;
492
+ const url2 = result[1].url;
493
+
494
+ const expectedUID1 = extractValueFromURL(url1, 'ttd_puid');
495
+ const expectedUID2 = extractValueFromURL(url2, 'uid');
496
+
497
+ expect(expectedUID1).to.equal(expectedUID2);
498
+
499
+ expect(result[0]).deep.equal({
500
+ type: 'image',
501
+ url: `https://match.adsrvr.org/track/cmf/generic?ttd_pid=k1on5ig&ttd_tpi=1&ttd_puid=${expectedUID1}&dsp=ttd`,
502
+ });
503
+ expect(result[1]).deep.equal({
504
+ type: 'image',
505
+ url: `https://dsp.myads.telkomsel.com/api/v1/pixel?uid=${expectedUID2}`,
506
+ });
507
+ // Helper function to extract UUID from URL
508
+ function extractValueFromURL(url, key) {
509
+ const match = url.match(new RegExp(`[?&]${key}=([^&]*)`));
510
+ return match ? match[1] : null;
511
+ }
512
+ });
513
+ });
514
+ });