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,3 +1,4 @@
1
+ import { config } from 'src/config.js';
1
2
  import { expect } from 'chai'
2
3
  import { spec } from 'modules/yieldlabBidAdapter.js'
3
4
  import { newBidder } from 'src/adapters/bidderFactory.js'
@@ -16,7 +17,22 @@ const REQUEST = {
16
17
  'extraParam': true,
17
18
  'foo': 'bar'
18
19
  },
19
- 'extId': 'abc'
20
+ 'extId': 'abc',
21
+ 'iabContent': {
22
+ 'id': 'foo_id',
23
+ 'episode': '99',
24
+ 'title': 'foo_title,bar_title',
25
+ 'series': 'foo_series',
26
+ 'season': 's1',
27
+ 'artist': 'foo bar',
28
+ 'genre': 'baz',
29
+ 'isrc': 'CC-XXX-YY-NNNNN',
30
+ 'url': 'http://foo_url.de',
31
+ 'cat': ['cat1', 'cat2,ppp', 'cat3|||//'],
32
+ 'context': '7',
33
+ 'keywords': ['k1,', 'k2..'],
34
+ 'live': '0'
35
+ }
20
36
  },
21
37
  'bidderRequestId': '143346cf0f1731',
22
38
  'auctionId': '2e41f65424c87c',
@@ -86,6 +102,10 @@ const REQPARAMS_GDPR = Object.assign({}, REQPARAMS, {
86
102
  consent: 'BN5lERiOMYEdiAKAWXEND1AAAAE6DABACMA'
87
103
  })
88
104
 
