prebid.js 5.16.0 → 5.20.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 (182) hide show
  1. package/.devcontainer/Dockerfile +11 -0
  2. package/.devcontainer/devcontainer.json +27 -0
  3. package/.devcontainer/postCreate.sh +6 -0
  4. package/browsers.json +1 -0
  5. package/integrationExamples/gpt/akamaidap_segments_example.html +132 -0
  6. package/modules/.submodules.json +1 -0
  7. package/modules/adfBidAdapter.js +21 -16
  8. package/modules/adgenerationBidAdapter.js +28 -4
  9. package/modules/adkernelBidAdapter.js +3 -1
  10. package/modules/admixerBidAdapter.js +11 -0
  11. package/modules/adnuntiusBidAdapter.js +1 -0
  12. package/modules/adtelligentBidAdapter.js +2 -1
  13. package/modules/airgridRtdProvider.js +1 -1
  14. package/modules/akamaiDapRtdProvider.js +474 -0
  15. package/modules/akamaiDapRtdProvider.md +47 -0
  16. package/modules/aolBidAdapter.js +2 -1
  17. package/modules/appnexusBidAdapter.js +5 -3
  18. package/modules/atsAnalyticsAdapter.js +89 -63
  19. package/modules/atsAnalyticsAdapter.md +1 -0
  20. package/modules/betweenBidAdapter.js +20 -3
  21. package/modules/bliinkBidAdapter.js +58 -32
  22. package/modules/bliinkBidAdapter.md +29 -6
  23. package/modules/browsiRtdProvider.js +106 -18
  24. package/modules/cleanioRtdProvider.js +192 -0
  25. package/modules/cleanioRtdProvider.md +59 -0
  26. package/modules/codefuelBidAdapter.js +183 -0
  27. package/modules/codefuelBidAdapter.md +111 -0
  28. package/modules/connectIdSystem.js +104 -0
  29. package/modules/connectIdSystem.md +33 -0
  30. package/modules/cwireBidAdapter.js +272 -0
  31. package/modules/cwireBidAdapter.md +43 -0
  32. package/modules/deepintentBidAdapter.js +106 -9
  33. package/modules/deepintentBidAdapter.md +36 -1
  34. package/modules/deltaprojectsBidAdapter.js +252 -0
  35. package/modules/deltaprojectsBidAdapter.md +32 -0
  36. package/modules/dgkeywordRtdProvider.js +0 -1
  37. package/modules/engageyaBidAdapter.js +157 -0
  38. package/modules/glimpseBidAdapter.js +160 -48
  39. package/modules/glimpseBidAdapter.md +11 -74
  40. package/modules/gridBidAdapter.js +1 -0
  41. package/modules/gridNMBidAdapter.js +7 -6
  42. package/modules/gumgumBidAdapter.js +16 -2
  43. package/modules/iasRtdProvider.js +83 -67
  44. package/modules/inskinBidAdapter.js +7 -3
  45. package/modules/ixBidAdapter.js +8 -1
  46. package/modules/jixieBidAdapter.js +8 -2
  47. package/modules/justpremiumBidAdapter.js +6 -1
  48. package/modules/kargoBidAdapter.js +14 -7
  49. package/modules/kargoBidAdapter.md +20 -0
  50. package/modules/limelightDigitalBidAdapter.js +22 -2
  51. package/modules/livewrappedAnalyticsAdapter.js +53 -3
  52. package/modules/mediakeysBidAdapter.js +405 -14
  53. package/modules/mediakeysBidAdapter.md +108 -0
  54. package/modules/multibid/index.js +3 -3
  55. package/modules/mytargetBidAdapter.js +112 -0
  56. package/modules/nativoBidAdapter.js +48 -29
  57. package/modules/nativoBidAdapter.md +0 -1
  58. package/modules/nextMillenniumBidAdapter.js +12 -3
  59. package/modules/nextrollBidAdapter.js +375 -0
  60. package/modules/nobidBidAdapter.js +2 -1
  61. package/modules/oguryBidAdapter.js +36 -7
  62. package/modules/openxBidAdapter.js +34 -22
  63. package/modules/operaadsBidAdapter.js +21 -1
  64. package/modules/otmBidAdapter.js +146 -0
  65. package/modules/otmBidAdapter.md +27 -26
  66. package/modules/outbrainBidAdapter.js +5 -0
  67. package/modules/pixfutureBidAdapter.js +24 -4
  68. package/modules/pixfutureBidAdapter.md +127 -0
  69. package/modules/playwireBidAdapter.md +61 -0
  70. package/modules/prebidServerBidAdapter/index.js +1 -1
  71. package/modules/proxistoreBidAdapter.js +4 -6
  72. package/modules/publinkIdSystem.js +17 -7
  73. package/modules/publinkIdSystem.md +7 -2
  74. package/modules/pubmaticBidAdapter.js +22 -6
  75. package/modules/pubmaticBidAdapter.md +1 -1
  76. package/modules/relaidoBidAdapter.js +8 -2
  77. package/modules/rtdModule/index.js +2 -2
  78. package/modules/sharethroughBidAdapter.js +12 -19
  79. package/modules/slimcutBidAdapter.js +121 -0
  80. package/modules/sonobiBidAdapter.js +7 -0
  81. package/modules/sortableBidAdapter.js +1 -0
  82. package/modules/spotxBidAdapter.js +15 -1
  83. package/modules/sspBCBidAdapter.js +207 -12
  84. package/modules/sspBCBidAdapter.md +1 -1
  85. package/modules/talkadsBidAdapter.js +129 -0
  86. package/modules/talkadsBidAdapter.md +60 -0
  87. package/modules/tappxBidAdapter.js +6 -5
  88. package/modules/teadsBidAdapter.js +3 -0
  89. package/modules/tripleliftBidAdapter.js +22 -5
  90. package/modules/trustxBidAdapter.js +17 -11
  91. package/modules/undertoneBidAdapter.js +9 -5
  92. package/modules/undertoneBidAdapter.md +5 -1
  93. package/modules/unicornBidAdapter.js +3 -3
  94. package/modules/userId/eids.js +18 -0
  95. package/modules/userId/eids.md +7 -0
  96. package/modules/userId/userId.md +12 -0
  97. package/modules/ventesBidAdapter.js +370 -0
  98. package/modules/ventesBidAdapter.md +94 -0
  99. package/modules/videobyteBidAdapter.js +13 -6
  100. package/modules/videobyteBidAdapter.md +49 -0
  101. package/modules/vidoomyBidAdapter.js +20 -12
  102. package/modules/visxBidAdapter.js +15 -22
  103. package/modules/yahoosspBidAdapter.js +637 -0
  104. package/modules/yahoosspBidAdapter.md +795 -0
  105. package/modules/yieldlabBidAdapter.js +48 -3
  106. package/modules/yieldlabBidAdapter.md +16 -1
  107. package/modules/yieldmoBidAdapter.js +20 -6
  108. package/modules/yieldmoSyntheticInventoryModule.js +46 -0
  109. package/modules/yieldmoSyntheticInventoryModule.md +68 -0
  110. package/package.json +1 -1
  111. package/src/adapterManager.js +5 -0
  112. package/src/adapters/bidderFactory.js +4 -3
  113. package/src/auction.js +11 -11
  114. package/src/constants.json +1 -0
  115. package/src/secureCreatives.js +6 -7
  116. package/src/targeting.js +11 -9
  117. package/test/.eslintrc.js +2 -1
  118. package/test/spec/modules/adfBidAdapter_spec.js +83 -29
  119. package/test/spec/modules/adgenerationBidAdapter_spec.js +121 -50
  120. package/test/spec/modules/adnuntiusBidAdapter_spec.js +68 -0
  121. package/test/spec/modules/adtelligentBidAdapter_spec.js +1 -0
  122. package/test/spec/modules/akamaiDapRtdProvider_spec.js +246 -0
  123. package/test/spec/modules/appnexusBidAdapter_spec.js +2 -1
  124. package/test/spec/modules/atsAnalyticsAdapter_spec.js +77 -9
  125. package/test/spec/modules/betweenBidAdapter_spec.js +41 -0
  126. package/test/spec/modules/bliinkBidAdapter_spec.js +87 -36
  127. package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
  128. package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
  129. package/test/spec/modules/codefuelBidAdapter_spec.js +316 -0
  130. package/test/spec/modules/connectIdSystem_spec.js +189 -0
  131. package/test/spec/modules/cwireBidAdapter_spec.js +246 -0
  132. package/test/spec/modules/deepintentBidAdapter_spec.js +153 -3
  133. package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
  134. package/test/spec/modules/engageyaBidAdapter_spec.js +286 -0
  135. package/test/spec/modules/glimpseBidAdapter_spec.js +302 -204
  136. package/test/spec/modules/gridNMBidAdapter_spec.js +40 -1
  137. package/test/spec/modules/gumgumBidAdapter_spec.js +23 -6
  138. package/test/spec/modules/iasRtdProvider_spec.js +71 -6
  139. package/test/spec/modules/ixBidAdapter_spec.js +13 -3
  140. package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
  141. package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
  142. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +155 -1
  143. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +67 -12
  144. package/test/spec/modules/mediakeysBidAdapter_spec.js +406 -51
  145. package/test/spec/modules/multibid_spec.js +31 -31
  146. package/test/spec/modules/mytargetBidAdapter_spec.js +199 -0
  147. package/test/spec/modules/nativoBidAdapter_spec.js +50 -3
  148. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +13 -1
  149. package/test/spec/modules/nextrollBidAdapter_spec.js +290 -0
  150. package/test/spec/modules/nobidBidAdapter_spec.js +65 -1
  151. package/test/spec/modules/oguryBidAdapter_spec.js +125 -37
  152. package/test/spec/modules/openxBidAdapter_spec.js +85 -13
  153. package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
  154. package/test/spec/modules/otmBidAdapter_spec.js +67 -0
  155. package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
  156. package/test/spec/modules/publinkIdSystem_spec.js +34 -15
  157. package/test/spec/modules/pubmaticBidAdapter_spec.js +217 -1
  158. package/test/spec/modules/relaidoBidAdapter_spec.js +21 -20
  159. package/test/spec/modules/sharethroughBidAdapter_spec.js +156 -136
  160. package/test/spec/modules/slimcutBidAdapter_spec.js +200 -0
  161. package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
  162. package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
  163. package/test/spec/modules/spotxBidAdapter_spec.js +36 -0
  164. package/test/spec/modules/sspBCBidAdapter_spec.js +210 -62
  165. package/test/spec/modules/talkadsBidAdapter_spec.js +231 -0
  166. package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
  167. package/test/spec/modules/tripleliftBidAdapter_spec.js +128 -0
  168. package/test/spec/modules/trustxBidAdapter_spec.js +38 -5
  169. package/test/spec/modules/undertoneBidAdapter_spec.js +52 -0
  170. package/test/spec/modules/unicornBidAdapter_spec.js +4 -4
  171. package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
  172. package/test/spec/modules/videobyteBidAdapter_spec.js +2 -2
  173. package/test/spec/modules/visxBidAdapter_spec.js +48 -4
  174. package/test/spec/modules/yahoosspBidAdapter_spec.js +1332 -0
  175. package/test/spec/modules/yieldlabBidAdapter_spec.js +65 -1
  176. package/test/spec/modules/yieldmoBidAdapter_spec.js +30 -9
  177. package/test/spec/modules/yieldmoSyntheticInventoryModule_spec.js +89 -0
  178. package/test/spec/unit/core/adapterManager_spec.js +32 -0
  179. package/test/spec/unit/core/bidderFactory_spec.js +61 -1
  180. package/test/spec/unit/pbjs_api_spec.js +37 -2
  181. package/test/spec/unit/secureCreatives_spec.js +54 -25
  182. package/modules/turktelekomBidAdapter.md +0 -49
