prebid.js 5.19.0 → 5.20.3

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 (67) hide show
  1. package/.circleci/config.yml +4 -5
  2. package/modules/adxcgBidAdapter.js +311 -359
  3. package/modules/airgridRtdProvider.js +1 -1
  4. package/modules/appnexusBidAdapter.js +9 -3
  5. package/modules/atsAnalyticsAdapter.js +67 -46
  6. package/modules/atsAnalyticsAdapter.md +1 -0
  7. package/modules/betweenBidAdapter.js +2 -1
  8. package/modules/browsiRtdProvider.js +106 -18
  9. package/modules/cleanioRtdProvider.js +192 -0
  10. package/modules/cleanioRtdProvider.md +59 -0
  11. package/modules/deltaprojectsBidAdapter.js +252 -0
  12. package/modules/deltaprojectsBidAdapter.md +32 -0
  13. package/modules/gridBidAdapter.js +1 -0
  14. package/modules/ipromBidAdapter.js +79 -0
  15. package/modules/ixBidAdapter.js +7 -1
  16. package/modules/jixieBidAdapter.js +8 -2
  17. package/modules/justpremiumBidAdapter.js +6 -1
  18. package/modules/kinessoIdSystem.js +1 -1
  19. package/modules/livewrappedAnalyticsAdapter.js +5 -0
  20. package/modules/multibid/index.js +3 -3
  21. package/modules/nativoBidAdapter.js +5 -1
  22. package/modules/openxBidAdapter.js +1 -1
  23. package/modules/operaadsBidAdapter.js +21 -1
  24. package/modules/otmBidAdapter.js +146 -0
  25. package/modules/otmBidAdapter.md +27 -26
  26. package/modules/outbrainBidAdapter.js +5 -0
  27. package/modules/playwireBidAdapter.md +61 -0
  28. package/modules/pubmaticBidAdapter.js +1 -1
  29. package/modules/rtdModule/index.js +2 -2
  30. package/modules/sonobiBidAdapter.js +7 -0
  31. package/modules/sortableBidAdapter.js +1 -0
  32. package/modules/teadsBidAdapter.js +3 -0
  33. package/modules/trustxBidAdapter.js +8 -6
  34. package/modules/ventesBidAdapter.js +370 -0
  35. package/modules/ventesBidAdapter.md +94 -0
  36. package/modules/yahoosspBidAdapter.js +6 -6
  37. package/package.json +1 -1
  38. package/src/auction.js +11 -11
  39. package/src/prebid.js +20 -4
  40. package/src/targeting.js +8 -0
  41. package/test/fixtures/fixtures.js +2 -1
  42. package/test/spec/modules/adxcgBidAdapter_spec.js +827 -571
  43. package/test/spec/modules/appnexusBidAdapter_spec.js +16 -1
  44. package/test/spec/modules/atsAnalyticsAdapter_spec.js +42 -9
  45. package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
  46. package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
  47. package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
  48. package/test/spec/modules/eplanningBidAdapter_spec.js +8 -8
  49. package/test/spec/modules/ipromBidAdapter_spec.js +195 -0
  50. package/test/spec/modules/ixBidAdapter_spec.js +3 -3
  51. package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
  52. package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
  53. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +23 -4
  54. package/test/spec/modules/multibid_spec.js +31 -31
  55. package/test/spec/modules/openxBidAdapter_spec.js +0 -26
  56. package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
  57. package/test/spec/modules/otmBidAdapter_spec.js +67 -0
  58. package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
  59. package/test/spec/modules/pubmaticBidAdapter_spec.js +40 -0
  60. package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
  61. package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
  62. package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
  63. package/test/spec/modules/trustxBidAdapter_spec.js +3 -3
  64. package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
  65. package/test/spec/unit/core/adapterManager_spec.js +7 -3
  66. package/test/spec/unit/core/targeting_spec.js +93 -0
  67. package/test/spec/unit/pbjs_api_spec.js +3 -1
@@ -1,653 +1,909 @@
1
- import {expect} from 'chai';
1
+ // jshint esversion: 6, es3: false, node: true
2
+ import {assert} from 'chai';
2
3
  import {spec} from 'modules/adxcgBidAdapter.js';
