diff --git a/.circleci/config.yml b/.circleci/config.yml
index 73ec23aa740..0d48ec13fa1 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -2,54 +2,93 @@
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
+
+aliases:
+ - &environment
+ docker:
+ # specify the version you desire here
+ - image: circleci/node:8.9.0
+
+ # Specify service dependencies here if necessary
+ # CircleCI maintains a library of pre-built images
+ # documented at https://circleci.com/docs/2.0/circleci-images/
+ # - image: circleci/mongo:3.4.4
+ working_directory: ~/Prebid.js
+
+ - &restore_dep_cache
+ keys:
+ - v1-dependencies-{{ checksum "package.json" }}
+ # fallback to using the latest cache if no exact match is found
+ - v1-dependencies-
+
+ - &save_dep_cache
+ paths:
+ - node_modules
+ key: v1-dependencies-{{ checksum "package.json" }}
+
+ - &install
+ name: Install gulp cli
+ command: sudo npm install -g gulp-cli
+
+ - &run_unit_test
+ name: BrowserStack testing
+ command: gulp test --browserstack --nolintfix
+
+ - &run_endtoend_test
+ name: BrowserStack End to end testing
+ command: echo "127.0.0.1 test.localhost" | sudo tee -a /etc/hosts && gulp e2e-test --host=test.localhost
+
+ # Download and run BrowserStack local
+ - &setup_browserstack
+ name : Download BrowserStack Local binary and start it.
+ command : |
+ # Download the browserstack binary file
+ wget "https://www.browserstack.com/browserstack-local/BrowserStackLocal-linux-x64.zip"
+ # Unzip it
+ unzip BrowserStackLocal-linux-x64.zip
+ # Run the file with user's access key
+ ./BrowserStackLocal ${BROWSERSTACK_ACCESS_KEY} &
+
+ - &unit_test_steps
+ - checkout
+ - restore_cache: *restore_dep_cache
+ - run: npm install
+ - save_cache: *save_dep_cache
+ - run: *install
+ - run: *setup_browserstack
+ - run: *run_unit_test
+
+ - &endtoend_test_steps
+ - checkout
+ - restore_cache: *restore_dep_cache
+ - run: npm install
+ - save_cache: *save_dep_cache
+ - run: *install
+ - run: *setup_browserstack
+ - run: *run_endtoend_test
+
version: 2
jobs:
build:
- docker:
- # specify the version you desire here
- - image: circleci/node:8.9.0
+ <<: *environment
+ steps: *unit_test_steps
- # Specify service dependencies here if necessary
- # CircleCI maintains a library of pre-built images
- # documented at https://circleci.com/docs/2.0/circleci-images/
- # - image: circleci/mongo:3.4.4
-
- working_directory: ~/Prebid.js
-
- steps:
- - checkout
-
- # Download and cache dependencies
- - restore_cache:
- keys:
- - v1-dependencies-{{ checksum "package.json" }}
- # fallback to using the latest cache if no exact match is found
- - v1-dependencies-
-
- - run: npm install
-
- - save_cache:
- paths:
- - node_modules
- key: v1-dependencies-{{ checksum "package.json" }}
-
- - run: sudo npm install -g gulp-cli
-
- # Download and run BrowserStack local
- - run:
- name : Download BrowserStack Local binary and start it.
- command : |
- # Download the browserstack binary file
- wget "https://www.browserstack.com/browserstack-local/BrowserStackLocal-linux-x64.zip"
- # Unzip it
- unzip BrowserStackLocal-linux-x64.zip
- # Run the file with user's access key
- ./BrowserStackLocal ${BROWSERSTACK_ACCESS_KEY} &
- # run tests!
- - run:
- name: BrowserStack testing
- command: gulp test --browserstack --nolintfix
- # run e2e tests
- - run:
- name: Functional testing
- command: echo "127.0.0.1 test.localhost" | sudo tee -a /etc/hosts && gulp e2e-test --host=test.localhost --file=./test/spec/e2e/banner/basic_banner_ad.spec.js
+ e2etest:
+ <<: *environment
+ steps: *endtoend_test_steps
+
+workflows:
+ version: 2
+ commit:
+ jobs:
+ - build
+ nightly:
+ triggers:
+ - schedule:
+ cron: "0 0 * * *"
+ filters:
+ branches:
+ only:
+ - master
+ jobs:
+ - e2etest
diff --git a/integrationExamples/gpt/userId_example.html b/integrationExamples/gpt/userId_example.html
index 09e9e4147fc..6d2c2ce677a 100644
--- a/integrationExamples/gpt/userId_example.html
+++ b/integrationExamples/gpt/userId_example.html
@@ -152,6 +152,17 @@
refreshInSeconds: 8*3600 // Refresh frequency of cookies, defaulting to 'expires'
},
+ }, {
+ name: "parrableId",
+ params: {
+ // change to Parrable Partner Client ID(s) you received from the Parrable Partners you are using
+ partner: '30182847-e426-4ff9-b2b5-9ca1324ea09b'
+ },
+ storage: {
+ type: "cookie",
+ name: "_parrable_eid", // create a cookie with this name
+ expires: 365 // cookie can last for a year
+ }
}, {
name: "pubCommonId",
storage: {
diff --git a/integrationExamples/longform/basic_w_bidderSettings.html b/integrationExamples/longform/basic_w_bidderSettings.html
index 4ccb01fbd6e..f9389686b1f 100644
--- a/integrationExamples/longform/basic_w_bidderSettings.html
+++ b/integrationExamples/longform/basic_w_bidderSettings.html
@@ -5,7 +5,7 @@
utils.isArray(size))
- const processedSizes = bid.sizes.map(size => ({w: parseInt(size[0], 10), h: parseInt(size[1], 10)}))
+
+ let bidSizes = (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) || bid.sizes;
+ bidSizes = ((utils.isArray(bidSizes) && utils.isArray(bidSizes[0])) ? bidSizes : [bidSizes])
+ bidSizes = bidSizes.filter(size => utils.isArray(size))
+ const processedSizes = bidSizes.map(size => ({w: parseInt(size[0], 10), h: parseInt(size[1], 10)}))
sovrnImps.push({
id: bid.bidId,
banner: {
@@ -43,15 +57,30 @@ export const spec = {
bidfloor: utils.getBidIdParameter('bidfloor', bid.params)
});
});
+
+ const page = bidderRequest.refererInfo.referer
+ // clever trick to get the domain
+ const el = document.createElement('a');
+ el.href = page;
+ const domain = el.hostname;
+
const sovrnBidReq = {
id: utils.getUniqueIdentifierStr(),
imp: sovrnImps,
site: {
- domain: loc.host,
- page: loc.host + loc.pathname + loc.search + loc.hash
+ page,
+ domain
}
};
+ if (schain) {
+ sovrnBidReq.source = {
+ ext: {
+ schain
+ }
+ };
+ }
+
if (bidderRequest && bidderRequest.gdprConsent) {
sovrnBidReq.regs = {
ext: {
@@ -63,7 +92,16 @@ export const spec = {
}};
}
- let url = `//ap.lijit.com/rtb/bid?` +
+ if (digitrust) {
+ sovrnBidReq.user = sovrnBidReq.user || {};
+ sovrnBidReq.user.ext = sovrnBidReq.user.ext || {}
+ sovrnBidReq.user.ext.digitrust = {
+ id: digitrust.id,
+ keyv: digitrust.keyv
+ }
+ }
+
+ let url = `https://ap.lijit.com/rtb/bid?` +
`src=$$REPO_AND_VERSION$$`;
if (iv) url += `&iv=${iv}`;
@@ -74,7 +112,8 @@ export const spec = {
options: {contentType: 'text/plain'}
}
} catch (e) {
- new LogError(e, {bidReqs, bidderRequest}).append()
+ console.log('error in build:')
+ console.log(e)
}
},
@@ -109,74 +148,43 @@ export const spec = {
}
return sovrnBidResponses
} catch (e) {
- new LogError(e, {id, seatbid}).append()
+ console.log('error in interpret:')
+ console.log(e)
}
},
getUserSyncs: function(syncOptions, serverResponses, gdprConsent) {
try {
let tracks = []
- if (serverResponses && serverResponses.length !== 0 && syncOptions.iframeEnabled) {
- let iidArr = serverResponses.filter(rsp => rsp.body && rsp.body.ext && rsp.body.ext.iid)
- .map(rsp => { return rsp.body.ext.iid });
- let consentString = '';
- if (gdprConsent && gdprConsent.gdprApplies && typeof gdprConsent.consentString === 'string') {
- consentString = gdprConsent.consentString
+ if (serverResponses && serverResponses.length !== 0) {
+ if (syncOptions.iframeEnabled) {
+ let iidArr = serverResponses.filter(resp => resp.body && resp.body.ext && resp.body.ext.iid)
+ .map(resp => resp.body.ext.iid);
+ let consentString = '';
+ if (gdprConsent && gdprConsent.gdprApplies && typeof gdprConsent.consentString === 'string') {
+ consentString = gdprConsent.consentString
+ }
+ if (iidArr[0]) {
+ tracks.push({
+ type: 'iframe',
+ url: '//ap.lijit.com/beacon?informer=' + iidArr[0] + '&gdpr_consent=' + consentString,
+ });
+ }
}
- if (iidArr[0]) {
- tracks.push({
- type: 'iframe',
- url: '//ap.lijit.com/beacon?informer=' + iidArr[0] + '&gdpr_consent=' + consentString,
- });
+
+ if (syncOptions.pixelEnabled) {
+ serverResponses.filter(resp => resp.body && resp.body.ext && resp.body.ext.sync && resp.body.ext.sync.pixels)
+ .flatMap(resp => resp.body.ext.sync.pixels)
+ .map(pixel => pixel.url)
+ .forEach(url => tracks.push({ type: 'image', url }))
}
}
- if (errorpxls.length && syncOptions.pixelEnabled) {
- tracks = tracks.concat(errorpxls)
- }
+
return tracks
} catch (e) {
- if (syncOptions.pixelEnabled) {
- return errorpxls
- }
return []
}
},
}
-export class LogError {
- constructor(e, data) {
- utils.logError(e)
- this.error = {}
- this.error.t = utils.timestamp()
- this.error.m = e.message
- this.error.s = e.stack
- this.error.d = data
- this.error.v = $$REPO_AND_VERSION$$
- this.error.u = utils.getTopWindowLocation().href
- this.error.ua = navigator.userAgent
- }
- buildErrorString(obj) {
- return errorUrl + '?b=' + btoa(JSON.stringify(obj))
- }
- append() {
- let errstr = this.buildErrorString(this.error)
- if (errstr.length > 2083) {
- delete this.error.d
- errstr = this.buildErrorString(this.error)
- if (errstr.length > 2083) {
- delete this.error.s
- errstr = this.buildErrorString(this.error)
- if (errstr.length > 2083) {
- errstr = this.buildErrorString({m: 'unknown error message', t: this.error.t, u: this.error.u})
- }
- }
- }
- let obj = {type: 'image', url: errstr}
- errorpxls.push(obj)
- }
- static getErrPxls() {
- return errorpxls
- }
-}
-
registerBidder(spec);
diff --git a/modules/spotxBidAdapter.js b/modules/spotxBidAdapter.js
index 6e374b991d3..45a3c925221 100644
--- a/modules/spotxBidAdapter.js
+++ b/modules/spotxBidAdapter.js
@@ -6,6 +6,7 @@ import { VIDEO } from '../src/mediaTypes';
const BIDDER_CODE = 'spotx';
const URL = '//search.spotxchange.com/openrtb/2.3/dados/';
const ORTB_VERSION = '2.3';
+export const GOOGLE_CONSENT = { consented_providers: ['3', '7', '11', '12', '15', '20', '22', '35', '43', '46', '48', '55', '57', '61', '62', '66', '70', '80', '83', '85', '86', '89', '93', '108', '122', '124', '125', '126', '131', '134', '135', '136', '143', '144', '147', '149', '153', '154', '159', '161', '162', '165', '167', '171', '178', '184', '188', '192', '195', '196', '202', '209', '211', '218', '221', '228', '229', '230', '236', '239', '241', '253', '255', '259', '266', '271', '272', '274', '286', '291', '294', '303', '308', '310', '311', '313', '314', '316', '317', '322', '323', '327', '336', '338', '340', '348', '350', '358', '359', '363', '367', '370', '371', '384', '385', '389', '393', '394', '397', '398', '407', '414', '415', '424', '429', '430', '432', '436', '438', '440', '442', '443', '445', '448', '449', '453', '459', '479', '482', '486', '491', '492', '494', '495', '503', '505', '510', '522', '523', '528', '537', '540', '550', '559', '560', '568', '571', '574', '575', '576', '584', '585', '587', '588', '590', '591', '592', '595', '609', '621', '624', '723', '725', '733', '737', '776', '780', '782', '787', '797', '798', '802', '803', '814', '817', '820', '821', '827', '829', '839', '853', '864', '867', '874', '899', '904', '922', '926', '931', '932', '933', '938', '955', '973', '976', '979', '981', '985', '987', '991', '1003', '1024', '1025', '1027', '1028', '1029', '1033', '1034', '1040', '1047', '1048', '1051', '1052', '1053', '1054', '1062', '1063', '1067', '1072', '1085', '1092', '1095', '1097', '1099', '1100', '1107', '1126', '1127', '1143', '1149', '1152', '1162', '1166', '1167', '1170', '1171', '1172', '1188', '1192', '1199', '1201', '1204', '1205', '1211', '1212', '1215', '1220', '1225', '1226', '1227', '1230', '1232', '1236', '1241', '1248', '1250', '1252', '1268', '1275', '1276', '1284', '1286', '1298', '1301', '1307', '1312', '1313', '1317', '1329', '1336', '1344', '1345', '1356', '1362', '1365', '1375', '1403', '1409', '1411', '1415', '1416', '1419', '1423', '1440', '1442', '1449', '1451', '1455', '1456', '1468', '1496', '1503', '1509', '1512', '1514', '1517', '1520', '1525', '1540', '1547', '1548', '1555', '1558', '1570', '1575', '1577', '1579', '1583', '1584', '1591', '1598', '1603', '1608', '1613', '1616', '1626', '1631', '1633', '1638', '1642', '1648', '1651', '1652', '1653', '1660', '1665', '1667', '1669', '1671', '1674', '1677', '1678', '1682', '1684', '1697', '1703', '1705', '1716', '1720', '1721', '1722', '1725', '1732', '1733', '1735', '1739', '1741', '1745', '1750', '1753', '1760', '1765', '1769', '1776', '1780', '1782', '1786', '1791', '1794', '1799', '1800', '1801', '1810', '1827', '1831', '1832', '1834', '1837', '1840', '1843', '1844', '1845', '1858', '1859', '1863', '1866', '1870', '1872', '1875', '1878', '1880', '1882', '1883', '1889', '1892', '1896', '1898', '1899', '1902', '1905', '1911', '1922', '1928', '1929', '1934', '1942', '1943', '1944', '1945', '1958', '1960', '1962', '1963', '1964', '1967', '1968', '1978', '1985', '1986', '1987', '1998', '2003', '2007', '2012', '2013', '2027', '2035', '2038', '2039', '2044', '2047', '2052', '2056', '2059', '2062', '2064', '2068', '2070', '2072', '2078', '2079', '2084', '2088', '2090', '2095', '2100', '2103', '2107', '2109', '2113', '2115', '2121', '2127', '2130', '2133', '2137', '2140', '2141', '2145', '2147', '2150', '2156', '2166', '2170', '2171', '2176', '2177', '2179', '2183', '2186', '2192', '2198', '2202', '2205', '2214', '2216', '2219', '2220', '2222', '2223', '2224', '2225', '2227', '2228', '2234', '2238', '2247', '2251', '2253', '2262', '2264', '2271', '2276', '2278', '2279', '2282', '2290', '2292', '2295', '2299', '2305', '2306', '2310', '2311', '2312', '2315', '2320', '2325', '2328', '2331', '2334', '2335', '2336', '2337', '2343', '2346', '2354', '2357', '2358', '2359', '2366', '2370', '2373', '2376', '2377', '2380', '2382', '2387', '2389', '2392', '2394', '2400', '2403', '2405', '2406', '2407', '2410', '2411', '2413', '2414', '2415', '2416', '2418', '2422', '2425', '2427', '2435', '2437', '2440', '2441', '2447', '2453', '2459', '2461', '2462', '2464', '2467', '2468', '2472', '2477', '2481', '2484', '2486', '2492', '2493', '2496', '2497', '2498', '2499', '2504', '2506', '2510', '2511', '2512', '2517', '2526', '2527', '2531', '2532', '2534', '2542', '2544', '2552', '2555', '2559', '2563', '2564', '2567', '2568', '2569', '2571', '2572', '2573', '2575', '2577', '2579', '2583', '2584', '2586', '2589', '2595', '2596', '2597', '2601', '2604', '2605', '2609', '2610', '2612', '2614', '2621', '2622', '2624', '2628', '2629', '2632', '2634', '2636', '2639', '2643', '2645', '2646', '2647', '2649', '2650', '2651', '2652', '2656', '2657', '2658', '2660', '2661', '2662', '2663', '2664', '2669', '2670', '2673', '2676', '2677', '2678', '2681', '2682', '2684', '2685', '2686', '2689', '2690', '2691', '2695', '2698', '2699', '2702', '2704', '2705', '2706', '2707', '2709', '2710', '2713', '2714', '2727', '2729', '2739', '2758', '2765', '2766', '2767', '2768', '2770', '2771', '2772', '2776', '2777', '2778', '2779', '2780', '2783', '2784', '2786', '2787', '2791', '2792', '2793', '2797', '2798', '2801', '2802', '2803', '2805', '2808', '2809', '2810', '2811', '2812', '2813', '2814', '2817', '2818', '2824', '2826', '2827', '2829', '2830', '2831', '2832', '2834', '2836', '2838', '2840', '2842', '2843', '2844', '2850', '2851', '2852', '2854', '2858', '2860', '2862', '2864', '2865', '2866', '2867', '2868', '2869', '2871'] };
export const spec = {
code: BIDDER_CODE,
@@ -192,6 +193,10 @@ export const spec = {
const userExt = {};
+ if (utils.getBidIdParameter('spotx_all_google_consent', bid.params) == 1) {
+ userExt['consented_providers_settings'] = GOOGLE_CONSENT;
+ }
+
// Add GDPR flag and consent string
if (bidderRequest && bidderRequest.gdprConsent) {
userExt.consent = bidderRequest.gdprConsent.consentString;
@@ -205,11 +210,30 @@ export const spec = {
}
}
+ // ID5 fied
+ if (bid && bid.userId && bid.userId.id5id) {
+ userExt.eids = [{
+ source: 'id5-sync.com',
+ uids: [{
+ id: bid.userId.id5id
+ }]
+ }];
+ }
+
// Add common id if available
if (pubcid) {
userExt.fpc = pubcid;
}
+ // Add schain object if it is present
+ if (bid && bid.schain) {
+ requestPayload['ext']['source'] = {
+ ext: {
+ schain: bid.schain
+ }
+ };
+ }
+
// Only add the user object if it's not empty
if (!utils.isEmpty(userExt)) {
requestPayload.user = { ext: userExt };
diff --git a/modules/spotxBidAdapter.md b/modules/spotxBidAdapter.md
index 038c698a259..0bd1cf71aa1 100644
--- a/modules/spotxBidAdapter.md
+++ b/modules/spotxBidAdapter.md
@@ -63,7 +63,8 @@ This adapter requires setup and approval from the SpotX team.
continue_out_of_view: '1',
ad_volume: '100',
content_container_id: 'video1',
- hide_skin: '1'
+ hide_skin: '1',
+ spotx_all_google_consent: '1'
}
}
}
@@ -121,7 +122,6 @@ function myOutstreamFunction(bid) {
script.setAttribute('data-spotx_click_to_replay', '1');
script.setAttribute('data-spotx_continue_out_of_view', '1');
script.setAttribute('data-spotx_ad_volume', '100');
- script.setAttribute('data-spotx_hide_skin', '1');
if (bid.renderer.config.inIframe && window.document.getElementById(bid.renderer.config.inIframe).nodeName == 'IFRAME') {
let rawframe = window.document.getElementById(bid.renderer.config.inIframe);
let framedoc = rawframe.contentDocument;
diff --git a/modules/userId/index.js b/modules/userId/index.js
index 8302a7a89e3..ac96fd2cec8 100644
--- a/modules/userId/index.js
+++ b/modules/userId/index.js
@@ -71,6 +71,8 @@
* @property {(boolean|undefined)} create - create id if missing. default is true.
* @property {(boolean|undefined)} extend - extend expiration time on each access. default is false.
* @property {(string|undefined)} pid - placement id url param value
+ * @property {(string|undefined)} publisherId - the unique identifier of the publisher in question
+ * @property {(array|undefined)} identifiersToResolve - the identifiers from either ls|cookie to be attached to the getId query
*/
/**
@@ -369,6 +371,7 @@ function initSubmodules(submodules, consentData) {
utils.logWarn(`${MODULE_NAME} - gdpr permission not valid for local storage or cookies, exit module`);
return [];
}
+
return submodules.reduce((carry, submodule) => {
// There are two submodule configuration types to handle: storage or value
// 1. storage: retrieve user id data from cookie/html storage or with the submodule's getId method
diff --git a/modules/userId/userId.md b/modules/userId/userId.md
index 9f71d59e5e1..b10aa2adc20 100644
--- a/modules/userId/userId.md
+++ b/modules/userId/userId.md
@@ -32,6 +32,17 @@ pbjs.setConfig({
name: "id5id",
expires: 5, // Expiration of cookies in days
refreshInSeconds: 8*3600 // User Id cache lifetime in seconds, defaulting to 'expires'
+ },
+ }, {
+ name: 'parrableId',
+ params: {
+ // Replace partner with comma-separated (if more than one) Parrable Partner Client ID(s) for Parrable-aware bid adapters in use
+ partner: "30182847-e426-4ff9-b2b5-9ca1324ea09b"
+ },
+ storage: {
+ type: 'cookie',
+ name: '_parrable_eid',
+ expires: 365
}
}, {
name: 'identityLink',
@@ -43,6 +54,16 @@ pbjs.setConfig({
name: 'idl_env',
expires: 30
}
+ }, {
+ name: 'liveIntentId',
+ params: {
+ publisherId: '7798696' // Set an identifier of a publisher know to your systems
+ },
+ storage: {
+ type: 'cookie',
+ name: '_li_pbid',
+ expires: 60
+ }
}],
syncDelay: 5000,
auctionDelay: 1000
@@ -82,6 +103,16 @@ pbjs.setConfig({
name: 'idl_env',
expires: 30
}
+ }, {
+ name: 'liveIntentId',
+ params: {
+ publisherId: '7798696' // Set an identifier of a publisher know to your systems
+ },
+ storage: {
+ type: 'html5',
+ name: '_li_pbid',
+ expires: 60
+ }
}],
syncDelay: 5000
}
diff --git a/modules/vidazooBidAdapter.js b/modules/vidazooBidAdapter.js
index 693d6f9724d..b4c2934ee63 100644
--- a/modules/vidazooBidAdapter.js
+++ b/modules/vidazooBidAdapter.js
@@ -29,7 +29,7 @@ function buildRequest(bid, topWindowUrl, size, bidderRequest) {
method: 'GET',
url: `${URL}/prebid/${cId}`,
data: {
- url: topWindowUrl,
+ url: encodeURIComponent(topWindowUrl),
cb: Date.now(),
bidFloor: bidFloor,
bidId: bidId,
@@ -38,7 +38,7 @@ function buildRequest(bid, topWindowUrl, size, bidderRequest) {
width,
height
}
- }
+ };
utils._each(ext, (value, key) => {
dto.data['ext.' + key] = value;
@@ -48,7 +48,7 @@ function buildRequest(bid, topWindowUrl, size, bidderRequest) {
}
function buildRequests(validBidRequests, bidderRequest) {
- const topWindowUrl = utils.getTopWindowUrl();
+ const topWindowUrl = bidderRequest.refererInfo.referer;
const requests = [];
validBidRequests.forEach(validBidRequest => {
const sizes = utils.parseSizesInput(validBidRequest.sizes);
diff --git a/modules/yieldoneAnalyticsAdapter.js b/modules/yieldoneAnalyticsAdapter.js
new file mode 100644
index 00000000000..94dd0daa0b2
--- /dev/null
+++ b/modules/yieldoneAnalyticsAdapter.js
@@ -0,0 +1,122 @@
+import {ajax} from '../src/ajax';
+import adapter from '../src/AnalyticsAdapter';
+import CONSTANTS from '../src/constants.json';
+import adapterManager from '../src/adapterManager';
+import { targeting } from '../src/targeting';
+import { auctionManager } from '../src/auctionManager';
+import * as utils from '../src/utils';
+
+const ANALYTICS_CODE = 'yieldone';
+const analyticsType = 'endpoint';
+// const VERSION = '1.0.0';
+const defaultUrl = '//pool.tsukiji.iponweb.net/hba';
+const requestedBidders = {};
+const requestedBids = {};
+const referrers = {};
+
+let currentAuctionId = '';
+let url = defaultUrl;
+let pubId = '';
+
+const yieldoneAnalytics = Object.assign(adapter({analyticsType}), {
+ getUrl() { return url; },
+ track({eventType, args = {}}) {
+ if (eventType === CONSTANTS.EVENTS.BID_REQUESTED) {
+ const reqBidderId = `${args.bidderCode}_${args.auctionId}`;
+ requestedBidders[reqBidderId] = utils.deepClone(args);
+ requestedBidders[reqBidderId].bids = [];
+ args.bids.forEach((bid) => {
+ requestedBids[`${bid.bidId}_${bid.auctionId}`] = bid;
+ });
+ }
+ if (eventType === CONSTANTS.EVENTS.BID_TIMEOUT && utils.isArray(args)) {
+ const eventsStorage = yieldoneAnalytics.eventsStorage;
+ const reqBidders = {};
+ args.forEach((bid) => {
+ const reqBidId = `${bid.bidId}_${bid.auctionId}`;
+ const reqBidderId = `${bid.bidder}_${bid.auctionId}`;
+ if (!eventsStorage[bid.auctionId]) eventsStorage[bid.auctionId] = [];
+ if (requestedBidders[reqBidderId] && requestedBids[reqBidId]) {
+ if (!reqBidders[bid.bidder]) {
+ reqBidders[bid.bidder] = requestedBidders[reqBidderId];
+ reqBidders[bid.bidder].pubId = pubId;
+ eventsStorage[bid.auctionId].push({eventType, params: reqBidders[bid.bidder]});
+ delete requestedBidders[reqBidderId];
+ }
+ reqBidders[bid.bidder].bids.push(requestedBids[reqBidId]);
+ delete requestedBids[reqBidId];
+ }
+ });
+ } else {
+ args.pubId = pubId;
+ currentAuctionId = args.auctionId || currentAuctionId;
+ if (currentAuctionId) {
+ const eventsStorage = yieldoneAnalytics.eventsStorage;
+ if (!eventsStorage[currentAuctionId]) eventsStorage[currentAuctionId] = [];
+ const referrer = args.refererInfo && args.refererInfo.referer;
+ if (referrer && referrers[currentAuctionId] !== referrer) {
+ referrers[currentAuctionId] = referrer;
+ }
+ eventsStorage[currentAuctionId].push({
+ eventType,
+ params: args
+ });
+ }
+ }
+ if (
+ eventType === CONSTANTS.EVENTS.AUCTION_END || eventType === CONSTANTS.EVENTS.BID_WON
+ ) {
+ args.adServerTargeting = targeting.getAllTargeting(
+ auctionManager.getAdUnitCodes(),
+ auctionManager.getBidsReceived()
+ );
+ if (yieldoneAnalytics.eventsStorage[args.auctionId]) {
+ yieldoneAnalytics.eventsStorage[args.auctionId].forEach((it) => {
+ it.page = {url: referrers[currentAuctionId]};
+ });
+ }
+ yieldoneAnalytics.sendStat(yieldoneAnalytics.eventsStorage[args.auctionId], args.auctionId);
+ }
+ },
+ sendStat(events, auctionId) {
+ if (!events) return;
+ delete yieldoneAnalytics.eventsStorage[auctionId];
+ ajax(
+ url,
+ {
+ success: function() {},
+ error: function() {}
+ },
+ JSON.stringify(events),
+ {
+ method: 'POST'
+ }
+ );
+ }
+});
+
+yieldoneAnalytics.eventsStorage = {};
+
+// save the base class function
+yieldoneAnalytics.originEnableAnalytics = yieldoneAnalytics.enableAnalytics;
+
+// override enableAnalytics so we can get access to the config passed in from the page
+yieldoneAnalytics.enableAnalytics = function (config) {
+ const options = config && config.options;
+ if (options) {
+ if (typeof options.url === 'string') {
+ url = options.url;
+ }
+ if (options.pubId) {
+ pubId = options.pubId.toString();
+ }
+ }
+ yieldoneAnalytics.originEnableAnalytics(config); // call the base class function
+};
+
+adapterManager.registerAnalyticsAdapter({
+ adapter: yieldoneAnalytics,
+ code: ANALYTICS_CODE
+});
+
+export default yieldoneAnalytics;
diff --git a/modules/yieldoneAnalyticsAdapter.md b/modules/yieldoneAnalyticsAdapter.md
new file mode 100644
index 00000000000..43be87b114b
--- /dev/null
+++ b/modules/yieldoneAnalyticsAdapter.md
@@ -0,0 +1,21 @@
+# Overview
+Module Name: Platform One Analytics
+
+Module Type: Analytics Adapter
+
+Maintainer: y1s@platform-one.co.jp
+
+# Description
+
+Analytics adapter for Platform One. Please contact y1s@platform-one.co.jp for any additional information. Official website link to the vendor: www.platform-one.co.jp/.
+
+# Test Parameters
+
+```
+{
+ provider: 'yieldone',
+ options : {
+ pubId : 'TestAnalyticsPublisher', //id provided by Platform One publisher team
+ }
+}
+```
\ No newline at end of file
diff --git a/package.json b/package.json
index 967dcede83c..0200db4eace 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "prebid.js",
- "version": "2.35.0-pre",
+ "version": "2.37.0-pre",
"description": "Header Bidding Management Library",
"main": "src/prebid.js",
"scripts": {
diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js
index 90cab154fd4..4ccbfd89457 100644
--- a/src/adapters/bidderFactory.js
+++ b/src/adapters/bidderFactory.js
@@ -9,7 +9,7 @@ import CONSTANTS from '../constants.json';
import events from '../events';
import includes from 'core-js/library/fn/array/includes';
import { ajax } from '../ajax';
-import { logWarn, logError, parseQueryStringParameters, delayExecution, parseSizesInput, getBidderRequest, flatten, uniques, timestamp, setDataInLocalStorage, getDataFromLocalStorage, deepAccess } from '../utils';
+import { logWarn, logError, parseQueryStringParameters, delayExecution, parseSizesInput, getBidderRequest, flatten, uniques, timestamp, setDataInLocalStorage, getDataFromLocalStorage, deepAccess, isArray } from '../utils';
import { ADPOD } from '../mediaTypes';
import { getHook } from '../hook';
@@ -290,7 +290,7 @@ export function newBidder(spec) {
}
if (bids) {
- if (bids.forEach) {
+ if (isArray(bids)) {
bids.forEach(addBidUsingRequestMap);
} else {
addBidUsingRequestMap(bids);
diff --git a/src/videoCache.js b/src/videoCache.js
index 06847012a6e..4a715cb1fe3 100644
--- a/src/videoCache.js
+++ b/src/videoCache.js
@@ -60,12 +60,18 @@ function wrapURI(uri, impUrl) {
*/
function toStorageRequest(bid) {
const vastValue = bid.vastXml ? bid.vastXml : wrapURI(bid.vastUrl, bid.vastImpUrl);
+
let payload = {
type: 'xml',
value: vastValue,
ttlseconds: Number(bid.ttl)
};
+ if (config.getConfig('cache.vasttrack')) {
+ payload.bidder = bid.bidder;
+ payload.bidid = bid.requestId;
+ }
+
if (typeof bid.customCacheKey === 'string' && bid.customCacheKey !== '') {
payload.key = bid.customCacheKey;
}
@@ -94,7 +100,7 @@ function toStorageRequest(bid) {
*/
function shimStorageCallback(done) {
return {
- success: function(responseBody) {
+ success: function (responseBody) {
let ids;
try {
ids = JSON.parse(responseBody).responses
@@ -109,7 +115,7 @@ function shimStorageCallback(done) {
done(new Error("The cache server didn't respond with a responses property."), []);
}
},
- error: function(statusText, responseBody) {
+ error: function (statusText, responseBody) {
done(new Error(`Error storing video ad in the cache: ${statusText}: ${JSON.stringify(responseBody)}`), []);
}
}
diff --git a/test/spec/modules/33acrossBidAdapter_spec.js b/test/spec/modules/33acrossBidAdapter_spec.js
index 08ea0a863ee..e98b4600d90 100644
--- a/test/spec/modules/33acrossBidAdapter_spec.js
+++ b/test/spec/modules/33acrossBidAdapter_spec.js
@@ -61,6 +61,7 @@ describe('33acrossBidAdapter:', function () {
},
ext: {
ttx: {
+ prebidStartedAt: 1,
caller: [{
'name': 'prebidjs',
'version': '$prebid.version$'
@@ -183,6 +184,7 @@ describe('33acrossBidAdapter:', function () {
];
sandbox = sinon.sandbox.create();
+ sandbox.stub(Date, 'now').returns(1);
sandbox.stub(document, 'getElementById').withArgs('div-id').returns(element);
sandbox.stub(utils, 'getWindowTop').returns(win);
sandbox.stub(utils, 'getWindowSelf').returns(win);
diff --git a/test/spec/modules/adponeBidAdapter_spec.js b/test/spec/modules/adponeBidAdapter_spec.js
index 1c64c60bd5c..da685a56394 100644
--- a/test/spec/modules/adponeBidAdapter_spec.js
+++ b/test/spec/modules/adponeBidAdapter_spec.js
@@ -1,6 +1,8 @@
import { expect } from 'chai';
import { spec } from 'modules/adponeBidAdapter';
+import {newBidder} from '../../../src/adapters/bidderFactory';
+const EMPTY_ARRAY = [];
describe('adponeBidAdapter', function () {
let bid = {
bidder: 'adpone',
@@ -14,6 +16,48 @@ describe('adponeBidAdapter', function () {
}
};
+ describe('build requests', () => {
+ it('sends bid request to ENDPOINT via POST', function () {
+ const request = spec.buildRequests([
+ {
+ bidder: 'adpone',
+ adUnitCode: 'adunit-code',
+ sizes: [[300, 250]],
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ params: {
+ placementId: '1',
+ }
+ }
+ ]);
+ expect(request[0].method).to.equal('POST');
+ });
+ it('sends bid request to adpone endpoint', function () {
+ const request = spec.buildRequests([
+ {
+ bidder: 'adpone',
+ adUnitCode: 'adunit-code',
+ sizes: [[300, 250]],
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ params: {
+ placementId: '1',
+ }
+ }
+ ]);
+ expect(request[0].url).to.equal('https://rtb.adpone.com/bid-request?pid=1');
+ });
+ });
+
+ describe('inherited functions', () => {
+ const adapter = newBidder(spec);
+ it('exists and is a function', () => {
+ expect(adapter.callBids).to.exist.and.to.be.a('function');
+ });
+ });
+
describe('isBidRequestValid', function () {
it('should return true when necessary information is found', function () {
expect(spec.isBidRequestValid(bid)).to.be.true;
@@ -34,6 +78,36 @@ describe('adponeBidAdapter', function () {
bid.adUnitCode = 'adunit-code';
});
+
+ it('returns false when bidder not set to "adpone"', function() {
+ const invalidBid = {
+ bidder: 'enopda',
+ adUnitCode: 'adunit-code',
+ sizes: [[300, 250]],
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ params: {
+ placementId: '1',
+ }
+ };
+ expect(spec.isBidRequestValid(invalidBid)).to.be.false;
+ });
+
+ it('returns false when placementId is not set in params', function() {
+ const invalidBid = {
+ bidder: 'adpone',
+ adUnitCode: 'adunit-code',
+ sizes: [[300, 250]],
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ params: {
+ }
+ };
+
+ expect(spec.isBidRequestValid(invalidBid)).to.be.false;
+ });
});
});
@@ -73,6 +147,19 @@ describe('interpretResponse', function () {
};
});
+ it('validate_response_params', function() {
+ const newResponse = spec.interpretResponse(serverResponse, bidRequest);
+ expect(newResponse[0].id).to.be.equal('613673EF-A07C-4486-8EE9-3FC71A7DC73D');
+ expect(newResponse[0].requestId).to.be.equal('1234');
+ expect(newResponse[0].cpm).to.be.equal(1);
+ expect(newResponse[0].width).to.be.equal(300);
+ expect(newResponse[0].height).to.be.equal(250);
+ expect(newResponse[0].currency).to.be.equal('USD');
+ expect(newResponse[0].netRevenue).to.be.equal(true);
+ expect(newResponse[0].ttl).to.be.equal(300);
+ expect(newResponse[0].ad).to.be.equal('

');
+ });
+
it('should correctly reorder the server response', function () {
const newResponse = spec.interpretResponse(serverResponse, bidRequest);
expect(newResponse.length).to.be.equal(1);
@@ -99,4 +186,38 @@ describe('interpretResponse', function () {
response = spec.interpretResponse(serverResponse, bidRequest);
expect(response).to.deep.equal([])
});
+ it('should add responses if the cpm is valid', function () {
+ serverResponse.body.seatbid[0].bid[0].price = 0.5;
+ let response = spec.interpretResponse(serverResponse, bidRequest);
+ expect(response).to.not.deep.equal([]);
+ });
+});
+
+describe('getUserSyncs', function () {
+ it('Verifies that getUserSyncs is a function', function () {
+ expect((typeof (spec.getUserSyncs)).should.equals('function'));
+ });
+ it('Verifies getUserSyncs returns expected result', function () {
+ expect((typeof (spec.getUserSyncs)).should.equals('function'));
+ expect(spec.getUserSyncs({iframeEnabled: true})).to.deep.equal({
+ type: 'iframe',
+ url: 'https://eu-ads.adpone.com'
+ });
+ });
+ it('Verifies that iframeEnabled: false returns an empty array', function () {
+ expect(spec.getUserSyncs({iframeEnabled: false})).to.deep.equal(EMPTY_ARRAY);
+ });
+ it('Verifies that iframeEnabled: null returns an empty array', function () {
+ expect(spec.getUserSyncs(null)).to.deep.equal(EMPTY_ARRAY);
+ });
+});
+
+describe('test onBidWon function', function () {
+ it('exists and is a function', () => {
+ expect(spec.onBidWon).to.exist.and.to.be.a('function');
+ });
+ it('should return nothing', function () {
+ var response = spec.onBidWon({});
+ expect(response).to.be.an('undefined')
+ });
});
diff --git a/test/spec/modules/fintezaAnalyticsAdapter_spec.js b/test/spec/modules/fintezaAnalyticsAdapter_spec.js
index 33b24f5f50f..2cc2f380016 100644
--- a/test/spec/modules/fintezaAnalyticsAdapter_spec.js
+++ b/test/spec/modules/fintezaAnalyticsAdapter_spec.js
@@ -2,17 +2,27 @@ import fntzAnalyticsAdapter from 'modules/fintezaAnalyticsAdapter';
import includes from 'core-js/library/fn/array/includes';
import { expect } from 'chai';
import { parse as parseURL } from 'src/url';
+
let adapterManager = require('src/adapterManager').default;
let events = require('src/events');
let constants = require('src/constants.json');
+function setCookie(name, value, expires) {
+ document.cookie = name + '=' + value +
+ '; path=/' +
+ (expires ? ('; expires=' + expires.toUTCString()) : '') +
+ '; SameSite=None';
+}
+
describe('finteza analytics adapter', function () {
const clientId = 'fntz-client-32145';
+ const uniqCookie = '5045380421580287382';
let xhr;
let requests;
beforeEach(function () {
+ setCookie('_fz_uniq', uniqCookie);
xhr = sinon.useFakeXMLHttpRequest();
requests = [];
xhr.onCreate = request => { requests.push(request) };
@@ -38,6 +48,7 @@ describe('finteza analytics adapter', function () {
});
afterEach(function () {
+ setCookie('_fz_uniq', '', new Date(0));
xhr.restore();
events.getEvents.restore();
fntzAnalyticsAdapter.track.restore();
@@ -74,6 +85,7 @@ describe('finteza analytics adapter', function () {
expect(requests.length).to.equal(1);
expect(requests[0].method).to.equal('GET');
+ expect(requests[0].withCredentials).to.equal(true);
const url = parseURL(requests[0].url);
@@ -81,6 +93,7 @@ describe('finteza analytics adapter', function () {
expect(url.hostname).to.equal('content.mql5.com');
expect(url.pathname).to.equal('/tr');
expect(url.search.id).to.equal(clientId);
+ expect(url.search.fz_uniq).to.equal(uniqCookie);
expect(decodeURIComponent(url.search.event)).to.equal(`Bid Request ${bidderCode.toUpperCase()}`);
sinon.assert.callCount(fntzAnalyticsAdapter.track, 1);
@@ -115,6 +128,7 @@ describe('finteza analytics adapter', function () {
expect(requests.length).to.equal(2);
expect(requests[0].method).to.equal('GET');
+ expect(requests[0].withCredentials).to.equal(true);
let url = parseURL(requests[0].url);
@@ -122,11 +136,13 @@ describe('finteza analytics adapter', function () {
expect(url.hostname).to.equal('content.mql5.com');
expect(url.pathname).to.equal('/tr');
expect(url.search.id).to.equal(clientId);
+ expect(url.search.fz_uniq).to.equal(uniqCookie);
expect(decodeURIComponent(url.search.event)).to.equal(`Bid Response Price ${bidderCode.toLowerCase()}`);
expect(url.search.value).to.equal(String(cpm));
expect(url.search.unit).to.equal('usd');
expect(requests[1].method).to.equal('GET');
+ expect(requests[1].withCredentials).to.equal(true);
url = parseURL(requests[1].url);
@@ -134,6 +150,7 @@ describe('finteza analytics adapter', function () {
expect(url.hostname).to.equal('content.mql5.com');
expect(url.pathname).to.equal('/tr');
expect(url.search.id).to.equal(clientId);
+ expect(url.search.fz_uniq).to.equal(uniqCookie);
expect(decodeURIComponent(url.search.event)).to.equal(`Bid Response Time ${bidderCode.toLowerCase()}`);
expect(url.search.value).to.equal(String(timeToRespond));
expect(url.search.unit).to.equal('ms');
@@ -165,6 +182,7 @@ describe('finteza analytics adapter', function () {
expect(requests.length).to.equal(1);
expect(requests[0].method).to.equal('GET');
+ expect(requests[0].withCredentials).to.equal(true);
const url = parseURL(requests[0].url);
@@ -172,6 +190,7 @@ describe('finteza analytics adapter', function () {
expect(url.hostname).to.equal('content.mql5.com');
expect(url.pathname).to.equal('/tr');
expect(url.search.id).to.equal(clientId);
+ expect(url.search.fz_uniq).to.equal(uniqCookie);
expect(decodeURIComponent(url.search.event)).to.equal(`Bid Won ${bidderCode.toUpperCase()}`);
expect(url.search.value).to.equal(String(cpm));
expect(url.search.unit).to.equal('usd');
@@ -202,6 +221,7 @@ describe('finteza analytics adapter', function () {
expect(requests.length).to.equal(1);
expect(requests[0].method).to.equal('GET');
+ expect(requests[0].withCredentials).to.equal(true);
const url = parseURL(requests[0].url);
@@ -209,6 +229,7 @@ describe('finteza analytics adapter', function () {
expect(url.hostname).to.equal('content.mql5.com');
expect(url.pathname).to.equal('/tr');
expect(url.search.id).to.equal(clientId);
+ expect(url.search.fz_uniq).to.equal(uniqCookie);
expect(decodeURIComponent(url.search.event)).to.equal(`Bid Timeout Bidder789`);
expect(url.search.value).to.equal(String(timeout));
expect(url.search.unit).to.equal('ms');
diff --git a/test/spec/modules/gamoshiBidAdapter_spec.js b/test/spec/modules/gamoshiBidAdapter_spec.js
index a2c4eebc213..2d63d47a73e 100644
--- a/test/spec/modules/gamoshiBidAdapter_spec.js
+++ b/test/spec/modules/gamoshiBidAdapter_spec.js
@@ -227,13 +227,49 @@ describe('GamoshiAdapter', function () {
it('builds request with gdpr consent', function () {
let response = spec.buildRequests([bidRequest], bidRequest)[0];
+ expect(response.data.ext.gdpr_consent).to.exist;
expect(response.data.ext).to.have.property('gdpr_consent');
expect(response.data.ext.gdpr_consent.consent_string).to.equal('some string');
expect(response.data.ext.gdpr_consent.consent_required).to.equal(true);
+
+ expect(response.data.regs.ext.gdpr).to.exist;
+ expect(response.data.user.ext.consent).to.equal('some string');
+ });
+
+ it('build request with ID5 Id', function () {
+ const bidRequestClone = utils.deepClone(bidRequest);
+ bidRequestClone.userId = {};
+ bidRequestClone.userId.id5id = 'id5-user-id';
+ let request = spec.buildRequests([bidRequestClone], bidRequestClone)[0];
+ expect(request.data.user.ext.eids).to.deep.equal([{
+ 'source': 'id5-sync.com',
+ 'uids': [{
+ 'id': 'id5-user-id',
+ 'ext': {
+ 'rtiPartner': 'ID5ID'
+ }
+ }]
+ }]);
+ });
+
+ it('build request with unified Id', function () {
+ const bidRequestClone = utils.deepClone(bidRequest);
+ bidRequestClone.userId = {};
+ bidRequestClone.userId.tdid = 'tdid-user-id';
+ let request = spec.buildRequests([bidRequestClone], bidRequestClone)[0];
+ expect(request.data.user.ext.eids).to.deep.equal([{
+ 'source': 'adserver.org',
+ 'uids': [{
+ 'id': 'tdid-user-id',
+ 'ext': {
+ 'rtiPartner': 'TDID'
+ }
+ }]
+ }]);
});
});
- describe('interpretResponse', function () {
+ describe('interpretResponse', () => {
const bannerBidRequest = {
'adUnitCode': 'adunit-code',
'auctionId': '1d1a030790a475',
diff --git a/test/spec/modules/gumgumBidAdapter_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js
index cedef568d56..82c8e494533 100644
--- a/test/spec/modules/gumgumBidAdapter_spec.js
+++ b/test/spec/modules/gumgumBidAdapter_spec.js
@@ -245,8 +245,8 @@ describe('gumgumAdapter', function () {
'thms': 10000
}
let result = spec.interpretResponse({ body: inscreenServerResponse }, inscreenBidRequest);
- expect(result[0].width).to.equal(inscreenBidRequest.sizes[0][0].toString());
- expect(result[0].height).to.equal(inscreenBidRequest.sizes[0][1].toString());
+ expect(result[0].width).to.equal('1');
+ expect(result[0].height).to.equal('1');
})
})
describe('getUserSyncs', function () {
diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js
index 8b8f6c4bf4c..2d9d51c0d68 100644
--- a/test/spec/modules/improvedigitalBidAdapter_spec.js
+++ b/test/spec/modules/improvedigitalBidAdapter_spec.js
@@ -193,6 +193,47 @@ describe('Improve Digital Adapter Tests', function () {
expect(params.bid_request.referrer).to.equal('https://blah.com/test.html');
});
+ it('should add ad type for instream video', function () {
+ let bidRequest = Object.assign({}, simpleBidRequest);
+ bidRequest.mediaType = 'video';
+ let request = spec.buildRequests([bidRequest])[0];
+ let params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length)));
+ expect(params.bid_request.imp[0].ad_types).to.deep.equal(['video']);
+
+ bidRequest = Object.assign({}, simpleBidRequest);
+ bidRequest.mediaTypes = {
+ video: {
+ context: 'instream',
+ playerSize: [640, 480]
+ }
+ };
+ request = spec.buildRequests([bidRequest])[0];
+ params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length)));
+ expect(params.bid_request.imp[0].ad_types).to.deep.equal(['video']);
+ });
+
+ it('should not set ad type for outstream video', function() {
+ const bidRequest = Object.assign({}, simpleBidRequest);
+ bidRequest.mediaTypes = {
+ video: {
+ context: 'outstream',
+ playerSize: [640, 480]
+ }
+ };
+ const request = spec.buildRequests([bidRequest])[0];
+ const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length)));
+ expect(params.bid_request.imp[0].ad_types).to.not.exist;
+ });
+
+ it('should add schain', function () {
+ const schain = '{"ver":"1.0","complete":1,"nodes":[{"asi":"headerlift.com","sid":"xyz","hp":1}]}';
+ const bidRequest = Object.assign({}, simpleBidRequest);
+ bidRequest.schain = schain;
+ const request = spec.buildRequests([bidRequest], bidderRequestReferrer)[0];
+ const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length)));
+ expect(params.bid_request.schain).to.equal(schain);
+ });
+
it('should return 2 requests', function () {
const requests = spec.buildRequests([
simpleBidRequest,
@@ -447,6 +488,34 @@ describe('Improve Digital Adapter Tests', function () {
}
};
+ const serverResponseVideo = {
+ 'body': {
+ 'id': '687a06c541d8d1',
+ 'site_id': 191642,
+ 'bid': [
+ {
+ 'isNet': false,
+ 'id': '33e9500b21129f',
+ 'advid': '5279',
+ 'price': 1.45888594164456,
+ 'nurl': 'http://ice.360yield.com/imp_pixel?ic=wVmhKI07hCVyGC1sNdFp.6buOSiGYOw8jPyZLlcMY2RCwD4ek3Fy6.xUI7U002skGBs3objMBoNU-Frpvmb9js3NKIG0YZJgWaNdcpXY9gOXE9hY4-wxybCjVSNzhOQB-zic73hzcnJnKeoGgcfvt8fMy18-yD0aVdYWt4zbqdoITOkKNCPBEgbPFu1rcje-o7a64yZ7H3dKvtnIixXQYc1Ep86xGSBGXY6xW2KfUOMT6vnkemxO72divMkMdhR8cAuqIubbx-ZID8-xf5c9k7p6DseeBW0I8ionrlTHx.rGosgxhiFaMqtr7HiA7PBzKvPdeEYN0hQ8RYo8JzYL82hA91A3V2m9Ij6y0DfIJnnrKN8YORffhxmJ6DzwEl1zjrVFbD01bqB3Vdww8w8PQJSkKQkd313tr-atU8LS26fnBmOngEkVHwAr2WCKxuUvxHmuVBTA-Lgz7wKwMoOJCA3hFxMavVb0ZFB7CK0BUTVU6z0De92Q.FJKNCHLMbjX3vcAQ90=',
+ 'h': 290,
+ 'pid': 1053688,
+ 'sync': [
+ 'http://link1',
+ 'http://link2'
+ ],
+ 'crid': '422031',
+ 'w': 600,
+ 'cid': '99006',
+ 'adm': '
',
+ 'ad_type': 'video'
+ }
+ ],
+ 'debug': ''
+ }
+ };
+
const nativeEventtrackers = [
{
event: 1,
@@ -543,6 +612,22 @@ describe('Improve Digital Adapter Tests', function () {
}
];
+ let expectedBidVideo = [
+ {
+ 'vastXml': '
',
+ 'adId': '33e9500b21129f',
+ 'creativeId': '422031',
+ 'cpm': 1.45888594164456,
+ 'currency': 'USD',
+ 'height': 290,
+ 'mediaType': 'video',
+ 'netRevenue': false,
+ 'requestId': '33e9500b21129f',
+ 'ttl': 300,
+ 'width': 600
+ }
+ ];
+
it('should return a well-formed bid', function () {
const bids = spec.interpretResponse(serverResponse);
expect(bids).to.deep.equal(expectedBid);
@@ -658,6 +743,12 @@ describe('Improve Digital Adapter Tests', function () {
delete bids[0].ortbNative;
expect(bids).to.deep.equal(expectedBids);
});
+
+ // Video
+ it('should return a well-formed video bid', function () {
+ const bids = spec.interpretResponse(serverResponseVideo);
+ expect(bids).to.deep.equal(expectedBidVideo);
+ });
});
describe('getUserSyncs', function () {
diff --git a/test/spec/modules/liveIntentIdSystem_spec.js b/test/spec/modules/liveIntentIdSystem_spec.js
new file mode 100644
index 00000000000..7620e8ac7b8
--- /dev/null
+++ b/test/spec/modules/liveIntentIdSystem_spec.js
@@ -0,0 +1,145 @@
+import { liveIntentIdSubmodule } from 'modules/liveIntentIdSystem';
+import * as utils from 'src/utils';
+
+describe('LiveIntentId', function() {
+ let xhr;
+ let requests;
+ let getCookieStub;
+ let getDataFromLocalStorageStub;
+ let logErrorStub;
+
+ const defaultConfigParams = {'publisherId': '89899'};
+ const responseHeader = { 'Content-Type': 'application/json' }
+
+ beforeEach(function () {
+ xhr = sinon.useFakeXMLHttpRequest();
+ requests = [];
+ xhr.onCreate = request => requests.push(request);
+ getCookieStub = sinon.stub(utils, 'getCookie');
+ getDataFromLocalStorageStub = sinon.stub(utils, 'getDataFromLocalStorage');
+ logErrorStub = sinon.stub(utils, 'logError');
+ });
+
+ afterEach(function () {
+ xhr.restore();
+ getCookieStub.restore();
+ getDataFromLocalStorageStub.restore();
+ logErrorStub.restore();
+ });
+
+ it('should log an error if no configParams were passed', function() {
+ liveIntentIdSubmodule.getId();
+ expect(logErrorStub.calledOnce).to.be.true;
+ });
+
+ it('should log an error if publisherId configParam was not passed', function() {
+ liveIntentIdSubmodule.getId({});
+ expect(logErrorStub.calledOnce).to.be.true;
+ });
+
+ it('should call the Custom URL of the LiveIntent Identity Exchange endpoint', function() {
+ getCookieStub.returns(null);
+ let callBackSpy = sinon.spy();
+ let submoduleCallback = liveIntentIdSubmodule.getId({...defaultConfigParams, ...{'url': 'https://dummy.liveintent.com'}}).callback;
+ submoduleCallback(callBackSpy);
+ let request = requests[0];
+ expect(request.url).to.be.eq('https://dummy.liveintent.com/idex/prebid/89899?');
+ request.respond(
+ 200,
+ responseHeader,
+ JSON.stringify({})
+ );
+ expect(callBackSpy.calledOnce).to.be.true;
+ });
+
+ it('should call the default url of the LiveIntent Identity Exchange endpoint, with a partner', function() {
+ getCookieStub.returns(null);
+ let callBackSpy = sinon.spy();
+ let submoduleCallback = liveIntentIdSubmodule.getId({...defaultConfigParams, ...{'url': 'https://dummy.liveintent.com', 'partner': 'rubicon'}}).callback;
+ submoduleCallback(callBackSpy);
+ let request = requests[0];
+ expect(request.url).to.be.eq('https://dummy.liveintent.com/idex/rubicon/89899?');
+ request.respond(
+ 200,
+ responseHeader,
+ JSON.stringify({})
+ );
+ expect(callBackSpy.calledOnce).to.be.true;
+ });
+
+ it('should call the LiveIntent Identity Exchange endpoint, with no additional query params', function() {
+ getCookieStub.returns(null);
+ let callBackSpy = sinon.spy();
+ let submoduleCallback = liveIntentIdSubmodule.getId(defaultConfigParams).callback;
+ submoduleCallback(callBackSpy);
+ let request = requests[0];
+ expect(request.url).to.be.eq('//idx.liadm.com/idex/prebid/89899?');
+ request.respond(
+ 200,
+ responseHeader,
+ JSON.stringify({})
+ );
+ expect(callBackSpy.calledOnce).to.be.true;
+ });
+
+ it('should include the LiveConnect identifier when calling the LiveIntent Identity Exchange endpoint', function() {
+ getCookieStub.withArgs('_li_duid').returns('li-fpc');
+ let callBackSpy = sinon.spy();
+ let submoduleCallback = liveIntentIdSubmodule.getId(defaultConfigParams).callback;
+ submoduleCallback(callBackSpy);
+ let request = requests[0];
+ expect(request.url).to.be.eq('//idx.liadm.com/idex/prebid/89899?duid=li-fpc&');
+ request.respond(
+ 200,
+ responseHeader,
+ JSON.stringify({})
+ );
+ expect(callBackSpy.calledOnce).to.be.true;
+ });
+
+ it('should include the LiveConnect identifier and additional Identifiers to resolve', function() {
+ getCookieStub.withArgs('_li_duid').returns('li-fpc');
+ getDataFromLocalStorageStub.withArgs('_thirdPC').returns('third-pc');
+ let configParams = {
+ ...defaultConfigParams,
+ ...{
+ 'identifiersToResolve': ['_thirdPC']
+ }
+ };
+
+ let callBackSpy = sinon.spy();
+ let submoduleCallback = liveIntentIdSubmodule.getId(configParams).callback;
+ submoduleCallback(callBackSpy);
+ let request = requests[0];
+ expect(request.url).to.be.eq('//idx.liadm.com/idex/prebid/89899?_thirdPC=third-pc&duid=li-fpc&');
+ request.respond(
+ 200,
+ responseHeader,
+ JSON.stringify({})
+ );
+ expect(callBackSpy.calledOnce).to.be.true;
+ });
+
+ it('should include an additional identifier value to resolve even if it is an object', function() {
+ getCookieStub.returns(null);
+ getDataFromLocalStorageStub.withArgs('_thirdPC').returns({'key': 'value'});
+ let configParams = {
+ ...defaultConfigParams,
+ ...{
+ 'identifiersToResolve': ['_thirdPC']
+ }
+ };
+
+ let callBackSpy = sinon.spy();
+ let submoduleCallback = liveIntentIdSubmodule.getId(configParams).callback;
+ submoduleCallback(callBackSpy);
+ let request = requests[0];
+ expect(request.url).to.be.eq('//idx.liadm.com/idex/prebid/89899?_thirdPC=%7B%22key%22%3A%22value%22%7D&');
+ request.respond(
+ 200,
+ responseHeader,
+ JSON.stringify({})
+ );
+ expect(callBackSpy.calledOnce).to.be.true;
+ });
+});
diff --git a/test/spec/modules/lockerdomeBidAdapter_spec.js b/test/spec/modules/lockerdomeBidAdapter_spec.js
index 6a3fd814030..a108b25e2ff 100644
--- a/test/spec/modules/lockerdomeBidAdapter_spec.js
+++ b/test/spec/modules/lockerdomeBidAdapter_spec.js
@@ -15,7 +15,6 @@ describe('LockerDomeAdapter', function () {
},
adUnitCode: 'ad-1',
transactionId: 'b55e97d7-792c-46be-95a5-3df40b115734',
- sizes: [[300, 250]],
bidId: '2652ca954bce9',
bidderRequestId: '14a54fade69854',
auctionId: 'd4c83108-615d-4c2c-9384-dac9ffd4fd72'
@@ -31,7 +30,6 @@ describe('LockerDomeAdapter', function () {
},
adUnitCode: 'ad-2',
transactionId: '73459f05-c482-4706-b2b7-72e6f6264ce6',
- sizes: [[300, 600]],
bidId: '4510f2834773ce',
bidderRequestId: '14a54fade69854',
auctionId: 'd4c83108-615d-4c2c-9384-dac9ffd4fd72'
@@ -51,19 +49,25 @@ describe('LockerDomeAdapter', function () {
describe('buildRequests', function () {
it('should generate a valid single POST request for multiple bid requests', function () {
- const request = spec.buildRequests(bidRequests);
+ const bidderRequest = {
+ refererInfo: {
+ canonicalUrl: 'https://example.com/canonical',
+ referer: 'https://example.com'
+ }
+ };
+ const request = spec.buildRequests(bidRequests, bidderRequest);
expect(request.method).to.equal('POST');
expect(request.url).to.equal('https://lockerdome.com/ladbid/prebid');
expect(request.data).to.exist;
const requestData = JSON.parse(request.data);
- expect(requestData.url).to.equal(utils.getTopWindowLocation().href);
- expect(requestData.referrer).to.equal(utils.getTopWindowReferrer());
-
const bids = requestData.bidRequests;
expect(bids).to.have.lengthOf(2);
+ expect(requestData.url).to.equal(encodeURIComponent(bidderRequest.refererInfo.canonicalUrl));
+ expect(requestData.referrer).to.equal(encodeURIComponent(bidderRequest.refererInfo.referer));
+
expect(bids[0].requestId).to.equal('2652ca954bce9');
expect(bids[0].adUnitCode).to.equal('ad-1');
expect(bids[0].adUnitId).to.equal('LD10809467961050726');
@@ -84,6 +88,10 @@ describe('LockerDomeAdapter', function () {
gdprConsent: {
consentString: 'AAABBB',
gdprApplies: true
+ },
+ refererInfo: {
+ canonicalUrl: 'https://example.com/canonical',
+ referer: 'https://example.com'
}
};
const request = spec.buildRequests(bidRequests, bidderRequest);
@@ -129,7 +137,14 @@ describe('LockerDomeAdapter', function () {
}
};
- const request = spec.buildRequests(bidRequests);
+ const bidderRequest = {
+ refererInfo: {
+ canonicalUrl: 'https://example.com/canonical',
+ referer: 'https://example.com'
+ }
+ };
+
+ const request = spec.buildRequests(bidRequests, bidderRequest);
const interpretedResponse = spec.interpretResponse(serverResponse, request);
expect(interpretedResponse).to.have.lengthOf(2);
diff --git a/test/spec/modules/orbidderBidAdapter_spec.js b/test/spec/modules/orbidderBidAdapter_spec.js
index aeaa5f30446..1b76de9841a 100644
--- a/test/spec/modules/orbidderBidAdapter_spec.js
+++ b/test/spec/modules/orbidderBidAdapter_spec.js
@@ -10,6 +10,7 @@ describe('orbidderBidAdapter', () => {
bidId: 'd66fa86787e0b0ca900a96eacfd5f0bb',
auctionId: 'ccc4c7cdfe11cfbd74065e6dd28413d8',
transactionId: 'd58851660c0c4461e4aa06344fc9c0c6',
+ bidRequestCount: 1,
adUnitCode: 'adunit-code',
sizes: [[300, 250], [300, 600]],
params: {
@@ -46,12 +47,6 @@ describe('orbidderBidAdapter', () => {
expect(spec.isBidRequestValid(defaultBidRequest)).to.equal(true);
});
- it('accepts optional keyValues object', () => {
- const bidRequest = deepClone(defaultBidRequest);
- bidRequest.params.keyValues = {'key': 'value'};
- expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- });
-
it('accepts optional profile object', () => {
const bidRequest = deepClone(defaultBidRequest);
bidRequest.params.profile = {'key': 'value'};
@@ -64,12 +59,6 @@ describe('orbidderBidAdapter', () => {
expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
});
- it('doesn\'t accept malformed keyValues', () => {
- const bidRequest = deepClone(defaultBidRequest);
- bidRequest.params.keyValues = 'another not usable string';
- expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
- });
-
it('doesn\'t accept malformed profile', () => {
const bidRequest = deepClone(defaultBidRequest);
bidRequest.params.profile = 'another not usable string';
diff --git a/test/spec/modules/outconBidAdapter_spec.js b/test/spec/modules/outconBidAdapter_spec.js
new file mode 100644
index 00000000000..dc9c96ed3a3
--- /dev/null
+++ b/test/spec/modules/outconBidAdapter_spec.js
@@ -0,0 +1,98 @@
+import { expect } from 'chai';
+import { spec } from '../../../modules/outconBidAdapter';
+
+describe('outconBidAdapter', function () {
+ describe('bidRequestValidity', function () {
+ it('Check the bidRequest with pod param', function () {
+ expect(spec.isBidRequestValid({
+ bidder: 'outcon',
+ params: {
+ pod: '5d603538eba7192ae14e39a4',
+ env: 'test'
+ }
+ })).to.equal(true);
+ });
+ it('Check the bidRequest with internalID and publisherID params', function () {
+ expect(spec.isBidRequestValid({
+ bidder: 'outcon',
+ params: {
+ internalId: '12345678',
+ publisher: '5d5d66f2306ea4114a37c7c2',
+ env: 'test'
+ }
+ })).to.equal(true);
+ });
+ });
+ describe('buildRequests', function () {
+ it('Build requests with pod param', function () {
+ expect(spec.buildRequests([{
+ bidder: 'outcon',
+ params: {
+ pod: '5d603538eba7192ae14e39a4',
+ env: 'test'
+ }
+ }])).to.have.keys('method', 'url', 'data');
+ });
+
+ it('Build requests with internalID and publisherID params', function () {
+ expect(spec.buildRequests([{
+ bidder: 'outcon',
+ params: {
+ internalId: '12345678',
+ publisher: '5d5d66f2306ea4114a37c7c2',
+ env: 'test'
+ }
+ }])).to.have.keys('method', 'url', 'data');
+ });
+ });
+
+ describe('interpretResponse', function () {
+ const bidRequest = {
+ method: 'GET',
+ url: 'http://test.outcondigital.com:8048/ad/',
+ data: {
+ pod: '5d603538eba7192ae14e39a4',
+ env: 'test'
+ }
+ };
+ const bidResponse = {
+ body: {
+ cpm: 0.10,
+ cur: 'USD',
+ exp: 10,
+ creatives: [
+ {
+ url: 'http://test.outcondigital.com/uploads/5d42e7a7306ea4689b67c122/frutas.mp4',
+ size: 3,
+ width: 1920,
+ height: 1080,
+ codec: 'video/mp4'
+ }
+ ],
+ id: '5d6e6aef22063e392bf7f564',
+ type: 'video',
+ campaign: '5d42e44b306ea469593c76a2',
+ trackingURL: 'http://test.outcondigital.com:8048/ad/track?track=5d6e6aef22063e392bf7f564'
+ },
+ };
+ it('check all the keys that are needed to interpret the response', function () {
+ const result = spec.interpretResponse(bidResponse, bidRequest);
+ let requiredKeys = [
+ 'requestId',
+ 'cpm',
+ 'width',
+ 'height',
+ 'creativeId',
+ 'currency',
+ 'netRevenue',
+ 'ttl',
+ 'ad',
+ 'vastImpUrl'
+ ];
+ let resultKeys = Object.keys(result[0]);
+ resultKeys.forEach(function(key) {
+ expect(requiredKeys.indexOf(key) !== -1).to.equal(true);
+ });
+ })
+ });
+});
diff --git a/test/spec/modules/parrableIdSystem_spec.js b/test/spec/modules/parrableIdSystem_spec.js
new file mode 100644
index 00000000000..540e63aa630
--- /dev/null
+++ b/test/spec/modules/parrableIdSystem_spec.js
@@ -0,0 +1,77 @@
+import { expect } from 'chai';
+import {config} from 'src/config';
+import * as utils from 'src/utils';
+import { init, requestBidsHook, setSubmoduleRegistry } from 'modules/userId/index.js';
+import { parrableIdSubmodule } from 'modules/parrableIdSystem';
+
+const EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT';
+const P_COOKIE_NAME = '_parrable_eid';
+const P_COOKIE_VALUE = '01.1563917337.test-eid';
+const P_CONFIG_MOCK = {
+ name: 'parrableId',
+ params: {
+ partner: 'parrable_test_partner_123,parrable_test_partner_456'
+ },
+ storage: {
+ name: '_parrable_eid',
+ type: 'cookie',
+ expires: 364
+ }
+};
+
+describe('Parrable ID System', function() {
+ function getConfigMock() {
+ return {
+ userSync: {
+ syncDelay: 0,
+ userIds: [P_CONFIG_MOCK]
+ }
+ }
+ }
+ function getAdUnitMock(code = 'adUnit-code') {
+ return {
+ code,
+ mediaTypes: {banner: {}, native: {}},
+ sizes: [
+ [300, 200],
+ [300, 600]
+ ],
+ bids: [{
+ bidder: 'sampleBidder',
+ params: { placementId: 'banner-only-bidder' }
+ }]
+ };
+ }
+
+ describe('Parrable ID in Bid Request', function() {
+ let adUnits;
+
+ beforeEach(function() {
+ adUnits = [getAdUnitMock()];
+ });
+
+ it('should append parrableid to bid request', function(done) {
+ // simulate existing browser local storage values
+ utils.setCookie(
+ P_COOKIE_NAME,
+ P_COOKIE_VALUE,
+ (new Date(Date.now() + 5000).toUTCString())
+ );
+
+ setSubmoduleRegistry([parrableIdSubmodule]);
+ init(config);
+ config.setConfig(getConfigMock());
+
+ requestBidsHook(function() {
+ adUnits.forEach(unit => {
+ unit.bids.forEach(bid => {
+ expect(bid).to.have.deep.nested.property('userId.parrableid');
+ expect(bid.userId.parrableid).to.equal(P_COOKIE_VALUE);
+ });
+ });
+ utils.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE);
+ done();
+ }, { adUnits });
+ });
+ });
+});
diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js
index c823e5aa370..658f130d144 100644
--- a/test/spec/modules/prebidServerBidAdapter_spec.js
+++ b/test/spec/modules/prebidServerBidAdapter_spec.js
@@ -1043,7 +1043,11 @@ describe('S2S Adapter', function () {
let userIdBidRequest = utils.deepClone(BID_REQUESTS);
userIdBidRequest[0].bids[0].userId = {
tdid: 'abc123',
- pubcid: '1234'
+ pubcid: '1234',
+ parrableid: '01.1563917337.test-eid',
+ lipb: {
+ lipbid: 'li-xyz'
+ }
};
adapter.callBids(REQUEST, userIdBidRequest, addBidResponse, done, ajax);
@@ -1054,6 +1058,10 @@ describe('S2S Adapter', function () {
expect(requestBid.user.ext.eids.filter(eid => eid.source === 'adserver.org')[0].uids[0].id).is.equal('abc123');
expect(requestBid.user.ext.eids.filter(eid => eid.source === 'pubcommon')).is.not.empty;
expect(requestBid.user.ext.eids.filter(eid => eid.source === 'pubcommon')[0].uids[0].id).is.equal('1234');
+ expect(requestBid.user.ext.eids.filter(eid => eid.source === 'parrable.com')).is.not.empty;
+ expect(requestBid.user.ext.eids.filter(eid => eid.source === 'parrable.com')[0].uids[0].id).is.equal('01.1563917337.test-eid');
+ expect(requestBid.user.ext.eids.filter(eid => eid.source === 'liveintent.com')).is.not.empty;
+ expect(requestBid.user.ext.eids.filter(eid => eid.source === 'liveintent.com')[0].uids[0].id).is.equal('li-xyz');
});
it('when config \'currency.adServerCurrency\' value is an array: ORTB has property \'cur\' value set to a single item array', function () {
diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js
index ababf2dcf5f..22c0f840026 100644
--- a/test/spec/modules/pubmaticBidAdapter_spec.js
+++ b/test/spec/modules/pubmaticBidAdapter_spec.js
@@ -1660,7 +1660,43 @@ describe('PubMatic adapter', function () {
expect(data.user.eids).to.equal(undefined);
});
});
- })
+
+ describe('LiveIntent Id', function() {
+ it('send the LiveIntent id if it is present', function() {
+ bidRequests[0].userId = {};
+ bidRequests[0].userId.lipb = { lipbid: 'live-intent-user-id' };
+ let request = spec.buildRequests(bidRequests, {});
+ let data = JSON.parse(request.data);
+ expect(data.user.eids).to.deep.equal([{
+ 'source': 'liveintent.com',
+ 'uids': [{
+ 'id': 'live-intent-user-id',
+ 'atype': 1
+ }]
+ }]);
+ });
+
+ it('do not pass if not string', function() {
+ bidRequests[0].userId = {};
+ bidRequests[0].userId.lipb = { lipbid: 1 };
+ let request = spec.buildRequests(bidRequests, {});
+ let data = JSON.parse(request.data);
+ expect(data.user.eids).to.equal(undefined);
+ bidRequests[0].userId.lipb.lipbid = [];
+ request = spec.buildRequests(bidRequests, {});
+ data = JSON.parse(request.data);
+ expect(data.user.eids).to.equal(undefined);
+ bidRequests[0].userId.lipb.lipbid = null;
+ request = spec.buildRequests(bidRequests, {});
+ data = JSON.parse(request.data);
+ expect(data.user.eids).to.equal(undefined);
+ bidRequests[0].userId.lipb.lipbid = {};
+ request = spec.buildRequests(bidRequests, {});
+ data = JSON.parse(request.data);
+ expect(data.user.eids).to.equal(undefined);
+ });
+ });
+ });
it('Request params check for video ad', function () {
let request = spec.buildRequests(videoBidRequests);
diff --git a/test/spec/modules/pulsepointBidAdapter_spec.js b/test/spec/modules/pulsepointBidAdapter_spec.js
index 1d22ca6eadc..9ed6d3631f5 100644
--- a/test/spec/modules/pulsepointBidAdapter_spec.js
+++ b/test/spec/modules/pulsepointBidAdapter_spec.js
@@ -1,7 +1,7 @@
/* eslint dot-notation:0, quote-props:0 */
import {expect} from 'chai';
import {spec} from 'modules/pulsepointBidAdapter';
-import {deepClone, getTopWindowLocation} from 'src/utils';
+import {deepClone} from 'src/utils';
describe('PulsePoint Adapter Tests', function () {
const slotConfigs = [{
@@ -138,9 +138,14 @@ describe('PulsePoint Adapter Tests', function () {
}
}
}];
+ const bidderRequest = {
+ refererInfo: {
+ referer: 'https://publisher.com/home'
+ }
+ };
it('Verify build request', function () {
- const request = spec.buildRequests(slotConfigs);
+ const request = spec.buildRequests(slotConfigs, bidderRequest);
expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
expect(request.method).to.equal('POST');
const ortbRequest = request.data;
@@ -149,7 +154,7 @@ describe('PulsePoint Adapter Tests', function () {
expect(ortbRequest.site.publisher).to.not.equal(null);
expect(ortbRequest.site.publisher.id).to.equal('p10000');
expect(ortbRequest.site.ref).to.equal(window.top.document.referrer);
- expect(ortbRequest.site.page).to.equal(getTopWindowLocation().href);
+ expect(ortbRequest.site.page).to.equal('https://publisher.com/home');
expect(ortbRequest.imp).to.have.lengthOf(2);
// device object
expect(ortbRequest.device).to.not.equal(null);
@@ -167,7 +172,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify parse response', function () {
- const request = spec.buildRequests(slotConfigs);
+ const request = spec.buildRequests(slotConfigs, bidderRequest);
const ortbRequest = request.data;
const ortbResponse = {
seatbid: [{
@@ -196,7 +201,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify use ttl in ext', function () {
- const request = spec.buildRequests(slotConfigs);
+ const request = spec.buildRequests(slotConfigs, bidderRequest);
const ortbRequest = request.data;
const ortbResponse = {
seatbid: [{
@@ -222,13 +227,13 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify full passback', function () {
- const request = spec.buildRequests(slotConfigs);
+ const request = spec.buildRequests(slotConfigs, bidderRequest);
const bids = spec.interpretResponse({ body: null }, request)
expect(bids).to.have.lengthOf(0);
});
it('Verify Native request', function () {
- const request = spec.buildRequests(nativeSlotConfig);
+ const request = spec.buildRequests(nativeSlotConfig, bidderRequest);
expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
expect(request.method).to.equal('POST');
const ortbRequest = request.data;
@@ -266,7 +271,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify Native response', function () {
- const request = spec.buildRequests(nativeSlotConfig);
+ const request = spec.buildRequests(nativeSlotConfig, bidderRequest);
expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
expect(request.method).to.equal('POST');
const ortbRequest = request.data;
@@ -355,7 +360,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify app requests', function () {
- const request = spec.buildRequests(appSlotConfig);
+ const request = spec.buildRequests(appSlotConfig, bidderRequest);
const ortbRequest = request.data;
// site object
expect(ortbRequest.site).to.equal(null);
@@ -368,13 +373,13 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify GDPR', function () {
- const bidderRequest = {
+ const bidderRequestGdpr = {
gdprConsent: {
gdprApplies: true,
consentString: 'serialized_gpdr_data'
}
};
- const request = spec.buildRequests(slotConfigs, bidderRequest);
+ const request = spec.buildRequests(slotConfigs, Object.assign({}, bidderRequest, bidderRequestGdpr));
expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
expect(request.method).to.equal('POST');
const ortbRequest = request.data;
@@ -389,7 +394,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify Video request', function () {
- const request = spec.buildRequests(videoSlotConfig);
+ const request = spec.buildRequests(videoSlotConfig, bidderRequest);
expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
expect(request.method).to.equal('POST');
const ortbRequest = request.data;
@@ -409,7 +414,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify Video response', function () {
- const request = spec.buildRequests(videoSlotConfig);
+ const request = spec.buildRequests(videoSlotConfig, bidderRequest);
expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
expect(request.method).to.equal('POST');
const ortbRequest = request.data;
@@ -433,7 +438,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify extra parameters', function () {
- let request = spec.buildRequests(additionalParamsConfig);
+ let request = spec.buildRequests(additionalParamsConfig, bidderRequest);
let ortbRequest = request.data;
expect(ortbRequest).to.not.equal(null);
expect(ortbRequest.imp).to.have.lengthOf(1);
@@ -448,7 +453,7 @@ describe('PulsePoint Adapter Tests', function () {
expect(ortbRequest.imp[0].ext.prebid.extra_key4).to.eql([1, 2, 3]);
expect(Object.keys(ortbRequest.imp[0].ext.prebid)).to.eql(['extra_key1', 'extra_key2', 'extra_key3', 'extra_key4']);
// attempting with a configuration with no unknown params.
- request = spec.buildRequests(outstreamSlotConfig);
+ request = spec.buildRequests(outstreamSlotConfig, bidderRequest);
ortbRequest = request.data;
expect(ortbRequest).to.not.equal(null);
expect(ortbRequest.imp).to.have.lengthOf(1);
@@ -456,7 +461,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify ortb parameters', function () {
- const request = spec.buildRequests(ortbParamsSlotConfig);
+ const request = spec.buildRequests(ortbParamsSlotConfig, bidderRequest);
const ortbRequest = request.data;
expect(ortbRequest).to.not.equal(null);
expect(ortbRequest.bcat).to.eql(['IAB-1', 'IAB-20']);
@@ -472,7 +477,8 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify outstream renderer', function () {
- const request = spec.buildRequests(outstreamSlotConfig, {bids: [outstreamSlotConfig[0]]});
+ const bidderRequestOutstream = Object.assign({}, bidderRequest, {bids: [outstreamSlotConfig[0]]});
+ const request = spec.buildRequests(outstreamSlotConfig, bidderRequestOutstream);
const ortbRequest = request.data;
expect(ortbRequest).to.not.be.null;
expect(ortbRequest.imp[0]).to.not.be.null;
@@ -521,7 +527,7 @@ describe('PulsePoint Adapter Tests', function () {
}
}
};
- const request = spec.buildRequests(bidRequests);
+ const request = spec.buildRequests(bidRequests, bidderRequest);
expect(request).to.be.not.null;
const ortbRequest = request.data;
expect(request.data).to.be.not.null;
diff --git a/test/spec/modules/rubiconAnalyticsAdapter_spec.js b/test/spec/modules/rubiconAnalyticsAdapter_spec.js
index 3452ae747b9..dd34245bd8e 100644
--- a/test/spec/modules/rubiconAnalyticsAdapter_spec.js
+++ b/test/spec/modules/rubiconAnalyticsAdapter_spec.js
@@ -92,6 +92,7 @@ const BID2 = Object.assign({}, BID, {
mediaType: 'banner',
cpm: 1.52,
source: 'server',
+ seatBidId: 'aaaa-bbbb-cccc-dddd',
rubiconTargeting: {
'rpfl_elemid': '/19968336/header-bid-tag1',
'rpfl_14062': '2_tier0100'
@@ -222,6 +223,7 @@ const MOCK = {
'transactionId': 'c116413c-9e3f-401a-bee1-d56aec29a1d4',
'sizes': [[1000, 300], [970, 250], [728, 90]],
'bidId': '3bd4ebb1c900e2',
+ 'seatBidId': 'aaaa-bbbb-cccc-dddd',
'bidderRequestId': '1be65d7958826a',
'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa'
}
@@ -354,7 +356,7 @@ const ANALYTICS_MESSAGE = {
'bids': [
{
'bidder': 'rubicon',
- 'bidId': '3bd4ebb1c900e2',
+ 'bidId': 'aaaa-bbbb-cccc-dddd',
'status': 'success',
'source': 'server',
'clientLatencyMillis': 3214,
@@ -421,7 +423,7 @@ const ANALYTICS_MESSAGE = {
'bidder': 'rubicon',
'transactionId': 'c116413c-9e3f-401a-bee1-d56aec29a1d4',
'adUnitCode': '/19968336/header-bid-tag1',
- 'bidId': '3bd4ebb1c900e2',
+ 'bidId': 'aaaa-bbbb-cccc-dddd',
'status': 'success',
'source': 'server',
'clientLatencyMillis': 3214,
diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js
index d31b83fd923..4688f0f5d32 100644
--- a/test/spec/modules/rubiconBidAdapter_spec.js
+++ b/test/spec/modules/rubiconBidAdapter_spec.js
@@ -2036,6 +2036,7 @@ describe('the rubicon adapter', function () {
expect(bids).to.be.lengthOf(1);
+ expect(bids[0].seatBidId).to.equal('0');
expect(bids[0].creativeId).to.equal('4259970');
expect(bids[0].cpm).to.equal(2);
expect(bids[0].ttl).to.equal(300);
diff --git a/test/spec/modules/shBidAdapter_spec.js b/test/spec/modules/shBidAdapter_spec.js
index 588d4c54150..525642da7d6 100644
--- a/test/spec/modules/shBidAdapter_spec.js
+++ b/test/spec/modules/shBidAdapter_spec.js
@@ -16,17 +16,11 @@ const gdpr = {
}
}
-const bidRequestVideo = {
+const bidRequestCommonParams = {
'bidder': 'showheroes-bs',
'params': {
'playerId': '47427aa0-f11a-4d24-abca-1295a46a46cd',
},
- 'mediaTypes': {
- 'video': {
- 'playerSize': [640, 480],
- 'context': 'instream',
- }
- },
'adUnitCode': 'adunit-code-1',
'sizes': [[640, 480]],
'bidId': '38b373e1e31c18',
@@ -34,40 +28,55 @@ const bidRequestVideo = {
'auctionId': '43aa080090a47f',
}
+const bidRequestVideo = {
+ ...bidRequestCommonParams,
+ ...{
+ 'mediaTypes': {
+ 'video': {
+ 'playerSize': [640, 480],
+ 'context': 'instream',
+ }
+ }
+ }
+}
+
+const bidRequestOutstream = {
+ ...bidRequestCommonParams,
+ ...{
+ 'mediaTypes': {
+ 'video': {
+ 'playerSize': [640, 480],
+ 'context': 'outstream',
+ }
+ }
+ }
+}
+
const bidRequestVideoVpaid = {
- 'bidder': 'showheroes-bs',
- 'params': {
- 'playerId': '47427aa0-f11a-4d24-abca-1295a46a46cd',
- 'vpaidMode': true,
- },
- 'mediaTypes': {
- 'video': {
- 'playerSize': [640, 480],
- 'context': 'instream',
+ ...bidRequestCommonParams,
+ ...{
+ 'params': {
+ 'playerId': '47427aa0-f11a-4d24-abca-1295a46a46cd',
+ 'vpaidMode': true,
+ },
+ 'mediaTypes': {
+ 'video': {
+ 'playerSize': [640, 480],
+ 'context': 'instream',
+ }
}
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[640, 480]],
- 'bidId': '38b373e1e31c18',
- 'bidderRequestId': '12e3ade2543ba6',
- 'auctionId': '43aa080090a47f',
+ }
}
const bidRequestBanner = {
- 'bidder': 'showheroes-bs',
- 'params': {
- 'playerId': '47427aa0-f11a-4d24-abca-1295a46a46cd',
- },
- 'mediaTypes': {
- 'banner': {
- 'sizes': [[640, 360]]
+ ...bidRequestCommonParams,
+ ...{
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [[640, 360]]
+ }
}
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[640, 480]],
- 'bidId': '38b373e1e31c18',
- 'bidderRequestId': '12e3ade2543ba6',
- 'auctionId': '43aa080090a47f',
+ }
}
describe('shBidAdapter', function () {
@@ -103,6 +112,58 @@ describe('shBidAdapter', function () {
expect(request.method).to.equal('POST')
})
+ it('check sizes formats', function () {
+ const request = spec.buildRequests([{
+ 'params': {},
+ 'mediaTypes': {},
+ 'sizes': [[640, 480]],
+ }], bidderRequest)
+ const payload = request.data.requests[0];
+ expect(payload).to.be.an('object');
+ expect(payload.video).to.have.property('width', 640);
+ expect(payload.video).to.have.property('height', 480);
+
+ const request2 = spec.buildRequests([{
+ 'params': {},
+ 'mediaTypes': {},
+ 'sizes': [320, 240],
+ }], bidderRequest)
+ const payload2 = request2.data.requests[0];
+ expect(payload).to.be.an('object');
+ expect(payload2.video).to.have.property('width', 320);
+ expect(payload2.video).to.have.property('height', 240);
+ })
+
+ it('should get size from mediaTypes when sizes property is empty', function () {
+ const request = spec.buildRequests([{
+ 'params': {},
+ 'mediaTypes': {
+ 'video': {
+ 'playerSize': [640, 480]
+ }
+ },
+ 'sizes': [],
+ }], bidderRequest)
+ const payload = request.data.requests[0];
+ expect(payload).to.be.an('object');
+ expect(payload.video).to.have.property('width', 640);
+ expect(payload.video).to.have.property('height', 480);
+
+ const request2 = spec.buildRequests([{
+ 'params': {},
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [[320, 240]]
+ }
+ },
+ 'sizes': [],
+ }], bidderRequest)
+ const payload2 = request2.data.requests[0];
+ expect(payload).to.be.an('object');
+ expect(payload2.video).to.have.property('width', 320);
+ expect(payload2.video).to.have.property('height', 240);
+ })
+
it('should attach valid params to the payload when type is video', function () {
const request = spec.buildRequests([bidRequestVideo], bidderRequest)
const payload = request.data.requests[0];
@@ -144,6 +205,9 @@ describe('shBidAdapter', function () {
expect(spec.interpretResponse({body: []}, {data: {meta: {}}}).length).to.equal(0)
})
+ const vastTag = 'https://video-library.stage.showheroes.com/commercial/wrapper?player_id=47427aa0-f11a-4d24-abca-1295a46a46cd&ad_bidder=showheroes-bs&master_shadt=1&description_url=https%3A%2F%2Fbid-service.stage.showheroes.com%2Fvast%2Fad%2Fcache%2F4840b920-40e1-4e09-9231-60bbf088c8d6'
+ const vastXml = '
'
+
const response = {
'bids': [{
'cpm': 5,
@@ -151,6 +215,7 @@ describe('shBidAdapter', function () {
'bidId': '38b373e1e31c18',
'video': {'width': 640, 'height': 480},
'vastTag': 'https:\/\/video-library.stage.showheroes.com\/commercial\/wrapper?player_id=47427aa0-f11a-4d24-abca-1295a46a46cd&ad_bidder=showheroes-bs&master_shadt=1&description_url=https%3A%2F%2Fbid-service.stage.showheroes.com%2Fvast%2Fad%2Fcache%2F4840b920-40e1-4e09-9231-60bbf088c8d6',
+ 'vastXml': vastXml,
}],
}
@@ -165,9 +230,13 @@ describe('shBidAdapter', function () {
'height': 480,
'mediaType': 'video',
'netRevenue': true,
- 'vastUrl': 'https://video-library.stage.showheroes.com/commercial/wrapper?player_id=47427aa0-f11a-4d24-abca-1295a46a46cd&ad_bidder=showheroes-bs&master_shadt=1&description_url=https%3A%2F%2Fbid-service.stage.showheroes.com%2Fvast%2Fad%2Fcache%2F4840b920-40e1-4e09-9231-60bbf088c8d6',
+ 'vastUrl': vastTag,
+ 'vastXml': vastXml,
'requestId': '38b373e1e31c18',
'ttl': 300,
+ 'adResponse': {
+ 'content': vastXml
+ }
}
]
@@ -183,5 +252,129 @@ describe('shBidAdapter', function () {
expect(result[0].ad).to.include('