prebid.js 7.35.0 → 7.37.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 (229) hide show
  1. package/.devcontainer/Dockerfile +2 -0
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/33acrossIdSystem.js +1 -1
  4. package/dist/adagioBidAdapter.js +1 -1
  5. package/dist/adbookpspBidAdapter.js +1 -1
  6. package/dist/adgenerationBidAdapter.js +1 -1
  7. package/dist/admaruBidAdapter.js +1 -1
  8. package/dist/adrelevantisBidAdapter.js +1 -1
  9. package/dist/adtrgtmeBidAdapter.js +1 -1
  10. package/dist/adxcgBidAdapter.js +1 -1
  11. package/dist/adyoulikeBidAdapter.js +1 -1
  12. package/dist/aidemBidAdapter.js +1 -1
  13. package/dist/ajaBidAdapter.js +1 -1
  14. package/dist/amxBidAdapter.js +1 -1
  15. package/dist/amxIdSystem.js +1 -1
  16. package/dist/aolBidAdapter.js +1 -1
  17. package/dist/appierAnalyticsAdapter.js +1 -1
  18. package/dist/appnexusBidAdapter.js +1 -1
  19. package/dist/asoBidAdapter.js +1 -1
  20. package/dist/audiencerunBidAdapter.js +1 -1
  21. package/dist/axonixBidAdapter.js +1 -1
  22. package/dist/bidglassBidAdapter.js +1 -1
  23. package/dist/big-richmediaBidAdapter.js +1 -1
  24. package/dist/bluebillywigBidAdapter.js +1 -1
  25. package/dist/bridgewellBidAdapter.js +1 -1
  26. package/dist/brightMountainMediaBidAdapter.js +1 -1
  27. package/dist/brightcomBidAdapter.js +1 -1
  28. package/dist/brightcomSSPBidAdapter.js +1 -0
  29. package/dist/carodaBidAdapter.js +1 -1
  30. package/dist/chtnwBidAdapter.js +1 -1
  31. package/dist/concertBidAdapter.js +1 -1
  32. package/dist/connectadBidAdapter.js +1 -1
  33. package/dist/consumableBidAdapter.js +1 -1
  34. package/dist/conversantBidAdapter.js +1 -1
  35. package/dist/craftBidAdapter.js +1 -1
  36. package/dist/criteoBidAdapter.js +1 -1
  37. package/dist/cwireBidAdapter.js +1 -1
  38. package/dist/dependencies.json +3 -0
  39. package/dist/discoveryBidAdapter.js +1 -1
  40. package/dist/dspxBidAdapter.js +1 -1
  41. package/dist/eplanningBidAdapter.js +1 -1
  42. package/dist/feedadBidAdapter.js +1 -1
  43. package/dist/finativeBidAdapter.js +1 -1
  44. package/dist/freewheel-sspBidAdapter.js +1 -1
  45. package/dist/glimpseBidAdapter.js +1 -1
  46. package/dist/gmosspBidAdapter.js +1 -1
  47. package/dist/goldbachBidAdapter.js +1 -1
  48. package/dist/gridBidAdapter.js +1 -1
  49. package/dist/gridNMBidAdapter.js +1 -1
  50. package/dist/gumgumBidAdapter.js +1 -1
  51. package/dist/h12mediaBidAdapter.js +1 -1
  52. package/dist/id5IdSystem.js +1 -1
  53. package/dist/impactifyBidAdapter.js +1 -1
  54. package/dist/improvedigitalBidAdapter.js +1 -1
  55. package/dist/incrxBidAdapter.js +1 -1
  56. package/dist/inmarBidAdapter.js +1 -1
  57. package/dist/insticatorBidAdapter.js +1 -1
  58. package/dist/ixBidAdapter.js +1 -1
  59. package/dist/jixieBidAdapter.js +1 -1
  60. package/dist/justpremiumBidAdapter.js +1 -1
  61. package/dist/konduitAnalyticsAdapter.js +1 -1
  62. package/dist/kueezBidAdapter.js +1 -1
  63. package/dist/kueezRtbBidAdapter.js +1 -1
  64. package/dist/lassoBidAdapter.js +1 -1
  65. package/dist/lifestreetBidAdapter.js +1 -1
  66. package/dist/limelightDigitalBidAdapter.js +1 -1
  67. package/dist/liveIntentIdSystem.js +1 -1
  68. package/dist/livewrappedBidAdapter.js +1 -1
  69. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  70. package/dist/logicadBidAdapter.js +1 -1
  71. package/dist/loglyliftBidAdapter.js +1 -1
  72. package/dist/magniteAnalyticsAdapter.js +1 -1
  73. package/dist/malltvAnalyticsAdapter.js +1 -1
  74. package/dist/marsmediaBidAdapter.js +1 -1
  75. package/dist/mediafuseBidAdapter.js +1 -1
  76. package/dist/mediagoBidAdapter.js +1 -1
  77. package/dist/mediakeysBidAdapter.js +1 -1
  78. package/dist/mediasquareBidAdapter.js +1 -1
  79. package/dist/mgidBidAdapter.js +1 -1
  80. package/dist/minutemediaBidAdapter.js +1 -1
  81. package/dist/minutemediaplusBidAdapter.js +1 -0
  82. package/dist/neuwoRtdProvider.js +1 -0
  83. package/dist/nextMillenniumBidAdapter.js +1 -1
  84. package/dist/nexx360BidAdapter.js +1 -1
  85. package/dist/not-for-prod/prebid.js +141 -137
  86. package/dist/oguryBidAdapter.js +1 -1
  87. package/dist/onetagBidAdapter.js +1 -1
  88. package/dist/ooloAnalyticsAdapter.js +1 -1
  89. package/dist/outbrainBidAdapter.js +1 -1
  90. package/dist/parrableIdSystem.js +1 -1
  91. package/dist/pixfutureBidAdapter.js +1 -1
  92. package/dist/prebid-core.js +1 -1
  93. package/dist/prebidServerBidAdapter.js +1 -1
  94. package/dist/proxistoreBidAdapter.js +1 -1
  95. package/dist/publinkIdSystem.js +1 -1
  96. package/dist/pubmaticBidAdapter.js +1 -1
  97. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  98. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  99. package/dist/pxyzBidAdapter.js +1 -1
  100. package/dist/quantcastBidAdapter.js +1 -1
  101. package/dist/readpeakBidAdapter.js +1 -1
  102. package/dist/relaidoBidAdapter.js +1 -1
  103. package/dist/rhythmoneBidAdapter.js +1 -1
  104. package/dist/riseBidAdapter.js +1 -1
  105. package/dist/rubiconAnalyticsAdapter.js +1 -1
  106. package/dist/rubiconBidAdapter.js +1 -1
  107. package/dist/scatteredBidAdapter.js +1 -0
  108. package/dist/seedingAllianceBidAdapter.js +1 -1
  109. package/dist/seedtagBidAdapter.js +1 -1
  110. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  111. package/dist/sharethroughBidAdapter.js +1 -1
  112. package/dist/shinezBidAdapter.js +1 -1
  113. package/dist/sirdataRtdProvider.js +1 -1
  114. package/dist/smaatoBidAdapter.js +1 -1
  115. package/dist/smartadserverBidAdapter.js +1 -1
  116. package/dist/smartxBidAdapter.js +1 -1
  117. package/dist/smilewantedBidAdapter.js +1 -1
  118. package/dist/sonobiBidAdapter.js +1 -1
  119. package/dist/sovrnAnalyticsAdapter.js +1 -1
  120. package/dist/sovrnBidAdapter.js +1 -1
  121. package/dist/sspBCBidAdapter.js +1 -1
  122. package/dist/sublimeBidAdapter.js +1 -1
  123. package/dist/synacormediaBidAdapter.js +1 -1
  124. package/dist/targetVideoBidAdapter.js +1 -1
  125. package/dist/teadsBidAdapter.js +1 -1
  126. package/dist/trionBidAdapter.js +1 -1
  127. package/dist/tripleliftBidAdapter.js +1 -1
  128. package/dist/ttdBidAdapter.js +1 -1
  129. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  130. package/dist/uid2IdSystem.js +1 -1
  131. package/dist/underdogmediaBidAdapter.js +1 -1
  132. package/dist/undertoneBidAdapter.js +1 -1
  133. package/dist/userId.js +1 -1
  134. package/dist/vidazooBidAdapter.js +1 -1
  135. package/dist/videobyteBidAdapter.js +1 -1
  136. package/dist/visxBidAdapter.js +1 -1
  137. package/dist/vuukleBidAdapter.js +1 -1
  138. package/dist/widespaceBidAdapter.js +1 -1
  139. package/dist/winrBidAdapter.js +1 -1
  140. package/dist/yahoosspBidAdapter.js +1 -1
  141. package/dist/yieldmoBidAdapter.js +1 -1
  142. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  143. package/integrationExamples/gpt/neuwoRtdProvider_example.html +190 -0
  144. package/modules/33acrossBidAdapter.js +13 -4
  145. package/modules/adagioBidAdapter.js +14 -14
  146. package/modules/adagioBidAdapter.md +3 -1
  147. package/modules/admaruBidAdapter.js +19 -1
  148. package/modules/aidemBidAdapter.js +90 -65
  149. package/modules/aidemBidAdapter.md +10 -7
  150. package/modules/ajaBidAdapter.js +6 -1
  151. package/modules/amxIdSystem.md +2 -10
  152. package/modules/aolBidAdapter.js +1 -1
  153. package/modules/appnexusBidAdapter.js +45 -48
  154. package/modules/brightcomBidAdapter.js +1 -0
  155. package/modules/brightcomSSPBidAdapter.js +323 -0
  156. package/modules/brightcomSSPBidAdapter.md +46 -0
  157. package/modules/criteoBidAdapter.js +4 -5
  158. package/modules/cwireBidAdapter.md +9 -3
  159. package/modules/discoveryBidAdapter.js +22 -12
  160. package/modules/feedadBidAdapter.js +35 -15
  161. package/modules/fpdModule/index.md +5 -2
  162. package/modules/freewheel-sspBidAdapter.js +5 -1
  163. package/modules/gridBidAdapter.js +3 -1
  164. package/modules/incrxBidAdapter.js +2 -0
  165. package/modules/ixBidAdapter.js +318 -175
  166. package/modules/kueezRtbBidAdapter.js +54 -20
  167. package/modules/limelightDigitalBidAdapter.js +6 -1
  168. package/modules/limelightDigitalBidAdapter.md +12 -2
  169. package/modules/liveIntentIdSystem.js +1 -1
  170. package/modules/livewrappedBidAdapter.js +28 -16
  171. package/modules/mediagoBidAdapter.js +22 -17
  172. package/modules/minutemediaplusBidAdapter.js +291 -0
  173. package/modules/minutemediaplusBidAdapter.md +35 -0
  174. package/modules/neuwoRtdProvider.js +171 -0
  175. package/modules/neuwoRtdProvider.md +40 -0
  176. package/modules/nextMillenniumBidAdapter.js +9 -1
  177. package/modules/nexx360BidAdapter.js +1 -1
  178. package/modules/prebidServerBidAdapter/ortbConverter.js +6 -0
  179. package/modules/proxistoreBidAdapter.js +2 -2
  180. package/modules/pubmaticBidAdapter.js +4 -0
  181. package/modules/pubxaiAnalyticsAdapter.js +2 -2
  182. package/modules/scatteredBidAdapter.js +72 -0
  183. package/modules/scatteredBidAdapter.md +36 -0
  184. package/modules/sirdataRtdProvider.js +262 -284
  185. package/modules/smartxBidAdapter.js +2 -0
  186. package/modules/smilewantedBidAdapter.js +5 -0
  187. package/modules/sonobiBidAdapter.js +1 -10
  188. package/modules/topicsFpdModule.md +62 -0
  189. package/modules/tripleliftBidAdapter.js +4 -0
  190. package/modules/userId/eids.js +1 -1
  191. package/modules/vidazooBidAdapter.js +3 -1
  192. package/modules/yahoosspBidAdapter.js +1 -1
  193. package/modules/yieldmoBidAdapter.js +1 -0
  194. package/package.json +2 -2
  195. package/src/adapterManager.js +30 -14
  196. package/src/utils.js +1 -1
  197. package/test/spec/modules/33acrossBidAdapter_spec.js +51 -18
  198. package/test/spec/modules/adagioBidAdapter_spec.js +2 -2
  199. package/test/spec/modules/admaruBidAdapter_spec.js +48 -0
  200. package/test/spec/modules/aidemBidAdapter_spec.js +77 -10
  201. package/test/spec/modules/ajaBidAdapter_spec.js +21 -1
  202. package/test/spec/modules/aolBidAdapter_spec.js +2 -2
  203. package/test/spec/modules/appnexusBidAdapter_spec.js +123 -16
  204. package/test/spec/modules/brightcomSSPBidAdapter_spec.js +411 -0
  205. package/test/spec/modules/criteoBidAdapter_spec.js +24 -1
  206. package/test/spec/modules/eids_spec.js +1 -1
  207. package/test/spec/modules/feedadBidAdapter_spec.js +47 -77
  208. package/test/spec/modules/freewheel-sspBidAdapter_spec.js +1 -1
  209. package/test/spec/modules/incrxBidAdapter_spec.js +4 -0
  210. package/test/spec/modules/ixBidAdapter_spec.js +24 -54
  211. package/test/spec/modules/kueezRtbBidAdapter_spec.js +63 -22
  212. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +35 -5
  213. package/test/spec/modules/livewrappedBidAdapter_spec.js +267 -2
  214. package/test/spec/modules/minutemediaplusBidAdapter_spec.js +519 -0
  215. package/test/spec/modules/neuwoRtdProvider_spec.js +123 -0
  216. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +11 -0
  217. package/test/spec/modules/prebidServerBidAdapter_spec.js +56 -0
  218. package/test/spec/modules/proxistoreBidAdapter_spec.js +2 -2
  219. package/test/spec/modules/pubmaticBidAdapter_spec.js +15 -0
  220. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +3 -1
  221. package/test/spec/modules/scatteredBidAdapter_spec.js +210 -0
  222. package/test/spec/modules/sirdataRtdProvider_spec.js +116 -22
  223. package/test/spec/modules/smilewantedBidAdapter_spec.js +54 -3
  224. package/test/spec/modules/sonobiBidAdapter_spec.js +3 -25
  225. package/test/spec/modules/tripleliftBidAdapter_spec.js +9 -2
  226. package/test/spec/modules/userId_spec.js +1 -1
  227. package/test/spec/modules/vidazooBidAdapter_spec.js +4 -1
  228. package/test/spec/modules/yahoosspBidAdapter_spec.js +1 -1
  229. package/test/spec/unit/core/adapterManager_spec.js +147 -0