3
- import {deepClone, parseUrl} from 'src/utils.js';
4
- import * as utils from '../../../src/utils.js';
5
-
6
- describe('AdxcgAdapter', function () {
7
- let bidBanner = {
8
- bidder: 'adxcg',
9
- params: {
10
- adzoneid: '1'
11
- },
12
- adUnitCode: 'adunit-code',
13
- mediaTypes: {
14
- banner: {
15
- sizes: [
16
- [300, 250],
17
- [640, 360],
18
- [1, 1]
19
- ]
20
- }
21
- },
22
- bidId: '84ab500420319d',
23
- bidderRequestId: '7101db09af0db2',
24
- auctionId: '1d1a030790a475'
25
- };
26
-
27
- let bidVideo = {
28
- bidder: 'adxcg',
29
- params: {
30
- adzoneid: '20',
31
- video: {
32
- api: [2],
33
- maxduration: 30
34
- }
35
- },
36
- mediaTypes: {
37
- video: {
38
- context: 'instream',
39
- playerSize: [[640, 480]],
40
- protocols: [1, 2],
41
- mimes: ['video/mp4'],
42
- }
43
- },
44
- adUnitCode: 'adunit-code',
45
- bidId: '84ab500420319d',
46
- bidderRequestId: '7101db09af0db2',
47
- auctionId: '1d1a030790a475'
48
- };
49
-
50
- let bidNative = {
51
- bidder: 'adxcg',
52
- params: {
53
- adzoneid: '2379'
54
- },
55
- mediaTypes: {
56
- native: {
57
- image: {
58
- sendId: false,
59
- required: true,
60
- sizes: [80, 80]
61
- },
62
- title: {
63
- required: true,
64
- len: 75
65
- },
66
- body: {
67
- required: true,
68
- len: 200
69
- },
70
- sponsoredBy: {
71
- required: false,
72
- len: 20
73
- }
74
- }
75
- },
76
- adUnitCode: 'adunit-code',
77
- bidId: '84ab500420319d',
78
- bidderRequestId: '7101db09af0db2',
79
- auctionId: '1d1a030790a475'
80
- };
4
+ import {config} from 'src/config.js';
5
+ import {createEidsArray} from 'modules/userId/eids.js';
6
+ const utils = require('src/utils');
81
7
 
82
- describe('isBidRequestValid', function () {
83
- it('should return true when required params found bidNative', function () {
84
- expect(spec.isBidRequestValid(bidNative)).to.equal(true);
85
- });
8
+ describe('Adxcg adapter', function () {
9
+ let bids = [];
86
10
 
87
- it('should return true when required params found bidVideo', function () {
88
- expect(spec.isBidRequestValid(bidVideo)).to.equal(true);
89
- });
11
+ describe('isBidRequestValid', function () {
12
+ let bid = {
13
+ 'bidder': 'adxcg',
14
+ 'params': {
15
+ 'adzoneid': '19910113'
16
+ }
17
+ };
90
18
 
91
- it('should return true when required params found bidBanner', function () {
92
- expect(spec.isBidRequestValid(bidBanner)).to.equal(true);
93
- });
19
+ it('should return true when required params found', function () {
20
+ assert(spec.isBidRequestValid(bid));
94
21
 
95
- it('should return false when required params not found', function () {
96
- expect(spec.isBidRequestValid({})).to.be.false;
22
+ bid.params = {
23
+ adzoneid: 4332,
24
+ };
25
+ assert(spec.isBidRequestValid(bid));
97
26
  });
98
27
 
99
- it('should return false when required params are not passed', function () {
100
- let bid = Object.assign({}, bidBanner);
101
- delete bid.params;
28
+ it('should return false when required params are missing', function () {
102
29
  bid.params = {};
103
- expect(spec.isBidRequestValid(bid)).to.equal(false);
104
- });
30
+ assert.isFalse(spec.isBidRequestValid(bid));
105
31
 
106
- it('should return true when required video params not found', function () {
107
- const simpleVideo = JSON.parse(JSON.stringify(bidVideo));
108
- simpleVideo.params.adzoneid = 123;
109
- expect(spec.isBidRequestValid(simpleVideo)).to.be.false;
32
+ bid.params = {
33
+ mname: 'some-placement'
34
+ };
35
+ assert.isFalse(spec.isBidRequestValid(bid));
36
+
37
+ bid.params = {
38
+ inv: 1234
39
+ };
40
+ assert.isFalse(spec.isBidRequestValid(bid));
110
41
  });
111
42
  });
112
43
 
113
- describe('request function http', function () {
114
- it('creates a valid adxcg request url bidBanner', function () {
115
- let request = spec.buildRequests([bidBanner]);
116
- expect(request).to.exist;
117
- expect(request.method).to.equal('GET');
118
- let parsedRequestUrl = parseUrl(request.url);
119
- expect(parsedRequestUrl.hostname).to.equal('hbps.adxcg.net');
120
- expect(parsedRequestUrl.pathname).to.equal('/get/adi');
121
-
122
- let query = parsedRequestUrl.search;
123
- expect(query.renderformat).to.equal('javascript');
124
- expect(query.ver).to.equal('r20210330PB40');
125
- expect(query.source).to.equal('pbjs10');
126
- expect(query.pbjs).to.equal('$prebid.version$');
127
- expect(query.adzoneid).to.equal('1');
128
- expect(query.format).to.equal('300x250|640x360|1x1');
129
- expect(query.jsonp).to.be.undefined;
130
- expect(query.prebidBidIds).to.equal('84ab500420319d');
131
- expect(query.bidfloors).to.equal('0');
132
-
133
- expect(query).to.have.property('secure');
134
- expect(query).to.have.property('uw');
135
- expect(query).to.have.property('uh');
136
- expect(query).to.have.property('dpr');
137
- expect(query).to.have.property('bt');
138
- expect(query).to.have.property('cookies');
139
- expect(query).to.have.property('tz');
140
- expect(query).to.have.property('dt');
141
- expect(query).to.have.property('iob');
142
- expect(query).to.have.property('rndid');
143
- expect(query).to.have.property('ref');
144
- expect(query).to.have.property('url');
44
+ describe('buildRequests', function () {
45
+ beforeEach(function () {
46
+ config.resetConfig();
145
47
  });
48
+ it('should send request with correct structure', function () {
49
+ let validBidRequests = [{
50
+ bidId: 'bidId',
51
+ params: {
52
+ adzoneid: '19910113'
53
+ }
54
+ }];
55
+ let request = spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}});
146
56
 
147
- it('creates a valid adxcg request url bidVideo', function () {
148
- let request = spec.buildRequests([bidVideo]);
149
- expect(request).to.exist;
150
- expect(request.method).to.equal('GET');
151
- let parsedRequestUrl = parseUrl(request.url);
152
- expect(parsedRequestUrl.hostname).to.equal('hbps.adxcg.net');
153
- expect(parsedRequestUrl.pathname).to.equal('/get/adi');
154
-
155
- let query = parsedRequestUrl.search;
156
- // general part
157
- expect(query.renderformat).to.equal('javascript');
158
- expect(query.ver).to.equal('r20210330PB40');
159
- expect(query.source).to.equal('pbjs10');
160
- expect(query.pbjs).to.equal('$prebid.version$');
161
- expect(query.adzoneid).to.equal('20');
162
- expect(query.format).to.equal('640x480');
163
- expect(query.jsonp).to.be.undefined;
164
- expect(query.prebidBidIds).to.equal('84ab500420319d');
165
- expect(query.bidfloors).to.equal('0');
166
-
167
- expect(query).to.have.property('secure');
168
- expect(query).to.have.property('uw');
169
- expect(query).to.have.property('uh');
170
- expect(query).to.have.property('dpr');
171
- expect(query).to.have.property('bt');
172
- expect(query).to.have.property('cookies');
173
- expect(query).to.have.property('tz');
174
- expect(query).to.have.property('dt');
175
- expect(query).to.have.property('iob');
176
- expect(query).to.have.property('rndid');
177
- expect(query).to.have.property('ref');
178
- expect(query).to.have.property('url');
179
-
180
- // video specific part
181
- expect(query['video.maxduration.0']).to.equal('30');
182
- expect(query['video.mimes.0']).to.equal('video/mp4');
183
- expect(query['video.context.0']).to.equal('instream');
57
+ assert.equal(request.method, 'POST');
58
+ assert.equal(request.url, 'https://pbc.adxcg.net/rtb/ortb/pbc?adExchangeId=1');
59
+ assert.deepEqual(request.options, {contentType: 'application/json'});
60
+ assert.ok(request.data);
184
61
  });
185
62
 
186
- it('creates a valid adxcg request url bidNative', function () {
187
- let request = spec.buildRequests([bidNative]);
188
- expect(request).to.exist;
189
- expect(request.method).to.equal('GET');
190
- let parsedRequestUrl = parseUrl(request.url);
191
- expect(parsedRequestUrl.hostname).to.equal('hbps.adxcg.net');
192
- expect(parsedRequestUrl.pathname).to.equal('/get/adi');
193
-
194
- let query = parsedRequestUrl.search;
195
- expect(query.renderformat).to.equal('javascript');
196
- expect(query.ver).to.equal('r20210330PB40');
197
- expect(query.source).to.equal('pbjs10');
198
- expect(query.pbjs).to.equal('$prebid.version$');
199
- expect(query.adzoneid).to.equal('2379');
200
- expect(query.format).to.equal('0x0');
201
- expect(query.jsonp).to.be.undefined;
202
- expect(query.prebidBidIds).to.equal('84ab500420319d');
203
- expect(query.bidfloors).to.equal('0');
204
-
205
- expect(query).to.have.property('secure');
206
- expect(query).to.have.property('uw');
207
- expect(query).to.have.property('uh');
208
- expect(query).to.have.property('dpr');
209
- expect(query).to.have.property('bt');
210
- expect(query).to.have.property('cookies');
211
- expect(query).to.have.property('tz');
212
- expect(query).to.have.property('dt');
213
- expect(query).to.have.property('iob');
214
- expect(query).to.have.property('rndid');
215
- expect(query).to.have.property('ref');
216
- expect(query).to.have.property('url');
217
- });
218
- });
63
+ describe('user privacy', function () {
64
+ it('should send GDPR Consent data to exchange if gdprApplies', function () {
65
+ let validBidRequests = [{bidId: 'bidId', params: {test: 1}}];
66
+ let bidderRequest = {
67
+ gdprConsent: {gdprApplies: true, consentString: 'consentDataString'},
68
+ refererInfo: {referer: 'page'}
69
+ };
70
+ let request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data);
71
+
72
+ assert.equal(request.user.ext.consent, bidderRequest.gdprConsent.consentString);
73
+ assert.equal(request.regs.ext.gdpr, bidderRequest.gdprConsent.gdprApplies);
74
+ assert.equal(typeof request.regs.ext.gdpr, 'number');
75
+ });
219
76
 
220
- describe('gdpr compliance', function () {
221
- it('should send GDPR Consent data if gdprApplies', function () {
222
- let request = spec.buildRequests([bidBanner], {
223
- gdprConsent: {
224
- gdprApplies: true,
225
- consentString: 'consentDataString'
226
- }
77
+ it('should send gdpr as number', function () {
78
+ let validBidRequests = [{bidId: 'bidId', params: {test: 1}}];
79
+ let bidderRequest = {
80
+ gdprConsent: {gdprApplies: true, consentString: 'consentDataString'},
81
+ refererInfo: {referer: 'page'}
82
+ };
83
+ let request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data);
84
+
85
+ assert.equal(typeof request.regs.ext.gdpr, 'number');
86
+ assert.equal(request.regs.ext.gdpr, 1);
227
87
  });
228
- let parsedRequestUrl = parseUrl(request.url);
229
- let query = parsedRequestUrl.search;
230
88
 
231
- expect(query.gdpr).to.equal('1');
232
- expect(query.gdpr_consent).to.equal('consentDataString');
233
- });
89
+ it('should send CCPA Consent data to exchange', function () {
90
+ let validBidRequests = [{bidId: 'bidId', params: {test: 1}}];
91
+ let bidderRequest = {uspConsent: '1YA-', refererInfo: {referer: 'page'}};
92
+ let request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data);
234
93
 
235
- it('should not send GDPR Consent data if gdprApplies is false or undefined', function () {
236
- let request = spec.buildRequests([bidBanner], {
237
- gdprConsent: {
238
- gdprApplies: false,
239
- consentString: 'consentDataString'
240
- }
94
+ assert.equal(request.regs.ext.us_privacy, '1YA-');
95
+
96
+ bidderRequest = {
97
+ uspConsent: '1YA-',
98
+ gdprConsent: {gdprApplies: true, consentString: 'consentDataString'},
99
+ refererInfo: {referer: 'page'}
100
+ };
101
+ request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data);
102
+
103
+ assert.equal(request.regs.ext.us_privacy, '1YA-');
104
+ assert.equal(request.user.ext.consent, 'consentDataString');
105
+ assert.equal(request.regs.ext.gdpr, 1);
241
106
  });
242
- let parsedRequestUrl = parseUrl(request.url);
243
- let query = parsedRequestUrl.search;
244
107
 
245
- expect(query.gdpr).to.be.undefined;
246
- expect(query.gdpr_consent).to.be.undefined;
108
+ it('should not send GDPR Consent data to adxcg if gdprApplies is undefined', function () {
109
+ let validBidRequests = [{
110
+ bidId: 'bidId',
111
+ params: {siteId: 'siteId'}
112
+ }];
113
+ let bidderRequest = {
114
+ gdprConsent: {gdprApplies: false, consentString: 'consentDataString'},
115
+ refererInfo: {referer: 'page'}
116
+ };
117
+ let request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data);
118
+
119
+ assert.equal(request.user.ext.consent, 'consentDataString');
120
+ assert.equal(request.regs.ext.gdpr, 0);
121
+
122
+ bidderRequest = {gdprConsent: {consentString: 'consentDataString'}, refererInfo: {referer: 'page'}};
123
+ request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data);
124
+
125
+ assert.equal(request.user, undefined);
126
+ assert.equal(request.regs, undefined);
127
+ });
128
+ it('should send default GDPR Consent data to exchange', function () {
129
+ let validBidRequests = [{
130
+ bidId: 'bidId',
131
+ params: {siteId: 'siteId'}
132
+ }];
133
+ let request = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data);
134
+
135
+ assert.equal(request.user, undefined);
136
+ assert.equal(request.regs, undefined);
137
+ });
247
138
  });
248
- });
249
139
 
250
- describe('userid pubcid should be passed to querystring', function () {
251
- let bidderRequests = {};
252
- let bid = deepClone([bidBanner]);
253
- bid[0].userId = {pubcid: 'pubcidabcd'};
140
+ it('should add test and is_debug to request, if test is set in parameters', function () {
141
+ let validBidRequests = [{
142
+ bidId: 'bidId',
143
+ params: {test: 1}
144
+ }];
145
+ let request = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data);
254
146
 
255
- it('should send pubcid if available', function () {
256
- let request = spec.buildRequests(bid, bidderRequests);
257
- let parsedRequestUrl = parseUrl(request.url);
258
- let query = parsedRequestUrl.search;
259
- expect(query.pubcid).to.equal('pubcidabcd');
147
+ assert.ok(request.is_debug);
148
+ assert.equal(request.test, 1);
260
149
  });
261
- });
262
150
 
263
- describe('userid tdid should be passed to querystring', function () {
264
- let bid = deepClone([bidBanner]);
265
- let bidderRequests = {};
151
+ it('should have default request structure', function () {
152
+ let keys = 'site,geo,device,source,ext,imp'.split(',');
153
+ let validBidRequests = [{
154
+ bidId: 'bidId',
155
+ params: {siteId: 'siteId'}
156
+ }];
157
+ let request = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data);
158
+ let data = Object.keys(request);
159
+
160
+ assert.deepEqual(keys, data);
161
+ });
266
162
 
267
- bid[0].userId = {tdid: 'tdidabcd'};
163
+ it('should set request keys correct values', function () {
164
+ let validBidRequests = [{
165
+ bidId: 'bidId',
166
+ params: {siteId: 'siteId'},
167
+ transactionId: 'transactionId'
168
+ }];
169
+ let request = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data);
268
170
 
269
- it('should send pubcid if available', function () {
270
- let request = spec.buildRequests(bid, bidderRequests);
271
- let parsedRequestUrl = parseUrl(request.url);
272
- let query = parsedRequestUrl.search;
273
- expect(query.tdid).to.equal('tdidabcd');
171
+ assert.equal(request.source.tid, validBidRequests[0].transactionId);
172
+ assert.equal(request.source.fd, 1);
274
173
  });
275
- });
276
174
 
277
- describe('userid id5id should be passed to querystring', function () {
278
- let bid = deepClone([bidBanner]);
279
- let bidderRequests = {};
175
+ it('should send info about device', function () {
176
+ config.setConfig({
177
+ device: {w: 100, h: 100}
178
+ });
179
+ let validBidRequests = [{
180
+ bidId: 'bidId',
181
+ params: {adzoneid: '1000'}
182
+ }];
183
+ let request = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data);
184
+
185
+ assert.equal(request.device.ua, navigator.userAgent);
186
+ assert.equal(request.device.w, 100);
187
+ assert.equal(request.device.h, 100);
188
+ });
280
189
 
281
- bid[0].userId = {id5id: {uid: 'id5idsample'}};
190
+ it('should send app info', function () {
191
+ config.setConfig({
192
+ app: {id: 'appid'},
193
+ ortb2: {app: {name: 'appname'}}
194
+ });
195
+ let validBidRequests = [{
196
+ bidId: 'bidId',
197
+ params: {adzoneid: '1000'}
198
+ }];
199
+ let request = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data);
200
+
201
+ assert.equal(request.app.id, 'appid');
202
+ assert.equal(request.app.name, 'appname');
203
+ assert.equal(request.site, undefined);
204
+ });
282
205
 
283
- it('should send pubcid if available', function () {
284
- let request = spec.buildRequests(bid, bidderRequests);
285
- let parsedRequestUrl = parseUrl(request.url);
286
- let query = parsedRequestUrl.search;
287
- expect(query.id5id).to.equal('id5idsample');
206
+ it('should send info about the site', function () {
207
+ config.setConfig({
208
+ site: {
209
+ id: '123123',
210
+ publisher: {
211
+ domain: 'publisher.domain.com'
212
+ }
213
+ },
214
+ ortb2: {
215
+ site: {
216
+ publisher: {
217
+ id: 4441,
218
+ name: 'publishers name'
219
+ }
220
+ }
221
+ }
222
+ });
223
+ let validBidRequests = [{
224
+ bidId: 'bidId',
225
+ params: {adzoneid: '1000'}
226
+ }];
227
+ let refererInfo = {referer: 'page'};
228
+ let request = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo}).data);
229
+
230
+ let expected = {
231
+ id: '123123',
232
+ publisher: {
233
+ domain: 'publisher.domain.com',
234
+ id: 4441,
235
+ name: 'publishers name'
236
+ },
237
+ page: 'page',
238
+ domain: 'localhost'
239
+ };
240
+
241
+ assert.deepEqual(request.site.id, expected.id);
242
+ assert.deepEqual(request.site.publisher, expected.publisher);
243
+ assert.deepEqual(request.site.page, expected.page);
244
+ // assert.deepEqual(request.site.domain, expected.site.domain); // disabled for browser specific problem (IE11)
245
+ // in browserstack IE 11 we get empty "" request.site.domain, while in gulp test we get "localhost"
246
+ // all other browserstack enabled browsers work without problem
288
247
  });
289
- });
290
248
 
291
- describe('userid idl_env should be passed to querystring', function () {
292
- let bid = deepClone([bidBanner]);
293
- let bidderRequests = {};
249
+ it('should pass extended ids', function () {
250
+ let validBidRequests = [{
251
+ bidId: 'bidId',
252
+ params: {},
253
+ userIdAsEids: createEidsArray({
254
+ tdid: 'TTD_ID_FROM_USER_ID_MODULE',
255
+ pubcid: 'pubCommonId_FROM_USER_ID_MODULE'
256
+ })
257
+ }];
258
+
259
+ let request = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data);
260
+ assert.deepEqual(request.user.ext.eids, [
261
+ {source: 'adserver.org', uids: [{id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: {rtiPartner: 'TDID'}}]},
262
+ {source: 'pubcid.org', uids: [{id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1}]}
263
+ ]);
264
+ });
294
265
 
295
- bid[0].userId = {idl_env: 'idl_envsample'};
266
+ it('should send currency if defined', function () {
267
+ config.setConfig({currency: {adServerCurrency: 'EUR'}});
268
+ let validBidRequests = [{params: {}}];
269
+ let refererInfo = {referer: 'page'};
270
+ let request = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo}).data);
296
271
 
297
- it('should send pubcid if available', function () {
298
- let request = spec.buildRequests(bid, bidderRequests);
299
- let parsedRequestUrl = parseUrl(request.url);
300
- let query = parsedRequestUrl.search;
301
- expect(query.idl_env).to.equal('idl_envsample');
272
+ assert.deepEqual(request.cur, ['EUR']);
302
273
  });
303
- });
304
274
 
305
- describe('response handler', function () {
306
- let BIDDER_REQUEST = {
307
- bidder: 'adxcg',
308
- params: {
309
- adzoneid: '1'
310
- },
311
- adUnitCode: 'adunit-code',
312
- mediaTypes: {
313
- banner: {
314
- sizes: [
315
- [300, 250],
316
- [640, 360],
317
- [1, 1]
318
- ]
275
+ it('should pass supply chain object', function () {
276
+ let validBidRequests = [{
277
+ bidId: 'bidId',
278
+ params: {},
279
+ schain: {
280
+ validation: 'strict',
281
+ config: {
282
+ ver: '1.0'
283
+ }
319
284
  }
320
- },
321
- bidId: '84ab500420319d',
322
- bidderRequestId: '7101db09af0db2',
323
- auctionId: '1d1a030790a475'
324
- };
285
+ }];
325
286
 
326
- let BANNER_RESPONSE = {
327
- body: {
328
- id: 'auctionid',
329
- bidid: '84ab500420319d',
330
- seatbid: [{
331
- bid: [
332
- {
333
- impid: '84ab500420319d',
334
- price: 0.45,
335
- crid: '42',
336
- adm: '<!-- adContent -->',
337
- w: 300,
338
- h: 250,
339
- adomain: ['adomain.com'],
340
- cat: ['IAB1-4', 'IAB8-16', 'IAB25-5'],
341
- ext: {
342
- crType: 'banner',
343
- advertiser_id: '777',
344
- advertiser_name: 'advertiser',
345
- agency_name: 'agency'
346
- }
287
+ let request = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data);
288
+ assert.deepEqual(request.source.ext.schain, {
289
+ validation: 'strict',
290
+ config: {
291
+ ver: '1.0'
292
+ }
293
+ });
294
+ });
295
+
296
+ describe('bids', function () {
297
+ it('should add more than one bid to the request', function () {
298
+ let validBidRequests = [{
299
+ bidId: 'bidId',
300
+ params: {siteId: 'siteId'}
301
+ }, {
302
+ bidId: 'bidId2',
303
+ params: {siteId: 'siteId'}
304
+ }];
305
+ let request = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data);
306
+
307
+ assert.equal(request.imp.length, 2);
308
+ });
309
+ it('should add incrementing values of id', function () {
310
+ let validBidRequests = [{
311
+ bidId: 'bidId',
312
+ params: {adzoneid: '1000'},
313
+ mediaTypes: {video: {}}
314
+ }, {
315
+ bidId: 'bidId2',
316
+ params: {adzoneid: '1000'},
317
+ mediaTypes: {video: {}}
318
+ }, {
319
+ bidId: 'bidId3',
320
+ params: {adzoneid: '1000'},
321
+ mediaTypes: {video: {}}
322
+ }];
323
+ let imps = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data).imp;
324
+
325
+ for (let i = 0; i < 3; i++) {
326
+ assert.equal(imps[i].id, i + 1);
327
+ }
328
+ });
329
+
330
+ it('should add adzoneid', function () {
331
+ let validBidRequests = [{bidId: 'bidId', params: {adzoneid: 1000}, mediaTypes: {video: {}}},
332
+ {bidId: 'bidId2', params: {adzoneid: 1001}, mediaTypes: {video: {}}},
333
+ {bidId: 'bidId3', params: {adzoneid: 1002}, mediaTypes: {video: {}}}];
334
+ let imps = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data).imp;
335
+ for (let i = 0; i < 3; i++) {
336
+ assert.equal(imps[i].tagid, validBidRequests[i].params.adzoneid);
337
+ }
338
+ });
339
+
340
+ describe('price floors', function () {
341
+ it('should not add if floors module not configured', function () {
342
+ const validBidRequests = [{bidId: 'bidId', params: {adzoneid: 1000}, mediaTypes: {video: {}}}];
343
+ let imp = getRequestImps(validBidRequests)[0];
344
+
345
+ assert.equal(imp.bidfloor, undefined);
346
+ assert.equal(imp.bidfloorcur, undefined);
347
+ });
348
+
349
+ it('should not add if floor price not defined', function () {
350
+ const validBidRequests = [getBidWithFloor()];
351
+ let imp = getRequestImps(validBidRequests)[0];
352
+
353
+ assert.equal(imp.bidfloor, undefined);
354
+ assert.equal(imp.bidfloorcur, 'USD');
355
+ });
356
+
357
+ it('should request floor price in adserver currency', function () {
358
+ config.setConfig({currency: {adServerCurrency: 'DKK'}});
359
+ const validBidRequests = [getBidWithFloor()];
360
+ let imp = getRequestImps(validBidRequests)[0];
361
+
362
+ assert.equal(imp.bidfloor, undefined);
363
+ assert.equal(imp.bidfloorcur, 'DKK');
364
+ });
365
+
366
+ it('should add correct floor values', function () {
367
+ const expectedFloors = [1, 1.3, 0.5];
368
+ const validBidRequests = expectedFloors.map(getBidWithFloor);
369
+ let imps = getRequestImps(validBidRequests);
370
+
371
+ expectedFloors.forEach((floor, index) => {
372
+ assert.equal(imps[index].bidfloor, floor);
373
+ assert.equal(imps[index].bidfloorcur, 'USD');
374
+ });
375
+ });
376
+
377
+ function getBidWithFloor(floor) {
378
+ return {
379
+ params: {adzoneid: 1},
380
+ mediaTypes: {video: {}},
381
+ getFloor: ({currency}) => {
382
+ return {
383
+ currency: currency,
384
+ floor
385
+ };
347
386
  }
348
- ]
349
- }],
350
- cur: 'USD'
351
- },
352
- headers: {someheader: 'fakedata'}
353
- };
387
+ };
388
+ }
389
+ });
354
390
 
355
- let BANNER_RESPONSE_WITHDEALID = {
356
- body: {
357
- id: 'auctionid',
358
- bidid: '84ab500420319d',
359
- seatbid: [{
360
- bid: [
361
- {
362
- impid: '84ab500420319d',
363
- price: 0.45,
364
- crid: '42',
365
- dealid: '7722',
366
- adm: '<!-- adContent -->',
367
- w: 300,
368
- h: 250,
369
- adomain: ['adomain.com'],
370
- ext: {
371
- crType: 'banner'
372
- }
391
+ describe('multiple media types', function () {
392
+ it('should use all configured media types for bidding', function () {
393
+ let validBidRequests = [{
394
+ bidId: 'bidId',
395
+ params: {adzoneid: 1000},
396
+ mediaTypes: {
397
+ banner: {
398
+ sizes: [[100, 100], [200, 300]]
399
+ },
400
+ video: {}
373
401
  }
374
- ]
375
- }],
376
- cur: 'USD'
377
- }
378
- };
402
+ }, {
403
+ bidId: 'bidId1',
404
+ params: {adzoneid: 1000},
405
+ mediaTypes: {
406
+ video: {},
407
+ native: {}
408
+ }
409
+ }, {
410
+ bidId: 'bidId2',
411
+ params: {adzoneid: 1000},
412
+ nativeParams: {
413
+ title: {required: true, len: 140}
414
+ },
415
+ mediaTypes: {
416
+ banner: {
417
+ sizes: [[100, 100], [200, 300]]
418
+ },
419
+ native: {},
420
+ video: {}
421
+ }
422
+ }];
423
+ let [first, second, third] = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data).imp;
379
424
 
380
- let VIDEO_RESPONSE = {
381
- body: {
382
- id: 'auctionid',
383
- bidid: '84ab500420319d',
384
- seatbid: [{
385
- bid: [
386
- {
387
- impid: '84ab500420319d',
388
- price: 0.45,
389
- crid: '42',
390
- nurl: 'vastContentUrl',
391
- adomain: ['adomain.com'],
392
- w: 640,
393
- h: 360,
394
- ext: {
395
- crType: 'video'
425
+ assert.ok(first.banner);
426
+ assert.ok(first.video);
427
+ assert.equal(first.native, undefined);
428
+
429
+ assert.ok(second.video);
430
+ assert.equal(second.banner, undefined);
431
+ assert.equal(second.native, undefined);
432
+
433
+ assert.ok(third.native);
434
+ assert.ok(third.video);
435
+ assert.ok(third.banner);
436
+ });
437
+ });
438
+
439
+ describe('banner', function () {
440
+ it('should convert sizes to openrtb format', function () {
441
+ let validBidRequests = [{
442
+ bidId: 'bidId',
443
+ params: {adzoneid: 1000},
444
+ mediaTypes: {
445
+ banner: {
446
+ sizes: [[100, 100], [200, 300]]
396
447
  }
397
448
  }
398
- ]
399
- }],
400
- cur: 'USD'
401
- },
402
- headers: {someheader: 'fakedata'}
403
- };
404
-
405
- let NATIVE_RESPONSEob = {
406
- assets: [
407
- {
408
- id: 1,
409
- required: 0,
410
- title: {
411
- text: 'titleContent'
412
- }
413
- },
414
- {
415
- id: 2,
416
- required: 0,
417
- img: {
418
- url: 'imageContent',
419
- w: 600,
420
- h: 600
421
- }
422
- },
423
- {
424
- id: 3,
425
- required: 0,
426
- data: {
427
- label: 'DESC',
428
- value: 'descriptionContent'
429
- }
430
- },
431
- {
432
- id: 0,
433
- required: 0,
434
- data: {
435
- label: 'SPONSORED',
436
- value: 'sponsoredByContent'
437
- }
438
- },
439
- {
440
- id: 5,
441
- required: 0,
442
- icon: {
443
- url: 'iconContent',
444
- w: 400,
445
- h: 400
446
- }
447
- }
448
- ],
449
- link: {
450
- url: 'linkContent'
451
- },
452
- imptrackers: ['impressionTracker1', 'impressionTracker2']
453
- }
449
+ }];
450
+ let {banner} = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data).imp[0];
451
+ assert.deepEqual(banner, {
452
+ format: [{w: 100, h: 100}, {w: 200, h: 300}]
453
+ });
454
+ });
455
+ });
454
456
 
455
- let NATIVE_RESPONSE = {
456
- body: {
457
- id: 'auctionid',
458
- bidid: '84ab500420319d',
459
- seatbid: [{
460
- bid: [
461
- {
462
- impid: '84ab500420319d',
463
- price: 0.45,
464
- crid: '42',
465
- w: 0,
466
- h: 0,
467
- adm: JSON.stringify(NATIVE_RESPONSEob),
468
- adomain: ['adomain.com'],
469
- ext: {
470
- crType: 'native'
457
+ describe('video', function () {
458
+ it('should pass video mediatype config', function () {
459
+ let validBidRequests = [{
460
+ bidId: 'bidId',
461
+ params: {adzoneid: 1000},
462
+ mediaTypes: {
463
+ video: {
464
+ playerSize: [640, 480],
465
+ context: 'outstream',
466
+ mimes: ['video/mp4']
471
467
  }
472
468
  }
473
- ]
474
- }],
475
- cur: 'USD'
476
- },
477
- headers: {someheader: 'fakedata'}
478
- };
469
+ }];
470
+ let {video} = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data).imp[0];
471
+ assert.deepEqual(video, {
472
+ playerSize: [640, 480],
473
+ context: 'outstream',
474
+ mimes: ['video/mp4']
475
+ });
476
+ });
477
+ });
479
478
 
480
- it('handles regular responses', function () {
481
- expect(BANNER_RESPONSE).to.exist;
482
- expect(BANNER_RESPONSE.body).to.exist;
483
- expect(BANNER_RESPONSE.body.id).to.exist;
484
- expect(BANNER_RESPONSE.body.seatbid[0]).to.exist;
485
- let result = spec.interpretResponse(BANNER_RESPONSE, BIDDER_REQUEST);
486
-
487
- expect(result).to.have.lengthOf(1);
488
-
489
- expect(result[0]).to.exist;
490
- expect(result[0].width).to.equal(300);
491
- expect(result[0].height).to.equal(250);
492
- expect(result[0].creativeId).to.equal(42);
493
- expect(result[0].cpm).to.be.within(0.45, 0.46);
494
- expect(result[0].ad).to.equal('<!-- adContent -->');
495
- expect(result[0].currency).to.equal('USD');
496
- expect(result[0].netRevenue).to.equal(true);
497
- expect(result[0].ttl).to.equal(300);
498
- expect(result[0].dealId).to.not.exist;
499
- expect(result[0].meta.advertiserDomains[0]).to.equal('adomain.com');
500
- expect(result[0].meta.advertiserId).to.be.eql('777');
501
- expect(result[0].meta.advertiserName).to.be.eql('advertiser');
502
- expect(result[0].meta.agencyName).to.be.eql('agency');
503
- expect(result[0].meta.advertiserDomains).to.be.eql(['adomain.com']);
504
- expect(result[0].meta.secondaryCatIds).to.be.eql(['IAB1-4', 'IAB8-16', 'IAB25-5']);
479
+ describe('native', function () {
480
+ describe('assets', function () {
481
+ it('should set correct asset id', function () {
482
+ let validBidRequests = [{
483
+ bidId: 'bidId',
484
+ params: {adzoneid: 1000},
485
+ nativeParams: {
486
+ title: {required: true, len: 140},
487
+ image: {required: false, wmin: 836, hmin: 627, w: 325, h: 300, mimes: ['image/jpg', 'image/gif']},
488
+ body: {len: 140}
489
+ }
490
+ }];
491
+ let nativeRequest = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data).imp[0].native.request;
492
+ let assets = JSON.parse(nativeRequest).assets;
493
+
494
+ assert.equal(assets[0].id, 0);
495
+ assert.equal(assets[1].id, 3);
496
+ assert.equal(assets[2].id, 4);
497
+ });
498
+ it('should add required key if it is necessary', function () {
499
+ let validBidRequests = [{
500
+ bidId: 'bidId',
501
+ params: {adzoneid: 1000},
502
+ nativeParams: {
503
+ title: {required: true, len: 140},
504
+ image: {required: false, wmin: 836, hmin: 627, w: 325, h: 300, mimes: ['image/jpg', 'image/gif']},
505
+ body: {len: 140},
506
+ sponsoredBy: {required: true, len: 140}
507
+ }
508
+ }];
509
+
510
+ let nativeRequest = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data).imp[0].native.request;
511
+ let assets = JSON.parse(nativeRequest).assets;
512
+
513
+ assert.equal(assets[0].required, 1);
514
+ assert.ok(!assets[1].required);
515
+ assert.ok(!assets[2].required);
516
+ assert.equal(assets[3].required, 1);
517
+ });
518
+
519
+ it('should map img and data assets', function () {
520
+ let validBidRequests = [{
521
+ bidId: 'bidId',
522
+ params: {adzoneid: 1000},
523
+ nativeParams: {
524
+ title: {required: true, len: 140},
525
+ image: {required: true, sizes: [150, 50]},
526
+ icon: {required: false, sizes: [50, 50]},
527
+ body: {required: false, len: 140},
528
+ sponsoredBy: {required: true},
529
+ cta: {required: false},
530
+ clickUrl: {required: false}
531
+ }
532
+ }];
533
+
534
+ let nativeRequest = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data).imp[0].native.request;
535
+ let assets = JSON.parse(nativeRequest).assets;
536
+ assert.ok(assets[0].title);
537
+ assert.equal(assets[0].title.len, 140);
538
+ assert.deepEqual(assets[1].img, {type: 3, w: 150, h: 50});
539
+ assert.deepEqual(assets[2].img, {type: 1, w: 50, h: 50});
540
+ assert.deepEqual(assets[3].data, {type: 2, len: 140});
541
+ assert.deepEqual(assets[4].data, {type: 1});
542
+ assert.deepEqual(assets[5].data, {type: 12});
543
+ assert.ok(!assets[6]);
544
+ });
545
+
546
+ describe('icon/image sizing', function () {
547
+ it('should flatten sizes and utilise first pair', function () {
548
+ const validBidRequests = [{
549
+ bidId: 'bidId',
550
+ params: {adzoneid: 1000},
551
+ nativeParams: {
552
+ image: {
553
+ sizes: [[200, 300], [100, 200]]
554
+ },
555
+ }
556
+ }];
557
+
558
+ let nativeRequest = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data).imp[0].native.request;
559
+ let assets = JSON.parse(nativeRequest).assets;
560
+ assert.ok(assets[0].img);
561
+ assert.equal(assets[0].img.w, 200);
562
+ assert.equal(assets[0].img.h, 300);
563
+ });
564
+ });
565
+
566
+ it('should utilise aspect_ratios', function () {
567
+ const validBidRequests = [{
568
+ bidId: 'bidId',
569
+ params: {adzoneid: 1000},
570
+ nativeParams: {
571
+ image: {
572
+ aspect_ratios: [{
573
+ min_width: 100,
574
+ ratio_height: 3,
575
+ ratio_width: 1
576
+ }]
577
+ },
578
+ icon: {
579
+ aspect_ratios: [{
580
+ min_width: 10,
581
+ ratio_height: 5,
582
+ ratio_width: 2
583
+ }]
584
+ }
585
+ }
586
+ }];
587
+
588
+ let nativeRequest = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data).imp[0].native.request;
589
+ let assets = JSON.parse(nativeRequest).assets;
590
+ assert.ok(assets[0].img);
591
+ assert.equal(assets[0].img.wmin, 100);
592
+ assert.equal(assets[0].img.hmin, 300);
593
+
594
+ assert.ok(assets[1].img);
595
+ assert.equal(assets[1].img.wmin, 10);
596
+ assert.equal(assets[1].img.hmin, 25);
597
+ });
598
+
599
+ it('should not throw error if aspect_ratios config is not defined', function () {
600
+ const validBidRequests = [{
601
+ bidId: 'bidId',
602
+ params: {adzoneid: 1000},
603
+ nativeParams: {
604
+ image: {
605
+ aspect_ratios: []
606
+ },
607
+ icon: {
608
+ aspect_ratios: []
609
+ }
610
+ }
611
+ }];
612
+
613
+ assert.doesNotThrow(() => spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}));
614
+ });
615
+ });
616
+
617
+ it('should expect any dimensions if min_width not passed', function () {
618
+ const validBidRequests = [{
619
+ bidId: 'bidId',
620
+ params: {adzoneid: 1000},
621
+ nativeParams: {
622
+ image: {
623
+ aspect_ratios: [{
624
+ ratio_height: 3,
625
+ ratio_width: 1
626
+ }]
627
+ }
628
+ }
629
+ }];
630
+
631
+ let nativeRequest = JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data).imp[0].native.request;
632
+ let assets = JSON.parse(nativeRequest).assets;
633
+ assert.ok(assets[0].img);
634
+ assert.equal(assets[0].img.wmin, 0);
635
+ assert.equal(assets[0].img.hmin, 0);
636
+ assert.ok(!assets[1]);
637
+ });
638
+ });
505
639
  });
506
640
 
507
- it('handles regular responses with dealid', function () {
508
- let result = spec.interpretResponse(BANNER_RESPONSE_WITHDEALID);
641
+ function getRequestImps(validBidRequests) {
642
+ return JSON.parse(spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}).data).imp;
643
+ }
644
+ });
509
645
 
510
- expect(result).to.have.lengthOf(1);
646
+ describe('interpretResponse', function () {
647
+ it('should return if no body in response', function () {
648
+ let serverResponse = {};
649
+ let bidRequest = {};
511
650
 
512
- expect(result[0].width).to.equal(300);
513
- expect(result[0].height).to.equal(250);
514
- expect(result[0].creativeId).to.equal(42);
515
- // expect(result[0].cpm).to.equal(0.45);
516
- expect(result[0].cpm).to.be.within(0.45, 0.46);
517
- expect(result[0].ad).to.equal('<!-- adContent -->');
518
- expect(result[0].currency).to.equal('USD');
519
- expect(result[0].netRevenue).to.equal(true);
520
- expect(result[0].ttl).to.equal(300);
651
+ assert.ok(!spec.interpretResponse(serverResponse, bidRequest));
521
652
  });
653
+ it('should return more than one bids', function () {
654
+ let serverResponse = {
655
+ body: {
656
+ seatbid: [{
657
+ bid: [{
658
+ impid: '1',
659
+ native: {ver: '1.1', link: {url: 'link'}, assets: [{id: 1, title: {text: 'Asset title text'}}]}
660
+ }]
661
+ }, {
662
+ bid: [{
663
+ impid: '2',
664
+ native: {ver: '1.1', link: {url: 'link'}, assets: [{id: 1, data: {value: 'Asset title text'}}]}
665
+ }]
666
+ }]
667
+ }
668
+ };
669
+ let bidRequest = {
670
+ data: {},
671
+ bids: [
672
+ {
673
+ bidId: 'bidId1',
674
+ params: {adzoneid: 1000},
675
+ nativeParams: {
676
+ title: {required: true, len: 140},
677
+ image: {required: false, wmin: 836, hmin: 627, w: 325, h: 300, mimes: ['image/jpg', 'image/gif']},
678
+ body: {len: 140}
679
+ }
680
+ },
681
+ {
682
+ bidId: 'bidId2',
683
+ params: {adzoneid: 1000},
684
+ nativeParams: {
685
+ title: {required: true, len: 140},
686
+ image: {required: false, wmin: 836, hmin: 627, w: 325, h: 300, mimes: ['image/jpg', 'image/gif']},
687
+ body: {len: 140}
688
+ }
689
+ }
690
+ ]
691
+ };
522
692
 
523
- it('handles video responses', function () {
524
- let result = spec.interpretResponse(VIDEO_RESPONSE);
525
- expect(result).to.have.lengthOf(1);
526
-
527
- expect(result[0].width).to.equal(640);
528
- expect(result[0].height).to.equal(360);
529
- expect(result[0].mediaType).to.equal('video');
530
- expect(result[0].creativeId).to.equal(42);
531
- expect(result[0].cpm).to.equal(0.45);
532
- expect(result[0].vastUrl).to.equal('vastContentUrl');
533
- expect(result[0].currency).to.equal('USD');
534
- expect(result[0].netRevenue).to.equal(true);
535
- expect(result[0].ttl).to.equal(300);
693
+ bids = spec.interpretResponse(serverResponse, bidRequest);
694
+ assert.equal(spec.interpretResponse(serverResponse, bidRequest).length, 2);
536
695
  });
537
696
 
538
- it('handles native responses', function () {
539
- let result = spec.interpretResponse(NATIVE_RESPONSE);
540
-
541
- expect(result[0].width).to.equal(0);
542
- expect(result[0].height).to.equal(0);
543
-
544
- expect(result[0].creativeId).to.equal(42);
545
- expect(result[0].cpm).to.equal(0.45);
546
- expect(result[0].currency).to.equal('USD');
547
- expect(result[0].netRevenue).to.equal(true);
548
- expect(result[0].ttl).to.equal(300);
697
+ it('should set correct values to bid', function () {
698
+ let nativeExample1 = {
699
+ assets: [],
700
+ link: {url: 'link'},
701
+ imptrackers: ['imptrackers url1', 'imptrackers url2']
702
+ }
549
703
 
550
- expect(result[0].mediaType).to.equal('native');
704
+ let serverResponse = {
705
+ body: {
706
+ id: null,
707
+ bidid: null,
708
+ seatbid: [{
709
+ bid: [
710
+ {
711
+ impid: '1',
712
+ price: 93.1231,
713
+ crid: '12312312',
714
+ adm: JSON.stringify(nativeExample1),
715
+ dealid: 'deal-id',
716
+ adomain: ['demo.com'],
717
+ ext: {
718
+ crType: 'native',
719
+ advertiser_id: 'adv1',
720
+ advertiser_name: 'advname',
721
+ agency_name: 'agname',
722
+ mediaType: 'native'
723
+ }
724
+ }
725
+ ]
726
+ }],
727
+ cur: 'EUR'
728
+ }
729
+ };
730
+ let bidRequest = {
731
+ data: {},
732
+ bids: [
733
+ {
734
+ bidId: 'bidId1',
735
+ params: {adzoneid: 1000},
736
+ nativeParams: {
737
+ title: {required: true, len: 140},
738
+ image: {required: false, wmin: 836, hmin: 627, w: 325, h: 300, mimes: ['image/jpg', 'image/gif']},
739
+ body: {len: 140}
740
+ }
741
+ }
742
+ ]
743
+ };
551
744
 
552
- expect(result[0].native.clickUrl).to.equal('linkContent');
553
- expect(result[0].native.impressionTrackers).to.deep.equal([
554
- 'impressionTracker1',
555
- 'impressionTracker2'
556
- ]);
557
- expect(result[0].native.title).to.equal('titleContent');
745
+ const bids = spec.interpretResponse(serverResponse, bidRequest);
746
+ const bid = serverResponse.body.seatbid[0].bid[0];
747
+ assert.deepEqual(bids[0].requestId, bidRequest.bids[0].bidId);
748
+ assert.deepEqual(bids[0].cpm, bid.price);
749
+ assert.deepEqual(bids[0].creativeId, bid.crid);
750
+ assert.deepEqual(bids[0].ttl, 300);
751
+ assert.deepEqual(bids[0].netRevenue, false);
752
+ assert.deepEqual(bids[0].currency, serverResponse.body.cur);
753
+ assert.deepEqual(bids[0].mediaType, 'native');
754
+ assert.deepEqual(bids[0].meta.mediaType, 'native');
755
+ assert.deepEqual(bids[0].meta.advertiserDomains, ['demo.com']);
756
+
757
+ assert.deepEqual(bids[0].meta.advertiserName, 'advname');
758
+ assert.deepEqual(bids[0].meta.agencyName, 'agname');
759
+
760
+ assert.deepEqual(bids[0].dealId, 'deal-id');
761
+ });
558
762
 
559
- expect(result[0].native.image.url).to.equal('imageContent');
560
- expect(result[0].native.image.height).to.equal(600);
561
- expect(result[0].native.image.width).to.equal(600);
763
+ it('should return empty when there is no bids in response', function () {
764
+ const serverResponse = {
765
+ body: {
766
+ id: null,
767
+ bidid: null,
768
+ seatbid: [{bid: []}],
769
+ cur: 'EUR'
770
+ }
771
+ };
772
+ let bidRequest = {
773
+ data: {},
774
+ bids: [{bidId: 'bidId1'}]
775
+ };
776
+ const result = spec.interpretResponse(serverResponse, bidRequest)[0];
777
+ assert.ok(!result);
778
+ });
562
779
 
563
- expect(result[0].native.icon.url).to.equal('iconContent');
564
- expect(result[0].native.icon.height).to.equal(400);
565
- expect(result[0].native.icon.width).to.equal(400);
780
+ describe('banner', function () {
781
+ it('should set ad content on response', function () {
782
+ let serverResponse = {
783
+ body: {
784
+ seatbid: [{
785
+ bid: [{impid: '1', adm: '<banner>', ext: {crType: 'banner'}}]
786
+ }]
787
+ }
788
+ };
789
+ let bidRequest = {
790
+ data: {},
791
+ bids: [
792
+ {
793
+ bidId: 'bidId1',
794
+ params: {adzoneid: 1000}
795
+ }
796
+ ]
797
+ };
566
798
 
567
- expect(result[0].native.body).to.equal('descriptionContent');
568
- expect(result[0].native.sponsoredBy).to.equal('sponsoredByContent');
799
+ bids = spec.interpretResponse(serverResponse, bidRequest);
800
+ assert.equal(bids.length, 1);
801
+ assert.equal(bids[0].ad, '<banner>');
802
+ assert.equal(bids[0].mediaType, 'banner');
803
+ assert.equal(bids[0].meta.mediaType, 'banner');
804
+ });
569
805
  });
570
806
 
571
- it('handles nobid responses', function () {
572
- let response = [];
573
- let bidderRequest = BIDDER_REQUEST;
807
+ describe('video', function () {
808
+ it('should set vastXml on response', function () {
809
+ let serverResponse = {
810
+ body: {
811
+ seatbid: [{
812
+ bid: [{impid: '1', adm: '<vast>', ext: {crType: 'video'}}]
813
+ }]
814
+ }
815
+ };
816
+ let bidRequest = {
817
+ data: {},
818
+ bids: [
819
+ {
820
+ bidId: 'bidId1',
821
+ params: {adzoneid: 1000}
822
+ }
823
+ ]
824
+ };
574
825
 
575
- let result = spec.interpretResponse(response, bidderRequest);
576
- expect(result.length).to.equal(0);
826
+ bids = spec.interpretResponse(serverResponse, bidRequest);
827
+ assert.equal(bids.length, 1);
828
+ assert.equal(bids[0].vastXml, '<vast>');
829
+ assert.equal(bids[0].mediaType, 'video');
830
+ assert.equal(bids[0].meta.mediaType, 'video');
831
+ });
577
832
  });
578
833
  });
579
834
 
580
835
  describe('getUserSyncs', function () {
581
- let syncoptionsIframe = {
582
- iframeEnabled: 'true'
583
- };
836
+ const usersyncUrl = 'https://usersync-url.com';
837
+ beforeEach(() => {
838
+ config.setConfig(
839
+ {
840
+ adxcg: {
841
+ usersyncUrl: usersyncUrl,
842
+ }
843
+ }
844
+ )
845
+ })
846
+ after(() => {
847
+ config.resetConfig()
848
+ })
849
+
850
+ it('should return user sync if pixel enabled with adxcg config', function () {
851
+ const ret = spec.getUserSyncs({pixelEnabled: true})
852
+ expect(ret).to.deep.equal([{type: 'image', url: usersyncUrl}])
853
+ })
854
+
855
+ it('should not return user sync if pixel disabled', function () {
856
+ const ret = spec.getUserSyncs({pixelEnabled: false})
857
+ expect(ret).to.be.an('array').that.is.empty
858
+ })
859
+
860
+ it('should not return user sync if url is not set', function () {
861
+ config.resetConfig()
862
+ const ret = spec.getUserSyncs({pixelEnabled: true})
863
+ expect(ret).to.be.an('array').that.is.empty
864
+ })
865
+
866
+ it('should pass GDPR consent', function() {
867
+ expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, undefined)).to.deep.equal([{
868
+ type: 'image', url: `${usersyncUrl}?gdpr=1&gdpr_consent=foo`
869
+ }]);
870
+ expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: false, consentString: 'foo'}, undefined)).to.deep.equal([{
871
+ type: 'image', url: `${usersyncUrl}?gdpr=0&gdpr_consent=foo`
872
+ }]);
873
+ expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: true, consentString: undefined}, undefined)).to.deep.equal([{
874
+ type: 'image', url: `${usersyncUrl}?gdpr=1&gdpr_consent=`
875
+ }]);
876
+ });
877
+
878
+ it('should pass US consent', function() {
879
+ expect(spec.getUserSyncs({ pixelEnabled: true }, {}, undefined, '1NYN')).to.deep.equal([{
880
+ type: 'image', url: `${usersyncUrl}?us_privacy=1NYN`
881
+ }]);
882
+ });
584
883
 
585
- it('should return iframe sync option', function () {
586
- expect(spec.getUserSyncs(syncoptionsIframe)[0].type).to.equal('iframe');
587
- expect(spec.getUserSyncs(syncoptionsIframe)[0].url).to.equal(
588
- 'https://cdn.adxcg.net/pb-sync.html'
589
- );
884
+ it('should pass GDPR and US consent', function() {
885
+ expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, '1NYN')).to.deep.equal([{
886
+ type: 'image', url: `${usersyncUrl}?gdpr=1&gdpr_consent=foo&us_privacy=1NYN`
887
+ }]);
590
888
  });
591
889
  });
