prebid.js 7.18.0 → 7.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 (313) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/33acrossIdSystem.js +1 -1
  3. package/dist/adWMGAnalyticsAdapter.js +1 -1
  4. package/dist/adagioAnalyticsAdapter.js +1 -1
  5. package/dist/adagioBidAdapter.js +1 -1
  6. package/dist/adbookpspBidAdapter.js +1 -1
  7. package/dist/adfBidAdapter.js +1 -1
  8. package/dist/adgenerationBidAdapter.js +1 -1
  9. package/dist/adkernelAdnAnalyticsAdapter.js +1 -1
  10. package/dist/adkernelBidAdapter.js +1 -1
  11. package/dist/adlooxAdServerVideo.js +1 -1
  12. package/dist/adlooxAnalyticsAdapter.js +1 -1
  13. package/dist/adlooxRtdProvider.js +1 -1
  14. package/dist/adomikAnalyticsAdapter.js +1 -1
  15. package/dist/adqueryIdSystem.js +1 -1
  16. package/dist/adrelevantisBidAdapter.js +1 -1
  17. package/dist/adtrgtmeBidAdapter.js +1 -1
  18. package/dist/adxcgAnalyticsAdapter.js +1 -1
  19. package/dist/adxcgBidAdapter.js +1 -1
  20. package/dist/adxpremiumAnalyticsAdapter.js +1 -1
  21. package/dist/ajaBidAdapter.js +1 -1
  22. package/dist/amxBidAdapter.js +1 -1
  23. package/dist/amxIdSystem.js +1 -1
  24. package/dist/aolBidAdapter.js +1 -1
  25. package/dist/appierAnalyticsAdapter.js +1 -1
  26. package/dist/appnexusBidAdapter.js +1 -1
  27. package/dist/asoBidAdapter.js +1 -1
  28. package/dist/atsAnalyticsAdapter.js +1 -1
  29. package/dist/axonixBidAdapter.js +1 -1
  30. package/dist/{andBeyondMediaBidAdapter.js → beyondmediaBidAdapter.js} +1 -1
  31. package/dist/bidViewability.js +1 -1
  32. package/dist/bidglassBidAdapter.js +1 -1
  33. package/dist/bidwatchAnalyticsAdapter.js +1 -1
  34. package/dist/big-richmediaBidAdapter.js +1 -1
  35. package/dist/bridgewellBidAdapter.js +1 -1
  36. package/dist/brightMountainMediaBidAdapter.js +1 -1
  37. package/dist/byDataAnalyticsAdapter.js +1 -1
  38. package/dist/carodaBidAdapter.js +1 -1
  39. package/dist/categoryTranslation.js +1 -1
  40. package/dist/cleanioRtdProvider.js +1 -1
  41. package/dist/colossussspBidAdapter.js +1 -1
  42. package/dist/concertAnalyticsAdapter.js +1 -1
  43. package/dist/concertBidAdapter.js +1 -1
  44. package/dist/connectIdSystem.js +1 -1
  45. package/dist/connectadBidAdapter.js +1 -1
  46. package/dist/consentManagement.js +1 -1
  47. package/dist/consentManagementUsp.js +1 -1
  48. package/dist/consumableBidAdapter.js +1 -1
  49. package/dist/conversantAnalyticsAdapter.js +1 -0
  50. package/dist/conversantBidAdapter.js +1 -1
  51. package/dist/craftBidAdapter.js +1 -1
  52. package/dist/criteoBidAdapter.js +1 -1
  53. package/dist/currency.js +1 -1
  54. package/dist/datablocksAnalyticsAdapter.js +1 -1
  55. package/dist/dchain.js +1 -1
  56. package/dist/debugging-standalone.js +1 -1
  57. package/dist/debugging.js +1 -1
  58. package/dist/dependencies.json +9 -0
  59. package/dist/dfpAdServerVideo.js +1 -1
  60. package/dist/dgkeywordRtdProvider.js +1 -1
  61. package/dist/dianomiBidAdapter.js +1 -1
  62. package/dist/dspxBidAdapter.js +1 -1
  63. package/dist/enrichmentFpdModule.js +1 -1
  64. package/dist/eplanningAnalyticsAdapter.js +1 -1
  65. package/dist/eplanningBidAdapter.js +1 -1
  66. package/dist/finativeBidAdapter.js +1 -1
  67. package/dist/fintezaAnalyticsAdapter.js +1 -1
  68. package/dist/fpd.js +1 -0
  69. package/dist/ftrackIdSystem.js +1 -1
  70. package/dist/gdprEnforcement.js +1 -1
  71. package/dist/glimpseBidAdapter.js +1 -1
  72. package/dist/gmosspBidAdapter.js +1 -1
  73. package/dist/goldbachBidAdapter.js +1 -1
  74. package/dist/googleAnalyticsAdapter.js +1 -1
  75. package/dist/gridBidAdapter.js +1 -1
  76. package/dist/gridNMBidAdapter.js +1 -1
  77. package/dist/gumgumBidAdapter.js +1 -1
  78. package/dist/h12mediaBidAdapter.js +1 -1
  79. package/dist/hadronAnalyticsAdapter.js +1 -1
  80. package/dist/id5AnalyticsAdapter.js +1 -1
  81. package/dist/id5IdSystem.js +1 -1
  82. package/dist/improvedigitalBidAdapter.js +1 -1
  83. package/dist/inmarBidAdapter.js +1 -1
  84. package/dist/insticatorBidAdapter.js +1 -1
  85. package/dist/invisiblyAnalyticsAdapter.js +1 -1
  86. package/dist/ixBidAdapter.js +1 -1
  87. package/dist/justpremiumBidAdapter.js +1 -1
  88. package/dist/kargoAnalyticsAdapter.js +1 -1
  89. package/dist/kinessoIdSystem.js +1 -1
  90. package/dist/konduitAnalyticsAdapter.js +1 -1
  91. package/dist/kueezBidAdapter.js +1 -1
  92. package/dist/lassoBidAdapter.js +1 -1
  93. package/dist/lifestreetBidAdapter.js +1 -1
  94. package/dist/liveIntentAnalyticsAdapter.js +1 -1
  95. package/dist/liveIntentIdSystem.js +1 -1
  96. package/dist/livewrappedAnalyticsAdapter.js +1 -1
  97. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  98. package/dist/logicadBidAdapter.js +1 -1
  99. package/dist/loglyliftBidAdapter.js +1 -1
  100. package/dist/lotamePanoramaIdSystem.js +1 -1
  101. package/dist/magniteAnalyticsAdapter.js +1 -0
  102. package/dist/malltvAnalyticsAdapter.js +1 -1
  103. package/dist/marsmediaAnalyticsAdapter.js +1 -1
  104. package/dist/marsmediaBidAdapter.js +1 -1
  105. package/dist/mass.js +1 -1
  106. package/dist/mediafuseBidAdapter.js +1 -1
  107. package/dist/mediakeysBidAdapter.js +1 -1
  108. package/dist/medianetAnalyticsAdapter.js +1 -1
  109. package/dist/mediasquareBidAdapter.js +1 -1
  110. package/dist/mgidBidAdapter.js +1 -1
  111. package/dist/minutemediaBidAdapter.js +1 -1
  112. package/dist/multibid.js +1 -1
  113. package/dist/nativoBidAdapter.js +1 -1
  114. package/dist/not-for-prod/prebid.js +198 -194
  115. package/dist/oguryBidAdapter.js +1 -1
  116. package/dist/onetagBidAdapter.js +1 -1
  117. package/dist/ooloAnalyticsAdapter.js +1 -1
  118. package/dist/openxAnalyticsAdapter.js +1 -1
  119. package/dist/optimonAnalyticsAdapter.js +1 -1
  120. package/dist/outbrainBidAdapter.js +1 -1
  121. package/dist/parrableIdSystem.js +1 -1
  122. package/dist/pianoDmpAnalyticsAdapter.js +1 -1
  123. package/dist/pixfutureBidAdapter.js +1 -1
  124. package/dist/prebid-core.js +2 -2
  125. package/dist/prebidServerBidAdapter.js +1 -1
  126. package/dist/prebidmanagerAnalyticsAdapter.js +1 -1
  127. package/dist/priceFloors.js +1 -1
  128. package/dist/publinkIdSystem.js +1 -1
  129. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  130. package/dist/pubmaticBidAdapter.js +1 -1
  131. package/dist/pubperfAnalyticsAdapter.js +1 -1
  132. package/dist/pubstackAnalyticsAdapter.js +1 -1
  133. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  134. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  135. package/dist/pulsepointAnalyticsAdapter.js +1 -1
  136. package/dist/pxyzBidAdapter.js +1 -1
  137. package/dist/quantcastBidAdapter.js +1 -1
  138. package/dist/quantcastIdSystem.js +1 -1
  139. package/dist/readpeakBidAdapter.js +1 -1
  140. package/dist/realvuAnalyticsAdapter.js +1 -1
  141. package/dist/relaidoBidAdapter.js +1 -1
  142. package/dist/relevantAnalyticsAdapter.js +1 -1
  143. package/dist/rhythmoneBidAdapter.js +1 -1
  144. package/dist/riseBidAdapter.js +1 -1
  145. package/dist/rivrAnalyticsAdapter.js +1 -1
  146. package/dist/roxotAnalyticsAdapter.js +1 -1
  147. package/dist/rtdModule.js +1 -1
  148. package/dist/rubiconAnalyticsAdapter.js +1 -1
  149. package/dist/rubiconBidAdapter.js +1 -1
  150. package/dist/s2sTesting.js +1 -1
  151. package/dist/scaleableAnalyticsAdapter.js +1 -1
  152. package/dist/schain.js +1 -1
  153. package/dist/seedingAllianceBidAdapter.js +1 -1
  154. package/dist/seedtagBidAdapter.js +1 -1
  155. package/dist/sharedIdSystem.js +1 -1
  156. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  157. package/dist/sharethroughBidAdapter.js +1 -1
  158. package/dist/shinezBidAdapter.js +1 -1
  159. package/dist/sigmoidAnalyticsAdapter.js +1 -1
  160. package/dist/smaatoBidAdapter.js +1 -1
  161. package/dist/smartadserverBidAdapter.js +1 -1
  162. package/dist/smartxBidAdapter.js +1 -1
  163. package/dist/smilewantedBidAdapter.js +1 -1
  164. package/dist/sonobiAnalyticsAdapter.js +1 -1
  165. package/dist/sonobiBidAdapter.js +1 -1
  166. package/dist/sovrnAnalyticsAdapter.js +1 -1
  167. package/dist/sovrnBidAdapter.js +1 -1
  168. package/dist/sspBCBidAdapter.js +1 -1
  169. package/dist/staqAnalyticsAdapter.js +1 -1
  170. package/dist/sublimeBidAdapter.js +1 -1
  171. package/dist/synacormediaBidAdapter.js +1 -1
  172. package/dist/taboolaBidAdapter.js +1 -1
  173. package/dist/tapadIdSystem.js +1 -1
  174. package/dist/targetVideoBidAdapter.js +1 -1
  175. package/dist/teadsBidAdapter.js +1 -1
  176. package/dist/teadsIdSystem.js +1 -0
  177. package/dist/terceptAnalyticsAdapter.js +1 -1
  178. package/dist/trionBidAdapter.js +1 -1
  179. package/dist/tripleliftBidAdapter.js +1 -1
  180. package/dist/ttdBidAdapter.js +1 -1
  181. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  182. package/dist/underdogmediaBidAdapter.js +1 -1
  183. package/dist/undertoneBidAdapter.js +1 -1
  184. package/dist/userId.js +1 -1
  185. package/dist/vidazooBidAdapter.js +1 -1
  186. package/dist/videobyteBidAdapter.js +1 -1
  187. package/dist/visxBidAdapter.js +1 -1
  188. package/dist/vrtcalBidAdapter.js +1 -1
  189. package/dist/vuukleBidAdapter.js +1 -1
  190. package/dist/weboramaRtdProvider.js +1 -1
  191. package/dist/widespaceBidAdapter.js +1 -1
  192. package/dist/winrBidAdapter.js +1 -1
  193. package/dist/yahoosspBidAdapter.js +1 -1
  194. package/dist/yandexBidAdapter.js +1 -1
  195. package/dist/yieldmoBidAdapter.js +1 -1
  196. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  197. package/dist/yuktamediaAnalyticsAdapter.js +1 -1
  198. package/dist/zeta_global_sspAnalyticsAdapter.js +1 -1
  199. package/libraries/fpd/sua.js +98 -0
  200. package/modules/.submodules.json +1 -0
  201. package/modules/adfBidAdapter.js +1 -1
  202. package/modules/adkernelAdnBidAdapter.js +1 -0
  203. package/modules/adkernelBidAdapter.js +2 -2
  204. package/modules/adqueryIdSystem.js +8 -8
  205. package/modules/adxcgBidAdapter.js +1 -1
  206. package/modules/amxBidAdapter.js +1 -1
  207. package/modules/aolBidAdapter.js +25 -2
  208. package/modules/appnexusBidAdapter.js +19 -2
  209. package/modules/{andBeyondMediaBidAdapter.js → beyondmediaBidAdapter.js} +0 -0
  210. package/modules/{andBeyondMediaBidAdapter.md → beyondmediaBidAdapter.md} +1 -1
  211. package/modules/categoryTranslation.js +4 -4
  212. package/modules/cleanioRtdProvider.js +3 -4
  213. package/modules/colossussspBidAdapter.js +2 -1
  214. package/modules/connectIdSystem.js +16 -1
  215. package/modules/conversantAnalyticsAdapter.js +560 -0
  216. package/modules/conversantAnalyticsAdapter.md +47 -0
  217. package/modules/criteoBidAdapter.js +1 -1
  218. package/modules/currency.js +11 -11
  219. package/modules/dchain.js +2 -2
  220. package/modules/debugging/bidInterceptor.js +2 -2
  221. package/modules/debugging/debugging.js +10 -2
  222. package/modules/debugging/legacy.js +2 -2
  223. package/modules/dgkeywordRtdProvider.js +21 -3
  224. package/modules/dianomiBidAdapter.js +1 -1
  225. package/modules/enrichmentFpdModule.js +33 -14
  226. package/modules/eplanningBidAdapter.js +48 -2
  227. package/modules/finativeBidAdapter.js +1 -1
  228. package/modules/gridBidAdapter.js +187 -117
  229. package/modules/improvedigitalBidAdapter.js +2 -2
  230. package/modules/ixBidAdapter.js +94 -23
  231. package/modules/liveIntentIdSystem.js +39 -5
  232. package/modules/lotamePanoramaIdSystem.js +10 -6
  233. package/modules/magniteAnalyticsAdapter.js +902 -0
  234. package/modules/magniteAnalyticsAdapter.md +18 -0
  235. package/modules/mass.js +2 -2
  236. package/modules/mediakeysBidAdapter.js +6 -1
  237. package/modules/mediakeysBidAdapter.md +50 -40
  238. package/modules/multibid/index.js +5 -5
  239. package/modules/nativoBidAdapter.js +1 -1
  240. package/modules/pixfutureBidAdapter.js +46 -15
  241. package/modules/prebidServerBidAdapter/index.js +54 -19
  242. package/modules/priceFloors.js +8 -22
  243. package/modules/readpeakBidAdapter.js +1 -1
  244. package/modules/rubiconAnalyticsAdapter.js +14 -9
  245. package/modules/rubiconBidAdapter.js +2 -3
  246. package/modules/seedingAllianceBidAdapter.js +1 -1
  247. package/modules/sharethroughBidAdapter.js +1 -1
  248. package/modules/taboolaBidAdapter.js +5 -5
  249. package/modules/talkadsBidAdapter.js +1 -0
  250. package/modules/teadsIdSystem.js +234 -0
  251. package/modules/teadsIdSystem.md +22 -0
  252. package/modules/truereachBidAdapter.js +1 -0
  253. package/modules/ttdBidAdapter.js +1 -1
  254. package/modules/userId/index.js +21 -14
  255. package/modules/vrtcalBidAdapter.js +7 -1
  256. package/modules/vuukleBidAdapter.js +34 -3
  257. package/modules/yahoosspBidAdapter.js +4 -2
  258. package/modules/yandexBidAdapter.js +31 -8
  259. package/package.json +2 -2
  260. package/src/adapterManager.js +2 -4
  261. package/src/adapters/bidderFactory.js +13 -11
  262. package/src/auction.js +140 -69
  263. package/src/constants.json +8 -0
  264. package/src/cpmBucketManager.js +22 -3
  265. package/src/native.js +1 -5
  266. package/src/prebid.js +5 -6
  267. package/src/targeting.js +31 -14
  268. package/test/fixtures/fixtures.js +2 -1
  269. package/test/spec/auctionmanager_spec.js +109 -21
  270. package/test/spec/cpmBucketManager_spec.js +239 -177
  271. package/test/spec/fpd/sua_spec.js +244 -0
  272. package/test/spec/modules/adfBidAdapter_spec.js +2 -3
  273. package/test/spec/modules/adqueryIdSystem_spec.js +0 -2
  274. package/test/spec/modules/adxcgBidAdapter_spec.js +2 -3
  275. package/test/spec/modules/amxBidAdapter_spec.js +3 -2
  276. package/test/spec/modules/aolBidAdapter_spec.js +42 -9
  277. package/test/spec/modules/appnexusBidAdapter_spec.js +24 -0
  278. package/test/spec/modules/{andBeyondMediaBidAdapter_spec.js → beyondmediaBidAdapter_spec.js} +1 -1
  279. package/test/spec/modules/colossussspBidAdapter_spec.js +4 -2
  280. package/test/spec/modules/connectIdSystem_spec.js +20 -0
  281. package/test/spec/modules/conversantAnalyticsAdapter_spec.js +963 -0
  282. package/test/spec/modules/currency_spec.js +14 -6
  283. package/test/spec/modules/debugging_mod_spec.js +9 -0
  284. package/test/spec/modules/dgkeywordRtdProvider_spec.js +83 -1
  285. package/test/spec/modules/dianomiBidAdapter_spec.js +2 -3
  286. package/test/spec/modules/enrichmentFpdModule_spec.js +50 -7
  287. package/test/spec/modules/eplanningBidAdapter_spec.js +285 -1
  288. package/test/spec/modules/fpdModule_spec.js +9 -0
  289. package/test/spec/modules/gridBidAdapter_spec.js +87 -31
  290. package/test/spec/modules/ixBidAdapter_spec.js +221 -2
  291. package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +62 -8
  292. package/test/spec/modules/liveIntentIdSystem_spec.js +62 -8
  293. package/test/spec/modules/lotamePanoramaIdSystem_spec.js +0 -1
  294. package/test/spec/modules/magniteAnalyticsAdapter_spec.js +1942 -0
  295. package/test/spec/modules/mediakeysBidAdapter_spec.js +20 -3
  296. package/test/spec/modules/nativoBidAdapter_spec.js +13 -2
  297. package/test/spec/modules/prebidServerBidAdapter_spec.js +202 -15
  298. package/test/spec/modules/priceFloors_spec.js +5 -5
  299. package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +2 -3
  300. package/test/spec/modules/seedtagBidAdapter_spec.js +15 -18
  301. package/test/spec/modules/sharethroughBidAdapter_spec.js +2 -1
  302. package/test/spec/modules/taboolaBidAdapter_spec.js +112 -13
  303. package/test/spec/modules/teadsIdSystem_spec.js +271 -0
  304. package/test/spec/modules/ttdBidAdapter_spec.js +3 -3
  305. package/test/spec/modules/userId_spec.js +39 -4
  306. package/test/spec/modules/vrtcalBidAdapter_spec.js +12 -1
  307. package/test/spec/modules/vuukleBidAdapter_spec.js +87 -0
  308. package/test/spec/modules/yahoosspBidAdapter_spec.js +48 -1
  309. package/test/spec/modules/yandexBidAdapter_spec.js +8 -5
  310. package/test/spec/native_spec.js +5 -0
  311. package/test/spec/unit/core/bidderFactory_spec.js +66 -11
  312. package/test/spec/unit/core/targeting_spec.js +28 -9
  313. package/test/spec/unit/pbjs_api_spec.js +48 -2