@@ -0,0 +1,519 @@
1
+ import { expect } from 'chai';
2
+ import {
3
+ spec as adapter,
4
+ SUPPORTED_ID_SYSTEMS,
5
+ createDomain,
6
+ hashCode,
7
+ extractPID,
8
+ extractCID,
9
+ extractSubDomain,
10
+ getStorageItem,
11
+ setStorageItem,
12
+ tryParseJSON,
13
+ getUniqueDealId,
14
+ } from 'modules/minutemediaplusBidAdapter.js';
15
+ import * as utils from 'src/utils.js';
16
+ import { version } from 'package.json';
17
+ import { useFakeTimers } from 'sinon';
18
+ import { BANNER, VIDEO } from '../../../src/mediaTypes';
19
+
20
+ const SUB_DOMAIN = 'exchange';
21
+
22
+ const BID = {
23
+ 'bidId': '2d52001cabd527',
24
+ 'adUnitCode': 'div-gpt-ad-12345-0',
25
+ 'params': {
26
+ 'subDomain': SUB_DOMAIN,
27
+ 'cId': '59db6b3b4ffaa70004f45cdc',
28
+ 'pId': '59ac17c192832d0011283fe3',
29
+ 'bidFloor': 0.1,
30
+ 'ext': {
31
+ 'param1': 'loremipsum',
32
+ 'param2': 'dolorsitamet'
33
+ }
34
+ },
35
+ 'placementCode': 'div-gpt-ad-1460505748561-0',
36
+ 'transactionId': 'c881914b-a3b5-4ecf-ad9c-1c2f37c6aabf',
37
+ 'sizes': [[300, 250], [300, 600]],
38
+ 'bidderRequestId': '1fdb5ff1b6eaa7',
39
+ 'requestId': 'b0777d85-d061-450e-9bc7-260dd54bbb7a',
40
+ 'schain': 'a0819c69-005b-41ed-af06-1be1e0aefefc',
41
+ 'mediaTypes': [BANNER]
42
+ };
43
+
44
+ const VIDEO_BID = {
45
+ 'bidId': '2d52001cabd527',
46
+ 'adUnitCode': '63550ad1ff6642d368cba59dh5884270560',
47
+ 'bidderRequestId': '12a8ae9ada9c13',
48
+ 'transactionId': '56e184c6-bde9-497b-b9b9-cf47a61381ee',
49
+ 'schain': 'a0819c69-005b-41ed-af06-1be1e0aefefc',
50
+ 'params': {
51
+ 'subDomain': SUB_DOMAIN,
52
+ 'cId': '635509f7ff6642d368cb9837',
53
+ 'pId': '59ac17c192832d0011283fe3',
54
+ 'bidFloor': 0.1
55
+ },
56
+ 'sizes': [[545, 307]],
57
+ 'mediaTypes': {
58
+ 'video': {
59
+ 'playerSize': [[545, 307]],
60
+ 'context': 'instream',
61
+ 'mimes': [
62
+ 'video/mp4',
63
+ 'application/javascript'
64
+ ],
65
+ 'protocols': [2, 3, 5, 6],
66
+ 'maxduration': 60,
67
+ 'minduration': 0,
68
+ 'startdelay': 0,
69
+ 'linearity': 1,
70
+ 'api': [2],
71
+ 'placement': 1
72
+ }
73
+ }
74
+ }
75
+
76
+ const BIDDER_REQUEST = {
77
+ 'gdprConsent': {
78
+ 'consentString': 'consent_string',
79
+ 'gdprApplies': true
80
+ },
81
+ 'uspConsent': 'consent_string',
82
+ 'refererInfo': {
83
+ 'page': 'https://www.greatsite.com',
84
+ 'ref': 'https://www.somereferrer.com'
85
+ }
86
+ };
87
+
88
+ const SERVER_RESPONSE = {
89
+ body: {
90
+ cid: 'testcid123',
91
+ results: [{
92
+ 'ad': '<iframe>console.log("hello world")</iframe>',
93
+ 'price': 0.8,
94
+ 'creativeId': '12610997325162499419',
95
+ 'exp': 30,
96
+ 'width': 300,
97
+ 'height': 250,
98
+ 'advertiserDomains': ['securepubads.g.doubleclick.net'],
99
+ 'cookies': [{
100
+ 'src': 'https://sync.com',
101
+ 'type': 'iframe'
102
+ }, {
103
+ 'src': 'https://sync.com',
104
+ 'type': 'img'
105
+ }]
106
+ }]
107
+ }
108
+ };
109
+
110
+ const VIDEO_SERVER_RESPONSE = {
111
+ body: {
112
+ 'cid': '635509f7ff6642d368cb9837',
113
+ 'results': [{
114
+ 'ad': '<VAST version=\"3.0\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"></VAST>',
115
+ 'advertiserDomains': ['minutemedia-prebid.com'],
116
+ 'exp': 60,
117
+ 'width': 545,
118
+ 'height': 307,
119
+ 'mediaType': 'video',
120
+ 'creativeId': '12610997325162499419',
121
+ 'price': 2,
122
+ 'cookies': []
123
+ }]
124
+ }
125
+ };
126
+
127
+ const REQUEST = {
128
+ data: {
129
+ width: 300,
130
+ height: 250,
131
+ bidId: '2d52001cabd527'
132
+ }
133
+ };
134
+
135
+ function getTopWindowQueryParams() {
136
+ try {
137
+ const parsedUrl = utils.parseUrl(window.top.document.URL, { decodeSearchAsString: true });
138
+ return parsedUrl.search;
139
+ } catch (e) {
140
+ return '';
141
+ }
142
+ }
143
+
144
+ describe('MinuteMediaPlus Bid Adapter', function () {
145
+ describe('validtae spec', function () {
146
+ it('exists and is a function', function () {
147
+ expect(adapter.isBidRequestValid).to.exist.and.to.be.a('function');
148
+ });
149
+
150
+ it('exists and is a function', function () {
151
+ expect(adapter.buildRequests).to.exist.and.to.be.a('function');
152
+ });
153
+
154
+ it('exists and is a function', function () {
155
+ expect(adapter.interpretResponse).to.exist.and.to.be.a('function');
156
+ });
157
+
158
+ it('exists and is a function', function () {
159
+ expect(adapter.getUserSyncs).to.exist.and.to.be.a('function');
160
+ });
161
+
162
+ it('exists and is a string', function () {
163
+ expect(adapter.code).to.exist.and.to.be.a('string');
164
+ });
165
+
166
+ it('exists and contains media types', function () {
167
+ expect(adapter.supportedMediaTypes).to.exist.and.to.be.an('array').with.length(2);
168
+ expect(adapter.supportedMediaTypes).to.contain.members([BANNER, VIDEO]);
169
+ });
170
+ });
171
+
172
+ describe('validate bid requests', function () {
173
+ it('should require cId', function () {
174
+ const isValid = adapter.isBidRequestValid({
175
+ params: {
176
+ pId: 'pid'
177
+ }
178
+ });
179
+ expect(isValid).to.be.false;
180
+ });
181
+
182
+ it('should require pId', function () {
183
+ const isValid = adapter.isBidRequestValid({
184
+ params: {
185
+ cId: 'cid'
186
+ }
187
+ });
188
+ expect(isValid).to.be.false;
189
+ });
190
+
191
+ it('should validate correctly', function () {
192
+ const isValid = adapter.isBidRequestValid({
193
+ params: {
194
+ cId: 'cid',
195
+ pId: 'pid'
196
+ }
197
+ });
198
+ expect(isValid).to.be.true;
199
+ });
200
+ });
201
+
202
+ describe('build requests', function () {
203
+ let sandbox;
204
+ before(function () {
205
+ $$PREBID_GLOBAL$$.bidderSettings = {
206
+ mmplus: {
207
+ storageAllowed: true
208
+ }
209
+ };
210
+ sandbox = sinon.sandbox.create();
211
+ sandbox.stub(Date, 'now').returns(1000);
212
+ });
213
+
214
+ it('should build video request', function () {
215
+ const hashUrl = hashCode(BIDDER_REQUEST.refererInfo.page);
216
+ const requests = adapter.buildRequests([VIDEO_BID], BIDDER_REQUEST);
217
+ expect(requests).to.have.length(1);
218
+ expect(requests[0]).to.deep.equal({
219
+ method: 'POST',
220
+ url: `${createDomain(SUB_DOMAIN)}/prebid/multi/635509f7ff6642d368cb9837`,
221
+ data: {
222
+ adUnitCode: '63550ad1ff6642d368cba59dh5884270560',
223
+ bidFloor: 0.1,
224
+ bidId: '2d52001cabd527',
225
+ bidderVersion: adapter.version,
226
+ cb: 1000,
227
+ gdpr: 1,
228
+ gdprConsent: 'consent_string',
229
+ usPrivacy: 'consent_string',
230
+ prebidVersion: version,
231
+ publisherId: '59ac17c192832d0011283fe3',
232
+ url: 'https%3A%2F%2Fwww.greatsite.com',
233
+ referrer: 'https://www.somereferrer.com',
234
+ res: `${window.top.screen.width}x${window.top.screen.height}`,
235
+ schain: VIDEO_BID.schain,
236
+ sizes: ['545x307'],
237
+ uniqueDealId: `${hashUrl}_${Date.now().toString()}`,
238
+ uqs: getTopWindowQueryParams(),
239
+ mediaTypes: {
240
+ video: {
241
+ api: [2],
242
+ context: 'instream',
243
+ linearity: 1,
244
+ maxduration: 60,
245
+ mimes: [
246
+ 'video/mp4',
247
+ 'application/javascript'
248
+ ],
249
+ minduration: 0,
250
+ placement: 1,
251
+ playerSize: [[545, 307]],
252
+ protocols: [2, 3, 5, 6],
253
+ startdelay: 0
254
+ }
255
+ }
256
+ }
257
+ });
258
+ });
259
+
260
+ it('should build banner request for each size', function () {
261
+ const hashUrl = hashCode(BIDDER_REQUEST.refererInfo.page);
262
+ const requests = adapter.buildRequests([BID], BIDDER_REQUEST);
263
+ expect(requests).to.have.length(1);
264
+ expect(requests[0]).to.deep.equal({
265
+ method: 'POST',
266
+ url: `${createDomain(SUB_DOMAIN)}/prebid/multi/59db6b3b4ffaa70004f45cdc`,
267
+ data: {
268
+ gdprConsent: 'consent_string',
269
+ gdpr: 1,
270
+ usPrivacy: 'consent_string',
271
+ sizes: ['300x250', '300x600'],
272
+ url: 'https%3A%2F%2Fwww.greatsite.com',
273
+ referrer: 'https://www.somereferrer.com',
274
+ cb: 1000,
275
+ bidFloor: 0.1,
276
+ bidId: '2d52001cabd527',
277
+ adUnitCode: 'div-gpt-ad-12345-0',
278
+ publisherId: '59ac17c192832d0011283fe3',
279
+ uniqueDealId: `${hashUrl}_${Date.now().toString()}`,
280
+ bidderVersion: adapter.version,
281
+ prebidVersion: version,
282
+ schain: BID.schain,
283
+ res: `${window.top.screen.width}x${window.top.screen.height}`,
284
+ mediaTypes: [BANNER],
285
+ uqs: getTopWindowQueryParams(),
286
+ 'ext.param1': 'loremipsum',
287
+ 'ext.param2': 'dolorsitamet',
288
+ }
289
+ });
290
+ });
291
+
292
+ after(function () {
293
+ $$PREBID_GLOBAL$$.bidderSettings = {};
294
+ sandbox.restore();
295
+ });
296
+ });
297
+ describe('getUserSyncs', function () {
298
+ it('should have valid user sync with iframeEnabled', function () {
299
+ const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]);
300
+
301
+ expect(result).to.deep.equal([{
302
+ type: 'iframe',
303
+ url: 'https://sync.minutemedia-prebid.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy='
304
+ }]);
305
+ });
306
+
307
+ it('should have valid user sync with cid on response', function () {
308
+ const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]);
309
+ expect(result).to.deep.equal([{
310
+ type: 'iframe',
311
+ url: 'https://sync.minutemedia-prebid.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy='
312
+ }]);
313
+ });
314
+
315
+ it('should have valid user sync with pixelEnabled', function () {
316
+ const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE]);
317
+
318
+ expect(result).to.deep.equal([{
319
+ 'url': 'https://sync.minutemedia-prebid.com/api/sync/image/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=',
320
+ 'type': 'image'
321
+ }]);
322
+ })
323
+ });
324
+
325
+ describe('interpret response', function () {
326
+ it('should return empty array when there is no response', function () {
327
+ const responses = adapter.interpretResponse(null);
328
+ expect(responses).to.be.empty;
329
+ });
330
+
331
+ it('should return empty array when there is no ad', function () {
332
+ const responses = adapter.interpretResponse({ price: 1, ad: '' });
333
+ expect(responses).to.be.empty;
334
+ });
335
+
336
+ it('should return empty array when there is no price', function () {
337
+ const responses = adapter.interpretResponse({ price: null, ad: 'great ad' });
338
+ expect(responses).to.be.empty;
339
+ });
340
+
341
+ it('should return an array of interpreted banner responses', function () {
342
+ const responses = adapter.interpretResponse(SERVER_RESPONSE, REQUEST);
343
+ expect(responses).to.have.length(1);
344
+ expect(responses[0]).to.deep.equal({
345
+ requestId: '2d52001cabd527',
346
+ cpm: 0.8,
347
+ width: 300,
348
+ height: 250,
349
+ creativeId: '12610997325162499419',
350
+ currency: 'USD',
351
+ netRevenue: true,
352
+ ttl: 30,
353
+ ad: '<iframe>console.log("hello world")</iframe>',
354
+ meta: {
355
+ advertiserDomains: ['securepubads.g.doubleclick.net']
356
+ }
357
+ });
358
+ });
359
+
360
+ it('should return an array of interpreted video responses', function () {
361
+ const responses = adapter.interpretResponse(VIDEO_SERVER_RESPONSE, REQUEST);
362
+ expect(responses).to.have.length(1);
363
+ expect(responses[0]).to.deep.equal({
364
+ requestId: '2d52001cabd527',
365
+ cpm: 2,
366
+ width: 545,
367
+ height: 307,
368
+ mediaType: 'video',
369
+ creativeId: '12610997325162499419',
370
+ currency: 'USD',
371
+ netRevenue: true,
372
+ ttl: 60,
373
+ vastXml: '<VAST version=\"3.0\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"></VAST>',
374
+ meta: {
375
+ advertiserDomains: ['minutemedia-prebid.com']
376
+ }
377
+ });
378
+ });
379
+
380
+ it('should take default TTL', function () {
381
+ const serverResponse = utils.deepClone(SERVER_RESPONSE);
382
+ delete serverResponse.body.results[0].exp;
383
+ const responses = adapter.interpretResponse(serverResponse, REQUEST);
384
+ expect(responses).to.have.length(1);
385
+ expect(responses[0].ttl).to.equal(300);
386
+ });
387
+ });
388
+
389
+ describe('user id system', function () {
390
+ Object.keys(SUPPORTED_ID_SYSTEMS).forEach((idSystemProvider) => {
391
+ const id = Date.now().toString();
392
+ const bid = utils.deepClone(BID);
393
+
394
+ const userId = (function () {
395
+ switch (idSystemProvider) {
396
+ case 'lipb':
397
+ return { lipbid: id };
398
+ case 'parrableId':
399
+ return { eid: id };
400
+ case 'id5id':
401
+ return { uid: id };
402
+ default:
403
+ return id;
404
+ }
405
+ })();
406
+
407
+ bid.userId = {
408
+ [idSystemProvider]: userId
409
+ };
410
+
411
+ it(`should include 'uid.${idSystemProvider}' in request params`, function () {
412
+ const requests = adapter.buildRequests([bid], BIDDER_REQUEST);
413
+ expect(requests[0].data[`uid.${idSystemProvider}`]).to.equal(id);
414
+ });
415
+ });
416
+ });
417
+
418
+ describe('alternate param names extractors', function () {
419
+ it('should return undefined when param not supported', function () {
420
+ const cid = extractCID({ 'c_id': '1' });
421
+ const pid = extractPID({ 'p_id': '1' });
422
+ const subDomain = extractSubDomain({ 'sub_domain': 'prebid' });
423
+ expect(cid).to.be.undefined;
424
+ expect(pid).to.be.undefined;
425
+ expect(subDomain).to.be.undefined;
426
+ });
427
+
428
+ it('should return value when param supported', function () {
429
+ const cid = extractCID({ 'cID': '1' });
430
+ const pid = extractPID({ 'Pid': '2' });
431
+ const subDomain = extractSubDomain({ 'subDOMAIN': 'prebid' });
432
+ expect(cid).to.be.equal('1');
433
+ expect(pid).to.be.equal('2');
434
+ expect(subDomain).to.be.equal('prebid');
435
+ });
436
+ });
437
+
438
+ describe('unique deal id', function () {
439
+ before(function () {
440
+ $$PREBID_GLOBAL$$.bidderSettings = {
441
+ mmplus: {
442
+ storageAllowed: true
443
+ }
444
+ };
445
+ });
446
+ after(function () {
447
+ $$PREBID_GLOBAL$$.bidderSettings = {};
448
+ });
449
+ const key = 'myKey';
450
+ let uniqueDealId;
451
+ beforeEach(() => {
452
+ uniqueDealId = getUniqueDealId(key, 0);
453
+ })
454
+
455
+ it('should get current unique deal id', function (done) {
456
+ // waiting some time so `now` will become past
457
+ setTimeout(() => {
458
+ const current = getUniqueDealId(key);
459
+ expect(current).to.be.equal(uniqueDealId);
460
+ done();
461
+ }, 200);
462
+ });
463
+
464
+ it('should get new unique deal id on expiration', function (done) {
465
+ setTimeout(() => {
466
+ const current = getUniqueDealId(key, 100);
467
+ expect(current).to.not.be.equal(uniqueDealId);
468
+ done();
469
+ }, 200)
470
+ });
471
+ });
472
+
473
+ describe('storage utils', function () {
474
+ before(function () {
475
+ $$PREBID_GLOBAL$$.bidderSettings = {
476
+ mmplus: {
477
+ storageAllowed: true
478
+ }
479
+ };
480
+ });
481
+ after(function () {
482
+ $$PREBID_GLOBAL$$.bidderSettings = {};
483
+ });
484
+ it('should get value from storage with create param', function () {
485
+ const now = Date.now();
486
+ const clock = useFakeTimers({
487
+ shouldAdvanceTime: true,
488
+ now
489
+ });
490
+ setStorageItem('myKey', 2020);
491
+ const { value, created } = getStorageItem('myKey');
492
+ expect(created).to.be.equal(now);
493
+ expect(value).to.be.equal(2020);
494
+ expect(typeof value).to.be.equal('number');
495
+ expect(typeof created).to.be.equal('number');
496
+ clock.restore();
497
+ });
498
+
499
+ it('should get external stored value', function () {
500
+ const value = 'superman'
501
+ window.localStorage.setItem('myExternalKey', value);
502
+ const item = getStorageItem('myExternalKey');
503
+ expect(item).to.be.equal(value);
504
+ });
505
+
506
+ it('should parse JSON value', function () {
507
+ const data = JSON.stringify({ event: 'send' });
508
+ const { event } = tryParseJSON(data);
509
+ expect(event).to.be.equal('send');
510
+ });
511
+
512
+ it('should get original value on parse fail', function () {
513
+ const value = 21;
514
+ const parsed = tryParseJSON(value);
515
+ expect(typeof parsed).to.be.equal('number');
516
+ expect(parsed).to.be.equal(value);
517
+ });
518
+ });
519
+ });
@@ -0,0 +1,123 @@
1
+ import { server } from 'test/mocks/xhr.js';
2
+ import * as neuwo from 'modules/neuwoRtdProvider';
3
+
4
+ const PUBLIC_TOKEN = 'public_key_0000';
5
+ const config = () => ({
6
+ params: {
7
+ publicToken: PUBLIC_TOKEN
8
+ }
9
+ })
10
+
11
+ const apiReturns = () => ({
12
+ somethingExtra: { object: true },
13
+ marketing_categories: {
14
+ iab_tier_1: [
15
+ { ID: 'IAB21', label: 'Real Estate', relevance: '0.45699' }
16
+ ]
17
+ }
18
+ })
19
+
20
+ const TAX_ID = '441'
21
+
22
+ /**
23
+ * Object generator, like above, written using alternative techniques
24
+ * @returns object with predefined (expected) bidsConfig fields
25
+ */
26
+ function bidsConfiglike() {
27
+ return Object.assign({}, {
28
+ ortb2Fragments: { global: {} }
29
+ })
30
+ }
31
+
32
+ describe('neuwoRtdProvider', function () {
33
+ describe('neuwoRtdModule', function () {
34
+ it('initializes', function () {
35
+ expect(neuwo.neuwoRtdModule.init(config())).to.be.true;
36
+ })
37
+ it('init needs that public token', function () {
38
+ expect(neuwo.neuwoRtdModule.init()).to.be.false;
39
+ })
40
+
41
+ describe('segment picking', function () {
42
+ it('handles bad inputs', function () {
43
+ expect(neuwo.pickSegments()).to.be.an('array').that.is.empty;
44
+ expect(neuwo.pickSegments('technically also an array')).to.be.an('array').that.is.empty;
45
+ expect(neuwo.pickSegments({ bad_object: 'bad' })).to.be.an('array').that.is.empty;
46
+ })
47
+ it('handles malformations', function () {
48
+ let result = neuwo.pickSegments([{something_wrong: true}, null, { ID: 'IAB19-20' }, { id: 'IAB3-1', ID: 'IAB9-20' }])
49
+ expect(result[0].id).to.equal('631')
50
+ expect(result[1].id).to.equal('58')
51
+ expect(result.length).to.equal(2)
52
+ })
53
+ })
54
+
55
+ describe('topic injection', function () {
56
+ it('mutates bidsConfig', function () {
57
+ let topics = apiReturns()
58
+ let bidsConfig = bidsConfiglike()
59
+ neuwo.injectTopics(topics, bidsConfig, () => { })
60
+ expect(bidsConfig.ortb2Fragments.global.site.content.data[0].name, 'name of first content data object').to.equal(neuwo.DATA_PROVIDER)
61
+ expect(bidsConfig.ortb2Fragments.global.site.content.data[0].segment[0].id, 'id of first segment in content.data').to.equal(TAX_ID)
62
+ expect(bidsConfig.ortb2Fragments.global.site.cattax, 'category taxonomy code for pagecat').to.equal(6) // CATTAX_IAB
63
+ expect(bidsConfig.ortb2Fragments.global.site.pagecat[0], 'category taxonomy code for pagecat').to.equal(TAX_ID)
64
+ })
65
+
66
+ it('handles malformed responses', function () {
67
+ let topics = { message: 'Forbidden' }
68
+ let bidsConfig = bidsConfiglike()
69
+ neuwo.injectTopics(topics, bidsConfig, () => { })
70
+ expect(bidsConfig.ortb2Fragments.global.site.content.data[0].name, 'name of first content data object').to.equal(neuwo.DATA_PROVIDER)
71
+ expect(bidsConfig.ortb2Fragments.global.site.content.data[0].segment, 'length of segment(s) in content.data').to.be.an('array').that.is.empty;
72
+
73
+ topics = '404 wouldn\'t really even show up for injection'
74
+ let bdsConfig = bidsConfiglike()
75
+ neuwo.injectTopics(topics, bdsConfig, () => { })
76
+ expect(bdsConfig.ortb2Fragments.global.site.content.data[0].name, 'name of first content data object').to.equal(neuwo.DATA_PROVIDER)
77
+ expect(bdsConfig.ortb2Fragments.global.site.content.data[0].segment, 'length of segment(s) in content.data').to.be.an('array').that.is.empty;
78
+
79
+ topics = undefined
80
+ let bdsConfigE = bidsConfiglike()
81
+ neuwo.injectTopics(topics, bdsConfigE, () => { })
82
+ expect(bdsConfigE.ortb2Fragments.global.site.content.data[0].name, 'name of first content data object').to.equal(neuwo.DATA_PROVIDER)
83
+ expect(bdsConfigE.ortb2Fragments.global.site.content.data[0].segment, 'length of segment(s) in content.data').to.be.an('array').that.is.empty;
84
+ })
85
+ })
86
+
87
+ describe('fragment addition', function () {
88
+ it('mutates input objects', function () {
89
+ let alphabet = { a: { b: { c: {} } } }
90
+ neuwo.addFragment(alphabet.a.b.c, 'd.e.f', { g: 'h' })
91
+ expect(alphabet.a.b.c.d.e.f.g).to.equal('h')
92
+ })
93
+ })
94
+
95
+ describe('getBidRequestData', function () {
96
+ it('forms requests properly and mutates input bidsConfig', function () {
97
+ let bids = bidsConfiglike()
98
+ let conf = config()
99
+ // control xhr api request target for testing
100
+ conf.params.argUrl = 'https://publisher.works/article.php?get=horrible_url_for_testing&id=5'
101
+
102
+ neuwo.getBidRequestData(bids, () => { }, conf, 'any consent data works, clearly')
103
+
104
+ let request = server.requests[0];
105
+ expect(request.url).to.be.a('string').that.includes(conf.params.publicToken)
106
+ expect(request.url).to.include(encodeURIComponent(conf.params.argUrl))
107
+ request.respond(200, { 'Content-Type': 'application/json; encoding=UTF-8' }, JSON.stringify(apiReturns()));
108
+
109
+ expect(bids.ortb2Fragments.global.site.content.data[0].name, 'name of first content data object').to.equal(neuwo.DATA_PROVIDER)
110
+ expect(bids.ortb2Fragments.global.site.content.data[0].segment[0].id, 'id of first segment in content.data').to.equal(TAX_ID)
111
+ })
112
+
113
+ it('accepts detail not available result', function () {
114
+ let bidsConfig = bidsConfiglike()
115
+ let comparison = bidsConfiglike()
116
+ neuwo.getBidRequestData(bidsConfig, () => { }, config(), 'consensually')
117
+ let request = server.requests[0];
118
+ request.respond(404, { 'Content-Type': 'application/json; encoding=UTF-8' }, JSON.stringify({ detail: 'Basically first time seeing this' }));
119
+ expect(bidsConfig).to.deep.equal(comparison)
120
+ })
121
+ })
122
+ })
123
+ })
@@ -142,6 +142,17 @@ describe('nextMillenniumBidAdapterTests', function() {
142
142
  expect(userSync[0].url).to.equal('urlB');
143
143
  });
144
144
 
145
+ it('Test getUserSyncs with no response', function () {
146
+ const syncOptions = {
147
+ 'iframeEnabled': true,
148
+ 'pixelEnabled': false
149
+ }
150
+ let userSync = spec.getUserSyncs(syncOptions, [], bidRequestData[0].gdprConsent, bidRequestData[0].uspConsent);
151
+ expect(userSync).to.be.an('array')
152
+ expect(userSync[0].type).to.equal('iframe')
153
+ expect(userSync[0].url).to.equal('https://cookies.nextmillmedia.com/sync?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&type=iframe')
154
+ })
155
+
145
156
  it('Test getUserSyncs function if GDPR is undefined', function () {
146
157
  const syncOptions = {
147
158
  'iframeEnabled': false,