prebid.js 5.17.0 → 6.0.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/.babelrc.js +3 -6
- package/README.md +3 -1
- package/browsers.json +1 -8
- package/integrationExamples/gpt/akamaidap_segments_example.html +132 -0
- package/modules/.submodules.json +1 -0
- package/modules/adfBidAdapter.js +21 -16
- package/modules/adgenerationBidAdapter.js +28 -4
- package/modules/adkernelBidAdapter.js +2 -1
- package/modules/admixerBidAdapter.js +11 -0
- package/modules/adtelligentBidAdapter.js +2 -1
- package/modules/airgridRtdProvider.js +1 -1
- package/modules/akamaiDapRtdProvider.js +474 -0
- package/modules/akamaiDapRtdProvider.md +47 -0
- package/modules/aolBidAdapter.js +2 -1
- package/modules/appnexusBidAdapter.js +5 -3
- package/modules/atsAnalyticsAdapter.js +67 -46
- package/modules/atsAnalyticsAdapter.md +1 -0
- package/modules/betweenBidAdapter.js +20 -3
- package/modules/bliinkBidAdapter.js +58 -32
- package/modules/bliinkBidAdapter.md +29 -6
- package/modules/browsiRtdProvider.js +106 -18
- package/modules/cleanioRtdProvider.js +192 -0
- package/modules/cleanioRtdProvider.md +59 -0
- package/modules/codefuelBidAdapter.js +183 -0
- package/modules/codefuelBidAdapter.md +111 -0
- package/modules/connectIdSystem.js +104 -0
- package/modules/connectIdSystem.md +33 -0
- package/modules/cwireBidAdapter.js +272 -0
- package/modules/cwireBidAdapter.md +43 -0
- package/modules/deepintentBidAdapter.js +106 -9
- package/modules/deepintentBidAdapter.md +36 -1
- package/modules/deltaprojectsBidAdapter.js +252 -0
- package/modules/deltaprojectsBidAdapter.md +32 -0
- package/modules/dgkeywordRtdProvider.js +0 -1
- package/modules/engageyaBidAdapter.js +157 -0
- package/modules/gridBidAdapter.js +1 -0
- package/modules/gumgumBidAdapter.js +8 -0
- package/modules/inskinBidAdapter.js +7 -3
- package/modules/ixBidAdapter.js +8 -1
- package/modules/jixieBidAdapter.js +8 -2
- package/modules/justpremiumBidAdapter.js +6 -1
- package/modules/limelightDigitalBidAdapter.js +22 -2
- package/modules/livewrappedAnalyticsAdapter.js +53 -3
- package/modules/mediakeysBidAdapter.js +2 -1
- package/modules/multibid/index.js +3 -3
- package/modules/nativoBidAdapter.js +6 -2
- package/modules/nextMillenniumBidAdapter.js +12 -3
- package/modules/oguryBidAdapter.js +36 -7
- package/modules/openxBidAdapter.js +34 -22
- package/modules/operaadsBidAdapter.js +21 -1
- package/modules/otmBidAdapter.js +146 -0
- package/modules/otmBidAdapter.md +27 -26
- package/modules/outbrainBidAdapter.js +5 -0
- package/modules/pixfutureBidAdapter.js +24 -4
- package/modules/pixfutureBidAdapter.md +127 -0
- package/modules/playwireBidAdapter.md +61 -0
- package/modules/prebidServerBidAdapter/index.js +1 -1
- package/modules/proxistoreBidAdapter.js +4 -6
- package/modules/publinkIdSystem.js +11 -6
- package/modules/pubmaticBidAdapter.js +9 -0
- package/modules/pubmaticBidAdapter.md +1 -1
- package/modules/rtdModule/index.js +2 -2
- package/modules/sonobiBidAdapter.js +7 -0
- package/modules/sortableBidAdapter.js +1 -0
- package/modules/talkadsBidAdapter.js +129 -0
- package/modules/talkadsBidAdapter.md +60 -0
- package/modules/teadsBidAdapter.js +3 -0
- package/modules/tripleliftBidAdapter.js +22 -5
- package/modules/trustxBidAdapter.js +8 -6
- package/modules/undertoneBidAdapter.js +9 -5
- package/modules/undertoneBidAdapter.md +5 -1
- package/modules/unicornBidAdapter.js +3 -3
- package/modules/userId/eids.js +18 -0
- package/modules/userId/eids.md +7 -0
- package/modules/userId/userId.md +12 -0
- package/modules/ventesBidAdapter.js +370 -0
- package/modules/ventesBidAdapter.md +94 -0
- package/modules/videobyteBidAdapter.js +13 -6
- package/modules/videobyteBidAdapter.md +49 -0
- package/modules/visxBidAdapter.js +15 -22
- package/modules/yahoosspBidAdapter.js +637 -0
- package/modules/yahoosspBidAdapter.md +795 -0
- package/modules/yieldlabBidAdapter.js +48 -3
- package/modules/yieldlabBidAdapter.md +16 -1
- package/modules/yieldmoSyntheticInventoryModule.js +46 -0
- package/modules/yieldmoSyntheticInventoryModule.md +68 -0
- package/package.json +1 -1
- package/src/adapterManager.js +5 -0
- package/src/adapters/bidderFactory.js +4 -3
- package/src/auction.js +11 -11
- package/src/constants.json +1 -0
- package/src/secureCreatives.js +6 -7
- package/src/targeting.js +11 -9
- package/test/spec/modules/adfBidAdapter_spec.js +83 -29
- package/test/spec/modules/adgenerationBidAdapter_spec.js +121 -50
- package/test/spec/modules/adtelligentBidAdapter_spec.js +1 -0
- package/test/spec/modules/akamaiDapRtdProvider_spec.js +246 -0
- package/test/spec/modules/appnexusBidAdapter_spec.js +2 -1
- package/test/spec/modules/atsAnalyticsAdapter_spec.js +42 -9
- package/test/spec/modules/betweenBidAdapter_spec.js +41 -0
- package/test/spec/modules/bliinkBidAdapter_spec.js +87 -36
- package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
- package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
- package/test/spec/modules/codefuelBidAdapter_spec.js +316 -0
- package/test/spec/modules/connectIdSystem_spec.js +189 -0
- package/test/spec/modules/cwireBidAdapter_spec.js +246 -0
- package/test/spec/modules/deepintentBidAdapter_spec.js +153 -3
- package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
- package/test/spec/modules/engageyaBidAdapter_spec.js +286 -0
- package/test/spec/modules/gumgumBidAdapter_spec.js +5 -1
- package/test/spec/modules/ixBidAdapter_spec.js +13 -3
- package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
- package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
- package/test/spec/modules/limelightDigitalBidAdapter_spec.js +155 -1
- package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +67 -12
- package/test/spec/modules/multibid_spec.js +31 -31
- package/test/spec/modules/nextMillenniumBidAdapter_spec.js +13 -1
- package/test/spec/modules/oguryBidAdapter_spec.js +125 -37
- package/test/spec/modules/openxBidAdapter_spec.js +85 -13
- package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
- package/test/spec/modules/otmBidAdapter_spec.js +67 -0
- package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
- package/test/spec/modules/publinkIdSystem_spec.js +6 -6
- package/test/spec/modules/pubmaticBidAdapter_spec.js +39 -1
- package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
- package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
- package/test/spec/modules/talkadsBidAdapter_spec.js +231 -0
- package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
- package/test/spec/modules/tripleliftBidAdapter_spec.js +128 -0
- package/test/spec/modules/trustxBidAdapter_spec.js +3 -3
- package/test/spec/modules/undertoneBidAdapter_spec.js +52 -0
- package/test/spec/modules/unicornBidAdapter_spec.js +4 -4
- package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
- package/test/spec/modules/videobyteBidAdapter_spec.js +2 -2
- package/test/spec/modules/visxBidAdapter_spec.js +48 -4
- package/test/spec/modules/yahoosspBidAdapter_spec.js +1332 -0
- package/test/spec/modules/yieldlabBidAdapter_spec.js +65 -1
- package/test/spec/modules/yieldmoSyntheticInventoryModule_spec.js +89 -0
- package/test/spec/unit/core/adapterManager_spec.js +32 -0
- package/test/spec/unit/core/bidderFactory_spec.js +61 -1
- package/test/spec/unit/pbjs_api_spec.js +37 -2
- package/test/spec/unit/secureCreatives_spec.js +54 -25
- package/wdio.conf.js +1 -1
- package/modules/turktelekomBidAdapter.md +0 -49
- package/yarn.lock +0 -13122
|
@@ -0,0 +1,1332 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { config } from 'src/config.js';
|
|
3
|
+
import { BANNER, VIDEO } from 'src/mediaTypes.js';
|
|
4
|
+
import { spec } from 'modules/yahoosspBidAdapter.js';
|
|
5
|
+
|
|
6
|
+
const DEFAULT_BID_ID = '84ab500420319d';
|
|
7
|
+
const DEFAULT_BID_DCN = '2093845709823475';
|
|
8
|
+
const DEFAULT_BID_POS = 'header';
|
|
9
|
+
const DEFAULT_PUBID = 'PubId';
|
|
10
|
+
const DEFAULT_AD_UNIT_CODE = '/19968336/header-bid-tag-1';
|
|
11
|
+
const DEFAULT_AD_UNIT_TYPE = 'banner';
|
|
12
|
+
const DEFAULT_PARAMS_BID_OVERRIDE = {};
|
|
13
|
+
const DEFAULT_VIDEO_CONTEXT = 'instream';
|
|
14
|
+
const ADAPTER_VERSION = '1.0.1';
|
|
15
|
+
const PREBID_VERSION = '$prebid.version$';
|
|
16
|
+
const INTEGRATION_METHOD = 'prebid.js';
|
|
17
|
+
|
|
18
|
+
// Utility functions
|
|
19
|
+
const generateBidRequest = ({bidId, pos, adUnitCode, adUnitType, bidOverrideObject, videoContext, pubIdMode}) => {
|
|
20
|
+
const bidRequest = {
|
|
21
|
+
adUnitCode,
|
|
22
|
+
auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917',
|
|
23
|
+
bidId,
|
|
24
|
+
bidderRequestsCount: 1,
|
|
25
|
+
bidder: 'yahoossp',
|
|
26
|
+
bidderRequestId: '7101db09af0db2',
|
|
27
|
+
bidderWinsCount: 0,
|
|
28
|
+
mediaTypes: {},
|
|
29
|
+
params: {
|
|
30
|
+
bidOverride: bidOverrideObject
|
|
31
|
+
},
|
|
32
|
+
src: 'client',
|
|
33
|
+
transactionId: '5b17b67d-7704-4732-8cc9-5b1723e9bcf9'
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const bannerObj = {
|
|
37
|
+
sizes: [[300, 250], [300, 600]]
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const videoObject = {
|
|
41
|
+
context: videoContext,
|
|
42
|
+
playerSize: [[300, 250]],
|
|
43
|
+
mimes: ['video/mp4', 'application/javascript'],
|
|
44
|
+
api: [2]
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
if (videoContext === 'outstream') {
|
|
48
|
+
bidRequest.renderer = undefined
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
if (adUnitType === 'banner' || adUnitType === 'dap-o2' || adUnitType === 'dap-up') {
|
|
52
|
+
bidRequest.mediaTypes.banner = bannerObj;
|
|
53
|
+
bidRequest.sizes = [[300, 250], [300, 600]];
|
|
54
|
+
} else if (adUnitType === 'video') {
|
|
55
|
+
bidRequest.mediaTypes.video = videoObject;
|
|
56
|
+
} else if (adUnitType === 'multi-format') {
|
|
57
|
+
bidRequest.mediaTypes.banner = bannerObj;
|
|
58
|
+
bidRequest.sizes = [[300, 250], [300, 600]];
|
|
59
|
+
bidRequest.mediaTypes.video = videoObject;
|
|
60
|
+
} else if (adUnitType === 'native') {
|
|
61
|
+
bidRequest.mediaTypes.native = {a: 123, b: 456};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (pubIdMode === true) {
|
|
65
|
+
bidRequest.params.pubId = DEFAULT_PUBID;
|
|
66
|
+
} else {
|
|
67
|
+
bidRequest.params.dcn = DEFAULT_BID_DCN;
|
|
68
|
+
bidRequest.params.pos = pos || DEFAULT_BID_POS;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
return bidRequest;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let generateBidderRequest = (bidRequestArray, adUnitCode) => {
|
|
75
|
+
const bidderRequest = {
|
|
76
|
+
adUnitCode: adUnitCode || 'default-adUnitCode',
|
|
77
|
+
auctionId: 'd4c83a3b-18e4-4208-b98b-63848449c7aa',
|
|
78
|
+
auctionStart: new Date().getTime(),
|
|
79
|
+
bidderCode: 'yahoossp',
|
|
80
|
+
bidderRequestId: '112f1c7c5d399a',
|
|
81
|
+
bids: bidRequestArray,
|
|
82
|
+
refererInfo: {
|
|
83
|
+
referer: 'https://publisher-test.com',
|
|
84
|
+
reachedTop: true,
|
|
85
|
+
isAmp: false,
|
|
86
|
+
numIframes: 0,
|
|
87
|
+
stack: ['https://publisher-test.com'],
|
|
88
|
+
},
|
|
89
|
+
gdprConsent: {
|
|
90
|
+
consentString: 'BOtmiBKOtmiBKABABAENAFAAAAACeAAA',
|
|
91
|
+
vendorData: {},
|
|
92
|
+
gdprApplies: true
|
|
93
|
+
},
|
|
94
|
+
start: new Date().getTime(),
|
|
95
|
+
timeout: 1000,
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
return bidderRequest;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const generateBuildRequestMock = ({bidId, pos, adUnitCode, adUnitType, bidOverrideObject, videoContext, pubIdMode}) => {
|
|
102
|
+
const bidRequestConfig = {
|
|
103
|
+
bidId: bidId || DEFAULT_BID_ID,
|
|
104
|
+
pos: pos || DEFAULT_BID_POS,
|
|
105
|
+
adUnitCode: adUnitCode || DEFAULT_AD_UNIT_CODE,
|
|
106
|
+
adUnitType: adUnitType || DEFAULT_AD_UNIT_TYPE,
|
|
107
|
+
bidOverrideObject: bidOverrideObject || DEFAULT_PARAMS_BID_OVERRIDE,
|
|
108
|
+
videoContext: videoContext || DEFAULT_VIDEO_CONTEXT,
|
|
109
|
+
pubIdMode: pubIdMode || false
|
|
110
|
+
};
|
|
111
|
+
const bidRequest = generateBidRequest(bidRequestConfig);
|
|
112
|
+
const validBidRequests = [bidRequest];
|
|
113
|
+
const bidderRequest = generateBidderRequest(validBidRequests, adUnitCode);
|
|
114
|
+
|
|
115
|
+
return { bidRequest, validBidRequests, bidderRequest }
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const generateAdmPayload = (admPayloadType) => {
|
|
119
|
+
let ADM_PAYLOAD;
|
|
120
|
+
switch (admPayloadType) {
|
|
121
|
+
case 'banner':
|
|
122
|
+
ADM_PAYLOAD = '<script>logInfo(\'ad\'); AdPlacement </script>'; // banner
|
|
123
|
+
break;
|
|
124
|
+
case 'video':
|
|
125
|
+
ADM_PAYLOAD = '<VAST></VAST>'; // VAST xml
|
|
126
|
+
break;
|
|
127
|
+
case 'multi-format':
|
|
128
|
+
const admPayloads = [
|
|
129
|
+
'<script>logInfo(\'ad\'); AdPlacement </script>', // banner
|
|
130
|
+
'<VAST></VAST>' // VAST xml
|
|
131
|
+
]
|
|
132
|
+
const random = Math.floor(Math.random() * admPayloads.length);
|
|
133
|
+
ADM_PAYLOAD = admPayloads[random]
|
|
134
|
+
break;
|
|
135
|
+
case 'dap-o2':
|
|
136
|
+
ADM_PAYLOAD = '<script>o2playerSettings</script>'; // O2 player
|
|
137
|
+
break;
|
|
138
|
+
case 'dap-up':
|
|
139
|
+
ADM_PAYLOAD = '<script>YAHOO.VideoPlatform.VideoPlayer</script>'; // Unified Player
|
|
140
|
+
break;
|
|
141
|
+
};
|
|
142
|
+
return ADM_PAYLOAD;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const generateResponseMock = (admPayloadType, vastVersion, videoContext) => {
|
|
146
|
+
const bidResponse = {
|
|
147
|
+
id: 'fc0c35df-21fb-4f93-9ebd-88759dbe31f9',
|
|
148
|
+
impid: '274395c06a24e5',
|
|
149
|
+
adm: generateAdmPayload(admPayloadType),
|
|
150
|
+
price: 1,
|
|
151
|
+
w: 300,
|
|
152
|
+
h: 250,
|
|
153
|
+
crid: 'ssp-placement-name',
|
|
154
|
+
adomain: ['advertiser-domain.com']
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
if (vastVersion === 'vast') {
|
|
158
|
+
bidResponse.nurl = 'https://yahoo.com?event=adAttempt';
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const serverResponse = {
|
|
162
|
+
body: {
|
|
163
|
+
id: 'fc0c35df-21fb-4f93-9ebd-88759dbe31f9',
|
|
164
|
+
seatbid: [{ bid: [ bidResponse ], seat: 13107 }]
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({adUnitType: admPayloadType, videoContext: videoContext});
|
|
168
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
169
|
+
|
|
170
|
+
return {serverResponse, data, bidderRequest};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Unit tests
|
|
174
|
+
describe('YahooSSP Bid Adapter:', () => {
|
|
175
|
+
it('PLACEHOLDER TO PASS GULP', () => {
|
|
176
|
+
const obj = {};
|
|
177
|
+
expect(obj).to.be.an('object');
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
describe('getUserSyncs()', () => {
|
|
181
|
+
const IMAGE_PIXEL_URL = 'http://image-pixel.com/foo/bar?1234&baz=true';
|
|
182
|
+
const IFRAME_ONE_URL = 'http://image-iframe.com/foo/bar?1234&baz=true';
|
|
183
|
+
const IFRAME_TWO_URL = 'http://image-iframe-two.com/foo/bar?1234&baz=true';
|
|
184
|
+
|
|
185
|
+
let serverResponses = [];
|
|
186
|
+
beforeEach(() => {
|
|
187
|
+
serverResponses[0] = {
|
|
188
|
+
body: {
|
|
189
|
+
ext: {
|
|
190
|
+
pixels: `<script>document.write('<iframe src="${IFRAME_ONE_URL}"></iframe>` +
|
|
191
|
+
`<img src="${IMAGE_PIXEL_URL}"></iframe>` +
|
|
192
|
+
`<iframe src="${IFRAME_TWO_URL}"></iframe>');</script>`
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
after(() => {
|
|
199
|
+
serverResponses = undefined;
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('for only iframe enabled syncs', () => {
|
|
203
|
+
let syncOptions = {
|
|
204
|
+
iframeEnabled: true,
|
|
205
|
+
pixelEnabled: false
|
|
206
|
+
};
|
|
207
|
+
let pixelsObjects = spec.getUserSyncs(syncOptions, serverResponses);
|
|
208
|
+
expect(pixelsObjects.length).to.equal(2);
|
|
209
|
+
expect(pixelsObjects).to.deep.equal(
|
|
210
|
+
[
|
|
211
|
+
{type: 'iframe', 'url': IFRAME_ONE_URL},
|
|
212
|
+
{type: 'iframe', 'url': IFRAME_TWO_URL}
|
|
213
|
+
]
|
|
214
|
+
)
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('for only pixel enabled syncs', () => {
|
|
218
|
+
let syncOptions = {
|
|
219
|
+
iframeEnabled: false,
|
|
220
|
+
pixelEnabled: true
|
|
221
|
+
};
|
|
222
|
+
let pixelsObjects = spec.getUserSyncs(syncOptions, serverResponses);
|
|
223
|
+
expect(pixelsObjects.length).to.equal(1);
|
|
224
|
+
expect(pixelsObjects).to.deep.equal(
|
|
225
|
+
[
|
|
226
|
+
{type: 'image', 'url': IMAGE_PIXEL_URL}
|
|
227
|
+
]
|
|
228
|
+
)
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('for both pixel and iframe enabled syncs', () => {
|
|
232
|
+
let syncOptions = {
|
|
233
|
+
iframeEnabled: true,
|
|
234
|
+
pixelEnabled: true
|
|
235
|
+
};
|
|
236
|
+
let pixelsObjects = spec.getUserSyncs(syncOptions, serverResponses);
|
|
237
|
+
expect(pixelsObjects.length).to.equal(3);
|
|
238
|
+
expect(pixelsObjects).to.deep.equal(
|
|
239
|
+
[
|
|
240
|
+
{type: 'iframe', 'url': IFRAME_ONE_URL},
|
|
241
|
+
{type: 'image', 'url': IMAGE_PIXEL_URL},
|
|
242
|
+
{type: 'iframe', 'url': IFRAME_TWO_URL}
|
|
243
|
+
]
|
|
244
|
+
)
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// Validate Bid Requests
|
|
249
|
+
describe('isBidRequestValid()', () => {
|
|
250
|
+
const INVALID_INPUT = [
|
|
251
|
+
{},
|
|
252
|
+
{params: {}},
|
|
253
|
+
{params: {dcn: '2c9d2b50015a5aa95b70a9b0b5b10012'}},
|
|
254
|
+
{params: {dcn: 1234, pos: 'header'}},
|
|
255
|
+
{params: {dcn: '2c9d2b50015a5aa95b70a9b0b5b10012', pos: 1234}},
|
|
256
|
+
{params: {dcn: '2c9d2b50015a5aa95b70a9b0b5b10012', pos: ''}},
|
|
257
|
+
{params: {dcn: '', pos: 'header'}},
|
|
258
|
+
];
|
|
259
|
+
|
|
260
|
+
INVALID_INPUT.forEach(input => {
|
|
261
|
+
it(`should determine that the bid is INVALID for the input ${JSON.stringify(input)}`, () => {
|
|
262
|
+
expect(spec.isBidRequestValid(input)).to.be.false;
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it('should determine that the bid is VALID if dcn and pos are present on the params object', () => {
|
|
267
|
+
const validBid = {
|
|
268
|
+
params: {
|
|
269
|
+
dcn: '2c9d2b50015a5aa95b70a9b0b5b10012',
|
|
270
|
+
pos: 'header'
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
expect(spec.isBidRequestValid(validBid)).to.be.true;
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('should mark bid as VALID if bid.params.testing.e2etest = "true" (dcn & pos not required)', () => {
|
|
277
|
+
const validBid = {
|
|
278
|
+
params: {
|
|
279
|
+
dcn: 8888,
|
|
280
|
+
pos: 9999,
|
|
281
|
+
testing: {
|
|
282
|
+
e2etest: true
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
expect(spec.isBidRequestValid(validBid)).to.be.true;
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
it('should mark bid ad VALID if pubId exists instead of dcn & pos', () => {
|
|
290
|
+
const validBid = {
|
|
291
|
+
params: {
|
|
292
|
+
pubId: DEFAULT_PUBID
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
expect(spec.isBidRequestValid(validBid)).to.be.true;
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
describe('Price Floor module support:', () => {
|
|
300
|
+
it('should get bidfloor from getFloor method', () => {
|
|
301
|
+
const { bidRequest, validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
302
|
+
bidRequest.params.bidOverride = {cur: 'EUR'};
|
|
303
|
+
bidRequest.getFloor = (floorObj) => {
|
|
304
|
+
return {
|
|
305
|
+
floor: bidRequest.floors.values[floorObj.mediaType + '|640x480'],
|
|
306
|
+
currency: floorObj.currency,
|
|
307
|
+
mediaType: floorObj.mediaType
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
bidRequest.floors = {
|
|
311
|
+
currency: 'EUR',
|
|
312
|
+
values: {
|
|
313
|
+
'banner|640x480': 5.55
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
317
|
+
expect(data.cur).to.deep.equal(['EUR']);
|
|
318
|
+
expect(data.imp[0].bidfloor).is.a('number');
|
|
319
|
+
expect(data.imp[0].bidfloor).to.equal(5.55);
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
describe('Schain module support:', () => {
|
|
324
|
+
it('should send Global or Bidder specific schain', function () {
|
|
325
|
+
const { bidRequest, validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
326
|
+
const globalSchain = {
|
|
327
|
+
ver: '1.0',
|
|
328
|
+
complete: 1,
|
|
329
|
+
nodes: [{
|
|
330
|
+
asi: 'some-platform.com',
|
|
331
|
+
sid: '111111',
|
|
332
|
+
rid: bidRequest.bidId,
|
|
333
|
+
hp: 1
|
|
334
|
+
}]
|
|
335
|
+
};
|
|
336
|
+
bidRequest.schain = globalSchain;
|
|
337
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
338
|
+
const schain = data.source.ext.schain;
|
|
339
|
+
expect(schain.nodes.length).to.equal(1);
|
|
340
|
+
expect(schain).to.equal(globalSchain);
|
|
341
|
+
});
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
describe('First party data module - "Site" support (ortb2):', () => {
|
|
345
|
+
// Should not allow invalid "site" data types
|
|
346
|
+
const INVALID_ORTB2_TYPES = [ null, [], 123, 'unsupportedKeyName', true, false, undefined ];
|
|
347
|
+
INVALID_ORTB2_TYPES.forEach(param => {
|
|
348
|
+
const ortb2 = { site: param }
|
|
349
|
+
config.setConfig({ortb2});
|
|
350
|
+
it(`should not allow invalid site types to be added to bid-request: ${JSON.stringify(param)}`, () => {
|
|
351
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
352
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
353
|
+
expect(data.site[param]).to.be.undefined;
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
// Should add valid "site" params
|
|
358
|
+
const VALID_SITE_STRINGS = ['name', 'domain', 'page', 'ref', 'keywords', 'search'];
|
|
359
|
+
const VALID_SITE_ARRAYS = ['cat', 'sectioncat', 'pagecat'];
|
|
360
|
+
|
|
361
|
+
VALID_SITE_STRINGS.forEach(param => {
|
|
362
|
+
it(`should allow supported site keys to be added bid-request: ${JSON.stringify(param)}`, () => {
|
|
363
|
+
const ortb2 = {
|
|
364
|
+
site: {
|
|
365
|
+
[param]: 'something'
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
config.setConfig({ortb2});
|
|
369
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
370
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
371
|
+
expect(data.site[param]).to.exist;
|
|
372
|
+
expect(data.site[param]).to.be.a('string');
|
|
373
|
+
expect(data.site[param]).to.be.equal(ortb2.site[param]);
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
VALID_SITE_ARRAYS.forEach(param => {
|
|
378
|
+
it(`should determine that the ortb2.site Array key is valid and append to the bid-request: ${JSON.stringify(param)}`, () => {
|
|
379
|
+
const ortb2 = {
|
|
380
|
+
site: {
|
|
381
|
+
[param]: ['something']
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
config.setConfig({ortb2});
|
|
385
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
386
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
387
|
+
expect(data.site[param]).to.exist;
|
|
388
|
+
expect(data.site[param]).to.be.a('array');
|
|
389
|
+
expect(data.site[param]).to.be.equal(ortb2.site[param]);
|
|
390
|
+
});
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
// Should not allow invalid "site.content" data types
|
|
394
|
+
INVALID_ORTB2_TYPES.forEach(param => {
|
|
395
|
+
it(`should determine that the ortb2.site.content key is invalid and should not be added to bid-request: ${JSON.stringify(param)}`, () => {
|
|
396
|
+
const ortb2 = {
|
|
397
|
+
site: {
|
|
398
|
+
content: param
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
config.setConfig({ortb2});
|
|
402
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
403
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
404
|
+
expect(data.site.content).to.be.undefined;
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
// Should not allow invalid "site.content" keys
|
|
409
|
+
it(`should not allow invalid ortb2.site.content object keys to be added to bid-request: {custom object}`, () => {
|
|
410
|
+
const ortb2 = {
|
|
411
|
+
site: {
|
|
412
|
+
content: {
|
|
413
|
+
fake: 'news',
|
|
414
|
+
unreal: 'param',
|
|
415
|
+
counterfit: 'data'
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
config.setConfig({ortb2});
|
|
420
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
421
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
422
|
+
expect(data.site.content).to.be.a('object');
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
// Should append valid "site.content" keys
|
|
426
|
+
const VALID_CONTENT_STRINGS = ['id', 'title', 'series', 'season', 'genre', 'contentrating', 'language'];
|
|
427
|
+
VALID_CONTENT_STRINGS.forEach(param => {
|
|
428
|
+
it(`should determine that the ortb2.site String key is valid and append to the bid-request: ${JSON.stringify(param)}`, () => {
|
|
429
|
+
const ortb2 = {
|
|
430
|
+
site: {
|
|
431
|
+
content: {
|
|
432
|
+
[param]: 'something'
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
config.setConfig({ortb2});
|
|
437
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
438
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
439
|
+
expect(data.site.content[param]).to.exist;
|
|
440
|
+
expect(data.site.content[param]).to.be.a('string');
|
|
441
|
+
expect(data.site.content[param]).to.be.equal(ortb2.site.content[param]);
|
|
442
|
+
});
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
const VALID_CONTENT_NUMBERS = ['episode', 'prodq', 'context', 'livestream', 'len'];
|
|
446
|
+
VALID_CONTENT_NUMBERS.forEach(param => {
|
|
447
|
+
it(`should determine that the ortb2.site.content Number key is valid and append to the bid-request: ${JSON.stringify(param)}`, () => {
|
|
448
|
+
const ortb2 = {
|
|
449
|
+
site: {
|
|
450
|
+
content: {
|
|
451
|
+
[param]: 1234
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
config.setConfig({ortb2});
|
|
456
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
457
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
458
|
+
expect(data.site.content[param]).to.be.a('number');
|
|
459
|
+
expect(data.site.content[param]).to.be.equal(ortb2.site.content[param]);
|
|
460
|
+
});
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
const VALID_CONTENT_ARRAYS = ['cat'];
|
|
464
|
+
VALID_CONTENT_ARRAYS.forEach(param => {
|
|
465
|
+
it(`should determine that the ortb2.site Array key is valid and append to the bid-request: ${JSON.stringify(param)}`, () => {
|
|
466
|
+
const ortb2 = {
|
|
467
|
+
site: {
|
|
468
|
+
content: {
|
|
469
|
+
[param]: ['something', 'something-else']
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
config.setConfig({ortb2});
|
|
474
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
475
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
476
|
+
expect(data.site.content[param]).to.be.a('array');
|
|
477
|
+
expect(data.site.content[param]).to.be.equal(ortb2.site.content[param]);
|
|
478
|
+
});
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
const VALID_CONTENT_OBJECTS = ['ext'];
|
|
482
|
+
VALID_CONTENT_OBJECTS.forEach(param => {
|
|
483
|
+
it(`should determine that the ortb2.site.content Object key is valid and append to the bid-request: ${JSON.stringify(param)}`, () => {
|
|
484
|
+
const ortb2 = {
|
|
485
|
+
site: {
|
|
486
|
+
content: {
|
|
487
|
+
[param]: {a: '123', b: '456'}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
config.setConfig({ortb2});
|
|
492
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
493
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
494
|
+
expect(data.site.content[param]).to.be.a('object');
|
|
495
|
+
expect(data.site.content[param]).to.be.equal(ortb2.site.content[param]);
|
|
496
|
+
config.setConfig({ortb2: {}});
|
|
497
|
+
});
|
|
498
|
+
});
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
describe('First party data module - "User" support (ortb2):', () => {
|
|
502
|
+
// Global ortb2.user validations
|
|
503
|
+
// Should not allow invalid "user" data types
|
|
504
|
+
const INVALID_ORTB2_TYPES = [ null, [], 'unsupportedKeyName', true, false, undefined ];
|
|
505
|
+
INVALID_ORTB2_TYPES.forEach(param => {
|
|
506
|
+
const ortb2 = { user: param }
|
|
507
|
+
config.setConfig({ortb2});
|
|
508
|
+
it(`should not allow invalid site types to be added to bid-request: ${JSON.stringify(param)}`, () => {
|
|
509
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
510
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
511
|
+
expect(data.user[param]).to.be.undefined;
|
|
512
|
+
});
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
// Should add valid "user" params
|
|
516
|
+
const VALID_USER_STRINGS = ['id', 'buyeruid', 'gender', 'keywords', 'customdata'];
|
|
517
|
+
VALID_USER_STRINGS.forEach(param => {
|
|
518
|
+
it(`should allow supported user string keys to be added bid-request: ${JSON.stringify(param)}`, () => {
|
|
519
|
+
const ortb2 = {
|
|
520
|
+
user: {
|
|
521
|
+
[param]: 'something'
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
config.setConfig({ortb2});
|
|
525
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
526
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
527
|
+
expect(data.user[param]).to.exist;
|
|
528
|
+
expect(data.user[param]).to.be.a('string');
|
|
529
|
+
expect(data.user[param]).to.be.equal(ortb2.user[param]);
|
|
530
|
+
});
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
const VALID_USER_NUMBERS = ['yob'];
|
|
534
|
+
VALID_USER_NUMBERS.forEach(param => {
|
|
535
|
+
it(`should allow supported user number keys to be added bid-request: ${JSON.stringify(param)}`, () => {
|
|
536
|
+
const ortb2 = {
|
|
537
|
+
user: {
|
|
538
|
+
[param]: 1982
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
config.setConfig({ortb2});
|
|
542
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
543
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
544
|
+
expect(data.user[param]).to.exist;
|
|
545
|
+
expect(data.user[param]).to.be.a('number');
|
|
546
|
+
expect(data.user[param]).to.be.equal(ortb2.user[param]);
|
|
547
|
+
});
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
const VALID_USER_ARRAYS = ['data'];
|
|
551
|
+
VALID_USER_ARRAYS.forEach(param => {
|
|
552
|
+
it(`should allow supported user Array keys to be added to the bid-request: ${JSON.stringify(param)}`, () => {
|
|
553
|
+
const ortb2 = {
|
|
554
|
+
user: {
|
|
555
|
+
[param]: ['something']
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
config.setConfig({ortb2});
|
|
559
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
560
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
561
|
+
expect(data.user[param]).to.exist;
|
|
562
|
+
expect(data.user[param]).to.be.a('array');
|
|
563
|
+
expect(data.user[param]).to.be.equal(ortb2.user[param]);
|
|
564
|
+
});
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
const VALID_USER_OBJECTS = ['ext'];
|
|
568
|
+
VALID_USER_OBJECTS.forEach(param => {
|
|
569
|
+
it(`should allow supported user extObject keys to be added to the bid-request: ${JSON.stringify(param)}`, () => {
|
|
570
|
+
const ortb2 = {
|
|
571
|
+
user: {
|
|
572
|
+
[param]: {a: '123', b: '456'}
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
config.setConfig({ortb2});
|
|
576
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
577
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
578
|
+
expect(data.user[param]).to.be.a('object');
|
|
579
|
+
expect(data.user[param]).to.be.deep.include({[param]: {a: '123', b: '456'}});
|
|
580
|
+
config.setConfig({ortb2: {}});
|
|
581
|
+
});
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
// Should allow valid user.data && site.content.data
|
|
585
|
+
const VALID_USER_DATA_STRINGS = ['id', 'name'];
|
|
586
|
+
VALID_USER_DATA_STRINGS.forEach(param => {
|
|
587
|
+
it(`should allow supported user.data & site.content.data strings to be added to the bid-request: ${JSON.stringify(param)}`, () => {
|
|
588
|
+
const ortb2 = {
|
|
589
|
+
user: {
|
|
590
|
+
data: [{[param]: 'string'}]
|
|
591
|
+
},
|
|
592
|
+
site: {
|
|
593
|
+
content: {
|
|
594
|
+
data: [{[param]: 'string'}]
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
config.setConfig({ortb2});
|
|
599
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
600
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
601
|
+
expect(data.user.data[0][param]).to.exist;
|
|
602
|
+
expect(data.user.data[0][param]).to.be.a('string');
|
|
603
|
+
expect(data.user.data[0][param]).to.be.equal(ortb2.user.data[0][param]);
|
|
604
|
+
expect(data.site.content.data[0][param]).to.exist;
|
|
605
|
+
expect(data.site.content.data[0][param]).to.be.a('string');
|
|
606
|
+
expect(data.site.content.data[0][param]).to.be.equal(ortb2.site.content.data[0][param]);
|
|
607
|
+
});
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
const VALID_USER_DATA_ARRAYS = ['segment']
|
|
611
|
+
VALID_USER_DATA_ARRAYS.forEach(param => {
|
|
612
|
+
it(`should allow supported user data arrays to be added to the bid-request: ${JSON.stringify(param)}`, () => {
|
|
613
|
+
const ortb2 = {
|
|
614
|
+
user: {
|
|
615
|
+
data: [{[param]: [{id: 1}]}]
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
config.setConfig({ortb2});
|
|
619
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
620
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
621
|
+
expect(data.user.data[0][param]).to.exist;
|
|
622
|
+
expect(data.user.data[0][param]).to.be.a('array');
|
|
623
|
+
expect(data.user.data[0][param]).to.be.equal(ortb2.user.data[0][param]);
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
const VALID_USER_DATA_OBJECTS = ['ext'];
|
|
628
|
+
VALID_USER_DATA_OBJECTS.forEach(param => {
|
|
629
|
+
it(`should allow supported user data objects to be added to the bid-request: ${JSON.stringify(param)}`, () => {
|
|
630
|
+
const ortb2 = {
|
|
631
|
+
user: {
|
|
632
|
+
data: [{[param]: {id: 'ext'}}]
|
|
633
|
+
}
|
|
634
|
+
};
|
|
635
|
+
config.setConfig({ortb2});
|
|
636
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
637
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
638
|
+
expect(data.user.data[0][param]).to.exist;
|
|
639
|
+
expect(data.user.data[0][param]).to.be.a('object');
|
|
640
|
+
expect(data.user.data[0][param]).to.be.equal(ortb2.user.data[0][param]);
|
|
641
|
+
config.setConfig({ortb2: {}});
|
|
642
|
+
});
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
// adUnit.ortb2Imp.ext.data
|
|
646
|
+
it(`should allow adUnit.ortb2Imp.ext.data object to be added to the bid-request`, () => {
|
|
647
|
+
let { validBidRequests, bidderRequest } = generateBuildRequestMock({})
|
|
648
|
+
validBidRequests[0].ortb2Imp = {
|
|
649
|
+
ext: {
|
|
650
|
+
data: {
|
|
651
|
+
pbadslot: 'homepage-top-rect',
|
|
652
|
+
adUnitSpecificAttribute: '123'
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
657
|
+
expect(data.imp[0].ext.data).to.deep.equal(validBidRequests[0].ortb2Imp.ext.data);
|
|
658
|
+
});
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
describe('e2etest mode support:', () => {
|
|
662
|
+
it(`should override DCN & POS when params.testing.e2etest = "true".`, () => {
|
|
663
|
+
const { bidRequest, validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
664
|
+
const params = {
|
|
665
|
+
dcn: '1234',
|
|
666
|
+
pos: '5678',
|
|
667
|
+
testing: {
|
|
668
|
+
e2etest: true
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
bidRequest.params = params;
|
|
672
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
673
|
+
expect(data.site.id).to.be.equal('8a969516017a7a396ec539d97f540011');
|
|
674
|
+
expect(data.imp[0].tagid).to.be.equal('8a969978017a7aaabab4ab0bc01a0009');
|
|
675
|
+
expect(data.imp[0].ext.e2eTestMode).to.be.true;
|
|
676
|
+
});
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
describe('GDPR & Consent:', () => {
|
|
680
|
+
it('should return request objects that do not send cookies if purpose 1 consent is not provided', () => {
|
|
681
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
682
|
+
bidderRequest.gdprConsent = {
|
|
683
|
+
consentString: 'BOtmiBKOtmiBKABABAENAFAAAAACeAAA',
|
|
684
|
+
apiVersion: 2,
|
|
685
|
+
vendorData: {
|
|
686
|
+
purpose: {
|
|
687
|
+
consents: {
|
|
688
|
+
'1': false
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
},
|
|
692
|
+
gdprApplies: true
|
|
693
|
+
};
|
|
694
|
+
const options = spec.buildRequests(validBidRequests, bidderRequest)[0].options;
|
|
695
|
+
expect(options.withCredentials).to.be.false;
|
|
696
|
+
});
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
describe('Endpoint & Impression Request Mode:', () => {
|
|
700
|
+
it('should route request to config override endpoint', () => {
|
|
701
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
702
|
+
const testOverrideEndpoint = 'http://foo.bar.baz.com/bidderRequest';
|
|
703
|
+
config.setConfig({
|
|
704
|
+
yahoossp: {
|
|
705
|
+
endpoint: testOverrideEndpoint
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
const response = spec.buildRequests(validBidRequests, bidderRequest)[0];
|
|
709
|
+
expect(response).to.deep.include(
|
|
710
|
+
{
|
|
711
|
+
method: 'POST',
|
|
712
|
+
url: testOverrideEndpoint
|
|
713
|
+
});
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
it('should route request to /bidRequest endpoint when dcn & pos present', () => {
|
|
717
|
+
config.setConfig({
|
|
718
|
+
yahoossp: {}
|
|
719
|
+
});
|
|
720
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
721
|
+
const response = spec.buildRequests(validBidRequests, bidderRequest);
|
|
722
|
+
expect(response[0]).to.deep.include({
|
|
723
|
+
method: 'POST',
|
|
724
|
+
url: 'https://c2shb.pubgw.yahoo.com/bidRequest'
|
|
725
|
+
});
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
it('should route request to /partners endpoint when pubId is present', () => {
|
|
729
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({pubIdMode: true});
|
|
730
|
+
const response = spec.buildRequests(validBidRequests, bidderRequest);
|
|
731
|
+
expect(response[0]).to.deep.include({
|
|
732
|
+
method: 'POST',
|
|
733
|
+
url: 'https://c2shb.pubgw.yahoo.com/admax/bid/partners/PBJS'
|
|
734
|
+
});
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
it('should return a single request object for single request mode', () => {
|
|
738
|
+
let { bidRequest, validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
739
|
+
const BID_ID_2 = '84ab50xxxxx';
|
|
740
|
+
const BID_POS_2 = 'footer';
|
|
741
|
+
const AD_UNIT_CODE_2 = 'test-ad-unit-code-123';
|
|
742
|
+
const { bidRequest: bidRequest2 } = generateBuildRequestMock({bidId: BID_ID_2, pos: BID_POS_2, adUnitCode: AD_UNIT_CODE_2});
|
|
743
|
+
validBidRequests = [bidRequest, bidRequest2];
|
|
744
|
+
bidderRequest.bids = validBidRequests;
|
|
745
|
+
|
|
746
|
+
config.setConfig({
|
|
747
|
+
yahoossp: {
|
|
748
|
+
singleRequestMode: true
|
|
749
|
+
}
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest).data;
|
|
753
|
+
expect(data.imp).to.be.an('array').with.lengthOf(2);
|
|
754
|
+
|
|
755
|
+
expect(data.imp[0]).to.deep.include({
|
|
756
|
+
id: DEFAULT_BID_ID,
|
|
757
|
+
ext: {
|
|
758
|
+
pos: DEFAULT_BID_POS,
|
|
759
|
+
dfp_ad_unit_code: DEFAULT_AD_UNIT_CODE
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
expect(data.imp[1]).to.deep.include({
|
|
764
|
+
id: BID_ID_2,
|
|
765
|
+
ext: {
|
|
766
|
+
pos: BID_POS_2,
|
|
767
|
+
dfp_ad_unit_code: AD_UNIT_CODE_2
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
});
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
describe('Validate request filtering:', () => {
|
|
774
|
+
it('should not return request when no bids are present', function () {
|
|
775
|
+
let request = spec.buildRequests([]);
|
|
776
|
+
expect(request).to.be.undefined;
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
it('buildRequests(): should return an array with the correct amount of request objects', () => {
|
|
780
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
781
|
+
const response = spec.buildRequests(validBidRequests, bidderRequest).bidderRequest;
|
|
782
|
+
expect(response.bids).to.be.an('array').to.have.lengthOf(1);
|
|
783
|
+
});
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
describe('Request Headers validation:', () => {
|
|
787
|
+
it('should return request objects with the relevant custom headers and content type declaration', () => {
|
|
788
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
789
|
+
const options = spec.buildRequests(validBidRequests, bidderRequest).options;
|
|
790
|
+
expect(options).to.deep.equal(
|
|
791
|
+
{
|
|
792
|
+
contentType: 'application/json',
|
|
793
|
+
customHeaders: {
|
|
794
|
+
'x-openrtb-version': '2.5'
|
|
795
|
+
},
|
|
796
|
+
withCredentials: true
|
|
797
|
+
});
|
|
798
|
+
});
|
|
799
|
+
});
|
|
800
|
+
|
|
801
|
+
describe('Request Payload oRTB bid validation:', () => {
|
|
802
|
+
it('should generate a valid openRTB bid-request object in the data field', () => {
|
|
803
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
804
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest).data;
|
|
805
|
+
expect(data.site).to.deep.equal({
|
|
806
|
+
id: bidderRequest.bids[0].params.dcn,
|
|
807
|
+
page: bidderRequest.refererInfo.referer
|
|
808
|
+
});
|
|
809
|
+
|
|
810
|
+
expect(data.device).to.deep.equal({
|
|
811
|
+
dnt: 0,
|
|
812
|
+
ua: navigator.userAgent,
|
|
813
|
+
ip: undefined
|
|
814
|
+
});
|
|
815
|
+
|
|
816
|
+
expect(data.regs).to.deep.equal({
|
|
817
|
+
ext: {
|
|
818
|
+
'us_privacy': '',
|
|
819
|
+
gdpr: 1
|
|
820
|
+
}
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
expect(data.source).to.deep.equal({
|
|
824
|
+
ext: {
|
|
825
|
+
hb: 1,
|
|
826
|
+
adapterver: ADAPTER_VERSION,
|
|
827
|
+
prebidver: PREBID_VERSION,
|
|
828
|
+
integration: {
|
|
829
|
+
name: INTEGRATION_METHOD,
|
|
830
|
+
ver: PREBID_VERSION
|
|
831
|
+
}
|
|
832
|
+
},
|
|
833
|
+
fd: 1
|
|
834
|
+
});
|
|
835
|
+
|
|
836
|
+
expect(data.user).to.deep.equal({
|
|
837
|
+
ext: {
|
|
838
|
+
consent: bidderRequest.gdprConsent.consentString,
|
|
839
|
+
eids: []
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
expect(data.cur).to.deep.equal(['USD']);
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
it('should generate a valid openRTB imp.ext object in the bid-request', () => {
|
|
847
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
848
|
+
const bid = validBidRequests[0];
|
|
849
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest).data;
|
|
850
|
+
expect(data.imp[0].ext).to.deep.equal({
|
|
851
|
+
pos: bid.params.pos,
|
|
852
|
+
dfp_ad_unit_code: DEFAULT_AD_UNIT_CODE
|
|
853
|
+
});
|
|
854
|
+
});
|
|
855
|
+
|
|
856
|
+
it('should use siteId value as site.id in the outbound bid-request when using "pubId" integration mode', () => {
|
|
857
|
+
let { validBidRequests, bidderRequest } = generateBuildRequestMock({pubIdMode: true});
|
|
858
|
+
validBidRequests[0].params.siteId = '1234567';
|
|
859
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest).data;
|
|
860
|
+
expect(data.site.id).to.equal('1234567');
|
|
861
|
+
});
|
|
862
|
+
|
|
863
|
+
it('should use placementId value as imp.tagid in the outbound bid-request when using "pubId" integration mode', () => {
|
|
864
|
+
let { validBidRequests, bidderRequest } = generateBuildRequestMock({pubIdMode: true});
|
|
865
|
+
validBidRequests[0].params.placementId = 'header-300x250';
|
|
866
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest).data;
|
|
867
|
+
expect(data.imp[0].tagid).to.deep.equal('header-300x250');
|
|
868
|
+
});
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
describe('Request Payload oRTB bid.imp validation:', () => {
|
|
872
|
+
// Validate Banner imp imp when yahoossp.mode=undefined
|
|
873
|
+
it('should generate a valid "Banner" imp object', () => {
|
|
874
|
+
config.setConfig({
|
|
875
|
+
yahoossp: {}
|
|
876
|
+
});
|
|
877
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
878
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
879
|
+
expect(data.imp[0].video).to.not.exist;
|
|
880
|
+
expect(data.imp[0].banner).to.deep.equal({
|
|
881
|
+
mimes: ['text/html', 'text/javascript', 'application/javascript', 'image/jpg'],
|
|
882
|
+
format: [{w: 300, h: 250}, {w: 300, h: 600}]
|
|
883
|
+
});
|
|
884
|
+
});
|
|
885
|
+
|
|
886
|
+
// Validate Banner imp when yahoossp.mode="banner"
|
|
887
|
+
it('should generate a valid "Banner" imp object', () => {
|
|
888
|
+
config.setConfig({
|
|
889
|
+
yahoossp: { mode: 'banner' }
|
|
890
|
+
});
|
|
891
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
|
|
892
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
893
|
+
expect(data.imp[0].video).to.not.exist;
|
|
894
|
+
expect(data.imp[0].banner).to.deep.equal({
|
|
895
|
+
mimes: ['text/html', 'text/javascript', 'application/javascript', 'image/jpg'],
|
|
896
|
+
format: [{w: 300, h: 250}, {w: 300, h: 600}]
|
|
897
|
+
});
|
|
898
|
+
});
|
|
899
|
+
|
|
900
|
+
// Validate Video imp
|
|
901
|
+
it('should generate a valid "Video" only imp object', () => {
|
|
902
|
+
config.setConfig({
|
|
903
|
+
yahoossp: { mode: 'video' }
|
|
904
|
+
});
|
|
905
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({adUnitType: 'video'});
|
|
906
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
907
|
+
expect(data.imp[0].banner).to.not.exist;
|
|
908
|
+
expect(data.imp[0].video).to.deep.equal({
|
|
909
|
+
mimes: ['video/mp4', 'application/javascript'],
|
|
910
|
+
w: 300,
|
|
911
|
+
h: 250,
|
|
912
|
+
api: [2],
|
|
913
|
+
protocols: [2, 5],
|
|
914
|
+
startdelay: 0,
|
|
915
|
+
linearity: 1,
|
|
916
|
+
maxbitrate: undefined,
|
|
917
|
+
maxduration: undefined,
|
|
918
|
+
minduration: undefined,
|
|
919
|
+
delivery: undefined,
|
|
920
|
+
pos: undefined,
|
|
921
|
+
playbackmethod: undefined,
|
|
922
|
+
rewarded: undefined,
|
|
923
|
+
placement: undefined
|
|
924
|
+
});
|
|
925
|
+
});
|
|
926
|
+
|
|
927
|
+
// Validate multi-format Video+banner imp
|
|
928
|
+
it('should generate a valid multi-format "Video + Banner" imp object', () => {
|
|
929
|
+
config.setConfig({
|
|
930
|
+
yahoossp: { mode: 'all' }
|
|
931
|
+
});
|
|
932
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({adUnitType: 'multi-format'});
|
|
933
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
934
|
+
expect(data.imp[0].banner).to.deep.equal({
|
|
935
|
+
mimes: ['text/html', 'text/javascript', 'application/javascript', 'image/jpg'],
|
|
936
|
+
format: [{w: 300, h: 250}, {w: 300, h: 600}]
|
|
937
|
+
});
|
|
938
|
+
expect(data.imp[0].video).to.deep.equal({
|
|
939
|
+
mimes: ['video/mp4', 'application/javascript'],
|
|
940
|
+
w: 300,
|
|
941
|
+
h: 250,
|
|
942
|
+
api: [2],
|
|
943
|
+
protocols: [2, 5],
|
|
944
|
+
startdelay: 0,
|
|
945
|
+
linearity: 1,
|
|
946
|
+
maxbitrate: undefined,
|
|
947
|
+
maxduration: undefined,
|
|
948
|
+
minduration: undefined,
|
|
949
|
+
delivery: undefined,
|
|
950
|
+
pos: undefined,
|
|
951
|
+
playbackmethod: undefined,
|
|
952
|
+
rewarded: undefined,
|
|
953
|
+
placement: undefined
|
|
954
|
+
});
|
|
955
|
+
});
|
|
956
|
+
|
|
957
|
+
// Validate Key-Value Pairs
|
|
958
|
+
it('should generate supported String, Number, Array of Strings, Array of Numbers key-value pairs and append to imp.ext.kvs', () => {
|
|
959
|
+
let { validBidRequests, bidderRequest } = generateBuildRequestMock({})
|
|
960
|
+
validBidRequests[0].params.kvp = {
|
|
961
|
+
key1: 'String',
|
|
962
|
+
key2: 123456,
|
|
963
|
+
key3: ['String', 'String', 'String'],
|
|
964
|
+
key4: [1, 2, 3],
|
|
965
|
+
invalidKey1: true,
|
|
966
|
+
invalidKey2: null,
|
|
967
|
+
invalidKey3: ['string', 1234],
|
|
968
|
+
invalidKey4: {a: 1, b: 2},
|
|
969
|
+
invalidKey5: undefined
|
|
970
|
+
};
|
|
971
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
972
|
+
|
|
973
|
+
expect(data.imp[0].ext.kvs).to.deep.equal({
|
|
974
|
+
key1: 'String',
|
|
975
|
+
key2: 123456,
|
|
976
|
+
key3: ['String', 'String', 'String'],
|
|
977
|
+
key4: [1, 2, 3]
|
|
978
|
+
});
|
|
979
|
+
});
|
|
980
|
+
});
|
|
981
|
+
|
|
982
|
+
describe('Multiple adUnit validations:', () => {
|
|
983
|
+
// Multiple banner adUnits
|
|
984
|
+
it('should generate multiple bid-requests for each adUnit - 2 banner only', () => {
|
|
985
|
+
config.setConfig({
|
|
986
|
+
yahoossp: { mode: 'banner' }
|
|
987
|
+
});
|
|
988
|
+
|
|
989
|
+
const BID_ID_2 = '84ab50xxxxx';
|
|
990
|
+
const BID_POS_2 = 'footer';
|
|
991
|
+
const AD_UNIT_CODE_2 = 'test-ad-unit-code-123';
|
|
992
|
+
const BID_ID_3 = '84ab50yyyyy';
|
|
993
|
+
const BID_POS_3 = 'hero';
|
|
994
|
+
const AD_UNIT_CODE_3 = 'video-ad-unit';
|
|
995
|
+
|
|
996
|
+
let { bidRequest, validBidRequests, bidderRequest } = generateBuildRequestMock({}); // banner
|
|
997
|
+
const { bidRequest: bidRequest2 } = generateBuildRequestMock({bidId: BID_ID_2, pos: BID_POS_2, adUnitCode: AD_UNIT_CODE_2}); // banner
|
|
998
|
+
const { bidRequest: bidRequest3 } = generateBuildRequestMock({bidId: BID_ID_3, pos: BID_POS_3, adUnitCode: AD_UNIT_CODE_3, adUnitType: 'video'}); // video (should be filtered)
|
|
999
|
+
validBidRequests = [bidRequest, bidRequest2, bidRequest3];
|
|
1000
|
+
bidderRequest.bids = validBidRequests;
|
|
1001
|
+
|
|
1002
|
+
const response = spec.buildRequests(validBidRequests, bidderRequest)
|
|
1003
|
+
expect(response).to.be.a('array');
|
|
1004
|
+
expect(response.length).to.equal(2);
|
|
1005
|
+
response.forEach((obj) => {
|
|
1006
|
+
expect(obj.data.imp[0].video).to.not.exist
|
|
1007
|
+
expect(obj.data.imp[0].banner).to.deep.equal({
|
|
1008
|
+
mimes: ['text/html', 'text/javascript', 'application/javascript', 'image/jpg'],
|
|
1009
|
+
format: [{w: 300, h: 250}, {w: 300, h: 600}]
|
|
1010
|
+
});
|
|
1011
|
+
});
|
|
1012
|
+
});
|
|
1013
|
+
|
|
1014
|
+
// Multiple video adUnits
|
|
1015
|
+
it('should generate multiple bid-requests for each adUnit - 2 video only', () => {
|
|
1016
|
+
config.setConfig({
|
|
1017
|
+
yahoossp: { mode: 'video' }
|
|
1018
|
+
});
|
|
1019
|
+
const BID_ID_2 = '84ab50xxxxx';
|
|
1020
|
+
const BID_POS_2 = 'footer';
|
|
1021
|
+
const AD_UNIT_CODE_2 = 'test-ad-unit-code-123';
|
|
1022
|
+
const BID_ID_3 = '84ab50yyyyy';
|
|
1023
|
+
const BID_POS_3 = 'hero';
|
|
1024
|
+
const AD_UNIT_CODE_3 = 'video-ad-unit';
|
|
1025
|
+
|
|
1026
|
+
let { bidRequest, validBidRequests, bidderRequest } = generateBuildRequestMock({adUnitType: 'video'}); // video
|
|
1027
|
+
const { bidRequest: bidRequest2 } = generateBuildRequestMock({bidId: BID_ID_2, pos: BID_POS_2, adUnitCode: AD_UNIT_CODE_2, adUnitType: 'video'}); // video
|
|
1028
|
+
const { bidRequest: bidRequest3 } = generateBuildRequestMock({bidId: BID_ID_3, pos: BID_POS_3, adUnitCode: AD_UNIT_CODE_3}); // banner (should be filtered)
|
|
1029
|
+
validBidRequests = [bidRequest, bidRequest2, bidRequest3];
|
|
1030
|
+
bidderRequest.bids = validBidRequests;
|
|
1031
|
+
|
|
1032
|
+
const response = spec.buildRequests(validBidRequests, bidderRequest)
|
|
1033
|
+
expect(response).to.be.a('array');
|
|
1034
|
+
expect(response.length).to.equal(2);
|
|
1035
|
+
response.forEach((obj) => {
|
|
1036
|
+
expect(obj.data.imp[0].banner).to.not.exist
|
|
1037
|
+
expect(obj.data.imp[0].video).to.deep.equal({
|
|
1038
|
+
mimes: ['video/mp4', 'application/javascript'],
|
|
1039
|
+
w: 300,
|
|
1040
|
+
h: 250,
|
|
1041
|
+
api: [2],
|
|
1042
|
+
protocols: [2, 5],
|
|
1043
|
+
startdelay: 0,
|
|
1044
|
+
linearity: 1,
|
|
1045
|
+
maxbitrate: undefined,
|
|
1046
|
+
maxduration: undefined,
|
|
1047
|
+
minduration: undefined,
|
|
1048
|
+
delivery: undefined,
|
|
1049
|
+
pos: undefined,
|
|
1050
|
+
playbackmethod: undefined,
|
|
1051
|
+
rewarded: undefined,
|
|
1052
|
+
placement: undefined
|
|
1053
|
+
});
|
|
1054
|
+
});
|
|
1055
|
+
});
|
|
1056
|
+
// Mixed adUnits 1-banner, 1-video, 1-native (should filter out native)
|
|
1057
|
+
it('should generate multiple bid-requests for both "video & banner" adUnits', () => {
|
|
1058
|
+
config.setConfig({
|
|
1059
|
+
yahoossp: { mode: 'all' }
|
|
1060
|
+
});
|
|
1061
|
+
const BID_ID_2 = '84ab50xxxxx';
|
|
1062
|
+
const BID_POS_2 = 'footer';
|
|
1063
|
+
const AD_UNIT_CODE_2 = 'video-ad-unit';
|
|
1064
|
+
const BID_ID_3 = '84ab50yyyyy';
|
|
1065
|
+
const BID_POS_3 = 'hero';
|
|
1066
|
+
const AD_UNIT_CODE_3 = 'native-ad-unit';
|
|
1067
|
+
|
|
1068
|
+
let { bidRequest, validBidRequests, bidderRequest } = generateBuildRequestMock({adUnitType: 'banner'}); // banner
|
|
1069
|
+
const { bidRequest: bidRequest2 } = generateBuildRequestMock({bidId: BID_ID_2, pos: BID_POS_2, adUnitCode: AD_UNIT_CODE_2, adUnitType: 'video'}); // video
|
|
1070
|
+
const { bidRequest: bidRequest3 } = generateBuildRequestMock({bidId: BID_ID_3, pos: BID_POS_3, adUnitCode: AD_UNIT_CODE_3, adUnitType: 'native'}); // native (should be filtered)
|
|
1071
|
+
validBidRequests = [bidRequest, bidRequest2, bidRequest3];
|
|
1072
|
+
bidderRequest.bids = validBidRequests;
|
|
1073
|
+
|
|
1074
|
+
const response = spec.buildRequests(validBidRequests, bidderRequest);
|
|
1075
|
+
expect(response).to.be.a('array');
|
|
1076
|
+
expect(response.length).to.equal(2);
|
|
1077
|
+
response.forEach((obj) => {
|
|
1078
|
+
expect(obj.data.imp[0].native).to.not.exist;
|
|
1079
|
+
});
|
|
1080
|
+
|
|
1081
|
+
const data1 = response[0].data;
|
|
1082
|
+
expect(data1.imp[0].video).to.not.exist;
|
|
1083
|
+
expect(data1.imp[0].banner).to.deep.equal({
|
|
1084
|
+
mimes: ['text/html', 'text/javascript', 'application/javascript', 'image/jpg'],
|
|
1085
|
+
format: [{w: 300, h: 250}, {w: 300, h: 600}]
|
|
1086
|
+
});
|
|
1087
|
+
|
|
1088
|
+
const data2 = response[1].data;
|
|
1089
|
+
expect(data2.imp[0].banner).to.not.exist;
|
|
1090
|
+
expect(data2.imp[0].video).to.deep.equal({
|
|
1091
|
+
mimes: ['video/mp4', 'application/javascript'],
|
|
1092
|
+
w: 300,
|
|
1093
|
+
h: 250,
|
|
1094
|
+
api: [2],
|
|
1095
|
+
protocols: [2, 5],
|
|
1096
|
+
startdelay: 0,
|
|
1097
|
+
linearity: 1,
|
|
1098
|
+
maxbitrate: undefined,
|
|
1099
|
+
maxduration: undefined,
|
|
1100
|
+
minduration: undefined,
|
|
1101
|
+
delivery: undefined,
|
|
1102
|
+
pos: undefined,
|
|
1103
|
+
playbackmethod: undefined,
|
|
1104
|
+
rewarded: undefined,
|
|
1105
|
+
placement: undefined
|
|
1106
|
+
});
|
|
1107
|
+
});
|
|
1108
|
+
});
|
|
1109
|
+
|
|
1110
|
+
describe('Video params firstlook & bidOverride validations:', () => {
|
|
1111
|
+
it('should first look at params.bidOverride for video placement data', () => {
|
|
1112
|
+
config.setConfig({
|
|
1113
|
+
yahoossp: { mode: 'video' }
|
|
1114
|
+
});
|
|
1115
|
+
const bidOverride = {
|
|
1116
|
+
imp: {
|
|
1117
|
+
video: {
|
|
1118
|
+
mimes: ['video/mp4'],
|
|
1119
|
+
w: 400,
|
|
1120
|
+
h: 350,
|
|
1121
|
+
api: [1],
|
|
1122
|
+
protocols: [1, 3],
|
|
1123
|
+
startdelay: 0,
|
|
1124
|
+
linearity: 1,
|
|
1125
|
+
maxbitrate: 400000,
|
|
1126
|
+
maxduration: 3600,
|
|
1127
|
+
minduration: 1500,
|
|
1128
|
+
delivery: 1,
|
|
1129
|
+
pos: 123456,
|
|
1130
|
+
playbackmethod: 1,
|
|
1131
|
+
rewarded: 1,
|
|
1132
|
+
placement: 1
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({adUnitType: 'video', bidOverrideObject: bidOverride});
|
|
1137
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
1138
|
+
expect(data.imp[0].video).to.deep.equal(bidOverride.imp.video);
|
|
1139
|
+
});
|
|
1140
|
+
|
|
1141
|
+
it('should second look at bid.mediaTypes.video for video placement data', () => {
|
|
1142
|
+
config.setConfig({
|
|
1143
|
+
yahoossp: { mode: 'video' }
|
|
1144
|
+
});
|
|
1145
|
+
let { bidRequest, bidderRequest } = generateBuildRequestMock({adUnitType: 'video'});
|
|
1146
|
+
bidRequest.mediaTypes.video = {
|
|
1147
|
+
mimes: ['video/mp4'],
|
|
1148
|
+
playerSize: [400, 350],
|
|
1149
|
+
api: [1],
|
|
1150
|
+
protocols: [1, 3],
|
|
1151
|
+
startdelay: 0,
|
|
1152
|
+
linearity: 1,
|
|
1153
|
+
maxbitrate: 400000,
|
|
1154
|
+
maxduration: 3600,
|
|
1155
|
+
minduration: 1500,
|
|
1156
|
+
delivery: 1,
|
|
1157
|
+
pos: 123456,
|
|
1158
|
+
playbackmethod: 1,
|
|
1159
|
+
placement: 1
|
|
1160
|
+
}
|
|
1161
|
+
const validBidRequests = [bidRequest];
|
|
1162
|
+
bidderRequest.bids = validBidRequests;
|
|
1163
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
1164
|
+
expect(data.imp[0].video).to.deep.equal({
|
|
1165
|
+
mimes: ['video/mp4'],
|
|
1166
|
+
w: 400,
|
|
1167
|
+
h: 350,
|
|
1168
|
+
api: [1],
|
|
1169
|
+
protocols: [1, 3],
|
|
1170
|
+
startdelay: 0,
|
|
1171
|
+
linearity: 1,
|
|
1172
|
+
maxbitrate: 400000,
|
|
1173
|
+
maxduration: 3600,
|
|
1174
|
+
minduration: 1500,
|
|
1175
|
+
delivery: 1,
|
|
1176
|
+
pos: 123456,
|
|
1177
|
+
playbackmethod: 1,
|
|
1178
|
+
placement: 1,
|
|
1179
|
+
rewarded: undefined
|
|
1180
|
+
});
|
|
1181
|
+
});
|
|
1182
|
+
|
|
1183
|
+
it('should use params.bidOverride.device.ip override', () => {
|
|
1184
|
+
config.setConfig({
|
|
1185
|
+
yahoossp: { mode: 'all' }
|
|
1186
|
+
});
|
|
1187
|
+
const bidOverride = {
|
|
1188
|
+
device: {
|
|
1189
|
+
ip: '1.2.3.4'
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
const { validBidRequests, bidderRequest } = generateBuildRequestMock({adUnitType: 'video', bidOverrideObject: bidOverride});
|
|
1193
|
+
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
|
|
1194
|
+
expect(data.device.ip).to.deep.equal(bidOverride.device.ip);
|
|
1195
|
+
});
|
|
1196
|
+
});
|
|
1197
|
+
// #endregion buildRequests():
|
|
1198
|
+
|
|
1199
|
+
describe('interpretResponse()', () => {
|
|
1200
|
+
describe('for mediaTypes: "banner"', () => {
|
|
1201
|
+
it('should insert banner payload into response[0].ad', () => {
|
|
1202
|
+
const { serverResponse, bidderRequest } = generateResponseMock('banner');
|
|
1203
|
+
const response = spec.interpretResponse(serverResponse, {bidderRequest});
|
|
1204
|
+
expect(response[0].ad).to.equal('<script>logInfo(\'ad\'); AdPlacement </script>');
|
|
1205
|
+
expect(response[0].mediaType).to.equal('banner');
|
|
1206
|
+
})
|
|
1207
|
+
});
|
|
1208
|
+
|
|
1209
|
+
describe('for mediaTypes: "video"', () => {
|
|
1210
|
+
it('should insert video VPAID payload into vastXml', () => {
|
|
1211
|
+
const { serverResponse, bidderRequest } = generateResponseMock('video');
|
|
1212
|
+
const response = spec.interpretResponse(serverResponse, {bidderRequest});
|
|
1213
|
+
expect(response[0].ad).to.be.undefined;
|
|
1214
|
+
expect(response[0].vastXml).to.equal('<VAST></VAST>');
|
|
1215
|
+
expect(response[0].mediaType).to.equal('video');
|
|
1216
|
+
})
|
|
1217
|
+
|
|
1218
|
+
it('should insert video VAST win notification into vastUrl', () => {
|
|
1219
|
+
const { serverResponse, bidderRequest } = generateResponseMock('video', 'vast');
|
|
1220
|
+
const response = spec.interpretResponse(serverResponse, {bidderRequest});
|
|
1221
|
+
expect(response[0].ad).to.be.undefined;
|
|
1222
|
+
expect(response[0].vastUrl).to.equal('https://yahoo.com?event=adAttempt');
|
|
1223
|
+
expect(response[0].vastXml).to.equal('<VAST></VAST>');
|
|
1224
|
+
expect(response[0].mediaType).to.equal('video');
|
|
1225
|
+
})
|
|
1226
|
+
|
|
1227
|
+
it('should insert video DAP O2 Player into ad', () => {
|
|
1228
|
+
const { serverResponse, bidderRequest } = generateResponseMock('dap-o2', 'vpaid');
|
|
1229
|
+
const response = spec.interpretResponse(serverResponse, {bidderRequest});
|
|
1230
|
+
expect(response[0].ad).to.equal('<script>o2playerSettings</script>');
|
|
1231
|
+
expect(response[0].vastUrl).to.be.undefined;
|
|
1232
|
+
expect(response[0].vastXml).to.be.undefined;
|
|
1233
|
+
expect(response[0].mediaType).to.equal('banner');
|
|
1234
|
+
});
|
|
1235
|
+
|
|
1236
|
+
it('should insert video DAP Unified Player into ad', () => {
|
|
1237
|
+
const { serverResponse, bidderRequest } = generateResponseMock('dap-up', 'vpaid');
|
|
1238
|
+
const response = spec.interpretResponse(serverResponse, {bidderRequest});
|
|
1239
|
+
expect(response[0].ad).to.equal('<script>YAHOO.VideoPlatform.VideoPlayer</script>');
|
|
1240
|
+
expect(response[0].vastUrl).to.be.undefined;
|
|
1241
|
+
expect(response[0].vastXml).to.be.undefined;
|
|
1242
|
+
expect(response[0].mediaType).to.equal('banner');
|
|
1243
|
+
})
|
|
1244
|
+
});
|
|
1245
|
+
|
|
1246
|
+
describe('Support Advertiser domains', () => {
|
|
1247
|
+
it('should append bid-response adomain to meta.advertiserDomains', () => {
|
|
1248
|
+
const { serverResponse, bidderRequest } = generateResponseMock('video', 'vpaid');
|
|
1249
|
+
const response = spec.interpretResponse(serverResponse, {bidderRequest});
|
|
1250
|
+
expect(response[0].meta.advertiserDomains).to.be.a('array');
|
|
1251
|
+
expect(response[0].meta.advertiserDomains[0]).to.equal('advertiser-domain.com');
|
|
1252
|
+
})
|
|
1253
|
+
});
|
|
1254
|
+
|
|
1255
|
+
describe('bid response Ad ID / Creative ID', () => {
|
|
1256
|
+
it('should use adId if it exists in the bid-response', () => {
|
|
1257
|
+
const { serverResponse, bidderRequest } = generateResponseMock('banner');
|
|
1258
|
+
const adId = 'bid-response-adId';
|
|
1259
|
+
serverResponse.body.seatbid[0].bid[0].adId = adId;
|
|
1260
|
+
const response = spec.interpretResponse(serverResponse, {bidderRequest});
|
|
1261
|
+
expect(response[0].adId).to.equal(adId);
|
|
1262
|
+
});
|
|
1263
|
+
|
|
1264
|
+
it('should use impid if adId does not exist in the bid-response', () => {
|
|
1265
|
+
const { serverResponse, bidderRequest } = generateResponseMock('banner');
|
|
1266
|
+
const impid = '25b6c429c1f52f';
|
|
1267
|
+
serverResponse.body.seatbid[0].bid[0].impid = impid;
|
|
1268
|
+
const response = spec.interpretResponse(serverResponse, {bidderRequest});
|
|
1269
|
+
expect(response[0].adId).to.equal(impid);
|
|
1270
|
+
});
|
|
1271
|
+
|
|
1272
|
+
it('should use crid if adId & impid do not exist in the bid-response', () => {
|
|
1273
|
+
const { serverResponse, bidderRequest } = generateResponseMock('banner');
|
|
1274
|
+
const crid = 'passback-12579';
|
|
1275
|
+
serverResponse.body.seatbid[0].bid[0].impid = undefined;
|
|
1276
|
+
serverResponse.body.seatbid[0].bid[0].crid = crid;
|
|
1277
|
+
const response = spec.interpretResponse(serverResponse, {bidderRequest});
|
|
1278
|
+
expect(response[0].adId).to.equal(crid);
|
|
1279
|
+
});
|
|
1280
|
+
});
|
|
1281
|
+
|
|
1282
|
+
describe('Time To Live (ttl)', () => {
|
|
1283
|
+
const UNSUPPORTED_TTL_FORMATS = ['string', [1, 2, 3], true, false, null, undefined];
|
|
1284
|
+
UNSUPPORTED_TTL_FORMATS.forEach(param => {
|
|
1285
|
+
it('should not allow unsupported global yahoossp.ttl formats and default to 300', () => {
|
|
1286
|
+
const { serverResponse, bidderRequest } = generateResponseMock('banner');
|
|
1287
|
+
config.setConfig({
|
|
1288
|
+
yahoossp: { ttl: param }
|
|
1289
|
+
});
|
|
1290
|
+
const response = spec.interpretResponse(serverResponse, {bidderRequest});
|
|
1291
|
+
expect(response[0].ttl).to.equal(300);
|
|
1292
|
+
});
|
|
1293
|
+
|
|
1294
|
+
it('should not allow unsupported params.ttl formats and default to 300', () => {
|
|
1295
|
+
const { serverResponse, bidderRequest } = generateResponseMock('banner');
|
|
1296
|
+
bidderRequest.bids[0].params.ttl = param;
|
|
1297
|
+
const response = spec.interpretResponse(serverResponse, {bidderRequest});
|
|
1298
|
+
expect(response[0].ttl).to.equal(300);
|
|
1299
|
+
});
|
|
1300
|
+
});
|
|
1301
|
+
|
|
1302
|
+
const UNSUPPORTED_TTL_VALUES = [-1, 3601];
|
|
1303
|
+
UNSUPPORTED_TTL_VALUES.forEach(param => {
|
|
1304
|
+
it('should not allow invalid global yahoossp.ttl values 3600 < ttl < 0 and default to 300', () => {
|
|
1305
|
+
const { serverResponse, bidderRequest } = generateResponseMock('banner');
|
|
1306
|
+
config.setConfig({
|
|
1307
|
+
yahoossp: { ttl: param }
|
|
1308
|
+
});
|
|
1309
|
+
const response = spec.interpretResponse(serverResponse, {bidderRequest});
|
|
1310
|
+
expect(response[0].ttl).to.equal(300);
|
|
1311
|
+
});
|
|
1312
|
+
|
|
1313
|
+
it('should not allow invalid params.ttl values 3600 < ttl < 0 and default to 300', () => {
|
|
1314
|
+
const { serverResponse, bidderRequest } = generateResponseMock('banner');
|
|
1315
|
+
bidderRequest.bids[0].params.ttl = param;
|
|
1316
|
+
const response = spec.interpretResponse(serverResponse, {bidderRequest});
|
|
1317
|
+
expect(response[0].ttl).to.equal(300);
|
|
1318
|
+
});
|
|
1319
|
+
});
|
|
1320
|
+
|
|
1321
|
+
it('should give presedence to Gloabl ttl over params.ttl ', () => {
|
|
1322
|
+
const { serverResponse, bidderRequest } = generateResponseMock('banner');
|
|
1323
|
+
config.setConfig({
|
|
1324
|
+
yahoossp: { ttl: 500 }
|
|
1325
|
+
});
|
|
1326
|
+
bidderRequest.bids[0].params.ttl = 400;
|
|
1327
|
+
const response = spec.interpretResponse(serverResponse, {bidderRequest});
|
|
1328
|
+
expect(response[0].ttl).to.equal(500);
|
|
1329
|
+
});
|
|
1330
|
+
});
|
|
1331
|
+
});
|
|
1332
|
+
});
|