diff --git a/integrationExamples/gpt/adloox.html b/integrationExamples/gpt/adloox.html
index e8920cf2ee1..fd61267479d 100644
--- a/integrationExamples/gpt/adloox.html
+++ b/integrationExamples/gpt/adloox.html
@@ -161,7 +161,11 @@
},
rubicon: {
singleRequest: true
- }
+ },
+ // RTD module honors pageUrl for referrer detection and
+ // the analytics module uses this for the 'pageurl' macro
+ // N.B. set this to a non-example.com URL to see the video
+ //pageUrl: 'https://yourdomain.com/some/path/to/content.html'
});
pbjs.enableAnalytics({
provider: 'adloox',
diff --git a/modules/adlooxAnalyticsAdapter.js b/modules/adlooxAnalyticsAdapter.js
index 2f4fd9334d2..1091b87a22d 100644
--- a/modules/adlooxAnalyticsAdapter.js
+++ b/modules/adlooxAnalyticsAdapter.js
@@ -11,6 +11,7 @@ import {auctionManager} from '../src/auctionManager.js';
import {AUCTION_COMPLETED} from '../src/auction.js';
import CONSTANTS from '../src/constants.json';
import {find} from '../src/polyfill.js';
+import {getRefererInfo} from '../src/refererDetection.js';
import {
deepAccess,
getGptSlotInfoForAdUnitCode,
@@ -58,6 +59,10 @@ MACRO['targetelt'] = function(b, c) {
MACRO['creatype'] = function(b, c) {
return b.mediaType == 'video' ? ADLOOX_MEDIATYPE.VIDEO : ADLOOX_MEDIATYPE.DISPLAY;
};
+MACRO['pageurl'] = function(b, c) {
+ const refererInfo = getRefererInfo();
+ return (refererInfo.canonicalUrl || refererInfo.referer || '').substr(0, 300).split(/[?#]/)[0];
+};
MACRO['pbadslot'] = function(b, c) {
const adUnit = find(auctionManager.getAdUnits(), a => b.adUnitCode === a.code);
return deepAccess(adUnit, 'ortb2Imp.ext.data.pbadslot') || getGptSlotInfoForAdUnitCode(b.adUnitCode).gptSlot || b.adUnitCode;
diff --git a/modules/adlooxAnalyticsAdapter.md b/modules/adlooxAnalyticsAdapter.md
index c4618a2e3aa..e21261d0b8d 100644
--- a/modules/adlooxAnalyticsAdapter.md
+++ b/modules/adlooxAnalyticsAdapter.md
@@ -127,6 +127,7 @@ The following macros are available
* `%%pbadslot%%`: [Prebid Ad Slot](https://docs.prebid.org/features/pbAdSlot.html) returns [`AdUnit.code`](https://docs.prebid.org/features/pbAdSlot.html) if set otherwise returns [`AdUnit.code`](https://docs.prebid.org/dev-docs/adunit-reference.html#adunit)
* it is recommended you read the [Prebid Ad Slot section in the Adloox RTD Provider documentation](./adlooxRtdProvider.md#prebid-ad-slot)
+ * `%%pageurl%%`: [`canonicalUrl`](https://docs.prebid.org/dev-docs/publisher-api-reference/setConfig.html#setConfig-Page-URL) from the [`refererInfo` object](https://docs.prebid.org/dev-docs/bidder-adaptor.html#referrers) otherwise uses `referer`
### Functions
diff --git a/modules/adlooxRtdProvider.js b/modules/adlooxRtdProvider.js
index edd040faee2..bb8334ec8fe 100644
--- a/modules/adlooxRtdProvider.js
+++ b/modules/adlooxRtdProvider.js
@@ -16,6 +16,7 @@ import {config as _config} from '../src/config.js';
import {submodule} from '../src/hook.js';
import {ajax} from '../src/ajax.js';
import {getGlobal} from '../src/prebidGlobal.js';
+import {getRefererInfo} from '../src/refererDetection.js';
import {
_each,
deepAccess,
@@ -297,6 +298,7 @@ function getBidRequestData(reqBidsConfigObj, callback, config, userConsent) {
}
}
+ const refererInfo = getRefererInfo();
const args = [
[ 'v', `pbjs-${getGlobal().version}` ],
[ 'c', config.params.clientid ],
@@ -305,7 +307,7 @@ function getBidRequestData(reqBidsConfigObj, callback, config, userConsent) {
[ 'imp', config.params.imps ],
[ 'fc_ip', config.params.freqcap_ip ],
[ 'fc_ipua', config.params.freqcap_ipua ],
- [ 'pn', document.location.pathname ]
+ [ 'pn', (refererInfo.canonicalUrl || refererInfo.referer || '').substr(0, 300).split(/[?#]/)[0] ]
];
if (!adUnits.length) {
diff --git a/modules/adrinoBidAdapter.js b/modules/adrinoBidAdapter.js
new file mode 100644
index 00000000000..4520066c3e7
--- /dev/null
+++ b/modules/adrinoBidAdapter.js
@@ -0,0 +1,74 @@
+import {registerBidder} from '../src/adapters/bidderFactory.js';
+import {triggerPixel} from '../src/utils.js';
+import {NATIVE} from '../src/mediaTypes.js';
+
+const BIDDER_CODE = 'adrino';
+const REQUEST_METHOD = 'POST';
+const BIDDER_HOST = 'https://prd-prebid-bidder.adrino.io';
+const GVLID = 1072;
+
+export const spec = {
+ code: BIDDER_CODE,
+ gvlid: GVLID,
+ supportedMediaTypes: [NATIVE],
+
+ isBidRequestValid: function (bid) {
+ return !!(bid.bidId) &&
+ !!(bid.params) &&
+ !!(bid.params.hash) &&
+ (typeof bid.params.hash === 'string') &&
+ !!(bid.mediaTypes) &&
+ Object.keys(bid.mediaTypes).includes(NATIVE) &&
+ (bid.bidder === BIDDER_CODE);
+ },
+
+ buildRequests: function (validBidRequests, bidderRequest) {
+ const bidRequests = [];
+
+ for (let i = 0; i < validBidRequests.length; i++) {
+ let requestData = {
+ bidId: validBidRequests[i].bidId,
+ nativeParams: validBidRequests[i].nativeParams,
+ placementHash: validBidRequests[i].params.hash,
+ referer: bidderRequest.refererInfo.referer,
+ userAgent: navigator.userAgent,
+ }
+
+ if (bidderRequest && bidderRequest.gdprConsent) {
+ requestData.gdprConsent = {
+ consentString: bidderRequest.gdprConsent.consentString,
+ consentRequired: bidderRequest.gdprConsent.gdprApplies
+ }
+ }
+
+ bidRequests.push({
+ method: REQUEST_METHOD,
+ url: BIDDER_HOST + '/bidder/bid/',
+ data: requestData,
+ options: {
+ contentType: 'application/json',
+ withCredentials: false,
+ }
+ });
+ }
+
+ return bidRequests;
+ },
+
+ interpretResponse: function (serverResponse, bidRequest) {
+ const response = serverResponse.body;
+ const bidResponses = [];
+ if (!response.noAd) {
+ bidResponses.push(response);
+ }
+ return bidResponses;
+ },
+
+ onBidWon: function (bid) {
+ if (bid['requestId']) {
+ triggerPixel(BIDDER_HOST + '/bidder/won/' + bid['requestId']);
+ }
+ }
+};
+
+registerBidder(spec);
diff --git a/modules/adrinoBidAdapter.md b/modules/adrinoBidAdapter.md
new file mode 100644
index 00000000000..5ec63a72736
--- /dev/null
+++ b/modules/adrinoBidAdapter.md
@@ -0,0 +1,45 @@
+# Overview
+
+```
+Module Name: Adrino Bidder Adapter
+Module Type: Bidder Adapter
+Maintainer: dev@adrino.pl
+```
+
+# Description
+
+Module connects to Adrino bidder to fetch bids. Only native format is supported.
+
+# Test Parameters
+
+```
+var adUnits = [
+ code: '/12345678/prebid_native_example_1',
+ mediaTypes: {
+ native: {
+ image: {
+ required: true,
+ sizes: [[300, 210],[300,150],[140,100]]
+ },
+ title: {
+ required: true
+ },
+ sponsoredBy: {
+ required: false
+ },
+ body: {
+ required: false
+ },
+ icon: {
+ required: false
+ }
+ }
+ },
+ bids: [{
+ bidder: 'adrino',
+ params: {
+ hash: 'abcdef123456'
+ }
+ }]
+];
+```
diff --git a/modules/consentManagement.js b/modules/consentManagement.js
index 88c643b484c..65e0d6e92eb 100644
--- a/modules/consentManagement.js
+++ b/modules/consentManagement.js
@@ -287,6 +287,7 @@ export function requestBidsHook(fn, reqBidsConfigObj) {
if (!includes(Object.keys(cmpCallMap), userCMP)) {
logWarn(`CMP framework (${userCMP}) is not a supported framework. Aborting consentManagement module and resuming auction.`);
+ gdprDataHandler.setConsentData(null);
return hookConfig.nextFn.apply(hookConfig.context, hookConfig.args);
}
@@ -450,6 +451,7 @@ function exitModule(errMsg, hookConfig, extraArgs) {
nextFn.apply(context, args);
} else {
logError(errMsg + ' Canceling auction as per consentManagement config.', extraArgs);
+ gdprDataHandler.setConsentData(null);
if (typeof hookConfig.bidsBackHandler === 'function') {
hookConfig.bidsBackHandler();
} else {
@@ -469,7 +471,7 @@ export function resetConsentData() {
consentData = undefined;
userCMP = undefined;
cmpVersion = 0;
- gdprDataHandler.setConsentData(null);
+ gdprDataHandler.reset();
}
/**
@@ -507,6 +509,7 @@ export function setConsentConfig(config) {
gdprScope = config.defaultGdprScope === true;
logInfo('consentManagement module has been activated...');
+ gdprDataHandler.enable();
if (userCMP === 'static') {
if (isPlainObject(config.consentData)) {
diff --git a/modules/consentManagementUsp.js b/modules/consentManagementUsp.js
index 4a4c4ae0a55..75462221403 100644
--- a/modules/consentManagementUsp.js
+++ b/modules/consentManagementUsp.js
@@ -186,6 +186,7 @@ export function requestBidsHook(fn, reqBidsConfigObj) {
if (!uspCallMap[consentAPI]) {
logWarn(`USP framework (${consentAPI}) is not a supported framework. Aborting consentManagement module and resuming auction.`);
+ uspDataHandler.setConsentData(null);
return hookConfig.nextFn.apply(hookConfig.context, hookConfig.args);
}
@@ -276,6 +277,7 @@ function exitModule(errMsg, hookConfig, extraArgs) {
if (errMsg) {
logWarn(errMsg + ' Resuming auction without consent data as per consentManagement config.', extraArgs);
+ uspDataHandler.setConsentData(null) // let core know that no consent data is available
}
nextFn.apply(context, args);
}
@@ -287,7 +289,7 @@ function exitModule(errMsg, hookConfig, extraArgs) {
export function resetConsentData() {
consentData = undefined;
consentAPI = undefined;
- uspDataHandler.setConsentData(null);
+ uspDataHandler.reset();
}
/**
@@ -315,6 +317,7 @@ export function setConsentConfig(config) {
}
logInfo('USPAPI consentManagement module has been activated...');
+ uspDataHandler.enable();
if (consentAPI === 'static') {
if (isPlainObject(config.consentData) && isPlainObject(config.consentData.getUSPData)) {
diff --git a/package-lock.json b/package-lock.json
index e7f349bd307..4c9bab3ea20 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4775,13 +4775,13 @@
"dev": true
},
"node_modules/browserslist": {
- "version": "4.19.3",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz",
- "integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==",
+ "version": "4.20.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.0.tgz",
+ "integrity": "sha512-bnpOoa+DownbciXj0jVGENf8VYQnE2LNWomhYuCsMmmx9Jd9lwq0WXODuwpSsp8AVdKM2/HorrzxAfbKvWTByQ==",
"dev": true,
"dependencies": {
- "caniuse-lite": "^1.0.30001312",
- "electron-to-chromium": "^1.4.71",
+ "caniuse-lite": "^1.0.30001313",
+ "electron-to-chromium": "^1.4.76",
"escalade": "^3.1.1",
"node-releases": "^2.0.2",
"picocolors": "^1.0.0"
@@ -5354,9 +5354,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001312",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz",
- "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==",
+ "version": "1.0.30001314",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001314.tgz",
+ "integrity": "sha512-0zaSO+TnCHtHJIbpLroX7nsD+vYuOVjl3uzFbJO1wMVbuveJA0RK2WcQA9ZUIOiO0/ArMiMgHJLxfEZhQiC0kw==",
"dev": true,
"funding": {
"type": "opencollective",
@@ -7687,9 +7687,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.75",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.75.tgz",
- "integrity": "sha512-LxgUNeu3BVU7sXaKjUDD9xivocQLxFtq6wgERrutdY/yIOps3ODOZExK1jg8DTEg4U8TUCb5MLGeWFOYuxjF3Q==",
+ "version": "1.4.78",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.78.tgz",
+ "integrity": "sha512-o61+D/Lx7j/E0LIin/efOqeHpXhwi1TaQco9vUcRmr91m25SfZY6L5hWJDv/r+6kNjboFKgBw1LbfM0lbhuK6Q==",
"dev": true
},
"node_modules/emoji-regex": {
@@ -7895,22 +7895,20 @@
}
},
"node_modules/es5-ext": {
- "version": "0.10.53",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
- "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+ "version": "0.10.57",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.57.tgz",
+ "integrity": "sha512-L7cCNoPwTkAp7IBHxrKLsh7NKiVFkcdxlP9vbVw9QUvb7gF0Mz9bEBN0WY9xqdTjGF907EMT/iG013vnbqwu1Q==",
"dev": true,
+ "hasInstallScript": true,
"dependencies": {
- "es6-iterator": "~2.0.3",
- "es6-symbol": "~3.1.3",
- "next-tick": "~1.0.0"
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.3",
+ "next-tick": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
}
},
- "node_modules/es5-ext/node_modules/next-tick": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
- "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
- "dev": true
- },
"node_modules/es5-shim": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/es5-shim/-/es5-shim-4.6.5.tgz",
@@ -12831,9 +12829,9 @@
}
},
"node_modules/http-parser-js": {
- "version": "0.5.5",
- "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz",
- "integrity": "sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==",
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.6.tgz",
+ "integrity": "sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA==",
"dev": true
},
"node_modules/http-proxy": {
@@ -18252,9 +18250,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.7",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.7.tgz",
- "integrity": "sha512-L9Ye3r6hkkCeOETQX6iOaWZgjp3LL6Lpqm6EtgbKrgqGGteRMNb9vzBfRL96YOSu8o7x3MfIH9Mo5cPJFGrW6A==",
+ "version": "8.4.8",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.8.tgz",
+ "integrity": "sha512-2tXEqGxrjvAO6U+CJzDL2Fk2kPHTv1jQsYkSoMeOis2SsYaXRO2COxTdQp99cYvif9JTXaAk9lYGc3VhJt7JPQ==",
"dev": true,
"optional": true,
"dependencies": {
@@ -18479,14 +18477,14 @@
}
},
"node_modules/puppeteer-core": {
- "version": "13.4.1",
- "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-13.4.1.tgz",
- "integrity": "sha512-AgRIWgIkUXXnbvoRhyveZnyoEYr3wTunSk2/evOfWvFs65GUzsrxnUTUSLgPM4MRshCQmRABW7qE1hDN1AD7nA==",
+ "version": "13.5.1",
+ "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-13.5.1.tgz",
+ "integrity": "sha512-dobVqWjV34ilyfQHR3BBnCYaekBYTi5MgegEYBRYd3s3uFy8jUpZEEWbaFjG9ETm+LGzR5Lmr0aF6LLuHtiuCg==",
"dev": true,
"dependencies": {
"cross-fetch": "3.1.5",
"debug": "4.3.3",
- "devtools-protocol": "0.0.960912",
+ "devtools-protocol": "0.0.969999",
"extract-zip": "2.0.1",
"https-proxy-agent": "5.0.0",
"pkg-dir": "4.2.0",
@@ -18514,9 +18512,9 @@
}
},
"node_modules/puppeteer-core/node_modules/devtools-protocol": {
- "version": "0.0.960912",
- "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.960912.tgz",
- "integrity": "sha512-I3hWmV9rWHbdnUdmMKHF2NuYutIM2kXz2mdXW8ha7TbRlGTVs+PF+PsB5QWvpCek4Fy9B+msiispCfwlhG5Sqg==",
+ "version": "0.0.969999",
+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.969999.tgz",
+ "integrity": "sha512-6GfzuDWU0OFAuOvBokXpXPLxjOJ5DZ157Ue3sGQQM3LgAamb8m0R0ruSfN0DDu+XG5XJgT50i6zZ/0o8RglreQ==",
"dev": true
},
"node_modules/puppeteer-core/node_modules/https-proxy-agent": {
@@ -19433,9 +19431,9 @@
}
},
"node_modules/rxjs": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz",
- "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==",
+ "version": "7.5.5",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz",
+ "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==",
"dev": true,
"dependencies": {
"tslib": "^2.1.0"
@@ -21552,9 +21550,9 @@
}
},
"node_modules/tsconfig-paths": {
- "version": "3.12.0",
- "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
- "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==",
+ "version": "3.13.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.13.0.tgz",
+ "integrity": "sha512-nWuffZppoaYK0vQ1SQmkSsQzJoHA4s6uzdb2waRpD806x9yfq153AdVsWz4je2qZcW+pENrMQXbGQ3sMCkXuhw==",
"dev": true,
"dependencies": {
"@types/json5": "^0.0.29",
@@ -23327,7 +23325,6 @@
}
},
"plugins/eslint": {
- "name": "eslint-plugin-prebid",
"version": "1.0.0",
"dev": true,
"license": "Apache-2.0"
@@ -26953,13 +26950,13 @@
"dev": true
},
"browserslist": {
- "version": "4.19.3",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz",
- "integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==",
+ "version": "4.20.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.0.tgz",
+ "integrity": "sha512-bnpOoa+DownbciXj0jVGENf8VYQnE2LNWomhYuCsMmmx9Jd9lwq0WXODuwpSsp8AVdKM2/HorrzxAfbKvWTByQ==",
"dev": true,
"requires": {
- "caniuse-lite": "^1.0.30001312",
- "electron-to-chromium": "^1.4.71",
+ "caniuse-lite": "^1.0.30001313",
+ "electron-to-chromium": "^1.4.76",
"escalade": "^3.1.1",
"node-releases": "^2.0.2",
"picocolors": "^1.0.0"
@@ -27394,9 +27391,9 @@
}
},
"caniuse-lite": {
- "version": "1.0.30001312",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz",
- "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==",
+ "version": "1.0.30001314",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001314.tgz",
+ "integrity": "sha512-0zaSO+TnCHtHJIbpLroX7nsD+vYuOVjl3uzFbJO1wMVbuveJA0RK2WcQA9ZUIOiO0/ArMiMgHJLxfEZhQiC0kw==",
"dev": true
},
"caseless": {
@@ -29225,9 +29222,9 @@
}
},
"electron-to-chromium": {
- "version": "1.4.75",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.75.tgz",
- "integrity": "sha512-LxgUNeu3BVU7sXaKjUDD9xivocQLxFtq6wgERrutdY/yIOps3ODOZExK1jg8DTEg4U8TUCb5MLGeWFOYuxjF3Q==",
+ "version": "1.4.78",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.78.tgz",
+ "integrity": "sha512-o61+D/Lx7j/E0LIin/efOqeHpXhwi1TaQco9vUcRmr91m25SfZY6L5hWJDv/r+6kNjboFKgBw1LbfM0lbhuK6Q==",
"dev": true
},
"emoji-regex": {
@@ -29397,22 +29394,14 @@
}
},
"es5-ext": {
- "version": "0.10.53",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
- "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+ "version": "0.10.57",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.57.tgz",
+ "integrity": "sha512-L7cCNoPwTkAp7IBHxrKLsh7NKiVFkcdxlP9vbVw9QUvb7gF0Mz9bEBN0WY9xqdTjGF907EMT/iG013vnbqwu1Q==",
"dev": true,
"requires": {
- "es6-iterator": "~2.0.3",
- "es6-symbol": "~3.1.3",
- "next-tick": "~1.0.0"
- },
- "dependencies": {
- "next-tick": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
- "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
- "dev": true
- }
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.3",
+ "next-tick": "^1.1.0"
}
},
"es5-shim": {
@@ -33387,9 +33376,9 @@
}
},
"http-parser-js": {
- "version": "0.5.5",
- "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz",
- "integrity": "sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==",
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.6.tgz",
+ "integrity": "sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA==",
"dev": true
},
"http-proxy": {
@@ -37616,9 +37605,9 @@
"dev": true
},
"postcss": {
- "version": "8.4.7",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.7.tgz",
- "integrity": "sha512-L9Ye3r6hkkCeOETQX6iOaWZgjp3LL6Lpqm6EtgbKrgqGGteRMNb9vzBfRL96YOSu8o7x3MfIH9Mo5cPJFGrW6A==",
+ "version": "8.4.8",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.8.tgz",
+ "integrity": "sha512-2tXEqGxrjvAO6U+CJzDL2Fk2kPHTv1jQsYkSoMeOis2SsYaXRO2COxTdQp99cYvif9JTXaAk9lYGc3VhJt7JPQ==",
"dev": true,
"optional": true,
"requires": {
@@ -37794,14 +37783,14 @@
"dev": true
},
"puppeteer-core": {
- "version": "13.4.1",
- "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-13.4.1.tgz",
- "integrity": "sha512-AgRIWgIkUXXnbvoRhyveZnyoEYr3wTunSk2/evOfWvFs65GUzsrxnUTUSLgPM4MRshCQmRABW7qE1hDN1AD7nA==",
+ "version": "13.5.1",
+ "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-13.5.1.tgz",
+ "integrity": "sha512-dobVqWjV34ilyfQHR3BBnCYaekBYTi5MgegEYBRYd3s3uFy8jUpZEEWbaFjG9ETm+LGzR5Lmr0aF6LLuHtiuCg==",
"dev": true,
"requires": {
"cross-fetch": "3.1.5",
"debug": "4.3.3",
- "devtools-protocol": "0.0.960912",
+ "devtools-protocol": "0.0.969999",
"extract-zip": "2.0.1",
"https-proxy-agent": "5.0.0",
"pkg-dir": "4.2.0",
@@ -37823,9 +37812,9 @@
}
},
"devtools-protocol": {
- "version": "0.0.960912",
- "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.960912.tgz",
- "integrity": "sha512-I3hWmV9rWHbdnUdmMKHF2NuYutIM2kXz2mdXW8ha7TbRlGTVs+PF+PsB5QWvpCek4Fy9B+msiispCfwlhG5Sqg==",
+ "version": "0.0.969999",
+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.969999.tgz",
+ "integrity": "sha512-6GfzuDWU0OFAuOvBokXpXPLxjOJ5DZ157Ue3sGQQM3LgAamb8m0R0ruSfN0DDu+XG5XJgT50i6zZ/0o8RglreQ==",
"dev": true
},
"https-proxy-agent": {
@@ -38545,9 +38534,9 @@
}
},
"rxjs": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz",
- "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==",
+ "version": "7.5.5",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz",
+ "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==",
"dev": true,
"requires": {
"tslib": "^2.1.0"
@@ -40272,9 +40261,9 @@
"dev": true
},
"tsconfig-paths": {
- "version": "3.12.0",
- "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
- "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==",
+ "version": "3.13.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.13.0.tgz",
+ "integrity": "sha512-nWuffZppoaYK0vQ1SQmkSsQzJoHA4s6uzdb2waRpD806x9yfq153AdVsWz4je2qZcW+pENrMQXbGQ3sMCkXuhw==",
"dev": true,
"requires": {
"@types/json5": "^0.0.29",
diff --git a/src/adapterManager.js b/src/adapterManager.js
index 89da900ae0a..a72b5daf6bf 100644
--- a/src/adapterManager.js
+++ b/src/adapterManager.js
@@ -20,7 +20,6 @@ import {
logWarn,
shuffle,
timestamp,
- isStr
} from './utils.js';
import {processAdUnitsForLabels} from './sizeMapping.js';
import { decorateAdUnitsWithNativeParams, nativeAdapters } from './native.js';
@@ -31,6 +30,7 @@ import { hook } from './hook.js';
import {includes, find} from './polyfill.js';
import { adunitCounter } from './adUnits.js';
import { getRefererInfo } from './refererDetection.js';
+import {GdprConsentHandler, UspConsentHandler} from './consentHandler.js';
var CONSTANTS = require('./constants.json');
var events = require('./events.js');
@@ -141,47 +141,8 @@ function getAdUnitCopyForClientAdapters(adUnits) {
return adUnitsClientCopy;
}
-export let gdprDataHandler = {
- consentData: null,
- generatedTime: null,
- setConsentData: function(consentInfo, time = timestamp()) {
- gdprDataHandler.consentData = consentInfo;
- gdprDataHandler.generatedTime = time;
- },
- getConsentData: function() {
- return gdprDataHandler.consentData;
- },
- getConsentMeta: function() {
- if (gdprDataHandler.consentData && gdprDataHandler.consentData.vendorData && gdprDataHandler.generatedTime) {
- return {
- gdprApplies: gdprDataHandler.consentData.gdprApplies,
- consentStringSize: (isStr(gdprDataHandler.consentData.vendorData.tcString)) ? gdprDataHandler.consentData.vendorData.tcString.length : 0,
- generatedAt: gdprDataHandler.generatedTime,
- apiVersion: gdprDataHandler.consentData.apiVersion
- };
- }
- }
-};
-
-export let uspDataHandler = {
- consentData: null,
- generatedTime: null,
- setConsentData: function(consentInfo, time = timestamp()) {
- uspDataHandler.consentData = consentInfo;
- uspDataHandler.generatedTime = time;
- },
- getConsentData: function() {
- return uspDataHandler.consentData;
- },
- getConsentMeta: function() {
- if (uspDataHandler.consentData && uspDataHandler.generatedTime) {
- return {
- usp: uspDataHandler.consentData,
- generatedAt: uspDataHandler.generatedTime
- }
- }
- }
-};
+export let gdprDataHandler = new GdprConsentHandler();
+export let uspDataHandler = new UspConsentHandler();
export let coppaDataHandler = {
getCoppa: function() {
diff --git a/src/consentHandler.js b/src/consentHandler.js
new file mode 100644
index 00000000000..0df9e6fcb3b
--- /dev/null
+++ b/src/consentHandler.js
@@ -0,0 +1,98 @@
+import {isStr, timestamp} from './utils.js';
+
+export class ConsentHandler {
+ #enabled;
+ #data;
+ #promise;
+ #resolve;
+ #ready;
+ generatedTime;
+
+ constructor() {
+ this.reset();
+ }
+
+ /**
+ * reset this handler (mainly for tests)
+ */
+ reset() {
+ this.#promise = new Promise((resolve) => {
+ this.#resolve = (data) => {
+ this.#ready = true;
+ this.#data = data;
+ resolve(data);
+ };
+ });
+ this.#enabled = false;
+ this.#data = null;
+ this.#ready = false;
+ this.generatedTime = null;
+ }
+
+ /**
+ * Enable this consent handler. This should be called by the relevant consent management module
+ * on initialization.
+ */
+ enable() {
+ this.#enabled = true;
+ }
+
+ /**
+ * @returns {boolean} true if the related consent management module is enabled.
+ */
+ get enabled() {
+ return this.#enabled;
+ }
+
+ /**
+ * @returns {boolean} true if consent data has been resolved (it may be `null` if the resolution failed).
+ */
+ get ready() {
+ return this.#ready;
+ }
+
+ /**
+ * @returns a promise than resolves to the consent data, or null if no consent data is available
+ */
+ get promise() {
+ if (!this.#enabled) {
+ this.#resolve(null);
+ }
+ return this.#promise;
+ }
+
+ setConsentData(data, time = timestamp()) {
+ this.generatedTime = time;
+ this.#resolve(data);
+ }
+
+ getConsentData() {
+ return this.#data;
+ }
+}
+
+export class UspConsentHandler extends ConsentHandler {
+ getConsentMeta() {
+ const consentData = this.getConsentData();
+ if (consentData && this.generatedTime) {
+ return {
+ usp: consentData,
+ generatedAt: this.generatedTime
+ };
+ }
+ }
+}
+
+export class GdprConsentHandler extends ConsentHandler {
+ getConsentMeta() {
+ const consentData = this.getConsentData();
+ if (consentData && consentData.vendorData && this.generatedTime) {
+ return {
+ gdprApplies: consentData.gdprApplies,
+ consentStringSize: (isStr(consentData.vendorData.tcString)) ? consentData.vendorData.tcString.length : 0,
+ generatedAt: this.generatedTime,
+ apiVersion: consentData.apiVersion
+ }
+ }
+ }
+}
diff --git a/test/spec/modules/adrinoBidAdapter_spec.js b/test/spec/modules/adrinoBidAdapter_spec.js
new file mode 100644
index 00000000000..52b2796e6db
--- /dev/null
+++ b/test/spec/modules/adrinoBidAdapter_spec.js
@@ -0,0 +1,204 @@
+import { expect } from 'chai';
+import { spec } from 'modules/adrinoBidAdapter.js';
+import * as utils from '../../../src/utils';
+
+describe('adrinoBidAdapter', function () {
+ describe('isBidRequestValid', function () {
+ const validBid = {
+ bidder: 'adrino',
+ params: {
+ hash: 'abcdef123456'
+ },
+ mediaTypes: {
+ native: {
+ title: {
+ required: true
+ },
+ image: {
+ required: true,
+ sizes: [[300, 150], [300, 210]]
+ }
+ }
+ },
+ adUnitCode: 'adunit-code',
+ bidId: '12345678901234',
+ bidderRequestId: '98765432109876',
+ auctionId: '01234567891234',
+ };
+
+ it('should return true when all mandatory parameters are there', function () {
+ expect(spec.isBidRequestValid(validBid)).to.equal(true);
+ });
+
+ it('should return false when there are no params', function () {
+ const bid = { ...validBid };
+ delete bid.params;
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
+ });
+
+ it('should return false when unsupported media type is requested', function () {
+ const bid = { ...validBid };
+ bid.mediaTypes = { banner: { sizes: [[300, 250]] } };
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
+ });
+
+ it('should return false when hash is not a string', function () {
+ const bid = { ...validBid };
+ bid.params.hash = 123;
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
+ });
+ });
+
+ describe('buildRequests', function () {
+ const bidRequest = {
+ bidder: 'adrino',
+ params: {
+ hash: 'abcdef123456'
+ },
+ mediaTypes: {
+ native: {
+ title: {
+ required: true
+ },
+ image: {
+ required: true,
+ sizes: [[300, 150], [300, 210]]
+ }
+ }
+ },
+ adUnitCode: 'adunit-code',
+ bidId: '12345678901234',
+ bidderRequestId: '98765432109876',
+ auctionId: '01234567891234',
+ };
+
+ it('should build the request correctly with gdpr', function () {
+ const result = spec.buildRequests(
+ [ bidRequest ],
+ { gdprConsent: { gdprApplies: true, consentString: 'abc123' }, refererInfo: { referer: 'http://example.com/' } }
+ );
+ expect(result.length).to.equal(1);
+ expect(result[0].method).to.equal('POST');
+ expect(result[0].url).to.equal('https://prd-prebid-bidder.adrino.io/bidder/bid/');
+ expect(result[0].data.bidId).to.equal('12345678901234');
+ expect(result[0].data.placementHash).to.equal('abcdef123456');
+ expect(result[0].data.referer).to.equal('http://example.com/');
+ expect(result[0].data.userAgent).to.equal(navigator.userAgent);
+ expect(result[0].data).to.have.property('nativeParams');
+ expect(result[0].data).to.have.property('gdprConsent');
+ });
+
+ it('should build the request correctly without gdpr', function () {
+ const result = spec.buildRequests(
+ [ bidRequest ],
+ { refererInfo: { referer: 'http://example.com/' } }
+ );
+ expect(result.length).to.equal(1);
+ expect(result[0].method).to.equal('POST');
+ expect(result[0].url).to.equal('https://prd-prebid-bidder.adrino.io/bidder/bid/');
+ expect(result[0].data.bidId).to.equal('12345678901234');
+ expect(result[0].data.placementHash).to.equal('abcdef123456');
+ expect(result[0].data.referer).to.equal('http://example.com/');
+ expect(result[0].data.userAgent).to.equal(navigator.userAgent);
+ expect(result[0].data).to.have.property('nativeParams');
+ expect(result[0].data).not.to.have.property('gdprConsent');
+ });
+ });
+
+ describe('interpretResponse', function () {
+ it('should interpret the response correctly', function () {
+ const response = {
+ requestId: '31662c69728811',
+ mediaType: 'native',
+ cpm: 0.53,
+ currency: 'PLN',
+ creativeId: '859115',
+ netRevenue: true,
+ ttl: 600,
+ width: 1,
+ height: 1,
+ noAd: false,
+ testAd: false,
+ native: {
+ title: 'Ad Title',
+ body: 'Ad Body',
+ image: {
+ url: 'http://emisja.contentstream.pl/_/getImageII/?vid=17180728299&typ=cs_300_150&element=IMAGE&scale=1&prefix=adart&nc=1643878278955',
+ height: 150,
+ width: 300
+ },
+ clickUrl: 'http://emisja.contentstream.pl/_/ctr2/?u=https%3A%2F%2Fonline.efortuna.pl%2Fpage%3Fkey%3Dej0xMzUzMTM1NiZsPTE1Mjc1MzY1JnA9NTMyOTA%253D&e=znU3tABN8K4N391dmUxYfte5G9tBaDXELJVo1_-kvaTJH2XwWRw77fmfL2YjcEmrbqRQ3M0GcJ0vPWcLtZlsrf8dWrAEHNoZKAC6JMnZF_65IYhTPbQIJ-zn3ac9TU7gEZftFKksH1al7rMuieleVv9r6_DtrOk_oZcYAe4rMRQM-TiWvivJRPBchAAblE0cqyG7rCunJFpal43sxlYm4GvcBJaYHzErn5PXjEzNbd3xHjkdiap-xU9y6BbfkUZ1xIMS8QZLvwNrTXMFCSfSRN2tgVfEj7KyGdLCITHSaFtuIKT2iW2pxC7f2RtPHnzsEPXH0SgAfhA3OxZ5jkQjOZy0PsO7MiCv3sJai5ezUAOjFgayU91ZhI0Y9r2YpB1tTGIjnO23wot8PvRENlThHQ%3D%3D&ref=https%3A%2F%2Fbox.adrino.cloud%2Ftmielcarz%2Fadrino_prebid%2Ftest_page3.html%3Fpbjs_debug%3Dtrue',
+ privacyLink: 'https://adrino.pl/wp-content/uploads/2021/01/POLITYKA-PRYWATNOS%CC%81CI-Adrino-Mobile.pdf',
+ impressionTrackers: [
+ 'https://prd-impression-tracker-producer.adrino.io/impression/eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ7XCJpbXByZXNzaW9uSWRcIjpcIjMxNjYyYzY5NzI4ODExXCIsXCJkYXRlXCI6WzIwMjIsMiwzXSxcInBsYWNlbWVudEhhc2hcIjpcIjk0NTVjMDQxYzlkMTI1ZmIwNDE4MWVhMGVlZTJmMmFlXCIsXCJjYW1wYWlnbklkXCI6MTc5MjUsXCJhZHZlcnRpc2VtZW50SWRcIjo5MjA3OSxcInZpc3VhbGlzYXRpb25JZFwiOjg1OTExNSxcImNwbVwiOjUzLjB9IiwiZXhwIjoxNjQzOTE2MjUxLCJpYXQiOjE2NDM5MTU2NTF9.0Y_HvInGl6Xo5xP6rDLC8lzQRGvy-wKe0blk1o8ebWyVRFiUY1JGLUeE0k3sCsPNxgdHAv-o6EcbogpUuqlMJA'
+ ]
+ }
+ };
+
+ const serverResponse = {
+ body: response
+ };
+
+ const result = spec.interpretResponse(serverResponse, {});
+ expect(result.length).to.equal(1);
+ expect(result[0]).to.equal(response);
+ });
+
+ it('should return empty array of responses', function () {
+ const response = {
+ requestId: '31662c69728811',
+ noAd: true,
+ testAd: false
+ };
+
+ const serverResponse = {
+ body: response
+ };
+
+ const result = spec.interpretResponse(serverResponse, {});
+ expect(result.length).to.equal(0);
+ });
+ });
+
+ describe('onBidWon', function () {
+ beforeEach(function() {
+ sinon.stub(utils, 'triggerPixel');
+ });
+ afterEach(function() {
+ utils.triggerPixel.restore();
+ });
+
+ it('should trigger pixel', function () {
+ const response = {
+ requestId: '31662c69728811',
+ mediaType: 'native',
+ cpm: 0.53,
+ currency: 'PLN',
+ creativeId: '859115',
+ netRevenue: true,
+ ttl: 600,
+ width: 1,
+ height: 1,
+ noAd: false,
+ testAd: false,
+ native: {
+ title: 'Ad Title',
+ body: 'Ad Body',
+ image: {
+ url: 'http://emisja.contentstream.pl/_/getImageII/?vid=17180728299&typ=cs_300_150&element=IMAGE&scale=1&prefix=adart&nc=1643878278955',
+ height: 150,
+ width: 300
+ },
+ clickUrl: 'http://emisja.contentstream.pl/_/ctr2/?u=https%3A%2F%2Fonline.efortuna.pl%2Fpage%3Fkey%3Dej0xMzUzMTM1NiZsPTE1Mjc1MzY1JnA9NTMyOTA%253D&e=znU3tABN8K4N391dmUxYfte5G9tBaDXELJVo1_-kvaTJH2XwWRw77fmfL2YjcEmrbqRQ3M0GcJ0vPWcLtZlsrf8dWrAEHNoZKAC6JMnZF_65IYhTPbQIJ-zn3ac9TU7gEZftFKksH1al7rMuieleVv9r6_DtrOk_oZcYAe4rMRQM-TiWvivJRPBchAAblE0cqyG7rCunJFpal43sxlYm4GvcBJaYHzErn5PXjEzNbd3xHjkdiap-xU9y6BbfkUZ1xIMS8QZLvwNrTXMFCSfSRN2tgVfEj7KyGdLCITHSaFtuIKT2iW2pxC7f2RtPHnzsEPXH0SgAfhA3OxZ5jkQjOZy0PsO7MiCv3sJai5ezUAOjFgayU91ZhI0Y9r2YpB1tTGIjnO23wot8PvRENlThHQ%3D%3D&ref=https%3A%2F%2Fbox.adrino.cloud%2Ftmielcarz%2Fadrino_prebid%2Ftest_page3.html%3Fpbjs_debug%3Dtrue',
+ privacyLink: 'https://adrino.pl/wp-content/uploads/2021/01/POLITYKA-PRYWATNOS%CC%81CI-Adrino-Mobile.pdf',
+ impressionTrackers: [
+ 'https://prd-impression-tracker-producer.adrino.io/impression/eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ7XCJpbXByZXNzaW9uSWRcIjpcIjMxNjYyYzY5NzI4ODExXCIsXCJkYXRlXCI6WzIwMjIsMiwzXSxcInBsYWNlbWVudEhhc2hcIjpcIjk0NTVjMDQxYzlkMTI1ZmIwNDE4MWVhMGVlZTJmMmFlXCIsXCJjYW1wYWlnbklkXCI6MTc5MjUsXCJhZHZlcnRpc2VtZW50SWRcIjo5MjA3OSxcInZpc3VhbGlzYXRpb25JZFwiOjg1OTExNSxcImNwbVwiOjUzLjB9IiwiZXhwIjoxNjQzOTE2MjUxLCJpYXQiOjE2NDM5MTU2NTF9.0Y_HvInGl6Xo5xP6rDLC8lzQRGvy-wKe0blk1o8ebWyVRFiUY1JGLUeE0k3sCsPNxgdHAv-o6EcbogpUuqlMJA'
+ ]
+ }
+ };
+
+ spec.onBidWon(response);
+ expect(utils.triggerPixel.callCount).to.equal(1)
+ });
+ });
+});
diff --git a/test/spec/modules/consentManagementUsp_spec.js b/test/spec/modules/consentManagementUsp_spec.js
index c3ee30afc7d..6dc46192128 100644
--- a/test/spec/modules/consentManagementUsp_spec.js
+++ b/test/spec/modules/consentManagementUsp_spec.js
@@ -8,9 +8,9 @@ import {
} from 'modules/consentManagementUsp.js';
import * as utils from 'src/utils.js';
import { config } from 'src/config.js';
-import { uspDataHandler } from 'src/adapterManager.js';
+import {gdprDataHandler, uspDataHandler} from 'src/adapterManager.js';
+import 'src/prebid.js';
-let assert = require('chai').assert;
let expect = require('chai').expect;
function createIFrameMarker() {
@@ -97,6 +97,21 @@ describe('consentManagement', function () {
expect(consentAPI).to.be.equal('daa');
expect(consentTimeout).to.be.equal(7500);
});
+
+ it('should enable uspDataHandler', () => {
+ setConsentConfig({usp: {cmpApi: 'daa', timeout: 7500}});
+ expect(uspDataHandler.enabled).to.be.true;
+ });
+
+ it('should call setConsentData(null) on invalid CMP api', () => {
+ setConsentConfig({usp: {cmpApi: 'invalid'}});
+ let hookRan = false;
+ requestBidsHook(() => {
+ hookRan = true;
+ }, {});
+ expect(hookRan).to.be.true;
+ expect(uspDataHandler.ready).to.be.true;
+ });
});
describe('static consent string setConsentConfig value', () => {
@@ -226,6 +241,32 @@ describe('consentManagement', function () {
expect(consent).to.equal(testConsentData.uspString);
sinon.assert.called(uspStub);
});
+
+ it('should call uspDataHandler.setConsentData(null) on error', () => {
+ let hookRan = false;
+ uspStub = sinon.stub(window, '__uspapi').callsFake((...args) => {
+ args[2](null, false);
+ });
+ requestBidsHook(() => {
+ hookRan = true;
+ }, {});
+ expect(hookRan).to.be.true;
+ expect(uspDataHandler.ready).to.be.true;
+ expect(uspDataHandler.getConsentData()).to.equal(null);
+ });
+
+ it('should call uspDataHandler.setConsentData(null) on timeout', (done) => {
+ setConsentConfig({usp: {timeout: 10}});
+ let hookRan = false;
+ uspStub = sinon.stub(window, '__uspapi').callsFake(() => {});
+ requestBidsHook(() => { hookRan = true; }, {});
+ setTimeout(() => {
+ expect(hookRan).to.be.true;
+ expect(uspDataHandler.ready).to.be.true;
+ expect(uspDataHandler.getConsentData()).to.equal(null);
+ done();
+ }, 20)
+ });
});
describe('USPAPI workflow for iframed page', function () {
diff --git a/test/spec/modules/consentManagement_spec.js b/test/spec/modules/consentManagement_spec.js
index 3b027f0845c..d95af454818 100644
--- a/test/spec/modules/consentManagement_spec.js
+++ b/test/spec/modules/consentManagement_spec.js
@@ -132,6 +132,11 @@ describe('consentManagement', function () {
});
expect(gdprScope).to.be.equal(false);
});
+
+ it('should enable gdprDataHandler', () => {
+ setConsentConfig({gdpr: {}});
+ expect(gdprDataHandler.enabled).to.be.true;
+ });
});
describe('static consent string setConsentConfig value', () => {
@@ -326,6 +331,14 @@ describe('consentManagement', function () {
expect(consent).to.be.null;
});
+ it('should call gpdrDataHandler.setConsentData() when unknown CMP api is used', () => {
+ setConsentConfig({gdpr: {cmpApi: 'invalid'}});
+ let hookRan = false;
+ requestBidsHook(() => { hookRan = true; }, {});
+ expect(hookRan).to.be.true;
+ expect(gdprDataHandler.ready).to.be.true;
+ })
+
it('should throw proper errors when CMP is not found', function () {
setConsentConfig(goodConfigWithCancelAuction);
@@ -337,6 +350,7 @@ describe('consentManagement', function () {
sinon.assert.calledTwice(utils.logError);
expect(didHookReturn).to.be.false;
expect(consent).to.be.null;
+ expect(gdprDataHandler.ready).to.be.true;
});
});
@@ -748,6 +762,7 @@ describe('consentManagement', function () {
expect(didHookReturn).to.be.false;
expect(bidsBackHandlerReturn).to.be.true;
expect(consent).to.be.null;
+ expect(gdprDataHandler.ready).to.be.true;
});
it('allows the auction when CMP is unresponsive', (done) => {
@@ -766,6 +781,7 @@ describe('consentManagement', function () {
const consent = gdprDataHandler.getConsentData();
expect(consent.gdprApplies).to.be.true;
expect(consent.consentString).to.be.undefined;
+ expect(gdprDataHandler.ready).to.be.true;
done();
}, 20);
});
diff --git a/test/spec/unit/core/consentHandler_spec.js b/test/spec/unit/core/consentHandler_spec.js
new file mode 100644
index 00000000000..bee5a2d9522
--- /dev/null
+++ b/test/spec/unit/core/consentHandler_spec.js
@@ -0,0 +1,41 @@
+import {ConsentHandler} from '../../../../src/consentHandler.js';
+
+describe('Consent data handler', () => {
+ let handler;
+ beforeEach(() => {
+ handler = new ConsentHandler();
+ })
+
+ it('should be disabled, return null data on init', () => {
+ expect(handler.enabled).to.be.false;
+ expect(handler.getConsentData()).to.equal(null);
+ })
+
+ it('should resolve promise to null when disabled', () => {
+ return handler.promise.then((data) => {
+ expect(data).to.equal(null);
+ });
+ });
+
+ it('should return data after setConsentData', () => {
+ const data = {consent: 'string'};
+ handler.enable();
+ handler.setConsentData(data);
+ expect(handler.getConsentData()).to.equal(data);
+ });
+
+ it('should resolve .promise to data after setConsentData', (done) => {
+ let actual = null;
+ const data = {consent: 'string'};
+ handler.enable();
+ handler.promise.then((d) => actual = d);
+ setTimeout(() => {
+ expect(actual).to.equal(null);
+ handler.setConsentData(data);
+ setTimeout(() => {
+ expect(actual).to.equal(data);
+ done();
+ })
+ })
+ });
+})