@@ -0,0 +1,963 @@
1
+ import sinon from 'sinon';
2
+ import {expect} from 'chai';
3
+ import {default as conversantAnalytics, CNVR_CONSTANTS, cnvrHelper} from 'modules/conversantAnalyticsAdapter';
4
+ import * as utils from 'src/utils.js';
5
+ import * as prebidGlobal from 'src/prebidGlobal';
6
+
7
+ import constants from 'src/constants.json'
8
+
9
+ let events = require('src/events');
10
+
11
+ describe('Conversant analytics adapter tests', function() {
12
+ let sandbox; // sinon sandbox to make restoring all stubbed objects easier
13
+ let xhr; // xhr stub from sinon for capturing data sent via ajax
14
+ let clock; // clock stub from sinon to mock our cache cleanup interval
15
+
16
+ const PREBID_VERSION = '1.2';
17
+ const SITE_ID = 108060;
18
+
19
+ let requests = [];
20
+ const DATESTAMP = Date.now();
21
+
22
+ const VALID_CONFIGURATION = {
23
+ options: {
24
+ site_id: SITE_ID
25
+ }
26
+ };
27
+
28
+ const VALID_ALWAYS_SAMPLE_CONFIG = {
29
+ options: {
30
+ site_id: SITE_ID,
31
+ cnvr_sampling: 1
32
+ }
33
+ };
34
+
35
+ beforeEach(function () {
36
+ sandbox = sinon.sandbox.create();
37
+ sandbox.stub(events, 'getEvents').returns([]); // need to stub this otherwise unwanted events seem to get fired during testing
38
+ xhr = sandbox.useFakeXMLHttpRequest(); // allows us to capture ajax requests
39
+ xhr.onCreate = function (req) { requests.push(req); }; // save ajax requests in a private array for testing purposes
40
+ let getGlobalStub = {
41
+ version: PREBID_VERSION,
42
+ getUserIds: function() { // userIdTargeting.js init() gets called on AUCTION_END so we need to mock this function.
43
+ return {};
44
+ }
45
+ };
46
+ sandbox.stub(prebidGlobal, 'getGlobal').returns(getGlobalStub); // getGlobal does not seem to be available in testing so need to mock it
47
+ clock = sandbox.useFakeTimers(DATESTAMP); // to use sinon fake timers they MUST be created before the interval/timeout is created in the code you are testing.
48
+ });
49
+
50
+ afterEach(function () {
51
+ sandbox.restore();
52
+ requests = []; // clean up any requests in our ajax request capture array.
53
+ });
54
+
55
+ describe('Initialization Tests', function() {
56
+ it('should log error if site id is not passed', function() {
57
+ sandbox.stub(utils, 'logError');
58
+
59
+ conversantAnalytics.enableAnalytics();
60
+ expect(utils.logError.calledWith(CNVR_CONSTANTS.LOG_PREFIX + 'siteId is required.')).to.be.true;
61
+ conversantAnalytics.disableAnalytics();
62
+ });
63
+
64
+ it('should not log error if valid config is passed', function() {
65
+ sandbox.stub(utils, 'logError');
66
+ sandbox.stub(utils, 'logInfo');
67
+
68
+ conversantAnalytics.enableAnalytics(VALID_CONFIGURATION);
69
+ expect(utils.logError.called).to.equal(false);
70
+ expect(utils.logInfo.called).to.equal(true);
71
+ expect(
72
+ utils.logInfo.calledWith(
73
+ CNVR_CONSTANTS.LOG_PREFIX + 'Conversant sample rate set to ' + CNVR_CONSTANTS.DEFAULT_SAMPLE_RATE
74
+ )
75
+ ).to.be.true;
76
+ expect(
77
+ utils.logInfo.calledWith(
78
+ CNVR_CONSTANTS.LOG_PREFIX + 'Global sample rate set to 1'
79
+ )
80
+ ).to.be.true;
81
+ conversantAnalytics.disableAnalytics();
82
+ });
83
+
84
+ it('should sample when sampling set to 1', function() {
85
+ sandbox.stub(utils, 'logError');
86
+ conversantAnalytics.enableAnalytics(VALID_ALWAYS_SAMPLE_CONFIG);
87
+ expect(utils.logError.called).to.equal(false);
88
+ expect(cnvrHelper.doSample).to.equal(true);
89
+ conversantAnalytics.disableAnalytics();
90
+ });
91
+
92
+ it('should NOT sample when sampling set to 0', function() {
93
+ sandbox.stub(utils, 'logError');
94
+ const NEVER_SAMPLE_CONFIG = utils.deepClone(VALID_ALWAYS_SAMPLE_CONFIG);
95
+ NEVER_SAMPLE_CONFIG['options'].cnvr_sampling = 0;
96
+ conversantAnalytics.enableAnalytics(NEVER_SAMPLE_CONFIG);
97
+ expect(utils.logError.called).to.equal(false);
98
+ expect(cnvrHelper.doSample).to.equal(false);
99
+ conversantAnalytics.disableAnalytics();
100
+ });
101
+ });
102
+
103
+ describe('Helper Function Tests', function() {
104
+ it('should cleanup up cache objects', function() {
105
+ conversantAnalytics.enableAnalytics(VALID_CONFIGURATION);
106
+
107
+ cnvrHelper.adIdLookup['keep'] = {timeReceived: DATESTAMP + 1};
108
+ cnvrHelper.adIdLookup['delete'] = {timeReceived: DATESTAMP - CNVR_CONSTANTS.MAX_MILLISECONDS_IN_CACHE};
109
+
110
+ cnvrHelper.timeoutCache['keep'] = {timeReceived: DATESTAMP + 1};
111
+ cnvrHelper.timeoutCache['delete'] = {timeReceived: DATESTAMP - CNVR_CONSTANTS.MAX_MILLISECONDS_IN_CACHE};
112
+
113
+ cnvrHelper.auctionIdTimestampCache['keep'] = {timeReceived: DATESTAMP + 1};
114
+ cnvrHelper.auctionIdTimestampCache['delete'] = {timeReceived: DATESTAMP - CNVR_CONSTANTS.MAX_MILLISECONDS_IN_CACHE};
115
+
116
+ expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(2);
117
+ expect(Object.keys(cnvrHelper.timeoutCache)).to.have.lengthOf(2);
118
+ expect(Object.keys(cnvrHelper.auctionIdTimestampCache)).to.have.lengthOf(2);
119
+
120
+ clock.tick(CNVR_CONSTANTS.CACHE_CLEANUP_TIME_IN_MILLIS);
121
+ expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(1);
122
+ expect(Object.keys(cnvrHelper.timeoutCache)).to.have.lengthOf(1);
123
+ expect(Object.keys(cnvrHelper.auctionIdTimestampCache)).to.have.lengthOf(1);
124
+
125
+ conversantAnalytics.disableAnalytics();
126
+
127
+ // After disable we should cleanup the cache
128
+ expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(0);
129
+ expect(Object.keys(cnvrHelper.timeoutCache)).to.have.lengthOf(0);
130
+ expect(Object.keys(cnvrHelper.auctionIdTimestampCache)).to.have.lengthOf(0);
131
+ });
132
+
133
+ it('createBid() should return correct object', function() {
134
+ const EVENT_CODE = 1;
135
+ const TIME = 2;
136
+ let bid = cnvrHelper.createBid(EVENT_CODE, 2);
137
+ expect(bid).to.deep.equal({'eventCodes': [EVENT_CODE], 'timeToRespond': TIME});
138
+ });
139
+
140
+ it('createAdUnit() should return correct object', function() {
141
+ let adUnit = cnvrHelper.createAdUnit();
142
+ expect(adUnit).to.deep.equal({
143
+ sizes: [],
144
+ mediaTypes: [],
145
+ bids: {}
146
+ });
147
+ });
148
+
149
+ it('createAdSize() should return correct object', function() {
150
+ let adSize = cnvrHelper.createAdSize(1, 2);
151
+ expect(adSize).to.deep.equal({w: 1, h: 2});
152
+
153
+ adSize = cnvrHelper.createAdSize();
154
+ expect(adSize).to.deep.equal({w: -1, h: -1});
155
+
156
+ adSize = cnvrHelper.createAdSize('foo', 'bar');
157
+ expect(adSize).to.deep.equal({w: -1, h: -1});
158
+ });
159
+
160
+ it('getLookupKey() should return correct object', function() {
161
+ let key = cnvrHelper.getLookupKey(undefined, undefined, undefined);
162
+ expect(key).to.equal('undefined-undefined-undefined');
163
+
164
+ key = cnvrHelper.getLookupKey('foo', 'bar', 'baz');
165
+ expect(key).to.equal('foo-bar-baz');
166
+ });
167
+
168
+ it('createPayload() should return correct object', function() {
169
+ const REQUEST_TYPE = 'foo';
170
+ const AUCTION_ID = '124 abc';
171
+ const myDate = Date.now();
172
+ conversantAnalytics.enableAnalytics(VALID_ALWAYS_SAMPLE_CONFIG);
173
+
174
+ let payload = cnvrHelper.createPayload(REQUEST_TYPE, AUCTION_ID, myDate);
175
+ expect(payload).to.deep.equal({
176
+ cnvrSampleRate: 1,
177
+ globalSampleRate: 1,
178
+ requestType: REQUEST_TYPE,
179
+ auction: {
180
+ auctionId: AUCTION_ID,
181
+ auctionTimestamp: myDate,
182
+ sid: VALID_ALWAYS_SAMPLE_CONFIG.options.site_id,
183
+ preBidVersion: PREBID_VERSION
184
+ },
185
+ adUnits: {}
186
+ });
187
+
188
+ conversantAnalytics.disableAnalytics();
189
+ });
190
+
191
+ it('keyExistsAndIsObject() should return correct data', function() {
192
+ let data = {
193
+ a: [],
194
+ b: 1,
195
+ c: 'foo',
196
+ d: function () { return true; },
197
+ e: {}
198
+ };
199
+ expect(cnvrHelper.keyExistsAndIsObject(data, 'foobar')).to.be.false;
200
+ expect(cnvrHelper.keyExistsAndIsObject(data, 'a')).to.be.false;
201
+ expect(cnvrHelper.keyExistsAndIsObject(data, 'b')).to.be.false;
202
+ expect(cnvrHelper.keyExistsAndIsObject(data, 'c')).to.be.false;
203
+ expect(cnvrHelper.keyExistsAndIsObject(data, 'd')).to.be.false;
204
+ expect(cnvrHelper.keyExistsAndIsObject(data, 'e')).to.be.true;
205
+ });
206
+
207
+ it('deduplicateArray() should return correct data', function () {
208
+ let arrayOfObjects = [{w: 1, h: 2}, {w: 2, h: 3}, {w: 1, h: 2}];
209
+ let array = [3, 2, 1, 1, 2, 3];
210
+ let empty;
211
+ let notArray = 3;
212
+ let emptyArray = [];
213
+
214
+ expect(JSON.stringify(cnvrHelper.deduplicateArray(array))).to.equal(JSON.stringify([3, 2, 1]));
215
+ expect(JSON.stringify(cnvrHelper.deduplicateArray(arrayOfObjects))).to.equal(JSON.stringify([{w: 1, h: 2}, {w: 2, h: 3}]));
216
+ expect(JSON.stringify(cnvrHelper.deduplicateArray(emptyArray))).to.equal(JSON.stringify([]));
217
+ expect(cnvrHelper.deduplicateArray(empty)).to.be.undefined;
218
+ expect(cnvrHelper.deduplicateArray(notArray)).to.equal(notArray);
219
+ });
220
+
221
+ it('getSampleRate() should return correct data', function () {
222
+ let obj = {
223
+ sampling: 1,
224
+ cnvr_sampling: 0.5,
225
+ too_big: 1.2,
226
+ too_small: -1,
227
+ string: 'foo',
228
+ object: {},
229
+ }
230
+ const DEFAULT_VAL = 0.11;
231
+ expect(cnvrHelper.getSampleRate(obj, 'sampling', DEFAULT_VAL)).to.equal(1);
232
+ expect(cnvrHelper.getSampleRate(obj, 'cnvr_sampling', DEFAULT_VAL)).to.equal(0.5);
233
+ expect(cnvrHelper.getSampleRate(obj, 'too_big', DEFAULT_VAL)).to.equal(DEFAULT_VAL);
234
+ expect(cnvrHelper.getSampleRate(obj, 'string', DEFAULT_VAL)).to.equal(DEFAULT_VAL);
235
+ expect(cnvrHelper.getSampleRate(obj, 'object', DEFAULT_VAL)).to.equal(DEFAULT_VAL);
236
+ expect(cnvrHelper.getSampleRate(obj, 'not_a_key', DEFAULT_VAL)).to.equal(DEFAULT_VAL);
237
+ expect(cnvrHelper.getSampleRate(obj, 'too_small', DEFAULT_VAL)).to.equal(0);
238
+ });
239
+ });
240
+
241
+ describe('Bid Timeout Event Tests', function() {
242
+ const BID_TIMEOUT_PAYLOAD = [{
243
+ 'bidId': '80882409358b8a8',
244
+ 'bidder': 'conversant',
245
+ 'adUnitCode': 'MedRect',
246
+ 'auctionId': 'afbd6e0b-e45b-46ab-87bf-c0bac0cb8881'
247
+ }, {
248
+ 'bidId': '9da4c107a6f24c8',
249
+ 'bidder': 'conversant',
250
+ 'adUnitCode': 'Leaderboard',
251
+ 'auctionId': 'afbd6e0b-e45b-46ab-87bf-c0bac0cb8881'
252
+ }];
253
+
254
+ beforeEach(function () {
255
+ conversantAnalytics.enableAnalytics(VALID_ALWAYS_SAMPLE_CONFIG);
256
+ });
257
+
258
+ afterEach(function () {
259
+ conversantAnalytics.disableAnalytics();
260
+ });
261
+
262
+ it('should put both items in timeout cache', function() {
263
+ expect(Object.keys(cnvrHelper.timeoutCache)).to.have.lengthOf(0);
264
+ events.emit(constants.EVENTS.BID_TIMEOUT, BID_TIMEOUT_PAYLOAD);
265
+ expect(Object.keys(cnvrHelper.timeoutCache)).to.have.lengthOf(2);
266
+
267
+ BID_TIMEOUT_PAYLOAD.forEach(timeoutBid => {
268
+ const key = cnvrHelper.getLookupKey(timeoutBid.auctionId, timeoutBid.adUnitCode, timeoutBid.bidder);
269
+ expect(cnvrHelper.timeoutCache[key].timeReceived).to.not.be.undefined;
270
+ });
271
+ expect(requests).to.have.lengthOf(0);
272
+ });
273
+ });
274
+
275
+ describe('Render Failed Tests', function() {
276
+ const RENDER_FAILED_PAYLOAD = {
277
+ reason: 'reason',
278
+ message: 'value',
279
+ adId: '57e03aeafd83a68'
280
+ };
281
+
282
+ const RENDER_FAILED_PAYLOAD_NO_ADID = {
283
+ reason: 'reason',
284
+ message: 'value'
285
+ };
286
+
287
+ beforeEach(function () {
288
+ conversantAnalytics.enableAnalytics(VALID_ALWAYS_SAMPLE_CONFIG);
289
+ });
290
+
291
+ afterEach(function () {
292
+ conversantAnalytics.disableAnalytics();
293
+ });
294
+
295
+ it('should empty adIdLookup and send data', function() {
296
+ cnvrHelper.adIdLookup[RENDER_FAILED_PAYLOAD.adId] = {
297
+ bidderCode: 'bidderCode',
298
+ adUnitCode: 'adUnitCode',
299
+ auctionId: 'auctionId',
300
+ timeReceived: Date.now()
301
+ };
302
+
303
+ expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(1);
304
+ events.emit(constants.EVENTS.AD_RENDER_FAILED, RENDER_FAILED_PAYLOAD);
305
+ expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(0); // object should be removed
306
+ expect(requests).to.have.lengthOf(1);
307
+ const data = JSON.parse(requests[0].requestBody);
308
+
309
+ expect(data.auction.auctionId).to.equal('auctionId');
310
+ expect(data.auction.preBidVersion).to.equal(PREBID_VERSION);
311
+ expect(data.auction.sid).to.equal(SITE_ID);
312
+ expect(data.adUnits['adUnitCode'].bids['bidderCode'][0].eventCodes.includes(CNVR_CONSTANTS.RENDER_FAILED)).to.be.true;
313
+ expect(data.adUnits['adUnitCode'].bids['bidderCode'][0].message).to.have.lengthOf.above(0);
314
+ });
315
+
316
+ it('should not send data if no adId', function() {
317
+ cnvrHelper.adIdLookup[RENDER_FAILED_PAYLOAD.adId] = {
318
+ bidderCode: 'bidderCode',
319
+ adUnitCode: 'adUnitCode',
320
+ auctionId: 'auctionId',
321
+ timeReceived: Date.now()
322
+ };
323
+
324
+ expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(1);
325
+ events.emit(constants.EVENTS.AD_RENDER_FAILED, RENDER_FAILED_PAYLOAD_NO_ADID);
326
+ expect(requests).to.have.lengthOf(0);
327
+ expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(1); // same object in cache as before... no change
328
+ expect(cnvrHelper.adIdLookup[RENDER_FAILED_PAYLOAD.adId]).to.not.be.undefined;
329
+ });
330
+
331
+ it('should not send data if bad data in lookup', function() {
332
+ cnvrHelper.adIdLookup[RENDER_FAILED_PAYLOAD.adId] = {
333
+ bidderCode: 'bidderCode',
334
+ auctionId: 'auctionId',
335
+ timeReceived: Date.now()
336
+ };
337
+ expect(requests).to.have.lengthOf(0);
338
+ expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(1);
339
+ events.emit(constants.EVENTS.AD_RENDER_FAILED, RENDER_FAILED_PAYLOAD);
340
+ expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(0); // object should be removed but no call made to send data
341
+ expect(requests).to.have.lengthOf(0);
342
+ });
343
+ });
344
+
345
+ describe('Bid Won Tests', function() {
346
+ const GOOD_BID_WON_ARGS = {
347
+ bidderCode: 'conversant',
348
+ width: 300,
349
+ height: 250,
350
+ statusMessage: 'Bid available',
351
+ adId: '57e03aeafd83a68',
352
+ requestId: '2c2a5485a076898',
353
+ mediaType: 'banner',
354
+ source: 'client',
355
+ currency: 'USD',
356
+ cpm: 4,
357
+ creativeId: '29123_55016759',
358
+ ttl: 300,
359
+ netRevenue: true,
360
+ ad: '<foobar add goes here />',
361
+ originalCpm: 0.04,
362
+ originalCurrency: 'USD',
363
+ auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
364
+ responseTimestamp: 1583851418626,
365
+ requestTimestamp: 1583851418292,
366
+ bidder: 'conversant',
367
+ adUnitCode: 'div-gpt-ad-1460505748561-0',
368
+ timeToRespond: 334,
369
+ pbLg: '4.00',
370
+ pbMg: '4.00',
371
+ pbHg: '4.00',
372
+ pbAg: '4.00',
373
+ pbDg: '4.00',
374
+ pbCg: '',
375
+ size: '300x250',
376
+ adserverTargeting: {
377
+ hb_bidder: 'conversant',
378
+ hb_adid: '57e03aeafd83a68',
379
+ hb_pb: '4.00',
380
+ hb_size: '300x250',
381
+ hb_source: 'client',
382
+ hb_format: 'banner'
383
+ },
384
+ status: 'rendered',
385
+ params: [
386
+ {
387
+ site_id: '108060'
388
+ }
389
+ ]
390
+ };
391
+
392
+ // no adUnitCode, auctionId or bidderCode will cause a failure
393
+ const BAD_BID_WON_ARGS = {
394
+ bidderCode: 'conversant',
395
+ width: 300,
396
+ height: 250,
397
+ statusMessage: 'Bid available',
398
+ adId: '57e03aeafd83a68',
399
+ requestId: '2c2a5485a076898',
400
+ mediaType: 'banner',
401
+ source: 'client',
402
+ currency: 'USD',
403
+ cpm: 4,
404
+ originalCpm: 0.04,
405
+ originalCurrency: 'USD',
406
+ bidder: 'conversant',
407
+ adUnitCode: 'div-gpt-ad-1460505748561-0',
408
+ size: '300x250',
409
+ status: 'rendered',
410
+ params: [
411
+ {
412
+ site_id: '108060'
413
+ }
414
+ ]
415
+ };
416
+
417
+ beforeEach(function () {
418
+ conversantAnalytics.enableAnalytics(VALID_ALWAYS_SAMPLE_CONFIG);
419
+ });
420
+
421
+ afterEach(function () {
422
+ conversantAnalytics.disableAnalytics();
423
+ });
424
+
425
+ it('should not send data or put a record in adIdLookup when bad data provided', function() {
426
+ expect(requests).to.have.lengthOf(0);
427
+ expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(0);
428
+ events.emit(constants.EVENTS.BID_WON, BAD_BID_WON_ARGS);
429
+ expect(requests).to.have.lengthOf(0);
430
+ expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(0);
431
+ });
432
+
433
+ it('should send data and put a record in adIdLookup', function() {
434
+ const myAuctionStart = Date.now();
435
+ cnvrHelper.auctionIdTimestampCache[GOOD_BID_WON_ARGS.auctionId] = {timeReceived: myAuctionStart};
436
+
437
+ expect(requests).to.have.lengthOf(0);
438
+ expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(0);
439
+ events.emit(constants.EVENTS.BID_WON, GOOD_BID_WON_ARGS);
440
+
441
+ // Check that adIdLookup was set correctly
442
+ expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(1);
443
+ expect(cnvrHelper.adIdLookup[GOOD_BID_WON_ARGS.adId].auctionId).to.equal(GOOD_BID_WON_ARGS.auctionId);
444
+ expect(cnvrHelper.adIdLookup[GOOD_BID_WON_ARGS.adId].adUnitCode).to.equal(GOOD_BID_WON_ARGS.adUnitCode);
445
+ expect(cnvrHelper.adIdLookup[GOOD_BID_WON_ARGS.adId].bidderCode).to.equal(GOOD_BID_WON_ARGS.bidderCode);
446
+ expect(cnvrHelper.adIdLookup[GOOD_BID_WON_ARGS.adId].timeReceived).to.not.be.undefined;
447
+
448
+ expect(requests).to.have.lengthOf(1);
449
+ const data = JSON.parse(requests[0].requestBody);
450
+ expect(data.requestType).to.equal('bid_won');
451
+ expect(data.auction.auctionId).to.equal(GOOD_BID_WON_ARGS.auctionId);
452
+ expect(data.auction.preBidVersion).to.equal(PREBID_VERSION);
453
+ expect(data.auction.sid).to.equal(VALID_ALWAYS_SAMPLE_CONFIG.options.site_id);
454
+ expect(data.auction.auctionTimestamp).to.equal(myAuctionStart);
455
+
456
+ expect(typeof data.adUnits).to.equal('object');
457
+ expect(Object.keys(data.adUnits)).to.have.lengthOf(1);
458
+
459
+ expect(Object.keys(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids)).to.have.lengthOf(1);
460
+ expect(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids[GOOD_BID_WON_ARGS.bidderCode][0].eventCodes.includes(CNVR_CONSTANTS.WIN)).to.be.true;
461
+ expect(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids[GOOD_BID_WON_ARGS.bidderCode][0].cpm).to.equal(GOOD_BID_WON_ARGS.cpm);
462
+ expect(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids[GOOD_BID_WON_ARGS.bidderCode][0].originalCpm).to.equal(GOOD_BID_WON_ARGS.originalCpm);
463
+ expect(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids[GOOD_BID_WON_ARGS.bidderCode][0].currency).to.equal(GOOD_BID_WON_ARGS.currency);
464
+ expect(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids[GOOD_BID_WON_ARGS.bidderCode][0].timeToRespond).to.equal(GOOD_BID_WON_ARGS.timeToRespond);
465
+ expect(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids[GOOD_BID_WON_ARGS.bidderCode][0].adSize.w).to.equal(GOOD_BID_WON_ARGS.width);
466
+ expect(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids[GOOD_BID_WON_ARGS.bidderCode][0].adSize.h).to.equal(GOOD_BID_WON_ARGS.height);
467
+ });
468
+ });
469
+
470
+ describe('Auction End Tests', function() {
471
+ const AUCTION_END_PAYLOAD = {
472
+ auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
473
+ timestamp: 1583851418288,
474
+ auctionEnd: 1583851418628,
475
+ auctionStatus: 'completed',
476
+ adUnits: [
477
+ {
478
+ code: 'div-gpt-ad-1460505748561-0',
479
+ mediaTypes: {
480
+ banner: {
481
+ sizes: [
482
+ [300, 250],
483
+ [100, 200]
484
+ ]
485
+ }
486
+ },
487
+ bids: [
488
+ {
489
+ bidder: 'appnexus',
490
+ params: {
491
+ placementId: 13144370
492
+ }
493
+ },
494
+ {
495
+ bidder: 'conversant',
496
+ params: {
497
+ site_id: '108060'
498
+ }
499
+ }
500
+ ],
501
+ sizes: [
502
+ [300, 250],
503
+ [100, 200]
504
+ ],
505
+ transactionId: '5fa8a7d7-2a73-4d1c-b73a-ff9f5b53ba17'
506
+ },
507
+ {
508
+ code: 'div-gpt-ad-1460505748561-0',
509
+ mediaTypes: {
510
+ banner: {
511
+ sizes: [
512
+ [300, 250],
513
+ [100, 200]
514
+ ]
515
+ },
516
+ video: {
517
+ playerSize: [
518
+ [300, 250],
519
+ [600, 400]
520
+ ]
521
+ }
522
+ },
523
+ sizes: [
524
+ [300, 250],
525
+ [100, 200],
526
+ [600, 400]
527
+ ],
528
+ bids: [
529
+ {
530
+ bidder: 'appnexus',
531
+ params: {
532
+ placementId: 13144370
533
+ }
534
+ },
535
+ {
536
+ bidder: 'conversant',
537
+ params: {
538
+ site_id: '108060'
539
+ }
540
+ }
541
+ ],
542
+ transactionId: '5fa8a7d7-2a73-4d1c-b73a-ff9f5b53ba18'
543
+ },
544
+ {
545
+ code: 'div-gpt-ad-1460505748561-1',
546
+ mediaTypes: {
547
+ native: {
548
+ type: 'image'
549
+ }
550
+ },
551
+ bids: [
552
+ {
553
+ bidder: 'appnexus',
554
+ params: {
555
+ placementId: 13144371
556
+ }
557
+ }
558
+ ],
559
+ transactionId: '5fa8a7d7-2a73-4d1c-b73a-ff9f5b53ba10'
560
+ }
561
+ ],
562
+ adUnitCodes: [
563
+ 'div-gpt-ad-1460505748561-0'
564
+ ],
565
+ bidderRequests: [
566
+ {
567
+ bidderCode: 'conversant',
568
+ auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
569
+ bidderRequestId: '13f16db358d4c58',
570
+ bids: [
571
+ {
572
+ bidder: 'conversant',
573
+ params: {
574
+ site_id: '108060'
575
+ },
576
+ mediaTypes: {
577
+ banner: {
578
+ sizes: [
579
+ [
580
+ 300,
581
+ 250
582
+ ]
583
+ ]
584
+ }
585
+ },
586
+ adUnitCode: 'div-gpt-ad-1460505748561-0',
587
+ transactionId: '5fa8a7d7-2a73-4d1c-b73a-ff9f5b53ba17',
588
+ sizes: [
589
+ [
590
+ 300,
591
+ 250
592
+ ]
593
+ ],
594
+ bidId: '2c2a5485a076898',
595
+ bidderRequestId: '13f16db358d4c58',
596
+ auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
597
+ src: 'client',
598
+ bidRequestsCount: 1,
599
+ bidderRequestsCount: 1,
600
+ bidderWinsCount: 0
601
+ }
602
+ ],
603
+ auctionStart: 1583851418288,
604
+ timeout: 3000,
605
+ refererInfo: {
606
+ referer: 'http://localhost:9999/integrationExamples/gpt/hello_analytics1.html',
607
+ reachedTop: true,
608
+ numIframes: 0,
609
+ stack: [
610
+ 'http://localhost:9999/integrationExamples/gpt/hello_analytics1.html'
611
+ ]
612
+ },
613
+ start: 1583851418292
614
+ },
615
+ {
616
+ bidderCode: 'appnexus',
617
+ auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
618
+ bidderRequestId: '3e8179f67f31b98',
619
+ bids: [
620
+ {
621
+ bidder: 'appnexus',
622
+ params: {
623
+ placementId: 13144370
624
+ },
625
+ mediaTypes: {
626
+ banner: {
627
+ sizes: [
628
+ [
629
+ 300,
630
+ 250
631
+ ]
632
+ ]
633
+ }
634
+ },
635
+ adUnitCode: 'div-gpt-ad-1460505748561-0',
636
+ transactionId: '5fa8a7d7-2a73-4d1c-b73a-ff9f5b53ba17',
637
+ sizes: [
638
+ [
639
+ 300,
640
+ 250
641
+ ]
642
+ ],
643
+ bidId: '40a1d3ac6b79668',
644
+ bidderRequestId: '3e8179f67f31b98',
645
+ auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
646
+ src: 'client',
647
+ bidRequestsCount: 1,
648
+ bidderRequestsCount: 1,
649
+ bidderWinsCount: 0
650
+ },
651
+ {
652
+ bidder: 'appnexus',
653
+ params: {
654
+ placementId: 13144370
655
+ },
656
+ mediaTypes: {
657
+ native: {
658
+ type: 'image'
659
+ }
660
+ },
661
+ adUnitCode: 'div-gpt-ad-1460505748561-1',
662
+ transactionId: '5fa8a7d7-2a73-4d1c-b73a-ff9f5b53ba17',
663
+ sizes: [],
664
+ bidId: '40a1d3ac6b79668',
665
+ bidderRequestId: '3e8179f67f31b98',
666
+ auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
667
+ src: 'client',
668
+ bidRequestsCount: 1,
669
+ bidderRequestsCount: 1,
670
+ bidderWinsCount: 0
671
+ }
672
+ ],
673
+ auctionStart: 1583851418288,
674
+ timeout: 3000,
675
+ refererInfo: {
676
+ referer: 'http://localhost:9999/integrationExamples/gpt/hello_analytics1.html',
677
+ reachedTop: true,
678
+ numIframes: 0,
679
+ stack: [
680
+ 'http://localhost:9999/integrationExamples/gpt/hello_analytics1.html'
681
+ ]
682
+ },
683
+ start: 1583851418295
684
+ }
685
+ ],
686
+ noBids: [
687
+ {
688
+ bidder: 'appnexus',
689
+ params: {
690
+ placementId: 13144370
691
+ },
692
+ mediaTypes: {
693
+ banner: {
694
+ sizes: [
695
+ [
696
+ 300,
697
+ 250
698
+ ]
699
+ ]
700
+ }
701
+ },
702
+ adUnitCode: 'div-gpt-ad-1460505748561-0',
703
+ transactionId: '5fa8a7d7-2a73-4d1c-b73a-ff9f5b53ba17',
704
+ sizes: [
705
+ [
706
+ 300,
707
+ 250
708
+ ]
709
+ ],
710
+ bidId: '40a1d3ac6b79668',
711
+ bidderRequestId: '3e8179f67f31b98',
712
+ auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
713
+ src: 'client',
714
+ bidRequestsCount: 1,
715
+ bidderRequestsCount: 1,
716
+ bidderWinsCount: 0
717
+ }
718
+ ],
719
+ bidsReceived: [
720
+ {
721
+ bidderCode: 'conversant',
722
+ width: 300,
723
+ height: 250,
724
+ statusMessage: 'Bid available',
725
+ adId: '57e03aeafd83a68',
726
+ requestId: '2c2a5485a076898',
727
+ mediaType: 'banner',
728
+ source: 'client',
729
+ currency: 'USD',
730
+ cpm: 4,
731
+ creativeId: '29123_55016759',
732
+ ttl: 300,
733
+ netRevenue: true,
734
+ ad: '<foobar add goes here />',
735
+ originalCpm: 0.04,
736
+ originalCurrency: 'USD',
737
+ auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
738
+ responseTimestamp: 1583851418626,
739
+ requestTimestamp: 1583851418292,
740
+ bidder: 'conversant',
741
+ adUnitCode: 'div-gpt-ad-1460505748561-0',
742
+ timeToRespond: 334,
743
+ pbLg: '4.00',
744
+ pbMg: '4.00',
745
+ pbHg: '4.00',
746
+ pbAg: '4.00',
747
+ pbDg: '4.00',
748
+ pbCg: '',
749
+ size: '300x250',
750
+ adserverTargeting: {
751
+ hb_bidder: 'conversant',
752
+ hb_adid: '57e03aeafd83a68',
753
+ hb_pb: '4.00',
754
+ hb_size: '300x250',
755
+ hb_source: 'client',
756
+ hb_format: 'banner'
757
+ }
758
+ }, {
759
+ bidderCode: 'conversant',
760
+ height: 100,
761
+ statusMessage: 'Bid available',
762
+ width: 200,
763
+ adId: '57e03aeafd83a68',
764
+ requestId: '2c2a5485a076898',
765
+ mediaType: 'banner',
766
+ source: 'client',
767
+ currency: 'USD',
768
+ cpm: 4,
769
+ creativeId: '29123_55016759',
770
+ ttl: 300,
771
+ netRevenue: true,
772
+ ad: '<foobar add goes here />',
773
+ originalCpm: 0.04,
774
+ originalCurrency: 'USD',
775
+ auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
776
+ responseTimestamp: 1583851418626,
777
+ requestTimestamp: 1583851418292,
778
+ bidder: 'conversant',
779
+ adUnitCode: 'div-gpt-ad-1460505748561-0',
780
+ timeToRespond: 334,
781
+ pbLg: '4.00',
782
+ pbMg: '4.00',
783
+ pbHg: '4.00',
784
+ pbAg: '4.00',
785
+ pbDg: '4.00',
786
+ pbCg: '',
787
+ size: '100x200',
788
+ adserverTargeting: {
789
+ hb_bidder: 'conversant',
790
+ hb_adid: '57e03aeafd83a68',
791
+ hb_pb: '4.00',
792
+ hb_size: '300x250',
793
+ hb_source: 'client',
794
+ hb_format: 'banner'
795
+ }
796
+ }, {
797
+ bidderCode: 'appnexus',
798
+ statusMessage: 'Bid available',
799
+ adId: '57e03aeafd83a68',
800
+ requestId: '2c2a5485a076898',
801
+ mediaType: 'native',
802
+ source: 'client',
803
+ currency: 'USD',
804
+ cpm: 4,
805
+ creativeId: '29123_55016759',
806
+ ttl: 300,
807
+ netRevenue: true,
808
+ ad: '<foobar add goes here />',
809
+ originalCpm: 0.04,
810
+ originalCurrency: 'USD',
811
+ auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
812
+ responseTimestamp: 1583851418626,
813
+ requestTimestamp: 1583851418292,
814
+ bidder: 'appnexus',
815
+ adUnitCode: 'div-gpt-ad-1460505748561-1',
816
+ timeToRespond: 334,
817
+ pbLg: '4.00',
818
+ pbMg: '4.00',
819
+ pbHg: '4.00',
820
+ pbAg: '4.00',
821
+ pbDg: '4.00',
822
+ pbCg: '',
823
+ adserverTargeting: {
824
+ hb_bidder: 'appnexus',
825
+ hb_adid: '57e03aeafd83a68',
826
+ hb_pb: '4.00',
827
+ hb_size: '300x250',
828
+ hb_source: 'client',
829
+ hb_format: 'banner'
830
+ }
831
+ }
832
+ ],
833
+ winningBids: [],
834
+ timeout: 3000
835
+ };
836
+
837
+ beforeEach(function () {
838
+ conversantAnalytics.enableAnalytics(VALID_ALWAYS_SAMPLE_CONFIG);
839
+ });
840
+
841
+ afterEach(function () {
842
+ conversantAnalytics.disableAnalytics();
843
+ });
844
+
845
+ it('should not do anything when auction id doesnt exist', function() {
846
+ sandbox.stub(utils, 'logError');
847
+
848
+ let BAD_ARGS = JSON.parse(JSON.stringify(AUCTION_END_PAYLOAD));
849
+ delete BAD_ARGS.auctionId;
850
+ expect(requests).to.have.lengthOf(0);
851
+ events.emit(constants.EVENTS.AUCTION_END, BAD_ARGS);
852
+ expect(requests).to.have.lengthOf(0);
853
+ expect(
854
+ utils.logError.calledWith(
855
+ CNVR_CONSTANTS.LOG_PREFIX + 'onAuctionEnd(): No auctionId in args supplied so unable to process event.'
856
+ )
857
+ ).to.be.true;
858
+ });
859
+
860
+ it('should send the expected data', function() {
861
+ sandbox.stub(utils, 'logError');
862
+ sandbox.stub(utils, 'logWarn'); /* .callsFake((arg, arg1, arg2) => { //debugging stuff
863
+ console.error(arg);
864
+ if (arg1) console.error(arg1);
865
+ if (arg2) console.error(arg2);
866
+ }); */
867
+ expect(requests).to.have.lengthOf(0);
868
+ const AUCTION_ID = AUCTION_END_PAYLOAD.auctionId;
869
+ const AD_UNIT_CODE = AUCTION_END_PAYLOAD.adUnits[0].code;
870
+ const AD_UNIT_CODE_NATIVE = AUCTION_END_PAYLOAD.adUnits[2].code;
871
+ const timeoutKey = cnvrHelper.getLookupKey(AUCTION_ID, AD_UNIT_CODE, 'appnexus');
872
+ cnvrHelper.timeoutCache[timeoutKey] = { timeReceived: Date.now() };
873
+ expect(Object.keys(cnvrHelper.timeoutCache)).to.have.lengthOf(1);
874
+ expect(utils.logError.called).to.equal(false);
875
+ expect(Object.keys(cnvrHelper.auctionIdTimestampCache)).to.have.lengthOf(0);
876
+
877
+ events.emit(constants.EVENTS.AUCTION_END, AUCTION_END_PAYLOAD);
878
+ expect(utils.logError.called).to.equal(false);
879
+ expect(requests).to.have.lengthOf(1);
880
+ expect(Object.keys(cnvrHelper.timeoutCache)).to.have.lengthOf(0);
881
+ expect(Object.keys(cnvrHelper.auctionIdTimestampCache)).to.have.lengthOf(1);
882
+ expect(cnvrHelper.auctionIdTimestampCache[AUCTION_END_PAYLOAD.auctionId].timeReceived).to.equal(AUCTION_END_PAYLOAD.timestamp);
883
+
884
+ const data = JSON.parse(requests[0].requestBody);
885
+ expect(data.requestType).to.equal('auction_end');
886
+ expect(data.auction.auctionId).to.equal(AUCTION_ID);
887
+ expect(data.auction.preBidVersion).to.equal(PREBID_VERSION);
888
+ expect(data.auction.sid).to.equal(VALID_ALWAYS_SAMPLE_CONFIG.options.site_id);
889
+
890
+ expect(Object.keys(data.adUnits)).to.have.lengthOf(2);
891
+
892
+ expect(data.adUnits[AD_UNIT_CODE].sizes).to.have.lengthOf(3);
893
+ expect(data.adUnits[AD_UNIT_CODE].sizes[0].w).to.equal(300);
894
+ expect(data.adUnits[AD_UNIT_CODE].sizes[0].h).to.equal(250);
895
+ expect(data.adUnits[AD_UNIT_CODE].sizes[1].w).to.equal(100);
896
+ expect(data.adUnits[AD_UNIT_CODE].sizes[1].h).to.equal(200);
897
+ expect(data.adUnits[AD_UNIT_CODE].sizes[2].w).to.equal(600);
898
+ expect(data.adUnits[AD_UNIT_CODE].sizes[2].h).to.equal(400);
899
+
900
+ expect(data.adUnits[AD_UNIT_CODE].mediaTypes).to.have.lengthOf(2);
901
+ expect(data.adUnits[AD_UNIT_CODE].mediaTypes[0]).to.equal('banner');
902
+ expect(data.adUnits[AD_UNIT_CODE].mediaTypes[1]).to.equal('video');
903
+
904
+ expect(data.adUnits[AD_UNIT_CODE_NATIVE].mediaTypes).to.have.lengthOf(1);
905
+ expect(data.adUnits[AD_UNIT_CODE_NATIVE].mediaTypes[0]).to.equal('native');
906
+ expect(data.adUnits[AD_UNIT_CODE_NATIVE].sizes).to.have.lengthOf(0);
907
+
908
+ expect(Object.keys(data.adUnits[AD_UNIT_CODE].bids)).to.have.lengthOf(2);
909
+ const cnvrBidsArray = data.adUnits[AD_UNIT_CODE].bids['conversant'];
910
+ // testing multiple bids from same bidder
911
+ expect(cnvrBidsArray).to.have.lengthOf(2);
912
+ expect(cnvrBidsArray[0].eventCodes.includes(CNVR_CONSTANTS.BID)).to.be.true;
913
+ expect(cnvrBidsArray[0].cpm).to.equal(4);
914
+ expect(cnvrBidsArray[0].originalCpm).to.equal(0.04);
915
+ expect(cnvrBidsArray[0].currency).to.equal('USD');
916
+ expect(cnvrBidsArray[0].timeToRespond).to.equal(334);
917
+ expect(cnvrBidsArray[0].adSize.w).to.equal(300);
918
+ expect(cnvrBidsArray[0].adSize.h).to.equal(250);
919
+ expect(cnvrBidsArray[0].mediaType).to.equal('banner');
920
+ // 2nd bid different size
921
+ expect(cnvrBidsArray[1].eventCodes.includes(CNVR_CONSTANTS.BID)).to.be.true;
922
+ expect(cnvrBidsArray[1].cpm).to.equal(4);
923
+ expect(cnvrBidsArray[1].originalCpm).to.equal(0.04);
924
+ expect(cnvrBidsArray[1].currency).to.equal('USD');
925
+ expect(cnvrBidsArray[1].timeToRespond).to.equal(334);
926
+ expect(cnvrBidsArray[1].adSize.w).to.equal(200);
927
+ expect(cnvrBidsArray[1].adSize.h).to.equal(100);
928
+ expect(cnvrBidsArray[1].mediaType).to.equal('banner');
929
+
930
+ const apnBidsArray = data.adUnits[AD_UNIT_CODE].bids['appnexus'];
931
+ expect(apnBidsArray).to.have.lengthOf(2);
932
+ let apnBid = apnBidsArray[0];
933
+ expect(apnBid.originalCpm).to.be.undefined;
934
+ expect(apnBid.eventCodes.includes(CNVR_CONSTANTS.TIMEOUT)).to.be.true;
935
+ expect(apnBid.cpm).to.be.undefined;
936
+ expect(apnBid.currency).to.be.undefined;
937
+ expect(apnBid.timeToRespond).to.equal(3000);
938
+ expect(apnBid.adSize).to.be.undefined;
939
+ expect(apnBid.mediaType).to.be.undefined;
940
+ apnBid = apnBidsArray[1];
941
+ expect(apnBid.originalCpm).to.be.undefined;
942
+ expect(apnBid.eventCodes.includes(CNVR_CONSTANTS.NO_BID)).to.be.true;
943
+ expect(apnBid.cpm).to.be.undefined;
944
+ expect(apnBid.currency).to.be.undefined;
945
+ expect(apnBid.timeToRespond).to.equal(0);
946
+ expect(apnBid.adSize).to.be.undefined;
947
+ expect(apnBid.mediaType).to.be.undefined;
948
+
949
+ expect(Object.keys(data.adUnits[AD_UNIT_CODE_NATIVE].bids)).to.have.lengthOf(1);
950
+ const apnNativeBidsArray = data.adUnits[AD_UNIT_CODE_NATIVE].bids['appnexus'];
951
+ expect(apnNativeBidsArray).to.have.lengthOf(1);
952
+ const apnNativeBid = apnNativeBidsArray[0];
953
+ expect(apnNativeBid.eventCodes.includes(CNVR_CONSTANTS.BID)).to.be.true;
954
+ expect(apnNativeBid.cpm).to.equal(4);
955
+ expect(apnNativeBid.originalCpm).to.equal(0.04);
956
+ expect(apnNativeBid.currency).to.equal('USD');
957
+ expect(apnNativeBid.timeToRespond).to.equal(334);
958
+ expect(apnNativeBid.adSize.w).to.be.undefined;
959
+ expect(apnNativeBid.adSize.h).to.be.undefined;
960
+ expect(apnNativeBid.mediaType).to.equal('native');
961
+ });
962
+ });
963
+ });