prebid.js 8.45.0 → 8.46.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 (203) 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/adnuntiusBidAdapter.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/alkimiBidAdapter.js +1 -1
  19. package/dist/amxBidAdapter.js +1 -1
  20. package/dist/amxIdSystem.js +1 -1
  21. package/dist/appierAnalyticsAdapter.js +1 -1
  22. package/dist/appnexusBidAdapter.js +1 -1
  23. package/dist/asoBidAdapter.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/chunk-core.js +1 -1
  33. package/dist/concertBidAdapter.js +1 -1
  34. package/dist/connectadBidAdapter.js +1 -1
  35. package/dist/consumableBidAdapter.js +1 -1
  36. package/dist/conversantAnalyticsAdapter.js +1 -1
  37. package/dist/conversantBidAdapter.js +1 -1
  38. package/dist/craftBidAdapter.js +1 -1
  39. package/dist/criteoBidAdapter.js +1 -1
  40. package/dist/cwireBidAdapter.js +1 -1
  41. package/dist/dependencies.json +12 -3
  42. package/dist/dspxBidAdapter.js +1 -1
  43. package/dist/dxkultureBidAdapter.js +1 -1
  44. package/dist/engageyaBidAdapter.js +1 -1
  45. package/dist/eplanningBidAdapter.js +1 -1
  46. package/dist/euidIdSystem.js +1 -1
  47. package/dist/feedadBidAdapter.js +1 -1
  48. package/dist/finativeBidAdapter.js +1 -1
  49. package/dist/freewheel-sspBidAdapter.js +1 -1
  50. package/dist/gmosspBidAdapter.js +1 -1
  51. package/dist/goldbachBidAdapter.js +1 -1
  52. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  53. package/dist/greenbidsRtdProvider.js +1 -1
  54. package/dist/gridBidAdapter.js +1 -1
  55. package/dist/gumgumBidAdapter.js +1 -1
  56. package/dist/h12mediaBidAdapter.js +1 -1
  57. package/dist/hypelabBidAdapter.js +1 -1
  58. package/dist/id5IdSystem.js +1 -1
  59. package/dist/illuminBidAdapter.js +1 -1
  60. package/dist/imdsBidAdapter.js +1 -1
  61. package/dist/improvedigitalBidAdapter.js +1 -1
  62. package/dist/insticatorBidAdapter.js +1 -1
  63. package/dist/ixBidAdapter.js +1 -1
  64. package/dist/jixieBidAdapter.js +1 -1
  65. package/dist/justpremiumBidAdapter.js +1 -1
  66. package/dist/jwplayerBidAdapter.js +1 -0
  67. package/dist/kargoBidAdapter.js +1 -1
  68. package/dist/kimberliteBidAdapter.js +1 -1
  69. package/dist/konduitAnalyticsAdapter.js +1 -1
  70. package/dist/kueezBidAdapter.js +1 -1
  71. package/dist/kueezRtbBidAdapter.js +1 -1
  72. package/dist/lassoBidAdapter.js +1 -1
  73. package/dist/lifestreetBidAdapter.js +1 -1
  74. package/dist/liveIntentIdSystem.js +1 -1
  75. package/dist/logicadBidAdapter.js +1 -1
  76. package/dist/loglyliftBidAdapter.js +1 -1
  77. package/dist/luceadBidAdapter.js +1 -1
  78. package/dist/magniteAnalyticsAdapter.js +1 -1
  79. package/dist/malltvAnalyticsAdapter.js +1 -1
  80. package/dist/marsmediaBidAdapter.js +1 -1
  81. package/dist/mediafuseBidAdapter.js +1 -1
  82. package/dist/mediasquareBidAdapter.js +1 -1
  83. package/dist/mgidBidAdapter.js +1 -1
  84. package/dist/minutemediaBidAdapter.js +1 -1
  85. package/dist/minutemediaplusBidAdapter.js +1 -1
  86. package/dist/missenaBidAdapter.js +1 -1
  87. package/dist/nexx360BidAdapter.js +1 -1
  88. package/dist/not-for-prod/prebid.js +154 -152
  89. package/dist/oguryBidAdapter.js +1 -1
  90. package/dist/onetagBidAdapter.js +1 -1
  91. package/dist/ooloAnalyticsAdapter.js +1 -1
  92. package/dist/openwebBidAdapter.js +1 -1
  93. package/dist/openxBidAdapter.js +1 -1
  94. package/dist/optableBidAdapter.js +1 -0
  95. package/dist/optidigitalBidAdapter.js +1 -1
  96. package/dist/ortbConverter.js +1 -1
  97. package/dist/outbrainBidAdapter.js +1 -1
  98. package/dist/parrableIdSystem.js +1 -1
  99. package/dist/pixfutureBidAdapter.js +1 -1
  100. package/dist/publinkIdSystem.js +1 -1
  101. package/dist/publirBidAdapter.js +1 -1
  102. package/dist/pubmaticBidAdapter.js +1 -1
  103. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  104. package/dist/pxyzBidAdapter.js +1 -1
  105. package/dist/quantcastBidAdapter.js +1 -1
  106. package/dist/readpeakBidAdapter.js +1 -1
  107. package/dist/relaidoBidAdapter.js +1 -1
  108. package/dist/retailspotBidAdapter.js +1 -1
  109. package/dist/rhythmoneBidAdapter.js +1 -1
  110. package/dist/riseBidAdapter.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/sirdataRtdProvider.js +1 -1
  119. package/dist/smaatoBidAdapter.js +1 -1
  120. package/dist/smartadserverBidAdapter.js +1 -1
  121. package/dist/smartxBidAdapter.js +1 -1
  122. package/dist/smilewantedBidAdapter.js +1 -1
  123. package/dist/sonobiBidAdapter.js +1 -1
  124. package/dist/sovrnAnalyticsAdapter.js +1 -1
  125. package/dist/sovrnBidAdapter.js +1 -1
  126. package/dist/sspBCBidAdapter.js +1 -1
  127. package/dist/stnBidAdapter.js +1 -1
  128. package/dist/stroeerCoreBidAdapter.js +1 -1
  129. package/dist/stvBidAdapter.js +1 -1
  130. package/dist/sublimeBidAdapter.js +1 -1
  131. package/dist/taboolaBidAdapter.js +1 -1
  132. package/dist/tagorasBidAdapter.js +1 -1
  133. package/dist/targetVideoBidAdapter.js +1 -1
  134. package/dist/teadsBidAdapter.js +1 -1
  135. package/dist/themoneytizerBidAdapter.js +1 -1
  136. package/dist/trionBidAdapter.js +1 -1
  137. package/dist/tripleliftBidAdapter.js +1 -1
  138. package/dist/ttdBidAdapter.js +1 -1
  139. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  140. package/dist/uid2IdSystem.js +1 -1
  141. package/dist/underdogmediaBidAdapter.js +1 -1
  142. package/dist/undertoneBidAdapter.js +1 -1
  143. package/dist/unrulyBidAdapter.js +1 -1
  144. package/dist/viantOrtbBidAdapter.js +1 -1
  145. package/dist/vidazooBidAdapter.js +1 -1
  146. package/dist/videobyteBidAdapter.js +1 -1
  147. package/dist/visxBidAdapter.js +1 -1
  148. package/dist/vuukleBidAdapter.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/yandexAnalyticsAdapter.js +1 -1
  153. package/dist/yieldmoBidAdapter.js +1 -1
  154. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  155. package/integrationExamples/noadserver/jwplayerBidAdapter_sample.html +75 -0
  156. package/integrationExamples/realTimeData/jwplayerRtdProvider_example.html +7 -0
  157. package/integrationExamples/videoModule/jwplayer/bidMarkedAsUsed.html +7 -0
  158. package/integrationExamples/videoModule/jwplayer/bidRequestScheduling.html +9 -4
  159. package/integrationExamples/videoModule/jwplayer/bidsBackHandlerOverride.html +7 -0
  160. package/integrationExamples/videoModule/jwplayer/eventListeners.html +7 -0
  161. package/integrationExamples/videoModule/jwplayer/eventsUI.html +7 -0
  162. package/integrationExamples/videoModule/jwplayer/gamAdServerMediation.html +7 -0
  163. package/integrationExamples/videoModule/jwplayer/mediaMetadata.html +7 -0
  164. package/integrationExamples/videoModule/jwplayer/playlist.html +7 -0
  165. package/integrationExamples/videoModule/videojs/bidMarkedAsUsed.html +7 -0
  166. package/integrationExamples/videoModule/videojs/bidRequestScheduling.html +7 -0
  167. package/integrationExamples/videoModule/videojs/bidsBackHandlerOverride.html +7 -0
  168. package/integrationExamples/videoModule/videojs/eventListeners.html +7 -0
  169. package/integrationExamples/videoModule/videojs/eventsUI.html +7 -0
  170. package/integrationExamples/videoModule/videojs/gamAdServerMediation.html +7 -0
  171. package/integrationExamples/videoModule/videojs/mediaMetadata.html +7 -0
  172. package/integrationExamples/videoModule/videojs/playlist.html +7 -0
  173. package/libraries/ortbConverter/processors/banner.js +2 -2
  174. package/modules/adgenerationBidAdapter.js +6 -10
  175. package/modules/adnuntiusBidAdapter.js +5 -0
  176. package/modules/alkimiBidAdapter.js +48 -8
  177. package/modules/engageyaBidAdapter.js +1 -1
  178. package/modules/gumgumBidAdapter.js +1 -1
  179. package/modules/jwplayerBidAdapter.js +412 -0
  180. package/modules/jwplayerBidAdapter.md +72 -0
  181. package/modules/optableBidAdapter.js +42 -0
  182. package/modules/optableBidAdapter.md +41 -0
  183. package/modules/optidigitalBidAdapter.js +20 -4
  184. package/modules/pubmaticBidAdapter.js +21 -1
  185. package/modules/relaidoBidAdapter.js +70 -9
  186. package/modules/sirdataRtdProvider.js +33 -43
  187. package/modules/stroeerCoreBidAdapter.js +7 -5
  188. package/modules/viantOrtbBidAdapter.js +2 -0
  189. package/modules/yandexAnalyticsAdapter.js +6 -0
  190. package/package.json +1 -1
  191. package/src/utils.js +15 -2
  192. package/test/spec/modules/adgenerationBidAdapter_spec.js +6 -6
  193. package/test/spec/modules/adnuntiusBidAdapter_spec.js +18 -1
  194. package/test/spec/modules/alkimiBidAdapter_spec.js +11 -5
  195. package/test/spec/modules/gumgumBidAdapter_spec.js +1 -1
  196. package/test/spec/modules/jwplayerBidAdapter_spec.js +412 -0
  197. package/test/spec/modules/liveIntentIdSystem_spec.js +13 -15
  198. package/test/spec/modules/optableBidAdapter_spec.js +89 -0
  199. package/test/spec/modules/optidigitalBidAdapter_spec.js +34 -4
  200. package/test/spec/modules/pubmaticBidAdapter_spec.js +24 -1
  201. package/test/spec/modules/relaidoBidAdapter_spec.js +62 -0
  202. package/test/spec/modules/stroeerCoreBidAdapter_spec.js +21 -0
  203. package/test/spec/utils_spec.js +17 -1
