prebid.js 7.27.0 → 7.28.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/.github/workflows/issue_tracker.yml +1 -1
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adhashBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/discoveryBidAdapter.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/glimpseBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gridNMBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmarBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveIntentIdSystem.js +1 -1
- package/dist/liveyieldAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/magniteAnalyticsAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediagoBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +118 -118
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +2 -2
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rubiconAnalyticsAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/synacormediaBidAdapter.js +1 -1
- package/dist/taboolaBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/libraries/ortb2.5StrictTranslator/dsl.js +54 -0
- package/libraries/ortb2.5StrictTranslator/spec.js +81 -0
- package/libraries/ortb2.5StrictTranslator/translator.js +37 -0
- package/libraries/ortb2.5Translator/translator.js +82 -0
- package/modules/33acrossIdSystem.js +3 -0
- package/modules/adhashBidAdapter.js +115 -30
- package/modules/adhashBidAdapter.md +1 -3
- package/modules/discoveryBidAdapter.js +3 -0
- package/modules/kargoBidAdapter.js +1 -1
- package/modules/lassoBidAdapter.js +8 -4
- package/modules/liveIntentIdSystem.js +1 -2
- package/modules/mediagoBidAdapter.js +2 -1
- package/modules/openxBidAdapter.md +15 -14
- package/modules/taboolaBidAdapter.js +20 -7
- package/modules/vidazooBidAdapter.js +20 -7
- package/package.json +2 -2
- package/src/auction.js +11 -1
- package/src/constants.json +2 -1
- package/test/helpers/refererDetectionHelper.js +88 -0
- package/test/spec/auctionmanager_spec.js +33 -1
- package/test/spec/modules/33acrossIdSystem_spec.js +4 -1
- package/test/spec/modules/adhashBidAdapter_spec.js +65 -11
- package/test/spec/modules/taboolaBidAdapter_spec.js +39 -0
- package/test/spec/modules/ttdBidAdapter_spec.js +36 -9
- package/test/spec/modules/vidazooBidAdapter_spec.js +134 -3
- package/test/spec/ortb2.5StrictTranslator/dsl_spec.js +137 -0
- package/test/spec/ortb2.5StrictTranslator/spec_spec.js +358 -0
- package/test/spec/ortb2.5StrictTranslator/translator_spec.js +16 -0
- package/test/spec/ortb2.5Translator/translator_spec.js +64 -0
- package/test/spec/refererDetection_spec.js +1 -88
|
@@ -15,23 +15,24 @@ Publishers are welcome to test the other adapter and give feedback. Please note
|
|
|
15
15
|
# Bid Parameters
|
|
16
16
|
## Banner
|
|
17
17
|
|
|
18
|
-
| Name
|
|
19
|
-
|
|
20
|
-
| `delDomain` or `platform
|
|
21
|
-
| `unit`
|
|
22
|
-
| `customParams`
|
|
23
|
-
| `customFloor`
|
|
24
|
-
| `doNotTrack`
|
|
25
|
-
| `coppa`
|
|
18
|
+
| Name | Scope | Type | Description | Example |
|
|
19
|
+
|---------------------------------|----------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------|
|
|
20
|
+
| `delDomain` ~~or `platform`~~** | required | String | OpenX delivery domain provided by your OpenX representative. | "PUBLISHER-d.openx.net" |
|
|
21
|
+
| `unit` | required | String | OpenX ad unit ID provided by your OpenX representative. | "1611023122" |
|
|
22
|
+
| `customParams` | optional | Object | User-defined targeting key-value pairs. customParams applies to a specific unit. | `{key1: "v1", key2: ["v2","v3"]}` |
|
|
23
|
+
| `customFloor` | optional | Number | Minimum price in USD. customFloor applies to a specific unit. For example, use the following value to set a $1.50 floor: 1.50 <br/><br/> **WARNING:**<br/> Misuse of this parameter can impact revenue<br/><br/>Note: OpenX suggests using the [Price Floor Module](https://docs.prebid.org/dev-docs/modules/floors.html) instead of customFloor. The Price Floor Module is prioritized over customFloor if both are present. | 1.50 |
|
|
24
|
+
| `doNotTrack` | optional | Boolean | Prevents advertiser from using data for this user. <br/><br/> **WARNING:**<br/> Request-level setting. May impact revenue. | true |
|
|
25
|
+
| `coppa` | optional | Boolean | Enables Child's Online Privacy Protection Act (COPPA) regulations. | true |
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
** platform is deprecated. Please use delDomain instead. If you have any questions please contact your representative.
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
| ---- | ----- | ---- | ----------- | -------
|
|
31
|
-
| `unit` | required | String | OpenX ad unit ID provided by your OpenX representative. | "1611023122"
|
|
32
|
-
| `delDomain` | required | String | OpenX delivery domain provided by your OpenX representative. | "PUBLISHER-d.openx.net"
|
|
33
|
-
| `openrtb` | optional | OpenRTB Impression | An OpenRtb Impression with Video subtype properties | `{ imp: [{ video: {mimes: ['video/x-ms-wmv, video/mp4']} }] }`
|
|
29
|
+
## Video
|
|
34
30
|
|
|
31
|
+
| Name | Scope | Type | Description | Example |
|
|
32
|
+
|-------------|----------|--------------------|--------------------------------------------------------------|----------------------------------------------------------------|
|
|
33
|
+
| `unit` | required | String | OpenX ad unit ID provided by your OpenX representative. | "1611023122" |
|
|
34
|
+
| `delDomain` | required | String | OpenX delivery domain provided by your OpenX representative. | "PUBLISHER-d.openx.net" |
|
|
35
|
+
| `openrtb` | optional | OpenRTB Impression | An OpenRtb Impression with Video subtype properties | `{ imp: [{ video: {mimes: ['video/x-ms-wmv, video/mp4']} }] }` |
|
|
35
36
|
|
|
36
37
|
# Example
|
|
37
38
|
```javascript
|
|
@@ -170,15 +170,28 @@ function getSiteProperties({publisherId, bcat = []}, refererInfo) {
|
|
|
170
170
|
|
|
171
171
|
function getImps(validBidRequests) {
|
|
172
172
|
return validBidRequests.map((bid, id) => {
|
|
173
|
-
const {tagId
|
|
174
|
-
|
|
175
|
-
return {
|
|
173
|
+
const {tagId} = bid.params;
|
|
174
|
+
const imp = {
|
|
176
175
|
id: id + 1,
|
|
177
176
|
banner: getBanners(bid),
|
|
178
|
-
tagid: tagId
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
177
|
+
tagid: tagId
|
|
178
|
+
}
|
|
179
|
+
if (typeof bid.getFloor === 'function') {
|
|
180
|
+
const floorInfo = bid.getFloor({
|
|
181
|
+
currency: CURRENCY,
|
|
182
|
+
mediaType: BANNER,
|
|
183
|
+
size: '*'
|
|
184
|
+
});
|
|
185
|
+
if (typeof floorInfo === 'object' && floorInfo.currency === CURRENCY && !isNaN(parseFloat(floorInfo.floor))) {
|
|
186
|
+
imp.bidfloor = parseFloat(floorInfo.floor);
|
|
187
|
+
imp.bidfloorcur = CURRENCY;
|
|
188
|
+
}
|
|
189
|
+
} else {
|
|
190
|
+
const {bidfloor = null, bidfloorcur = CURRENCY} = bid.params;
|
|
191
|
+
imp.bidfloor = bidfloor;
|
|
192
|
+
imp.bidfloorcur = bidfloorcur;
|
|
193
|
+
}
|
|
194
|
+
return imp;
|
|
182
195
|
});
|
|
183
196
|
}
|
|
184
197
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _each, deepAccess, parseSizesInput, parseUrl, uniques, isFn } from '../src/utils.js';
|
|
2
2
|
import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
3
|
-
import { BANNER } from '../src/mediaTypes.js';
|
|
3
|
+
import { BANNER, VIDEO } from '../src/mediaTypes.js';
|
|
4
4
|
import { getStorageManager } from '../src/storageManager.js';
|
|
5
5
|
import { bidderSettings } from '../src/bidderSettings.js';
|
|
6
6
|
|
|
@@ -59,7 +59,7 @@ function isBidRequestValid(bid) {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function buildRequest(bid, topWindowUrl, sizes, bidderRequest) {
|
|
62
|
-
const { params, bidId, userId, adUnitCode, schain } = bid;
|
|
62
|
+
const { params, bidId, userId, adUnitCode, schain, mediaTypes } = bid;
|
|
63
63
|
const { ext } = params;
|
|
64
64
|
let { bidFloor } = params;
|
|
65
65
|
const hashUrl = hashCode(topWindowUrl);
|
|
@@ -105,6 +105,7 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest) {
|
|
|
105
105
|
prebidVersion: '$prebid.version$',
|
|
106
106
|
res: `${screen.width}x${screen.height}`,
|
|
107
107
|
schain: schain,
|
|
108
|
+
mediaTypes: mediaTypes,
|
|
108
109
|
ptrace: ptrace,
|
|
109
110
|
isStorageAllowed: isStorageAllowed,
|
|
110
111
|
gpid: gpid,
|
|
@@ -188,11 +189,12 @@ function interpretResponse(serverResponse, request) {
|
|
|
188
189
|
|
|
189
190
|
try {
|
|
190
191
|
results.forEach(result => {
|
|
191
|
-
const { creativeId, ad, price, exp, width, height, currency, advertiserDomains } = result;
|
|
192
|
+
const { creativeId, ad, price, exp, width, height, currency, advertiserDomains, mediaType = BANNER } = result;
|
|
192
193
|
if (!ad || !price) {
|
|
193
194
|
return;
|
|
194
195
|
}
|
|
195
|
-
|
|
196
|
+
|
|
197
|
+
const response = {
|
|
196
198
|
requestId: bidId,
|
|
197
199
|
cpm: price,
|
|
198
200
|
width: width,
|
|
@@ -201,11 +203,22 @@ function interpretResponse(serverResponse, request) {
|
|
|
201
203
|
currency: currency || CURRENCY,
|
|
202
204
|
netRevenue: true,
|
|
203
205
|
ttl: exp || TTL_SECONDS,
|
|
204
|
-
ad: ad,
|
|
205
206
|
meta: {
|
|
206
207
|
advertiserDomains: advertiserDomains || []
|
|
207
208
|
}
|
|
208
|
-
}
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
if (mediaType === BANNER) {
|
|
212
|
+
Object.assign(response, {
|
|
213
|
+
ad: ad,
|
|
214
|
+
});
|
|
215
|
+
} else {
|
|
216
|
+
Object.assign(response, {
|
|
217
|
+
vastXml: ad,
|
|
218
|
+
mediaType: VIDEO
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
output.push(response);
|
|
209
222
|
});
|
|
210
223
|
return output;
|
|
211
224
|
} catch (e) {
|
|
@@ -322,7 +335,7 @@ export const spec = {
|
|
|
322
335
|
code: BIDDER_CODE,
|
|
323
336
|
version: BIDDER_VERSION,
|
|
324
337
|
gvlid: GVLID,
|
|
325
|
-
supportedMediaTypes: [BANNER],
|
|
338
|
+
supportedMediaTypes: [BANNER, VIDEO],
|
|
326
339
|
isBidRequestValid,
|
|
327
340
|
buildRequests,
|
|
328
341
|
interpretResponse,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prebid.js",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.28.0",
|
|
4
4
|
"description": "Header Bidding Management Library",
|
|
5
5
|
"main": "src/prebid.js",
|
|
6
6
|
"scripts": {
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
"express": "^4.15.4",
|
|
131
131
|
"fun-hooks": "^0.9.9",
|
|
132
132
|
"just-clone": "^1.0.2",
|
|
133
|
-
"live-connect-js": "
|
|
133
|
+
"live-connect-js": "3.0.1"
|
|
134
134
|
},
|
|
135
135
|
"optionalDependencies": {
|
|
136
136
|
"fsevents": "^2.3.2"
|
package/src/auction.js
CHANGED
|
@@ -828,6 +828,16 @@ export const getAdvertiserDomain = () => {
|
|
|
828
828
|
}
|
|
829
829
|
}
|
|
830
830
|
|
|
831
|
+
/**
|
|
832
|
+
* This function returns a function to get the primary category id from bid response meta
|
|
833
|
+
* @returns {function}
|
|
834
|
+
*/
|
|
835
|
+
export const getPrimaryCatId = () => {
|
|
836
|
+
return (bid) => {
|
|
837
|
+
return (bid.meta && bid.meta.primaryCatId) ? bid.meta.primaryCatId : '';
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
831
841
|
// factory for key value objs
|
|
832
842
|
function createKeyVal(key, value) {
|
|
833
843
|
return {
|
|
@@ -853,6 +863,7 @@ function defaultAdserverTargeting() {
|
|
|
853
863
|
createKeyVal(TARGETING_KEYS.SOURCE, 'source'),
|
|
854
864
|
createKeyVal(TARGETING_KEYS.FORMAT, 'mediaType'),
|
|
855
865
|
createKeyVal(TARGETING_KEYS.ADOMAIN, getAdvertiserDomain()),
|
|
866
|
+
createKeyVal(TARGETING_KEYS.ACAT, getPrimaryCatId()),
|
|
856
867
|
]
|
|
857
868
|
}
|
|
858
869
|
|
|
@@ -865,7 +876,6 @@ function defaultAdserverTargeting() {
|
|
|
865
876
|
export function getStandardBidderSettings(mediaType, bidderCode) {
|
|
866
877
|
const TARGETING_KEYS = CONSTANTS.TARGETING_KEYS;
|
|
867
878
|
const standardSettings = Object.assign({}, bidderSettings.settingsFor(null));
|
|
868
|
-
|
|
869
879
|
if (!standardSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]) {
|
|
870
880
|
standardSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING] = defaultAdserverTargeting();
|
|
871
881
|
}
|
package/src/constants.json
CHANGED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a walkable linked list of window-like objects for testing.
|
|
3
|
+
*
|
|
4
|
+
* @param {Array} urls Array of URL strings starting from the top window.
|
|
5
|
+
* @param {string} [topReferrer]
|
|
6
|
+
* @param {string} [canonicalUrl]
|
|
7
|
+
* @param {boolean} [ancestorOrigins]
|
|
8
|
+
* @returns {Object}
|
|
9
|
+
*/
|
|
10
|
+
export function buildWindowTree(urls, topReferrer = null, canonicalUrl = null, ancestorOrigins = false) {
|
|
11
|
+
/**
|
|
12
|
+
* Find the origin from a given fully-qualified URL.
|
|
13
|
+
*
|
|
14
|
+
* @param {string} url The fully qualified URL
|
|
15
|
+
* @returns {string|null}
|
|
16
|
+
*/
|
|
17
|
+
function getOrigin(url) {
|
|
18
|
+
const originRegex = new RegExp('^(https?://[^/]+/?)');
|
|
19
|
+
|
|
20
|
+
const result = originRegex.exec(url);
|
|
21
|
+
|
|
22
|
+
if (result && result[0]) {
|
|
23
|
+
return result[0];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const inaccessibles = [];
|
|
30
|
+
|
|
31
|
+
let previousWindow, topWindow;
|
|
32
|
+
const topOrigin = getOrigin(urls[0]);
|
|
33
|
+
|
|
34
|
+
const windowList = urls.map((url, index) => {
|
|
35
|
+
const thisOrigin = getOrigin(url),
|
|
36
|
+
sameOriginAsPrevious = index === 0 ? true : (getOrigin(urls[index - 1]) === thisOrigin),
|
|
37
|
+
sameOriginAsTop = thisOrigin === topOrigin;
|
|
38
|
+
|
|
39
|
+
const win = {
|
|
40
|
+
location: {
|
|
41
|
+
href: url,
|
|
42
|
+
},
|
|
43
|
+
document: {
|
|
44
|
+
referrer: index === 0 ? topReferrer : urls[index - 1]
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
if (topWindow == null) {
|
|
49
|
+
topWindow = win;
|
|
50
|
+
win.document.querySelector = function (selector) {
|
|
51
|
+
if (selector === 'link[rel=\'canonical\']') {
|
|
52
|
+
return {
|
|
53
|
+
href: canonicalUrl
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (sameOriginAsPrevious) {
|
|
61
|
+
win.parent = previousWindow;
|
|
62
|
+
} else {
|
|
63
|
+
win.parent = inaccessibles[inaccessibles.length - 1];
|
|
64
|
+
}
|
|
65
|
+
if (ancestorOrigins) {
|
|
66
|
+
win.location.ancestorOrigins = urls.slice(0, index).reverse().map(getOrigin);
|
|
67
|
+
}
|
|
68
|
+
win.top = sameOriginAsTop ? topWindow : inaccessibles[0];
|
|
69
|
+
|
|
70
|
+
const inWin = {parent: inaccessibles[inaccessibles.length - 1], top: inaccessibles[0]};
|
|
71
|
+
if (index === 0) {
|
|
72
|
+
inWin.top = inWin;
|
|
73
|
+
}
|
|
74
|
+
['document', 'location'].forEach((prop) => {
|
|
75
|
+
Object.defineProperty(inWin, prop, {
|
|
76
|
+
get: function () {
|
|
77
|
+
throw new Error('cross-origin access');
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
inaccessibles.push(inWin);
|
|
82
|
+
previousWindow = win;
|
|
83
|
+
|
|
84
|
+
return win;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return windowList[windowList.length - 1];
|
|
88
|
+
}
|
|
@@ -186,7 +186,8 @@ describe('auctionmanager.js', function () {
|
|
|
186
186
|
source: 'client',
|
|
187
187
|
mediaType: 'banner',
|
|
188
188
|
meta: {
|
|
189
|
-
advertiserDomains: ['adomain']
|
|
189
|
+
advertiserDomains: ['adomain'],
|
|
190
|
+
primaryCatId: 'IAB-test'
|
|
190
191
|
}
|
|
191
192
|
};
|
|
192
193
|
|
|
@@ -200,6 +201,7 @@ describe('auctionmanager.js', function () {
|
|
|
200
201
|
expected[ CONSTANTS.TARGETING_KEYS.SOURCE ] = bid.source;
|
|
201
202
|
expected[ CONSTANTS.TARGETING_KEYS.FORMAT ] = bid.mediaType;
|
|
202
203
|
expected[ CONSTANTS.TARGETING_KEYS.ADOMAIN ] = bid.meta.advertiserDomains[0];
|
|
204
|
+
expected[ CONSTANTS.TARGETING_KEYS.ACAT ] = bid.meta.primaryCatId;
|
|
203
205
|
if (bid.mediaType === 'video') {
|
|
204
206
|
expected[ CONSTANTS.TARGETING_KEYS.UUID ] = bid.videoCacheKey;
|
|
205
207
|
expected[ CONSTANTS.TARGETING_KEYS.CACHE_ID ] = bid.videoCacheKey;
|
|
@@ -290,6 +292,12 @@ describe('auctionmanager.js', function () {
|
|
|
290
292
|
val: function (bidResponse) {
|
|
291
293
|
return bidResponse.meta.advertiserDomains[0];
|
|
292
294
|
}
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
key: CONSTANTS.TARGETING_KEYS.ACAT,
|
|
298
|
+
val: function (bidResponse) {
|
|
299
|
+
return bidResponse.meta.primaryCatId;
|
|
300
|
+
}
|
|
293
301
|
}
|
|
294
302
|
]
|
|
295
303
|
|
|
@@ -367,6 +375,12 @@ describe('auctionmanager.js', function () {
|
|
|
367
375
|
val: function (bidResponse) {
|
|
368
376
|
return bidResponse.meta.advertiserDomains[0];
|
|
369
377
|
}
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
key: CONSTANTS.TARGETING_KEYS.ACAT,
|
|
381
|
+
val: function (bidResponse) {
|
|
382
|
+
return bidResponse.meta.primaryCatId;
|
|
383
|
+
}
|
|
370
384
|
}
|
|
371
385
|
]
|
|
372
386
|
|
|
@@ -455,6 +469,24 @@ describe('auctionmanager.js', function () {
|
|
|
455
469
|
assert.deepEqual(response, expected);
|
|
456
470
|
});
|
|
457
471
|
|
|
472
|
+
it('Should set targeting as expecting when pbs is enabled', function () {
|
|
473
|
+
config.setConfig({
|
|
474
|
+
s2sConfig: {
|
|
475
|
+
accountId: '1',
|
|
476
|
+
enabled: true,
|
|
477
|
+
defaultVendor: 'appnexus',
|
|
478
|
+
bidders: ['appnexus'],
|
|
479
|
+
timeout: 1000,
|
|
480
|
+
adapter: 'prebidServer'
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
$$PREBID_GLOBAL$$.bidderSettings = {};
|
|
485
|
+
let expected = getDefaultExpected(bid);
|
|
486
|
+
let response = getKeyValueTargetingPairs(bid.bidderCode, bid);
|
|
487
|
+
assert.deepEqual(response, expected);
|
|
488
|
+
});
|
|
489
|
+
|
|
458
490
|
it('Custom bidCpmAdjustment for one bidder and inherit standard but doesn\'t use standard bidCpmAdjustment', function () {
|
|
459
491
|
$$PREBID_GLOBAL$$.bidderSettings =
|
|
460
492
|
{
|
|
@@ -43,7 +43,10 @@ describe('33acrossIdSystem', () => {
|
|
|
43
43
|
|
|
44
44
|
expect(request.method).to.equal('GET');
|
|
45
45
|
expect(request.withCredentials).to.be.true;
|
|
46
|
-
|
|
46
|
+
|
|
47
|
+
const regExp = new RegExp('https://lexicon.33across.com/v1/envelope\\?pid=12345&gdpr=\\d&src=pbjs&ver=$prebid.version$');
|
|
48
|
+
|
|
49
|
+
expect(request.url).to.match(regExp);
|
|
47
50
|
expect(completeCallback.calledOnceWithExactly('foo')).to.be.true;
|
|
48
51
|
});
|
|
49
52
|
|
|
@@ -60,6 +60,12 @@ describe('adhashBidAdapter', function () {
|
|
|
60
60
|
bid.params.platformURL = 'https://';
|
|
61
61
|
expect(spec.isBidRequestValid(bid)).to.equal(false);
|
|
62
62
|
});
|
|
63
|
+
|
|
64
|
+
it('should return false when bidderURL is present but not https://', function () {
|
|
65
|
+
const bid = { ...validBid };
|
|
66
|
+
bid.params.bidderURL = 'http://example.com/';
|
|
67
|
+
expect(spec.isBidRequestValid(bid)).to.equal(false);
|
|
68
|
+
});
|
|
63
69
|
});
|
|
64
70
|
|
|
65
71
|
describe('buildRequests', function () {
|
|
@@ -73,11 +79,11 @@ describe('adhashBidAdapter', function () {
|
|
|
73
79
|
it('should build the request correctly', function () {
|
|
74
80
|
const result = spec.buildRequests(
|
|
75
81
|
[ bidRequest ],
|
|
76
|
-
{ gdprConsent: { gdprApplies: true, consentString: 'example' }, refererInfo: {
|
|
82
|
+
{ gdprConsent: { gdprApplies: true, consentString: 'example' }, refererInfo: { topmostLocation: 'https://example.com/path.html' } }
|
|
77
83
|
);
|
|
78
84
|
expect(result.length).to.equal(1);
|
|
79
85
|
expect(result[0].method).to.equal('POST');
|
|
80
|
-
expect(result[0].url).to.equal('https://bidder.adhash.com/rtb?version=
|
|
86
|
+
expect(result[0].url).to.equal('https://bidder.adhash.com/rtb?version=3.2&prebid=true&publisher=0xc3b09b27e9c6ef73957901aa729b9e69e5bbfbfb');
|
|
81
87
|
expect(result[0].bidRequest).to.equal(bidRequest);
|
|
82
88
|
expect(result[0].data).to.have.property('timezone');
|
|
83
89
|
expect(result[0].data).to.have.property('location');
|
|
@@ -93,7 +99,7 @@ describe('adhashBidAdapter', function () {
|
|
|
93
99
|
const result = spec.buildRequests([ bidRequest ], { gdprConsent: { gdprApplies: true, consentString: 'example' } });
|
|
94
100
|
expect(result.length).to.equal(1);
|
|
95
101
|
expect(result[0].method).to.equal('POST');
|
|
96
|
-
expect(result[0].url).to.equal('https://bidder.adhash.com/rtb?version=
|
|
102
|
+
expect(result[0].url).to.equal('https://bidder.adhash.com/rtb?version=3.2&prebid=true&publisher=0xc3b09b27e9c6ef73957901aa729b9e69e5bbfbfb');
|
|
97
103
|
expect(result[0].bidRequest).to.equal(bidRequest);
|
|
98
104
|
expect(result[0].data).to.have.property('timezone');
|
|
99
105
|
expect(result[0].data).to.have.property('location');
|
|
@@ -127,9 +133,15 @@ describe('adhashBidAdapter', function () {
|
|
|
127
133
|
creatives: [{ costEUR: 1.234 }],
|
|
128
134
|
advertiserDomains: 'adhash.com',
|
|
129
135
|
badWords: [
|
|
130
|
-
['
|
|
131
|
-
['
|
|
136
|
+
['onqjbeq', 'full', 1],
|
|
137
|
+
['onqjbeqo', 'partial', 1],
|
|
132
138
|
['tbbqjbeq', 'full', -1],
|
|
139
|
+
['fgnegf', 'starts', 1],
|
|
140
|
+
['raqf', 'ends', 1],
|
|
141
|
+
['kkk[no]lll', 'regexp', 1],
|
|
142
|
+
['дума', 'full', 1],
|
|
143
|
+
['старт', 'starts', 1],
|
|
144
|
+
['край', 'ends', 1],
|
|
133
145
|
],
|
|
134
146
|
maxScore: 2
|
|
135
147
|
}
|
|
@@ -155,42 +167,84 @@ describe('adhashBidAdapter', function () {
|
|
|
155
167
|
|
|
156
168
|
it('should return empty array when there are bad words (full)', function () {
|
|
157
169
|
bodyStub = sinon.stub(window.top.document.body, 'innerText').get(function() {
|
|
158
|
-
return 'example text
|
|
170
|
+
return 'example text badword badword example badword text' + ' word'.repeat(993);
|
|
171
|
+
});
|
|
172
|
+
expect(spec.interpretResponse(serverResponse, request).length).to.equal(0);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('should return empty array when there are bad words (full cyrillic)', function () {
|
|
176
|
+
bodyStub = sinon.stub(window.top.document.body, 'innerText').get(function() {
|
|
177
|
+
return 'example text дума дума example дума text' + ' текст'.repeat(993);
|
|
159
178
|
});
|
|
160
179
|
expect(spec.interpretResponse(serverResponse, request).length).to.equal(0);
|
|
161
180
|
});
|
|
162
181
|
|
|
163
182
|
it('should return empty array when there are bad words (partial)', function () {
|
|
164
183
|
bodyStub = sinon.stub(window.top.document.body, 'innerText').get(function() {
|
|
165
|
-
return 'example text
|
|
184
|
+
return 'example text partialbadwordb badwordb example badwordbtext' + ' word'.repeat(994);
|
|
185
|
+
});
|
|
186
|
+
expect(spec.interpretResponse(serverResponse, request).length).to.equal(0);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('should return empty array when there are bad words (starts)', function () {
|
|
190
|
+
bodyStub = sinon.stub(window.top.document.body, 'innerText').get(function() {
|
|
191
|
+
return 'example text startsWith starts text startsAgain' + ' word'.repeat(994);
|
|
192
|
+
});
|
|
193
|
+
expect(spec.interpretResponse(serverResponse, request).length).to.equal(0);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('should return empty array when there are bad words (starts cyrillic)', function () {
|
|
197
|
+
bodyStub = sinon.stub(window.top.document.body, 'innerText').get(function() {
|
|
198
|
+
return 'example text стартТекст старт text стартТекст' + ' дума'.repeat(994);
|
|
199
|
+
});
|
|
200
|
+
expect(spec.interpretResponse(serverResponse, request).length).to.equal(0);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it('should return empty array when there are bad words (ends)', function () {
|
|
204
|
+
bodyStub = sinon.stub(window.top.document.body, 'innerText').get(function() {
|
|
205
|
+
return 'example text wordEnds ends text anotherends' + ' word'.repeat(994);
|
|
206
|
+
});
|
|
207
|
+
expect(spec.interpretResponse(serverResponse, request).length).to.equal(0);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('should return empty array when there are bad words (ends cyrillic)', function () {
|
|
211
|
+
bodyStub = sinon.stub(window.top.document.body, 'innerText').get(function() {
|
|
212
|
+
return 'example text ДругКрай край text ощеединкрай' + ' дума'.repeat(994);
|
|
213
|
+
});
|
|
214
|
+
expect(spec.interpretResponse(serverResponse, request).length).to.equal(0);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('should return empty array when there are bad words (regexp)', function () {
|
|
218
|
+
bodyStub = sinon.stub(window.top.document.body, 'innerText').get(function() {
|
|
219
|
+
return 'example text xxxayyy zzxxxAyyyzz text xxxbyyy' + ' word'.repeat(994);
|
|
166
220
|
});
|
|
167
221
|
expect(spec.interpretResponse(serverResponse, request).length).to.equal(0);
|
|
168
222
|
});
|
|
169
223
|
|
|
170
224
|
it('should return non-empty array when there are not enough bad words (full)', function () {
|
|
171
225
|
bodyStub = sinon.stub(window.top.document.body, 'innerText').get(function() {
|
|
172
|
-
return 'example text
|
|
226
|
+
return 'example text badword badword example text' + ' word'.repeat(994);
|
|
173
227
|
});
|
|
174
228
|
expect(spec.interpretResponse(serverResponse, request).length).to.equal(1);
|
|
175
229
|
});
|
|
176
230
|
|
|
177
231
|
it('should return non-empty array when there are not enough bad words (partial)', function () {
|
|
178
232
|
bodyStub = sinon.stub(window.top.document.body, 'innerText').get(function() {
|
|
179
|
-
return 'example text
|
|
233
|
+
return 'example text partialbadwordb example' + ' word'.repeat(996);
|
|
180
234
|
});
|
|
181
235
|
expect(spec.interpretResponse(serverResponse, request).length).to.equal(1);
|
|
182
236
|
});
|
|
183
237
|
|
|
184
238
|
it('should return non-empty array when there are no-bad word matches', function () {
|
|
185
239
|
bodyStub = sinon.stub(window.top.document.body, 'innerText').get(function() {
|
|
186
|
-
return 'example text
|
|
240
|
+
return 'example text partialbadword example text' + ' word'.repeat(995);
|
|
187
241
|
});
|
|
188
242
|
expect(spec.interpretResponse(serverResponse, request).length).to.equal(1);
|
|
189
243
|
});
|
|
190
244
|
|
|
191
245
|
it('should return non-empty array when there are bad words and good words', function () {
|
|
192
246
|
bodyStub = sinon.stub(window.top.document.body, 'innerText').get(function() {
|
|
193
|
-
return 'example text
|
|
247
|
+
return 'example text badword badword example badword goodWord goodWord ' + ' word'.repeat(992);
|
|
194
248
|
});
|
|
195
249
|
expect(spec.interpretResponse(serverResponse, request).length).to.equal(1);
|
|
196
250
|
});
|
|
@@ -167,6 +167,45 @@ describe('Taboola Adapter', function () {
|
|
|
167
167
|
expect(resData.imp[0].bidfloorcur).to.deep.equal('EUR');
|
|
168
168
|
});
|
|
169
169
|
|
|
170
|
+
it('should pass bid floor', function () {
|
|
171
|
+
const bidRequest = {
|
|
172
|
+
...defaultBidRequest,
|
|
173
|
+
params: {...commonBidRequest.params},
|
|
174
|
+
getFloor: function() {
|
|
175
|
+
return {
|
|
176
|
+
currency: 'USD',
|
|
177
|
+
floor: 2.7,
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
const res = spec.buildRequests([bidRequest], commonBidderRequest);
|
|
182
|
+
const resData = JSON.parse(res.data);
|
|
183
|
+
expect(resData.imp[0].bidfloor).to.deep.equal(2.7);
|
|
184
|
+
expect(resData.imp[0].bidfloorcur).to.deep.equal('USD');
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('should pass bid floor even if they is a bid floor param', function () {
|
|
188
|
+
const optionalParams = {
|
|
189
|
+
bidfloor: 0.25,
|
|
190
|
+
bidfloorcur: 'EUR'
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const bidRequest = {
|
|
194
|
+
...defaultBidRequest,
|
|
195
|
+
params: {...commonBidRequest.params, ...optionalParams},
|
|
196
|
+
getFloor: function() {
|
|
197
|
+
return {
|
|
198
|
+
currency: 'USD',
|
|
199
|
+
floor: 2.7,
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
const res = spec.buildRequests([bidRequest], commonBidderRequest);
|
|
204
|
+
const resData = JSON.parse(res.data);
|
|
205
|
+
expect(resData.imp[0].bidfloor).to.deep.equal(2.7);
|
|
206
|
+
expect(resData.imp[0].bidfloorcur).to.deep.equal('USD');
|
|
207
|
+
});
|
|
208
|
+
|
|
170
209
|
it('should pass bidder timeout', function () {
|
|
171
210
|
const bidderRequest = {
|
|
172
211
|
...commonBidderRequest,
|
|
@@ -2,6 +2,9 @@ import { expect } from 'chai';
|
|
|
2
2
|
import { spec } from 'modules/ttdBidAdapter';
|
|
3
3
|
import { deepClone } from 'src/utils.js';
|
|
4
4
|
import { config } from 'src/config';
|
|
5
|
+
import { detectReferer } from 'src/refererDetection.js';
|
|
6
|
+
|
|
7
|
+
import { buildWindowTree } from '../../helpers/refererDetectionHelper';
|
|
5
8
|
|
|
6
9
|
describe('ttdBidAdapter', function () {
|
|
7
10
|
function testBuildRequests(bidRequests, bidderRequestBase) {
|
|
@@ -200,20 +203,15 @@ describe('ttdBidAdapter', function () {
|
|
|
200
203
|
'bidRequestsCount': 1
|
|
201
204
|
}];
|
|
202
205
|
|
|
206
|
+
const testWindow = buildWindowTree(['https://www.example.com/test', 'https://www.example.com/other/page', 'https://www.example.com/third/page'], 'https://othersite.com/', 'https://example.com/canonical/page');
|
|
207
|
+
const baseBidderRequestReferer = detectReferer(testWindow)();
|
|
203
208
|
const baseBidderRequest = {
|
|
204
209
|
'bidderCode': 'ttd',
|
|
205
210
|
'auctionId': 'e7b34fa3-8654-424e-8c49-03e509e53d8c',
|
|
206
211
|
'bidderRequestId': '18084284054531',
|
|
207
212
|
'auctionStart': 1540945362095,
|
|
208
213
|
'timeout': 3000,
|
|
209
|
-
'refererInfo':
|
|
210
|
-
'page': 'https://www.example.com/test',
|
|
211
|
-
'reachedTop': true,
|
|
212
|
-
'numIframes': 0,
|
|
213
|
-
'stack': [
|
|
214
|
-
'https://www.example.com/test'
|
|
215
|
-
]
|
|
216
|
-
},
|
|
214
|
+
'refererInfo': baseBidderRequestReferer,
|
|
217
215
|
'start': 1540945362099,
|
|
218
216
|
'doneCbCallCount': 0
|
|
219
217
|
};
|
|
@@ -291,6 +289,11 @@ describe('ttdBidAdapter', function () {
|
|
|
291
289
|
expect(requestBody.site.page).to.equal('https://www.example.com/test');
|
|
292
290
|
});
|
|
293
291
|
|
|
292
|
+
it('ensure top most location is used', function () {
|
|
293
|
+
const requestBody = testBuildRequests(baseBannerBidRequests, baseBidderRequest).data;
|
|
294
|
+
expect(requestBody.site.page).to.equal('https://www.example.com/test');
|
|
295
|
+
});
|
|
296
|
+
|
|
294
297
|
it('sets the banner pos correctly if sent', function () {
|
|
295
298
|
let clonedBannerRequests = deepClone(baseBannerBidRequests);
|
|
296
299
|
clonedBannerRequests[0].mediaTypes.banner.pos = 1;
|
|
@@ -318,11 +321,35 @@ describe('ttdBidAdapter', function () {
|
|
|
318
321
|
}
|
|
319
322
|
}
|
|
320
323
|
};
|
|
321
|
-
const
|
|
324
|
+
const baseBidderRequestWithoutRefererDomain = {
|
|
325
|
+
...baseBidderRequest,
|
|
326
|
+
refererInfo: {
|
|
327
|
+
...baseBannerBidRequests.referer,
|
|
328
|
+
domain: null
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
const requestBody = testBuildRequests(
|
|
332
|
+
baseBannerBidRequests, {...baseBidderRequestWithoutRefererDomain, ortb2}
|
|
333
|
+
).data;
|
|
322
334
|
config.resetConfig();
|
|
323
335
|
expect(requestBody.site.publisher).to.deep.equal({domain: 'https://foo.bar', id: '13144370'});
|
|
324
336
|
});
|
|
325
337
|
|
|
338
|
+
it('referer domain overrides first party site data publisher domain', function () {
|
|
339
|
+
const ortb2 = {
|
|
340
|
+
site: {
|
|
341
|
+
publisher: {
|
|
342
|
+
domain: 'https://foo.bar',
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
const requestBody = testBuildRequests(
|
|
347
|
+
baseBannerBidRequests, {...baseBidderRequest, ortb2}
|
|
348
|
+
).data;
|
|
349
|
+
config.resetConfig();
|
|
350
|
+
expect(requestBody.site.publisher.domain).to.equal(baseBidderRequest.refererInfo.domain);
|
|
351
|
+
});
|
|
352
|
+
|
|
326
353
|
it('sets keywords properly if sent', function () {
|
|
327
354
|
const ortb2 = {
|
|
328
355
|
site: {
|