prebid.js 7.18.0 → 7.19.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 (197) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/adagioBidAdapter.js +1 -1
  3. package/dist/adbookpspBidAdapter.js +1 -1
  4. package/dist/adfBidAdapter.js +1 -1
  5. package/dist/adgenerationBidAdapter.js +1 -1
  6. package/dist/adqueryIdSystem.js +1 -1
  7. package/dist/adrelevantisBidAdapter.js +1 -1
  8. package/dist/adtrgtmeBidAdapter.js +1 -1
  9. package/dist/adxcgBidAdapter.js +1 -1
  10. package/dist/ajaBidAdapter.js +1 -1
  11. package/dist/amxBidAdapter.js +1 -1
  12. package/dist/amxIdSystem.js +1 -1
  13. package/dist/appierAnalyticsAdapter.js +1 -1
  14. package/dist/appnexusBidAdapter.js +1 -1
  15. package/dist/asoBidAdapter.js +1 -1
  16. package/dist/axonixBidAdapter.js +1 -1
  17. package/dist/{andBeyondMediaBidAdapter.js → beyondmediaBidAdapter.js} +1 -1
  18. package/dist/bidglassBidAdapter.js +1 -1
  19. package/dist/big-richmediaBidAdapter.js +1 -1
  20. package/dist/bridgewellBidAdapter.js +1 -1
  21. package/dist/brightMountainMediaBidAdapter.js +1 -1
  22. package/dist/carodaBidAdapter.js +1 -1
  23. package/dist/cleanioRtdProvider.js +1 -1
  24. package/dist/colossussspBidAdapter.js +1 -1
  25. package/dist/concertBidAdapter.js +1 -1
  26. package/dist/connectadBidAdapter.js +1 -1
  27. package/dist/consumableBidAdapter.js +1 -1
  28. package/dist/conversantAnalyticsAdapter.js +1 -0
  29. package/dist/conversantBidAdapter.js +1 -1
  30. package/dist/craftBidAdapter.js +1 -1
  31. package/dist/criteoBidAdapter.js +1 -1
  32. package/dist/debugging-standalone.js +1 -1
  33. package/dist/debugging.js +1 -1
  34. package/dist/dependencies.json +6 -0
  35. package/dist/dgkeywordRtdProvider.js +1 -1
  36. package/dist/dianomiBidAdapter.js +1 -1
  37. package/dist/dspxBidAdapter.js +1 -1
  38. package/dist/enrichmentFpdModule.js +1 -1
  39. package/dist/eplanningBidAdapter.js +1 -1
  40. package/dist/finativeBidAdapter.js +1 -1
  41. package/dist/fpd.js +1 -0
  42. package/dist/glimpseBidAdapter.js +1 -1
  43. package/dist/gmosspBidAdapter.js +1 -1
  44. package/dist/goldbachBidAdapter.js +1 -1
  45. package/dist/gridBidAdapter.js +1 -1
  46. package/dist/gridNMBidAdapter.js +1 -1
  47. package/dist/gumgumBidAdapter.js +1 -1
  48. package/dist/h12mediaBidAdapter.js +1 -1
  49. package/dist/id5IdSystem.js +1 -1
  50. package/dist/improvedigitalBidAdapter.js +1 -1
  51. package/dist/inmarBidAdapter.js +1 -1
  52. package/dist/insticatorBidAdapter.js +1 -1
  53. package/dist/ixBidAdapter.js +1 -1
  54. package/dist/justpremiumBidAdapter.js +1 -1
  55. package/dist/konduitAnalyticsAdapter.js +1 -1
  56. package/dist/kueezBidAdapter.js +1 -1
  57. package/dist/lassoBidAdapter.js +1 -1
  58. package/dist/lifestreetBidAdapter.js +1 -1
  59. package/dist/liveIntentIdSystem.js +1 -1
  60. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  61. package/dist/logicadBidAdapter.js +1 -1
  62. package/dist/loglyliftBidAdapter.js +1 -1
  63. package/dist/malltvAnalyticsAdapter.js +1 -1
  64. package/dist/marsmediaBidAdapter.js +1 -1
  65. package/dist/mediafuseBidAdapter.js +1 -1
  66. package/dist/mediakeysBidAdapter.js +1 -1
  67. package/dist/mediasquareBidAdapter.js +1 -1
  68. package/dist/mgidBidAdapter.js +1 -1
  69. package/dist/minutemediaBidAdapter.js +1 -1
  70. package/dist/nativoBidAdapter.js +1 -1
  71. package/dist/not-for-prod/prebid.js +123 -121
  72. package/dist/oguryBidAdapter.js +1 -1
  73. package/dist/onetagBidAdapter.js +1 -1
  74. package/dist/ooloAnalyticsAdapter.js +1 -1
  75. package/dist/outbrainBidAdapter.js +1 -1
  76. package/dist/parrableIdSystem.js +1 -1
  77. package/dist/pixfutureBidAdapter.js +1 -1
  78. package/dist/prebid-core.js +1 -1
  79. package/dist/prebidServerBidAdapter.js +1 -1
  80. package/dist/publinkIdSystem.js +1 -1
  81. package/dist/pubmaticBidAdapter.js +1 -1
  82. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  83. package/dist/pxyzBidAdapter.js +1 -1
  84. package/dist/quantcastBidAdapter.js +1 -1
  85. package/dist/readpeakBidAdapter.js +1 -1
  86. package/dist/relaidoBidAdapter.js +1 -1
  87. package/dist/rhythmoneBidAdapter.js +1 -1
  88. package/dist/riseBidAdapter.js +1 -1
  89. package/dist/rubiconAnalyticsAdapter.js +1 -1
  90. package/dist/rubiconBidAdapter.js +1 -1
  91. package/dist/seedingAllianceBidAdapter.js +1 -1
  92. package/dist/seedtagBidAdapter.js +1 -1
  93. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  94. package/dist/sharethroughBidAdapter.js +1 -1
  95. package/dist/shinezBidAdapter.js +1 -1
  96. package/dist/smaatoBidAdapter.js +1 -1
  97. package/dist/smartadserverBidAdapter.js +1 -1
  98. package/dist/smartxBidAdapter.js +1 -1
  99. package/dist/smilewantedBidAdapter.js +1 -1
  100. package/dist/sonobiBidAdapter.js +1 -1
  101. package/dist/sovrnAnalyticsAdapter.js +1 -1
  102. package/dist/sovrnBidAdapter.js +1 -1
  103. package/dist/sspBCBidAdapter.js +1 -1
  104. package/dist/sublimeBidAdapter.js +1 -1
  105. package/dist/synacormediaBidAdapter.js +1 -1
  106. package/dist/taboolaBidAdapter.js +1 -1
  107. package/dist/targetVideoBidAdapter.js +1 -1
  108. package/dist/teadsBidAdapter.js +1 -1
  109. package/dist/trionBidAdapter.js +1 -1
  110. package/dist/tripleliftBidAdapter.js +1 -1
  111. package/dist/ttdBidAdapter.js +1 -1
  112. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  113. package/dist/underdogmediaBidAdapter.js +1 -1
  114. package/dist/undertoneBidAdapter.js +1 -1
  115. package/dist/vidazooBidAdapter.js +1 -1
  116. package/dist/videobyteBidAdapter.js +1 -1
  117. package/dist/visxBidAdapter.js +1 -1
  118. package/dist/vuukleBidAdapter.js +1 -1
  119. package/dist/widespaceBidAdapter.js +1 -1
  120. package/dist/winrBidAdapter.js +1 -1
  121. package/dist/yahoosspBidAdapter.js +1 -1
  122. package/dist/yandexBidAdapter.js +1 -1
  123. package/dist/yieldmoBidAdapter.js +1 -1
  124. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  125. package/libraries/fpd/sua.js +98 -0
  126. package/modules/adfBidAdapter.js +1 -1
  127. package/modules/adkernelAdnBidAdapter.js +1 -0
  128. package/modules/adqueryIdSystem.js +8 -8
  129. package/modules/adxcgBidAdapter.js +1 -1
  130. package/modules/amxBidAdapter.js +1 -1
  131. package/modules/{andBeyondMediaBidAdapter.js → beyondmediaBidAdapter.js} +0 -0
  132. package/modules/{andBeyondMediaBidAdapter.md → beyondmediaBidAdapter.md} +1 -1
  133. package/modules/cleanioRtdProvider.js +3 -4
  134. package/modules/colossussspBidAdapter.js +2 -1
  135. package/modules/conversantAnalyticsAdapter.js +560 -0
  136. package/modules/conversantAnalyticsAdapter.md +47 -0
  137. package/modules/criteoBidAdapter.js +1 -1
  138. package/modules/debugging/bidInterceptor.js +2 -2
  139. package/modules/debugging/debugging.js +10 -2
  140. package/modules/dgkeywordRtdProvider.js +21 -3
  141. package/modules/dianomiBidAdapter.js +1 -1
  142. package/modules/enrichmentFpdModule.js +33 -14
  143. package/modules/finativeBidAdapter.js +1 -1
  144. package/modules/gridBidAdapter.js +187 -117
  145. package/modules/improvedigitalBidAdapter.js +2 -2
  146. package/modules/ixBidAdapter.js +94 -23
  147. package/modules/liveIntentIdSystem.js +39 -5
  148. package/modules/mediakeysBidAdapter.js +6 -1
  149. package/modules/mediakeysBidAdapter.md +50 -40
  150. package/modules/nativoBidAdapter.js +1 -1
  151. package/modules/prebidServerBidAdapter/index.js +44 -13
  152. package/modules/readpeakBidAdapter.js +1 -1
  153. package/modules/rubiconBidAdapter.js +2 -3
  154. package/modules/seedingAllianceBidAdapter.js +1 -1
  155. package/modules/sharethroughBidAdapter.js +1 -1
  156. package/modules/taboolaBidAdapter.js +1 -1
  157. package/modules/talkadsBidAdapter.js +1 -0
  158. package/modules/truereachBidAdapter.js +1 -0
  159. package/modules/ttdBidAdapter.js +1 -1
  160. package/modules/vuukleBidAdapter.js +34 -3
  161. package/modules/yahoosspBidAdapter.js +3 -1
  162. package/modules/yandexBidAdapter.js +31 -8
  163. package/package.json +2 -2
  164. package/src/adapterManager.js +2 -4
  165. package/src/cpmBucketManager.js +22 -3
  166. package/src/native.js +1 -5
  167. package/src/prebid.js +3 -3
  168. package/test/spec/cpmBucketManager_spec.js +239 -177
  169. package/test/spec/fpd/sua_spec.js +244 -0
  170. package/test/spec/modules/adfBidAdapter_spec.js +2 -3
  171. package/test/spec/modules/adqueryIdSystem_spec.js +0 -2
  172. package/test/spec/modules/adxcgBidAdapter_spec.js +2 -3
  173. package/test/spec/modules/amxBidAdapter_spec.js +3 -2
  174. package/test/spec/modules/{andBeyondMediaBidAdapter_spec.js → beyondmediaBidAdapter_spec.js} +1 -1
  175. package/test/spec/modules/colossussspBidAdapter_spec.js +4 -2
  176. package/test/spec/modules/conversantAnalyticsAdapter_spec.js +963 -0
  177. package/test/spec/modules/debugging_mod_spec.js +9 -0
  178. package/test/spec/modules/dgkeywordRtdProvider_spec.js +83 -1
  179. package/test/spec/modules/dianomiBidAdapter_spec.js +2 -3
  180. package/test/spec/modules/enrichmentFpdModule_spec.js +50 -7
  181. package/test/spec/modules/fpdModule_spec.js +9 -0
  182. package/test/spec/modules/gridBidAdapter_spec.js +87 -31
  183. package/test/spec/modules/ixBidAdapter_spec.js +221 -2
  184. package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +62 -8
  185. package/test/spec/modules/liveIntentIdSystem_spec.js +62 -8
  186. package/test/spec/modules/mediakeysBidAdapter_spec.js +20 -3
  187. package/test/spec/modules/nativoBidAdapter_spec.js +13 -2
  188. package/test/spec/modules/prebidServerBidAdapter_spec.js +159 -4
  189. package/test/spec/modules/seedtagBidAdapter_spec.js +15 -18
  190. package/test/spec/modules/sharethroughBidAdapter_spec.js +2 -1
  191. package/test/spec/modules/taboolaBidAdapter_spec.js +2 -2
  192. package/test/spec/modules/ttdBidAdapter_spec.js +3 -3
  193. package/test/spec/modules/vuukleBidAdapter_spec.js +87 -0
  194. package/test/spec/modules/yahoosspBidAdapter_spec.js +3 -1
  195. package/test/spec/modules/yandexBidAdapter_spec.js +8 -5
  196. package/test/spec/native_spec.js +5 -0
  197. package/test/spec/unit/pbjs_api_spec.js +44 -0
@@ -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
+ });