@@ -91,11 +91,11 @@ describe('alkimiBidAdapter', function () {
91
91
  })
92
92
 
93
93
  it('should return false when required params are not passed', function () {
94
- let bid = Object.assign({}, REQUEST)
94
+ let bid = JSON.parse(JSON.stringify(REQUEST))
95
95
  delete bid.params.token
96
96
  expect(spec.isBidRequestValid(bid)).to.equal(false)
97
97
 
98
- bid = Object.assign({}, REQUEST)
98
+ bid = JSON.parse(JSON.stringify(REQUEST))
99
99
  delete bid.params
100
100
  expect(spec.isBidRequestValid(bid)).to.equal(false)
101
101
  })
@@ -115,29 +115,35 @@ describe('alkimiBidAdapter', function () {
115
115
  uspConsent: 'uspConsent',
116
116
  ortb2: {
117
117
  site: {
118
- keywords: 'test1, test2'
118
+ keywords: 'test1, test2',
119
+ cat: ['IAB2'],
120
+ pagecat: ['IAB3'],
121
+ sectioncat: ['IAB4']
119
122
  },
120
123
  at: 2,
121
124
  bcat: ['BSW1', 'BSW2'],
122
125
  wseat: ['16', '165']
123
126
  }
124
127
  }
125
- const bidderRequest = spec.buildRequests(bidRequests, requestData)
126
128
 
127
129
  it('should return a properly formatted request with eids defined', function () {
130
+ const bidderRequest = spec.buildRequests(bidRequests, requestData)
128
131
  expect(bidderRequest.data.eids).to.deep.equal(REQUEST.userIdAsEids)
129
132
  })
130
133
 
131
134
  it('should return a properly formatted request with gdpr defined', function () {
135
+ const bidderRequest = spec.buildRequests(bidRequests, requestData)
132
136
  expect(bidderRequest.data.gdprConsent.consentRequired).to.equal(true)
133
137
  expect(bidderRequest.data.gdprConsent.consentString).to.equal('test-consent')
134
138
  })
135
139
 
136
140
  it('should return a properly formatted request with uspConsent defined', function () {
141
+ const bidderRequest = spec.buildRequests(bidRequests, requestData)
137
142
  expect(bidderRequest.data.uspConsent).to.equal('uspConsent')
138
143
  })
139
144
 
140
145
  it('sends bid request to ENDPOINT via POST', function () {
146
+ const bidderRequest = spec.buildRequests(bidRequests, requestData)
141
147
  expect(bidderRequest.method).to.equal('POST')
142
148
  expect(bidderRequest.data.requestId).to.not.equal(undefined)
143
149
  expect(bidderRequest.data.referer).to.equal('http://test.com/path.html')
@@ -146,7 +152,7 @@ describe('alkimiBidAdapter', function () {
146
152
  expect(bidderRequest.data.signRequest.randomUUID).to.equal(undefined)
147
153
  expect(bidderRequest.data.bidIds).to.deep.contains('456')
148
154
  expect(bidderRequest.data.signature).to.equal(undefined)
149
- expect(bidderRequest.data.ortb2).to.deep.contains({ at: 2, wseat: ['16', '165'], bcat: ['BSW1', 'BSW2'], site: { keywords: 'test1, test2' }, })
155
+ expect(bidderRequest.data.ortb2).to.deep.contains({ at: 2, wseat: ['16', '165'], bcat: ['BSW1', 'BSW2'], site: { keywords: 'test1, test2', cat: ['IAB2'], pagecat: ['IAB3'], sectioncat: ['IAB4'] } })
150
156
  expect(bidderRequest.options.customHeaders).to.deep.equal({ 'Rtb-Direct': true })
151
157
  expect(bidderRequest.options.contentType).to.equal('application/json')
152
158
  expect(bidderRequest.url).to.equal(ENDPOINT)
@@ -610,7 +610,7 @@ describe('gumgumAdapter', function () {
610
610
  // Call the buildRequests function to generate the bid request
611
611
  const [bidRequest] = spec.buildRequests(bidRequests, fakeBidRequest);
612
612
  // Assert that the DSA information in the bid request matches the provided ORTB2 data
613
- expect(bidRequest.data.dsa).to.deep.equal(fakeBidRequest.ortb2.regs.ext.dsa);
613
+ expect(bidRequest.data.dsa).to.deep.equal(JSON.stringify(fakeBidRequest.ortb2.regs.ext.dsa));
614
614
  });
615
615
  it('should not set coppa parameter if coppa config is set to false', function () {
616
616
  config.setConfig({
@@ -0,0 +1,412 @@
1
+ import { expect, assert } from 'chai';
2
+ import { spec } from 'modules/jwplayerBidAdapter.js';
3
+
4
+ describe('jwplayerBidAdapter', function() {
5
+ beforeEach(function() {
6
+ this.defaultBidderRequest = {
7
+ gdprConsent: {
8
+ consentString: 'testConsentString',
9
+ gdprApplies: true
10
+ },
11
+ uspConsent: 'testCCPA',
12
+ refererInfo: {
13
+ referer: 'https://example.com'
14
+ },
15
+ ortb2: {
16
+ site: {
17
+ domain: 'page.example.com',
18
+ page: 'https://examplepage.com',
19
+ content: {
20
+ url: 'media.mp4',
21
+ id: 'testMediaId',
22
+ title: 'testTile',
23
+ data: [{
24
+ name: 'jwplayer.com',
25
+ segment: [{
26
+ id: '00000000'
27
+ }, {
28
+ id: '88888888'
29
+ }, {
30
+ id: '80808080'
31
+ }],
32
+ ext: {
33
+ segtax: 502,
34
+ cids: ['testMediaId', 'externalTestId'],
35
+ }
36
+ }],
37
+ ext: {
38
+ description: 'testDescription'
39
+ }
40
+ }
41
+ }
42
+ },
43
+ timeout: 1000
44
+ }
45
+ });
46
+
47
+ it('should use jwplayer bidder code', function () {
48
+ expect(spec.code).to.equal('jwplayer');
49
+ });
50
+
51
+ it('should use jwplayer GVLID code', function () {
52
+ expect(spec.gvlid).to.equal(1046);
53
+ });
54
+
55
+ it('should support VIDEO media type only', function () {
56
+ expect(spec.supportedMediaTypes).to.have.length(1);
57
+ expect(spec.supportedMediaTypes[0]).to.equal('video');
58
+ });
59
+
60
+ describe('isBidRequestValid', function() {
61
+ it('should be invalid when bidRequest is undefined', function() {
62
+ assert(spec.isBidRequestValid() === false);
63
+ });
64
+
65
+ it('should be invalid when bidRequest is null', function() {
66
+ assert(spec.isBidRequestValid(null) === false);
67
+ });
68
+
69
+ it('should be invalid when the bidRequest has no params', function() {
70
+ assert(spec.isBidRequestValid({}) === false);
71
+ });
72
+
73
+ it('should be invalid when the bid request only includes a publisher ID', function() {
74
+ assert(spec.isBidRequestValid({params: {publisherId: 'foo'}}) === false);
75
+ });
76
+
77
+ it('should be invalid when the bid request only includes a placement ID', function() {
78
+ assert(spec.isBidRequestValid({params: {placementId: 'foo'}}) === false);
79
+ });
80
+
81
+ it('should be invalid when the bid request only includes a site ID', function() {
82
+ assert(spec.isBidRequestValid({params: {siteId: 'foo'}}) === false);
83
+ });
84
+
85
+ it('should be valid when the bid includes a placement ID, a publisher ID and a site ID', function() {
86
+ assert(spec.isBidRequestValid({params: {placementId: 'foo', publisherId: 'bar', siteId: 'siteId '}}) === true);
87
+ });
88
+ });
89
+
90
+ describe('buildRequests', function() {
91
+ it('should return undefined when bidRequests is undefined', function () {
92
+ expect(spec.buildRequests()).to.be.undefined;
93
+ });
94
+
95
+ it('should return undefined when bidRequests is null', function () {
96
+ expect(spec.buildRequests(null)).to.be.undefined;
97
+ });
98
+
99
+ it('should return undefined when ortb site.content.url is absent', function () {
100
+ const request = spec.buildRequests({}, {
101
+ ortb2: {
102
+ site: {
103
+ content: {
104
+ url: null,
105
+ }
106
+ }
107
+ }
108
+ });
109
+
110
+ expect(request).to.be.undefined;
111
+ });
112
+
113
+ it('should build a valid request when bid request is complete', function() {
114
+ const incomingBidRequests = [
115
+ {
116
+ bidder: 'jwplayer',
117
+ params: {
118
+ placementId: 'testPlacementId',
119
+ publisherId: 'testPublisherId',
120
+ siteId: 'testSiteId',
121
+ bidFloor: 10,
122
+ currency: 'EUR',
123
+ },
124
+ mediaTypes: {
125
+ video: {
126
+ pos: 3,
127
+ w: 640,
128
+ h: 480,
129
+ context: 'instream',
130
+ mimes: [
131
+ 'video/mp4',
132
+ 'application/javascript'
133
+ ],
134
+ protocols: [2, 3, 5, 6],
135
+ maxduration: 60,
136
+ minduration: 3,
137
+ startdelay: 0,
138
+ linearity: 1,
139
+ placement: 1,
140
+ plcmt: 1,
141
+ skip: 1,
142
+ skipafter: 4,
143
+ minbitrate: 500,
144
+ maxbitrate: 1000,
145
+ api: [2],
146
+ delivery: [2],
147
+ playbackmethod: [1],
148
+ playbackend: 2
149
+ }
150
+ },
151
+ schain: {
152
+ ver: '1.0',
153
+ complete: 1,
154
+ nodes: [
155
+ {
156
+ asi: 'publisher.com',
157
+ sid: '00001',
158
+ hp: 1
159
+ }
160
+ ]
161
+ },
162
+ bidRequestsCount: 1,
163
+ adUnitCode: 'testAdUnitCode',
164
+ bidId: 'testBidId'
165
+ }
166
+ ];
167
+
168
+ const outgoingBidRequests = spec.buildRequests(incomingBidRequests, this.defaultBidderRequest);
169
+
170
+ outgoingBidRequests.forEach(serverRequest => {
171
+ expect(serverRequest.url).to.equal('https://vpb-server.jwplayer.com/openrtb2/auction');
172
+ expect(serverRequest.method).to.equal('POST');
173
+
174
+ const openrtbRequest = JSON.parse(serverRequest.data);
175
+
176
+ expect(openrtbRequest.id).to.equal('testBidId');
177
+
178
+ expect(openrtbRequest.imp[0].id).to.equal('testAdUnitCode');
179
+ expect(openrtbRequest.imp[0].video.w).to.equal(640);
180
+ expect(openrtbRequest.imp[0].video.h).to.equal(480);
181
+ expect(openrtbRequest.imp[0].video.mimes).to.deep.equal(['video/mp4', 'application/javascript']);
182
+ expect(openrtbRequest.imp[0].video.protocols).to.deep.equal([2, 3, 5, 6]);
183
+ expect(openrtbRequest.imp[0].video.api).to.deep.equal([2]);
184
+ expect(openrtbRequest.imp[0].video.startdelay).to.equal(0);
185
+ expect(openrtbRequest.imp[0].video.placement).to.equal(1);
186
+ expect(openrtbRequest.imp[0].video.plcmt).to.equal(1);
187
+ expect(openrtbRequest.imp[0].video.pos).to.equal(3);
188
+ expect(openrtbRequest.imp[0].video.minduration).to.equal(3);
189
+ expect(openrtbRequest.imp[0].video.maxduration).to.equal(60);
190
+ expect(openrtbRequest.imp[0].video.skip).to.equal(1);
191
+ expect(openrtbRequest.imp[0].video.skipafter).to.equal(4);
192
+ expect(openrtbRequest.imp[0].video.minbitrate).to.equal(500);
193
+ expect(openrtbRequest.imp[0].video.maxbitrate).to.equal(1000);
194
+ expect(openrtbRequest.imp[0].video.delivery).to.deep.equal([2]);
195
+ expect(openrtbRequest.imp[0].video.playbackmethod).to.deep.equal([1]);
196
+ expect(openrtbRequest.imp[0].video.playbackend).to.equal(2);
197
+ expect(openrtbRequest.imp[0].video.linearity).to.equal(1);
198
+
199
+ expect(openrtbRequest.imp[0].bidfloor).to.equal(10);
200
+ expect(openrtbRequest.imp[0].bidfloorcur).to.equal('EUR');
201
+
202
+ expect(openrtbRequest.imp[0].ext.prebid.bidder.jwplayer.placementId).to.equal('testPlacementId');
203
+
204
+ expect(openrtbRequest.site.domain).to.equal('page.example.com');
205
+ expect(openrtbRequest.site.page).to.equal('https://examplepage.com');
206
+ expect(openrtbRequest.site.ref).to.equal('https://example.com');
207
+
208
+ expect(openrtbRequest.site.publisher.ext.jwplayer.publisherId).to.equal('testPublisherId');
209
+ expect(openrtbRequest.site.publisher.ext.jwplayer.siteId).to.equal('testSiteId');
210
+
211
+ expect(openrtbRequest.site.content.url).to.equal('media.mp4');
212
+ expect(openrtbRequest.site.content.id).to.equal('testMediaId');
213
+ expect(openrtbRequest.site.content.title).to.equal('testTile');
214
+ expect(openrtbRequest.site.content.ext.description).to.equal('testDescription');
215
+ expect(openrtbRequest.site.content.data.length).to.equal(1);
216
+ const datum = openrtbRequest.site.content.data[0];
217
+ expect(datum.name).to.equal('jwplayer.com');
218
+ expect(datum.segment).to.deep.equal([{
219
+ id: '00000000'
220
+ }, {
221
+ id: '88888888'
222
+ }, {
223
+ id: '80808080'
224
+ }]);
225
+ expect(datum.ext.segtax).to.equal(502);
226
+ expect(datum.ext.cids).to.deep.equal(['testMediaId', 'externalTestId']);
227
+
228
+ expect(openrtbRequest.device.ua).to.equal(navigator.userAgent);
229
+ expect(openrtbRequest.device.w).to.not.be.undefined;
230
+ expect(openrtbRequest.device.h).to.not.be.undefined;
231
+ expect(openrtbRequest.device.dnt).to.not.be.undefined;
232
+ expect(openrtbRequest.device.js).to.equal(1);
233
+ expect(openrtbRequest.device.language).to.not.be.undefined;
234
+
235
+ expect(openrtbRequest.user.ext.consent).to.equal('testConsentString');
236
+
237
+ expect(openrtbRequest.regs.ext.gdpr).to.equal(1);
238
+ expect(openrtbRequest.regs.ext.us_privacy).to.equal('testCCPA');
239
+
240
+ expect(openrtbRequest.source.schain).to.deep.equal({
241
+ ver: '1.0',
242
+ complete: 1,
243
+ nodes: [
244
+ {
245
+ asi: 'publisher.com',
246
+ sid: '00001',
247
+ hp: 1
248
+ }
249
+ ]
250
+ });
251
+
252
+ expect(openrtbRequest.tmax).to.equal(1000);
253
+ });
254
+ });
255
+ });
256
+
257
+ describe('interpretResponse', function() {
258
+ const serverResponse = {
259
+ body: {
260
+ id: 'test-request-id',
261
+ cur: 'USD',
262
+ seatbid: [{
263
+ bid: [{
264
+ id: 'testId',
265
+ impid: 'test-imp-id',
266
+ price: 5.000,
267
+ adid: 'test-creative-id',
268
+ adm: 'test-ad-xml',
269
+ adomain: ['prebid.com'],
270
+ cat: ['test-iab-category'],
271
+ w: 200,
272
+ h: 150,
273
+ dealid: 'test-deal-id'
274
+ }],
275
+ seat: 1000
276
+ }]
277
+ }
278
+ };
279
+
280
+ const bidResponses = spec.interpretResponse(serverResponse);
281
+
282
+ expect(bidResponses).to.have.length(1);
283
+ const bid = bidResponses[0];
284
+ expect(bid.requestId).to.equal('test-request-id');
285
+ expect(bid.cpm).to.equal(5);
286
+ expect(bid.currency).to.equal('USD');
287
+ expect(bid.width).to.equal(200);
288
+ expect(bid.height).to.equal(150);
289
+ expect(bid.creativeId).to.equal('test-creative-id');
290
+ expect(bid.vastXml).to.equal('test-ad-xml');
291
+ expect(bid.netRevenue).to.equal(false);
292
+ expect(bid.ttl).to.equal(3600);
293
+ expect(bid.ad).to.equal('test-ad-xml');
294
+ expect(bid.dealId).to.equal('test-deal-id');
295
+
296
+ expect(bid.meta).to.not.be.undefined;
297
+
298
+ expect(bid.meta.advertiserDomains).to.have.length(1);
299
+ expect(bid.meta.advertiserDomains[0]).to.equal('prebid.com');
300
+
301
+ expect(bid.meta.mediaType).to.equal('video');
302
+
303
+ expect(bid.meta.primaryCatId).to.have.length(1);
304
+ expect(bid.meta.primaryCatId[0]).to.equal('test-iab-category');
305
+ });
306
+
307
+ describe('getUserSyncs', function() {
308
+ const consentString = 'test_consent_string';
309
+ const baseGdprConsent = {
310
+ gdprApplies: true,
311
+ vendorData: {
312
+ purpose: {
313
+ consents: {
314
+ 1: true
315
+ }
316
+ }
317
+ }
318
+ };
319
+
320
+ const expectedBaseUrl = 'https://ib.adnxs.com/getuid?https://vpb-server.jwplayer.com/setuid?bidder=jwplayer&uid=$UID&f=i';
321
+
322
+ it('should return empty when Purpose 1 consent is not granted', function() {
323
+ expect(spec.getUserSyncs({}, {})).to.be.empty;
324
+ expect(spec.getUserSyncs({}, {}, {})).to.be.empty;
325
+ expect(spec.getUserSyncs({}, {}, { gdprApplies: false })).to.be.empty;
326
+ expect(spec.getUserSyncs({}, {}, {
327
+ gdprApplies: true,
328
+ vendorData: {
329
+ purpose: {
330
+ consents: {
331
+ 1: false
332
+ }
333
+ }
334
+ }
335
+ })).to.be.empty;
336
+ });
337
+
338
+ it('should return iframe when enabled', function () {
339
+ const userSyncs = spec.getUserSyncs({ iframeEnabled: true }, {}, baseGdprConsent);
340
+ expect(userSyncs.length).to.equal(1);
341
+ const sync = userSyncs[0];
342
+ expect(sync.type).to.equal('iframe');
343
+ expect(sync.url).to.equal(expectedBaseUrl);
344
+ });
345
+
346
+ it('should return image when enabled', function () {
347
+ const userSyncs = spec.getUserSyncs({ pixelEnabled: true }, {}, baseGdprConsent);
348
+ expect(userSyncs.length).to.equal(1);
349
+ const sync = userSyncs[0];
350
+ expect(sync.type).to.equal('image');
351
+ expect(sync.url).to.equal(expectedBaseUrl);
352
+ });
353
+
354
+ it('should return both iframe and image when enabled', function () {
355
+ const userSyncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, {}, baseGdprConsent);
356
+ expect(userSyncs.length).to.equal(2);
357
+
358
+ const iframeSync = userSyncs[0];
359
+ expect(iframeSync.type).to.equal('iframe');
360
+ expect(iframeSync.url).to.equal(expectedBaseUrl);
361
+
362
+ const imageSync = userSyncs[1];
363
+ expect(imageSync.type).to.equal('image');
364
+ expect(imageSync.url).to.equal(expectedBaseUrl);
365
+ });
366
+
367
+ it('should include gdpr consent query params in sync redirect url', function () {
368
+ const expectedUrl = expectedBaseUrl + '&gdpr=1&gdpr_consent=' + consentString;
369
+ const gdprConsent = Object.assign({ }, baseGdprConsent, { consentString });
370
+ const userSyncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, {}, gdprConsent);
371
+ expect(userSyncs.length).to.equal(2);
372
+
373
+ const iframeSync = userSyncs[0];
374
+ expect(iframeSync.type).to.equal('iframe');
375
+ expect(iframeSync.url).to.equal(expectedUrl);
376
+
377
+ const imageSync = userSyncs[1];
378
+ expect(imageSync.type).to.equal('image');
379
+ expect(imageSync.url).to.equal(expectedUrl);
380
+ });
381
+
382
+ it('should include gdpr 0 in consent query params when gdprApplies is false', function () {
383
+ const expectedUrl = expectedBaseUrl + '&gdpr=0&gdpr_consent=' + consentString;
384
+ const gdprConsent = Object.assign({ }, baseGdprConsent, { consentString, gdprApplies: false });
385
+ const userSyncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, {}, gdprConsent);
386
+ expect(userSyncs.length).to.equal(2);
387
+
388
+ const iframeSync = userSyncs[0];
389
+ expect(iframeSync.type).to.equal('iframe');
390
+ expect(iframeSync.url).to.equal(expectedUrl);
391
+
392
+ const imageSync = userSyncs[1];
393
+ expect(imageSync.type).to.equal('image');
394
+ expect(imageSync.url).to.equal(expectedUrl);
395
+ });
396
+
397
+ it('should include gdpr 0 in consent query params when gdprApplies is not a bool', function () {
398
+ const expectedUrl = expectedBaseUrl + '&gdpr=0&gdpr_consent=' + consentString;
399
+ const gdprConsent = Object.assign({ }, baseGdprConsent, { consentString, gdprApplies: 1 });
400
+ const userSyncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, {}, gdprConsent);
401
+ expect(userSyncs.length).to.equal(2);
402
+
403
+ const iframeSync = userSyncs[0];
404
+ expect(iframeSync.type).to.equal('iframe');
405
+ expect(iframeSync.url).to.equal(expectedUrl);
406
+
407
+ const imageSync = userSyncs[1];
408
+ expect(imageSync.type).to.equal('image');
409
+ expect(imageSync.url).to.equal(expectedUrl);
410
+ });
411
+ });
412
+ });
@@ -85,28 +85,26 @@ describe('LiveIntentId', function() {
85
85
  setTimeout(() => {
86
86
  expect(server.requests[0].url).to.match(/https:\/\/rp.liadm.com\/j\?.*&us_privacy=1YNY.*&wpn=prebid.*&gdpr=1&n3pc=1&n3pct=1&nb=1&gdpr_consent=consentDataString&gpp_s=gppConsentDataString&gpp_as=1.*/);
87
87
  done();
88
- }, 200);
88
+ }, 300);
89
89
  });
90
90
 
91
91
  it('should fire an event when getId and a hash is provided', function(done) {
92
92
  liveIntentIdSubmodule.getId({ params: {
93
- ...defaultConfigParams,
93
+ ...defaultConfigParams.params,
94
94
  emailHash: '58131bc547fb87af94cebdaf3102321f'
95
95
  }});
96
96
  setTimeout(() => {
97
97
  expect(server.requests[0].url).to.match(/https:\/\/rp.liadm.com\/j\?.*e=58131bc547fb87af94cebdaf3102321f.+/)
98
98
  done();
99
- }, 200);
99
+ }, 300);
100
100
  });
101
101
 
102
102
  it('should initialize LiveConnect and forward the prebid version when decode and emit an event', function(done) {
103
- liveIntentIdSubmodule.decode({}, { params: {
104
- ...defaultConfigParams
105
- }});
103
+ liveIntentIdSubmodule.decode({}, defaultConfigParams);
106
104
  setTimeout(() => {
107
105
  expect(server.requests[0].url).to.contain('tv=$prebid.version$')
108
106
  done();
109
- }, 200);
107
+ }, 300);
110
108
  });