@@ -1,8 +1,9 @@
1
1
  import { expect } from 'chai';
2
2
  import { spec } from 'modules/oguryBidAdapter';
3
- import { deepClone } from 'src/utils.js';
3
+ import * as utils from 'src/utils.js';
4
4
 
5
- const BID_HOST = 'https://mweb-hb.presage.io/api/header-bidding-request';
5
+ const BID_URL = 'https://mweb-hb.presage.io/api/header-bidding-request';
6
+ const TIMEOUT_URL = 'https://ms-ads-monitoring-events.presage.io/bid_timeout'
6
7
 
7
8
  describe('OguryBidAdapter', function () {
8
9
  let bidRequests;
@@ -67,14 +68,14 @@ describe('OguryBidAdapter', function () {
67
68
 
68
69
  describe('isBidRequestValid', function () {
69
70
  it('should validate correct bid', () => {
70
- let validBid = deepClone(bidRequests[0]);
71
+ let validBid = utils.deepClone(bidRequests[0]);
71
72
 
72
73
  let isValid = spec.isBidRequestValid(validBid);
73
74
  expect(isValid).to.equal(true);
74
75
  });
75
76
 
76
77
  it('should not validate incorrect bid', () => {
77
- let invalidBid = deepClone(bidRequests[0]);
78
+ let invalidBid = utils.deepClone(bidRequests[0]);
78
79
  delete invalidBid.sizes;
79
80
  delete invalidBid.mediaTypes;
80
81
 
@@ -83,7 +84,7 @@ describe('OguryBidAdapter', function () {
83
84
  });
84
85
 
85
86
  it('should not validate bid if adunit is not present', () => {
86
- let invalidBid = deepClone(bidRequests[0]);
87
+ let invalidBid = utils.deepClone(bidRequests[0]);
87
88
  delete invalidBid.params.adUnitId;
88
89
 
89
90
  let isValid = spec.isBidRequestValid(invalidBid);
@@ -91,7 +92,7 @@ describe('OguryBidAdapter', function () {
91
92
  });
92
93
 
93
94
  it('should not validate bid if assetKet is not present', () => {
94
- let invalidBid = deepClone(bidRequests[0]);
95
+ let invalidBid = utils.deepClone(bidRequests[0]);
95
96
  delete invalidBid.params.assetKey;
96
97
 
97
98
  let isValid = spec.isBidRequestValid(invalidBid);
@@ -99,7 +100,7 @@ describe('OguryBidAdapter', function () {
99
100
  });
100
101
 
101
102
  it('should validate bid if getFloor is not present', () => {
102
- let invalidBid = deepClone(bidRequests[1]);
103
+ let invalidBid = utils.deepClone(bidRequests[1]);
103
104
  delete invalidBid.getFloor;
104
105
 
105
106
  let isValid = spec.isBidRequestValid(invalidBid);
@@ -118,22 +119,26 @@ describe('OguryBidAdapter', function () {
118
119
  };
119
120
  });
120
121
 
121
- it('should return syncs array with an element of type image', () => {
122
+ it('should return sync array with two elements of type image', () => {
122
123
  const userSyncs = spec.getUserSyncs(syncOptions, [], gdprConsent);
123
124
 
124
- expect(userSyncs).to.have.lengthOf(1);
125
+ expect(userSyncs).to.have.lengthOf(2);
125
126
  expect(userSyncs[0].type).to.equal('image');
126
127
  expect(userSyncs[0].url).to.contain('https://ms-cookie-sync.presage.io/v1/init-sync/bid-switch');
128
+ expect(userSyncs[1].type).to.equal('image');
129
+ expect(userSyncs[1].url).to.contain('https://ms-cookie-sync.presage.io/ttd/init-sync');
127
130
  });
128
131
 
129
- it('should set the source as query param', () => {
132
+ it('should set the same source as query param', () => {
130
133
  const userSyncs = spec.getUserSyncs(syncOptions, [], gdprConsent);
131
134
  expect(userSyncs[0].url).to.contain('source=prebid');
135
+ expect(userSyncs[1].url).to.contain('source=prebid');
132
136
  });
133
137
 
134
138
  it('should set the tcString as query param', () => {
135
139
  const userSyncs = spec.getUserSyncs(syncOptions, [], gdprConsent);
136
140
  expect(userSyncs[0].url).to.contain(`iab_string=${gdprConsent.consentString}`);
141
+ expect(userSyncs[1].url).to.contain(`iab_string=${gdprConsent.consentString}`);
137
142
  });
138
143
 
139
144
  it('should return an empty array when pixel is disable', () => {
@@ -141,70 +146,82 @@ describe('OguryBidAdapter', function () {
141
146
  expect(spec.getUserSyncs(syncOptions, [], gdprConsent)).to.have.lengthOf(0);
142
147
  });
143
148
 
144
- it('should return syncs array with an element of type image when consentString is undefined', () => {
149
+ it('should return sync array with two elements of type image when consentString is undefined', () => {
145
150
  gdprConsent = {
146
151
  gdprApplies: true,
147
152
  consentString: undefined
148
153
  };
149
154
 
150
155
  const userSyncs = spec.getUserSyncs(syncOptions, [], gdprConsent);
151
- expect(userSyncs).to.have.lengthOf(1);
156
+ expect(userSyncs).to.have.lengthOf(2);
152
157
  expect(userSyncs[0].type).to.equal('image');
153
- expect(userSyncs[0].url).to.equal('https://ms-cookie-sync.presage.io/v1/init-sync/bid-switch?iab_string=&source=prebid');
158
+ expect(userSyncs[0].url).to.equal('https://ms-cookie-sync.presage.io/v1/init-sync/bid-switch?iab_string=&source=prebid')
159
+ expect(userSyncs[1].type).to.equal('image');
160
+ expect(userSyncs[1].url).to.equal('https://ms-cookie-sync.presage.io/ttd/init-sync?iab_string=&source=prebid')
154
161
  });
155
162
 
156
- it('should return syncs array with an element of type image when consentString is null', () => {
163
+ it('should return sync array with two elements of type image when consentString is null', () => {
157
164
  gdprConsent = {
158
165
  gdprApplies: true,
159
166
  consentString: null
160
167
  };
161
168
 
162
169
  const userSyncs = spec.getUserSyncs(syncOptions, [], gdprConsent);
163
- expect(userSyncs).to.have.lengthOf(1);
170
+ expect(userSyncs).to.have.lengthOf(2);
164
171
  expect(userSyncs[0].type).to.equal('image');
165
- expect(userSyncs[0].url).to.equal('https://ms-cookie-sync.presage.io/v1/init-sync/bid-switch?iab_string=&source=prebid');
172
+ expect(userSyncs[0].url).to.equal('https://ms-cookie-sync.presage.io/v1/init-sync/bid-switch?iab_string=&source=prebid')
173
+ expect(userSyncs[1].type).to.equal('image');
174
+ expect(userSyncs[1].url).to.equal('https://ms-cookie-sync.presage.io/ttd/init-sync?iab_string=&source=prebid')
166
175
  });
167
176
 
168
- it('should return syncs array with an element of type image when gdprConsent is undefined', () => {
177
+ it('should return sync array with two elements of type image when gdprConsent is undefined', () => {
169
178
  gdprConsent = undefined;
170
179
 
171
180
  const userSyncs = spec.getUserSyncs(syncOptions, [], gdprConsent);
172
- expect(userSyncs).to.have.lengthOf(1);
181
+ expect(userSyncs).to.have.lengthOf(2);
173
182
  expect(userSyncs[0].type).to.equal('image');
174
- expect(userSyncs[0].url).to.equal('https://ms-cookie-sync.presage.io/v1/init-sync/bid-switch?iab_string=&source=prebid');
183
+ expect(userSyncs[0].url).to.equal('https://ms-cookie-sync.presage.io/v1/init-sync/bid-switch?iab_string=&source=prebid')
184
+ expect(userSyncs[1].type).to.equal('image');
185
+ expect(userSyncs[1].url).to.equal('https://ms-cookie-sync.presage.io/ttd/init-sync?iab_string=&source=prebid')
175
186
  });
176
187
 
177
- it('should return syncs array with an element of type image when gdprConsent is null', () => {
188
+ it('should return sync array with two elements of type image when gdprConsent is null', () => {
178
189
  gdprConsent = null;
179
190
 
180
191
  const userSyncs = spec.getUserSyncs(syncOptions, [], gdprConsent);
181
- expect(userSyncs).to.have.lengthOf(1);
192
+ expect(userSyncs).to.have.lengthOf(2);
182
193
  expect(userSyncs[0].type).to.equal('image');
183
- expect(userSyncs[0].url).to.equal('https://ms-cookie-sync.presage.io/v1/init-sync/bid-switch?iab_string=&source=prebid');
194
+ expect(userSyncs[0].url).to.equal('https://ms-cookie-sync.presage.io/v1/init-sync/bid-switch?iab_string=&source=prebid')
195
+ expect(userSyncs[1].type).to.equal('image');
196
+ expect(userSyncs[1].url).to.equal('https://ms-cookie-sync.presage.io/ttd/init-sync?iab_string=&source=prebid')
184
197
  });
185
198
 
186
- it('should return syncs array with an element of type image when gdprConsent is null and gdprApplies is false', () => {
199
+ it('should return sync array with two elements of type image when gdprConsent is null and gdprApplies is false', () => {
187
200
  gdprConsent = {
188
201
  gdprApplies: false,
189
202
  consentString: null
190
203
  };
191
204
 
192
205
  const userSyncs = spec.getUserSyncs(syncOptions, [], gdprConsent);
193
- expect(userSyncs).to.have.lengthOf(1);
206
+ expect(userSyncs).to.have.lengthOf(2);
194
207
  expect(userSyncs[0].type).to.equal('image');
195
- expect(userSyncs[0].url).to.equal('https://ms-cookie-sync.presage.io/v1/init-sync/bid-switch?iab_string=&source=prebid');
208
+ expect(userSyncs[0].url).to.equal('https://ms-cookie-sync.presage.io/v1/init-sync/bid-switch?iab_string=&source=prebid')
209
+ expect(userSyncs[1].type).to.equal('image');
210
+ expect(userSyncs[1].url).to.equal('https://ms-cookie-sync.presage.io/ttd/init-sync?iab_string=&source=prebid')
196
211
  });
197
212
 
198
- it('should return syncs array with an element of type image when gdprConsent is empty string and gdprApplies is false', () => {
213
+ it('should return sync array with two elements of type image when gdprConsent is empty string and gdprApplies is false', () => {
199
214
  gdprConsent = {
200
215
  gdprApplies: false,
201
216
  consentString: ''
202
217
  };
203
218
 
204
219
  const userSyncs = spec.getUserSyncs(syncOptions, [], gdprConsent);
205
- expect(userSyncs).to.have.lengthOf(1);
220
+ expect(userSyncs).to.have.lengthOf(2);
206
221
  expect(userSyncs[0].type).to.equal('image');
207
- expect(userSyncs[0].url).to.equal('https://ms-cookie-sync.presage.io/v1/init-sync/bid-switch?iab_string=&source=prebid');
222
+ expect(userSyncs[0].url).to.equal('https://ms-cookie-sync.presage.io/v1/init-sync/bid-switch?iab_string=&source=prebid')
223
+ expect(userSyncs[1].type).to.equal('image');
224
+ expect(userSyncs[1].url).to.equal('https://ms-cookie-sync.presage.io/ttd/init-sync?iab_string=&source=prebid')
208
225
  });
209
226
  });
210
227
 
@@ -243,6 +260,7 @@ describe('OguryBidAdapter', function () {
243
260
  site: {
244
261
  id: bidRequests[0].params.assetKey,
245
262
  domain: window.location.hostname,
263
+ page: window.location.href
246
264
  },
247
265
  user: {
248
266
  ext: {
@@ -252,15 +270,15 @@ describe('OguryBidAdapter', function () {
252
270
  };
253
271
 
254
272
  it('sends bid request to ENDPOINT via POST', function () {
255
- const validBidRequests = deepClone(bidRequests)
273
+ const validBidRequests = utils.deepClone(bidRequests)
256
274
 
257
275
  const request = spec.buildRequests(validBidRequests, bidderRequest);
258
- expect(request.url).to.equal(BID_HOST);
276
+ expect(request.url).to.equal(BID_URL);
259
277
  expect(request.method).to.equal('POST');
260
278
  });
261
279
 
262
280
  it('bid request object should be conform', function () {
263
- const validBidRequests = deepClone(bidRequests)
281
+ const validBidRequests = utils.deepClone(bidRequests)
264
282
 
265
283
  const request = spec.buildRequests(validBidRequests, bidderRequest);
266
284
  expect(request.data).to.deep.equal(expectedRequestObject);
@@ -298,7 +316,7 @@ describe('OguryBidAdapter', function () {
298
316
  ...expectedRequestObject
299
317
  };
300
318
 
301
- const validBidRequests = deepClone(bidRequests);
319
+ const validBidRequests = utils.deepClone(bidRequests);
302
320
  validBidRequests[1] = {
303
321
  ...validBidRequests[1],
304
322
  getFloor: undefined
@@ -313,7 +331,7 @@ describe('OguryBidAdapter', function () {
313
331
  ...expectedRequestObject
314
332
  };
315
333
 
316
- let validBidRequests = deepClone(bidRequests);
334
+ let validBidRequests = utils.deepClone(bidRequests);
317
335
  validBidRequests[1] = {
318
336
  ...validBidRequests[1],
319
337
  getFloor: 'getFloor'
@@ -324,9 +342,9 @@ describe('OguryBidAdapter', function () {
324
342
  });
325
343
 
326
344
  it('should handle bidFloor when currency is not USD', () => {
327
- const expectedRequestWithUnsupportedFloorCurrency = deepClone(expectedRequestObject)
345
+ const expectedRequestWithUnsupportedFloorCurrency = utils.deepClone(expectedRequestObject)
328
346
  expectedRequestWithUnsupportedFloorCurrency.imp[0].bidfloor = 0;
329
- let validBidRequests = deepClone(bidRequests);
347
+ let validBidRequests = utils.deepClone(bidRequests);
330
348
  validBidRequests[0] = {
331
349
  ...validBidRequests[0],
332
350
  getFloor: ({ size, currency, mediaType }) => {
@@ -453,11 +471,11 @@ describe('OguryBidAdapter', function () {
453
471
  })
454
472
 
455
473
  afterEach(function() {
456
- xhr.restore();
474
+ xhr.restore()
457
475
  })
458
476
 
459
477
  it('Should not create nurl request if bid is undefined', function() {
460
- spec.onBidWon();
478
+ spec.onBidWon()
461
479
  expect(requests.length).to.equal(0);
462
480
  })
463
481
 
@@ -472,5 +490,75 @@ describe('OguryBidAdapter', function () {
472
490
  expect(requests[0].url).to.equal(nurl);
473
491
  expect(requests[0].method).to.equal('GET')
474
492
  })
493
+
494
+ it('Should trigger getWindowContext method', function() {
495
+ const bidSample = {
496
+ id: 'advertId',
497
+ impid: 'bidId',
498
+ price: 100,
499
+ nurl: 'url',
500
+ adm: `<html><head><title>test creative</title></head><body style="margin: 0;"><div><img style="width: 300px; height: 250px;" src="https://assets.afcdn.com/recipe/20190529/93153_w1024h768c1cx2220cy1728cxt0cyt0cxb4441cyb3456.jpg" alt="cookies" /></div></body></html>`,
501
+ adomain: ['renault.fr'],
502
+ ext: {
503
+ adcontent: 'sample_creative',
504
+ advertid: '1a278c48-b79a-4bbf-b69f-3824803e7d87',
505
+ campaignid: '31724',
506
+ mediatype: 'image',
507
+ userid: 'ab4aabed-5230-49d9-9f1a-f06280d28366',
508
+ usersync: true,
509
+ advertiserid: '1',
510
+ isomidcompliant: false
511
+ },
512
+ w: 180,
513
+ h: 101
514
+ }
515
+ spec.onBidWon(bidSample)
516
+ expect(window.top.OG_PREBID_BID_OBJECT).to.deep.equal(bidSample)
517
+ })
475
518
  })
519
+
520
+ describe('getWindowContext', function() {
521
+ it('Should return top window if exist', function() {
522
+ const res = spec.getWindowContext()
523
+ expect(res).to.equal(window.top)
524
+ expect(res).to.not.be.undefined;
525
+ })
526
+
527
+ it('Should return self window if getting top window throw an error', function() {
528
+ const stub = sinon.stub(utils, 'getWindowTop')
529
+ stub.throws()
530
+ const res = spec.getWindowContext()
531
+ expect(res).to.equal(window.self)
532
+ utils.getWindowTop.restore()
533
+ })
534
+ })
535
+
536
+ describe('onTimeout', function () {
537
+ let xhr;
538
+ let requests;
539
+
540
+ beforeEach(function() {
541
+ xhr = sinon.useFakeXMLHttpRequest();
542
+ requests = [];
543
+ xhr.onCreate = (xhr) => {
544
+ requests.push(xhr);
545
+ };
546
+ })
547
+
548
+ afterEach(function() {
549
+ xhr.restore()
550
+ })
551
+
552
+ it('should send notification on bid timeout', function() {
553
+ const bid = {
554
+ ad: '<img style="width: 300px; height: 250px;" src="https://assets.afcdn.com/recipe/20190529/93153_w1024h768c1cx2220cy1728cxt0cyt0cxb4441cyb3456.jpg" alt="cookies" />',
555
+ cpm: 3
556
+ }
557
+ spec.onTimeout(bid);
558
+ expect(requests).to.not.be.undefined;
559
+ expect(requests.length).to.equal(1);
560
+ expect(requests[0].url).to.equal(TIMEOUT_URL);
561
+ expect(requests[0].method).to.equal('POST');
562
+ })
563
+ });
476
564
  });
@@ -1085,7 +1085,7 @@ describe('OpenxAdapter', function () {
1085
1085
  intentIqId: '1111-intentiqid',
1086
1086
  lipb: {lipbid: '1111-lipb'},
1087
1087
  lotamePanoramaId: '1111-lotameid',
1088
- merkleId: '1111-merkleid',
1088
+ merkleId: {id: '1111-merkleid'},
1089
1089
  netId: 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg',
1090
1090
  parrableId: { eid: 'eidVersion.encryptionKeyReference.encryptedValue' },
1091
1091
  pubcid: '1111-pubcid',
@@ -1139,6 +1139,9 @@ describe('OpenxAdapter', function () {
1139
1139
  let userIdValue;
1140
1140
  // handle cases where userId key refers to an object
1141
1141
  switch (userIdProviderKey) {
1142
+ case 'merkleId':
1143
+ userIdValue = EXAMPLE_DATA_BY_ATTR.merkleId.id;
1144
+ break;
1142
1145
  case 'flocId':
1143
1146
  userIdValue = EXAMPLE_DATA_BY_ATTR.flocId.id;
1144
1147
  break;
@@ -1545,7 +1548,7 @@ describe('OpenxAdapter', function () {
1545
1548
  describe('with segments', function () {
1546
1549
  const TESTS = [
1547
1550
  {
1548
- name: 'should send proprietary segment data from first party config',
1551
+ name: 'should send proprietary segment data from ortb2.user.data',
1549
1552
  config: {
1550
1553
  ortb2: {
1551
1554
  user: {
@@ -1556,10 +1559,51 @@ describe('OpenxAdapter', function () {
1556
1559
  }
1557
1560
  }
1558
1561
  },
1559
- expect: 'dmp1/4:foo|bar,dmp2:baz',
1562
+ expect: {sm: 'dmp1/4:foo|bar,dmp2:baz'},
1560
1563
  },
1561
1564
  {
1562
- name: 'should combine same provider segment data from first party config',
1565
+ name: 'should send proprietary segment data from ortb2.site.content.data',
1566
+ config: {
1567
+ ortb2: {
1568
+ site: {
1569
+ content: {
1570
+ data: [
1571
+ {name: 'dmp1', ext: {segtax: 4}, segment: [{id: 'foo'}, {id: 'bar'}]},
1572
+ {name: 'dmp2', segment: [{id: 'baz'}]},
1573
+ ]
1574
+ }
1575
+ }
1576
+ }
1577
+ },
1578
+ expect: {scsm: 'dmp1/4:foo|bar,dmp2:baz'},
1579
+ },
1580
+ {
1581
+ name: 'should send proprietary segment data from both ortb2.site.content.data and ortb2.user.data',
1582
+ config: {
1583
+ ortb2: {
1584
+ user: {
1585
+ data: [
1586
+ {name: 'dmp1', ext: {segtax: 4}, segment: [{id: 'foo'}, {id: 'bar'}]},
1587
+ {name: 'dmp2', segment: [{id: 'baz'}]},
1588
+ ]
1589
+ },
1590
+ site: {
1591
+ content: {
1592
+ data: [
1593
+ {name: 'dmp3', ext: {segtax: 5}, segment: [{id: 'foo2'}, {id: 'bar2'}]},
1594
+ {name: 'dmp4', segment: [{id: 'baz2'}]},
1595
+ ]
1596
+ }
1597
+ }
1598
+ }
1599
+ },
1600
+ expect: {
1601
+ sm: 'dmp1/4:foo|bar,dmp2:baz',
1602
+ scsm: 'dmp3/5:foo2|bar2,dmp4:baz2'
1603
+ },
1604
+ },
1605
+ {
1606
+ name: 'should combine same provider segment data from ortb2.user.data',
1563
1607
  config: {
1564
1608
  ortb2: {
1565
1609
  user: {
@@ -1570,7 +1614,23 @@ describe('OpenxAdapter', function () {
1570
1614
  }
1571
1615
  }
1572
1616
  },
1573
- expect: 'dmp1/4:foo|bar,dmp1:baz',
1617
+ expect: {sm: 'dmp1/4:foo|bar,dmp1:baz'},
1618
+ },
1619
+ {
1620
+ name: 'should combine same provider segment data from ortb2.site.content.data',
1621
+ config: {
1622
+ ortb2: {
1623
+ site: {
1624
+ content: {
1625
+ data: [
1626
+ {name: 'dmp1', ext: {segtax: 4}, segment: [{id: 'foo'}, {id: 'bar'}]},
1627
+ {name: 'dmp1', ext: {}, segment: [{id: 'baz'}]},
1628
+ ]
1629
+ }
1630
+ }
1631
+ }
1632
+ },
1633
+ expect: {scsm: 'dmp1/4:foo|bar,dmp1:baz'},
1574
1634
  },
1575
1635
  {
1576
1636
  name: 'should not send any segment data if first party config is incomplete',
@@ -1595,6 +1655,14 @@ describe('OpenxAdapter', function () {
1595
1655
  {name: 'dmp1', segment: [{id: 'foo'}, {id: 'bar'}]},
1596
1656
  {name: 'dmp2', segment: [{id: 'baz'}]},
1597
1657
  ]
1658
+ },
1659
+ site: {
1660
+ content: {
1661
+ data: [
1662
+ {name: 'dmp3', ext: {segtax: 5}, segment: [{id: 'foo2'}, {id: 'bar2'}]},
1663
+ {name: 'dmp4', segment: [{id: 'baz2'}]},
1664
+ ]
1665
+ }
1598
1666
  }
1599
1667
  }
1600
1668
  },
@@ -1606,7 +1674,10 @@ describe('OpenxAdapter', function () {
1606
1674
  },
1607
1675
  },
1608
1676
  },
1609
- expect: 'dmp1:foo|bar,dmp2:baz,liveintent:l1|l2',
1677
+ expect: {
1678
+ sm: 'dmp1:foo|bar,dmp2:baz,liveintent:l1|l2',
1679
+ scsm: 'dmp3/5:foo2|bar2,dmp4:baz2'
1680
+ },
1610
1681
  },
1611
1682
  {
1612
1683
  name: 'should send just liveintent segment from request if no first party config',
@@ -1619,7 +1690,7 @@ describe('OpenxAdapter', function () {
1619
1690
  },
1620
1691
  },
1621
1692
  },
1622
- expect: 'liveintent:l1|l2',
1693
+ expect: {sm: 'liveintent:l1|l2'},
1623
1694
  },
1624
1695
  {
1625
1696
  name: 'should send nothing if lipb section does not contain segments',
@@ -1636,13 +1707,11 @@ describe('OpenxAdapter', function () {
1636
1707
  utils._each(TESTS, (t) => {
1637
1708
  context('in ortb2.user.data', function () {
1638
1709
  let bidRequests;
1639
- let configStub;
1640
-
1641
1710
  beforeEach(function () {
1642
1711
  let fpdConfig = t.config
1643
- configStub = sinon
1712
+ sinon
1644
1713
  .stub(config, 'getConfig')
1645
- .withArgs('ortb2.user.data')
1714
+ .withArgs(sinon.match(/^ortb2\.user\.data$|^ortb2\.site\.content\.data$/))
1646
1715
  .callsFake((key) => {
1647
1716
  return utils.deepAccess(fpdConfig, key);
1648
1717
  });
@@ -1658,10 +1727,13 @@ describe('OpenxAdapter', function () {
1658
1727
  const request = spec.buildRequests(bidRequests, mockBidderRequest)
1659
1728
  expect(request.length).to.equal(1);
1660
1729
  if (t.expect) {
1661
- expect(request[0].data.sm).to.exist;
1662
- expect(request[0].data.sm).to.equal(encodeURIComponent(t.expect));
1730
+ for (const key in t.expect) {
1731
+ expect(request[0].data[key]).to.exist;
1732
+ expect(request[0].data[key]).to.equal(t.expect[key]);
1733
+ }
1663
1734
  } else {
1664
1735
  expect(request[0].data.sm).to.not.exist;
1736
+ expect(request[0].data.scsm).to.not.exist;
1665
1737
  }
1666
1738
  });
1667
1739
  });
@@ -369,7 +369,7 @@ describe('Opera Ads Bid Adapter', function () {
369
369
  requestData = JSON.parse(reqs[0].data);
370
370
  }).to.not.throw();
371
371
 
372
- expect(requestData.user.id).to.equal(bidRequests[0].userId.sharedid.id);
372
+ expect(requestData.user.buyeruid).to.equal(bidRequests[0].userId.sharedid.id);
373
373
  });
374
374
 
375
375
  it('pubcid should be used when sharedid is empty', function () {
@@ -406,7 +406,7 @@ describe('Opera Ads Bid Adapter', function () {
406
406
  requestData = JSON.parse(reqs[0].data);
407
407
  }).to.not.throw();
408
408
 
409
- expect(requestData.user.id).to.equal(bidRequests[0].userId.pubcid);
409
+ expect(requestData.user.buyeruid).to.equal(bidRequests[0].userId.pubcid);
410
410
  });
411
411
 
412
412
  it('random uid will be generate when userId is empty', function () {
@@ -433,7 +433,7 @@ describe('Opera Ads Bid Adapter', function () {
433
433
  requestData = JSON.parse(reqs[0].data);
434
434
  }).to.not.throw();
435
435
 
436
- expect(requestData.user.id).to.not.be.empty;
436
+ expect(requestData.user.buyeruid).to.not.be.empty;
437
437
  })
438
438
  });
439
439
 
@@ -679,9 +679,41 @@ describe('Opera Ads Bid Adapter', function () {
679
679
  });
680
680
  });
681
681
 
682
- describe('Test getUserSyncs', function () {
683
- it('getUserSyncs should return empty array', function () {
684
- expect(spec.getUserSyncs()).to.be.an('array').that.is.empty;
682
+ describe('Test getUserSyncs with both iframe and pixel disabled', function () {
683
+ it('getUserSyncs should return an empty array', function () {
684
+ const syncOptions = {};
685
+ expect(spec.getUserSyncs(syncOptions)).to.be.an('array').that.is.empty;
686
+ });
687
+ });
688
+
689
+ describe('Test getUserSyncs with iframe enabled', function () {
690
+ it('getUserSyncs should return array', function () {
691
+ const syncOptions = {
692
+ iframeEnabled: true
693
+ }
694
+ const userSyncPixels = spec.getUserSyncs(syncOptions)
695
+ expect(userSyncPixels).to.have.lengthOf(1);
696
+ expect(userSyncPixels[0].url).to.equal('https://s.adx.opera.com/usersync/page')
697
+ });
698
+ });
699
+
700
+ describe('Test getUserSyncs with pixel enabled', function () {
701
+ it('getUserSyncs should return array', function () {
702
+ const serverResponse = {
703
+ body: {
704
+ 'pixels': [
705
+ 'https://b1.com/usersync',
706
+ 'https://b2.com/usersync'
707
+ ]
708
+ }
709
+ };
710
+ const syncOptions = {
711
+ pixelEnabled: true
712
+ }
713
+ const userSyncPixels = spec.getUserSyncs(syncOptions, [serverResponse])
714
+ expect(userSyncPixels).to.have.lengthOf(2);
715
+ expect(userSyncPixels[0].url).to.equal('https://b1.com/usersync')
716
+ expect(userSyncPixels[1].url).to.equal('https://b2.com/usersync')
685
717
  });
686
718
  });
687
719
 
@@ -0,0 +1,67 @@
1
+ import {expect} from 'chai';
2
+ import {spec} from 'modules/otmBidAdapter';
3
+
4
+ describe('otmBidAdapter', function () {
5
+ it('validate_pub_params', function () {
6
+ expect(spec.isBidRequestValid({
7
+ bidder: 'otm',
8
+ params: {
9
+ tid: '123',
10
+ bidfloor: 20
11
+ }
12
+ })).to.equal(true);
13
+ });
14
+
15
+ it('validate_generated_params', function () {
16
+ let bidRequestData = [{
17
+ bidId: 'bid1234',
18
+ bidder: 'otm',
19
+ params: {
20
+ tid: '123',
21
+ bidfloor: 20
22
+ },
23
+ sizes: [[240, 400]]
24
+ }];
25
+
26
+ let request = spec.buildRequests(bidRequestData);
27
+ let req_data = request[0].data;
28
+
29
+ expect(req_data.bidid).to.equal('bid1234');
30
+ });
31
+
32
+ it('validate_response_params', function () {
33
+ let bidRequestData = {
34
+ data: {
35
+ bidId: 'bid1234'
36
+ }
37
+ };
38
+
39
+ let serverResponse = {
40
+ body: [
41
+ {
42
+ 'auctionid': '3c6f8e22-541b-485c-9214-e974d9fb1b6f',
43
+ 'cpm': 847.097,
44
+ 'ad': '<html><body>test html</body></html>',
45
+ 'w': 240,
46
+ 'h': 400,
47
+ 'currency': 'RUB',
48
+ 'ttl': 300,
49
+ 'creativeid': '1_7869053',
50
+ 'bidid': '101f211def7c99',
51
+ 'transactionid': 'transaction_id_1'
52
+ }
53
+ ]
54
+ };
55
+
56
+ let bids = spec.interpretResponse(serverResponse, bidRequestData);
57
+ expect(bids).to.have.lengthOf(1);
58
+ let bid = bids[0];
59
+ expect(bid.cpm).to.equal(847.097);
60
+ expect(bid.currency).to.equal('RUB');
61
+ expect(bid.width).to.equal(240);
62
+ expect(bid.height).to.equal(400);
63
+ expect(bid.netRevenue).to.equal(true);
64
+ expect(bid.requestId).to.equal('101f211def7c99');
65
+ expect(bid.ad).to.equal('<html><body>test html</body></html>');
66
+ });
67
+ });
@@ -2,6 +2,7 @@ import {expect} from 'chai';
2
2
  import {spec} from 'modules/outbrainBidAdapter.js';
3
3
  import {config} from 'src/config.js';
4
4
  import {server} from 'test/mocks/xhr';
5
+ import { createEidsArray } from 'modules/userId/eids.js';
5
6
 
6
7
  describe('Outbrain Adapter', function () {
7
8
  describe('Bid request and response', function () {
@@ -344,6 +345,23 @@ describe('Outbrain Adapter', function () {
344
345
 
345
346
  config.resetConfig()
346
347
  });
348
+
349
+ it('should pass extended ids', function () {
350
+ let bidRequest = {
351
+ bidId: 'bidId',
352
+ params: {},
353
+ userIdAsEids: createEidsArray({
354
+ idl_env: 'id-value',
355
+ }),
356
+ ...commonBidRequest,
357
+ };
358
+
359
+ let res = spec.buildRequests([bidRequest], commonBidderRequest);
360
+ const resData = JSON.parse(res.data)
361
+ expect(resData.user.ext.eids).to.deep.equal([
362
+ {source: 'liveramp.com', uids: [{id: 'id-value', atype: 3}]}
363
+ ]);
364
+ });
347
365
  })
348
366
 
349
367
  describe('interpretResponse', function () {