diff --git a/modules/newspassid.md b/modules/newspassid.md
deleted file mode 100644
index 6fa709e5ba6..00000000000
--- a/modules/newspassid.md
+++ /dev/null
@@ -1,76 +0,0 @@
----
-Module Name: NewspassId Bidder Adapter
-Module Type: Bidder Adapter
-Maintainer: techsupport@newspassid.com
-layout: bidder
-title: Newspass ID
-description: LMC Newspass ID Prebid JS Bidder Adapter
-biddercode: newspassid
-gdpr_supported: false
-gvl_id: none
-usp_supported: true
-coppa_supported: false
-schain_supported: true
-dchain_supported: false
-userIds: criteo, id5Id, tdid, identityLink, liveIntentId, parrableId, pubCommonId, lotamePanoramaId, sharedId, fabrickId
-media_types: banner
-safeframes_ok: true
-deals_supported: true
-floors_supported: false
-fpd_supported: false
-pbjs: true
-pbs: false
-prebid_member: false
-multiformat_supported: will-bid-on-any
----
-
-### Description
-
-LMC Newspass ID Prebid JS Bidder Adapter that connects to the NewspassId demand source(s).
-
-The Newspass bid adapter supports Banner mediaTypes ONLY.
-This is intended for USA audiences only, and does not support GDPR
-
-
-### Bid Params
-
-{: .table .table-bordered .table-striped }
-
-| Name | Scope | Description | Example | Type |
-|-----------|----------|---------------------------|------------|----------|
-| `siteId` | required | The site ID. | `"NPID0000001"` | `string` |
-| `publisherId` | required | The publisher ID. | `"4204204201"` | `string` |
-| `placementId` | required | The placement ID. | `"0420420421"` | `string` |
-| `customData` | optional | publisher key-values used for targeting | `[{"settings":{},"targeting":{"key1": "value1", "key2": "value2"}}], ` | `array` |
-
-### Test Parameters
-
-
-A test ad unit that will consistently return test creatives:
-
-```
-
-//Banner adUnit
-
-adUnits = [{
- code: 'id-of-your-banner-div',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300,600]]
- }
- },
- bids: [{
- bidder: 'newspassid',
- params: {
- publisherId: 'NEWSPASS0001', /* an ID to identify the publisher account - required */
- siteId: '4204204201', /* An ID used to identify a site within a publisher account - required */
- placementId: '8000000015', /* an ID used to identify the piece of inventory - required - for appnexus test use 13144370. */
- customData: [{"settings": {}, "targeting": {"key": "value", "key2": ["value1", "value2"]}}],/* optional array with 'targeting' placeholder for passing publisher specific key-values for targeting. */
- }
- }]
- }];
-```
-
-### Note:
-
-Please contact us at techsupport@newspassid.com for any assistance testing your implementation before going live into production.
diff --git a/modules/newspassidBidAdapter.js b/modules/newspassidBidAdapter.js
index d33b4e64297..fac9841318d 100644
--- a/modules/newspassidBidAdapter.js
+++ b/modules/newspassidBidAdapter.js
@@ -1,674 +1,165 @@
-import {
- deepClone,
- logInfo,
- logError,
- deepAccess,
- logWarn,
- deepSetValue,
- isArray,
- contains,
- parseUrl,
- generateUUID
-} from '../src/utils.js';
+import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
+import { config } from '../src/config.js';
+import { deepSetValue } from '../src/utils.js';
+import { hasPurpose1Consent } from '../src/utils/gdpr.js';
+import { ortbConverter } from '../libraries/ortbConverter/converter.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
-import { BANNER, NATIVE } from '../src/mediaTypes.js';
-import {config} from '../src/config.js';
-import {getPriceBucketString} from '../src/cpmBucketManager.js';
-import {getRefererInfo} from '../src/refererDetection.js';
+
+/**
+ * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest
+ * @typedef {import('../src/adapters/bidderFactory.js').BidderSpec} BidderSpec
+ */
+
const BIDDER_CODE = 'newspassid';
-const ORIGIN = 'https://bidder.newspassid.com' // applies only to auction & cookie
-const AUCTIONURI = '/openrtb2/auction';
-const NEWSPASSCOOKIESYNC = '/static/load-cookie.html';
-const NEWSPASSVERSION = '1.1.4';
+const DEFAULT_CURRENCY = 'USD';
+const DEFAULT_NET_REVENUE = true;
+const DEFAULT_TTL = 300;
+const ENDPOINT_URL = 'https://npid.amspbs.com/v0/bid/request';
+const GVL_ID = 1317;
+const SYNC_URL = 'https://npid.amspbs.com/v0/user/sync';
+
+const converter = ortbConverter({
+ imp(buildImp, bidRequest, context) {
+ const imp = buildImp(bidRequest, context);
+ deepSetValue(imp, 'ext.newspassid', {
+ publisher: resolveNewpassidPublisherId(bidRequest),
+ placementId: bidRequest.params.placementId,
+ })
+ return imp;
+ },
+ context: {
+ ttl: DEFAULT_TTL,
+ netRevenue: DEFAULT_NET_REVENUE
+ }
+});
+
+/**
+ * Helper function to add params to url
+ * @param {string} url
+ * @param {object} params
+ * @returns {string}
+ */
+const addParamsToUrl = (url, params) => {
+ const urlObj = new URL(url);
+ Object.entries(params).forEach(([key, value]) => {
+ urlObj.searchParams.set(key, value);
+ });
+ return urlObj.toString();
+};
+
+/**
+ * Get the global publisherId for the newspassid bidder
+ * @returns {string|null}
+ */
+const getGlobalPublisherIdOrNull = () => {
+ const globalPublisherId = config.getConfig('newspassid.publisherId');
+ if (globalPublisherId) return globalPublisherId;
+ return null;
+};
+
+/**
+ * Resolve the publisherId for the newspassid bidder
+ * @param {BidRequest|undefined} bidRequest
+ * @returns {string|null}
+ */
+export const resolveNewpassidPublisherId = (bidRequest) => {
+ if (typeof bidRequest !== 'object') return getGlobalPublisherIdOrNull();
+
+ // get publisherId from bidRequest params
+ const { params } = bidRequest;
+ if (params?.publisherId) return params?.publisherId;
+
+ return getGlobalPublisherIdOrNull();
+};
+
+/**
+ * @type {BidderSpec}
+ */
export const spec = {
- version: NEWSPASSVERSION,
code: BIDDER_CODE,
- supportedMediaTypes: [BANNER],
- cookieSyncBag: {publisherId: null, siteId: null, userIdObject: {}}, // variables we want to make available to cookie sync
- propertyBag: {config: null, pageId: null, buildRequestsStart: 0, buildRequestsEnd: 0, endpointOverride: null}, /* allow us to store vars in instance scope - needs to be an object to be mutable */
- config_defaults: {
- 'logId': 'NEWSPASSID',
- 'bidder': 'newspassid',
- 'auctionUrl': ORIGIN + AUCTIONURI,
- 'cookieSyncUrl': ORIGIN + NEWSPASSCOOKIESYNC
- },
- loadConfiguredData(bid) {
- if (this.propertyBag.config) { return; }
- this.propertyBag.config = deepClone(this.config_defaults);
- let bidder = bid.bidder || 'newspassid';
- this.propertyBag.config.logId = bidder.toUpperCase();
- this.propertyBag.config.bidder = bidder;
- let bidderConfig = config.getConfig(bidder) || {};
- logInfo('got bidderConfig: ', deepClone(bidderConfig));
- let arrGetParams = this.getGetParametersAsObject();
- if (bidderConfig.endpointOverride) {
- if (bidderConfig.endpointOverride.origin) {
- this.propertyBag.endpointOverride = bidderConfig.endpointOverride.origin;
- this.propertyBag.config.auctionUrl = bidderConfig.endpointOverride.origin + AUCTIONURI;
- this.propertyBag.config.cookieSyncUrl = bidderConfig.endpointOverride.origin + NEWSPASSCOOKIESYNC;
- }
- if (bidderConfig.endpointOverride.cookieSyncUrl) {
- this.propertyBag.config.cookieSyncUrl = bidderConfig.endpointOverride.cookieSyncUrl;
- }
- if (bidderConfig.endpointOverride.auctionUrl) {
- this.propertyBag.endpointOverride = bidderConfig.endpointOverride.auctionUrl;
- this.propertyBag.config.auctionUrl = bidderConfig.endpointOverride.auctionUrl;
- }
- }
- try {
- if (arrGetParams.hasOwnProperty('auction')) {
- logInfo('GET: setting auction endpoint to: ' + arrGetParams.auction);
- this.propertyBag.config.auctionUrl = arrGetParams.auction;
- }
- if (arrGetParams.hasOwnProperty('cookiesync')) {
- logInfo('GET: setting cookiesync to: ' + arrGetParams.cookiesync);
- this.propertyBag.config.cookieSyncUrl = arrGetParams.cookiesync;
- }
- } catch (e) {}
- logInfo('set propertyBag.config to', this.propertyBag.config);
- },
- getAuctionUrl() {
- return this.propertyBag.config.auctionUrl;
- },
- getCookieSyncUrl() {
- return this.propertyBag.config.cookieSyncUrl;
- },
- isBidRequestValid(bid) {
- this.loadConfiguredData(bid);
- logInfo('isBidRequestValid : ', config.getConfig(), bid);
- let adUnitCode = bid.adUnitCode; // adunit[n].code
- let err1 = 'VALIDATION FAILED : missing {param} : siteId, placementId and publisherId are REQUIRED';
- if (!(bid.params.hasOwnProperty('placementId'))) {
- logError(err1.replace('{param}', 'placementId'), adUnitCode);
- return false;
- }
- if (!this.isValidPlacementId(bid.params.placementId)) {
- logError('VALIDATION FAILED : placementId must be exactly 10 numeric characters', adUnitCode);
- return false;
- }
- if (!(bid.params.hasOwnProperty('publisherId'))) {
- logError(err1.replace('{param}', 'publisherId'), adUnitCode);
- return false;
- }
- if (!(bid.params.publisherId).toString().match(/^[a-zA-Z0-9\-]{12}$/)) {
- logError('VALIDATION FAILED : publisherId must be exactly 12 alphanumeric characters including hyphens', adUnitCode);
- return false;
- }
- if (!(bid.params.hasOwnProperty('siteId'))) {
- logError(err1.replace('{param}', 'siteId'), adUnitCode);
- return false;
- }
- if (!(bid.params.siteId).toString().match(/^[0-9]{10}$/)) {
- logError('VALIDATION FAILED : siteId must be exactly 10 numeric characters', adUnitCode);
- return false;
- }
- if (bid.params.hasOwnProperty('customParams')) {
- logError('VALIDATION FAILED : customParams should be renamed to customData', adUnitCode);
- return false;
- }
- if (bid.params.hasOwnProperty('customData')) {
- if (!Array.isArray(bid.params.customData)) {
- logError('VALIDATION FAILED : customData is not an Array', adUnitCode);
- return false;
- }
- if (bid.params.customData.length < 1) {
- logError('VALIDATION FAILED : customData is an array but does not contain any elements', adUnitCode);
- return false;
- }
- if (!(bid.params.customData[0]).hasOwnProperty('targeting')) {
- logError('VALIDATION FAILED : customData[0] does not contain "targeting"', adUnitCode);
- return false;
- }
- if (typeof bid.params.customData[0]['targeting'] != 'object') {
- logError('VALIDATION FAILED : customData[0] targeting is not an object', adUnitCode);
- return false;
- }
- }
- return true;
- },
- isValidPlacementId(placementId) {
- return placementId.toString().match(/^[0-9]{10}$/);
- },
- buildRequests(validBidRequests, bidderRequest) {
- this.loadConfiguredData(validBidRequests[0]);
- this.propertyBag.buildRequestsStart = new Date().getTime();
- logInfo(`buildRequests time: ${this.propertyBag.buildRequestsStart} v ${NEWSPASSVERSION} validBidRequests`, deepClone(validBidRequests), 'bidderRequest', deepClone(bidderRequest));
- if (this.blockTheRequest()) {
- return [];
- }
- let htmlParams = {'publisherId': '', 'siteId': ''};
- if (validBidRequests.length > 0) {
- this.cookieSyncBag.userIdObject = Object.assign(this.cookieSyncBag.userIdObject, this.findAllUserIds(validBidRequests[0]));
- this.cookieSyncBag.siteId = deepAccess(validBidRequests[0], 'params.siteId');
- this.cookieSyncBag.publisherId = deepAccess(validBidRequests[0], 'params.publisherId');
- htmlParams = validBidRequests[0].params;
- }
- logInfo('cookie sync bag', this.cookieSyncBag);
- let singleRequest = config.getConfig('newspassid.singleRequest');
- singleRequest = singleRequest !== false; // undefined & true will be true
- logInfo(`config newspassid.singleRequest : `, singleRequest);
- let npRequest = {}; // we only want to set specific properties on this, not validBidRequests[0].params
- logInfo('going to get ortb2 from bidder request...');
- let fpd = deepAccess(bidderRequest, 'ortb2', null);
- logInfo('got fpd: ', fpd);
- if (fpd && deepAccess(fpd, 'user')) {
- logInfo('added FPD user object');
- npRequest.user = fpd.user;
- }
- const getParams = this.getGetParametersAsObject();
- const isTestMode = getParams['nptestmode'] || null; // this can be any string, it's used for testing ads
- npRequest.device = {'w': window.innerWidth, 'h': window.innerHeight};
- let placementIdOverrideFromGetParam = this.getPlacementIdOverrideFromGetParam(); // null or string
- let schain = null;
- let tosendtags = validBidRequests.map(npBidRequest => {
- var obj = {};
- let placementId = placementIdOverrideFromGetParam || this.getPlacementId(npBidRequest); // prefer to use a valid override param, else the bidRequest placement Id
- obj.id = npBidRequest.bidId; // this causes an error if we change it to something else, even if you update the bidRequest object: "WARNING: Bidder newspass made bid for unknown request ID: mb7953.859498327448. Ignoring."
- obj.tagid = placementId;
- let parsed = parseUrl(this.getRefererInfo().page);
- obj.secure = parsed.protocol === 'https' ? 1 : 0;
- let arrBannerSizes = [];
- if (!npBidRequest.hasOwnProperty('mediaTypes')) {
- if (npBidRequest.hasOwnProperty('sizes')) {
- logInfo('no mediaTypes detected - will use the sizes array in the config root');
- arrBannerSizes = npBidRequest.sizes;
- } else {
- logInfo('Cannot set sizes for banner type');
- }
- } else {
- if (npBidRequest.mediaTypes.hasOwnProperty(BANNER)) {
- arrBannerSizes = npBidRequest.mediaTypes[BANNER].sizes; /* Note - if there is a sizes element in the config root it will be pushed into here */
- logInfo('setting banner size from the mediaTypes.banner element for bidId ' + obj.id + ': ', arrBannerSizes);
- }
- if (npBidRequest.mediaTypes.hasOwnProperty(NATIVE)) {
- obj.native = npBidRequest.mediaTypes[NATIVE];
- logInfo('setting native object from the mediaTypes.native element: ' + obj.id + ':', obj.native);
- }
- }
- if (arrBannerSizes.length > 0) {
- obj.banner = {
- topframe: 1,
- w: arrBannerSizes[0][0] || 0,
- h: arrBannerSizes[0][1] || 0,
- format: arrBannerSizes.map(s => {
- return {w: s[0], h: s[1]};
- })
- };
- }
- obj.placementId = placementId;
- deepSetValue(obj, 'ext.prebid', {'storedrequest': {'id': placementId}});
- obj.ext['newspassid'] = {};
- obj.ext['newspassid'].adUnitCode = npBidRequest.adUnitCode; // eg. 'mpu'
- if (npBidRequest.params.hasOwnProperty('customData')) {
- obj.ext['newspassid'].customData = npBidRequest.params.customData;
- }
- logInfo(`obj.ext.newspassid is `, obj.ext['newspassid']);
- if (isTestMode != null) {
- logInfo('setting isTestMode to ', isTestMode);
- if (obj.ext['newspassid'].hasOwnProperty('customData')) {
- for (let i = 0; i < obj.ext['newspassid'].customData.length; i++) {
- obj.ext['newspassid'].customData[i]['targeting']['nptestmode'] = isTestMode;
- }
- } else {
- obj.ext['newspassid'].customData = [{'settings': {}, 'targeting': {}}];
- obj.ext['newspassid'].customData[0].targeting['nptestmode'] = isTestMode;
+ gvlid: GVL_ID,
+ supportedMediaTypes: [BANNER, NATIVE, VIDEO],
+
+ isBidRequestValid: function(bidRequest) {
+ const publisherId = resolveNewpassidPublisherId(bidRequest);
+ return !!(bidRequest.params && publisherId && bidRequest.params.placementId);
+ },
+
+ buildRequests: function(bidRequests, bidderRequest) {
+ // convert to ortb using the converter utility
+ const data = converter.toORTB({ bidRequests, bidderRequest });
+
+ return [
+ {
+ method: 'POST',
+ url: ENDPOINT_URL,
+ data: data,
+ options: {
+ withCredentials: true
}
}
- if (fpd && deepAccess(fpd, 'site')) {
- logInfo('adding fpd.site');
- if (deepAccess(obj, 'ext.newspassid.customData.0.targeting', false)) {
- obj.ext.newspassid.customData[0].targeting = Object.assign(obj.ext.newspassid.customData[0].targeting, fpd.site);
- } else {
- deepSetValue(obj, 'ext.newspassid.customData.0.targeting', fpd.site);
+ ];
+ },
+
+ interpretResponse: function(serverResponse, bidRequest) {
+ const response = serverResponse.body;
+ const bidResponses = [];
+
+ if (!response || !response.seatbid || !response.seatbid[0].bid) {
+ return bidResponses;
+ }
+
+ response.seatbid[0].bid.forEach(bid => {
+ bidResponses.push({
+ requestId: bid.impid,
+ cpm: bid.price,
+ width: bid.w,
+ height: bid.h,
+ creativeId: bid.crid || bid.id,
+ currency: response.cur || DEFAULT_CURRENCY,
+ netRevenue: true,
+ ttl: DEFAULT_TTL,
+ ad: bid.adm,
+ meta: {
+ advertiserDomains: bid.adomain || [],
}
- }
- if (!schain && deepAccess(npBidRequest, 'schain')) {
- schain = npBidRequest.schain;
- }
- let gpid = deepAccess(npBidRequest, 'ortb2Imp.ext.gpid');
- if (gpid) {
- deepSetValue(obj, 'ext.gpid', gpid);
- }
- return obj;
+ });
});
- let extObj = {};
- extObj['newspassid'] = {};
- extObj['newspassid']['np_pb_v'] = NEWSPASSVERSION;
- extObj['newspassid']['np_rw'] = placementIdOverrideFromGetParam ? 1 : 0;
- if (validBidRequests.length > 0) {
- let userIds = this.cookieSyncBag.userIdObject; // 2021-01-06 - slight optimisation - we've already found this info
- if (userIds.hasOwnProperty('pubcid')) {
- extObj['newspassid'].pubcid = userIds.pubcid;
- }
- }
- extObj['newspassid'].pv = this.getPageId(); // attach the page ID that will be common to all auction calls for this page if refresh() is called
- let whitelistAdserverKeys = config.getConfig('newspassid.np_whitelist_adserver_keys');
- let useWhitelistAdserverKeys = isArray(whitelistAdserverKeys) && whitelistAdserverKeys.length > 0;
- extObj['newspassid']['np_kvp_rw'] = useWhitelistAdserverKeys ? 1 : 0;
- if (getParams.hasOwnProperty('npf')) { extObj['newspassid']['npf'] = getParams.npf === 'true' || getParams.npf === '1' ? 1 : 0; }
- if (getParams.hasOwnProperty('nppf')) { extObj['newspassid']['nppf'] = getParams.nppf === 'true' || getParams.nppf === '1' ? 1 : 0; }
- if (getParams.hasOwnProperty('nprp') && getParams.nprp.match(/^[0-3]$/)) { extObj['newspassid']['nprp'] = parseInt(getParams.nprp); }
- if (getParams.hasOwnProperty('npip') && getParams.npip.match(/^\d+$/)) { extObj['newspassid']['npip'] = parseInt(getParams.npip); }
- if (this.propertyBag.endpointOverride != null) { extObj['newspassid']['origin'] = this.propertyBag.endpointOverride; }
- let userExtEids = deepAccess(validBidRequests, '0.userIdAsEids', []); // generate the UserIDs in the correct format for UserId module
- npRequest.site = {
- 'publisher': {'id': htmlParams.publisherId},
- 'page': this.getRefererInfo().page,
- 'id': htmlParams.siteId
+
+ return bidResponses;
+ },
+
+ getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) {
+ if (!syncOptions.iframeEnabled) return []; // disable if iframe sync is disabled
+ if (!hasPurpose1Consent(gdprConsent)) return []; // disable if no purpose1 consent
+ if (config.getConfig('coppa') === true) return []; // disable syncs for coppa
+
+ const params = {
+ gdpr: gdprConsent?.gdprApplies ? 1 : 0,
+ gdpr_consent: gdprConsent?.gdprApplies
+ ? encodeURIComponent(gdprConsent?.consentString || '')
+ : '',
+ gpp: encodeURIComponent(gppConsent?.gppString || ''),
+ gpp_sid: encodeURIComponent(gppConsent?.applicableSections || ''),
+ us_privacy: encodeURIComponent(uspConsent || ''),
};
- npRequest.test = config.getConfig('debug') ? 1 : 0;
- if (bidderRequest && bidderRequest.uspConsent) {
- logInfo('ADDING USP consent info');
- deepSetValue(npRequest, 'regs.ext.us_privacy', bidderRequest.uspConsent);
- } else {
- logInfo('WILL NOT ADD USP consent info; no bidderRequest.uspConsent.');
- }
- if (schain) { // we set this while iterating over the bids
- logInfo('schain found');
- deepSetValue(npRequest, 'source.ext.schain', schain);
- }
- if (config.getConfig('coppa') === true) {
- deepSetValue(npRequest, 'regs.coppa', 1);
- }
- if (singleRequest) {
- logInfo('buildRequests starting to generate response for a single request');
- npRequest.id = generateUUID(); // Unique ID of the bid request, provided by the exchange. (REQUIRED)
- npRequest.imp = tosendtags;
- npRequest.ext = extObj;
- deepSetValue(npRequest, 'user.ext.eids', userExtEids);
- var ret = {
- method: 'POST',
- url: this.getAuctionUrl(),
- data: JSON.stringify(npRequest),
- bidderRequest: bidderRequest
- };
- logInfo('buildRequests request data for single = ', deepClone(npRequest));
- this.propertyBag.buildRequestsEnd = new Date().getTime();
- logInfo(`buildRequests going to return for single at time ${this.propertyBag.buildRequestsEnd} (took ${this.propertyBag.buildRequestsEnd - this.propertyBag.buildRequestsStart}ms): `, ret);
- return ret;
- }
- let arrRet = tosendtags.map(imp => {
- logInfo('buildRequests starting to generate non-single response, working on imp : ', imp);
- let npRequestSingle = Object.assign({}, npRequest);
- npRequestSingle.id = generateUUID();
- npRequestSingle.imp = [imp];
- npRequestSingle.ext = extObj;
- deepSetValue(npRequestSingle, 'user.ext.eids', userExtEids);
- logInfo('buildRequests RequestSingle (for non-single) = ', npRequestSingle);
- return {
- method: 'POST',
- url: this.getAuctionUrl(),
- data: JSON.stringify(npRequestSingle),
- bidderRequest: bidderRequest
- };
+
+ const globalPublisherId = resolveNewpassidPublisherId({});
+ if (globalPublisherId) {
+ // "publisher" is a convention on the server side
+ params.publisher = globalPublisherId;
+ }
+
+ let syncs = [];
+
+ // iframe sync
+ syncs.push({
+ type: 'iframe',
+ url: addParamsToUrl(SYNC_URL, params),
});
- this.propertyBag.buildRequestsEnd = new Date().getTime();
- logInfo(`buildRequests going to return for non-single at time ${this.propertyBag.buildRequestsEnd} (took ${this.propertyBag.buildRequestsEnd - this.propertyBag.buildRequestsStart}ms): `, arrRet);
- return arrRet;
- },
- interpretResponse(serverResponse, request) {
- if (request && request.bidderRequest && request.bidderRequest.bids) { this.loadConfiguredData(request.bidderRequest.bids[0]); }
- let startTime = new Date().getTime();
- logInfo(`interpretResponse time: ${startTime}. buildRequests done -> interpretResponse start was ${startTime - this.propertyBag.buildRequestsEnd}ms`);
- logInfo(`serverResponse, request`, deepClone(serverResponse), deepClone(request));
- serverResponse = serverResponse.body || {};
- let aucId = serverResponse.id; // this will be correct for single requests and non-single
- if (!serverResponse.hasOwnProperty('seatbid')) {
- return [];
- }
- if (typeof serverResponse.seatbid !== 'object') {
- return [];
- }
- let arrAllBids = [];
- let enhancedAdserverTargeting = config.getConfig('newspassid.enhancedAdserverTargeting');
- logInfo('enhancedAdserverTargeting', enhancedAdserverTargeting);
- if (typeof enhancedAdserverTargeting == 'undefined') {
- enhancedAdserverTargeting = true;
- }
- logInfo('enhancedAdserverTargeting', enhancedAdserverTargeting);
- serverResponse.seatbid = injectAdIdsIntoAllBidResponses(serverResponse.seatbid); // we now make sure that each bid in the bidresponse has a unique (within page) adId attribute.
- serverResponse.seatbid = this.removeSingleBidderMultipleBids(serverResponse.seatbid);
- let whitelistAdserverKeys = config.getConfig('newspassid.np_whitelist_adserver_keys');
- let useWhitelistAdserverKeys = isArray(whitelistAdserverKeys) && whitelistAdserverKeys.length > 0;
- for (let i = 0; i < serverResponse.seatbid.length; i++) {
- let sb = serverResponse.seatbid[i];
- for (let j = 0; j < sb.bid.length; j++) {
- let thisRequestBid = this.getBidRequestForBidId(sb.bid[j].impid, request.bidderRequest.bids);
- logInfo(`seatbid:${i}, bid:${j} Going to set default w h for seatbid/bidRequest`, sb.bid[j], thisRequestBid);
- const {defaultWidth, defaultHeight} = defaultSize(thisRequestBid);
- let thisBid = this.addStandardProperties(sb.bid[j], defaultWidth, defaultHeight);
- thisBid.meta = {advertiserDomains: thisBid.adomain || []};
- let bidType = deepAccess(thisBid, 'ext.prebid.type');
- logInfo(`this bid type is : ${bidType}`, j);
- let adserverTargeting = {};
- if (enhancedAdserverTargeting) {
- let allBidsForThisBidid = this.getAllBidsForBidId(thisBid.bidId, serverResponse.seatbid);
- logInfo('Going to iterate allBidsForThisBidId', allBidsForThisBidid);
- Object.keys(allBidsForThisBidid).forEach((bidderName, index, ar2) => {
- logInfo(`adding adserverTargeting for ${bidderName} for bidId ${thisBid.bidId}`);
- adserverTargeting['np_' + bidderName] = bidderName;
- adserverTargeting['np_' + bidderName + '_crid'] = String(allBidsForThisBidid[bidderName].crid);
- adserverTargeting['np_' + bidderName + '_adv'] = String(allBidsForThisBidid[bidderName].adomain);
- adserverTargeting['np_' + bidderName + '_adId'] = String(allBidsForThisBidid[bidderName].adId);
- adserverTargeting['np_' + bidderName + '_pb_r'] = getRoundedBid(allBidsForThisBidid[bidderName].price, allBidsForThisBidid[bidderName].ext.prebid.type);
- if (allBidsForThisBidid[bidderName].hasOwnProperty('dealid')) {
- adserverTargeting['np_' + bidderName + '_dealid'] = String(allBidsForThisBidid[bidderName].dealid);
- }
- });
- } else {
- logInfo(`newspassid.enhancedAdserverTargeting is set to false, no per-bid keys will be sent to adserver.`);
- }
- let {seat: winningSeat, bid: winningBid} = this.getWinnerForRequestBid(thisBid.bidId, serverResponse.seatbid);
- adserverTargeting['np_auc_id'] = String(aucId);
- adserverTargeting['np_winner'] = String(winningSeat);
- adserverTargeting['np_bid'] = 'true';
- if (enhancedAdserverTargeting) {
- adserverTargeting['np_imp_id'] = String(winningBid.impid);
- adserverTargeting['np_pb_r'] = getRoundedBid(winningBid.price, bidType);
- adserverTargeting['np_adId'] = String(winningBid.adId);
- adserverTargeting['np_size'] = `${winningBid.width}x${winningBid.height}`;
- }
- if (useWhitelistAdserverKeys) { // delete any un-whitelisted keys
- logInfo('Going to filter out adserver targeting keys not in the whitelist: ', whitelistAdserverKeys);
- Object.keys(adserverTargeting).forEach(function(key) { if (whitelistAdserverKeys.indexOf(key) === -1) { delete adserverTargeting[key]; } });
- }
- thisBid.adserverTargeting = adserverTargeting;
- arrAllBids.push(thisBid);
- }
- }
- let endTime = new Date().getTime();
- logInfo(`interpretResponse going to return at time ${endTime} (took ${endTime - startTime}ms) Time from buildRequests Start -> interpretRequests End = ${endTime - this.propertyBag.buildRequestsStart}ms`, arrAllBids);
- return arrAllBids;
- },
- removeSingleBidderMultipleBids(seatbid) {
- var ret = [];
- for (let i = 0; i < seatbid.length; i++) {
- let sb = seatbid[i];
- var retSeatbid = {'seat': sb.seat, 'bid': []};
- var bidIds = [];
- for (let j = 0; j < sb.bid.length; j++) {
- var candidate = sb.bid[j];
- if (contains(bidIds, candidate.impid)) {
- continue; // we've already fully assessed this impid, found the highest bid from this seat for it
- }
- bidIds.push(candidate.impid);
- for (let k = j + 1; k < sb.bid.length; k++) {
- if (sb.bid[k].impid === candidate.impid && sb.bid[k].price > candidate.price) {
- candidate = sb.bid[k];
- }
- }
- retSeatbid.bid.push(candidate);
- }
- ret.push(retSeatbid);
- }
- return ret;
- },
- getUserSyncs(optionsType, serverResponse, gdprConsent, usPrivacy) {
- logInfo('getUserSyncs optionsType', optionsType, 'serverResponse', serverResponse, 'usPrivacy', usPrivacy, 'cookieSyncBag', this.cookieSyncBag);
- if (!serverResponse || serverResponse.length === 0) {
- return [];
- }
- if (optionsType.iframeEnabled) {
- var arrQueryString = [];
- if (config.getConfig('debug')) {
- arrQueryString.push('pbjs_debug=true');
- }
- arrQueryString.push('usp_consent=' + (usPrivacy || ''));
- for (let keyname in this.cookieSyncBag.userIdObject) {
- arrQueryString.push(keyname + '=' + this.cookieSyncBag.userIdObject[keyname]);
- }
- arrQueryString.push('publisherId=' + this.cookieSyncBag.publisherId);
- arrQueryString.push('siteId=' + this.cookieSyncBag.siteId);
- arrQueryString.push('cb=' + Date.now());
- arrQueryString.push('bidder=' + this.propertyBag.config.bidder);
- var strQueryString = arrQueryString.join('&');
- if (strQueryString.length > 0) {
- strQueryString = '?' + strQueryString;
- }
- logInfo('getUserSyncs going to return cookie sync url : ' + this.getCookieSyncUrl() + strQueryString);
- return [{
- type: 'iframe',
- url: this.getCookieSyncUrl() + strQueryString
- }];
- }
- },
- getBidRequestForBidId(bidId, arrBids) {
- for (let i = 0; i < arrBids.length; i++) {
- if (arrBids[i].bidId === bidId) { // bidId in the request comes back as impid in the seatbid bids
- return arrBids[i];
- }
- }
- return null;
- },
- findAllUserIds(bidRequest) {
- var ret = {};
- let searchKeysSingle = ['pubcid', 'tdid', 'idl_env', 'criteoId', 'lotamePanoramaId', 'fabrickId'];
- if (bidRequest.hasOwnProperty('userId')) {
- for (let arrayId in searchKeysSingle) {
- let key = searchKeysSingle[arrayId];
- if (bidRequest.userId.hasOwnProperty(key)) {
- if (typeof (bidRequest.userId[key]) == 'string') {
- ret[key] = bidRequest.userId[key];
- } else if (typeof (bidRequest.userId[key]) == 'object') {
- logError(`WARNING: findAllUserIds had to use first key in user object to get value for bid.userId key: ${key}. Prebid adapter should be updated.`);
- ret[key] = bidRequest.userId[key][Object.keys(bidRequest.userId[key])[0]]; // cannot use Object.values
- } else {
- logError(`failed to get string key value for userId : ${key}`);
- }
- }
- }
- let lipbid = deepAccess(bidRequest.userId, 'lipb.lipbid');
- if (lipbid) {
- ret['lipb'] = {'lipbid': lipbid};
- }
- let id5id = deepAccess(bidRequest.userId, 'id5id.uid');
- if (id5id) {
- ret['id5id'] = id5id;
- }
- let sharedid = deepAccess(bidRequest.userId, 'sharedid.id');
- if (sharedid) {
- ret['sharedid'] = sharedid;
- }
- }
- if (!ret.hasOwnProperty('pubcid')) {
- let pubcid = deepAccess(bidRequest, 'crumbs.pubcid');
- if (pubcid) {
- ret['pubcid'] = pubcid; // if built with old pubCommonId module
- }
- }
- return ret;
- },
- getPlacementId(bidRequest) {
- return (bidRequest.params.placementId).toString();
- },
- getPlacementIdOverrideFromGetParam() {
- let arr = this.getGetParametersAsObject();
- if (arr.hasOwnProperty('npstoredrequest')) {
- if (this.isValidPlacementId(arr['npstoredrequest'])) {
- logInfo(`using GET npstoredrequest ` + arr['npstoredrequest'] + ' to replace placementId');
- return arr['npstoredrequest'];
- } else {
- logError(`GET npstoredrequest FAILED VALIDATION - will not use it`);
- }
- }
- return null;
- },
- getGetParametersAsObject() {
- let parsed = parseUrl(this.getRefererInfo().location); // was getRefererInfo().page but this is not backwards compatible
- logInfo('getGetParametersAsObject found:', parsed.search);
- return parsed.search;
- },
- getRefererInfo() {
- if (getRefererInfo().hasOwnProperty('location')) {
- logInfo('FOUND location on getRefererInfo OK (prebid >= 7); will use getRefererInfo for location & page');
- return getRefererInfo();
- } else {
- logInfo('DID NOT FIND location on getRefererInfo (prebid < 7); will use legacy code that ALWAYS worked reliably to get location & page ;-)');
- try {
- return {
- page: top.location.href,
- location: top.location.href
- };
- } catch (e) {
- return {
- page: window.location.href,
- location: window.location.href
- };
- }
- }
- },
- blockTheRequest() {
- let npRequest = config.getConfig('newspassid.np_request');
- if (typeof npRequest == 'boolean' && !npRequest) {
- logWarn(`Will not allow auction : np_request is set to false`);
- return true;
- }
- return false;
- },
- getPageId: function() {
- if (this.propertyBag.pageId == null) {
- let randPart = '';
- let allowable = '0123456789abcdefghijklmnopqrstuvwxyz';
- for (let i = 20; i > 0; i--) {
- randPart += allowable[Math.floor(Math.random() * 36)];
- }
- this.propertyBag.pageId = new Date().getTime() + '_' + randPart;
- }
- return this.propertyBag.pageId;
- },
- addStandardProperties(seatBid, defaultWidth, defaultHeight) {
- seatBid.cpm = seatBid.price;
- seatBid.bidId = seatBid.impid;
- seatBid.requestId = seatBid.impid;
- seatBid.width = seatBid.w || defaultWidth;
- seatBid.height = seatBid.h || defaultHeight;
- seatBid.ad = seatBid.adm;
- seatBid.netRevenue = true;
- seatBid.creativeId = seatBid.crid;
- seatBid.currency = 'USD';
- seatBid.ttl = 300;
- return seatBid;
- },
- getWinnerForRequestBid(requestBidId, serverResponseSeatBid) {
- let thisBidWinner = null;
- let winningSeat = null;
- for (let j = 0; j < serverResponseSeatBid.length; j++) {
- let theseBids = serverResponseSeatBid[j].bid;
- let thisSeat = serverResponseSeatBid[j].seat;
- for (let k = 0; k < theseBids.length; k++) {
- if (theseBids[k].impid === requestBidId) {
- if ((thisBidWinner == null) || (thisBidWinner.price < theseBids[k].price)) {
- thisBidWinner = theseBids[k];
- winningSeat = thisSeat;
- break;
- }
- }
- }
- }
- return {'seat': winningSeat, 'bid': thisBidWinner};
- },
- getAllBidsForBidId(matchBidId, serverResponseSeatBid) {
- let objBids = {};
- for (let j = 0; j < serverResponseSeatBid.length; j++) {
- let theseBids = serverResponseSeatBid[j].bid;
- let thisSeat = serverResponseSeatBid[j].seat;
- for (let k = 0; k < theseBids.length; k++) {
- if (theseBids[k].impid === matchBidId) {
- if (objBids.hasOwnProperty(thisSeat)) { // > 1 bid for an adunit from a bidder - only use the one with the highest bid
- if (objBids[thisSeat]['price'] < theseBids[k].price) {
- objBids[thisSeat] = theseBids[k];
- }
- } else {
- objBids[thisSeat] = theseBids[k];
- }
- }
- }
- }
- return objBids;
+
+ return syncs;
}
};
-export function injectAdIdsIntoAllBidResponses(seatbid) {
- logInfo('injectAdIdsIntoAllBidResponses', seatbid);
- for (let i = 0; i < seatbid.length; i++) {
- let sb = seatbid[i];
- for (let j = 0; j < sb.bid.length; j++) {
- sb.bid[j]['adId'] = `${sb.bid[j]['impid']}-${i}-np-${j}`;
- }
- }
- return seatbid;
-}
-export function checkDeepArray(Arr) {
- if (Array.isArray(Arr)) {
- if (Array.isArray(Arr[0])) {
- return Arr[0];
- } else {
- return Arr;
- }
- } else {
- return Arr;
- }
-}
-export function defaultSize(thebidObj) {
- if (!thebidObj) {
- logInfo('defaultSize received empty bid obj! going to return fixed default size');
- return {
- 'defaultHeight': 250,
- 'defaultWidth': 300
- };
- }
- const {sizes} = thebidObj;
- const returnObject = {};
- returnObject.defaultWidth = checkDeepArray(sizes)[0];
- returnObject.defaultHeight = checkDeepArray(sizes)[1];
- return returnObject;
-}
-export function getRoundedBid(price, mediaType) {
- const mediaTypeGranularity = config.getConfig(`mediaTypePriceGranularity.${mediaType}`); // might be string or object or nothing; if set then this takes precedence over 'priceGranularity'
- let objBuckets = config.getConfig('customPriceBucket'); // this is always an object - {} if strBuckets is not 'custom'
- let strBuckets = config.getConfig('priceGranularity'); // priceGranularity value, always a string ** if priceGranularity is set to an object then it's always 'custom' **
- let theConfigObject = getGranularityObject(mediaType, mediaTypeGranularity, strBuckets, objBuckets);
- let theConfigKey = getGranularityKeyName(mediaType, mediaTypeGranularity, strBuckets);
- logInfo('getRoundedBid. price:', price, 'mediaType:', mediaType, 'configkey:', theConfigKey, 'configObject:', theConfigObject, 'mediaTypeGranularity:', mediaTypeGranularity, 'strBuckets:', strBuckets);
- let priceStringsObj = getPriceBucketString(
- price,
- theConfigObject,
- config.getConfig('currency.granularityMultiplier')
- );
- logInfo('priceStringsObj', priceStringsObj);
- let granularityNamePriceStringsKeyMapping = {
- 'medium': 'med',
- 'custom': 'custom',
- 'high': 'high',
- 'low': 'low',
- 'dense': 'dense'
- };
- if (granularityNamePriceStringsKeyMapping.hasOwnProperty(theConfigKey)) {
- let priceStringsKey = granularityNamePriceStringsKeyMapping[theConfigKey];
- logInfo('getRoundedBid: looking for priceStringsKey:', priceStringsKey);
- return priceStringsObj[priceStringsKey];
- }
- return priceStringsObj['auto'];
-}
-export function getGranularityKeyName(mediaType, mediaTypeGranularity, strBuckets) {
- if (typeof mediaTypeGranularity === 'string') {
- return mediaTypeGranularity;
- }
- if (typeof mediaTypeGranularity === 'object') {
- return 'custom';
- }
- if (typeof strBuckets === 'string') {
- return strBuckets;
- }
- return 'auto'; // fall back to a default key - should literally never be needed.
-}
-export function getGranularityObject(mediaType, mediaTypeGranularity, strBuckets, objBuckets) {
- if (typeof mediaTypeGranularity === 'object') {
- return mediaTypeGranularity;
- }
- if (strBuckets === 'custom') {
- return objBuckets;
- }
- return '';
-}
+
registerBidder(spec);
-logInfo(`*BidAdapter ${NEWSPASSVERSION} was loaded`);
diff --git a/modules/newspassidBidAdapter.md b/modules/newspassidBidAdapter.md
new file mode 100644
index 00000000000..aff1d902c3e
--- /dev/null
+++ b/modules/newspassidBidAdapter.md
@@ -0,0 +1,47 @@
+Overview
+========
+
+```
+Module Name: NewsPassID Bid Adapter
+Module Type: Bidder Adapter
+Maintainer: techsupport@newspassid.com
+```
+
+Description
+===========
+
+Bid adapter to connect to Local Media Consortium's NewsPassID (NPID) demand source(s). This adapter runs bid requests through ad server technology built and maintained by Aditude.
+
+# Bid Parameters
+
+| Key | Required | Example | Description |
+| --- | -------- | ------- | ----------- |
+| `publisherId` | yes | `"123456"` | For associating the publisher account for the NewsPassID initiative |
+| `placementId` | yes | `"leftrail-mobile-1"` | For associating the ad placement inventory with demand. This ID must be predefined by NewsPassID provider |
+
+
+# Test Parameters
+
+```javascript
+pbjs.setConfig({
+ newspassid: {
+ publisherId: '123456',
+ }
+});
+
+var adUnits = [
+ {
+ code: 'newspass-test-div',
+ sizes: [[300, 250]],
+ bids: [
+ {
+ bidder: 'newspassid',
+ params: {
+ publisherId: '123456', // optional if you set in bidder config
+ placementId: 'test-group1'
+ }
+ }
+ ]
+ }
+]
+```
diff --git a/test/spec/modules/newspassidBidAdapter_spec.js b/test/spec/modules/newspassidBidAdapter_spec.js
index 6468d4f530a..dec630f3f6a 100644
--- a/test/spec/modules/newspassidBidAdapter_spec.js
+++ b/test/spec/modules/newspassidBidAdapter_spec.js
@@ -1,1799 +1,346 @@
-import { expect } from 'chai';
-import { spec, defaultSize } from 'modules/newspassidBidAdapter.js';
+import { spec } from 'modules/newspassidBidAdapter.js';
import { config } from 'src/config.js';
-import {getGranularityKeyName, getGranularityObject} from '../../../modules/newspassidBidAdapter.js';
-import * as utils from '../../../src/utils.js';
-const NEWSPASSURI = 'https://bidder.newspassid.com/openrtb2/auction';
-const BIDDER_CODE = 'newspassid';
-var validBidRequests = [
- {
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
- bidId: '2899ec066a91ff8',
- bidRequestsCount: 1,
+import { deepClone } from 'src/utils.js';
+import { resolveNewpassidPublisherId } from '../../../modules/newspassidBidAdapter';
+
+describe('newspassidBidAdapter', function () {
+ const TEST_PUBLISHER_ID = '123456';
+ const TEST_PLACEMENT_ID = 'test-group1';
+
+ const validBidRequest = {
bidder: 'newspassid',
- bidderRequestId: '1c1586b27a1b5c8',
- crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'},
- params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] },
- sizes: [[300, 250], [300, 600]],
- transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
- }
-];
-var validBidRequestsNoCustomData = [
- {
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
- bidId: '2899ec066a91ff8',
- bidRequestsCount: 1,
- bidder: 'newspassid',
- bidderRequestId: '1c1586b27a1b5c8',
- crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'},
- params: { publisherId: '9876abcd12-3', placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] },
- sizes: [[300, 250], [300, 600]],
- transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
- }
-];
-var validBidRequestsMulti = [
- {
- testId: 1,
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
- bidId: '2899ec066a91ff8',
- bidRequestsCount: 1,
- bidder: 'newspassid',
- bidderRequestId: '1c1586b27a1b5c8',
- crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'},
- params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] },
- sizes: [[300, 250], [300, 600]],
- transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
- },
- {
- testId: 2,
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
- bidId: '2899ec066a91ff0',
- bidRequestsCount: 1,
- bidder: 'newspassid',
- bidderRequestId: '1c1586b27a1b5c0',
- crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'},
- params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] },
- sizes: [[300, 250], [300, 600]],
- transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
- }
-];
-var validBidRequestsWithUserIdData = [
- {
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
- bidId: '2899ec066a91ff8',
- bidRequestsCount: 1,
- bidder: 'newspassid',
- bidderRequestId: '1c1586b27a1b5c8',
- crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'},
- params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] },
- sizes: [[300, 250], [300, 600]],
- transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87',
- userId: {
- 'pubcid': '12345678',
- 'tdid': '1111tdid',
- 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } },
- 'criteoId': '1111criteoId',
- 'idl_env': 'liverampId',
- 'lipb': {'lipbid': 'lipbidId123'},
- 'parrableId': {'eid': '01.5678.parrableid'},
- 'sharedid': {'id': '01EAJWWNEPN3CYMM5N8M5VXY22', 'third': '01EAJWWNEPN3CYMM5N8M5VXY22'}
- },
- userIdAsEids: [
- {
- 'source': 'pubcid.org',
- 'uids': [
- {
- 'id': '12345678',
- 'atype': 1
- }
- ]
- },
- {
- 'source': 'adserver.org',
- 'uids': [{
- 'id': '1111tdid',
- 'atype': 1,
- 'ext': {
- 'rtiPartner': 'TDID'
- }
- }]
- },
- {
- 'source': 'id5-sync.com',
- 'uids': [{
- 'id': 'ID5-someId',
- 'atype': 1,
- }]
- },
- {
- 'source': 'criteoId',
- 'uids': [{
- 'id': '1111criteoId',
- 'atype': 1,
- }]
- },
- {
- 'source': 'idl_env',
- 'uids': [{
- 'id': 'liverampId',
- 'atype': 1,
- }]
- },
- {
- 'source': 'lipb',
- 'uids': [{
- 'id': {'lipbid': 'lipbidId123'},
- 'atype': 1,
- }]
- },
- {
- 'source': 'parrableId',
- 'uids': [{
- 'id': {'eid': '01.5678.parrableid'},
- 'atype': 1,
- }]
- }
- ]
- }
-];
-var validBidRequestsMinimal = [
- {
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
- bidId: '2899ec066a91ff8',
- bidRequestsCount: 1,
- bidder: 'newspassid',
- bidderRequestId: '1c1586b27a1b5c8',
- params: { publisherId: '9876abcd12-3', placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] },
- sizes: [[300, 250], [300, 600]],
- transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
- }
-];
-var validBidRequestsNoSizes = [
- {
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
- bidId: '2899ec066a91ff8',
- bidRequestsCount: 1,
- bidder: 'newspassid',
- bidderRequestId: '1c1586b27a1b5c8',
- crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'},
- params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] },
- transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
- }
-];
-var validBidRequestsWithBannerMediaType = [
- {
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
- bidId: '2899ec066a91ff8',
- bidRequestsCount: 1,
- bidder: 'newspassid',
- bidderRequestId: '1c1586b27a1b5c8',
- crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'},
- params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] },
- mediaTypes: {banner: {sizes: [[300, 250], [300, 600]]}},
- transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
- }
-];
-var validBidRequestsIsThisCamelCaseEnough = [
- {
- 'bidder': 'newspassid',
- 'testname': 'validBidRequestsIsThisCamelCaseEnough',
- 'params': {
- 'publisherId': 'newspassRUP0001',
- 'placementId': '8000000009',
- 'siteId': '4204204201',
- 'customData': [
- {
- 'settings': {},
- 'targeting': {
- 'sens': 'f',
- 'pt1': '/uk',
- 'pt2': 'uk',
- 'pt3': 'network-front',
- 'pt4': 'ng',
- 'pt5': [
- 'uk'
- ],
- 'pt7': 'desktop',
- 'pt8': [
- 'tfmqxwj7q',
- 'penl4dfdk',
- 'sek9ghqwi'
- ],
- 'pt9': '|k0xw2vqzp33kklb3j5w4|||'
- }
- }
- ],
- 'userId': {
- 'pubcid': '2ada6ae6-aeca-4e07-8922-a99b3aaf8a56'
- },
- 'userIdAsEids': [
- {
- 'source': 'pubcid.org',
- 'uids': [
- {
- 'id': '2ada6ae6-aeca-4e07-8922-a99b3aaf8a56',
- 'atype': 1
- }
- ]
- }
- ]
- },
- mediaTypes: {banner: {sizes: [[300, 250], [300, 600]]}},
- 'adUnitCode': 'some-ad',
- 'transactionId': '02c1ea7d-0bf2-451b-a122-1420040d1cf8',
- 'bidId': '2899ec066a91ff8',
- 'bidderRequestId': '1c1586b27a1b5c8',
- 'auctionId': '0456c9b7-5ab2-4fec-9e10-f418d3d1f04c',
- 'src': 'client',
- 'bidRequestsCount': 1,
- 'bidderRequestsCount': 1,
- 'bidderWinsCount': 0
- }
-];
-var validBidderRequest = {
- auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
- auctionStart: 1536838908986,
- bidderCode: 'newspassid',
- bidderRequestId: '1c1586b27a1b5c8',
- bids: [{
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
- bidId: '2899ec066a91ff8',
- bidRequestsCount: 1,
- bidder: 'newspassid',
- bidderRequestId: '1c1586b27a1b5c8',
- crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'},
- params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { banner: { topframe: 1, w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 300, h: 600 }] }, id: '2899ec066a91ff8', secure: 1, tagid: 'undefined' } ] },
- sizes: [[300, 250], [300, 600]],
- transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
- }],
- doneCbCallCount: 1,
- start: 1536838908987,
- timeout: 3000
-};
-var emptyObject = {};
-var validResponse = {
- 'body': {
- 'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba',
- 'seatbid': [
- {
- 'bid': [
- {
- 'id': '677903815252395017',
- 'impid': '2899ec066a91ff8',
- 'price': 0.5,
- 'adm': '',
- 'adid': '98493581',
- 'adomain': [
- 'http://prebid.org'
- ],
- 'iurl': 'https://fra1-ib.adnxs.com/cr?id=98493581',
- 'cid': '9325',
- 'crid': '98493581',
- 'cat': [
- 'IAB3-1'
- ],
- 'w': 300,
- 'h': 600,
- 'ext': {
- 'prebid': {
- 'type': 'banner'
- },
- 'bidder': {
- 'appnexus': {
- 'brand_id': 555545,
- 'auction_id': 6500448734132353000,
- 'bidder_id': 2,
- 'bid_ad_type': 0
- }
- }
- }
- }
- ],
- 'seat': 'appnexus'
- }
- ],
- 'cur': 'GBP', /* NOTE - this is where cur is, not in the seatbids. */
- 'ext': {
- 'responsetimemillis': {
- 'appnexus': 47,
- 'openx': 30
- }
- },
- 'timing': {
- 'start': 1536848078.089177,
- 'end': 1536848078.142203,
- 'TimeTaken': 0.05302619934082031
- }
- },
- 'headers': {}
-};
-var validResponse2BidsSameAdunit = {
- 'body': {
- 'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba',
- 'seatbid': [
- {
- 'bid': [
- {
- 'id': '677903815252395017',
- 'impid': '2899ec066a91ff8',
- 'price': 0.5,
- 'adm': '',
- 'adid': '98493581',
- 'adomain': [
- 'http://prebid.org'
- ],
- 'iurl': 'https://fra1-ib.adnxs.com/cr?id=98493581',
- 'cid': '9325',
- 'crid': '98493581',
- 'cat': [
- 'IAB3-1'
- ],
- 'w': 300,
- 'h': 600,
- 'ext': {
- 'prebid': {
- 'type': 'banner'
- },
- 'bidder': {
- 'appnexus': {
- 'brand_id': 555545,
- 'auction_id': 6500448734132353000,
- 'bidder_id': 2,
- 'bid_ad_type': 0
- }
- }
- }
- },
- {
- 'id': '677903815252395010',
- 'impid': '2899ec066a91ff8',
- 'price': 0.9,
- 'adm': '',
- 'adid': '98493580',
- 'adomain': [
- 'http://prebid.org'
- ],
- 'iurl': 'https://fra1-ib.adnxs.com/cr?id=98493581',
- 'cid': '9320',
- 'crid': '98493580',
- 'cat': [
- 'IAB3-1'
- ],
- 'w': 300,
- 'h': 250,
- 'ext': {
- 'prebid': {
- 'type': 'banner'
- },
- 'bidder': {
- 'appnexus': {
- 'brand_id': 555540,
- 'auction_id': 6500448734132353000,
- 'bidder_id': 2,
- 'bid_ad_type': 0
- }
- }
- }
- } ],
- 'seat': 'npappnexus'
- }
- ],
- 'cur': 'GBP', /* NOTE - this is where cur is, not in the seatbids. */
- 'ext': {
- 'responsetimemillis': {
- 'appnexus': 47,
- 'openx': 30
- }
- },
- 'timing': {
- 'start': 1536848078.089177,
- 'end': 1536848078.142203,
- 'TimeTaken': 0.05302619934082031
- }
- },
- 'headers': {}
-};
-var validBidResponse1adWith2Bidders = {
- 'body': {
- 'id': '91221f96-b931-4acc-8f05-c2a1186fa5ac',
- 'seatbid': [
- {
- 'bid': [
- {
- 'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba',
- 'impid': '2899ec066a91ff8',
- 'price': 0.36754,
- 'adm': '',
- 'adid': '134928661',
- 'adomain': [
- 'somecompany.com'
- ],
- 'iurl': 'https:\/\/ams1-ib.adnxs.com\/cr?id=134928661',
- 'cid': '8825',
- 'crid': '134928661',
- 'cat': [
- 'IAB8-15',
- 'IAB8-16',
- 'IAB8-4',
- 'IAB8-1',
- 'IAB8-14',
- 'IAB8-6',
- 'IAB8-13',
- 'IAB8-3',
- 'IAB8-17',
- 'IAB8-12',
- 'IAB8-8',
- 'IAB8-7',
- 'IAB8-2',
- 'IAB8-9',
- 'IAB8',
- 'IAB8-11'
- ],
- 'w': 300,
- 'h': 250,
- 'ext': {
- 'prebid': {
- 'type': 'banner'
- },
- 'bidder': {
- 'appnexus': {
- 'brand_id': 14640,
- 'auction_id': 1.8369641905139e+18,
- 'bidder_id': 2,
- 'bid_ad_type': 0
- }
- }
- }
- }
- ],
- 'seat': 'appnexus'
- },
- {
- 'bid': [
- {
- 'id': '75665207-a1ca-49db-ba0e-a5e9c7d26f32',
- 'impid': '37fff511779365a',
- 'price': 1.046,
- 'adm': '
removed
',
- 'adomain': [
- 'kx.com'
- ],
- 'crid': '13005',
- 'w': 300,
- 'h': 250,
- 'ext': {
- 'prebid': {
- 'type': 'banner'
- }
- }
- }
- ],
- 'seat': 'openx'
- }
- ],
- 'ext': {
- 'responsetimemillis': {
- 'appnexus': 91,
- 'openx': 109,
- 'npappnexus': 46,
- 'npbeeswax': 2,
- 'pangaea': 91
- }
- }
- },
- 'headers': {}
-};
-var multiRequest1 = [
- {
- 'bidder': 'newspassid',
- 'params': {
- 'publisherId': 'newspassRUP0001',
- 'siteId': '4204204201',
- 'placementId': '0420420421',
- 'customData': [
- {
- 'settings': {},
- 'targeting': {
- 'sens': 'f',
- 'pt1': '/uk',
- 'pt2': 'uk',
- 'pt3': 'network-front',
- 'pt4': 'ng',
- 'pt5': [
- 'uk'
- ],
- 'pt7': 'desktop',
- 'pt8': [
- 'tfmqxwj7q',
- 'penl4dfdk',
- 'uayf5jmv3',
- 't8nyiude5',
- 'sek9ghqwi'
- ],
- 'pt9': '|k0xw2vqzp33kklb3j5w4|||'
- }
- }
- ]
+ params: {
+ publisherId: TEST_PUBLISHER_ID,
+ placementId: TEST_PLACEMENT_ID
},
- 'mediaTypes': {
- 'banner': {
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ]
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250]]
}
},
- 'adUnitCode': 'mpu',
- 'transactionId': '6480bac7-31b5-4723-9145-ad8966660651',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '2d30e86db743a8',
- 'bidderRequestId': '1d03a1dfc563fc',
- 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f',
- 'src': 'client',
- 'bidRequestsCount': 1,
- 'bidderRequestsCount': 1,
- 'bidderWinsCount': 0
- },
- {
- 'bidder': 'newspassid',
- 'params': {
- 'publisherId': 'newspassRUP0001',
- 'siteId': '4204204201',
- 'placementId': '0420420421',
- 'customData': [
- {
- 'settings': {},
- 'targeting': {
- 'sens': 'f',
- 'pt1': '/uk',
- 'pt2': 'uk',
- 'pt3': 'network-front',
- 'pt4': 'ng',
- 'pt5': [
- 'uk'
- ],
- 'pt7': 'desktop',
- 'pt8': [
- 'tfmqxwj7q',
- 'penl4dfdk',
- 't8nxz6qzd',
- 't8nyiude5',
- 'sek9ghqwi'
- ],
- 'pt9': '|k0xw2vqzp33kklb3j5w4|||'
- }
- }
- ]
- },
- 'mediaTypes': {
- 'banner': {
- 'sizes': [
- [
- 728,
- 90
- ],
- [
- 970,
- 250
- ]
- ]
- }
- },
- 'adUnitCode': 'leaderboard',
- 'transactionId': 'a49988e6-ae7c-46c4-9598-f18db49892a0',
- 'sizes': [
- [
- 728,
- 90
- ],
- [
- 970,
- 250
- ]
- ],
- 'bidId': '3025f169863b7f8',
- 'bidderRequestId': '1d03a1dfc563fc',
- 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f',
- 'src': 'client',
- 'bidRequestsCount': 1,
- 'bidderRequestsCount': 1,
- 'bidderWinsCount': 0
- }
-];
-var multiBidderRequest1 = {
- bidderRequest: {
- 'bidderCode': 'newspassid',
- 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f',
- 'bidderRequestId': '1d03a1dfc563fc',
- 'bids': [
- {
- 'bidder': 'newspassid',
- 'params': {
- 'publisherId': 'newspassRUP0001',
- 'siteId': '4204204201',
- 'placementId': '0420420421',
- 'customData': [
- {
- 'settings': {},
- 'targeting': {
- 'sens': 'f',
- 'pt1': '/uk',
- 'pt2': 'uk',
- 'pt3': 'network-front',
- 'pt4': 'ng',
- 'pt5': [
- 'uk'
- ],
- 'pt7': 'desktop',
- 'pt8': [
- 'tfmqxwj7q',
- 'txeh7uyo0',
- 't8nxz6qzd',
- 't8nyiude5',
- 'sek9ghqwi'
- ],
- 'pt9': '|k0xw2vqzp33kklb3j5w4|||'
- }
- }
- ]
- },
- 'mediaTypes': {
- 'banner': {
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ]
- }
- },
- 'adUnitCode': 'mpu',
- 'transactionId': '6480bac7-31b5-4723-9145-ad8966660651',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '2d30e86db743a8',
- 'bidderRequestId': '1d03a1dfc563fc',
- 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f',
- 'src': 'client',
- 'bidRequestsCount': 1,
- 'bidderRequestsCount': 1,
- 'bidderWinsCount': 0
- },
- {
- 'bidder': 'newspassid',
- 'params': {
- 'publisherId': 'newspassRUP0001',
- 'siteId': '4204204201',
- 'placementId': '0420420421',
- 'customData': [
- {
- 'settings': {},
- 'targeting': {
- 'sens': 'f',
- 'pt1': '/uk',
- 'pt2': 'uk',
- 'pt3': 'network-front',
- 'pt4': 'ng',
- 'pt5': [
- 'uk'
- ],
- 'pt7': 'desktop',
- 'pt8': [
- 'tfmqxwj7q',
- 'penl4dfdk',
- 't8nxz6qzd',
- 't8nyiude5',
- 'sek9ghqwi'
- ],
- 'pt9': '|k0xw2vqzp33kklb3j5w4|||'
- }
- }
- ]
- },
- 'mediaTypes': {
- 'banner': {
- 'sizes': [
- [
- 728,
- 90
- ],
- [
- 970,
- 250
- ]
- ]
- }
- },
- 'adUnitCode': 'leaderboard',
- 'transactionId': 'a49988e6-ae7c-46c4-9598-f18db49892a0',
- 'sizes': [
- [
- 728,
- 90
- ],
- [
- 970,
- 250
- ]
- ],
- 'bidId': '3025f169863b7f8',
- 'bidderRequestId': '1d03a1dfc563fc',
- 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f',
- 'src': 'client',
- 'bidRequestsCount': 1,
- 'bidderRequestsCount': 1,
- 'bidderWinsCount': 0
- }
- ],
- 'auctionStart': 1592918645574,
- 'timeout': 3000,
- 'refererInfo': {
- 'referer': 'http://some.referrer.com',
- 'reachedTop': true,
- 'numIframes': 0,
- 'stack': [
- 'http://some.referrer.com'
- ]
+ adUnitCode: 'test-div',
+ transactionId: '123456',
+ bidId: '789',
+ bidderRequestId: 'abc',
+ auctionId: 'xyz'
+ };
+
+ const validBidderRequest = {
+ bidderCode: 'newspassid',
+ auctionId: 'xyz',
+ bidderRequestId: 'abc',
+ bids: [validBidRequest],
+ gdprConsent: {
+ gdprApplies: true,
+ consentString: 'consent123'
},
- 'start': 1592918645578
- }
-};
-var multiResponse1 = {
- 'body': {
- 'id': '592ee33b-fb2e-4c00-b2d5-383e99cac57f',
- 'seatbid': [
- {
- 'bid': [
- {
- 'id': '4419718600113204943',
- 'impid': '2d30e86db743a8',
- 'price': 0.2484,
- 'adm': '',
- 'adid': '119683582',
- 'adomain': [
- 'https://someurl.com'
- ],
- 'iurl': 'https://ams1-ib.adnxs.com/cr?id=119683582',
- 'cid': '9979',
- 'crid': '119683582',
- 'cat': [
- 'IAB3'
- ],
- 'w': 300,
- 'h': 250,
- 'ext': {
- 'prebid': {
- 'type': 'banner'
- },
- 'bidder': {
- 'newspassid': {},
- 'appnexus': {
- 'brand_id': 734921,
- 'auction_id': 2995348111857539600,
- 'bidder_id': 2,
- 'bid_ad_type': 0
- }
- }
- },
- 'cpm': 0.2484,
- 'bidId': '2d30e86db743a8',
- 'requestId': '2d30e86db743a8',
- 'width': 300,
- 'height': 250,
- 'ad': '',
- 'netRevenue': true,
- 'creativeId': '119683582',
- 'currency': 'USD',
- 'ttl': 300,
- 'originalCpm': 0.2484,
- 'originalCurrency': 'USD'
- },
- {
- 'id': '18552976939844681',
- 'impid': '3025f169863b7f8',
- 'price': 0.0621,
- 'adm': '',
- 'adid': '120179216',
- 'adomain': [
- 'appnexus.com'
- ],
- 'iurl': 'https://ams1-ib.adnxs.com/cr?id=120179216',
- 'cid': '9979',
- 'crid': '120179216',
- 'w': 970,
- 'h': 250,
- 'ext': {
- 'prebid': {
- 'type': 'banner'
- },
- 'bidder': {
- 'newspassid': {},
- 'appnexus': {
- 'brand_id': 1,
- 'auction_id': 3449036134472542700,
- 'bidder_id': 2,
- 'bid_ad_type': 0
- }
- }
- },
- 'cpm': 0.0621,
- 'bidId': '3025f169863b7f8',
- 'requestId': '3025f169863b7f8',
- 'width': 970,
- 'height': 250,
- 'ad': '',
- 'netRevenue': true,
- 'creativeId': '120179216',
- 'currency': 'USD',
- 'ttl': 300,
- 'originalCpm': 0.0621,
- 'originalCurrency': 'USD'
- },
- {
- 'id': '18552976939844999',
- 'impid': '3025f169863b7f8',
- 'price': 0.521,
- 'adm': '',
- 'adid': '120179216',
- 'adomain': [
- 'appnexus.com'
- ],
- 'iurl': 'https://ams1-ib.adnxs.com/cr?id=120179216',
- 'cid': '9999',
- 'crid': '120179299',
- 'w': 728,
- 'h': 90,
- 'ext': {
- 'prebid': {
- 'type': 'banner'
- },
- 'bidder': {
- 'newspassid': {},
- 'appnexus': {
- 'brand_id': 1,
- 'auction_id': 3449036134472542700,
- 'bidder_id': 2,
- 'bid_ad_type': 0
- }
- }
- },
- 'cpm': 0.521,
- 'bidId': '3025f169863b7f8',
- 'requestId': '3025f169863b7f8',
- 'width': 728,
- 'height': 90,
- 'ad': '',
- 'netRevenue': true,
- 'creativeId': '120179299',
- 'currency': 'USD',
- 'ttl': 300,
- 'originalCpm': 0.0621,
- 'originalCurrency': 'USD'
- }
- ],
- 'seat': 'npappnexus'
- },
- {
- 'bid': [
- {
- 'id': '1c605e8a-4992-4ec6-8a5c-f82e2938c2db',
- 'impid': '2d30e86db743a8',
- 'price': 0.01,
- 'adm': '',
- 'crid': '540463358',
- 'w': 300,
- 'h': 250,
- 'ext': {
- 'prebid': {
- 'type': 'banner'
- },
- 'bidder': {
- 'newspassid': {}
- }
- },
- 'cpm': 0.01,
- 'bidId': '2d30e86db743a8',
- 'requestId': '2d30e86db743a8',
- 'width': 300,
- 'height': 250,
- 'ad': '
',
- 'netRevenue': true,
- 'creativeId': '540463358',
- 'currency': 'USD',
- 'ttl': 300,
- 'originalCpm': 0.01,
- 'originalCurrency': 'USD'
- },
- {
- 'id': '3edeb4f7-d91d-44e2-8aeb-4a2f6d295ce5',
- 'impid': '3025f169863b7f8',
- 'price': 0.01,
- 'adm': '
',
- 'crid': '540221061',
- 'w': 970,
- 'h': 250,
- 'ext': {
- 'prebid': {
- 'type': 'banner'
- },
- 'bidder': {
- 'newspassid': {}
- }
- },
- 'cpm': 0.01,
- 'bidId': '3025f169863b7f8',
- 'requestId': '3025f169863b7f8',
- 'width': 970,
- 'height': 250,
- 'ad': '
',
- 'netRevenue': true,
- 'creativeId': '540221061',
- 'currency': 'USD',
- 'ttl': 300,
- 'originalCpm': 0.01,
- 'originalCurrency': 'USD'
- }
- ],
- 'seat': 'openx'
- }
- ],
- 'ext': {
- 'debug': {},
- 'responsetimemillis': {
- 'beeswax': 6,
- 'openx': 91,
- 'npappnexus': 40,
- 'npbeeswax': 6
- }
+ refererInfo: {
+ page: 'http://example.com'
}
- },
- 'headers': {}
-};
-describe('newspassid Adapter', function () {
- describe('isBidRequestValid', function () {
- let validBidReq = {
- bidder: BIDDER_CODE,
- params: {
- placementId: '1310000099',
- publisherId: '9876abcd12-3',
- siteId: '1234567890'
- }
- };
- it('should return true when required params found', function () {
- expect(spec.isBidRequestValid(validBidReq)).to.equal(true);
- });
- var validBidReq2 = {
- bidder: BIDDER_CODE,
- params: {
- placementId: '1310000099',
- publisherId: '9876abcd12-3',
- siteId: '1234567890',
- customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}]
- },
- siteId: 1234567890
+ };
+
+ const serverResponse = {
+ body: {
+ seatbid: [{
+ bid: [{
+ impid: '789',
+ price: 2.5,
+ w: 300,
+ h: 250,
+ crid: 'creative123',
+ adm: '
ad
',
+ adomain: ['advertiser.com']
+ }]
+ }],
+ cur: 'USD'
}
- it('should return true when required params found and all optional params are valid', function () {
- expect(spec.isBidRequestValid(validBidReq2)).to.equal(true);
- });
- var xEmptyPlacement = {
- bidder: BIDDER_CODE,
- params: {
- placementId: '',
- publisherId: '9876abcd12-3',
- siteId: '1234567890'
- }
- };
- it('should not validate empty placementId', function () {
- expect(spec.isBidRequestValid(xEmptyPlacement)).to.equal(false);
- });
- var xMissingPlacement = {
- bidder: BIDDER_CODE,
- params: {
- publisherId: '9876abcd12-3',
- siteId: '1234567890'
- }
- };
- it('should not validate missing placementId', function () {
- expect(spec.isBidRequestValid(xMissingPlacement)).to.equal(false);
- });
- var xBadPlacement = {
- bidder: BIDDER_CODE,
- params: {
- placementId: '123X45',
- publisherId: '9876abcd12-3',
- siteId: '1234567890'
- }
- };
- it('should not validate placementId with a non-numeric value', function () {
- expect(spec.isBidRequestValid(xBadPlacement)).to.equal(false);
- });
- var xBadPlacementTooShort = {
- bidder: BIDDER_CODE,
- params: {
- placementId: 123456789, /* should be exactly 10 chars */
- publisherId: '9876abcd12-3',
- siteId: '1234567890'
- }
- };
- it('should not validate placementId with a numeric value of wrong length', function () {
- expect(spec.isBidRequestValid(xBadPlacementTooShort)).to.equal(false);
- });
- var xBadPlacementTooLong = {
- bidder: BIDDER_CODE,
- params: {
- placementId: 12345678901, /* should be exactly 10 chars */
- publisherId: '9876abcd12-3',
- siteId: '1234567890'
- }
- };
- it('should not validate placementId with a numeric value of wrong length', function () {
- expect(spec.isBidRequestValid(xBadPlacementTooLong)).to.equal(false);
- });
- var xMissingPublisher = {
- bidder: BIDDER_CODE,
- params: {
- placementId: '1234567890',
- siteId: '1234567890'
- }
- };
- it('should not validate missing publisherId', function () {
- expect(spec.isBidRequestValid(xMissingPublisher)).to.equal(false);
- });
- var xMissingSiteId = {
- bidder: BIDDER_CODE,
- params: {
- publisherId: '9876abcd12-3',
- placementId: '1234567890',
- }
- };
- it('should not validate missing sitetId', function () {
- expect(spec.isBidRequestValid(xMissingSiteId)).to.equal(false);
- });
- var xBadPublisherTooShort = {
- bidder: BIDDER_CODE,
- params: {
- placementId: '1234567890',
- publisherId: '9876abcd12a',
- siteId: '1234567890'
- }
- };
- it('should not validate publisherId being too short', function () {
- expect(spec.isBidRequestValid(xBadPublisherTooShort)).to.equal(false);
- });
- var xBadPublisherTooLong = {
- bidder: BIDDER_CODE,
- params: {
- placementId: '1234567890',
- publisherId: '9876abcd12abc',
- siteId: '1234567890'
- }
- };
- it('should not validate publisherId being too long', function () {
- expect(spec.isBidRequestValid(xBadPublisherTooLong)).to.equal(false);
- });
- var publisherNumericOk = {
- bidder: BIDDER_CODE,
- params: {
- placementId: '1234567890',
- publisherId: 123456789012,
- siteId: '1234567890'
- }
- };
- it('should validate publisherId being 12 digits', function () {
- expect(spec.isBidRequestValid(publisherNumericOk)).to.equal(true);
- });
- var xEmptyPublisher = {
- bidder: BIDDER_CODE,
- params: {
- placementId: '1234567890',
- publisherId: '',
- siteId: '1234567890'
- }
- };
- it('should not validate empty publisherId', function () {
- expect(spec.isBidRequestValid(xEmptyPublisher)).to.equal(false);
- });
- var xBadSite = {
- bidder: BIDDER_CODE,
- params: {
- placementId: '1234567890',
- publisherId: '9876abcd12-3',
- siteId: '12345Z'
- }
- };
- it('should not validate bad siteId', function () {
- expect(spec.isBidRequestValid(xBadSite)).to.equal(false);
- });
- it('should not validate siteId too long', function () {
- expect(spec.isBidRequestValid(xBadSite)).to.equal(false);
- });
- it('should not validate siteId too short', function () {
- expect(spec.isBidRequestValid(xBadSite)).to.equal(false);
- });
- var allNonStrings = {
- bidder: BIDDER_CODE,
- params: {
- placementId: 1234567890,
- publisherId: '9876abcd12-3',
- siteId: 1234567890
- }
- };
- it('should validate all numeric values being sent as non-string numbers', function () {
- expect(spec.isBidRequestValid(allNonStrings)).to.equal(true);
- });
- var emptySiteId = {
- bidder: BIDDER_CODE,
- params: {
- placementId: 1234567890,
- publisherId: '9876abcd12-3',
- siteId: ''
- }
- };
- it('should not validate siteId being empty string (it is required now)', function () {
- expect(spec.isBidRequestValid(emptySiteId)).to.equal(false);
- });
- var xBadCustomData = {
- bidder: BIDDER_CODE,
- params: {
- 'placementId': '1234567890',
- 'publisherId': '9876abcd12-3',
- 'siteId': '1234567890',
- 'customData': 'this aint gonna work'
- }
- };
- it('should not validate customData not being an array', function () {
- expect(spec.isBidRequestValid(xBadCustomData)).to.equal(false);
- });
- var xBadCustomDataOldCustomdataValue = {
- bidder: BIDDER_CODE,
- params: {
- 'placementId': '1234567890',
- 'publisherId': '9876abcd12-3',
- 'siteId': '1234567890',
- 'customData': {'gender': 'bart', 'age': 'low'}
- }
- };
- it('should not validate customData being an object, not an array', function () {
- expect(spec.isBidRequestValid(xBadCustomDataOldCustomdataValue)).to.equal(false);
- });
- var xBadCustomDataZerocd = {
- bidder: BIDDER_CODE,
- params: {
- 'placementId': '1111111110',
- 'publisherId': '9876abcd12-3',
- 'siteId': '1234567890',
- 'customData': []
- }
- };
- it('should not validate customData array having no elements', function () {
- expect(spec.isBidRequestValid(xBadCustomDataZerocd)).to.equal(false);
- });
- var xBadCustomDataNotargeting = {
- bidder: BIDDER_CODE,
- params: {
- 'placementId': '1234567890',
- 'publisherId': '9876abcd12-3',
- 'customData': [{'settings': {}, 'xx': {'gender': 'bart', 'age': 'low'}}],
- siteId: '1234567890'
- }
- };
- it('should not validate customData[] having no "targeting"', function () {
- expect(spec.isBidRequestValid(xBadCustomDataNotargeting)).to.equal(false);
- });
- var xBadCustomDataTgtNotObj = {
- bidder: BIDDER_CODE,
- params: {
- 'placementId': '1234567890',
- 'publisherId': '9876abcd12-3',
- 'customData': [{'settings': {}, 'targeting': 'this should be an object'}],
- siteId: '1234567890'
- }
- };
- it('should not validate customData[0].targeting not being an object', function () {
- expect(spec.isBidRequestValid(xBadCustomDataTgtNotObj)).to.equal(false);
- });
- var xBadCustomParams = {
- bidder: BIDDER_CODE,
- params: {
- 'placementId': '1234567890',
- 'publisherId': '9876abcd12-3',
- 'siteId': '1234567890',
- 'customParams': 'this key is no longer valid'
- }
- };
- it('should not validate customParams - this is a renamed key', function () {
- expect(spec.isBidRequestValid(xBadCustomParams)).to.equal(false);
+ };
+
+ describe('gvlid', function() {
+ it('should expose gvlid', function() {
+ expect(spec.gvlid).to.equal(1317);
});
});
- describe('buildRequests', function () {
- it('sends bid request to NEWSPASSURI via POST', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- expect(request.url).to.equal(NEWSPASSURI);
- expect(request.method).to.equal('POST');
- });
- it('sends data as a string', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- expect(request.data).to.be.a('string');
- });
- it('sends all bid parameters', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
- });
- it('adds all parameters inside the ext object only', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- expect(request.data).to.be.a('string');
- var data = JSON.parse(request.data);
- expect(data.imp[0].ext.newspassid.customData).to.be.an('array');
- expect(request).not.to.have.key('lotameData');
- expect(request).not.to.have.key('customData');
- });
- it('adds all parameters inside the ext object only - lightning', function () {
- let localBidReq = JSON.parse(JSON.stringify(validBidRequests));
- const request = spec.buildRequests(localBidReq, validBidderRequest);
- expect(request.data).to.be.a('string');
- var data = JSON.parse(request.data);
- expect(data.imp[0].ext.newspassid.customData).to.be.an('array');
- expect(request).not.to.have.key('lotameData');
- expect(request).not.to.have.key('customData');
- });
- it('has correct bidder', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- expect(request.bidderRequest.bids[0].bidder).to.equal(BIDDER_CODE);
- });
- it('handles mediaTypes element correctly', function () {
- const request = spec.buildRequests(validBidRequestsWithBannerMediaType, validBidderRequest);
- expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
- });
- it('handles no newspassid or custom data', function () {
- const request = spec.buildRequests(validBidRequestsMinimal, validBidderRequest);
- expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
- });
- it('should not crash when there is no sizes element at all', function () {
- const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest);
- expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
- });
- it('should be able to handle non-single requests', function () {
- config.setConfig({'newspassid': {'singleRequest': false}});
- const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest);
- expect(request).to.be.a('array');
- expect(request[0]).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
- config.setConfig({'newspassid': {'singleRequest': true}});
- });
- it('should not have imp[N].ext.newspassid.userId', function () {
- let bidderRequest = validBidderRequest;
- let bidRequests = validBidRequests;
- bidRequests[0]['userId'] = {
- 'digitrustid': {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}},
- 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } },
- 'idl_env': '3333',
- 'parrableid': 'eidVersion.encryptionKeyReference.encryptedValue',
- 'pubcid': '5555',
- 'tdid': '6666',
- 'sharedid': {'id': '01EAJWWNEPN3CYMM5N8M5VXY22', 'third': '01EAJWWNEPN3CYMM5N8M5VXY22'}
- };
- bidRequests[0]['userIdAsEids'] = validBidRequestsWithUserIdData[0]['userIdAsEids'];
- const request = spec.buildRequests(bidRequests, bidderRequest);
- const payload = JSON.parse(request.data);
- let firstBid = payload.imp[0].ext.newspassid;
- expect(firstBid).to.not.have.property('userId');
- delete validBidRequests[0].userId; // tidy up now, else it will screw with other tests
- });
- it('should pick up the value of pubcid when built using the pubCommonId module (not userId)', function () {
- let bidRequests = validBidRequests;
- bidRequests[0]['userId'] = {
- 'digitrustid': {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}},
- 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } },
- 'idl_env': '3333',
- 'parrableid': 'eidVersion.encryptionKeyReference.encryptedValue',
- 'tdid': '6666',
- 'sharedid': {'id': '01EAJWWNEPN3CYMM5N8M5VXY22', 'third': '01EAJWWNEPN3CYMM5N8M5VXY22'}
- };
- bidRequests[0]['userIdAsEids'] = validBidRequestsWithUserIdData[0]['userIdAsEids'];
- const request = spec.buildRequests(bidRequests, validBidderRequest);
- const payload = JSON.parse(request.data);
- expect(payload.ext.newspassid.pubcid).to.equal(bidRequests[0]['crumbs']['pubcid']);
- delete validBidRequests[0].userId; // tidy up now, else it will screw with other tests
- });
- it('should add a user.ext.eids object to contain user ID data in the new location (Nov 2019) Updated Aug 2020', function() {
- const request = spec.buildRequests(validBidRequestsWithUserIdData, validBidderRequest);
- const payload = JSON.parse(request.data);
- expect(payload.user).to.exist;
- expect(payload.user.ext).to.exist;
- expect(payload.user.ext.eids).to.exist;
- expect(payload.user.ext.eids[0]['source']).to.equal('pubcid.org');
- expect(payload.user.ext.eids[0]['uids'][0]['id']).to.equal('12345678');
- expect(payload.user.ext.eids[1]['source']).to.equal('adserver.org');
- expect(payload.user.ext.eids[1]['uids'][0]['id']).to.equal('1111tdid');
- expect(payload.user.ext.eids[2]['source']).to.equal('id5-sync.com');
- expect(payload.user.ext.eids[2]['uids'][0]['id']).to.equal('ID5-someId');
- expect(payload.user.ext.eids[3]['source']).to.equal('criteoId');
- expect(payload.user.ext.eids[3]['uids'][0]['id']).to.equal('1111criteoId');
- expect(payload.user.ext.eids[4]['source']).to.equal('idl_env');
- expect(payload.user.ext.eids[4]['uids'][0]['id']).to.equal('liverampId');
- expect(payload.user.ext.eids[5]['source']).to.equal('lipb');
- expect(payload.user.ext.eids[5]['uids'][0]['id']['lipbid']).to.equal('lipbidId123');
- expect(payload.user.ext.eids[6]['source']).to.equal('parrableId');
- expect(payload.user.ext.eids[6]['uids'][0]['id']['eid']).to.equal('01.5678.parrableid');
- });
- it('replaces the auction url for a config override', function () {
- spec.propertyBag.config = null;
- let fakeOrigin = 'http://sometestendpoint';
- config.setConfig({'newspassid': {'endpointOverride': {'origin': fakeOrigin}}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- expect(request.url).to.equal(fakeOrigin + '/openrtb2/auction');
- expect(request.method).to.equal('POST');
- const data = JSON.parse(request.data);
- expect(data.ext.newspassid.origin).to.equal(fakeOrigin);
- config.setConfig({'newspassid': {'kvpPrefix': null, 'endpointOverride': null}});
- });
- it('replaces the FULL auction url for a config override', function () {
- spec.propertyBag.config = null;
- let fakeurl = 'http://sometestendpoint/myfullurl';
- config.setConfig({'newspassid': {'endpointOverride': {'auctionUrl': fakeurl}}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- expect(request.url).to.equal(fakeurl);
- expect(request.method).to.equal('POST');
- const data = JSON.parse(request.data);
- expect(data.ext.newspassid.origin).to.equal(fakeurl);
- config.setConfig({'newspassid': {'kvpPrefix': null, 'endpointOverride': null}});
- });
- it('should ignore kvpPrefix', function () {
- spec.propertyBag.config = null;
- config.setConfig({'newspassid': {'kvpPrefix': 'np'}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- const result = spec.interpretResponse(validResponse, request);
- expect(result[0].adserverTargeting).to.have.own.property('np_appnexus_crid');
- expect(utils.deepAccess(result[0].adserverTargeting, 'np_appnexus_crid')).to.equal('98493581');
- expect(utils.deepAccess(result[0].adserverTargeting, 'np_adId')).to.equal('2899ec066a91ff8-0-np-0');
- expect(utils.deepAccess(result[0].adserverTargeting, 'np_size')).to.equal('300x600');
- expect(utils.deepAccess(result[0].adserverTargeting, 'np_pb_r')).to.equal('0.50');
- expect(utils.deepAccess(result[0].adserverTargeting, 'np_bid')).to.equal('true');
+
+ describe('resolveNewpassidPublisherId', function() {
+ afterEach(() => {
config.resetConfig();
});
- it('should create a meta object on each bid returned', function () {
- spec.propertyBag.config = null;
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- const result = spec.interpretResponse(validResponse, request);
- expect(result[0]).to.have.own.property('meta');
- expect(result[0].meta.advertiserDomains[0]).to.equal('http://prebid.org');
- config.resetConfig();
- });
- it('should use nptestmode GET value if set', function() {
- var specMock = utils.deepClone(spec);
- specMock.getGetParametersAsObject = function() {
- return {'nptestmode': 'mytestvalue_123'};
- };
- const request = specMock.buildRequests(validBidRequests, validBidderRequest);
- const data = JSON.parse(request.data);
- expect(data.imp[0].ext.newspassid.customData).to.be.an('array');
- expect(data.imp[0].ext.newspassid.customData[0].targeting.nptestmode).to.equal('mytestvalue_123');
- });
- it('should pass through GET params if present: npf, nppf, nprp, npip', function() {
- var specMock = utils.deepClone(spec);
- specMock.getGetParametersAsObject = function() {
- return {npf: '1', nppf: '0', nprp: '2', npip: '123'};
- };
- const request = specMock.buildRequests(validBidRequests, validBidderRequest);
- const data = JSON.parse(request.data);
- expect(data.ext.newspassid.npf).to.equal(1);
- expect(data.ext.newspassid.nppf).to.equal(0);
- expect(data.ext.newspassid.nprp).to.equal(2);
- expect(data.ext.newspassid.npip).to.equal(123);
- });
- it('should pass through GET params if present: npf, nppf, nprp, npip with alternative values', function() {
- var specMock = utils.deepClone(spec);
- specMock.getGetParametersAsObject = function() {
- return {npf: 'false', nppf: 'true', nprp: 'xyz', npip: 'hello'};
- };
- const request = specMock.buildRequests(validBidRequests, validBidderRequest);
- const data = JSON.parse(request.data);
- expect(data.ext.newspassid.npf).to.equal(0);
- expect(data.ext.newspassid.nppf).to.equal(1);
- expect(data.ext.newspassid).to.not.haveOwnProperty('nprp');
- expect(data.ext.newspassid).to.not.haveOwnProperty('npip');
+
+ it('should return null if no bidrequest object or no global publisherId set', function() {
+ expect(resolveNewpassidPublisherId()).to.equal(null);
});
- it('should use nptestmode GET value if set, even if there is no customdata in config', function() {
- var specMock = utils.deepClone(spec);
- specMock.getGetParametersAsObject = function() {
- return {'nptestmode': 'mytestvalue_123'};
- };
- const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
- const data = JSON.parse(request.data);
- expect(data.imp[0].ext.newspassid.customData).to.be.an('array');
- expect(data.imp[0].ext.newspassid.customData[0].targeting.nptestmode).to.equal('mytestvalue_123');
+
+ it('should return global publisherId if no bidrequest object and global publisherId set', function() {
+ config.setConfig({
+ newspassid: {
+ publisherId: TEST_PUBLISHER_ID
+ }
+ });
+ expect(resolveNewpassidPublisherId()).to.equal(TEST_PUBLISHER_ID);
});
- it('should use GET values auction=[encoded URL] & cookiesync=[encoded url] if set', function() {
- spec.propertyBag.config = null;
- var specMock = utils.deepClone(spec);
- specMock.getGetParametersAsObject = function() {
- return {};
- };
- let request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
- let url = request.url;
- expect(url).to.equal('https://bidder.newspassid.com/openrtb2/auction');
- let cookieUrl = specMock.getCookieSyncUrl();
- expect(cookieUrl).to.equal('https://bidder.newspassid.com/static/load-cookie.html');
- specMock = utils.deepClone(spec);
- specMock.getGetParametersAsObject = function() {
- return {'auction': 'https://www.someurl.com/auction', 'cookiesync': 'https://www.someurl.com/sync'};
- };
- request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
- url = request.url;
- expect(url).to.equal('https://www.someurl.com/auction');
- cookieUrl = specMock.getCookieSyncUrl();
- expect(cookieUrl).to.equal('https://www.someurl.com/sync');
+ });
+
+ describe('isBidRequestValid', function() {
+ it('should return true when required params are present', function() {
+ expect(spec.isBidRequestValid(validBidRequest)).to.be.true;
+ });
+
+ it('should return false when publisherId is missing', function() {
+ const bid = deepClone(validBidRequest);
+ delete bid.params.publisherId;
+ expect(spec.isBidRequestValid(bid)).to.be.false;
+ });
+
+ it('should return false when placementId is missing', function() {
+ const bid = deepClone(validBidRequest);
+ delete bid.params.placementId;
+ expect(spec.isBidRequestValid(bid)).to.be.false;
});
- it('should use a valid npstoredrequest GET value if set to override the placementId values, and set np_rw if we find it', function() {
- var specMock = utils.deepClone(spec);
- specMock.getGetParametersAsObject = function() {
- return {'npstoredrequest': '1122334455'}; // 10 digits are valid
+ });
+
+ describe('buildRequests', function() {
+ it('should create request data', function() {
+ const requests = spec.buildRequests([validBidRequest], validBidderRequest);
+ expect(requests).to.have.lengthOf(1);
+ expect(requests[0].method).to.equal('POST');
+ expect(requests[0].url).to.equal('https://npid.amspbs.com/v0/bid/request');
+ expect(requests[0].options.withCredentials).to.be.true;
+ });
+
+ it('should include bidder params in ortb2 request', function() {
+ const requests = spec.buildRequests([validBidRequest], validBidderRequest);
+ const data = requests[0].data;
+ expect(data.imp[0].ext.newspassid.publisher).to.equal(TEST_PUBLISHER_ID);
+ expect(data.imp[0].ext.newspassid.placementId).to.equal(TEST_PLACEMENT_ID);
+ });
+
+ it('should use global publisherId when not set in bid params', function() {
+ const validBidRequestWithoutPublisherId = {
+ ...validBidRequest,
+ params: {
+ placementId: TEST_PLACEMENT_ID
+ },
};
- const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
- const data = JSON.parse(request.data);
- expect(data.ext.newspassid.np_rw).to.equal(1);
- expect(data.imp[0].ext.prebid.storedrequest.id).to.equal('1122334455');
- });
- it('should NOT use an invalid npstoredrequest GET value if set to override the placementId values, and set np_rw to 0', function() {
- var specMock = utils.deepClone(spec);
- specMock.getGetParametersAsObject = function() {
- return {'npstoredrequest': 'BADVAL'}; // 10 digits are valid
+ config.setConfig({
+ newspassid: {
+ publisherId: TEST_PUBLISHER_ID
+ }
+ });
+ const requests = spec.buildRequests([validBidRequestWithoutPublisherId], validBidderRequest);
+ const data = requests[0].data;
+ expect(data.imp[0].ext.newspassid.publisher).to.equal(TEST_PUBLISHER_ID);
+ expect(data.imp[0].ext.newspassid.placementId).to.equal(TEST_PLACEMENT_ID);
+ });
+
+ it('should use publisherId from bidRequest first over global publisherId', function() {
+ config.setConfig({
+ newspassid: {
+ publisherId: TEST_PUBLISHER_ID
+ }
+ });
+ const validBidRequestWithDifferentPublisherId = {
+ ...validBidRequest,
+ params: {
+ publisherId: 'publisherId123'
+ }
};
- const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
- const data = JSON.parse(request.data);
- expect(data.ext.newspassid.np_rw).to.equal(0);
- expect(data.imp[0].ext.prebid.storedrequest.id).to.equal('1310000099');
- });
- it('should pick up the config value of coppa & set it in the request', function () {
- config.setConfig({'coppa': true});
- const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest);
- const payload = JSON.parse(request.data);
- expect(payload.regs).to.include.keys('coppa');
- expect(payload.regs.coppa).to.equal(1);
- config.resetConfig();
- });
- it('should pick up the config value of coppa & only set it in the request if its true', function () {
- config.setConfig({'coppa': false});
- const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest);
- const payload = JSON.parse(request.data);
- expect(utils.deepAccess(payload, 'regs.coppa')).to.be.undefined;
- config.resetConfig();
- });
- it('should should contain a unique page view id in the auction request which persists across calls', function () {
- let request = spec.buildRequests(validBidRequests, validBidderRequest);
- let payload = JSON.parse(request.data);
- expect(utils.deepAccess(payload, 'ext.newspassid.pv')).to.be.a('string');
- request = spec.buildRequests(validBidRequestsIsThisCamelCaseEnough, validBidderRequest);
- let payload2 = JSON.parse(request.data);
- expect(utils.deepAccess(payload2, 'ext.newspassid.pv')).to.be.a('string');
- expect(utils.deepAccess(payload2, 'ext.newspassid.pv')).to.equal(utils.deepAccess(payload, 'ext.newspassid.pv'));
+ const requests = spec.buildRequests([validBidRequestWithDifferentPublisherId], validBidderRequest);
+ const data = requests[0].data;
+ expect(data.imp[0].ext.newspassid.publisher).to.equal('publisherId123');
+ });
+
+ it('should handle multiple bid requests', function() {
+ const secondBidRequest = deepClone(validBidRequest);
+ secondBidRequest.bidId = '790';
+ const requests = spec.buildRequests([validBidRequest, secondBidRequest], validBidderRequest);
+ expect(requests).to.have.lengthOf(1);
+ expect(requests[0].data.imp).to.have.lengthOf(2);
});
- it('should indicate that the whitelist was used when it contains valid data', function () {
- config.setConfig({'newspassid': {'np_whitelist_adserver_keys': ['np_appnexus_pb', 'np_appnexus_imp_id']}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- const payload = JSON.parse(request.data);
- expect(payload.ext.newspassid.np_kvp_rw).to.equal(1);
- config.resetConfig();
+ });
+
+ describe('interpretResponse', function() {
+ it('should return empty array if no valid bids', function() {
+ const invalidResponse = {body: {}};
+ const bids = spec.interpretResponse(invalidResponse);
+ expect(bids).to.be.empty;
+ });
+
+ it('should return empty array if no seatbid', function() {
+ const noSeatbidResponse = {body: {cur: 'USD'}};
+ const bids = spec.interpretResponse(noSeatbidResponse);
+ expect(bids).to.be.empty;
+ });
+
+ it('should interpret valid server response', function() {
+ const bids = spec.interpretResponse(serverResponse);
+ expect(bids).to.have.lengthOf(1);
+ expect(bids[0]).to.deep.equal({
+ requestId: '789',
+ cpm: 2.5,
+ width: 300,
+ height: 250,
+ creativeId: 'creative123',
+ currency: 'USD',
+ netRevenue: true,
+ ttl: 300,
+ ad: '
ad
',
+ meta: {
+ advertiserDomains: ['advertiser.com']
+ }
+ });
});
- it('should indicate that the whitelist was not used when it contains no data', function () {
- config.setConfig({'newspassid': {'np_whitelist_adserver_keys': []}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- const payload = JSON.parse(request.data);
- expect(payload.ext.newspassid.np_kvp_rw).to.equal(0);
+ });
+
+ describe('getUserSyncs', function() {
+ afterEach(() => {
config.resetConfig();
});
- it('should indicate that the whitelist was not used when it is not set in the config', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- const payload = JSON.parse(request.data);
- expect(payload.ext.newspassid.np_kvp_rw).to.equal(0);
- });
- it('should handle ortb2 site data', function () {
- let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest));
- bidderRequest.ortb2 = {
- 'site': {
- 'name': 'example_ortb2_name',
- 'domain': 'page.example.com',
- 'cat': ['IAB2'],
- 'sectioncat': ['IAB2-2'],
- 'pagecat': ['IAB2-2'],
- 'page': 'https://page.example.com/here.html',
- 'ref': 'https://ref.example.com',
- 'keywords': 'power tools, drills',
- 'search': 'drill'
+
+ it('should expect correct host', function() {
+ const syncs = spec.getUserSyncs({iframeEnabled: true}, [], {}, '', {});
+ const url = new URL(syncs[0].url);
+ expect(url.host).to.equal('npid.amspbs.com');
+ });
+
+ it('should expect correct pathname', function() {
+ const syncs = spec.getUserSyncs({iframeEnabled: true}, [], {}, '', {});
+ const url = new URL(syncs[0].url);
+ expect(url.pathname).to.equal('/v0/user/sync');
+ });
+
+ it('should return empty array when iframe sync option is disabled', function() {
+ const syncs = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false});
+ expect(syncs).to.be.empty;
+ });
+
+ it('should use iframe sync when iframe enabled', function() {
+ const syncs = spec.getUserSyncs({iframeEnabled: true});
+ expect(syncs).to.have.lengthOf(1);
+ expect(syncs[0].type).to.equal('iframe');
+ expect(syncs[0].url).to.equal('https://npid.amspbs.com/v0/user/sync?gdpr=0&gdpr_consent=&gpp=&gpp_sid=&us_privacy=');
+ });
+
+ it('should include GDPR params if purpose 1 is true', function() {
+ const consentString = 'CQO03QAQO03QAPoABABGBiEIAIAAAIAAAACQKSwAQKSgpLABApKAAAAA.QKSwAQKSgAAA.IAAA'; // purpose 1 true
+ const gdprConsent = {
+ gdprApplies: true,
+ consentString: consentString,
+ vendorData: {
+ purpose: {
+ consents: {
+ 1: true
+ }
+ }
}
};
- const request = spec.buildRequests(validBidRequests, bidderRequest);
- const payload = JSON.parse(request.data);
- expect(payload.imp[0].ext.newspassid.customData[0].targeting.name).to.equal('example_ortb2_name');
- expect(payload.user.ext).to.not.have.property('gender');
- });
- it('should add ortb2 site data when there is no customData already created', function () {
- let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest));
- bidderRequest.ortb2 = {
- 'site': {
- 'name': 'example_ortb2_name',
- 'domain': 'page.example.com',
- 'cat': ['IAB2'],
- 'sectioncat': ['IAB2-2'],
- 'pagecat': ['IAB2-2'],
- 'page': 'https://page.example.com/here.html',
- 'ref': 'https://ref.example.com',
- 'keywords': 'power tools, drills',
- 'search': 'drill'
+ const syncs = spec.getUserSyncs({iframeEnabled: true}, [], gdprConsent);
+ const url = new URL(syncs[0].url);
+ expect(url.searchParams.get('gdpr')).to.equal('1');
+ expect(url.searchParams.get('gdpr_consent')).to.equal(encodeURIComponent(consentString));
+ });
+
+ it('should disable user sync when purpose 1 is false', function() {
+ const consentString = 'CQO03QAQO03QAPoABABGBiEIAHAAAHAAAACQKSwAQKSgpLABApKAAAAA.QKSwAQKSgAAA.IAAA'; // purpose 1 false
+ const gdprConsent = {
+ gdprApplies: true,
+ consentString: consentString,
+ vendorData: {
+ purpose: {
+ consents: {
+ 1: false
+ }
+ }
}
};
- const request = spec.buildRequests(validBidRequestsNoCustomData, bidderRequest);
- const payload = JSON.parse(request.data);
- expect(payload.imp[0].ext.newspassid.customData[0].targeting.name).to.equal('example_ortb2_name');
- expect(payload.imp[0].ext.newspassid.customData[0].targeting).to.not.have.property('gender')
- });
- it('should add ortb2 user data to the user object', function () {
- let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest));
- bidderRequest.ortb2 = {
- 'user': {
- 'gender': 'I identify as a box of rocks'
- }
+ const syncs = spec.getUserSyncs({iframeEnabled: true}, [], gdprConsent);
+ expect(syncs).to.be.empty;
+ });
+
+ it('should include correct us_privacy param', function() {
+ const uspConsent = '1YNN';
+ const syncs = spec.getUserSyncs({iframeEnabled: true}, [], {}, uspConsent, {});
+ const url = new URL(syncs[0].url);
+ expect(url.searchParams.get('gdpr')).to.equal('0');
+ expect(url.searchParams.get('gdpr_consent')).to.equal('');
+ expect(url.searchParams.get('gpp')).to.equal('');
+ expect(url.searchParams.get('gpp_sid')).to.equal('');
+ expect(url.searchParams.get('us_privacy')).to.equal(uspConsent);
+ });
+
+ it('should include correct GPP params', function() {
+ const gppConsentString = 'DBABMA~1YNN';
+ const gppSections = '2,6';
+ const gppConsent = {
+ gppApplies: true,
+ gppString: gppConsentString,
+ applicableSections: gppSections
};
- const request = spec.buildRequests(validBidRequests, bidderRequest);
- const payload = JSON.parse(request.data);
- expect(payload.user.gender).to.equal('I identify as a box of rocks');
- });
- it('handles schain object in each bidrequest (will be the same in each br)', function () {
- let br = JSON.parse(JSON.stringify(validBidRequests));
- let schainConfigObject = {
- 'ver': '1.0',
- 'complete': 1,
- 'nodes': [
- {
- 'asi': 'bidderA.com',
- 'sid': '00001',
- 'hp': 1
+ const syncs = spec.getUserSyncs({iframeEnabled: true}, [], {}, '', gppConsent);
+ const url = new URL(syncs[0].url);
+ expect(url.searchParams.get('gdpr')).to.equal('0');
+ expect(url.searchParams.get('gdpr_consent')).to.equal('');
+ expect(url.searchParams.get('gpp')).to.equal(encodeURIComponent(gppConsentString));
+ expect(url.searchParams.get('gpp_sid')).to.equal(encodeURIComponent(gppSections));
+ expect(url.searchParams.get('us_privacy')).to.equal('');
+ });
+
+ it('should include publisher param when publisherId is set in config', function() {
+ config.setConfig({
+ newspassid: {
+ publisherId: TEST_PUBLISHER_ID
+ }
+ });
+ const syncs = spec.getUserSyncs({iframeEnabled: true});
+ const url = new URL(syncs[0].url);
+ expect(url.searchParams.get('gdpr')).to.equal('0');
+ expect(url.searchParams.get('gdpr_consent')).to.equal('');
+ expect(url.searchParams.get('gpp')).to.equal('');
+ expect(url.searchParams.get('gpp_sid')).to.equal('');
+ expect(url.searchParams.get('us_privacy')).to.equal('');
+ expect(url.searchParams.get('publisher')).to.equal(encodeURIComponent(TEST_PUBLISHER_ID));
+ });
+
+ it('should have zero user syncs if coppa is true', function() {
+ config.setConfig({coppa: true});
+ const syncs = spec.getUserSyncs({iframeEnabled: true});
+ expect(syncs).to.be.empty;
+ });
+
+ it('should include all params when all are present', function() {
+ const consentString = 'CQO03QAQO03QAPoABABGBiEIAIAAAIAAAACQKSwAQKSgpLABApKAAAAA.QKSwAQKSgAAA.IAAA'; // purpose 1 true
+ const gdprConsent = {
+ gdprApplies: true,
+ consentString: consentString,
+ vendorData: {
+ purpose: {
+ consents: {
+ 1: true
+ }
}
- ]
+ }
};
- br[0]['schain'] = schainConfigObject;
- const request = spec.buildRequests(br, validBidderRequest);
- const data = JSON.parse(request.data);
- expect(data.source.ext).to.haveOwnProperty('schain');
- expect(data.source.ext.schain).to.deep.equal(schainConfigObject); // .deep.equal() : Target object deeply (but not strictly) equals `{a: 1}`
- });
- });
- describe('interpretResponse', function () {
- it('should build bid array', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- const result = spec.interpretResponse(validResponse, request);
- expect(result.length).to.equal(1);
- });
- it('should have all relevant fields', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- const result = spec.interpretResponse(validResponse, request);
- const bid = result[0];
- expect(bid.cpm).to.equal(validResponse.body.seatbid[0].bid[0].cpm);
- expect(bid.width).to.equal(validResponse.body.seatbid[0].bid[0].width);
- expect(bid.height).to.equal(validResponse.body.seatbid[0].bid[0].height);
- });
- it('should build bid array with usp/CCPA', function () {
- let validBR = JSON.parse(JSON.stringify(validBidderRequest));
- validBR.uspConsent = '1YNY';
- const request = spec.buildRequests(validBidRequests, validBR);
- const payload = JSON.parse(request.data);
- expect(payload.user.ext.uspConsent).not.to.exist;
- expect(payload.regs.ext.us_privacy).to.equal('1YNY');
- });
- it('should fail ok if no seatbid in server response', function () {
- const result = spec.interpretResponse({}, {});
- expect(result).to.be.an('array');
- expect(result).to.be.empty;
- });
- it('should fail ok if seatbid is not an array', function () {
- const result = spec.interpretResponse({'body': {'seatbid': 'nothing_here'}}, {});
- expect(result).to.be.an('array');
- expect(result).to.be.empty;
- });
- it('should correctly parse response where there are more bidders than ad slots', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- const result = spec.interpretResponse(validBidResponse1adWith2Bidders, request);
- expect(result.length).to.equal(2);
- });
- it('should have a ttl of 600', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- const result = spec.interpretResponse(validResponse, request);
- expect(result[0].ttl).to.equal(300);
- });
- it('should handle a valid whitelist, removing items not on the list & leaving others', function () {
- config.setConfig({'newspassid': {'np_whitelist_adserver_keys': ['np_appnexus_crid', 'np_appnexus_adId']}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- const result = spec.interpretResponse(validResponse, request);
- expect(utils.deepAccess(result[0].adserverTargeting, 'np_appnexus_adv')).to.be.undefined;
- expect(utils.deepAccess(result[0].adserverTargeting, 'np_appnexus_adId')).to.equal('2899ec066a91ff8-0-np-0');
- config.resetConfig();
- });
- it('should ignore a whitelist if enhancedAdserverTargeting is false', function () {
- config.setConfig({'newspassid': {'np_whitelist_adserver_keys': ['np_appnexus_crid', 'np_appnexus_imp_id'], 'enhancedAdserverTargeting': false}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- const result = spec.interpretResponse(validResponse, request);
- expect(utils.deepAccess(result[0].adserverTargeting, 'np_appnexus_adv')).to.be.undefined;
- expect(utils.deepAccess(result[0].adserverTargeting, 'np_appnexus_imp_id')).to.be.undefined;
- config.resetConfig();
- });
- it('should correctly handle enhancedAdserverTargeting being false', function () {
- config.setConfig({'newspassid': {'enhancedAdserverTargeting': false}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- const result = spec.interpretResponse(validResponse, request);
- expect(utils.deepAccess(result[0].adserverTargeting, 'np_appnexus_adv')).to.be.undefined;
- expect(utils.deepAccess(result[0].adserverTargeting, 'np_appnexus_imp_id')).to.be.undefined;
- config.resetConfig();
- });
- it('should add unique adId values to each bid', function() {
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- let validres = JSON.parse(JSON.stringify(validResponse2BidsSameAdunit));
- const result = spec.interpretResponse(validres, request);
- expect(result.length).to.equal(1);
- expect(result[0]['price']).to.equal(0.9);
- expect(result[0]['adserverTargeting']['np_npappnexus_adId']).to.equal('2899ec066a91ff8-0-np-1');
- });
- it('should add np_auc_id (response id value)', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest);
- let validres = JSON.parse(JSON.stringify(validBidResponse1adWith2Bidders));
- const result = spec.interpretResponse(validres, request);
- expect(utils.deepAccess(result[0].adserverTargeting, 'np_auc_id')).to.equal(validBidResponse1adWith2Bidders.body.id);
- });
- it('should correctly process an auction with 2 adunits & multiple bidders one of which bids for both adslots', function() {
- let validres = JSON.parse(JSON.stringify(multiResponse1));
- let request = spec.buildRequests(multiRequest1, multiBidderRequest1.bidderRequest);
- let result = spec.interpretResponse(validres, request);
- expect(result.length).to.equal(4); // one of the 5 bids will have been removed
- expect(result[1]['price']).to.equal(0.521);
- expect(result[1]['impid']).to.equal('3025f169863b7f8');
- expect(result[1]['id']).to.equal('18552976939844999');
- expect(result[1]['adserverTargeting']['np_npappnexus_adId']).to.equal('3025f169863b7f8-0-np-2');
- validres = JSON.parse(JSON.stringify(multiResponse1));
- validres.body.seatbid[0].bid[1].price = 1.1;
- validres.body.seatbid[0].bid[1].cpm = 1.1;
- request = spec.buildRequests(multiRequest1, multiBidderRequest1.bidderRequest);
- result = spec.interpretResponse(validres, request);
- expect(result[1]['price']).to.equal(1.1);
- expect(result[1]['impid']).to.equal('3025f169863b7f8');
- expect(result[1]['id']).to.equal('18552976939844681');
- expect(result[1]['adserverTargeting']['np_npappnexus_adId']).to.equal('3025f169863b7f8-0-np-1');
- });
- });
- describe('userSyncs', function () {
- it('should fail gracefully if no server response', function () {
- const result = spec.getUserSyncs('bad', false, emptyObject);
- expect(result).to.be.empty;
- });
- it('should fail gracefully if server response is empty', function () {
- const result = spec.getUserSyncs('bad', [], emptyObject);
- expect(result).to.be.empty;
- });
- it('should append the various values if they exist', function() {
- spec.buildRequests(validBidRequests, validBidderRequest);
- const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', emptyObject);
- expect(result).to.be.an('array');
- expect(result[0].url).to.include('publisherId=9876abcd12-3');
- expect(result[0].url).to.include('siteId=1234567890');
- });
- it('should append ccpa (usp data)', function() {
- spec.buildRequests(validBidRequests, validBidderRequest);
- const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', emptyObject, '1YYN');
- expect(result).to.be.an('array');
- expect(result[0].url).to.include('usp_consent=1YYN');
- });
- it('should use "" if no usp is sent to cookieSync', function() {
- spec.buildRequests(validBidRequests, validBidderRequest);
- const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', emptyObject);
- expect(result).to.be.an('array');
- expect(result[0].url).to.include('usp_consent=&');
- });
- });
- describe('default size', function () {
- it('should should return default sizes if no obj is sent', function () {
- let obj = '';
- const result = defaultSize(obj);
- expect(result.defaultHeight).to.equal(250);
- expect(result.defaultWidth).to.equal(300);
- });
- });
- describe('getGranularityKeyName', function() {
- it('should return a string granularity as-is', function() {
- const result = getGranularityKeyName('', 'this is it', '');
- expect(result).to.equal('this is it');
- });
- it('should return "custom" for a mediaTypeGranularity object', function() {
- const result = getGranularityKeyName('', {}, '');
- expect(result).to.equal('custom');
- });
- it('should return "custom" for a mediaTypeGranularity object', function() {
- const result = getGranularityKeyName('', false, 'string buckets');
- expect(result).to.equal('string buckets');
- });
- });
- describe('getGranularityObject', function() {
- it('should return an object as-is', function() {
- const result = getGranularityObject('', {'name': 'mark'}, '', '');
- expect(result.name).to.equal('mark');
- });
- it('should return an object as-is', function() {
- const result = getGranularityObject('', false, 'custom', {'name': 'rupert'});
- expect(result.name).to.equal('rupert');
- });
- });
- describe('blockTheRequest', function() {
- it('should return true if np_request is false', function() {
- config.setConfig({'newspassid': {'np_request': false}});
- let result = spec.blockTheRequest();
- expect(result).to.be.true;
- config.resetConfig();
- });
- it('should return false if np_request is true', function() {
- config.setConfig({'newspassid': {'np_request': true}});
- let result = spec.blockTheRequest();
- expect(result).to.be.false;
- config.resetConfig();
- });
- });
- describe('getPageId', function() {
- it('should return the same Page ID for multiple calls', function () {
- let result = spec.getPageId();
- expect(result).to.be.a('string');
- let result2 = spec.getPageId();
- expect(result2).to.equal(result);
- });
- });
- describe('getBidRequestForBidId', function() {
- it('should locate a bid inside a bid array', function () {
- let result = spec.getBidRequestForBidId('2899ec066a91ff8', validBidRequestsMulti);
- expect(result.testId).to.equal(1);
- result = spec.getBidRequestForBidId('2899ec066a91ff0', validBidRequestsMulti);
- expect(result.testId).to.equal(2);
- });
- });
- describe('removeSingleBidderMultipleBids', function() {
- it('should remove the multi bid by npappnexus for adslot 2d30e86db743a8', function() {
- let validres = JSON.parse(JSON.stringify(multiResponse1));
- expect(validres.body.seatbid[0].bid.length).to.equal(3);
- expect(validres.body.seatbid[0].seat).to.equal('npappnexus');
- let response = spec.removeSingleBidderMultipleBids(validres.body.seatbid);
- expect(response.length).to.equal(2);
- expect(response[0].bid.length).to.equal(2);
- expect(response[0].seat).to.equal('npappnexus');
- expect(response[1].bid.length).to.equal(2);
+ const uspConsent = '1YNN';
+ const gppConsentString = 'DBABMA~1YNN';
+ const gppSections = '2,6';
+ const gppConsent = {
+ gppApplies: true,
+ gppString: gppConsentString,
+ applicableSections: gppSections
+ };
+ config.setConfig({
+ newspassid: {
+ publisherId: TEST_PUBLISHER_ID
+ }
+ });
+ const syncs = spec.getUserSyncs({iframeEnabled: true}, [], gdprConsent, uspConsent, gppConsent);
+ const url = new URL(syncs[0].url);
+ expect(url.searchParams.get('gdpr')).to.equal('1');
+ expect(url.searchParams.get('gdpr_consent')).to.equal(encodeURIComponent(consentString));
+ expect(url.searchParams.get('gpp')).to.equal(encodeURIComponent(gppConsentString));
+ expect(url.searchParams.get('gpp_sid')).to.equal(encodeURIComponent(gppSections));
+ expect(url.searchParams.get('us_privacy')).to.equal(encodeURIComponent(uspConsent));
+ expect(url.searchParams.get('publisher')).to.equal(encodeURIComponent(TEST_PUBLISHER_ID));
});
});
});