prebid.js 6.1.0 → 6.2.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.
- package/README.md +1 -1
- package/browsers.json +13 -29
- package/karma.conf.maker.js +1 -1
- package/modules/admixerBidAdapter.js +2 -1
- package/modules/adnuntiusBidAdapter.js +2 -1
- package/modules/adplusBidAdapter.js +203 -0
- package/modules/adplusBidAdapter.md +39 -0
- package/modules/adyoulikeBidAdapter.js +7 -2
- package/modules/appnexusBidAdapter.js +19 -2
- package/modules/beachfrontBidAdapter.js +14 -17
- package/modules/craftBidAdapter.js +5 -3
- package/modules/dchain.js +149 -0
- package/modules/dchain.md +45 -0
- package/modules/emx_digitalBidAdapter.js +9 -1
- package/modules/freewheel-sspBidAdapter.js +6 -0
- package/modules/goldbachBidAdapter.js +1176 -0
- package/modules/goldbachBidAdapter.md +151 -0
- package/modules/gumgumBidAdapter.js +5 -1
- package/modules/intersectionRtdProvider.js +114 -0
- package/modules/invibesBidAdapter.js +15 -9
- package/modules/ipromBidAdapter.js +79 -0
- package/modules/limelightDigitalBidAdapter.js +2 -1
- package/modules/luponmediaBidAdapter.js +570 -0
- package/modules/missenaBidAdapter.js +89 -0
- package/modules/pubmaticBidAdapter.js +3 -3
- package/modules/relaidoBidAdapter.js +86 -65
- package/modules/richaudienceBidAdapter.js +1 -1
- package/modules/smaatoBidAdapter.js +4 -1
- package/modules/smartxBidAdapter.js +17 -1
- package/modules/tappxBidAdapter.js +3 -1
- package/modules/undertoneBidAdapter.js +8 -1
- package/modules/userId/index.js +27 -2
- package/modules/ventes.md +71 -0
- package/modules/ventesBidAdapter.js +104 -64
- package/modules/ventesBidAdapter.md +0 -1
- package/modules/visxBidAdapter.js +19 -2
- package/modules/visxBidAdapter.md +4 -6
- package/modules/yahoosspBidAdapter.md +1 -1
- package/modules/yieldoneBidAdapter.js +115 -11
- package/package.json +1 -1
- package/src/auction.js +3 -2
- package/src/targeting.js +2 -2
- package/src/utils.js +7 -0
- package/test/spec/integration/faker/googletag.js +6 -0
- package/test/spec/modules/adnuntiusBidAdapter_spec.js +18 -0
- package/test/spec/modules/adplusBidAdapter_spec.js +213 -0
- package/test/spec/modules/adyoulikeBidAdapter_spec.js +26 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +49 -1
- package/test/spec/modules/beachfrontBidAdapter_spec.js +65 -1
- package/test/spec/modules/dchain_spec.js +329 -0
- package/test/spec/modules/emx_digitalBidAdapter_spec.js +10 -0
- package/test/spec/modules/freewheel-sspBidAdapter_spec.js +19 -0
- package/test/spec/modules/goldbachBidAdapter_spec.js +1359 -0
- package/test/spec/modules/gumgumBidAdapter_spec.js +6 -0
- package/test/spec/modules/intersectionRtdProvider_spec.js +141 -0
- package/test/spec/modules/invibesBidAdapter_spec.js +29 -4
- package/test/spec/modules/ipromBidAdapter_spec.js +195 -0
- package/test/spec/modules/limelightDigitalBidAdapter_spec.js +10 -7
- package/test/spec/modules/luponmediaBidAdapter_spec.js +412 -0
- package/test/spec/modules/missenaBidAdapter_spec.js +134 -0
- package/test/spec/modules/pubmaticBidAdapter_spec.js +1 -1
- package/test/spec/modules/relaidoBidAdapter_spec.js +71 -63
- package/test/spec/modules/smaatoBidAdapter_spec.js +31 -0
- package/test/spec/modules/smartxBidAdapter_spec.js +9 -0
- package/test/spec/modules/tappxBidAdapter_spec.js +4 -0
- package/test/spec/modules/userId_spec.js +51 -0
- package/test/spec/modules/visxBidAdapter_spec.js +120 -4
- package/test/spec/modules/yieldoneBidAdapter_spec.js +299 -53
- package/test/spec/unit/core/targeting_spec.js +44 -0
|
@@ -0,0 +1,1359 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { spec } from 'modules/goldbachBidAdapter.js';
|
|
3
|
+
import { newBidder } from 'src/adapters/bidderFactory.js';
|
|
4
|
+
import * as bidderFactory from 'src/adapters/bidderFactory.js';
|
|
5
|
+
import { auctionManager } from 'src/auctionManager.js';
|
|
6
|
+
import { deepClone } from 'src/utils.js';
|
|
7
|
+
import { config } from 'src/config.js';
|
|
8
|
+
|
|
9
|
+
const ENDPOINT = 'https://ib.adnxs.com/ut/v3/prebid';
|
|
10
|
+
const PRICING_ENDPOINT = 'https://templates.da-services.ch/01_universal/burda_prebid/1.0/json/sizeCPMMapping.json';
|
|
11
|
+
|
|
12
|
+
describe('GoldbachXandrAdapter', function () {
|
|
13
|
+
const adapter = newBidder(spec);
|
|
14
|
+
|
|
15
|
+
describe('inherited functions', function () {
|
|
16
|
+
it('exists and is a function', function () {
|
|
17
|
+
expect(adapter.callBids).to.exist.and.to.be.a('function');
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('isBidRequestValid', function () {
|
|
22
|
+
let bid = {
|
|
23
|
+
'bidder': 'goldbach',
|
|
24
|
+
'params': {
|
|
25
|
+
'placementId': '10433394'
|
|
26
|
+
},
|
|
27
|
+
'adUnitCode': 'adunit-code',
|
|
28
|
+
'sizes': [[300, 250], [300, 600]],
|
|
29
|
+
'bidId': '30b31c1838de1e',
|
|
30
|
+
'bidderRequestId': '22edbae2733bf6',
|
|
31
|
+
'auctionId': '1d1a030790a475',
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
it('should return true when required params found', function () {
|
|
35
|
+
expect(spec.isBidRequestValid(bid)).to.equal(true);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should return true when required params found', function () {
|
|
39
|
+
let bid = Object.assign({}, bid);
|
|
40
|
+
delete bid.params;
|
|
41
|
+
bid.params = {
|
|
42
|
+
'member': '1234',
|
|
43
|
+
'invCode': 'ABCD'
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
expect(spec.isBidRequestValid(bid)).to.equal(true);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should return false when required params are not passed', function () {
|
|
50
|
+
let bid = Object.assign({}, bid);
|
|
51
|
+
delete bid.params;
|
|
52
|
+
bid.params = {
|
|
53
|
+
'placementId': 0
|
|
54
|
+
};
|
|
55
|
+
expect(spec.isBidRequestValid(bid)).to.equal(false);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe('buildRequests', function () {
|
|
60
|
+
let getAdUnitsStub;
|
|
61
|
+
let bidRequests = [
|
|
62
|
+
{
|
|
63
|
+
'bidder': 'goldbach',
|
|
64
|
+
'params': {
|
|
65
|
+
'placementId': '10433394'
|
|
66
|
+
},
|
|
67
|
+
'adUnitCode': 'adunit-code',
|
|
68
|
+
'sizes': [[300, 250], [300, 600]],
|
|
69
|
+
'bidId': '30b31c1838de1e',
|
|
70
|
+
'bidderRequestId': '22edbae2733bf6',
|
|
71
|
+
'auctionId': '1d1a030790a475',
|
|
72
|
+
'transactionId': '04f2659e-c005-4eb1-a57c-fa93145e3843'
|
|
73
|
+
}
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
beforeEach(function() {
|
|
77
|
+
getAdUnitsStub = sinon.stub(auctionManager, 'getAdUnits').callsFake(function() {
|
|
78
|
+
return [];
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
afterEach(function() {
|
|
83
|
+
getAdUnitsStub.restore();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should parse out private sizes', function () {
|
|
87
|
+
let bidRequest = Object.assign({},
|
|
88
|
+
bidRequests[0],
|
|
89
|
+
{
|
|
90
|
+
params: {
|
|
91
|
+
placementId: '10433394',
|
|
92
|
+
privateSizes: [300, 250]
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
98
|
+
const payload = JSON.parse(request.data);
|
|
99
|
+
|
|
100
|
+
expect(payload.tags[0].private_sizes).to.exist;
|
|
101
|
+
expect(payload.tags[0].private_sizes).to.deep.equal([{width: 300, height: 250}]);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should add publisher_id in request', function() {
|
|
105
|
+
let bidRequest = Object.assign({},
|
|
106
|
+
bidRequests[0],
|
|
107
|
+
{
|
|
108
|
+
params: {
|
|
109
|
+
placementId: '10433394',
|
|
110
|
+
publisherId: '1231234'
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
114
|
+
const payload = JSON.parse(request.data);
|
|
115
|
+
|
|
116
|
+
expect(payload.tags[0].publisher_id).to.exist;
|
|
117
|
+
expect(payload.tags[0].publisher_id).to.deep.equal(1231234);
|
|
118
|
+
expect(payload.publisher_id).to.exist;
|
|
119
|
+
expect(payload.publisher_id).to.deep.equal(1231234);
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it('should add source and verison to the tag', function () {
|
|
123
|
+
const request = spec.buildRequests(bidRequests)[1];
|
|
124
|
+
const payload = JSON.parse(request.data);
|
|
125
|
+
expect(payload.sdk).to.exist;
|
|
126
|
+
expect(payload.sdk).to.deep.equal({
|
|
127
|
+
source: 'pbjs',
|
|
128
|
+
version: '$prebid.version$'
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should populate the ad_types array on all requests', function () {
|
|
133
|
+
let adUnits = [{
|
|
134
|
+
code: 'adunit-code',
|
|
135
|
+
mediaTypes: {
|
|
136
|
+
banner: {
|
|
137
|
+
sizes: [[300, 250], [300, 600]]
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
bids: [{
|
|
141
|
+
bidder: 'goldbach',
|
|
142
|
+
params: {
|
|
143
|
+
placementId: '10433394'
|
|
144
|
+
}
|
|
145
|
+
}],
|
|
146
|
+
transactionId: '04f2659e-c005-4eb1-a57c-fa93145e3843'
|
|
147
|
+
}];
|
|
148
|
+
|
|
149
|
+
['banner', 'video', 'native'].forEach(type => {
|
|
150
|
+
getAdUnitsStub.callsFake(function(...args) {
|
|
151
|
+
return adUnits;
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const bidRequest = Object.assign({}, bidRequests[0]);
|
|
155
|
+
bidRequest.mediaTypes = {};
|
|
156
|
+
bidRequest.mediaTypes[type] = {};
|
|
157
|
+
|
|
158
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
159
|
+
const payload = JSON.parse(request.data);
|
|
160
|
+
|
|
161
|
+
expect(payload.tags[0].ad_types).to.deep.equal([type]);
|
|
162
|
+
|
|
163
|
+
if (type === 'banner') {
|
|
164
|
+
delete adUnits[0].mediaTypes;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('should not populate the ad_types array when adUnit.mediaTypes is undefined', function() {
|
|
170
|
+
const bidRequest = Object.assign({}, bidRequests[0]);
|
|
171
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
172
|
+
const payload = JSON.parse(request.data);
|
|
173
|
+
|
|
174
|
+
expect(payload.tags[0].ad_types).to.not.exist;
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('should populate the ad_types array on outstream requests', function () {
|
|
178
|
+
const bidRequest = Object.assign({}, bidRequests[0]);
|
|
179
|
+
bidRequest.mediaTypes = {};
|
|
180
|
+
bidRequest.mediaTypes.video = {context: 'outstream'};
|
|
181
|
+
|
|
182
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
183
|
+
const payload = JSON.parse(request.data);
|
|
184
|
+
|
|
185
|
+
expect(payload.tags[0].ad_types).to.deep.equal(['video']);
|
|
186
|
+
expect(payload.tags[0].hb_source).to.deep.equal(1);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('sends bid request to ENDPOINT via POST', function () {
|
|
190
|
+
const request = spec.buildRequests(bidRequests)[1];
|
|
191
|
+
expect(request.url).to.equal(ENDPOINT);
|
|
192
|
+
expect(request.method).to.equal('POST');
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('sends bid request to ENDPOINT via GET', function () {
|
|
196
|
+
const request = spec.buildRequests(bidRequests)[0];
|
|
197
|
+
expect(request.url).to.equal(PRICING_ENDPOINT);
|
|
198
|
+
expect(request.method).to.equal('GET');
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('should attach valid video params to the tag', function () {
|
|
202
|
+
let bidRequest = Object.assign({},
|
|
203
|
+
bidRequests[0],
|
|
204
|
+
{
|
|
205
|
+
params: {
|
|
206
|
+
placementId: '10433394',
|
|
207
|
+
video: {
|
|
208
|
+
id: 123,
|
|
209
|
+
minduration: 100,
|
|
210
|
+
foobar: 'invalid'
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
217
|
+
const payload = JSON.parse(request.data);
|
|
218
|
+
expect(payload.tags[0].video).to.deep.equal({
|
|
219
|
+
id: 123,
|
|
220
|
+
minduration: 100
|
|
221
|
+
});
|
|
222
|
+
expect(payload.tags[0].hb_source).to.deep.equal(1);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('should include ORTB video values when video params were not set', function() {
|
|
226
|
+
let bidRequest = deepClone(bidRequests[0]);
|
|
227
|
+
bidRequest.params = {
|
|
228
|
+
placementId: '1234235',
|
|
229
|
+
video: {
|
|
230
|
+
skippable: true,
|
|
231
|
+
playback_method: ['auto_play_sound_off', 'auto_play_sound_unknown'],
|
|
232
|
+
context: 'outstream'
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
bidRequest.mediaTypes = {
|
|
236
|
+
video: {
|
|
237
|
+
playerSize: [640, 480],
|
|
238
|
+
context: 'outstream',
|
|
239
|
+
mimes: ['video/mp4'],
|
|
240
|
+
skip: 0,
|
|
241
|
+
minduration: 5,
|
|
242
|
+
api: [1, 5, 6],
|
|
243
|
+
playbackmethod: [2, 4]
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
248
|
+
const payload = JSON.parse(request.data);
|
|
249
|
+
|
|
250
|
+
expect(payload.tags[0].video).to.deep.equal({
|
|
251
|
+
minduration: 5,
|
|
252
|
+
playback_method: 2,
|
|
253
|
+
skippable: true,
|
|
254
|
+
context: 4
|
|
255
|
+
});
|
|
256
|
+
expect(payload.tags[0].video_frameworks).to.deep.equal([1, 4])
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('should add video property when adUnit includes a renderer', function () {
|
|
260
|
+
const videoData = {
|
|
261
|
+
mediaTypes: {
|
|
262
|
+
video: {
|
|
263
|
+
context: 'outstream',
|
|
264
|
+
mimes: ['video/mp4']
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
params: {
|
|
268
|
+
placementId: '10433394',
|
|
269
|
+
video: {
|
|
270
|
+
skippable: true,
|
|
271
|
+
playback_method: ['auto_play_sound_off']
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
let bidRequest1 = deepClone(bidRequests[0]);
|
|
277
|
+
bidRequest1 = Object.assign({}, bidRequest1, videoData, {
|
|
278
|
+
renderer: {
|
|
279
|
+
url: 'https://test.renderer.url',
|
|
280
|
+
render: function () {}
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
let bidRequest2 = deepClone(bidRequests[0]);
|
|
285
|
+
bidRequest2.adUnitCode = 'adUnit_code_2';
|
|
286
|
+
bidRequest2 = Object.assign({}, bidRequest2, videoData);
|
|
287
|
+
|
|
288
|
+
const request = spec.buildRequests([bidRequest1, bidRequest2])[1];
|
|
289
|
+
const payload = JSON.parse(request.data);
|
|
290
|
+
expect(payload.tags[0].video).to.deep.equal({
|
|
291
|
+
skippable: true,
|
|
292
|
+
playback_method: 2,
|
|
293
|
+
custom_renderer_present: true
|
|
294
|
+
});
|
|
295
|
+
expect(payload.tags[1].video).to.deep.equal({
|
|
296
|
+
skippable: true,
|
|
297
|
+
playback_method: 2
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
it('should attach valid user params to the tag', function () {
|
|
302
|
+
let bidRequest = Object.assign({},
|
|
303
|
+
bidRequests[0],
|
|
304
|
+
{
|
|
305
|
+
params: {
|
|
306
|
+
placementId: '10433394',
|
|
307
|
+
user: {
|
|
308
|
+
externalUid: '123',
|
|
309
|
+
segments: [123, { id: 987, value: 876 }],
|
|
310
|
+
foobar: 'invalid'
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
317
|
+
const payload = JSON.parse(request.data);
|
|
318
|
+
|
|
319
|
+
expect(payload.user).to.exist;
|
|
320
|
+
expect(payload.user).to.deep.equal({
|
|
321
|
+
external_uid: '123',
|
|
322
|
+
segments: [{id: 123}, {id: 987, value: 876}]
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it('should attach reserve param when either bid param or getFloor function exists', function () {
|
|
327
|
+
let getFloorResponse = { currency: 'USD', floor: 3 };
|
|
328
|
+
let request, payload = null;
|
|
329
|
+
let bidRequest = deepClone(bidRequests[0]);
|
|
330
|
+
|
|
331
|
+
// 1 -> reserve not defined, getFloor not defined > empty
|
|
332
|
+
request = spec.buildRequests([bidRequest])[1];
|
|
333
|
+
payload = JSON.parse(request.data);
|
|
334
|
+
|
|
335
|
+
expect(payload.tags[0].reserve).to.not.exist;
|
|
336
|
+
|
|
337
|
+
// 2 -> reserve is defined, getFloor not defined > reserve is used
|
|
338
|
+
bidRequest.params = {
|
|
339
|
+
'placementId': '10433394',
|
|
340
|
+
'reserve': 0.5
|
|
341
|
+
};
|
|
342
|
+
request = spec.buildRequests([bidRequest])[1];
|
|
343
|
+
payload = JSON.parse(request.data);
|
|
344
|
+
|
|
345
|
+
expect(payload.tags[0].reserve).to.exist.and.to.equal(0.5);
|
|
346
|
+
|
|
347
|
+
// 3 -> reserve is defined, getFloor is defined > getFloor is used
|
|
348
|
+
bidRequest.getFloor = () => getFloorResponse;
|
|
349
|
+
|
|
350
|
+
request = spec.buildRequests([bidRequest])[1];
|
|
351
|
+
payload = JSON.parse(request.data);
|
|
352
|
+
|
|
353
|
+
expect(payload.tags[0].reserve).to.exist.and.to.equal(3);
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
it('should duplicate adpod placements into batches and set correct maxduration', function() {
|
|
357
|
+
let bidRequest = Object.assign({},
|
|
358
|
+
bidRequests[0],
|
|
359
|
+
{
|
|
360
|
+
params: { placementId: '14542875' }
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
mediaTypes: {
|
|
364
|
+
video: {
|
|
365
|
+
context: 'adpod',
|
|
366
|
+
playerSize: [640, 480],
|
|
367
|
+
adPodDurationSec: 300,
|
|
368
|
+
durationRangeSec: [15, 30],
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
);
|
|
373
|
+
|
|
374
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
375
|
+
const payload1 = JSON.parse(request[0].data);
|
|
376
|
+
const payload2 = JSON.parse(request[1].data);
|
|
377
|
+
|
|
378
|
+
// 300 / 15 = 20 total
|
|
379
|
+
expect(payload1.tags.length).to.equal(15);
|
|
380
|
+
expect(payload2.tags.length).to.equal(5);
|
|
381
|
+
|
|
382
|
+
expect(payload1.tags[0]).to.deep.equal(payload1.tags[1]);
|
|
383
|
+
expect(payload1.tags[0].video.maxduration).to.equal(30);
|
|
384
|
+
|
|
385
|
+
expect(payload2.tags[0]).to.deep.equal(payload1.tags[1]);
|
|
386
|
+
expect(payload2.tags[0].video.maxduration).to.equal(30);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it('should round down adpod placements when numbers are uneven', function() {
|
|
390
|
+
let bidRequest = Object.assign({},
|
|
391
|
+
bidRequests[0],
|
|
392
|
+
{
|
|
393
|
+
params: { placementId: '14542875' }
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
mediaTypes: {
|
|
397
|
+
video: {
|
|
398
|
+
context: 'adpod',
|
|
399
|
+
playerSize: [640, 480],
|
|
400
|
+
adPodDurationSec: 123,
|
|
401
|
+
durationRangeSec: [45],
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
);
|
|
406
|
+
|
|
407
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
408
|
+
const payload = JSON.parse(request.data);
|
|
409
|
+
expect(payload.tags.length).to.equal(2);
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
it('should duplicate adpod placements when requireExactDuration is set', function() {
|
|
413
|
+
let bidRequest = Object.assign({},
|
|
414
|
+
bidRequests[0],
|
|
415
|
+
{
|
|
416
|
+
params: { placementId: '14542875' }
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
mediaTypes: {
|
|
420
|
+
video: {
|
|
421
|
+
context: 'adpod',
|
|
422
|
+
playerSize: [640, 480],
|
|
423
|
+
adPodDurationSec: 300,
|
|
424
|
+
durationRangeSec: [15, 30],
|
|
425
|
+
requireExactDuration: true,
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
// 20 total placements with 15 max impressions = 2 requests
|
|
432
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
433
|
+
expect(request.length).to.equal(2);
|
|
434
|
+
|
|
435
|
+
// 20 spread over 2 requests = 15 in first request, 5 in second
|
|
436
|
+
const payload1 = JSON.parse(request[0].data);
|
|
437
|
+
const payload2 = JSON.parse(request[1].data);
|
|
438
|
+
expect(payload1.tags.length).to.equal(15);
|
|
439
|
+
expect(payload2.tags.length).to.equal(5);
|
|
440
|
+
|
|
441
|
+
// 10 placements should have max/min at 15
|
|
442
|
+
// 10 placemenst should have max/min at 30
|
|
443
|
+
const payload1tagsWith15 = payload1.tags.filter(tag => tag.video.maxduration === 15);
|
|
444
|
+
const payload1tagsWith30 = payload1.tags.filter(tag => tag.video.maxduration === 30);
|
|
445
|
+
expect(payload1tagsWith15.length).to.equal(10);
|
|
446
|
+
expect(payload1tagsWith30.length).to.equal(5);
|
|
447
|
+
|
|
448
|
+
// 5 placemenst with min/max at 30 were in the first request
|
|
449
|
+
// so 5 remaining should be in the second
|
|
450
|
+
const payload2tagsWith30 = payload2.tags.filter(tag => tag.video.maxduration === 30);
|
|
451
|
+
expect(payload2tagsWith30.length).to.equal(5);
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
it('should set durations for placements when requireExactDuration is set and numbers are uneven', function() {
|
|
455
|
+
let bidRequest = Object.assign({},
|
|
456
|
+
bidRequests[0],
|
|
457
|
+
{
|
|
458
|
+
params: { placementId: '14542875' }
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
mediaTypes: {
|
|
462
|
+
video: {
|
|
463
|
+
context: 'adpod',
|
|
464
|
+
playerSize: [640, 480],
|
|
465
|
+
adPodDurationSec: 105,
|
|
466
|
+
durationRangeSec: [15, 30, 60],
|
|
467
|
+
requireExactDuration: true,
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
);
|
|
472
|
+
|
|
473
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
474
|
+
const payload = JSON.parse(request.data);
|
|
475
|
+
expect(payload.tags.length).to.equal(7);
|
|
476
|
+
|
|
477
|
+
const tagsWith15 = payload.tags.filter(tag => tag.video.maxduration === 15);
|
|
478
|
+
const tagsWith30 = payload.tags.filter(tag => tag.video.maxduration === 30);
|
|
479
|
+
const tagsWith60 = payload.tags.filter(tag => tag.video.maxduration === 60);
|
|
480
|
+
expect(tagsWith15.length).to.equal(3);
|
|
481
|
+
expect(tagsWith30.length).to.equal(3);
|
|
482
|
+
expect(tagsWith60.length).to.equal(1);
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
it('should break adpod request into batches', function() {
|
|
486
|
+
let bidRequest = Object.assign({},
|
|
487
|
+
bidRequests[0],
|
|
488
|
+
{
|
|
489
|
+
params: { placementId: '14542875' }
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
mediaTypes: {
|
|
493
|
+
video: {
|
|
494
|
+
context: 'adpod',
|
|
495
|
+
playerSize: [640, 480],
|
|
496
|
+
adPodDurationSec: 225,
|
|
497
|
+
durationRangeSec: [5],
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
);
|
|
502
|
+
|
|
503
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
504
|
+
const payload1 = JSON.parse(request[0].data);
|
|
505
|
+
const payload2 = JSON.parse(request[1].data);
|
|
506
|
+
const payload3 = JSON.parse(request[2].data);
|
|
507
|
+
|
|
508
|
+
expect(payload1.tags.length).to.equal(15);
|
|
509
|
+
expect(payload2.tags.length).to.equal(15);
|
|
510
|
+
expect(payload3.tags.length).to.equal(15);
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
// it('should contain hb_source value for adpod', function() {
|
|
514
|
+
// let bidRequest = Object.assign({},
|
|
515
|
+
// bidRequests[0],
|
|
516
|
+
// {
|
|
517
|
+
// params: { placementId: '14542875' }
|
|
518
|
+
// },
|
|
519
|
+
// {
|
|
520
|
+
// mediaTypes: {
|
|
521
|
+
// video: {
|
|
522
|
+
// context: 'adpod',
|
|
523
|
+
// playerSize: [640, 480],
|
|
524
|
+
// adPodDurationSec: 300,
|
|
525
|
+
// durationRangeSec: [15, 30],
|
|
526
|
+
// }
|
|
527
|
+
// }
|
|
528
|
+
// }
|
|
529
|
+
// );
|
|
530
|
+
// const request = spec.buildRequests([bidRequest])[1];
|
|
531
|
+
// const payload = JSON.parse(request.data);
|
|
532
|
+
// expect(payload.tags[0].hb_source).to.deep.equal(7);
|
|
533
|
+
// });
|
|
534
|
+
|
|
535
|
+
it('should contain hb_source value for other media', function() {
|
|
536
|
+
let bidRequest = Object.assign({},
|
|
537
|
+
bidRequests[0],
|
|
538
|
+
{
|
|
539
|
+
mediaType: 'banner',
|
|
540
|
+
params: {
|
|
541
|
+
sizes: [[300, 250], [300, 600]],
|
|
542
|
+
placementId: 13144370
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
);
|
|
546
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
547
|
+
const payload = JSON.parse(request.data);
|
|
548
|
+
expect(payload.tags[0].hb_source).to.deep.equal(1);
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
it('adds brand_category_exclusion to request when set', function() {
|
|
552
|
+
let bidRequest = Object.assign({}, bidRequests[0]);
|
|
553
|
+
sinon
|
|
554
|
+
.stub(config, 'getConfig')
|
|
555
|
+
.withArgs('adpod.brandCategoryExclusion')
|
|
556
|
+
.returns(true);
|
|
557
|
+
|
|
558
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
559
|
+
const payload = JSON.parse(request.data);
|
|
560
|
+
|
|
561
|
+
expect(payload.brand_category_uniqueness).to.equal(true);
|
|
562
|
+
|
|
563
|
+
config.getConfig.restore();
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
it('should attach native params to the request', function () {
|
|
567
|
+
let bidRequest = Object.assign({},
|
|
568
|
+
bidRequests[0],
|
|
569
|
+
{
|
|
570
|
+
mediaType: 'native',
|
|
571
|
+
nativeParams: {
|
|
572
|
+
title: {required: true},
|
|
573
|
+
body: {required: true},
|
|
574
|
+
body2: {required: true},
|
|
575
|
+
image: {required: true, sizes: [100, 100]},
|
|
576
|
+
icon: {required: true},
|
|
577
|
+
cta: {required: false},
|
|
578
|
+
rating: {required: true},
|
|
579
|
+
sponsoredBy: {required: true},
|
|
580
|
+
privacyLink: {required: true},
|
|
581
|
+
displayUrl: {required: true},
|
|
582
|
+
address: {required: true},
|
|
583
|
+
downloads: {required: true},
|
|
584
|
+
likes: {required: true},
|
|
585
|
+
phone: {required: true},
|
|
586
|
+
price: {required: true},
|
|
587
|
+
salePrice: {required: true}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
);
|
|
591
|
+
|
|
592
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
593
|
+
const payload = JSON.parse(request.data);
|
|
594
|
+
|
|
595
|
+
expect(payload.tags[0].native.layouts[0]).to.deep.equal({
|
|
596
|
+
title: {required: true},
|
|
597
|
+
description: {required: true},
|
|
598
|
+
desc2: {required: true},
|
|
599
|
+
main_image: {required: true, sizes: [{ width: 100, height: 100 }]},
|
|
600
|
+
icon: {required: true},
|
|
601
|
+
ctatext: {required: false},
|
|
602
|
+
rating: {required: true},
|
|
603
|
+
sponsored_by: {required: true},
|
|
604
|
+
privacy_link: {required: true},
|
|
605
|
+
displayurl: {required: true},
|
|
606
|
+
address: {required: true},
|
|
607
|
+
downloads: {required: true},
|
|
608
|
+
likes: {required: true},
|
|
609
|
+
phone: {required: true},
|
|
610
|
+
price: {required: true},
|
|
611
|
+
saleprice: {required: true},
|
|
612
|
+
privacy_supported: true
|
|
613
|
+
});
|
|
614
|
+
expect(payload.tags[0].hb_source).to.equal(1);
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
it('should always populated tags[].sizes with 1,1 for native if otherwise not defined', function () {
|
|
618
|
+
let bidRequest = Object.assign({},
|
|
619
|
+
bidRequests[0],
|
|
620
|
+
{
|
|
621
|
+
mediaType: 'native',
|
|
622
|
+
nativeParams: {
|
|
623
|
+
image: { required: true }
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
);
|
|
627
|
+
bidRequest.sizes = [[150, 100], [300, 250]];
|
|
628
|
+
|
|
629
|
+
let request = spec.buildRequests([bidRequest])[1];
|
|
630
|
+
let payload = JSON.parse(request.data);
|
|
631
|
+
expect(payload.tags[0].sizes).to.deep.equal([{width: 150, height: 100}, {width: 300, height: 250}]);
|
|
632
|
+
|
|
633
|
+
delete bidRequest.sizes;
|
|
634
|
+
|
|
635
|
+
request = spec.buildRequests([bidRequest])[1];
|
|
636
|
+
payload = JSON.parse(request.data);
|
|
637
|
+
|
|
638
|
+
expect(payload.tags[0].sizes).to.deep.equal([{width: 1, height: 1}]);
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
it('should convert keyword params to proper form and attaches to request', function () {
|
|
642
|
+
let bidRequest = Object.assign({},
|
|
643
|
+
bidRequests[0],
|
|
644
|
+
{
|
|
645
|
+
params: {
|
|
646
|
+
placementId: '10433394',
|
|
647
|
+
keywords: {
|
|
648
|
+
single: 'val',
|
|
649
|
+
singleArr: ['val'],
|
|
650
|
+
singleArrNum: [5],
|
|
651
|
+
multiValMixed: ['value1', 2, 'value3'],
|
|
652
|
+
singleValNum: 123,
|
|
653
|
+
emptyStr: '',
|
|
654
|
+
emptyArr: [''],
|
|
655
|
+
badValue: {'foo': 'bar'} // should be dropped
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
);
|
|
660
|
+
|
|
661
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
662
|
+
const payload = JSON.parse(request.data);
|
|
663
|
+
|
|
664
|
+
expect(payload.tags[0].keywords).to.deep.equal([{
|
|
665
|
+
'key': 'single',
|
|
666
|
+
'value': ['val']
|
|
667
|
+
}, {
|
|
668
|
+
'key': 'singleArr',
|
|
669
|
+
'value': ['val']
|
|
670
|
+
}, {
|
|
671
|
+
'key': 'singleArrNum',
|
|
672
|
+
'value': ['5']
|
|
673
|
+
}, {
|
|
674
|
+
'key': 'multiValMixed',
|
|
675
|
+
'value': ['value1', '2', 'value3']
|
|
676
|
+
}, {
|
|
677
|
+
'key': 'singleValNum',
|
|
678
|
+
'value': ['123']
|
|
679
|
+
}, {
|
|
680
|
+
'key': 'emptyStr'
|
|
681
|
+
}, {
|
|
682
|
+
'key': 'emptyArr'
|
|
683
|
+
}]);
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
it('should add payment rules to the request', function () {
|
|
687
|
+
let bidRequest = Object.assign({},
|
|
688
|
+
bidRequests[0],
|
|
689
|
+
{
|
|
690
|
+
params: {
|
|
691
|
+
placementId: '10433394',
|
|
692
|
+
usePaymentRule: true
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
);
|
|
696
|
+
|
|
697
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
698
|
+
const payload = JSON.parse(request.data);
|
|
699
|
+
|
|
700
|
+
expect(payload.tags[0].use_pmt_rule).to.equal(true);
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
it('should add gpid to the request', function () {
|
|
704
|
+
let testGpid = '/12345/my-gpt-tag-0';
|
|
705
|
+
let bidRequest = deepClone(bidRequests[0]);
|
|
706
|
+
bidRequest.ortb2Imp = { ext: { data: { pbadslot: testGpid } } };
|
|
707
|
+
|
|
708
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
709
|
+
const payload = JSON.parse(request.data);
|
|
710
|
+
|
|
711
|
+
expect(payload.tags[0].gpid).to.exist.and.equal(testGpid)
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
it('should add gdpr consent information to the request', function () {
|
|
715
|
+
let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==';
|
|
716
|
+
let bidderRequest = {
|
|
717
|
+
'bidderCode': 'goldbach',
|
|
718
|
+
'auctionId': '1d1a030790a475',
|
|
719
|
+
'bidderRequestId': '22edbae2733bf6',
|
|
720
|
+
'timeout': 3000,
|
|
721
|
+
'gdprConsent': {
|
|
722
|
+
consentString: consentString,
|
|
723
|
+
gdprApplies: true,
|
|
724
|
+
addtlConsent: '1~7.12.35.62.66.70.89.93.108'
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
bidderRequest.bids = bidRequests;
|
|
728
|
+
|
|
729
|
+
const request = spec.buildRequests(bidRequests, bidderRequest)[1];
|
|
730
|
+
expect(request.options).to.deep.equal({withCredentials: true});
|
|
731
|
+
const payload = JSON.parse(request.data);
|
|
732
|
+
|
|
733
|
+
expect(payload.gdpr_consent).to.exist;
|
|
734
|
+
expect(payload.gdpr_consent.consent_string).to.exist.and.to.equal(consentString);
|
|
735
|
+
expect(payload.gdpr_consent.consent_required).to.exist.and.to.be.true;
|
|
736
|
+
expect(payload.gdpr_consent.addtl_consent).to.exist.and.to.deep.equal([7, 12, 35, 62, 66, 70, 89, 93, 108]);
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
it('should add us privacy string to payload', function() {
|
|
740
|
+
let consentString = '1YA-';
|
|
741
|
+
let bidderRequest = {
|
|
742
|
+
'bidderCode': 'goldbach',
|
|
743
|
+
'auctionId': '1d1a030790a475',
|
|
744
|
+
'bidderRequestId': '22edbae2733bf6',
|
|
745
|
+
'timeout': 3000,
|
|
746
|
+
'uspConsent': consentString
|
|
747
|
+
};
|
|
748
|
+
bidderRequest.bids = bidRequests;
|
|
749
|
+
|
|
750
|
+
const request = spec.buildRequests(bidRequests, bidderRequest)[1];
|
|
751
|
+
const payload = JSON.parse(request.data);
|
|
752
|
+
|
|
753
|
+
expect(payload.us_privacy).to.exist;
|
|
754
|
+
expect(payload.us_privacy).to.exist.and.to.equal(consentString);
|
|
755
|
+
});
|
|
756
|
+
|
|
757
|
+
it('supports sending hybrid mobile app parameters', function () {
|
|
758
|
+
let appRequest = Object.assign({},
|
|
759
|
+
bidRequests[0],
|
|
760
|
+
{
|
|
761
|
+
params: {
|
|
762
|
+
placementId: '10433394',
|
|
763
|
+
app: {
|
|
764
|
+
id: 'B1O2W3M4AN.com.prebid.webview',
|
|
765
|
+
geo: {
|
|
766
|
+
lat: 40.0964439,
|
|
767
|
+
lng: -75.3009142
|
|
768
|
+
},
|
|
769
|
+
device_id: {
|
|
770
|
+
idfa: '4D12078D-3246-4DA4-AD5E-7610481E7AE', // Apple advertising identifier
|
|
771
|
+
aaid: '38400000-8cf0-11bd-b23e-10b96e40000d', // Android advertising identifier
|
|
772
|
+
md5udid: '5756ae9022b2ea1e47d84fead75220c8', // MD5 hash of the ANDROID_ID
|
|
773
|
+
sha1udid: '4DFAA92388699AC6539885AEF1719293879985BF', // SHA1 hash of the ANDROID_ID
|
|
774
|
+
windowsadid: '750c6be243f1c4b5c9912b95a5742fc5' // Windows advertising identifier
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
);
|
|
780
|
+
const request = spec.buildRequests([appRequest])[1];
|
|
781
|
+
const payload = JSON.parse(request.data);
|
|
782
|
+
expect(payload.app).to.exist;
|
|
783
|
+
expect(payload.app).to.deep.equal({
|
|
784
|
+
appid: 'B1O2W3M4AN.com.prebid.webview'
|
|
785
|
+
});
|
|
786
|
+
expect(payload.device.device_id).to.exist;
|
|
787
|
+
expect(payload.device.device_id).to.deep.equal({
|
|
788
|
+
aaid: '38400000-8cf0-11bd-b23e-10b96e40000d',
|
|
789
|
+
idfa: '4D12078D-3246-4DA4-AD5E-7610481E7AE',
|
|
790
|
+
md5udid: '5756ae9022b2ea1e47d84fead75220c8',
|
|
791
|
+
sha1udid: '4DFAA92388699AC6539885AEF1719293879985BF',
|
|
792
|
+
windowsadid: '750c6be243f1c4b5c9912b95a5742fc5'
|
|
793
|
+
});
|
|
794
|
+
expect(payload.device.geo).to.exist;
|
|
795
|
+
expect(payload.device.geo).to.deep.equal({
|
|
796
|
+
lat: 40.0964439,
|
|
797
|
+
lng: -75.3009142
|
|
798
|
+
});
|
|
799
|
+
});
|
|
800
|
+
|
|
801
|
+
it('should add referer info to payload', function () {
|
|
802
|
+
const bidRequest = Object.assign({}, bidRequests[0])
|
|
803
|
+
const bidderRequest = {
|
|
804
|
+
refererInfo: {
|
|
805
|
+
referer: 'https://example.com/page.html',
|
|
806
|
+
reachedTop: true,
|
|
807
|
+
numIframes: 2,
|
|
808
|
+
stack: [
|
|
809
|
+
'https://example.com/page.html',
|
|
810
|
+
'https://example.com/iframe1.html',
|
|
811
|
+
'https://example.com/iframe2.html'
|
|
812
|
+
]
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
const request = spec.buildRequests([bidRequest], bidderRequest)[1];
|
|
816
|
+
const payload = JSON.parse(request.data);
|
|
817
|
+
|
|
818
|
+
expect(payload.referrer_detection).to.exist;
|
|
819
|
+
expect(payload.referrer_detection).to.deep.equal({
|
|
820
|
+
rd_ref: 'https%3A%2F%2Fexample.com%2Fpage.html',
|
|
821
|
+
rd_top: true,
|
|
822
|
+
rd_ifs: 2,
|
|
823
|
+
rd_stk: bidderRequest.refererInfo.stack.map((url) => encodeURIComponent(url)).join(',')
|
|
824
|
+
});
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
it('should populate schain if available', function () {
|
|
828
|
+
const bidRequest = Object.assign({}, bidRequests[0], {
|
|
829
|
+
schain: {
|
|
830
|
+
ver: '1.0',
|
|
831
|
+
complete: 1,
|
|
832
|
+
nodes: [
|
|
833
|
+
{
|
|
834
|
+
'asi': 'blob.com',
|
|
835
|
+
'sid': '001',
|
|
836
|
+
'hp': 1
|
|
837
|
+
}
|
|
838
|
+
]
|
|
839
|
+
}
|
|
840
|
+
});
|
|
841
|
+
|
|
842
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
843
|
+
const payload = JSON.parse(request.data);
|
|
844
|
+
expect(payload.schain).to.deep.equal({
|
|
845
|
+
ver: '1.0',
|
|
846
|
+
complete: 1,
|
|
847
|
+
nodes: [
|
|
848
|
+
{
|
|
849
|
+
'asi': 'blob.com',
|
|
850
|
+
'sid': '001',
|
|
851
|
+
'hp': 1
|
|
852
|
+
}
|
|
853
|
+
]
|
|
854
|
+
});
|
|
855
|
+
});
|
|
856
|
+
|
|
857
|
+
it('should populate coppa if set in config', function () {
|
|
858
|
+
let bidRequest = Object.assign({}, bidRequests[0]);
|
|
859
|
+
sinon.stub(config, 'getConfig')
|
|
860
|
+
.withArgs('coppa')
|
|
861
|
+
.returns(true);
|
|
862
|
+
|
|
863
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
864
|
+
const payload = JSON.parse(request.data);
|
|
865
|
+
|
|
866
|
+
expect(payload.user.coppa).to.equal(true);
|
|
867
|
+
|
|
868
|
+
config.getConfig.restore();
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
it('should set the X-Is-Test customHeader if test flag is enabled', function () {
|
|
872
|
+
let bidRequest = Object.assign({}, bidRequests[0]);
|
|
873
|
+
sinon.stub(config, 'getConfig')
|
|
874
|
+
.withArgs('apn_test')
|
|
875
|
+
.returns(true);
|
|
876
|
+
|
|
877
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
878
|
+
expect(request.options.customHeaders).to.deep.equal({'X-Is-Test': 1});
|
|
879
|
+
|
|
880
|
+
config.getConfig.restore();
|
|
881
|
+
});
|
|
882
|
+
|
|
883
|
+
it('should always set withCredentials: true on the request.options', function () {
|
|
884
|
+
let bidRequest = Object.assign({}, bidRequests[0]);
|
|
885
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
886
|
+
expect(request.options.withCredentials).to.equal(true);
|
|
887
|
+
});
|
|
888
|
+
|
|
889
|
+
it('should set simple domain variant if purpose 1 consent is not given', function () {
|
|
890
|
+
let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==';
|
|
891
|
+
let bidderRequest = {
|
|
892
|
+
'bidderCode': 'goldbach',
|
|
893
|
+
'auctionId': '1d1a030790a475',
|
|
894
|
+
'bidderRequestId': '22edbae2733bf6',
|
|
895
|
+
'timeout': 3000,
|
|
896
|
+
'gdprConsent': {
|
|
897
|
+
consentString: consentString,
|
|
898
|
+
gdprApplies: true,
|
|
899
|
+
apiVersion: 2,
|
|
900
|
+
vendorData: {
|
|
901
|
+
purpose: {
|
|
902
|
+
consents: {
|
|
903
|
+
1: false
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
};
|
|
909
|
+
bidderRequest.bids = bidRequests;
|
|
910
|
+
|
|
911
|
+
const request = spec.buildRequests(bidRequests, bidderRequest)[1];
|
|
912
|
+
expect(request.url).to.equal('https://ib.adnxs-simple.com/ut/v3/prebid');
|
|
913
|
+
});
|
|
914
|
+
|
|
915
|
+
it('should populate eids when supported userIds are available', function () {
|
|
916
|
+
const bidRequest = Object.assign({}, bidRequests[0], {
|
|
917
|
+
userId: {
|
|
918
|
+
tdid: 'sample-userid',
|
|
919
|
+
uid2: { id: 'sample-uid2-value' },
|
|
920
|
+
criteoId: 'sample-criteo-userid',
|
|
921
|
+
netId: 'sample-netId-userid',
|
|
922
|
+
idl_env: 'sample-idl-userid',
|
|
923
|
+
flocId: {
|
|
924
|
+
id: 'sample-flocid-value',
|
|
925
|
+
version: 'chrome.1.0'
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
const request = spec.buildRequests([bidRequest])[1];
|
|
931
|
+
const payload = JSON.parse(request.data);
|
|
932
|
+
expect(payload.eids).to.deep.include({
|
|
933
|
+
source: 'adserver.org',
|
|
934
|
+
id: 'sample-userid',
|
|
935
|
+
rti_partner: 'TDID'
|
|
936
|
+
});
|
|
937
|
+
|
|
938
|
+
expect(payload.eids).to.deep.include({
|
|
939
|
+
source: 'criteo.com',
|
|
940
|
+
id: 'sample-criteo-userid',
|
|
941
|
+
});
|
|
942
|
+
|
|
943
|
+
expect(payload.eids).to.deep.include({
|
|
944
|
+
source: 'chrome.com',
|
|
945
|
+
id: 'sample-flocid-value'
|
|
946
|
+
});
|
|
947
|
+
|
|
948
|
+
expect(payload.eids).to.deep.include({
|
|
949
|
+
source: 'netid.de',
|
|
950
|
+
id: 'sample-netId-userid',
|
|
951
|
+
});
|
|
952
|
+
|
|
953
|
+
expect(payload.eids).to.deep.include({
|
|
954
|
+
source: 'liveramp.com',
|
|
955
|
+
id: 'sample-idl-userid'
|
|
956
|
+
});
|
|
957
|
+
|
|
958
|
+
expect(payload.eids).to.deep.include({
|
|
959
|
+
source: 'uidapi.com',
|
|
960
|
+
id: 'sample-uid2-value',
|
|
961
|
+
rti_partner: 'UID2'
|
|
962
|
+
});
|
|
963
|
+
});
|
|
964
|
+
|
|
965
|
+
it('should populate iab_support object at the root level if omid support is detected', function () {
|
|
966
|
+
// with bid.params.frameworks
|
|
967
|
+
let bidRequest_A = Object.assign({}, bidRequests[0], {
|
|
968
|
+
params: {
|
|
969
|
+
frameworks: [1, 2, 5, 6],
|
|
970
|
+
video: {
|
|
971
|
+
frameworks: [1, 2, 5, 6]
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
});
|
|
975
|
+
let request = spec.buildRequests([bidRequest_A])[1];
|
|
976
|
+
let payload = JSON.parse(request.data);
|
|
977
|
+
expect(payload.iab_support).to.be.an('object');
|
|
978
|
+
expect(payload.iab_support).to.deep.equal({
|
|
979
|
+
omidpn: 'Appnexus',
|
|
980
|
+
omidpv: '$prebid.version$'
|
|
981
|
+
});
|
|
982
|
+
expect(payload.tags[0].banner_frameworks).to.be.an('array');
|
|
983
|
+
expect(payload.tags[0].banner_frameworks).to.deep.equal([1, 2, 5, 6]);
|
|
984
|
+
expect(payload.tags[0].video_frameworks).to.be.an('array');
|
|
985
|
+
expect(payload.tags[0].video_frameworks).to.deep.equal([1, 2, 5, 6]);
|
|
986
|
+
expect(payload.tags[0].video.frameworks).to.not.exist;
|
|
987
|
+
|
|
988
|
+
// without bid.params.frameworks
|
|
989
|
+
const bidRequest_B = Object.assign({}, bidRequests[0]);
|
|
990
|
+
request = spec.buildRequests([bidRequest_B])[1];
|
|
991
|
+
payload = JSON.parse(request.data);
|
|
992
|
+
expect(payload.iab_support).to.not.exist;
|
|
993
|
+
expect(payload.tags[0].banner_frameworks).to.not.exist;
|
|
994
|
+
expect(payload.tags[0].video_frameworks).to.not.exist;
|
|
995
|
+
|
|
996
|
+
// with video.frameworks but it is not an array
|
|
997
|
+
const bidRequest_C = Object.assign({}, bidRequests[0], {
|
|
998
|
+
params: {
|
|
999
|
+
video: {
|
|
1000
|
+
frameworks: "'1', '2', '3', '6'"
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
});
|
|
1004
|
+
request = spec.buildRequests([bidRequest_C])[1];
|
|
1005
|
+
payload = JSON.parse(request.data);
|
|
1006
|
+
expect(payload.iab_support).to.not.exist;
|
|
1007
|
+
expect(payload.tags[0].banner_frameworks).to.not.exist;
|
|
1008
|
+
expect(payload.tags[0].video_frameworks).to.not.exist;
|
|
1009
|
+
});
|
|
1010
|
+
})
|
|
1011
|
+
|
|
1012
|
+
describe('interpretResponse', function () {
|
|
1013
|
+
let bfStub;
|
|
1014
|
+
before(function() {
|
|
1015
|
+
bfStub = sinon.stub(bidderFactory, 'getIabSubCategory');
|
|
1016
|
+
});
|
|
1017
|
+
|
|
1018
|
+
after(function() {
|
|
1019
|
+
bfStub.restore();
|
|
1020
|
+
});
|
|
1021
|
+
|
|
1022
|
+
let response = {
|
|
1023
|
+
'version': '3.0.0',
|
|
1024
|
+
'tags': [
|
|
1025
|
+
{
|
|
1026
|
+
'uuid': '3db3773286ee59',
|
|
1027
|
+
'tag_id': 10433394,
|
|
1028
|
+
'auction_id': '4534722592064951574',
|
|
1029
|
+
'nobid': false,
|
|
1030
|
+
'no_ad_url': 'https://lax1-ib.adnxs.com/no-ad',
|
|
1031
|
+
'timeout_ms': 10000,
|
|
1032
|
+
'ad_profile_id': 27079,
|
|
1033
|
+
'ads': [
|
|
1034
|
+
{
|
|
1035
|
+
'content_source': 'rtb',
|
|
1036
|
+
'ad_type': 'banner',
|
|
1037
|
+
'buyer_member_id': 958,
|
|
1038
|
+
'creative_id': 29681110,
|
|
1039
|
+
'media_type_id': 1,
|
|
1040
|
+
'media_subtype_id': 1,
|
|
1041
|
+
'cpm': 0.5,
|
|
1042
|
+
'cpm_publisher_currency': 0.5,
|
|
1043
|
+
'publisher_currency_code': '$',
|
|
1044
|
+
'client_initiated_ad_counting': true,
|
|
1045
|
+
'viewability': {
|
|
1046
|
+
'config': '<script type=\'text/javascript\' async=\'true\' src=\'https://cdn.adnxs.com/v/s/152/trk.js#v;vk=appnexus.com-omid;tv=native1-18h;dom_id=%native_dom_id%;st=0;d=1x1;vc=iab;vid_ccr=1;tag_id=13232354;cb=https%3A%2F%2Fams1-ib.adnxs.com%2Fvevent%3Freferrer%3Dhttps253A%252F%252Ftestpages-pmahe.tp.adnxs.net%252F01_basic_single%26e%3DwqT_3QLNB6DNAwAAAwDWAAUBCLfl_-MFEMStk8u3lPTjRxih88aF0fq_2QsqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlCDy74uWJzxW2AAaM26dXjzjwWAAQGKAQNVU0SSAQEG8FCYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NTE4ODkwNzkpO3VmKCdyJywgOTc0OTQ0MDM2HgDwjZIC8QEha0RXaXBnajgtTHdLRUlQTHZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWU1rR2FBQndMSGlrTDRBQlVvZ0JwQy1RQVFHWUFRR2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCbWo4dDA1ZU84VF9aQVFBQUEBAyRQQV80QUVBOVFFAQ4sQW1BSUFvQUlBdFFJBRAAdg0IeHdBSUF5QUlBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQVAFzIh1Z01KUVUxVE1UbzBNekl3NEFPVENBLi6aAmEhUXcxdGNRagUoEfQkblBGYklBUW9BRAl8AEEBqAREbzJEABRRSk1JU1EBGwRBQQGsAFURDAxBQUFXHQzwWNgCAOACrZhI6gIzaHR0cDovL3Rlc3RwYWdlcy1wbWFoZS50cC5hZG54cy5uZXQvMDFfYmFzaWNfc2luZ2xl8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAPExFQUZfTkFNRRIA8gIeCho2HQAIQVNUAT7wnElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgD8ao-4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECjEwLjIuMTIuMzioBIqpB7IEDggAEAEYACAAKAAwADgCuAQAwAQAyAQA0gQOOTMyNSNBTVMxOjQzMjDaBAIIAeAEAfAEg8u-LogFAZgFAKAF______8BAxgBwAUAyQUABQEU8D_SBQkJBQt8AAAA2AUB4AUB8AWZ9CH6BQQIABAAkAYBmAYAuAYAwQYBITAAAPA_yAYA2gYWChAAOgEAGBAAGADgBgw.%26s%3D971dce9d49b6bee447c8a58774fb30b40fe98171;ts=1551889079;cet=0;cecb=\'></script>'
|
|
1047
|
+
},
|
|
1048
|
+
'rtb': {
|
|
1049
|
+
'banner': {
|
|
1050
|
+
'content': '<!-- Creative -->',
|
|
1051
|
+
'width': 300,
|
|
1052
|
+
'height': 250
|
|
1053
|
+
},
|
|
1054
|
+
'trackers': [
|
|
1055
|
+
{
|
|
1056
|
+
'impression_urls': [
|
|
1057
|
+
'https://lax1-ib.adnxs.com/impression'
|
|
1058
|
+
],
|
|
1059
|
+
'video_events': {}
|
|
1060
|
+
}
|
|
1061
|
+
]
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
]
|
|
1065
|
+
}
|
|
1066
|
+
]
|
|
1067
|
+
};
|
|
1068
|
+
|
|
1069
|
+
it('should get correct bid response', function () {
|
|
1070
|
+
let expectedResponse = [
|
|
1071
|
+
{
|
|
1072
|
+
'requestId': '3db3773286ee59',
|
|
1073
|
+
'cpm': 0.5,
|
|
1074
|
+
'creativeId': 29681110,
|
|
1075
|
+
'dealId': undefined,
|
|
1076
|
+
'width': 300,
|
|
1077
|
+
'height': 250,
|
|
1078
|
+
'ad': '<!-- Creative -->',
|
|
1079
|
+
'mediaType': 'banner',
|
|
1080
|
+
'currency': 'USD',
|
|
1081
|
+
'ttl': 300,
|
|
1082
|
+
'netRevenue': true,
|
|
1083
|
+
'adUnitCode': 'code',
|
|
1084
|
+
'appnexus': {
|
|
1085
|
+
'buyerMemberId': 958
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
];
|
|
1089
|
+
let bidderRequest = {
|
|
1090
|
+
bids: [{
|
|
1091
|
+
bidId: '3db3773286ee59',
|
|
1092
|
+
adUnitCode: 'code'
|
|
1093
|
+
}]
|
|
1094
|
+
}
|
|
1095
|
+
let result = spec.interpretResponse({ body: response }, {bidderRequest});
|
|
1096
|
+
expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0]));
|
|
1097
|
+
});
|
|
1098
|
+
|
|
1099
|
+
it('handles nobid responses', function () {
|
|
1100
|
+
let response = {
|
|
1101
|
+
'version': '0.0.1',
|
|
1102
|
+
'tags': [{
|
|
1103
|
+
'uuid': '84ab500420319d',
|
|
1104
|
+
'tag_id': 5976557,
|
|
1105
|
+
'auction_id': '297492697822162468',
|
|
1106
|
+
'nobid': true
|
|
1107
|
+
}]
|
|
1108
|
+
};
|
|
1109
|
+
let bidderRequest;
|
|
1110
|
+
|
|
1111
|
+
let result = spec.interpretResponse({ body: response }, {bidderRequest});
|
|
1112
|
+
expect(result.length).to.equal(0);
|
|
1113
|
+
});
|
|
1114
|
+
|
|
1115
|
+
it('handles outstream video responses', function () {
|
|
1116
|
+
let response = {
|
|
1117
|
+
'tags': [{
|
|
1118
|
+
'uuid': '84ab500420319d',
|
|
1119
|
+
'ads': [{
|
|
1120
|
+
'ad_type': 'video',
|
|
1121
|
+
'cpm': 0.500000,
|
|
1122
|
+
'notify_url': 'imptracker.com',
|
|
1123
|
+
'rtb': {
|
|
1124
|
+
'video': {
|
|
1125
|
+
'content': '<!-- VAST Creative -->'
|
|
1126
|
+
}
|
|
1127
|
+
},
|
|
1128
|
+
'javascriptTrackers': '<script type=\'text/javascript\' async=\'true\' src=\'https://cdn.adnxs.com/v/s/152/trk.js#v;vk=appnexus.com-omid;tv=native1-18h;dom_id=%native_dom_id%;st=0;d=1x1;vc=iab;vid_ccr=1;tag_id=13232354;cb=https%3A%2F%2Fams1-ib.adnxs.com%2Fvevent%3Freferrer%3Dhttps253A%252F%252Ftestpages-pmahe.tp.adnxs.net%252F01_basic_single%26e%3DwqT_3QLNB6DNAwAAAwDWAAUBCLfl_-MFEMStk8u3lPTjRxih88aF0fq_2QsqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlCDy74uWJzxW2AAaM26dXjzjwWAAQGKAQNVU0SSAQEG8FCYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NTE4ODkwNzkpO3VmKCdyJywgOTc0OTQ0MDM2HgDwjZIC8QEha0RXaXBnajgtTHdLRUlQTHZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWU1rR2FBQndMSGlrTDRBQlVvZ0JwQy1RQVFHWUFRR2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCbWo4dDA1ZU84VF9aQVFBQUEBAyRQQV80QUVBOVFFAQ4sQW1BSUFvQUlBdFFJBRAAdg0IeHdBSUF5QUlBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQVAFzIh1Z01KUVUxVE1UbzBNekl3NEFPVENBLi6aAmEhUXcxdGNRagUoEfQkblBGYklBUW9BRAl8AEEBqAREbzJEABRRSk1JU1EBGwRBQQGsAFURDAxBQUFXHQzwWNgCAOACrZhI6gIzaHR0cDovL3Rlc3RwYWdlcy1wbWFoZS50cC5hZG54cy5uZXQvMDFfYmFzaWNfc2luZ2xl8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAPExFQUZfTkFNRRIA8gIeCho2HQAIQVNUAT7wnElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgD8ao-4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECjEwLjIuMTIuMzioBIqpB7IEDggAEAEYACAAKAAwADgCuAQAwAQAyAQA0gQOOTMyNSNBTVMxOjQzMjDaBAIIAeAEAfAEg8u-LogFAZgFAKAF______8BAxgBwAUAyQUABQEU8D_SBQkJBQt8AAAA2AUB4AUB8AWZ9CH6BQQIABAAkAYBmAYAuAYAwQYBITAAAPA_yAYA2gYWChAAOgEAGBAAGADgBgw.%26s%3D971dce9d49b6bee447c8a58774fb30b40fe98171;ts=1551889079;cet=0;cecb=\'></script>'
|
|
1129
|
+
}]
|
|
1130
|
+
}]
|
|
1131
|
+
};
|
|
1132
|
+
let bidderRequest = {
|
|
1133
|
+
bids: [{
|
|
1134
|
+
bidId: '84ab500420319d',
|
|
1135
|
+
adUnitCode: 'code',
|
|
1136
|
+
mediaTypes: {
|
|
1137
|
+
video: {
|
|
1138
|
+
context: 'outstream'
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
}]
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
let result = spec.interpretResponse({ body: response }, {bidderRequest});
|
|
1145
|
+
expect(result[0]).to.have.property('vastXml');
|
|
1146
|
+
expect(result[0]).to.have.property('vastImpUrl');
|
|
1147
|
+
expect(result[0]).to.have.property('mediaType', 'video');
|
|
1148
|
+
});
|
|
1149
|
+
|
|
1150
|
+
it('handles instream video responses', function () {
|
|
1151
|
+
let response = {
|
|
1152
|
+
'tags': [{
|
|
1153
|
+
'uuid': '84ab500420319d',
|
|
1154
|
+
'ads': [{
|
|
1155
|
+
'ad_type': 'video',
|
|
1156
|
+
'cpm': 0.500000,
|
|
1157
|
+
'notify_url': 'imptracker.com',
|
|
1158
|
+
'rtb': {
|
|
1159
|
+
'video': {
|
|
1160
|
+
'asset_url': 'https://sample.vastURL.com/here/vid'
|
|
1161
|
+
}
|
|
1162
|
+
},
|
|
1163
|
+
'javascriptTrackers': '<script type=\'text/javascript\' async=\'true\' src=\'https://cdn.adnxs.com/v/s/152/trk.js#v;vk=appnexus.com-omid;tv=native1-18h;dom_id=%native_dom_id%;st=0;d=1x1;vc=iab;vid_ccr=1;tag_id=13232354;cb=https%3A%2F%2Fams1-ib.adnxs.com%2Fvevent%3Freferrer%3Dhttps253A%252F%252Ftestpages-pmahe.tp.adnxs.net%252F01_basic_single%26e%3DwqT_3QLNB6DNAwAAAwDWAAUBCLfl_-MFEMStk8u3lPTjRxih88aF0fq_2QsqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlCDy74uWJzxW2AAaM26dXjzjwWAAQGKAQNVU0SSAQEG8FCYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NTE4ODkwNzkpO3VmKCdyJywgOTc0OTQ0MDM2HgDwjZIC8QEha0RXaXBnajgtTHdLRUlQTHZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWU1rR2FBQndMSGlrTDRBQlVvZ0JwQy1RQVFHWUFRR2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCbWo4dDA1ZU84VF9aQVFBQUEBAyRQQV80QUVBOVFFAQ4sQW1BSUFvQUlBdFFJBRAAdg0IeHdBSUF5QUlBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQVAFzIh1Z01KUVUxVE1UbzBNekl3NEFPVENBLi6aAmEhUXcxdGNRagUoEfQkblBGYklBUW9BRAl8AEEBqAREbzJEABRRSk1JU1EBGwRBQQGsAFURDAxBQUFXHQzwWNgCAOACrZhI6gIzaHR0cDovL3Rlc3RwYWdlcy1wbWFoZS50cC5hZG54cy5uZXQvMDFfYmFzaWNfc2luZ2xl8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAPExFQUZfTkFNRRIA8gIeCho2HQAIQVNUAT7wnElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgD8ao-4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECjEwLjIuMTIuMzioBIqpB7IEDggAEAEYACAAKAAwADgCuAQAwAQAyAQA0gQOOTMyNSNBTVMxOjQzMjDaBAIIAeAEAfAEg8u-LogFAZgFAKAF______8BAxgBwAUAyQUABQEU8D_SBQkJBQt8AAAA2AUB4AUB8AWZ9CH6BQQIABAAkAYBmAYAuAYAwQYBITAAAPA_yAYA2gYWChAAOgEAGBAAGADgBgw.%26s%3D971dce9d49b6bee447c8a58774fb30b40fe98171;ts=1551889079;cet=0;cecb=\'></script>'
|
|
1164
|
+
}]
|
|
1165
|
+
}]
|
|
1166
|
+
};
|
|
1167
|
+
let bidderRequest = {
|
|
1168
|
+
bids: [{
|
|
1169
|
+
bidId: '84ab500420319d',
|
|
1170
|
+
adUnitCode: 'code',
|
|
1171
|
+
mediaTypes: {
|
|
1172
|
+
video: {
|
|
1173
|
+
context: 'instream'
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
}]
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
let result = spec.interpretResponse({ body: response }, {bidderRequest});
|
|
1180
|
+
expect(result[0]).to.have.property('vastUrl');
|
|
1181
|
+
expect(result[0]).to.have.property('vastImpUrl');
|
|
1182
|
+
expect(result[0]).to.have.property('mediaType', 'video');
|
|
1183
|
+
});
|
|
1184
|
+
|
|
1185
|
+
it('handles adpod responses', function () {
|
|
1186
|
+
let response = {
|
|
1187
|
+
'tags': [{
|
|
1188
|
+
'uuid': '84ab500420319d',
|
|
1189
|
+
'ads': [{
|
|
1190
|
+
'ad_type': 'video',
|
|
1191
|
+
'brand_category_id': 10,
|
|
1192
|
+
'cpm': 0.500000,
|
|
1193
|
+
'notify_url': 'imptracker.com',
|
|
1194
|
+
'rtb': {
|
|
1195
|
+
'video': {
|
|
1196
|
+
'asset_url': 'https://sample.vastURL.com/here/adpod',
|
|
1197
|
+
'duration_ms': 30000,
|
|
1198
|
+
}
|
|
1199
|
+
},
|
|
1200
|
+
'viewability': {
|
|
1201
|
+
'config': '<script type=\'text/javascript\' async=\'true\' src=\'https://cdn.adnxs.com/v/s/152/trk.js#v;vk=appnexus.com-omid;tv=native1-18h;dom_id=%native_dom_id%;st=0;d=1x1;vc=iab;vid_ccr=1;tag_id=13232354;cb=https%3A%2F%2Fams1-ib.adnxs.com%2Fvevent%3Freferrer%3Dhttps253A%252F%252Ftestpages-pmahe.tp.adnxs.net%252F01_basic_single%26e%3DwqT_3QLNB6DNAwAAAwDWAAUBCLfl_-MFEMStk8u3lPTjRxih88aF0fq_2QsqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlCDy74uWJzxW2AAaM26dXjzjwWAAQGKAQNVU0SSAQEG8FCYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NTE4ODkwNzkpO3VmKCdyJywgOTc0OTQ0MDM2HgDwjZIC8QEha0RXaXBnajgtTHdLRUlQTHZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWU1rR2FBQndMSGlrTDRBQlVvZ0JwQy1RQVFHWUFRR2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCbWo4dDA1ZU84VF9aQVFBQUEBAyRQQV80QUVBOVFFAQ4sQW1BSUFvQUlBdFFJBRAAdg0IeHdBSUF5QUlBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQVAFzIh1Z01KUVUxVE1UbzBNekl3NEFPVENBLi6aAmEhUXcxdGNRagUoEfQkblBGYklBUW9BRAl8AEEBqAREbzJEABRRSk1JU1EBGwRBQQGsAFURDAxBQUFXHQzwWNgCAOACrZhI6gIzaHR0cDovL3Rlc3RwYWdlcy1wbWFoZS50cC5hZG54cy5uZXQvMDFfYmFzaWNfc2luZ2xl8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAPExFQUZfTkFNRRIA8gIeCho2HQAIQVNUAT7wnElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgD8ao-4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECjEwLjIuMTIuMzioBIqpB7IEDggAEAEYACAAKAAwADgCuAQAwAQAyAQA0gQOOTMyNSNBTVMxOjQzMjDaBAIIAeAEAfAEg8u-LogFAZgFAKAF______8BAxgBwAUAyQUABQEU8D_SBQkJBQt8AAAA2AUB4AUB8AWZ9CH6BQQIABAAkAYBmAYAuAYAwQYBITAAAPA_yAYA2gYWChAAOgEAGBAAGADgBgw.%26s%3D971dce9d49b6bee447c8a58774fb30b40fe98171;ts=1551889079;cet=0;cecb=\'></script>'
|
|
1202
|
+
}
|
|
1203
|
+
}]
|
|
1204
|
+
}]
|
|
1205
|
+
};
|
|
1206
|
+
|
|
1207
|
+
let bidderRequest = {
|
|
1208
|
+
bids: [{
|
|
1209
|
+
bidId: '84ab500420319d',
|
|
1210
|
+
adUnitCode: 'code',
|
|
1211
|
+
mediaTypes: {
|
|
1212
|
+
video: {
|
|
1213
|
+
context: 'adpod'
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
}]
|
|
1217
|
+
};
|
|
1218
|
+
bfStub.returns('1');
|
|
1219
|
+
|
|
1220
|
+
let result = spec.interpretResponse({ body: response }, {bidderRequest});
|
|
1221
|
+
expect(result[0]).to.have.property('vastUrl');
|
|
1222
|
+
expect(result[0].video.context).to.equal('adpod');
|
|
1223
|
+
expect(result[0].video.durationSeconds).to.equal(30);
|
|
1224
|
+
});
|
|
1225
|
+
|
|
1226
|
+
it('handles native responses', function () {
|
|
1227
|
+
let response1 = deepClone(response);
|
|
1228
|
+
response1.tags[0].ads[0].ad_type = 'native';
|
|
1229
|
+
response1.tags[0].ads[0].rtb.native = {
|
|
1230
|
+
'title': 'Native Creative',
|
|
1231
|
+
'desc': 'Cool description great stuff',
|
|
1232
|
+
'desc2': 'Additional body text',
|
|
1233
|
+
'ctatext': 'Do it',
|
|
1234
|
+
'sponsored': 'AppNexus',
|
|
1235
|
+
'icon': {
|
|
1236
|
+
'width': 0,
|
|
1237
|
+
'height': 0,
|
|
1238
|
+
'url': 'https://cdn.adnxs.com/icon.png'
|
|
1239
|
+
},
|
|
1240
|
+
'main_img': {
|
|
1241
|
+
'width': 2352,
|
|
1242
|
+
'height': 1516,
|
|
1243
|
+
'url': 'https://cdn.adnxs.com/img.png'
|
|
1244
|
+
},
|
|
1245
|
+
'link': {
|
|
1246
|
+
'url': 'https://www.appnexus.com',
|
|
1247
|
+
'fallback_url': '',
|
|
1248
|
+
'click_trackers': ['https://nym1-ib.adnxs.com/click']
|
|
1249
|
+
},
|
|
1250
|
+
'impression_trackers': ['https://example.com'],
|
|
1251
|
+
'rating': '5',
|
|
1252
|
+
'displayurl': 'https://AppNexus.com/?url=display_url',
|
|
1253
|
+
'likes': '38908320',
|
|
1254
|
+
'downloads': '874983',
|
|
1255
|
+
'price': '9.99',
|
|
1256
|
+
'saleprice': 'FREE',
|
|
1257
|
+
'phone': '1234567890',
|
|
1258
|
+
'address': '28 W 23rd St, New York, NY 10010',
|
|
1259
|
+
'privacy_link': 'https://appnexus.com/?url=privacy_url',
|
|
1260
|
+
'javascriptTrackers': '<script type=\'text/javascript\' async=\'true\' src=\'https://cdn.adnxs.com/v/s/152/trk.js#v;vk=appnexus.com-omid;tv=native1-18h;dom_id=;css_selector=.pb-click;st=0;d=1x1;vc=iab;vid_ccr=1;tag_id=13232354;cb=https%3A%2F%2Fams1-ib.adnxs.com%2Fvevent%3Freferrer%3Dhttps253A%252F%252Ftestpages-pmahe.tp.adnxs.net%252F01_basic_single%26e%3DwqT_3QLNB6DNAwAAAwDWAAUBCLfl_-MFEMStk8u3lPTjRxih88aF0fq_2QsqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlCDy74uWJzxW2AAaM26dXjzjwWAAQGKAQNVU0SSAQEG8FCYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NTE4ODkwNzkpO3VmKCdyJywgOTc0OTQ0MDM2HgDwjZIC8QEha0RXaXBnajgtTHdLRUlQTHZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWU1rR2FBQndMSGlrTDRBQlVvZ0JwQy1RQVFHWUFRR2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCbWo4dDA1ZU84VF9aQVFBQUEBAyRQQV80QUVBOVFFAQ4sQW1BSUFvQUlBdFFJBRAAdg0IeHdBSUF5QUlBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQVAFzIh1Z01KUVUxVE1UbzBNekl3NEFPVENBLi6aAmEhUXcxdGNRagUoEfQkblBGYklBUW9BRAl8AEEBqAREbzJEABRRSk1JU1EBGwRBQQGsAFURDAxBQUFXHQzwWNgCAOACrZhI6gIzaHR0cDovL3Rlc3RwYWdlcy1wbWFoZS50cC5hZG54cy5uZXQvMDFfYmFzaWNfc2luZ2xl8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAPExFQUZfTkFNRRIA8gIeCho2HQAIQVNUAT7wnElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgD8ao-4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECjEwLjIuMTIuMzioBIqpB7IEDggAEAEYACAAKAAwADgCuAQAwAQAyAQA0gQOOTMyNSNBTVMxOjQzMjDaBAIIAeAEAfAEg8u-LogFAZgFAKAF______8BAxgBwAUAyQUABQEU8D_SBQkJBQt8AAAA2AUB4AUB8AWZ9CH6BQQIABAAkAYBmAYAuAYAwQYBITAAAPA_yAYA2gYWChAAOgEAGBAAGADgBgw.%26s%3D971dce9d49b6bee447c8a58774fb30b40fe98171;ts=1551889079;cet=0;cecb=\'></script>'
|
|
1261
|
+
};
|
|
1262
|
+
let bidderRequest = {
|
|
1263
|
+
bids: [{
|
|
1264
|
+
bidId: '3db3773286ee59',
|
|
1265
|
+
adUnitCode: 'code'
|
|
1266
|
+
}]
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
let result = spec.interpretResponse({ body: response1 }, {bidderRequest});
|
|
1270
|
+
expect(result[0].native.title).to.equal('Native Creative');
|
|
1271
|
+
expect(result[0].native.body).to.equal('Cool description great stuff');
|
|
1272
|
+
expect(result[0].native.cta).to.equal('Do it');
|
|
1273
|
+
expect(result[0].native.image.url).to.equal('https://cdn.adnxs.com/img.png');
|
|
1274
|
+
});
|
|
1275
|
+
|
|
1276
|
+
it('supports configuring outstream renderers', function () {
|
|
1277
|
+
const outstreamResponse = deepClone(response);
|
|
1278
|
+
outstreamResponse.tags[0].ads[0].rtb.video = {};
|
|
1279
|
+
outstreamResponse.tags[0].ads[0].renderer_url = 'renderer.js';
|
|
1280
|
+
|
|
1281
|
+
const bidderRequest = {
|
|
1282
|
+
bids: [{
|
|
1283
|
+
bidId: '3db3773286ee59',
|
|
1284
|
+
renderer: {
|
|
1285
|
+
options: {
|
|
1286
|
+
adText: 'configured'
|
|
1287
|
+
}
|
|
1288
|
+
},
|
|
1289
|
+
mediaTypes: {
|
|
1290
|
+
video: {
|
|
1291
|
+
context: 'outstream'
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
}]
|
|
1295
|
+
};
|
|
1296
|
+
|
|
1297
|
+
const result = spec.interpretResponse({ body: outstreamResponse }, {bidderRequest});
|
|
1298
|
+
expect(result[0].renderer.config).to.deep.equal(
|
|
1299
|
+
bidderRequest.bids[0].renderer.options
|
|
1300
|
+
);
|
|
1301
|
+
});
|
|
1302
|
+
|
|
1303
|
+
it('should add deal_priority and deal_code', function() {
|
|
1304
|
+
let responseWithDeal = deepClone(response);
|
|
1305
|
+
responseWithDeal.tags[0].ads[0].ad_type = 'video';
|
|
1306
|
+
responseWithDeal.tags[0].ads[0].deal_priority = 5;
|
|
1307
|
+
responseWithDeal.tags[0].ads[0].deal_code = '123';
|
|
1308
|
+
responseWithDeal.tags[0].ads[0].rtb.video = {
|
|
1309
|
+
duration_ms: 1500,
|
|
1310
|
+
player_width: 640,
|
|
1311
|
+
player_height: 340,
|
|
1312
|
+
};
|
|
1313
|
+
|
|
1314
|
+
let bidderRequest = {
|
|
1315
|
+
bids: [{
|
|
1316
|
+
bidId: '3db3773286ee59',
|
|
1317
|
+
adUnitCode: 'code',
|
|
1318
|
+
mediaTypes: {
|
|
1319
|
+
video: {
|
|
1320
|
+
context: 'adpod'
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
}]
|
|
1324
|
+
}
|
|
1325
|
+
let result = spec.interpretResponse({ body: responseWithDeal }, {bidderRequest});
|
|
1326
|
+
expect(Object.keys(result[0].appnexus)).to.include.members(['buyerMemberId', 'dealPriority', 'dealCode']);
|
|
1327
|
+
expect(result[0].video.dealTier).to.equal(5);
|
|
1328
|
+
});
|
|
1329
|
+
|
|
1330
|
+
it('should add advertiser id', function() {
|
|
1331
|
+
let responseAdvertiserId = deepClone(response);
|
|
1332
|
+
responseAdvertiserId.tags[0].ads[0].advertiser_id = '123';
|
|
1333
|
+
|
|
1334
|
+
let bidderRequest = {
|
|
1335
|
+
bids: [{
|
|
1336
|
+
bidId: '3db3773286ee59',
|
|
1337
|
+
adUnitCode: 'code'
|
|
1338
|
+
}]
|
|
1339
|
+
}
|
|
1340
|
+
let result = spec.interpretResponse({ body: responseAdvertiserId }, {bidderRequest});
|
|
1341
|
+
expect(Object.keys(result[0].meta)).to.include.members(['advertiserId']);
|
|
1342
|
+
});
|
|
1343
|
+
|
|
1344
|
+
it('should add advertiserDomains', function() {
|
|
1345
|
+
let responseAdvertiserId = deepClone(response);
|
|
1346
|
+
responseAdvertiserId.tags[0].ads[0].adomain = ['123'];
|
|
1347
|
+
|
|
1348
|
+
let bidderRequest = {
|
|
1349
|
+
bids: [{
|
|
1350
|
+
bidId: '3db3773286ee59',
|
|
1351
|
+
adUnitCode: 'code'
|
|
1352
|
+
}]
|
|
1353
|
+
}
|
|
1354
|
+
let result = spec.interpretResponse({ body: responseAdvertiserId }, {bidderRequest});
|
|
1355
|
+
expect(Object.keys(result[0].meta)).to.include.members(['advertiserDomains']);
|
|
1356
|
+
expect(Object.keys(result[0].meta.advertiserDomains)).to.deep.equal([]);
|
|
1357
|
+
});
|
|
1358
|
+
});
|
|
1359
|
+
});
|