111
109
 
112
110
  it('should initialize LiveConnect with the config params when decode and emit an event', function (done) {
@@ -123,7 +121,7 @@ describe('LiveIntentId', function() {
123
121
  setTimeout(() => {
124
122
  expect(server.requests[0].url).to.match(/https:\/\/collector.liveintent.com\/j\?.*aid=a-0001.*&wpn=prebid.*/);
125
123
  done();
126
- }, 200);
124
+ }, 300);
127
125
  });
128
126
 
129
127
  it('should fire an event with the provided distributorId', function (done) {
@@ -131,7 +129,7 @@ describe('LiveIntentId', function() {
131
129
  setTimeout(() => {
132
130
  expect(server.requests[0].url).to.match(/https:\/\/rp.liadm.com\/j\?.*did=did-1111.*&wpn=prebid.*/);
133
131
  done();
134
- }, 200);
132
+ }, 300);
135
133
  });
136
134
 
137
135
  it('should fire an event without the provided distributorId when appId is provided', function (done) {
@@ -140,7 +138,7 @@ describe('LiveIntentId', function() {
140
138
  expect(server.requests[0].url).to.match(/https:\/\/rp.liadm.com\/j\?.*aid=a-0001.*&wpn=prebid.*/);
141
139
  expect(server.requests[0].url).to.not.match(/.*did=*/);
142
140
  done();
143
- }, 200);
141
+ }, 300);
144
142
  });