105
+ const REQPARAMS_IAB_CONTENT = Object.assign({}, REQPARAMS, {
106
+ iab_content: 'id%3Afoo_id%2Cepisode%3A99%2Ctitle%3Afoo_title%252Cbar_title%2Cseries%3Afoo_series%2Cseason%3As1%2Cartist%3Afoo%2520bar%2Cgenre%3Abaz%2Cisrc%3ACC-XXX-YY-NNNNN%2Curl%3Ahttp%253A%252F%252Ffoo_url.de%2Ccat%3Acat1%7Ccat2%252Cppp%7Ccat3%257C%257C%257C%252F%252F%2Ccontext%3A7%2Ckeywords%3Ak1%252C%7Ck2..%2Clive%3A0'
107
+ })
108
+
89
109
  describe('yieldlabBidAdapter', function () {
90
110
  const adapter = newBidder(spec)
91
111
 
@@ -139,6 +159,40 @@ describe('yieldlabBidAdapter', function () {
139
159
  expect(request.url).to.include('schain=1.0,1!indirectseller.com,1,1,,,,!indirectseller2.com,2,1,,indirectseller2%20name%20with%20comma%20%2C%20and%20bang%20%21,,')
140
160
  })
141
161
 
162
+ it('passes iab_content string to bid request', function () {
163
+ expect(request.url).to.include('iab_content=id%3Afoo_id%2Cepisode%3A99%2Ctitle%3Afoo_title%252Cbar_title%2Cseries%3Afoo_series%2Cseason%3As1%2Cartist%3Afoo%2520bar%2Cgenre%3Abaz%2Cisrc%3ACC-XXX-YY-NNNNN%2Curl%3Ahttp%253A%252F%252Ffoo_url.de%2Ccat%3Acat1%7Ccat2%252Cppp%7Ccat3%257C%257C%257C%252F%252F%2Ccontext%3A7%2Ckeywords%3Ak1%252C%7Ck2..%2Clive%3A0')
164
+ })
165
+
166
+ const siteConfig = {
167
+ 'ortb2': {
168
+ 'site': {
169
+ 'content': {
170
+ 'id': 'id_from_config'
171
+ }
172
+ }
173
+ }
174
+ }
175
+
176
+ it('generates iab_content string from bidder params', function () {
177
+ config.setConfig(siteConfig);
178
+ const request = spec.buildRequests([REQUEST])
179
+ expect(request.url).to.include('iab_content=id%3Afoo_id%2Cepisode%3A99%2Ctitle%3Afoo_title%252Cbar_title%2Cseries%3Afoo_series%2Cseason%3As1%2Cartist%3Afoo%2520bar%2Cgenre%3Abaz%2Cisrc%3ACC-XXX-YY-NNNNN%2Curl%3Ahttp%253A%252F%252Ffoo_url.de%2Ccat%3Acat1%7Ccat2%252Cppp%7Ccat3%257C%257C%257C%252F%252F%2Ccontext%3A7%2Ckeywords%3Ak1%252C%7Ck2..%2Clive%3A0')
180
+ config.resetConfig();
181
+ })
182
+
183
+ it('generates iab_content string from first party data if not provided in bidder params', function () {
184
+ const requestWithoutIabContent = {
185
+ 'params': {
186
+ 'adslotId': '1111',
187
+ 'supplyId': '2222'
188
+ }
189
+ }
190
+ config.setConfig(siteConfig);
191
+ const request = spec.buildRequests([requestWithoutIabContent])
192
+ expect(request.url).to.include('iab_content=id%3Aid_from_config')
193
+ config.resetConfig();
194
+ })
195
+
142
196
  const refererRequest = spec.buildRequests(bidRequests, {
143
197
  refererInfo: {
144
198
  canonicalUrl: undefined,
@@ -203,6 +257,11 @@ describe('yieldlabBidAdapter', function () {
203
257
  expect(result[0].ad).to.include('&consent=BN5lERiOMYEdiAKAWXEND1AAAAE6DABACMA')
204
258
  })
205
259
 
260
+ it('should append iab_content to adtag', function () {
261
+ const result = spec.interpretResponse({body: [RESPONSE]}, {validBidRequests: [REQUEST], queryParams: REQPARAMS_IAB_CONTENT})
262
+ expect(result[0].ad).to.include('&iab_content=id%3Afoo_id%2Cepisode%3A99%2Ctitle%3Afoo_title%252Cbar_title%2Cseries%3Afoo_series%2Cseason%3As1%2Cartist%3Afoo%2520bar%2Cgenre%3Abaz%2Cisrc%3ACC-XXX-YY-NNNNN%2Curl%3Ahttp%253A%252F%252Ffoo_url.de%2Ccat%3Acat1%7Ccat2%252Cppp%7Ccat3%257C%257C%257C%252F%252F%2Ccontext%3A7%2Ckeywords%3Ak1%252C%7Ck2..%2Clive%3A0')
263
+ })
264
+
206
265
  it('should get correct bid response when passing more than one size', function () {
207
266
  const REQUEST2 = Object.assign({}, REQUEST, {
208
267
  'sizes': [
@@ -268,5 +327,10 @@ describe('yieldlabBidAdapter', function () {
268
327
  expect(result[0].ad).to.include('&pvid=43513f11-55a0-4a83-94e5-0ebc08f54a2c')
269
328
  expect(result[0].vastUrl).to.include('&pvid=43513f11-55a0-4a83-94e5-0ebc08f54a2c')
270
329
  })
330
+
331
+ it('should append iab_content to vastUrl', function () {
332
+ const result = spec.interpretResponse({body: [VIDEO_RESPONSE]}, {validBidRequests: [VIDEO_REQUEST], queryParams: REQPARAMS_IAB_CONTENT})
333
+ expect(result[0].vastUrl).to.include('&iab_content=id%3Afoo_id%2Cepisode%3A99%2Ctitle%3Afoo_title%252Cbar_title%2Cseries%3Afoo_series%2Cseason%3As1%2Cartist%3Afoo%2520bar%2Cgenre%3Abaz%2Cisrc%3ACC-XXX-YY-NNNNN%2Curl%3Ahttp%253A%252F%252Ffoo_url.de%2Ccat%3Acat1%7Ccat2%252Cppp%7Ccat3%257C%257C%257C%252F%252F%2Ccontext%3A7%2Ckeywords%3Ak1%252C%7Ck2..%2Clive%3A0')
334
+ })
271
335
  })
272
336
  })
@@ -307,7 +307,7 @@ describe('YieldmoAdapter', function () {
307
307
  });
308
308
 
309
309
  it('should only shortcut properties rather then completely remove it', () => {
310
- const longString = new Array(7516).join('a');
310
+ const longString = new Array(8000).join('a');
311
311
  const localWindow = utils.getWindowTop();
312
312
 
313
313
  const originalTitle = localWindow.document.title;
@@ -319,7 +319,7 @@ describe('YieldmoAdapter', function () {
319
319
  refererInfo: {
320
320
  numIframes: 1,
321
321
  reachedTop: true,
322
- referer: longString,
322
+ title: longString,
323
323
  },
324
324
  })
325
325
  )[0];
@@ -345,6 +345,20 @@ describe('YieldmoAdapter', function () {
345
345
  let placementInfo = buildAndGetPlacementInfo(bidArray);
346
346
  expect(placementInfo).to.include('"gpid":"/6355419/Travel/Europe/France/Paris"');
347
347
  });
348
+
349
+ it('should add eids to the banner bid request', function () {
350
+ const params = {
351
+ userId: {pubcid: 'fake_pubcid'},
352
+ fakeUserIdAsEids: [{
353
+ source: 'pubcid.org',
354
+ uids: [{
355
+ id: 'fake_pubcid',
356
+ atype: 1
357
+ }]
358
+ }]
359
+ };
360
+ expect(buildAndGetData([mockBannerBid({...params})]).eids).equal(JSON.stringify(params.fakeUserIdAsEids));
361
+ });
348
362
  });
349
363
 
350
364
  describe('Instream video:', function () {
@@ -469,19 +483,26 @@ describe('YieldmoAdapter', function () {
469
483
  expect(buildAndGetData([mockVideoBid({schain})]).schain).to.deep.equal(schain);
470
484
  });
471
485
 
472
- it('should add ip to the video bidRequest', () => {
473
- const device = {
474
- ip: '111.222.333.444'
475
- };
476
- expect(buildAndGetData([mockVideoBid(null, {device})]).device.ip).to.be.equal(device.ip);
477
- });
478
-
479
486
  it('should add gpid to the video request', function () {
480
487
  const ortb2Imp = {
481
488
  ext: { data: { pbadslot: '/6355419/Travel/Europe/France/Paris' } },
482
489
  };
483
490
  expect(buildAndGetData([mockVideoBid({ortb2Imp})]).imp[0].ext.gpid).to.be.equal(ortb2Imp.ext.data.pbadslot);
484
491
  });
492
+
493
+ it('should add eids to the video bid request', function () {
494
+ const params = {
495
+ userId: {pubcid: 'fake_pubcid'},
496
+ fakeUserIdAsEids: [{
497
+ source: 'pubcid.org',
498
+ uids: [{
499
+ id: 'fake_pubcid',
500
+ atype: 1
501
+ }]
502
+ }]
503
+ };
504
+ expect(buildAndGetData([mockVideoBid({...params})]).user.eids).to.eql(params.fakeUserIdAsEids);
505
+ });
485
506
  });
486
507
  });
487
508
 
@@ -0,0 +1,89 @@
1
+ import { expect } from 'chai';
2
+ import {
3
+ init,
4
+ MODULE_NAME,
5
+ validateConfig
6
+ } from 'modules/yieldmoSyntheticInventoryModule';
7
+
8
+ const mockedYmConfig = {
9
+ placementId: '123456',
10
+ adUnitPath: '/6355419/ad_unit_name_used_in_gam'
11
+ };
12
+
13
+ const setGoogletag = () => {
14
+ window.googletag = {
15
+ cmd: [],
16
+ defineSlot: sinon.stub(),
17
+ addService: sinon.stub(),
18
+ pubads: sinon.stub(),
19
+ setTargeting: sinon.stub(),
20
+ enableServices: sinon.stub(),
21
+ display: sinon.stub(),
22
+ };
23
+ window.googletag.defineSlot.returns(window.googletag);
24
+ window.googletag.addService.returns(window.googletag);
25
+ window.googletag.pubads.returns({getSlots: sinon.stub()});
26
+ return window.googletag;
27
+ }
28
+
29
+ describe('Yieldmo Synthetic Inventory Module', function() {
30
+ let config = Object.assign({}, mockedYmConfig);
31
+ let googletagBkp;
32
+
33
+ beforeEach(function () {
34
+ googletagBkp = window.googletag;
35
+ delete window.googletag;
36
+ });
37
+
38
+ afterEach(function () {
39
+ window.googletag = googletagBkp;
40
+ });
41
+
42
+ it('should be enabled with valid required params', function() {
43
+ expect(function () {
44
+ init(mockedYmConfig);
45
+ }).not.to.throw()
46
+ });
47
+
48
+ it('should throw an error if placementId is missed', function() {
49
+ const {placementId, ...config} = mockedYmConfig;
50
+
51
+ expect(function () {
52
+ validateConfig(config);
53
+ }).throw(`${MODULE_NAME}: placementId required`)
54
+ });
55
+
56
+ it('should throw an error if adUnitPath is missed', function() {
57
+ const {adUnitPath, ...config} = mockedYmConfig;
58
+
59
+ expect(function () {
60
+ validateConfig(config);
61
+ }).throw(`${MODULE_NAME}: adUnitPath required`)
62
+ });
63
+
64
+ it('should add correct googletag.cmd', function() {
65
+ const containerName = 'ym_sim_container_' + mockedYmConfig.placementId;
66
+ const gtag = setGoogletag();
67
+
68
+ init(mockedYmConfig);
69
+
70
+ expect(gtag.cmd.length).to.equal(1);
71
+
72
+ gtag.cmd[0]();
73
+
74
+ expect(gtag.addService.getCall(0)).to.not.be.null;
75
+ expect(gtag.setTargeting.getCall(0)).to.not.be.null;
76
+ expect(gtag.setTargeting.getCall(0).args[0]).to.exist.and.to.equal('ym_sim_p_id');
77
+ expect(gtag.setTargeting.getCall(0).args[1]).to.exist.and.to.equal(mockedYmConfig.placementId);
78
+ expect(gtag.defineSlot.getCall(0)).to.not.be.null;
79
+ expect(gtag.enableServices.getCall(0)).to.not.be.null;
80
+ expect(gtag.display.getCall(0)).to.not.be.null;
81
+ expect(gtag.display.getCall(0).args[0]).to.exist.and.to.equal(containerName);
82
+ expect(gtag.pubads.getCall(0)).to.not.be.null;
83
+
84
+ const gamContainerEl = window.document.getElementById(containerName);
85
+ expect(gamContainerEl).to.not.be.null;
86
+
87
+ gamContainerEl.parentNode.removeChild(gamContainerEl);
88
+ });
89
+ });
@@ -436,6 +436,38 @@ describe('adapterManager tests', function () {
436
436
  });
437
437
  }); // end onBidViewable
438
438
 
439
+ describe('onBidderError', function () {
440
+ const bidder = 'appnexus';
441
+ const appnexusSpec = { onBidderError: sinon.stub() };
442
+ const appnexusAdapter = {
443
+ bidder,
444
+ getSpec: function() { return appnexusSpec; },
445
+ }
446
+ before(function () {
447
+ config.setConfig({s2sConfig: { enabled: false }});
448
+ });
449
+
450
+ beforeEach(function () {
451
+ adapterManager.bidderRegistry[bidder] = appnexusAdapter;
452
+ });
453
+
454
+ afterEach(function () {
455
+ delete adapterManager.bidderRegistry[bidder];
456
+ });
457
+
458
+ it('should call spec\'s onBidderError callback when callBidderError is called', function () {
459
+ const bidRequests = getBidRequests();
460
+ const bidderRequest = find(bidRequests, bidRequest => bidRequest.bidderCode === bidder);
461
+ const xhrErrorMock = {
462
+ status: 500,
463
+ statusText: 'Internal Server Error'
464
+ };
465
+ adapterManager.callBidderError(bidder, xhrErrorMock, bidderRequest);
466
+ sinon.assert.calledOnce(appnexusSpec.onBidderError);
467
+ sinon.assert.calledWithExactly(appnexusSpec.onBidderError, { error: xhrErrorMock, bidderRequest });
468
+ });
469
+ }); // end onBidderError
470
+
439
471
  describe('S2S tests', function () {
440
472
  beforeEach(function () {
441
473
  config.setConfig({s2sConfig: CONFIG});
@@ -552,17 +552,27 @@ describe('bidders created by newBidder', function () {
552
552
 
553
553
  describe('when the ajax call fails', function () {
554
554
  let ajaxStub;
555
+ let callBidderErrorStub;
556
+ let eventEmitterStub;
557
+ let xhrErrorMock = {
558
+ status: 500,
559
+ statusText: 'Internal Server Error'
560
+ };
555
561
 
556
562
  beforeEach(function () {
557
563
  ajaxStub = sinon.stub(ajax, 'ajax').callsFake(function(url, callbacks) {
558
- callbacks.error('ajax call failed.');
564
+ callbacks.error('ajax call failed.', xhrErrorMock);
559
565
  });
566
+ callBidderErrorStub = sinon.stub(adapterManager, 'callBidderError');
567
+ eventEmitterStub = sinon.stub(events, 'emit');
560
568
  addBidResponseStub.reset();
561
569
  doneStub.reset();
562
570
  });
563
571
 
564
572
  afterEach(function () {
565
573
  ajaxStub.restore();
574
+ callBidderErrorStub.restore();
575
+ eventEmitterStub.restore();
566
576
  });
567
577
 
568
578
  it('should not spec.interpretResponse()', function () {
@@ -580,6 +590,14 @@ describe('bidders created by newBidder', function () {
580
590
 
581
591
  expect(spec.interpretResponse.called).to.equal(false);
582
592
  expect(doneStub.calledOnce).to.equal(true);
593
+ expect(callBidderErrorStub.calledOnce).to.equal(true);
594
+ expect(callBidderErrorStub.firstCall.args[0]).to.equal(CODE);
595
+ expect(callBidderErrorStub.firstCall.args[1]).to.equal(xhrErrorMock);
596
+ expect(callBidderErrorStub.firstCall.args[2]).to.equal(MOCK_BIDS_REQUEST);
597
+ sinon.assert.calledWith(eventEmitterStub, CONSTANTS.EVENTS.BIDDER_ERROR, {
598
+ error: xhrErrorMock,
599
+ bidderRequest: MOCK_BIDS_REQUEST
600
+ });
583
601
  });
584
602
 
585
603
  it('should not add bids for each adunit code into the auction', function () {
@@ -598,6 +616,14 @@ describe('bidders created by newBidder', function () {
598
616
 
599
617
  expect(addBidResponseStub.callCount).to.equal(0);
600
618
  expect(doneStub.calledOnce).to.equal(true);
619
+ expect(callBidderErrorStub.calledOnce).to.equal(true);
620
+ expect(callBidderErrorStub.firstCall.args[0]).to.equal(CODE);
621
+ expect(callBidderErrorStub.firstCall.args[1]).to.equal(xhrErrorMock);
622
+ expect(callBidderErrorStub.firstCall.args[2]).to.equal(MOCK_BIDS_REQUEST);
623
+ sinon.assert.calledWith(eventEmitterStub, CONSTANTS.EVENTS.BIDDER_ERROR, {
624
+ error: xhrErrorMock,
625
+ bidderRequest: MOCK_BIDS_REQUEST
626
+ });
601
627
  });
602
628
 
603
629
  it('should call spec.getUserSyncs() with no responses', function () {
@@ -616,6 +642,40 @@ describe('bidders created by newBidder', function () {
616
642
  expect(spec.getUserSyncs.calledOnce).to.equal(true);
617
643
  expect(spec.getUserSyncs.firstCall.args[1]).to.deep.equal([]);
618
644
  expect(doneStub.calledOnce).to.equal(true);
645
+ expect(callBidderErrorStub.calledOnce).to.equal(true);
646
+ expect(callBidderErrorStub.firstCall.args[0]).to.equal(CODE);
647
+ expect(callBidderErrorStub.firstCall.args[1]).to.equal(xhrErrorMock);
648
+ expect(callBidderErrorStub.firstCall.args[2]).to.equal(MOCK_BIDS_REQUEST);
649
+ sinon.assert.calledWith(eventEmitterStub, CONSTANTS.EVENTS.BIDDER_ERROR, {
650
+ error: xhrErrorMock,
651
+ bidderRequest: MOCK_BIDS_REQUEST
652
+ });
653
+ });
654
+
655
+ it('should call spec.getUserSyncs() with no responses', function () {
656
+ const bidder = newBidder(spec);
657
+
658
+ spec.isBidRequestValid.returns(true);
659
+ spec.buildRequests.returns({
660
+ method: 'POST',
661
+ url: 'test.url.com',
662
+ data: {}
663
+ });
664
+ spec.getUserSyncs.returns([]);
665
+
666
+ bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
667
+
668
+ expect(spec.getUserSyncs.calledOnce).to.equal(true);
669
+ expect(spec.getUserSyncs.firstCall.args[1]).to.deep.equal([]);
670
+ expect(doneStub.calledOnce).to.equal(true);
671
+ expect(callBidderErrorStub.calledOnce).to.equal(true);
672
+ expect(callBidderErrorStub.firstCall.args[0]).to.equal(CODE);
673
+ expect(callBidderErrorStub.firstCall.args[1]).to.equal(xhrErrorMock);
674
+ expect(callBidderErrorStub.firstCall.args[2]).to.equal(MOCK_BIDS_REQUEST);
675
+ sinon.assert.calledWith(eventEmitterStub, CONSTANTS.EVENTS.BIDDER_ERROR, {
676
+ error: xhrErrorMock,
677
+ bidderRequest: MOCK_BIDS_REQUEST
678
+ });
619
679
  });
620
680
  });
621
681
  });
@@ -98,7 +98,6 @@ var createSlotArrayScenario2 = function createSlotArrayScenario2() {
98
98
  var slot1 = new Slot(config.adUnitElementIDs[0], config.adUnitCodes[0]);
99
99
  slot1.setTargeting('pos1', '750x350');
100
100
  var slot2 = new Slot(config.adUnitElementIDs[1], config.adUnitCodes[0]);
101
- slot2.setTargeting('gender', ['male', 'female']);
102
101
  return [
103
102
  slot1,
104
103
  slot2
@@ -862,6 +861,9 @@ describe('Unit: Prebid Module', function () {
862
861
 
863
862
  it('should set googletag targeting keys after calling setTargetingForGPTAsync function', function () {
864
863
  var slots = createSlotArrayScenario2();
864
+
865
+ // explicitly setting some PBJS key value pairs to verify whether these are removed befor new keys are set
866
+
865
867
  window.googletag.pubads().setSlots(slots);
866
868
  $$PREBID_GLOBAL$$.setTargetingForGPTAsync([config.adUnitCodes[0]]);
867
869
 
@@ -869,7 +871,7 @@ describe('Unit: Prebid Module', function () {
869
871
  // googletag's targeting structure
870
872
  // googletag setTargeting will override old value if invoked with same key
871
873
 
872
- const targeting = [];
874
+ let targeting = [];
873
875
  slots[1].getTargetingKeys().map(function (key) {
874
876
  const value = slots[1].getTargeting(key);
875
877
  targeting.push([key, value]);
@@ -887,6 +889,39 @@ describe('Unit: Prebid Module', function () {
887
889
  invokedTargeting.push([key, value]);
888
890
  });
889
891
  assert.deepEqual(targeting, invokedTargeting, 'google tag targeting options not matching');
892
+
893
+ // resetPresetTargeting: initiate a new auction with no winning bids, now old targeting should be removed
894
+
895
+ resetAuction();
896
+ auction.getBidsReceived = function() { return [] };
897
+
898
+ var slots = createSlotArrayScenario2();
899
+ window.googletag.pubads().setSlots(slots);
900
+
901
+ $$PREBID_GLOBAL$$.setTargetingForGPTAsync([config.adUnitCodes[0]]);
902
+
903
+ targeting = [];
904
+ slots[1].getTargetingKeys().map(function (key) {
905
+ const value = slots[1].getTargeting(key);
906
+ targeting.push([key, value]);
907
+ });
908
+
909
+ invokedTargetingMap = {};
910
+ slots[1].spySetTargeting.args.map(function (entry) {
911
+ invokedTargetingMap[entry[0]] = entry[1];
912
+ });
913
+
914
+ var invokedTargeting = [];
915
+
916
+ Object.getOwnPropertyNames(invokedTargetingMap).map(function (key) {
917
+ const value = Array.isArray(invokedTargetingMap[key]) ? invokedTargetingMap[key] : [invokedTargetingMap[key]]; // values are always returned as array in googletag
918
+ invokedTargeting.push([key, value]);
919
+ });
920
+ assert.deepEqual(targeting, invokedTargeting, 'google tag targeting options not matching');
921
+ targeting.forEach(function(e) {
922
+ // here e[0] is key and e[1] is value in array that should be [null] as we are un-setting prebid keys in resetPresetTargeting
923
+ assert.deepEqual(e[1], [null], 'resetPresetTargeting: the value of the key ' + e[0] + ' should be [null]');
924
+ });
890
925
  });
891
926
 
892
927
  it('should set googletag targeting keys to specific slot with customSlotMatching', function () {
@@ -116,7 +116,7 @@ describe('secureCreatives', () => {
116
116
  beforeEach(function() {
117
117
  spyAddWinningBid = sinon.spy(auctionManager, 'addWinningBid');
118
118
  spyLogWarn = sinon.spy(utils, 'logWarn');
119
- stubFireNativeTrackers = sinon.stub(native, 'fireNativeTrackers');
119
+ stubFireNativeTrackers = sinon.stub(native, 'fireNativeTrackers').callsFake(message => { return message.action; });
120
120
  stubGetAllAssetsMessage = sinon.stub(native, 'getAllAssetsMessage');
121
121
  stubEmit = sinon.stub(events, 'emit');
122
122
  });
@@ -263,10 +263,9 @@ describe('secureCreatives', () => {
263
263
  sinon.assert.calledOnce(stubGetAllAssetsMessage);
264
264
  sinon.assert.calledWith(stubGetAllAssetsMessage, data, adResponse);
265
265
  sinon.assert.calledOnce(ev.source.postMessage);
266
- sinon.assert.calledOnce(stubFireNativeTrackers);
267
- sinon.assert.calledWith(stubFireNativeTrackers, data, adResponse);
268
- sinon.assert.calledOnce(spyAddWinningBid);
269
- sinon.assert.calledWith(stubEmit, CONSTANTS.EVENTS.BID_WON, adResponse);
266
+ sinon.assert.notCalled(stubFireNativeTrackers);
267
+ sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.BID_WON);
268
+ sinon.assert.notCalled(spyAddWinningBid);
270
269
  sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.STALE_RENDER);
271
270
  });
272
271
 
@@ -293,14 +292,11 @@ describe('secureCreatives', () => {
293
292
  sinon.assert.calledOnce(stubGetAllAssetsMessage);
294
293
  sinon.assert.calledWith(stubGetAllAssetsMessage, data, adResponse);
295
294
  sinon.assert.calledOnce(ev.source.postMessage);
296
- sinon.assert.calledOnce(stubFireNativeTrackers);
297
- sinon.assert.calledWith(stubFireNativeTrackers, data, adResponse);
298
- sinon.assert.calledOnce(spyAddWinningBid);
299
- sinon.assert.calledWith(stubEmit, CONSTANTS.EVENTS.BID_WON, adResponse);
295
+ sinon.assert.notCalled(stubFireNativeTrackers);
296
+ sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.BID_WON);
297
+ sinon.assert.notCalled(spyAddWinningBid);
300
298
  sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.STALE_RENDER);
301
299
 
302
- expect(adResponse).to.have.property('status', CONSTANTS.BID_STATUS.RENDERED);
303
-
304
300
  resetHistories(ev.source.postMessage);
305
301
 
306
302
  receiveMessage(ev);
@@ -309,10 +305,9 @@ describe('secureCreatives', () => {
309
305
  sinon.assert.calledOnce(stubGetAllAssetsMessage);
310
306
  sinon.assert.calledWith(stubGetAllAssetsMessage, data, adResponse);
311
307
  sinon.assert.calledOnce(ev.source.postMessage);
312
- sinon.assert.calledOnce(stubFireNativeTrackers);
313
- sinon.assert.calledWith(stubFireNativeTrackers, data, adResponse);
314
- sinon.assert.calledOnce(spyAddWinningBid);
315
- sinon.assert.calledWith(stubEmit, CONSTANTS.EVENTS.BID_WON, adResponse);
308
+ sinon.assert.notCalled(stubFireNativeTrackers);
309
+ sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.BID_WON);
310
+ sinon.assert.notCalled(spyAddWinningBid);
316
311
  sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.STALE_RENDER);
317
312
  });
318
313
 
@@ -341,14 +336,11 @@ describe('secureCreatives', () => {
341
336
  sinon.assert.calledOnce(stubGetAllAssetsMessage);
342
337
  sinon.assert.calledWith(stubGetAllAssetsMessage, data, adResponse);
343
338
  sinon.assert.calledOnce(ev.source.postMessage);
344
- sinon.assert.calledOnce(stubFireNativeTrackers);
345
- sinon.assert.calledWith(stubFireNativeTrackers, data, adResponse);
346
- sinon.assert.calledOnce(spyAddWinningBid);
347
- sinon.assert.calledWith(stubEmit, CONSTANTS.EVENTS.BID_WON, adResponse);
339
+ sinon.assert.notCalled(stubFireNativeTrackers);
340
+ sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.BID_WON);
341
+ sinon.assert.notCalled(spyAddWinningBid);
348
342
  sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.STALE_RENDER);
349
343
 
350
- expect(adResponse).to.have.property('status', CONSTANTS.BID_STATUS.RENDERED);
351
-
352
344
  resetHistories(ev.source.postMessage);
353
345
 
354
346
  receiveMessage(ev);
@@ -357,14 +349,51 @@ describe('secureCreatives', () => {
357
349
  sinon.assert.calledOnce(stubGetAllAssetsMessage);
358
350
  sinon.assert.calledWith(stubGetAllAssetsMessage, data, adResponse);
359
351
  sinon.assert.calledOnce(ev.source.postMessage);
360
- sinon.assert.calledOnce(stubFireNativeTrackers);
361
- sinon.assert.calledWith(stubFireNativeTrackers, data, adResponse);
362
- sinon.assert.calledOnce(spyAddWinningBid);
363
- sinon.assert.calledWith(stubEmit, CONSTANTS.EVENTS.BID_WON, adResponse);
352
+ sinon.assert.notCalled(stubFireNativeTrackers);
353
+ sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.BID_WON);
354
+ sinon.assert.notCalled(spyAddWinningBid);
364
355
  sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.STALE_RENDER);
365
356
 
366
357
  configObj.setConfig({'auctionOptions': {}});
367
358
  });
359
+
360
+ it('Prebid native should fire trackers', function () {
361
+ pushBidResponseToAuction({});
362
+
363
+ const data = {
364
+ adId: bidId,
365
+ message: 'Prebid Native',
366
+ action: 'click',
367
+ };
368
+
369
+ const ev = {
370
+ data: JSON.stringify(data),
371
+ source: {
372
+ postMessage: sinon.stub()
373
+ },
374
+ origin: 'any origin'
375
+ };
376
+
377
+ receiveMessage(ev);
378
+
379
+ sinon.assert.neverCalledWith(spyLogWarn, warning);
380
+ sinon.assert.calledOnce(stubFireNativeTrackers);
381
+ sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.BID_WON);
382
+ sinon.assert.notCalled(spyAddWinningBid);
383
+
384
+ resetHistories(ev.source.postMessage);
385
+
386
+ delete data.action;
387
+ ev.data = JSON.stringify(data);
388
+ receiveMessage(ev);
389
+
390
+ sinon.assert.neverCalledWith(spyLogWarn, warning);
391
+ sinon.assert.calledOnce(stubFireNativeTrackers);
392
+ sinon.assert.calledWith(stubEmit, CONSTANTS.EVENTS.BID_WON, adResponse);
393
+ sinon.assert.calledOnce(spyAddWinningBid);
394
+
395
+ expect(adResponse).to.have.property('status', CONSTANTS.BID_STATUS.RENDERED);
396
+ });
368
397
  });
369
398
  });
370
399
  });
@@ -1,49 +0,0 @@
1
- # Overview
2
-
3
- Module Name: Türk Telekom Bidder Adapter
4
- Module Type: Bidder Adapter
5
- Maintainer: turktelssp@gmail.com
6
-
7
- # Description
8
-
9
- Module that connects to Türk Telekom demand source to fetch bids.
10
- Türk Telekom Bid Adapter supports Banner and Video (instream and outstream).
11
-
12
- # Test Parameters
13
- ```
14
- var adUnits = [
15
- {
16
- code: 'test-div',
17
- mediaTypes: {
18
- banner: {
19
- sizes: [[300, 250], [300,600]]
20
- }
21
- },
22
- bids: [
23
- {
24
- bidder: "turktelekom",
25
- params: {
26
- uid: 17,
27
- priceType: 'gross' // by default is 'net'
28
- }
29
- }
30
- ]
31
- },{
32
- code: 'test-div',
33
- mediaTypes: {
34
- video: {
35
- playerSize: [[640, 360]],
36
- context: 'instream'
37
- }
38
- },
39
- bids: [
40
- {
41
- bidder: "turktelekom",
42
- params: {
43
- uid: 19
44
- }
45
- }
46
- ]
47
- }
48
- ];
49
- ```