592
890
 
593
- describe('on bidWon', function () {
594
- beforeEach(function () {
891
+ describe('onBidWon', function() {
892
+ beforeEach(function() {
595
893
  sinon.stub(utils, 'triggerPixel');
596
894
  });
597
- afterEach(function () {
895
+ afterEach(function() {
598
896
  utils.triggerPixel.restore();
599
897
  });
600
- it('should replace burl for banner', function () {
601
- const burl = 'burl=${' + 'AUCTION_PRICE}';
898
+
899
+ it('Should trigger pixel if bid nurl', function() {
602
900
  const bid = {
603
- 'bidderCode': 'adxcg',
604
- 'width': 0,
605
- 'height': 0,
606
- 'statusMessage': 'Bid available',
607
- 'adId': '3d0b6ff1dda89',
608
- 'requestId': '2a423489e058a1',
609
- 'mediaType': 'banner',
610
- 'source': 'client',
611
- 'ad': burl,
612
- 'cpm': 0.66,
613
- 'creativeId': '353538_591471',
614
- 'currency': 'USD',
615
- 'dealId': '',
616
- 'netRevenue': true,
617
- 'ttl': 300,
618
- // 'nurl': nurl,
619
- 'burl': burl,
620
- 'isBurl': true,
621
- 'auctionId': 'a92bffce-14d2-4f8f-a78a-7b9b5e4d28fa',
622
- 'responseTimestamp': 1556867386065,
623
- 'requestTimestamp': 1556867385916,
624
- 'bidder': 'adxcg',
625
- 'adUnitCode': 'div-gpt-ad-1555415275793-0',
626
- 'timeToRespond': 149,
627
- 'pbLg': '0.50',
628
- 'pbMg': '0.60',
629
- 'pbHg': '0.66',
630
- 'pbAg': '0.65',
631
- 'pbDg': '0.66',
632
- 'pbCg': '',
633
- 'size': '0x0',
634
- 'adserverTargeting': {
635
- 'hb_bidder': 'mgid',
636
- 'hb_adid': '3d0b6ff1dda89',
637
- 'hb_pb': '0.66',
638
- 'hb_size': '0x0',
639
- 'hb_source': 'client',
640
- 'hb_format': 'banner',
641
- 'hb_banner_title': 'TITLE',
642
- 'hb_banner_image': 'hb_banner_image:3d0b6ff1dda89',
643
- 'hb_banner_icon': 'IconURL',
644
- 'hb_banner_linkurl': 'hb_banner_linkurl:3d0b6ff1dda89'
645
- },
646
- 'status': 'targetingSet',
647
- 'params': [{'adzoneid': '20'}]
648
- };
901
+ nurl: 'http://example.com/win/${AUCTION_PRICE}',
902
+ cpm: 2.1,
903
+ originalCpm: 1.1,
904
+ }
649
905
  spec.onBidWon(bid);
650
- expect(bid.burl).to.deep.equal(burl);
651
- });
652
- });
906
+ expect(utils.triggerPixel.callCount).to.equal(1)
907
+ })
908
+ })
653
909
  });