145
143
 
146
144
  it('should initialize LiveConnect and emit an event with a privacy string when decode', function(done) {
@@ -157,7 +155,7 @@ describe('LiveIntentId', function() {
157
155
  setTimeout(() => {
158
156
  expect(server.requests[0].url).to.match(/.*us_privacy=1YNY.*&gdpr=0&gdpr_consent=consentDataString.*&gpp_s=gppConsentDataString&gpp_as=1.*/);
159
157
  done();
160
- }, 200);
158
+ }, 300);
161
159
  });
162
160
 
163
161
  it('should fire an event when decode and a hash is provided', function(done) {
@@ -168,11 +166,11 @@ describe('LiveIntentId', function() {
168
166
  setTimeout(() => {
169
167
  expect(server.requests[0].url).to.match(/https:\/\/rp.liadm.com\/j\?.*e=58131bc547fb87af94cebdaf3102321f.+/);
170
168
  done();
171
- }, 200);
169
+ }, 300);
172
170
  });
173
171
 
174
172
  it('should not return a decoded identifier when the unifiedId is not present in the value', function() {
175
- const result = liveIntentIdSubmodule.decode({ additionalData: 'data' });
173
+ const result = liveIntentIdSubmodule.decode({ fireEventDelay: 1, additionalData: 'data' });
176
174
  expect(result).to.be.eql({});
177
175
  });
