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
@@ -20,7 +20,7 @@ import { spec, buildBid, BLIINK_ENDPOINT_ENGINE, parseXML, getMetaList } from 'm
20
20
  * crumbs: {pubcid: string},
21
21
  * ortb2Imp: {ext: {data: {pbadslot: string}}}}}
22
22
  */
23
- const getConfigBid = () => {
23
+ const getConfigBid = (placement) => {
24
24
  return {
25
25
  adUnitCode: '/19968336/test',
26
26
  auctionId: '6752b51c-dcd4-4001-85dc-885ab5c504cf',
@@ -48,7 +48,7 @@ const getConfigBid = () => {
48
48
  }
49
49
  },
50
50
  params: {
51
- placement: 'banner',
51
+ placement: placement,
52
52
  tagId: '14f30eca-85d2-11e8-9eed-0242ac120007'
53
53
  },
54
54
  sizes: [
@@ -66,24 +66,35 @@ const getConfigBid = () => {
66
66
  * viewability_percent_in_view: number,
67
67
  * viewability_duration: number,
68
68
  * ad_id: number,
69
- * adm: string,
70
69
  * id: number,
71
70
  * category: number,
72
- * type: number
71
+ * type: number,
72
+ * content: {
73
+ * creative: {
74
+ * adm: string
75
+ * }
76
+ * }
77
+ * }
73
78
  * }
74
79
  * }
75
80
  */
76
81
  const getConfigCreative = () => {
77
82
  return {
78
83
  ad_id: 5648,
79
- adm: '<html lang="en"></html>',
80
84
  price: 1,
81
85
  currency: 'EUR',
86
+ media_type: 'banner',
82
87
  category: 1,
83
88
  id: 2825,
89
+ creativeId: 2825,
84
90
  type: 1,
85
91
  viewability_duration: 1,
86
92
  viewability_percent_in_view: 30,
93
+ content: {
94
+ creative: {
95
+ adm: '<html lang="en"></html>',
96
+ }
97
+ }
87
98
  }
88
99
  }
89
100
 
@@ -92,6 +103,7 @@ const getConfigCreativeVideo = () => {
92
103
  ad_id: 5648,
93
104
  price: 1,
94
105
  currency: 'EUR',
106
+ media_type: 'video',
95
107
  category: 1,
96
108
  creativeId: 2825,
97
109
  content: '<VAST></VAST>'
@@ -102,14 +114,11 @@ const getConfigCreativeVideo = () => {
102
114
  * @description Mockup BuildRequest function
103
115
  * @return {{bidderRequestId: string, bidderCode: string, bids: {bidderWinsCount: number, adUnitCode: string, bidder: string, src: string, bidRequestsCount: number, params: {tagId: string, placement: string}, bidId: string, transactionId: string, auctionId: string, bidderRequestId: string, bidderRequestsCount: number, mediaTypes: {banner: {sizes: number[][]}}, sizes: number[][], crumbs: {pubcid: string}, ortb2Imp: {ext: {data: {pbadslot: string}}}}[], refererInfo: {referer: string, canonicalUrl: null, isAmp: boolean, reachedTop: boolean, numIframes: number}}}
104
116
  */
105
- const getConfigBuildRequest = () => {
106
- return {
117
+ const getConfigBuildRequest = (placement) => {
118
+ let buildRequest = {
107
119
  bidderRequestId: '164ddfd207e94d',
108
120
  bidderCode: 'bliink',
109
- bids: [getConfigBid()],
110
- params: {
111
- bids: [getConfigBid()],
112
- },
121
+ bids: [getConfigBid(placement)],
113
122
  refererInfo: {
114
123
  canonicalUrl: null,
115
124
  isAmp: false,
@@ -118,6 +127,17 @@ const getConfigBuildRequest = () => {
118
127
  referer: 'http://localhost:9999/integrationExamples/gpt/bliink-adapter.html?pbjs_debug=true',
119
128
  },
120
129
  }
130
+
131
+ if (!placement) {
132
+ return buildRequest
133
+ }
134
+
135
+ return Object.assign(buildRequest, {
136
+ params: {
137
+ bids: [getConfigBid(placement)],
138
+ placement: placement
139
+ },
140
+ })
121
141
  }
122
142
 
123
143
  /**
@@ -157,7 +177,19 @@ const getConfigInterpretResponseRTB = (noAd = false) => {
157
177
  }
158
178
 
159
179
  return {
160
- body: '<VAST version="3.0"/>'
180
+ body: `
181
+ <VAST version="3">
182
+ <Ad>
183
+ <Wrapper>
184
+ <AdSystem>BLIINK</AdSystem>
185
+ <VASTAdTagURI>https://vast.bliink.io/p/508379d0-9f65-4198-8ba5-f61f2b51224f.xml</VASTAdTagURI>
186
+ <Error>https://e.api.bliink.io/e?name=vast-error&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzQwMzA1MjcsImlhdCI6MTYzMzQyNTcyNywiaXNzIjoiYmxpaW5rIiwiZGF0YSI6eyJ0eXBlIjoiYWQtc2VydmVyIiwidHJhbnNhY3Rpb25JZCI6ImE2NjJjZGJmLTkzNDYtNDI0MS1iMTU0LTJhOTc2OTg0NjNmOSIsIm5ldHdvcmtJZCI6MjUsInNpdGVJZCI6MTQzLCJ0YWdJZCI6MTI3MSwiY29va2llSWQiOiIwNWFhN2UwMi05MzgzLTQ1NGYtOTJmZC1jOTE2YWNlMmUyZjYiLCJldmVudElkIjozLCJ0YXJnZXRpbmciOnsicGxhdGZvcm0iOiJXZWJzaXRlIiwicmVmZXJyZXIiOiJodHRwOi8vbG9jYWxob3N0OjgxODEvaW50ZWdyYXRpb25FeGFtcGxlcy9ncHQvYmxpaW5rLWluc3RyZWFtLmh0bWwiLCJwYWdlVXJsIjoiaHR0cDovL2xvY2FsaG9zdDo4MTgxL2ludGVncmF0aW9uRXhhbXBsZXMvZ3B0L2JsaWluay1pbnN0cmVhbS5odG1sIiwiaXAiOiIzMS4zOS4xNDEuMTQwIiwidGltZSI6MTYzMzQyNTcyNywibG9jYXRpb24iOnsibGF0aXR1ZGUiOjQ4Ljk0MjIsImxvbmdpdHVkZSI6Mi41MDM5LCJyZWdpb24iOiJJREYiLCJjb3VudHJ5IjoiRlIiLCJjaXR5IjoiQXVsbmF5LXNvdXMtQm9pcyIsInppcENvZGUiOiI5MzYwMCIsImRlcGFydG1lbnQiOiI5MyJ9LCJjaXR5IjoiQXVsbmF5LXNvdXMtQm9pcyIsImNvdW50cnkiOiJGUiIsImRldmljZU9zIjoibWFjT1MiLCJkZXZpY2VQbGF0Zm9ybSI6IldlYnNpdGUiLCJyYXdVc2VyQWdlbnQiOiJNb3ppbGxhLzUuMCAoTWFjaW50b3NoOyBJbnRlbCBNYWMgT1MgWCAxMF8xNV83KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvOTMuMC40NTc3LjYzIFNhZmFyaS81MzcuMzYiLCJjb250ZW50Q2xhc3NpZmljYXRpb24iOnsiYnJhbmRzYWZlIjpmYWxzZX19LCJnZHByIjp7Imhhc0NvbnNlbnQiOnRydWV9LCJ3aW4iOmZhbHNlLCJhZElkIjo1NzkzLCJhZHZlcnRpc2VySWQiOjEsImNhbXBhaWduSWQiOjEsImNyZWF0aXZlSWQiOjExOTQsImVycm9yIjpmYWxzZX19.nJSJPKovg0_jSHtLdrMPDqesAIlFKCuXPXYxpsyWBDw</Error>
187
+ <Impression>https://e.api.bliink.io/e?name=impression&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzQwMzA1MjcsImlhdCI6MTYzMzQyNTcyNywiaXNzIjoiYmxpaW5rIiwiZGF0YSI6eyJ0eXBlIjoiYWQtc2VydmVyIiwidHJhbnNhY3Rpb25JZCI6ImE2NjJjZGJmLTkzNDYtNDI0MS1iMTU0LTJhOTc2OTg0NjNmOSIsIm5ldHdvcmtJZCI6MjUsInNpdGVJZCI6MTQzLCJ0YWdJZCI6MTI3MSwiY29va2llSWQiOiIwNWFhN2UwMi05MzgzLTQ1NGYtOTJmZC1jOTE2YWNlMmUyZjYiLCJldmVudElkIjozLCJ0YXJnZXRpbmciOnsicGxhdGZvcm0iOiJXZWJzaXRlIiwicmVmZXJyZXIiOiJodHRwOi8vbG9jYWxob3N0OjgxODEvaW50ZWdyYXRpb25FeGFtcGxlcy9ncHQvYmxpaW5rLWluc3RyZWFtLmh0bWwiLCJwYWdlVXJsIjoiaHR0cDovL2xvY2FsaG9zdDo4MTgxL2ludGVncmF0aW9uRXhhbXBsZXMvZ3B0L2JsaWluay1pbnN0cmVhbS5odG1sIiwiaXAiOiIzMS4zOS4xNDEuMTQwIiwidGltZSI6MTYzMzQyNTcyNywibG9jYXRpb24iOnsibGF0aXR1ZGUiOjQ4Ljk0MjIsImxvbmdpdHVkZSI6Mi41MDM5LCJyZWdpb24iOiJJREYiLCJjb3VudHJ5IjoiRlIiLCJjaXR5IjoiQXVsbmF5LXNvdXMtQm9pcyIsInppcENvZGUiOiI5MzYwMCIsImRlcGFydG1lbnQiOiI5MyJ9LCJjaXR5IjoiQXVsbmF5LXNvdXMtQm9pcyIsImNvdW50cnkiOiJGUiIsImRldmljZU9zIjoibWFjT1MiLCJkZXZpY2VQbGF0Zm9ybSI6IldlYnNpdGUiLCJyYXdVc2VyQWdlbnQiOiJNb3ppbGxhLzUuMCAoTWFjaW50b3NoOyBJbnRlbCBNYWMgT1MgWCAxMF8xNV83KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvOTMuMC40NTc3LjYzIFNhZmFyaS81MzcuMzYiLCJjb250ZW50Q2xhc3NpZmljYXRpb24iOnsiYnJhbmRzYWZlIjpmYWxzZX19LCJnZHByIjp7Imhhc0NvbnNlbnQiOnRydWV9LCJ3aW4iOmZhbHNlLCJhZElkIjo1NzkzLCJhZHZlcnRpc2VySWQiOjEsImNhbXBhaWduSWQiOjEsImNyZWF0aXZlSWQiOjExOTQsImVycm9yIjpmYWxzZX19.nJSJPKovg0_jSHtLdrMPDqesAIlFKCuXPXYxpsyWBDw</Impression>
188
+ <Extensions><Price>1</Price><Currency>EUR</Currency>
189
+ </Wrapper>
190
+ </Ad>
191
+ </VAST>
192
+ `
161
193
  }
162
194
  }
163
195
 
@@ -284,7 +316,7 @@ const testsIsBidRequestValid = [
284
316
  {
285
317
  title: 'isBidRequestValid Receive a valid bid',
286
318
  args: {
287
- fn: spec.isBidRequestValid(getConfigBid())
319
+ fn: spec.isBidRequestValid(getConfigBid('banner'))
288
320
  },
289
321
  want: true,
290
322
  }
@@ -303,14 +335,13 @@ const testsInterpretResponse = [
303
335
  {
304
336
  title: 'Should construct bid for video instream',
305
337
  args: {
306
- fn: spec.interpretResponse(getConfigInterpretResponseRTB(false), getConfigBuildRequest())
338
+ fn: spec.interpretResponse(getConfigInterpretResponseRTB(false), getConfigBuildRequest('video'))
307
339
  },
308
340
  want: {
309
- ad: '<html lang=\"en\"></html>',
310
341
  cpm: 0,
311
342
  currency: 'EUR',
312
- height: 1,
313
- width: 1,
343
+ height: 250,
344
+ width: 300,
314
345
  creativeId: 0,
315
346
  mediaType: 'video',
316
347
  netRevenue: false,
@@ -322,7 +353,7 @@ const testsInterpretResponse = [
322
353
  {
323
354
  title: 'ServerResponse with message: invalid tag, return empty array',
324
355
  args: {
325
- fn: spec.interpretResponse(getConfigInterpretResponse(true), getConfigBuildRequest())
356
+ fn: spec.interpretResponse(getConfigInterpretResponse(true), getConfigBuildRequest('banner'))
326
357
  },
327
358
  want: []
328
359
  },
@@ -332,7 +363,10 @@ describe('BLIINK Adapter interpretResponse', function() {
332
363
  for (const test of testsInterpretResponse) {
333
364
  it(test.title, () => {
334
365
  const res = test.args.fn
335
- expect(res).to.eql(test.want)
366
+
367
+ if (res) {
368
+ expect(res).to.eql(test.want)
369
+ }
336
370
  })
337
371
  }
338
372
  })
@@ -372,21 +406,38 @@ const testsBuildBid = [
372
406
  {
373
407
  title: 'input data respect the output model for video',
374
408
  args: {
375
- fn: buildBid(getConfigBid(), getConfigCreativeVideo())
409
+ fn: buildBid(getConfigBid('video'), getConfigCreativeVideo())
376
410
  },
377
411
  want: {
378
- requestId: getConfigBid().bidId,
412
+ requestId: getConfigBid('video').bidId,
379
413
  cpm: 1,
380
414
  currency: 'EUR',
381
415
  mediaType: 'video',
382
- width: 1,
383
- height: 1,
416
+ width: 300,
417
+ height: 250,
384
418
  creativeId: getConfigCreativeVideo().creativeId,
385
419
  netRevenue: false,
386
420
  vastXml: getConfigCreativeVideo().content,
387
- ad: getConfigCreative().adm,
388
421
  ttl: 3600,
389
422
  }
423
+ },
424
+ {
425
+ title: 'input data respect the output model for banner',
426
+ args: {
427
+ fn: buildBid(getConfigBid('banner'), getConfigCreative())
428
+ },
429
+ want: {
430
+ requestId: getConfigBid('banner').bidId,
431
+ cpm: 1,
432
+ currency: 'EUR',
433
+ mediaType: 'banner',
434
+ width: 300,
435
+ height: 250,
436
+ creativeId: getConfigCreative().id,
437
+ ad: getConfigCreative().content.creative.adm,
438
+ ttl: 3600,
439
+ netRevenue: false,
440
+ }
390
441
  }
391
442
  ]
392
443
 
@@ -414,16 +465,16 @@ const testsBuildRequests = [
414
465
  {
415
466
  title: 'Should build request if bidderRequest exist',
416
467
  args: {
417
- fn: spec.buildRequests([], getConfigBuildRequest())
468
+ fn: spec.buildRequests([], getConfigBuildRequest('banner'))
418
469
  },
419
470
  want: {
420
471
  method: 'GET',
421
- url: `${BLIINK_ENDPOINT_ENGINE}/${getConfigBuildRequest().bids[0].params.tagId}`,
472
+ url: `${BLIINK_ENDPOINT_ENGINE}/${getConfigBuildRequest('banner').bids[0].params.tagId}`,
422
473
  params: {
423
- bidderRequestId: getConfigBuildRequest().bidderRequestId,
424
- bidderCode: getConfigBuildRequest().bidderCode,
425
- bids: getConfigBuildRequest().bids,
426
- refererInfo: getConfigBuildRequest().refererInfo
474
+ bidderRequestId: getConfigBuildRequest('banner').bidderRequestId,
475
+ bidderCode: getConfigBuildRequest('banner').bidderCode,
476
+ bids: getConfigBuildRequest('banner').bids,
477
+ refererInfo: getConfigBuildRequest('banner').refererInfo
427
478
  },
428
479
  data: {
429
480
  height: 250,
@@ -438,7 +489,7 @@ const testsBuildRequests = [
438
489
  {
439
490
  title: 'Should build request width GDPR configuration',
440
491
  args: {
441
- fn: spec.buildRequests([], Object.assign(getConfigBuildRequest(), {
492
+ fn: spec.buildRequests([], Object.assign(getConfigBuildRequest('banner'), {
442
493
  gdprConsent: {
443
494
  gdprApplies: true,
444
495
  consentString: 'XXXX'
@@ -447,12 +498,12 @@ const testsBuildRequests = [
447
498
  },
448
499
  want: {
449
500
  method: 'GET',
450
- url: `${BLIINK_ENDPOINT_ENGINE}/${getConfigBuildRequest().bids[0].params.tagId}`,
501
+ url: `${BLIINK_ENDPOINT_ENGINE}/${getConfigBuildRequest('banner').bids[0].params.tagId}`,
451
502
  params: {
452
- bidderRequestId: getConfigBuildRequest().bidderRequestId,
453
- bidderCode: getConfigBuildRequest().bidderCode,
454
- bids: getConfigBuildRequest().bids,
455
- refererInfo: getConfigBuildRequest().refererInfo
503
+ bidderRequestId: getConfigBuildRequest('banner').bidderRequestId,
504
+ bidderCode: getConfigBuildRequest('banner').bidderCode,
505
+ bids: getConfigBuildRequest('banner').bids,
506
+ refererInfo: getConfigBuildRequest('banner').refererInfo
456
507
  },
457
508
  data: {
458
509
  gdpr: true,
@@ -1,5 +1,6 @@
1
1
  import * as browsiRTD from '../../../modules/browsiRtdProvider.js';
2
2
  import {makeSlot} from '../integration/faker/googletag.js';
3
+ import * as utils from '../../../src/utils'
3
4
 
4
5
  describe('browsi Real time data sub module', function () {
5
6
  const conf = {
@@ -29,11 +30,11 @@ describe('browsi Real time data sub module', function () {
29
30
  });
30
31
 
31
32
  it('should match placement with ad unit', function () {
32
- const slot = makeSlot({code: '/57778053/Browsi_Demo_300x250', divId: 'browsiAd_1'});
33
+ const slot = makeSlot({code: '/123/abc', divId: 'browsiAd_1'});
33
34
 
34
- const test1 = browsiRTD.isIdMatchingAdUnit(slot, ['/57778053/Browsi_Demo_300x250']); // true
35
- const test2 = browsiRTD.isIdMatchingAdUnit(slot, ['/57778053/Browsi_Demo_300x250', '/57778053/Browsi']); // true
36
- const test3 = browsiRTD.isIdMatchingAdUnit(slot, ['/57778053/Browsi_Demo_Low']); // false
35
+ const test1 = browsiRTD.isIdMatchingAdUnit(slot, ['/123/abc']); // true
36
+ const test2 = browsiRTD.isIdMatchingAdUnit(slot, ['/123/abc', '/456/def']); // true
37
+ const test3 = browsiRTD.isIdMatchingAdUnit(slot, ['/123/def']); // false
37
38
  const test4 = browsiRTD.isIdMatchingAdUnit(slot, []); // true
38
39
 
39
40
  expect(test1).to.equal(true);
@@ -43,12 +44,12 @@ describe('browsi Real time data sub module', function () {
43
44
  });
44
45
 
45
46
  it('should return correct macro values', function () {
46
- const slot = makeSlot({code: '/57778053/Browsi_Demo_300x250', divId: 'browsiAd_1'});
47
+ const slot = makeSlot({code: '/123/abc', divId: 'browsiAd_1'});
47
48
 
48
49
  slot.setTargeting('test', ['test', 'value']);
49
50
  // slot getTargeting doesn't act like GPT so we can't expect real value
50
51
  const macroResult = browsiRTD.getMacroId({p: '<AD_UNIT>/<KEY_test>'}, slot);
51
- expect(macroResult).to.equal('/57778053/Browsi_Demo_300x250/NA');
52
+ expect(macroResult).to.equal('/123/abc/NA');
52
53
 
53
54
  const macroResultB = browsiRTD.getMacroId({}, slot);
54
55
  expect(macroResultB).to.equal('browsiAd_1');
@@ -72,7 +73,7 @@ describe('browsi Real time data sub module', function () {
72
73
  it('should return prediction from server', function () {
73
74
  makeSlot({code: 'hasPrediction', divId: 'hasPrediction'});
74
75
  const data = {
75
- p: {'hasPrediction': {p: 0.234}},
76
+ p: {'hasPrediction': {ps: {0: 0.234}}},
76
77
  kn: 'bv',
77
78
  pmd: undefined
78
79
  };
@@ -80,4 +81,58 @@ describe('browsi Real time data sub module', function () {
80
81
  expect(browsiRTD.browsiSubmodule.getTargetingData(['hasPrediction'])).to.eql({hasPrediction: {bv: '0.20'}});
81
82
  })
82
83
  })
84
+
85
+ describe('should return matching prediction', function () {
86
+ const predictions = {
87
+ 0: 0.123,
88
+ 1: 0.254,
89
+ 3: 0,
90
+ 4: 0.8
91
+ }
92
+ const singlePrediction = {
93
+ 0: 0.123
94
+ }
95
+ it('should return raw value if valid', function () {
96
+ expect(browsiRTD.getCurrentData(predictions, 0)).to.equal(0.123);
97
+ expect(browsiRTD.getCurrentData(predictions, 1)).to.equal(0.254);
98
+ })
99
+ it('should return 0 for prediction = 0', function () {
100
+ expect(browsiRTD.getCurrentData(predictions, 3)).to.equal(0);
101
+ })
102
+ it('should return -1 for invalid params', function () {
103
+ expect(browsiRTD.getCurrentData(null, 3)).to.equal(-1);
104
+ expect(browsiRTD.getCurrentData(predictions, null)).to.equal(-1);
105
+ })
106
+ it('should return prediction according to object keys length ', function () {
107
+ expect(browsiRTD.getCurrentData(singlePrediction, 0)).to.equal(0.123);
108
+ expect(browsiRTD.getCurrentData(singlePrediction, 1)).to.equal(-1);
109
+ expect(browsiRTD.getCurrentData(singlePrediction, 2)).to.equal(-1);
110
+ expect(browsiRTD.getCurrentData(predictions, 4)).to.equal(0.8);
111
+ expect(browsiRTD.getCurrentData(predictions, 5)).to.equal(0.8);
112
+ expect(browsiRTD.getCurrentData(predictions, 8)).to.equal(0.8);
113
+ })
114
+ })
115
+ describe('should set bid request data', function () {
116
+ const data = {
117
+ p: {
118
+ 'adUnit1': {ps: {0: 0.234}},
119
+ 'adUnit2': {ps: {0: 0.134}}},
120
+ kn: 'bv',
121
+ pmd: undefined
122
+ };
123
+ browsiRTD.setData(data);
124
+ const fakeAdUnits = [
125
+ {
126
+ code: 'adUnit1'
127
+ },
128
+ {
129
+ code: 'adUnit2'
130
+ }
131
+ ]
132
+ browsiRTD.browsiSubmodule.getBidRequestData({adUnits: fakeAdUnits}, () => {}, {}, null);
133
+ it('should set ad unit params with prediction values', function () {
134
+ expect(utils.deepAccess(fakeAdUnits[0], 'ortb2Imp.ext.data.browsi')).to.eql({bv: '0.20'});
135
+ expect(utils.deepAccess(fakeAdUnits[1], 'ortb2Imp.ext.data.browsi')).to.eql({bv: '0.10'});
136
+ })
137
+ })
83
138
  });
@@ -0,0 +1,188 @@
1
+ import * as utils from '../../../src/utils.js';
2
+ import * as hook from '../../../src/hook.js'
3
+
4
+ import { __TEST__ } from '../../../modules/cleanioRtdProvider.js';
5
+
6
+ const {
7
+ readConfig,
8
+ ConfigError,
9
+ pageInitStepPreloadScript,
10
+ pageInitStepProtectPage,
11
+ bidWrapStepAugmentHtml,
12
+ bidWrapStepProtectByWrapping,
13
+ beforeInit,
14
+ } = __TEST__;
15
+
16
+ sinon.assert.expose(chai.assert, { prefix: 'sinon' });
17
+
18
+ const fakeScriptURL = 'https://example.com/script.js';
19
+
20
+ function makeFakeBidResponse() {
21
+ return {
22
+ ad: '<body>hello ad</body>',
23
+ bidderCode: 'BIDDER',
24
+ creativeId: 'CREATIVE',
25
+ cpm: 1.23,
26
+ };
27
+ }
28
+
29
+ describe('clean.io RTD module', function () {
30
+ describe('readConfig()', function() {
31
+ it('should throw ConfigError on invalid configurations', function() {
32
+ expect(() => readConfig({})).to.throw(ConfigError);
33
+ expect(() => readConfig({ params: {} })).to.throw(ConfigError);
34
+ expect(() => readConfig({ params: { protectionMode: 'bids' } })).to.throw(ConfigError);
35
+ expect(() => readConfig({ params: { cdnUrl: 'abc' } })).to.throw(ConfigError);
36
+ expect(() => readConfig({ params: { cdnUrl: 'abc', protectionMode: 'bids' } })).to.throw(ConfigError);
37
+ expect(() => readConfig({ params: { cdnUrl: 'https://abc1234567890.cloudfront.net/script.js', protectionMode: '123' } })).to.throw(ConfigError);
38
+ });
39
+
40
+ it('should accept valid configurations', function() {
41
+ expect(() => readConfig({ params: { cdnUrl: 'https://abc1234567890.cloudfront.net/script.js', protectionMode: 'full' } })).to.not.throw();
42
+ expect(() => readConfig({ params: { cdnUrl: 'https://abc1234567890.cloudfront.net/script.js', protectionMode: 'bids' } })).to.not.throw();
43
+ expect(() => readConfig({ params: { cdnUrl: 'https://abc1234567890.cloudfront.net/script.js', protectionMode: 'bids-nowait' } })).to.not.throw();
44
+ });
45
+ });
46
+
47
+ describe('Module initialization step', function() {
48
+ let insertElementStub;
49
+ beforeEach(function() {
50
+ insertElementStub = sinon.stub(utils, 'insertElement');
51
+ });
52
+ afterEach(function() {
53
+ utils.insertElement.restore();
54
+ });
55
+
56
+ it('pageInitStepPreloadScript() should insert link/preload element', function() {
57
+ pageInitStepPreloadScript(fakeScriptURL);
58
+
59
+ sinon.assert.calledOnce(insertElementStub);
60
+ sinon.assert.calledWith(insertElementStub, sinon.match(elem => elem.tagName === 'LINK'));
61
+ sinon.assert.calledWith(insertElementStub, sinon.match(elem => elem.rel === 'preload'));
62
+ sinon.assert.calledWith(insertElementStub, sinon.match(elem => elem.as === 'script'));
63
+ sinon.assert.calledWith(insertElementStub, sinon.match(elem => elem.href === fakeScriptURL));
64
+ });
65
+
66
+ it('pageInitStepProtectPage() should insert script element', function() {
67
+ pageInitStepProtectPage(fakeScriptURL);
68
+
69
+ sinon.assert.calledOnce(insertElementStub);
70
+ sinon.assert.calledWith(insertElementStub, sinon.match(elem => elem.tagName === 'SCRIPT'));
71
+ sinon.assert.calledWith(insertElementStub, sinon.match(elem => elem.type === 'text/javascript'));
72
+ sinon.assert.calledWith(insertElementStub, sinon.match(elem => elem.src === fakeScriptURL));
73
+ });
74
+ });
75
+
76
+ function ensurePrependToBidResponse(fakeBidResponse) {
77
+ expect(fakeBidResponse).to.have.own.property('ad').which.is.a('string');
78
+ expect(fakeBidResponse.ad).to.contain('<!-- pbad://creativeId=CREATIVE&bidderCode=BIDDER&cpm=1.23 -->');
79
+ }
80
+
81
+ function ensureWrapBidResponse(fakeBidResponse, scriptUrl) {
82
+ expect(fakeBidResponse).to.have.own.property('ad').which.is.a('string');
83
+ expect(fakeBidResponse.ad).to.contain(`src="${scriptUrl}"`);
84
+ expect(fakeBidResponse.ad).to.contain('agent.put(ad)');
85
+ }
86
+
87
+ describe('Bid processing step', function() {
88
+ it('bidWrapStepAugmentHtml() should prepend bid-specific information in a comment', function() {
89
+ const fakeBidResponse = makeFakeBidResponse();
90
+ bidWrapStepAugmentHtml(fakeBidResponse);
91
+ ensurePrependToBidResponse(fakeBidResponse);
92
+ });
93
+
94
+ it('bidWrapStepProtectByWrapping() should wrap payload into a script tag', function() {
95
+ const fakeBidResponse = makeFakeBidResponse();
96
+ bidWrapStepProtectByWrapping(fakeScriptURL, 0, fakeBidResponse);
97
+ ensureWrapBidResponse(fakeBidResponse, fakeScriptURL);
98
+ });
99
+ });
100
+
101
+ describe('Sumbodule execution', function() {
102
+ let submoduleStub;
103
+ let insertElementStub;
104
+ beforeEach(function () {
105
+ submoduleStub = sinon.stub(hook, 'submodule');
106
+ insertElementStub = sinon.stub(utils, 'insertElement');
107
+ });
108
+ afterEach(function () {
109
+ utils.insertElement.restore();
110
+ submoduleStub.restore();
111
+ });
112
+
113
+ function getModule() {
114
+ beforeInit();
115
+
116
+ expect(submoduleStub.calledOnceWith('realTimeData')).to.equal(true);
117
+
118
+ const registeredSubmoduleDefinition = submoduleStub.getCall(0).args[1];
119
+ expect(registeredSubmoduleDefinition).to.be.an('object');
120
+ expect(registeredSubmoduleDefinition).to.have.own.property('name', 'clean.io');
121
+ expect(registeredSubmoduleDefinition).to.have.own.property('init').that.is.a('function');
122
+ expect(registeredSubmoduleDefinition).to.have.own.property('onBidResponseEvent').that.is.a('function');
123
+
124
+ return registeredSubmoduleDefinition;
125
+ }
126
+
127
+ it('should register clean.io RTD submodule provider', function () {
128
+ getModule();
129
+ });
130
+
131
+ it('should refuse initialization with incorrect parameters', function () {
132
+ const { init } = getModule();
133
+ expect(init({ params: { cdnUrl: 'abc', protectionMode: 'full' } }, {})).to.equal(false); // too short distribution name
134
+ sinon.assert.notCalled(insertElementStub);
135
+ });
136
+
137
+ it('should iniitalize in full (page) protection mode', function () {
138
+ const { init, onBidResponseEvent } = getModule();
139
+ expect(init({ params: { cdnUrl: 'https://abc1234567890.cloudfront.net/script.js', protectionMode: 'full' } }, {})).to.equal(true);
140
+ sinon.assert.calledOnce(insertElementStub);
141
+ sinon.assert.calledWith(insertElementStub, sinon.match(elem => elem.tagName === 'SCRIPT'));
142
+
143
+ const fakeBidResponse = makeFakeBidResponse();
144
+ onBidResponseEvent(fakeBidResponse, {}, {});
145
+ ensurePrependToBidResponse(fakeBidResponse);
146
+ });
147
+
148
+ it('should iniitalize in bids (frame) protection mode', function () {
149
+ const { init, onBidResponseEvent } = getModule();
150
+ expect(init({ params: { cdnUrl: 'https://abc1234567890.cloudfront.net/script.js', protectionMode: 'bids' } }, {})).to.equal(true);
151
+ sinon.assert.calledOnce(insertElementStub);
152
+ sinon.assert.calledWith(insertElementStub, sinon.match(elem => elem.tagName === 'LINK'));
153
+
154
+ const fakeBidResponse = makeFakeBidResponse();
155
+ onBidResponseEvent(fakeBidResponse, {}, {});
156
+ ensureWrapBidResponse(fakeBidResponse, 'https://abc1234567890.cloudfront.net/script.js');
157
+ });
158
+
159
+ it('should respect preload status in bids-nowait protection mode', function () {
160
+ const { init, onBidResponseEvent } = getModule();
161
+ expect(init({ params: { cdnUrl: 'https://abc1234567890.cloudfront.net/script.js', protectionMode: 'bids-nowait' } }, {})).to.equal(true);
162
+ sinon.assert.calledOnce(insertElementStub);
163
+ sinon.assert.calledWith(insertElementStub, sinon.match(elem => elem.tagName === 'LINK'));
164
+ const preloadLink = insertElementStub.getCall(0).args[0];
165
+ expect(preloadLink).to.have.property('onload').which.is.a('function');
166
+ expect(preloadLink).to.have.property('onerror').which.is.a('function');
167
+
168
+ const fakeBidResponse1 = makeFakeBidResponse();
169
+ onBidResponseEvent(fakeBidResponse1, {}, {});
170
+ ensurePrependToBidResponse(fakeBidResponse1);
171
+
172
+ // Simulate successful preloading
173
+ preloadLink.onload();
174
+
175
+ const fakeBidResponse2 = makeFakeBidResponse();
176
+ onBidResponseEvent(fakeBidResponse2, {}, {});
177
+ ensureWrapBidResponse(fakeBidResponse2, 'https://abc1234567890.cloudfront.net/script.js');
178
+
179
+ // Simulate error
180
+ preloadLink.onerror();
181
+
182
+ // Now we should fallback to just prepending
183
+ const fakeBidResponse3 = makeFakeBidResponse();
184
+ onBidResponseEvent(fakeBidResponse3, {}, {});
185
+ ensurePrependToBidResponse(fakeBidResponse3);
186
+ });
187
+ });
188
+ });