178
176
 
@@ -181,7 +179,7 @@ describe('LiveIntentId', function() {
181
179
  setTimeout(() => {
182
180
  expect(server.requests[0].url).to.be.not.null
183
181
  done();
184
- }, 200);
182
+ }, 300);
185
183
  });
186
184
 
187
185
  it('should initialize LiveConnect and send data only once', function(done) {
@@ -192,7 +190,7 @@ describe('LiveIntentId', function() {
192
190
  setTimeout(() => {
193
191
  expect(server.requests.length).to.be.eq(1);
194
192
  done();
195
- }, 200);
193
+ }, 300);
196
194
  });
197
195
 
198
196
  it('should call the custom URL of the LiveIntent Identity Exchange endpoint', function() {
@@ -0,0 +1,89 @@
1
+ import { expect } from 'chai';
2
+ import { spec } from 'modules/optableBidAdapter';
3
+ import { newBidder } from 'src/adapters/bidderFactory.js';
4
+
5
+ describe('optableBidAdapter', function() {
6
+ const adapter = newBidder(spec);
7
+
8
+ describe('isBidRequestValid', function() {
9
+ const validBid = {
10
+ bidder: 'optable',
11
+ params: { site: '123' },
12
+ };
13
+
14
+ it('should return true when required params are present', function() {
15
+ expect(spec.isBidRequestValid(validBid)).to.be.true;
16
+ });
17
+
18
+ it('should return false when site is missing', function() {
19
+ const invalidBid = { ...validBid };
20
+ delete invalidBid.params.site;
21
+ expect(spec.isBidRequestValid(invalidBid)).to.be.false;
22
+ });
23
+ });
24
+
25
+ describe('buildRequests', function() {
26
+ const validBid = {
27
+ bidder: 'optable',
28
+ params: {
29
+ site: '123',
30
+ },
31
+ };
32
+
33
+ const bidderRequest = {
34
+ bidderRequestId: 'bid123',
35
+ refererInfo: {
36
+ domain: 'example.com',
37
+ page: 'https://example.com/page',
38
+ ref: 'https://referrer.com'
39
+ },
40
+ };
41
+
42
+ it('should include site as tagid in imp', function() {
43
+ const request = spec.buildRequests([validBid], bidderRequest);
44
+ expect(request.url).to.equal('https://ads.optable.co/ca/ortb2/v1/ssp/bid');
45
+ expect(request.method).to.equal('POST');
46
+ expect(request.data.imp[0].tagid).to.equal('123')
47
+ });
48
+ });
49
+
50
+ describe('interpretResponse', function() {
51
+ const validBid = {
52
+ bidder: 'optable',
53
+ params: {
54
+ site: '123',
55
+ },
56
+ };
57
+
58
+ const bidderRequest = {
59
+ bidderRequestId: 'bid123',
60
+ refererInfo: {
61
+ domain: 'example.com',
62
+ page: 'https://example.com/page',
63
+ ref: 'https://referrer.com'
64
+ },
65
+ };
66
+
67
+ const response = {
68
+ body: {
69
+ ext: {
70
+ optable: {
71
+ fledge: {
72
+ auctionconfigs: [
73
+ { impid: 'bid123', seller: 'https://ads.optable.co' },
74
+ ]
75
+ }
76
+ }
77
+ }
78
+ }
79
+ };
80
+
81
+ it('maps fledgeAuctionConfigs from ext.optable.fledge.auctionconfigs', function() {
82
+ const request = spec.buildRequests([validBid], bidderRequest);
83
+ const result = spec.interpretResponse(response, request);
84
+ expect(result.fledgeAuctionConfigs).to.deep.equal([
85
+ { bidId: 'bid123', config: { seller: 'https://ads.optable.co' } }
86
+ ]);
87
+ });
88
+ });
89
+ });