diff --git a/modules/ozoneBidAdapter.js b/modules/ozoneBidAdapter.js index 928344be74f..8ada9d59ae2 100644 --- a/modules/ozoneBidAdapter.js +++ b/modules/ozoneBidAdapter.js @@ -11,17 +11,16 @@ const ORIGIN = 'https://elb.the-ozone-project.com' // applies only to auction & const AUCTIONURI = '/openrtb2/auction'; const OZONECOOKIESYNC = '/static/load-cookie.html'; const OZONE_RENDERER_URL = 'https://prebid.the-ozone-project.com/ozone-renderer.js'; -const ORIGIN_DEV = 'https://test.ozpr.net'; -const OZONEVERSION = '2.6.0'; +const OZONEVERSION = '2.5.0'; export const spec = { gvlid: 524, - aliases: [{code: 'lmc', gvlid: 524}, {code: 'newspassid', gvlid: 524}], + aliases: [{ code: 'lmc' }], version: OZONEVERSION, code: BIDDER_CODE, supportedMediaTypes: [VIDEO, BANNER], - cookieSyncBag: {publisherId: null, siteId: null, userIdObject: {}}, // variables we want to make available to cookie sync - propertyBag: {pageId: null, buildRequestsStart: 0, buildRequestsEnd: 0, endpointOverride: null}, /* allow us to store vars in instance scope - needs to be an object to be mutable */ + cookieSyncBag: {'publisherId': null, 'siteId': null, 'userIdObject': {}}, // variables we want to make available to cookie sync + propertyBag: {'pageId': null, 'buildRequestsStart': 0, 'buildRequestsEnd': 0}, /* allow us to store vars in instance scope - needs to be an object to be mutable */ whitelabel_defaults: { 'logId': 'OZONE', 'bidder': 'ozone', @@ -41,45 +40,19 @@ export const spec = { this.propertyBag.whitelabel.logId = bidder.toUpperCase(); this.propertyBag.whitelabel.bidder = bidder; let bidderConfig = config.getConfig(bidder) || {}; - utils.logInfo('got bidderConfig: ', JSON.parse(JSON.stringify(bidderConfig))); if (bidderConfig.kvpPrefix) { this.propertyBag.whitelabel.keyPrefix = bidderConfig.kvpPrefix; } - let arr = this.getGetParametersAsObject(); if (bidderConfig.endpointOverride) { if (bidderConfig.endpointOverride.origin) { - this.propertyBag.endpointOverride = bidderConfig.endpointOverride.origin; this.propertyBag.whitelabel.auctionUrl = bidderConfig.endpointOverride.origin + AUCTIONURI; this.propertyBag.whitelabel.cookieSyncUrl = bidderConfig.endpointOverride.origin + OZONECOOKIESYNC; } - if (arr.hasOwnProperty('renderer')) { - if (arr.renderer.match('%3A%2F%2F')) { - this.propertyBag.whitelabel.rendererUrl = decodeURIComponent(arr['renderer']); - } else { - this.propertyBag.whitelabel.rendererUrl = arr['renderer']; - } - } else if (bidderConfig.endpointOverride.rendererUrl) { + if (bidderConfig.endpointOverride.rendererUrl) { this.propertyBag.whitelabel.rendererUrl = bidderConfig.endpointOverride.rendererUrl; } - if (bidderConfig.endpointOverride.cookieSyncUrl) { - this.propertyBag.whitelabel.cookieSyncUrl = bidderConfig.endpointOverride.cookieSyncUrl; - } - if (bidderConfig.endpointOverride.auctionUrl) { - this.propertyBag.endpointOverride = bidderConfig.endpointOverride.auctionUrl; - this.propertyBag.whitelabel.auctionUrl = bidderConfig.endpointOverride.auctionUrl; - } } - try { - if (arr.hasOwnProperty('auction') && arr.auction === 'dev') { - utils.logInfo('GET: auction=dev'); - this.propertyBag.whitelabel.auctionUrl = ORIGIN_DEV + AUCTIONURI; - } - if (arr.hasOwnProperty('cookiesync') && arr.cookiesync === 'dev') { - utils.logInfo('GET: cookiesync=dev'); - this.propertyBag.whitelabel.cookieSyncUrl = ORIGIN_DEV + OZONECOOKIESYNC; - } - } catch (e) {} - utils.logInfo('set propertyBag.whitelabel to', this.propertyBag.whitelabel); + this.logInfo('set propertyBag.whitelabel to', this.propertyBag.whitelabel); }, getAuctionUrl() { return this.propertyBag.whitelabel.auctionUrl; @@ -90,6 +63,27 @@ export const spec = { getRendererUrl() { return this.propertyBag.whitelabel.rendererUrl; }, + /** + * wrappers for this.logInfo logWarn & logError, to add the proper prefix + */ + logInfo() { + if (!this.propertyBag.whitelabel) { return; } + let args = arguments; + args[0] = `${this.propertyBag.whitelabel.logId}: ${arguments[0]}`; + utils.logInfo.apply(this, args); + }, + logError() { + if (!this.propertyBag.whitelabel) { return; } + let args = arguments; + args[0] = `${this.propertyBag.whitelabel.logId}: ${arguments[0]}`; + utils.logError.apply(this, args); + }, + logWarn() { + if (!this.propertyBag.whitelabel) { return; } + let args = arguments; + args[0] = `${this.propertyBag.whitelabel.logId}: ${arguments[0]}`; + utils.logWarn.apply(this, args); + }, /** * Basic check to see whether required parameters are in the request. * @param bid @@ -97,62 +91,62 @@ export const spec = { */ isBidRequestValid(bid) { this.loadWhitelabelData(bid); - utils.logInfo('isBidRequestValid : ', config.getConfig(), bid); + this.logInfo('isBidRequestValid : ', config.getConfig(), bid); let adUnitCode = bid.adUnitCode; // adunit[n].code if (!(bid.params.hasOwnProperty('placementId'))) { - utils.logError('VALIDATION FAILED : missing placementId : siteId, placementId and publisherId are REQUIRED', adUnitCode); + this.logError('BID ADAPTER VALIDATION FAILED : missing placementId : siteId, placementId and publisherId are REQUIRED', adUnitCode); return false; } if (!this.isValidPlacementId(bid.params.placementId)) { - utils.logError('VALIDATION FAILED : placementId must be exactly 10 numeric characters', adUnitCode); + this.logError('BID ADAPTER VALIDATION FAILED : placementId must be exactly 10 numeric characters', adUnitCode); return false; } if (!(bid.params.hasOwnProperty('publisherId'))) { - utils.logError('VALIDATION FAILED : missing publisherId : siteId, placementId and publisherId are REQUIRED', adUnitCode); + this.logError('BID ADAPTER VALIDATION FAILED : missing publisherId : siteId, placementId and publisherId are REQUIRED', adUnitCode); return false; } if (!(bid.params.publisherId).toString().match(/^[a-zA-Z0-9\-]{12}$/)) { - utils.logError('VALIDATION FAILED : publisherId must be exactly 12 alphanumieric characters including hyphens', adUnitCode); + this.logError('BID ADAPTER VALIDATION FAILED : publisherId must be exactly 12 alphanumieric characters including hyphens', adUnitCode); return false; } if (!(bid.params.hasOwnProperty('siteId'))) { - utils.logError('VALIDATION FAILED : missing siteId : siteId, placementId and publisherId are REQUIRED', adUnitCode); + this.logError('BID ADAPTER VALIDATION FAILED : missing siteId : siteId, placementId and publisherId are REQUIRED', adUnitCode); return false; } if (!(bid.params.siteId).toString().match(/^[0-9]{10}$/)) { - utils.logError('VALIDATION FAILED : siteId must be exactly 10 numeric characters', adUnitCode); + this.logError('BID ADAPTER VALIDATION FAILED : siteId must be exactly 10 numeric characters', adUnitCode); return false; } if (bid.params.hasOwnProperty('customParams')) { - utils.logError('VALIDATION FAILED : customParams should be renamed to customData', adUnitCode); + this.logError('BID ADAPTER VALIDATION FAILED : customParams should be renamed to customData', adUnitCode); return false; } if (bid.params.hasOwnProperty('customData')) { if (!Array.isArray(bid.params.customData)) { - utils.logError('VALIDATION FAILED : customData is not an Array', adUnitCode); + this.logError('BID ADAPTER VALIDATION FAILED : customData is not an Array', adUnitCode); return false; } if (bid.params.customData.length < 1) { - utils.logError('VALIDATION FAILED : customData is an array but does not contain any elements', adUnitCode); + this.logError('BID ADAPTER VALIDATION FAILED : customData is an array but does not contain any elements', adUnitCode); return false; } if (!(bid.params.customData[0]).hasOwnProperty('targeting')) { - utils.logError('VALIDATION FAILED : customData[0] does not contain "targeting"', adUnitCode); + this.logError('BID ADAPTER VALIDATION FAILED : customData[0] does not contain "targeting"', adUnitCode); return false; } if (typeof bid.params.customData[0]['targeting'] != 'object') { - utils.logError('VALIDATION FAILED : customData[0] targeting is not an object', adUnitCode); + this.logError('BID ADAPTER VALIDATION FAILED : customData[0] targeting is not an object', adUnitCode); return false; } } if (bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(VIDEO)) { if (!bid.mediaTypes[VIDEO].hasOwnProperty('context')) { - utils.logError('No video context key/value in bid. Rejecting bid: ', bid); + this.logError('No video context key/value in bid. Rejecting bid: ', bid); return false; } if (bid.mediaTypes[VIDEO].context !== 'instream' && bid.mediaTypes[VIDEO].context !== 'outstream') { - utils.logError('video.context is invalid. Only instream/outstream video is supported. Rejecting bid: ', bid); + this.logError('video.context is invalid. Only instream/outstream video is supported. Rejecting bid: ', bid); return false; } } @@ -172,7 +166,7 @@ export const spec = { this.propertyBag.buildRequestsStart = new Date().getTime(); let whitelabelBidder = this.propertyBag.whitelabel.bidder; // by default = ozone let whitelabelPrefix = this.propertyBag.whitelabel.keyPrefix; - utils.logInfo(`buildRequests time: ${this.propertyBag.buildRequestsStart} v ${OZONEVERSION} validBidRequests`, JSON.parse(JSON.stringify(validBidRequests)), 'bidderRequest', JSON.parse(JSON.stringify(bidderRequest))); + this.logInfo(`buildRequests time: ${this.propertyBag.buildRequestsStart} v ${OZONEVERSION} validBidRequests`, JSON.parse(JSON.stringify(validBidRequests)), 'bidderRequest', JSON.parse(JSON.stringify(bidderRequest))); // First check - is there any config to block this request? if (this.blockTheRequest()) { return []; @@ -184,20 +178,26 @@ export const spec = { this.cookieSyncBag.publisherId = utils.deepAccess(validBidRequests[0], 'params.publisherId'); htmlParams = validBidRequests[0].params; } - utils.logInfo('cookie sync bag', this.cookieSyncBag); + this.logInfo('cookie sync bag', this.cookieSyncBag); let singleRequest = this.getWhitelabelConfigItem('ozone.singleRequest'); singleRequest = singleRequest !== false; // undefined & true will be true - utils.logInfo(`config ${whitelabelBidder}.singleRequest : `, singleRequest); + this.logInfo(`config ${whitelabelBidder}.singleRequest : `, singleRequest); let ozoneRequest = {}; // we only want to set specific properties on this, not validBidRequests[0].params delete ozoneRequest.test; // don't allow test to be set in the config - ONLY use $_GET['pbjs_debug'] - // First party data module : look for ortb2 in setconfig & set the User object. NOTE THAT this should happen before we set the consentString - let fpd = config.getConfig('ortb2'); - if (fpd && utils.deepAccess(fpd, 'user')) { - utils.logInfo('added FPD user object'); - ozoneRequest.user = fpd.user; + if (bidderRequest && bidderRequest.gdprConsent) { + this.logInfo('ADDING GDPR info'); + let apiVersion = bidderRequest.gdprConsent.apiVersion || '1'; + ozoneRequest.regs = {ext: {gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0, apiVersion: apiVersion}}; + if (ozoneRequest.regs.ext.gdpr) { + ozoneRequest.user = ozoneRequest.user || {}; + ozoneRequest.user.ext = {'consent': bidderRequest.gdprConsent.consentString}; + } else { + this.logInfo('**** Strange CMP info: bidderRequest.gdprConsent exists BUT bidderRequest.gdprConsent.gdprApplies is false. See bidderRequest logged above. ****'); + } + } else { + this.logInfo('WILL NOT ADD GDPR info; no bidderRequest.gdprConsent object was present.'); } - const getParams = this.getGetParametersAsObject(); const wlOztestmodeKey = whitelabelPrefix + 'testmode'; const isTestMode = getParams[wlOztestmodeKey] || null; // this can be any string, it's used for testing ads @@ -214,18 +214,18 @@ export const spec = { let arrBannerSizes = []; if (!ozoneBidRequest.hasOwnProperty('mediaTypes')) { if (ozoneBidRequest.hasOwnProperty('sizes')) { - utils.logInfo('no mediaTypes detected - will use the sizes array in the config root'); + this.logInfo('no mediaTypes detected - will use the sizes array in the config root'); arrBannerSizes = ozoneBidRequest.sizes; } else { - utils.logInfo('no mediaTypes detected, no sizes array in the config root either. Cannot set sizes for banner type'); + this.logInfo('no mediaTypes detected, no sizes array in the config root either. Cannot set sizes for banner type'); } } else { if (ozoneBidRequest.mediaTypes.hasOwnProperty(BANNER)) { arrBannerSizes = ozoneBidRequest.mediaTypes[BANNER].sizes; /* Note - if there is a sizes element in the config root it will be pushed into here */ - utils.logInfo('setting banner size from the mediaTypes.banner element for bidId ' + obj.id + ': ', arrBannerSizes); + this.logInfo('setting banner size from the mediaTypes.banner element for bidId ' + obj.id + ': ', arrBannerSizes); } if (ozoneBidRequest.mediaTypes.hasOwnProperty(VIDEO)) { - utils.logInfo('openrtb 2.5 compliant video'); + this.logInfo('openrtb 2.5 compliant video'); // examine all the video attributes in the config, and either put them into obj.video if allowed by IAB2.5 or else in to obj.video.ext if (typeof ozoneBidRequest.mediaTypes[VIDEO] == 'object') { let childConfig = utils.deepAccess(ozoneBidRequest, 'params.video', {}); @@ -234,33 +234,25 @@ export const spec = { } // we need to duplicate some of the video values let wh = getWidthAndHeightFromVideoObject(obj.video); - utils.logInfo('setting video object from the mediaTypes.video element: ' + obj.id + ':', obj.video, 'wh=', wh); + this.logInfo('setting video object from the mediaTypes.video element: ' + obj.id + ':', obj.video, 'wh=', wh); if (wh && typeof wh === 'object') { obj.video.w = wh['w']; obj.video.h = wh['h']; if (playerSizeIsNestedArray(obj.video)) { // this should never happen; it was in the original spec for this change though. - utils.logInfo('setting obj.video.format to be an array of objects'); + this.logInfo('setting obj.video.format to be an array of objects'); obj.video.ext.format = [wh]; } else { - utils.logInfo('setting obj.video.format to be an object'); + this.logInfo('setting obj.video.format to be an object'); obj.video.ext.format = wh; } } else { - utils.logWarn('cannot set w, h & format values for video; the config is not right'); + this.logWarn('cannot set w, h & format values for video; the config is not right'); } } // Native integration is not complete yet if (ozoneBidRequest.mediaTypes.hasOwnProperty(NATIVE)) { obj.native = ozoneBidRequest.mediaTypes[NATIVE]; - utils.logInfo('setting native object from the mediaTypes.native element: ' + obj.id + ':', obj.native); - } - // is the publisher specifying floors, and is the floors module enabled? - if (ozoneBidRequest.hasOwnProperty('getFloor')) { - utils.logInfo('This bidRequest object has property: getFloor'); - obj.floor = this.getFloorObjectForAuction(ozoneBidRequest); - utils.logInfo('obj.floor is : ', obj.floor); - } else { - utils.logInfo('This bidRequest object DOES NOT have property: getFloor'); + this.logInfo('setting native object from the mediaTypes.native element: ' + obj.id + ':', obj.native); } } if (arrBannerSizes.length > 0) { @@ -276,18 +268,17 @@ export const spec = { } // these 3 MUST exist - we check them in the validation method obj.placementId = placementId; - // build the imp['ext'] object - NOTE - Dont obliterate anything that' already in obj.ext - utils.deepSetValue(obj, 'ext.prebid', {'storedrequest': {'id': placementId}}); - // obj.ext = {'prebid': {'storedrequest': {'id': placementId}}}; + // build the imp['ext'] object + obj.ext = {'prebid': {'storedrequest': {'id': placementId}}}; obj.ext[whitelabelBidder] = {}; obj.ext[whitelabelBidder].adUnitCode = ozoneBidRequest.adUnitCode; // eg. 'mpu' obj.ext[whitelabelBidder].transactionId = ozoneBidRequest.transactionId; // this is the transactionId PER adUnit, common across bidders for this unit if (ozoneBidRequest.params.hasOwnProperty('customData')) { obj.ext[whitelabelBidder].customData = ozoneBidRequest.params.customData; } - utils.logInfo(`obj.ext.${whitelabelBidder} is `, obj.ext[whitelabelBidder]); + this.logInfo(`obj.ext.${whitelabelBidder} is `, obj.ext[whitelabelBidder]); if (isTestMode != null) { - utils.logInfo('setting isTestMode to ', isTestMode); + this.logInfo('setting isTestMode to ', isTestMode); if (obj.ext[whitelabelBidder].hasOwnProperty('customData')) { for (let i = 0; i < obj.ext[whitelabelBidder].customData.length; i++) { obj.ext[whitelabelBidder].customData[i]['targeting'][wlOztestmodeKey] = isTestMode; @@ -297,19 +288,6 @@ export const spec = { obj.ext[whitelabelBidder].customData[0].targeting[wlOztestmodeKey] = isTestMode; } } - if (fpd && utils.deepAccess(fpd, 'site')) { - // attach the site fpd into exactly : imp[n].ext.[whitelabel].customData.0.targeting - utils.logInfo('added FPD site object'); - if (utils.deepAccess(obj, 'ext.' + whitelabelBidder + '.customData.0.targeting', false)) { - obj.ext[whitelabelBidder].customData[0].targeting = Object.assign(obj.ext[whitelabelBidder].customData[0].targeting, fpd.site); - // let keys = utils.getKeys(fpd.site); - // for (let i = 0; i < keys.length; i++) { - // obj.ext[whitelabelBidder].customData[0].targeting[keys[i]] = fpd.site[keys[i]]; - // } - } else { - utils.deepSetValue(obj, 'ext.' + whitelabelBidder + '.customData.0.targeting', fpd.site); - } - } return obj; }); @@ -327,27 +305,20 @@ export const spec = { } extObj[whitelabelBidder].pv = this.getPageId(); // attach the page ID that will be common to all auciton calls for this page if refresh() is called let ozOmpFloorDollars = this.getWhitelabelConfigItem('ozone.oz_omp_floor'); // valid only if a dollar value (typeof == 'number') - utils.logInfo(`${whitelabelPrefix}_omp_floor dollar value = `, ozOmpFloorDollars); + this.logInfo(`${whitelabelPrefix}_omp_floor dollar value = `, ozOmpFloorDollars); if (typeof ozOmpFloorDollars === 'number') { extObj[whitelabelBidder][whitelabelPrefix + '_omp_floor'] = ozOmpFloorDollars; } else if (typeof ozOmpFloorDollars !== 'undefined') { - utils.logError(`${whitelabelPrefix}_omp_floor is invalid - IF SET then this must be a number, representing dollar value eg. ${whitelabelPrefix}_omp_floor: 1.55. You have it set as a ` + (typeof ozOmpFloorDollars)); + this.logError(`${whitelabelPrefix}_omp_floor is invalid - IF SET then this must be a number, representing dollar value eg. ${whitelabelPrefix}_omp_floor: 1.55. You have it set as a ` + (typeof ozOmpFloorDollars)); } let ozWhitelistAdserverKeys = this.getWhitelabelConfigItem('ozone.oz_whitelist_adserver_keys'); let useOzWhitelistAdserverKeys = utils.isArray(ozWhitelistAdserverKeys) && ozWhitelistAdserverKeys.length > 0; extObj[whitelabelBidder][whitelabelPrefix + '_kvp_rw'] = useOzWhitelistAdserverKeys ? 1 : 0; if (whitelabelBidder != 'ozone') { - utils.logInfo('setting aliases object'); + this.logInfo('setting aliases object'); extObj.prebid = {aliases: {'ozone': whitelabelBidder}}; } - // 20210413 - adding a set of GET params to pass to auction - if (getParams.hasOwnProperty('ozf')) { extObj[whitelabelBidder]['ozf'] = getParams.ozf == 'true' || getParams.ozf == 1 ? 1 : 0; } - if (getParams.hasOwnProperty('ozpf')) { extObj[whitelabelBidder]['ozpf'] = getParams.ozpf == 'true' || getParams.ozpf == 1 ? 1 : 0; } - if (getParams.hasOwnProperty('ozrp') && getParams.ozrp.match(/^[0-3]$/)) { extObj[whitelabelBidder]['ozrp'] = parseInt(getParams.ozrp); } - if (getParams.hasOwnProperty('ozip') && getParams.ozip.match(/^\d+$/)) { extObj[whitelabelBidder]['ozip'] = parseInt(getParams.ozip); } - if (this.propertyBag.endpointOverride != null) { extObj[whitelabelBidder]['origin'] = this.propertyBag.endpointOverride; } - // extObj.ortb2 = config.getConfig('ortb2'); // original test location var userExtEids = this.generateEids(validBidRequests); // generate the UserIDs in the correct format for UserId module ozoneRequest.site = { @@ -357,26 +328,6 @@ export const spec = { }; ozoneRequest.test = (getParams.hasOwnProperty('pbjs_debug') && getParams['pbjs_debug'] === 'true') ? 1 : 0; - // this should come as late as possible so it overrides any user.ext.consent value - if (bidderRequest && bidderRequest.gdprConsent) { - utils.logInfo('ADDING GDPR info'); - let apiVersion = utils.deepAccess(bidderRequest, 'gdprConsent.apiVersion', 1); - ozoneRequest.regs = {ext: {gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0, apiVersion: apiVersion}}; - if (utils.deepAccess(ozoneRequest, 'regs.ext.gdpr')) { - utils.deepSetValue(ozoneRequest, 'user.ext.consent', bidderRequest.gdprConsent.consentString); - } else { - utils.logInfo('**** Strange CMP info: bidderRequest.gdprConsent exists BUT bidderRequest.gdprConsent.gdprApplies is false. See bidderRequest logged above. ****'); - } - } else { - utils.logInfo('WILL NOT ADD GDPR info; no bidderRequest.gdprConsent object'); - } - if (bidderRequest && bidderRequest.uspConsent) { - utils.logInfo('ADDING CCPA info'); - utils.deepSetValue(ozoneRequest, 'user.ext.uspConsent', bidderRequest.uspConsent); - } else { - utils.logInfo('WILL NOT ADD CCPA info; no bidderRequest.uspConsent.'); - } - // this is for 2.2.1 // coppa compliance if (config.getConfig('coppa') === true) { @@ -385,7 +336,7 @@ export const spec = { // return the single request object OR the array: if (singleRequest) { - utils.logInfo('buildRequests starting to generate response for a single request'); + this.logInfo('buildRequests starting to generate response for a single request'); ozoneRequest.id = bidderRequest.auctionId; // Unique ID of the bid request, provided by the exchange. ozoneRequest.auctionId = bidderRequest.auctionId; // not sure if this should be here? ozoneRequest.imp = tosendtags; @@ -398,14 +349,14 @@ export const spec = { data: JSON.stringify(ozoneRequest), bidderRequest: bidderRequest }; - utils.logInfo('buildRequests request data for single = ', JSON.parse(JSON.stringify(ozoneRequest))); + this.logInfo('buildRequests request data for single = ', ozoneRequest); this.propertyBag.buildRequestsEnd = new Date().getTime(); - utils.logInfo(`buildRequests going to return for single at time ${this.propertyBag.buildRequestsEnd} (took ${this.propertyBag.buildRequestsEnd - this.propertyBag.buildRequestsStart}ms): `, ret); + this.logInfo(`buildRequests going to return for single at time ${this.propertyBag.buildRequestsEnd} (took ${this.propertyBag.buildRequestsEnd - this.propertyBag.buildRequestsStart}ms): `, ret); return ret; } // not single request - pull apart the tosendtags array & return an array of objects each containing one element in the imp array. let arrRet = tosendtags.map(imp => { - utils.logInfo('buildRequests starting to generate non-single response, working on imp : ', imp); + this.logInfo('buildRequests starting to generate non-single response, working on imp : ', imp); let ozoneRequestSingle = Object.assign({}, ozoneRequest); imp.ext[whitelabelBidder].pageAuctionId = bidderRequest['auctionId']; // make a note in the ext object of what the original auctionId was, in the bidderRequest object ozoneRequestSingle.id = imp.ext[whitelabelBidder].transactionId; // Unique ID of the bid request, provided by the exchange. @@ -414,7 +365,7 @@ export const spec = { ozoneRequestSingle.ext = extObj; ozoneRequestSingle.source = {'tid': imp.ext[whitelabelBidder].transactionId}; utils.deepSetValue(ozoneRequestSingle, 'user.ext.eids', userExtEids); - utils.logInfo('buildRequests RequestSingle (for non-single) = ', ozoneRequestSingle); + this.logInfo('buildRequests RequestSingle (for non-single) = ', ozoneRequestSingle); return { method: 'POST', url: this.getAuctionUrl(), @@ -423,42 +374,9 @@ export const spec = { }; }); this.propertyBag.buildRequestsEnd = new Date().getTime(); - utils.logInfo(`buildRequests going to return for non-single at time ${this.propertyBag.buildRequestsEnd} (took ${this.propertyBag.buildRequestsEnd - this.propertyBag.buildRequestsStart}ms): `, arrRet); + this.logInfo(`buildRequests going to return for non-single at time ${this.propertyBag.buildRequestsEnd} (took ${this.propertyBag.buildRequestsEnd - this.propertyBag.buildRequestsStart}ms): `, arrRet); return arrRet; }, - /** - * parse a bidRequestRef that contains getFloor(), get all the data from it for the sizes & media requested for this bid & return an object containing floor data you can send to auciton endpoint - * @param bidRequestRef object = a valid bid request object reference - * @return object - * - * call: - * bidObj.getFloor({ - currency: 'USD', <- currency to return the value in - mediaType: ‘banner’, - size: ‘*’ <- or [300,250] or [[300,250],[640,480]] - * }); - * - */ - getFloorObjectForAuction(bidRequestRef) { - const mediaTypesSizes = { - banner: utils.deepAccess(bidRequestRef, 'mediaTypes.banner.sizes', null), - video: utils.deepAccess(bidRequestRef, 'mediaTypes.video.playerSize', null), - native: utils.deepAccess(bidRequestRef, 'mediaTypes.native.image.sizes', null) - } - utils.logInfo('getFloorObjectForAuction mediaTypesSizes : ', mediaTypesSizes); - let ret = {}; - if (mediaTypesSizes.banner) { - ret.banner = bidRequestRef.getFloor({mediaType: 'banner', currency: 'USD', size: mediaTypesSizes.banner}); - } - if (mediaTypesSizes.video) { - ret.video = bidRequestRef.getFloor({mediaType: 'video', currency: 'USD', size: mediaTypesSizes.video}); - } - if (mediaTypesSizes.native) { - ret.native = bidRequestRef.getFloor({mediaType: 'native', currency: 'USD', size: mediaTypesSizes.native}); - } - utils.logInfo('getFloorObjectForAuction returning : ', JSON.parse(JSON.stringify(ret))); - return ret; - }, /** * Interpret the response if the array contains BIDDER elements, in the format: [ [bidder1 bid 1, bidder1 bid 2], [bidder2 bid 1, bidder2 bid 2] ] * NOte that in singleRequest mode this will be called once, else it will be called for each adSlot's response @@ -474,8 +392,8 @@ export const spec = { let startTime = new Date().getTime(); let whitelabelBidder = this.propertyBag.whitelabel.bidder; // by default = ozone let whitelabelPrefix = this.propertyBag.whitelabel.keyPrefix; - utils.logInfo(`interpretResponse time: ${startTime} . Time between buildRequests done and interpretResponse start was ${startTime - this.propertyBag.buildRequestsEnd}ms`); - utils.logInfo(`serverResponse, request`, JSON.parse(JSON.stringify(serverResponse)), JSON.parse(JSON.stringify(request))); + this.logInfo(`interpretResponse time: ${startTime} . Time between buildRequests done and interpretResponse start was ${startTime - this.propertyBag.buildRequestsEnd}ms`); + this.logInfo(`serverResponse, request`, JSON.parse(JSON.stringify(serverResponse)), JSON.parse(JSON.stringify(request))); serverResponse = serverResponse.body || {}; // note that serverResponse.id value is the auction_id we might want to use for reporting reasons. if (!serverResponse.hasOwnProperty('seatbid')) { @@ -486,15 +404,12 @@ export const spec = { } let arrAllBids = []; let enhancedAdserverTargeting = this.getWhitelabelConfigItem('ozone.enhancedAdserverTargeting'); - utils.logInfo('enhancedAdserverTargeting', enhancedAdserverTargeting); + this.logInfo('enhancedAdserverTargeting', enhancedAdserverTargeting); if (typeof enhancedAdserverTargeting == 'undefined') { enhancedAdserverTargeting = true; } - utils.logInfo('enhancedAdserverTargeting', enhancedAdserverTargeting); - - // 2021-03-05 - comment this out for a build without adding adid to the response + this.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 ozOmpFloorDollars = this.getWhitelabelConfigItem('ozone.oz_omp_floor'); // valid only if a dollar value (typeof == 'number') let addOzOmpFloorDollars = typeof ozOmpFloorDollars === 'number'; @@ -505,32 +420,30 @@ export const spec = { 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); - utils.logInfo(`seatbid:${i}, bid:${j} Going to set default w h for seatbid/bidRequest`, sb.bid[j], thisRequestBid); + this.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 = ozoneAddStandardProperties(sb.bid[j], defaultWidth, defaultHeight); - // prebid 4.0 compliance - thisBid.meta = {advertiserDomains: thisBid.adomain || []}; let videoContext = null; let isVideo = false; let bidType = utils.deepAccess(thisBid, 'ext.prebid.type'); - utils.logInfo(`this bid type is : ${bidType}`, j); + this.logInfo(`this bid type is : ${bidType}`, j); if (bidType === VIDEO) { isVideo = true; videoContext = this.getVideoContextForBidId(thisBid.bidId, request.bidderRequest.bids); // should be instream or outstream (or null if error) if (videoContext === 'outstream') { - utils.logInfo('going to attach a renderer to OUTSTREAM video : ', j); + this.logInfo('going to attach a renderer to OUTSTREAM video : ', j); thisBid.renderer = newRenderer(thisBid.bidId); } else { - utils.logInfo('bid is not an outstream video, will not attach a renderer: ', j); + this.logInfo('bid is not an outstream video, will not attach a renderer: ', j); } } let adserverTargeting = {}; if (enhancedAdserverTargeting) { let allBidsForThisBidid = ozoneGetAllBidsForBidId(thisBid.bidId, serverResponse.seatbid); // add all the winning & non-winning bids for this bidId: - utils.logInfo('Going to iterate allBidsForThisBidId', allBidsForThisBidid); + this.logInfo('Going to iterate allBidsForThisBidId', allBidsForThisBidid); Object.keys(allBidsForThisBidid).forEach((bidderName, index, ar2) => { - utils.logInfo(`adding adserverTargeting for ${bidderName} for bidId ${thisBid.bidId}`); + this.logInfo(`adding adserverTargeting for ${bidderName} for bidId ${thisBid.bidId}`); // let bidderName = bidderNameWH.split('_')[0]; adserverTargeting[whitelabelPrefix + '_' + bidderName] = bidderName; adserverTargeting[whitelabelPrefix + '_' + bidderName + '_crid'] = String(allBidsForThisBidid[bidderName].crid); @@ -560,27 +473,21 @@ export const spec = { }); } else { if (useOzWhitelistAdserverKeys) { - utils.logWarn(`You have set a whitelist of adserver keys but this will be ignored because ${whitelabelBidder}.enhancedAdserverTargeting is set to false. No per-bid keys will be sent to adserver.`); + this.logWarn(`You have set a whitelist of adserver keys but this will be ignored because ${whitelabelBidder}.enhancedAdserverTargeting is set to false. No per-bid keys will be sent to adserver.`); } else { - utils.logInfo(`${whitelabelBidder}.enhancedAdserverTargeting is set to false, so no per-bid keys will be sent to adserver.`); + this.logInfo(`${whitelabelBidder}.enhancedAdserverTargeting is set to false, so no per-bid keys will be sent to adserver.`); } } // also add in the winning bid, to be sent to dfp let {seat: winningSeat, bid: winningBid} = ozoneGetWinnerForRequestBid(thisBid.bidId, serverResponse.seatbid); adserverTargeting[whitelabelPrefix + '_auc_id'] = String(request.bidderRequest.auctionId); adserverTargeting[whitelabelPrefix + '_winner'] = String(winningSeat); - adserverTargeting[whitelabelPrefix + '_bid'] = 'true'; - if (enhancedAdserverTargeting) { adserverTargeting[whitelabelPrefix + '_imp_id'] = String(winningBid.impid); adserverTargeting[whitelabelPrefix + '_pb_v'] = OZONEVERSION; - adserverTargeting[whitelabelPrefix + '_pb'] = winningBid.price; - adserverTargeting[whitelabelPrefix + '_pb_r'] = getRoundedBid(winningBid.price, bidType); - adserverTargeting[whitelabelPrefix + '_adId'] = String(winningBid.adId); - adserverTargeting[whitelabelPrefix + '_size'] = `${winningBid.width}x${winningBid.height}`; } if (useOzWhitelistAdserverKeys) { // delete any un-whitelisted keys - utils.logInfo('Going to filter out adserver targeting keys not in the whitelist: ', ozWhitelistAdserverKeys); + this.logInfo('Going to filter out adserver targeting keys not in the whitelist: ', ozWhitelistAdserverKeys); Object.keys(adserverTargeting).forEach(function(key) { if (ozWhitelistAdserverKeys.indexOf(key) === -1) { delete adserverTargeting[key]; } }); } thisBid.adserverTargeting = adserverTargeting; @@ -588,7 +495,7 @@ export const spec = { } } let endTime = new Date().getTime(); - utils.logInfo(`interpretResponse going to return at time ${endTime} (took ${endTime - startTime}ms) Time from buildRequests Start -> interpretRequests End = ${endTime - this.propertyBag.buildRequestsStart}ms`, arrAllBids); + this.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; }, /** @@ -632,9 +539,8 @@ export const spec = { return ret; }, // see http://prebid.org/dev-docs/bidder-adaptor.html#registering-user-syncs - // us privacy: https://docs.prebid.org/dev-docs/modules/consentManagementUsp.html - getUserSyncs(optionsType, serverResponse, gdprConsent, usPrivacy) { - utils.logInfo('getUserSyncs optionsType', optionsType, 'serverResponse', serverResponse, 'gdprConsent', gdprConsent, 'usPrivacy', usPrivacy, 'cookieSyncBag', this.cookieSyncBag); + getUserSyncs(optionsType, serverResponse, gdprConsent) { + this.logInfo('getUserSyncs optionsType, serverResponse, gdprConsent, cookieSyncBag', optionsType, serverResponse, gdprConsent, this.cookieSyncBag); if (!serverResponse || serverResponse.length === 0) { return []; } @@ -645,13 +551,9 @@ export const spec = { } arrQueryString.push('gdpr=' + (utils.deepAccess(gdprConsent, 'gdprApplies', false) ? '1' : '0')); arrQueryString.push('gdpr_consent=' + utils.deepAccess(gdprConsent, 'consentString', '')); - arrQueryString.push('usp_consent=' + (usPrivacy || '')); - // var objKeys = Object.getOwnPropertyNames(this.cookieSyncBag.userIdObject); - // for (let idx in objKeys) { - // let keyname = objKeys[idx]; - // arrQueryString.push(keyname + '=' + this.cookieSyncBag.userIdObject[keyname]); - // } - for (let keyname in this.cookieSyncBag.userIdObject) { + var objKeys = Object.getOwnPropertyNames(this.cookieSyncBag.userIdObject); + for (let idx in objKeys) { + let keyname = objKeys[idx]; arrQueryString.push(keyname + '=' + this.cookieSyncBag.userIdObject[keyname]); } arrQueryString.push('publisherId=' + this.cookieSyncBag.publisherId); @@ -663,7 +565,7 @@ export const spec = { if (strQueryString.length > 0) { strQueryString = '?' + strQueryString; } - utils.logInfo('getUserSyncs going to return cookie sync url : ' + this.getCookieSyncUrl() + strQueryString); + this.logInfo('getUserSyncs going to return cookie sync url : ' + this.getCookieSyncUrl() + strQueryString); return [{ type: 'iframe', url: this.getCookieSyncUrl() + strQueryString @@ -698,15 +600,15 @@ export const spec = { return null; }, /** - * This is used for cookie sync, not auction call * Look for pubcid & all the other IDs according to http://prebid.org/dev-docs/modules/userId.html + * NOTE that criteortus is deprecated & should be removed asap * @return map */ findAllUserIds(bidRequest) { var ret = {}; - // @todo - what is Neustar fabrick called & where to look for it? If it's a simple value then it will automatically be ok - // it is not in the table 'Bidder Adapter Implementation' on https://docs.prebid.org/dev-docs/modules/userId.html#prebidjs-adapters - let searchKeysSingle = ['pubcid', 'tdid', 'idl_env', 'criteoId', 'lotamePanoramaId', 'fabrickId']; + // @todo - what is fabrick called & where to look for it? If it's a simple value then it will automatically be ok + let searchKeysSingle = ['pubcid', 'tdid', 'id5id', 'parrableId', 'idl_env', 'criteoId', 'criteortus', + 'sharedid', 'lotamePanoramaId', 'fabrickId']; if (bidRequest.hasOwnProperty('userId')) { for (let arrayId in searchKeysSingle) { let key = searchKeysSingle[arrayId]; @@ -714,37 +616,19 @@ export const spec = { if (typeof (bidRequest.userId[key]) == 'string') { ret[key] = bidRequest.userId[key]; } else if (typeof (bidRequest.userId[key]) == 'object') { - utils.logError(`WARNING: findAllUserIds had to use first key in user object to get value for bid.userId key: ${key}. Prebid adapter should be updated.`); - // fallback - get the value of the first key in the object; this is NOT desirable behaviour ret[key] = bidRequest.userId[key][Object.keys(bidRequest.userId[key])[0]]; // cannot use Object.values } else { - utils.logError(`failed to get string key value for userId : ${key}`); + this.logError(`failed to get string key value for userId : ${key}`); } } } - let lipbid = utils.deepAccess(bidRequest.userId, 'lipb.lipbid'); + var lipbid = utils.deepAccess(bidRequest.userId, 'lipb.lipbid'); if (lipbid) { ret['lipb'] = {'lipbid': lipbid}; } - let id5id = utils.deepAccess(bidRequest.userId, 'id5id.uid'); - if (id5id) { - ret['id5id'] = id5id; - } - let parrableId = utils.deepAccess(bidRequest.userId, 'parrableId.eid'); - if (parrableId) { - ret['parrableId'] = parrableId; - } - let sharedid = utils.deepAccess(bidRequest.userId, 'sharedid.id'); - if (sharedid) { - ret['sharedid'] = sharedid; - } - let sharedidthird = utils.deepAccess(bidRequest.userId, 'sharedid.third'); - if (sharedidthird) { - ret['sharedidthird'] = sharedidthird; - } } if (!ret.hasOwnProperty('pubcid')) { - let pubcid = utils.deepAccess(bidRequest, 'crumbs.pubcid'); + var pubcid = utils.deepAccess(bidRequest, 'crumbs.pubcid'); if (pubcid) { ret['pubcid'] = pubcid; // if built with old pubCommonId module } @@ -770,10 +654,10 @@ export const spec = { let arr = this.getGetParametersAsObject(); if (arr.hasOwnProperty(whitelabelPrefix + 'storedrequest')) { if (this.isValidPlacementId(arr[whitelabelPrefix + 'storedrequest'])) { - utils.logInfo(`using GET ${whitelabelPrefix}storedrequest ` + arr[whitelabelPrefix + 'storedrequest'] + ' to replace placementId'); + this.logInfo(`using GET ${whitelabelPrefix}storedrequest ` + arr[whitelabelPrefix + 'storedrequest'] + ' to replace placementId'); return arr[whitelabelPrefix + 'storedrequest']; } else { - utils.logError(`GET ${whitelabelPrefix}storedrequest FAILED VALIDATION - will not use it`); + this.logError(`GET ${whitelabelPrefix}storedrequest FAILED VALIDATION - will not use it`); } } return null; @@ -833,7 +717,7 @@ export const spec = { // if there is an ozone.oz_request = false then quit now. let ozRequest = this.getWhitelabelConfigItem('ozone.oz_request'); if (typeof ozRequest == 'boolean' && !ozRequest) { - utils.logWarn(`Will not allow auction : ${this.propertyBag.whitelabel.keyPrefix}one.${this.propertyBag.whitelabel.keyPrefix}_request is set to false`); + this.logWarn(`Will not allow auction : ${this.propertyBag.whitelabel.keyPrefix}one.${this.propertyBag.whitelabel.keyPrefix}_request is set to false`); return true; } return false; @@ -931,13 +815,13 @@ export const spec = { * @returns seatbid object */ export function injectAdIdsIntoAllBidResponses(seatbid) { - utils.logInfo('injectAdIdsIntoAllBidResponses', seatbid); + spec.logInfo('injectAdIdsIntoAllBidResponses', seatbid); for (let i = 0; i < seatbid.length; i++) { let sb = seatbid[i]; for (let j = 0; j < sb.bid.length; j++) { // modify the bidId per-bid, so each bid has a unique adId within this response, and dfp can select one. // 2020-06 we now need a second level of ID because there might be multiple identical impid's within a seatbid! - sb.bid[j]['adId'] = `${sb.bid[j]['impid']}-${i}-${spec.propertyBag.whitelabel.keyPrefix}-${j}`; + sb.bid[j]['adId'] = `${sb.bid[j]['impid']}-${i}-${j}`; } } return seatbid; @@ -957,7 +841,7 @@ export function checkDeepArray(Arr) { export function defaultSize(thebidObj) { if (!thebidObj) { - utils.logInfo('defaultSize received empty bid obj! going to return fixed default size'); + spec.logInfo('defaultSize received empty bid obj! going to return fixed default size'); return { 'defaultHeight': 250, 'defaultWidth': 300 @@ -1035,14 +919,14 @@ export function getRoundedBid(price, mediaType) { let theConfigObject = getGranularityObject(mediaType, mediaTypeGranularity, strBuckets, objBuckets); let theConfigKey = getGranularityKeyName(mediaType, mediaTypeGranularity, strBuckets); - utils.logInfo('getRoundedBid. price:', price, 'mediaType:', mediaType, 'configkey:', theConfigKey, 'configObject:', theConfigObject, 'mediaTypeGranularity:', mediaTypeGranularity, 'strBuckets:', strBuckets); + spec.logInfo('getRoundedBid. price:', price, 'mediaType:', mediaType, 'configkey:', theConfigKey, 'configObject:', theConfigObject, 'mediaTypeGranularity:', mediaTypeGranularity, 'strBuckets:', strBuckets); let priceStringsObj = getPriceBucketString( price, theConfigObject, config.getConfig('currency.granularityMultiplier') ); - utils.logInfo('priceStringsObj', priceStringsObj); + spec.logInfo('priceStringsObj', priceStringsObj); // by default, without any custom granularity set, you get granularity name : 'medium' let granularityNamePriceStringsKeyMapping = { 'medium': 'med', @@ -1053,7 +937,7 @@ export function getRoundedBid(price, mediaType) { }; if (granularityNamePriceStringsKeyMapping.hasOwnProperty(theConfigKey)) { let priceStringsKey = granularityNamePriceStringsKeyMapping[theConfigKey]; - utils.logInfo('getRoundedBid: looking for priceStringsKey:', priceStringsKey); + spec.logInfo('getRoundedBid: looking for priceStringsKey:', priceStringsKey); return priceStringsObj[priceStringsKey]; } return priceStringsObj['auto']; @@ -1122,15 +1006,15 @@ export function getWidthAndHeightFromVideoObject(objVideo) { return null; } if (playerSize[0] && typeof playerSize[0] === 'object') { - utils.logInfo('getWidthAndHeightFromVideoObject found nested array inside playerSize.', playerSize[0]); + spec.logInfo('getWidthAndHeightFromVideoObject found nested array inside playerSize.', playerSize[0]); playerSize = playerSize[0]; if (typeof playerSize[0] !== 'number' && typeof playerSize[0] !== 'string') { - utils.logInfo('getWidthAndHeightFromVideoObject found non-number/string type inside the INNER array in playerSize. This is totally wrong - cannot continue.', playerSize[0]); + spec.logInfo('getWidthAndHeightFromVideoObject found non-number/string type inside the INNER array in playerSize. This is totally wrong - cannot continue.', playerSize[0]); return null; } } if (playerSize.length !== 2) { - utils.logInfo('getWidthAndHeightFromVideoObject found playerSize with length of ' + playerSize.length + '. This is totally wrong - cannot continue.'); + spec.logInfo('getWidthAndHeightFromVideoObject found playerSize with length of ' + playerSize.length + '. This is totally wrong - cannot continue.'); return null; } return ({'w': playerSize[0], 'h': playerSize[1]}); @@ -1157,17 +1041,17 @@ export function playerSizeIsNestedArray(objVideo) { * @returns {*} */ function getPlayerSizeFromObject(objVideo) { - utils.logInfo('getPlayerSizeFromObject received object', objVideo); + spec.logInfo('getPlayerSizeFromObject received object', objVideo); let playerSize = utils.deepAccess(objVideo, 'playerSize'); if (!playerSize) { playerSize = utils.deepAccess(objVideo, 'ext.playerSize'); } if (!playerSize) { - utils.logError('getPlayerSizeFromObject FAILED: no playerSize in video object or ext', objVideo); + spec.logError('getPlayerSizeFromObject FAILED: no playerSize in video object or ext', objVideo); return null; } if (typeof playerSize !== 'object') { - utils.logError('getPlayerSizeFromObject FAILED: playerSize is not an object/array', objVideo); + spec.logError('getPlayerSizeFromObject FAILED: playerSize is not an object/array', objVideo); return null; } return playerSize; @@ -1178,7 +1062,7 @@ function getPlayerSizeFromObject(objVideo) { */ function newRenderer(adUnitCode, rendererOptions = {}) { let isLoaded = window.ozoneVideo; - utils.logInfo(`newRenderer going to set loaded to ${isLoaded ? 'true' : 'false'}`); + spec.logInfo(`newRenderer going to set loaded to ${isLoaded ? 'true' : 'false'}`); const renderer = Renderer.install({ url: spec.getRendererUrl(), config: rendererOptions, @@ -1188,12 +1072,12 @@ function newRenderer(adUnitCode, rendererOptions = {}) { try { renderer.setRender(outstreamRender); } catch (err) { - utils.logError('Prebid Error when calling setRender on renderer', JSON.parse(JSON.stringify(renderer)), err); + spec.logError('Prebid Error when calling setRender on renderer', JSON.parse(JSON.stringify(renderer)), err); } return renderer; } function outstreamRender(bid) { - utils.logInfo('outstreamRender called. Going to push the call to window.ozoneVideo.outstreamRender(bid) bid =', JSON.parse(JSON.stringify(bid))); + spec.logInfo('outstreamRender called. Going to push the call to window.ozoneVideo.outstreamRender(bid) bid =', JSON.parse(JSON.stringify(bid))); // push to render queue because ozoneVideo may not be loaded yet bid.renderer.push(() => { window.ozoneVideo.outstreamRender(bid); diff --git a/test/spec/modules/ozoneBidAdapter_spec.js b/test/spec/modules/ozoneBidAdapter_spec.js index 6a8682c1c30..10b8ce31d28 100644 --- a/test/spec/modules/ozoneBidAdapter_spec.js +++ b/test/spec/modules/ozoneBidAdapter_spec.js @@ -27,20 +27,6 @@ var validBidRequests = [ 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: 'ozone', - 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, @@ -69,7 +55,8 @@ var validBidRequestsMulti = [ transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' } ]; -// use 'pubcid', 'tdid', 'id5id', 'parrableId', 'idl_env', 'criteoId' +// use 'pubcid', 'tdid', 'id5id', 'parrableId', 'idl_env', 'criteoId', 'criteortus' +// NOTE THAT criteortus is no longer referenced anywhere - should be removed asap // see http://prebid.org/dev-docs/modules/userId.html var validBidRequestsWithUserIdData = [ { @@ -86,12 +73,12 @@ var validBidRequestsWithUserIdData = [ userId: { 'pubcid': '12345678', 'tdid': '1111tdid', - 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } }, + 'id5id': 'ID5-someId', + 'criteortus': {'ozone': {'userid': 'critId123'}}, 'criteoId': '1111criteoId', 'idl_env': 'liverampId', 'lipb': {'lipbid': 'lipbidId123'}, - 'parrableId': {'eid': '01.5678.parrableid'}, - 'sharedid': {'id': '01EAJWWNEPN3CYMM5N8M5VXY22', 'third': '01EAJWWNEPN3CYMM5N8M5VXY22'} + 'parrableId': {'eid': '01.5678.parrableid'} }, userIdAsEids: [ { @@ -120,6 +107,13 @@ var validBidRequestsWithUserIdData = [ 'atype': 1, }] }, + { + 'source': 'criteortus', + 'uids': [{ + 'id': {'ozone': {'userid': 'critId123'}}, + 'atype': 1, + }] + }, { 'source': 'criteoId', 'uids': [{ @@ -336,7 +330,7 @@ var validBidderRequest1OutstreamVideo2020 = { ] }, 'userId': { - 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } }, + 'id5id': 'ID5-ZHMOpSv9CkZNiNd1oR4zc62AzCgSS73fPjmQ6Od7OA', 'pubcid': '2ada6ae6-aeca-4e07-8922-a99b3aaf8a56' }, 'userIdAsEids': [ @@ -2020,13 +2014,14 @@ describe('ozone Adapter', function () { let bidRequests = validBidRequests; // values from http://prebid.org/dev-docs/modules/userId.html#pubcommon-id bidRequests[0]['userId'] = { + 'criteortus': '1111', 'digitrustid': {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}}, - 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } }, + 'id5id': '2222', 'idl_env': '3333', + 'lipb': {'lipbid': '4444'}, 'parrableid': 'eidVersion.encryptionKeyReference.encryptedValue', 'pubcid': '5555', - 'tdid': '6666', - 'sharedid': {'id': '01EAJWWNEPN3CYMM5N8M5VXY22', 'third': '01EAJWWNEPN3CYMM5N8M5VXY22'} + 'tdid': '6666' }; bidRequests[0]['userIdAsEids'] = validBidRequestsWithUserIdData[0]['userIdAsEids']; const request = spec.buildRequests(bidRequests, bidderRequest); @@ -2040,13 +2035,14 @@ describe('ozone Adapter', function () { let bidRequests = validBidRequests; // values from http://prebid.org/dev-docs/modules/userId.html#pubcommon-id bidRequests[0]['userId'] = { + 'criteortus': '1111', 'digitrustid': {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}}, - 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } }, + 'id5id': '2222', 'idl_env': '3333', + 'lipb': {'lipbid': '4444'}, 'parrableid': 'eidVersion.encryptionKeyReference.encryptedValue', // 'pubcid': '5555', // remove pubcid from here to emulate the OLD module & cause the failover code to kick in - 'tdid': '6666', - 'sharedid': {'id': '01EAJWWNEPN3CYMM5N8M5VXY22', 'third': '01EAJWWNEPN3CYMM5N8M5VXY22'} + 'tdid': '6666' }; bidRequests[0]['userIdAsEids'] = validBidRequestsWithUserIdData[0]['userIdAsEids']; const request = spec.buildRequests(bidRequests, validBidderRequest.bidderRequest); @@ -2060,9 +2056,11 @@ describe('ozone Adapter', function () { /* 'pubcid': '12345678', 'tdid': '1111tdid', - 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } }, + 'id5id': 'ID5-someId', + 'criteortus': {'ozone': {'userid': 'critId123'}}, 'criteoId': '1111criteoId', 'idl_env': 'liverampId', + 'lipb': {'lipbid': 'lipbidId123'}, 'parrableId': {'eid': '01.5678.parrableid'} */ @@ -2076,14 +2074,16 @@ describe('ozone Adapter', function () { 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'); + expect(payload.user.ext.eids[3]['source']).to.equal('criteortus'); // this is deprecated + expect(payload.user.ext.eids[3]['uids'][0]['id']['ozone']['userid']).to.equal('critId123'); + expect(payload.user.ext.eids[4]['source']).to.equal('criteoId'); + expect(payload.user.ext.eids[4]['uids'][0]['id']).to.equal('1111criteoId'); + expect(payload.user.ext.eids[5]['source']).to.equal('idl_env'); + expect(payload.user.ext.eids[5]['uids'][0]['id']).to.equal('liverampId'); + expect(payload.user.ext.eids[6]['source']).to.equal('lipb'); + expect(payload.user.ext.eids[6]['uids'][0]['id']['lipbid']).to.equal('lipbidId123'); + expect(payload.user.ext.eids[7]['source']).to.equal('parrableId'); + expect(payload.user.ext.eids[7]['uids'][0]['id']['eid']).to.equal('01.5678.parrableid'); }); it('replaces the auction url for a config override', function () { @@ -2093,21 +2093,6 @@ describe('ozone Adapter', function () { const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); expect(request.url).to.equal(fakeOrigin + '/openrtb2/auction'); expect(request.method).to.equal('POST'); - const data = JSON.parse(request.data); - expect(data.ext.ozone.origin).to.equal(fakeOrigin); - config.setConfig({'ozone': {'kvpPrefix': null, 'endpointOverride': null}}); - spec.propertyBag.whitelabel = null; - }); - - it('replaces the FULL auction url for a config override', function () { - spec.propertyBag.whitelabel = null; - let fakeurl = 'http://sometestendpoint/myfullurl'; - config.setConfig({'ozone': {'endpointOverride': {'auctionUrl': fakeurl}}}); - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - expect(request.url).to.equal(fakeurl); - expect(request.method).to.equal('POST'); - const data = JSON.parse(request.data); - expect(data.ext.ozone.origin).to.equal(fakeurl); config.setConfig({'ozone': {'kvpPrefix': null, 'endpointOverride': null}}); spec.propertyBag.whitelabel = null; }); @@ -2124,28 +2109,6 @@ describe('ozone Adapter', function () { config.setConfig({'ozone': {'kvpPrefix': null, 'endpointOverride': null}}); spec.propertyBag.whitelabel = null; }); - it('should generate all the adservertargeting keys correctly named', function () { - var specMock = utils.deepClone(spec); - config.setConfig({'ozone': {'kvpPrefix': 'xx'}}); - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const result = spec.interpretResponse(validResponse, request); - expect(result[0].adserverTargeting).to.have.own.property('xx_appnexus_crid'); - expect(utils.deepAccess(result[0].adserverTargeting, 'xx_appnexus_crid')).to.equal('98493581'); - expect(utils.deepAccess(result[0].adserverTargeting, 'xx_pb')).to.equal(0.5); - expect(utils.deepAccess(result[0].adserverTargeting, 'xx_adId')).to.equal('2899ec066a91ff8-0-xx-0'); - expect(utils.deepAccess(result[0].adserverTargeting, 'xx_size')).to.equal('300x600'); - expect(utils.deepAccess(result[0].adserverTargeting, 'xx_pb_r')).to.equal('0.50'); - expect(utils.deepAccess(result[0].adserverTargeting, 'xx_bid')).to.equal('true'); - config.resetConfig(); - }); - it('should create a meta object on each bid returned', function () { - var specMock = utils.deepClone(spec); - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - 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('replaces the kvp prefix ', function () { spec.propertyBag.whitelabel = null; @@ -2168,8 +2131,8 @@ describe('ozone Adapter', function () { config.setConfig({'lmc': {'kvpPrefix': null}}); // I cant remove the key so set the value to null spec.propertyBag.whitelabel = null; }); + var specMock = utils.deepClone(spec); it('should use oztestmode GET value if set', function() { - var specMock = utils.deepClone(spec); // mock the getGetParametersAsObject function to simulate GET parameters for oztestmode: specMock.getGetParametersAsObject = function() { return {'oztestmode': 'mytestvalue_123'}; @@ -2179,34 +2142,7 @@ describe('ozone Adapter', function () { expect(data.imp[0].ext.ozone.customData).to.be.an('array'); expect(data.imp[0].ext.ozone.customData[0].targeting.oztestmode).to.equal('mytestvalue_123'); }); - it('should pass through GET params if present: ozf, ozpf, ozrp, ozip', function() { - var specMock = utils.deepClone(spec); - // mock the getGetParametersAsObject function to simulate GET parameters : - specMock.getGetParametersAsObject = function() { - return {ozf: '1', ozpf: '0', ozrp: '2', ozip: '123'}; - }; - const request = specMock.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const data = JSON.parse(request.data); - expect(data.ext.ozone.ozf).to.equal(1); - expect(data.ext.ozone.ozpf).to.equal(0); - expect(data.ext.ozone.ozrp).to.equal(2); - expect(data.ext.ozone.ozip).to.equal(123); - }); - it('should pass through GET params if present: ozf, ozpf, ozrp, ozip with alternative values', function() { - var specMock = utils.deepClone(spec); - // mock the getGetParametersAsObject function to simulate GET parameters : - specMock.getGetParametersAsObject = function() { - return {ozf: 'false', ozpf: 'true', ozrp: 'xyz', ozip: 'hello'}; - }; - const request = specMock.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const data = JSON.parse(request.data); - expect(data.ext.ozone.ozf).to.equal(0); - expect(data.ext.ozone.ozpf).to.equal(1); - expect(data.ext.ozone).to.not.haveOwnProperty('ozrp'); - expect(data.ext.ozone).to.not.haveOwnProperty('ozip'); - }); it('should use oztestmode GET value if set, even if there is no customdata in config', function() { - var specMock = utils.deepClone(spec); // mock the getGetParametersAsObject function to simulate GET parameters for oztestmode: specMock.getGetParametersAsObject = function() { return {'oztestmode': 'mytestvalue_123'}; @@ -2216,33 +2152,8 @@ describe('ozone Adapter', function () { expect(data.imp[0].ext.ozone.customData).to.be.an('array'); expect(data.imp[0].ext.ozone.customData[0].targeting.oztestmode).to.equal('mytestvalue_123'); }); - it('should use GET values auction=dev & cookiesync=dev if set', function() { - // mock the getGetParametersAsObject function to simulate GET parameters for oztestmode: - var specMock = utils.deepClone(spec); - specMock.getGetParametersAsObject = function() { - return {}; - }; - let request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest); - let url = request.url; - expect(url).to.equal('https://elb.the-ozone-project.com/openrtb2/auction'); - let cookieUrl = specMock.getCookieSyncUrl(); - expect(cookieUrl).to.equal('https://elb.the-ozone-project.com/static/load-cookie.html'); - - // now mock the response from getGetParametersAsObject & do the request again - - specMock = utils.deepClone(spec); - specMock.getGetParametersAsObject = function() { - return {'auction': 'dev', 'cookiesync': 'dev'}; - }; - request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest); - url = request.url; - expect(url).to.equal('https://test.ozpr.net/openrtb2/auction'); - cookieUrl = specMock.getCookieSyncUrl(); - expect(cookieUrl).to.equal('https://test.ozpr.net/static/load-cookie.html'); - }); it('should use a valid ozstoredrequest GET value if set to override the placementId values, and set oz_rw if we find it', function() { // mock the getGetParametersAsObject function to simulate GET parameters for ozstoredrequest: - var specMock = utils.deepClone(spec); specMock.getGetParametersAsObject = function() { return {'ozstoredrequest': '1122334455'}; // 10 digits are valid }; @@ -2253,7 +2164,6 @@ describe('ozone Adapter', function () { }); it('should NOT use an invalid ozstoredrequest GET value if set to override the placementId values, and set oz_rw to 0', function() { // mock the getGetParametersAsObject function to simulate GET parameters for ozstoredrequest: - var specMock = utils.deepClone(spec); specMock.getGetParametersAsObject = function() { return {'ozstoredrequest': 'BADVAL'}; // 10 digits are valid }; @@ -2320,72 +2230,6 @@ describe('ozone Adapter', function () { const payload = JSON.parse(request.data); expect(payload.ext.ozone.oz_kvp_rw).to.equal(0); }); - it('should handle ortb2 site data', function () { - config.setConfig({'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 request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.imp[0].ext.ozone.customData[0].targeting.name).to.equal('example_ortb2_name'); - expect(payload.user.ext).to.not.have.property('gender'); - config.resetConfig(); - }); - it('should add ortb2 site data when there is no customData already created', function () { - config.setConfig({'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 request = spec.buildRequests(validBidRequestsNoCustomData, validBidderRequest.bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.imp[0].ext.ozone.customData[0].targeting.name).to.equal('example_ortb2_name'); - expect(payload.imp[0].ext.ozone.customData[0].targeting).to.not.have.property('gender') - config.resetConfig(); - }); - it('should add ortb2 user data to the user object', function () { - config.setConfig({'ortb2': { - 'user': { - 'gender': 'who knows these days' - } - }}); - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.user.gender).to.equal('who knows these days'); - config.resetConfig(); - }); - it('should not override the user.ext.consent string even if this is set in config ortb2', function () { - config.setConfig({'ortb2': { - 'user': { - 'ext': { - 'consent': 'this is the consent override that shouldnt work', - 'consent2': 'this should be set' - } - } - }}); - const request = spec.buildRequests(validBidRequests, bidderRequestWithFullGdpr.bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.user.ext.consent2).to.equal('this should be set'); - expect(payload.user.ext.consent).to.equal('BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA'); - config.resetConfig(); - }); it('should have openrtb video params', function() { let allowed = ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', 'placement', 'linearity', 'skip', 'skipmin', 'skipafter', 'sequence', 'battr', 'maxextended', 'minbitrate', 'maxbitrate', 'boxingallowed', 'playbackmethod', 'playbackend', 'delivery', 'pos', 'companionad', 'api', 'companiontype', 'ext']; const request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest.bidderRequest); @@ -2397,33 +2241,6 @@ describe('ozone Adapter', function () { } expect(payload.imp[0].video.ext).to.include({'context': 'outstream'}); }); - it('should handle standard floor config correctly', function () { - config.setConfig({ - floors: { - enforcement: { - floorDeals: false, - bidAdjustment: true - }, - data: { - currency: 'USD', - schema: { - fields: ['mediaType'] - }, - values: { - 'video': 1.20, - 'banner': 0.8 - } - } - } - }); - let localBidRequest = JSON.parse(JSON.stringify(validBidRequestsWithBannerMediaType)); - localBidRequest[0].getFloor = function(x) { return {'currency': 'USD', 'floor': 0.8} }; - const request = spec.buildRequests(localBidRequest, validBidderRequest.bidderRequest); - const payload = JSON.parse(request.data); - expect(utils.deepAccess(payload, 'imp.0.floor.banner.currency')).to.equal('USD'); - expect(utils.deepAccess(payload, 'imp.0.floor.banner.floor')).to.equal(0.8); - config.resetConfig(); - }); }); describe('interpretResponse', function () { @@ -2449,20 +2266,11 @@ describe('ozone Adapter', function () { const result = spec.interpretResponse(validResponse, request); expect(result.length).to.equal(1); }); - it('should build bid array with usp/CCPA', function () { - let validBR = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr.bidderRequest)); - validBR.uspConsent = '1YNY'; - const request = spec.buildRequests(validBidRequests, validBR); - const payload = JSON.parse(request.data); - expect(payload.user.ext.uspConsent).to.equal('1YNY'); - }); it('should build bid array with only partial gdpr', function () { var validBidderRequestWithGdpr = bidderRequestWithPartialGdpr.bidderRequest; validBidderRequestWithGdpr.gdprConsent = {'gdprApplies': 1, 'consentString': 'This is the gdpr consent string'}; const request = spec.buildRequests(validBidRequests, validBidderRequestWithGdpr); - const payload = JSON.parse(request.data); - expect(payload.user.ext.consent).to.be.a('string'); }); it('should fail ok if no seatbid in server response', function () { @@ -2566,7 +2374,7 @@ describe('ozone Adapter', function () { const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); const result = spec.interpretResponse(validResponse, request); expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adv')).to.be.undefined; - expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adId')).to.equal('2899ec066a91ff8-0-oz-0'); + expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adId')).to.equal('2899ec066a91ff8-0-0'); config.resetConfig(); }); it('should ignore a whitelist if enhancedAdserverTargeting is false', function () { @@ -2613,7 +2421,7 @@ describe('ozone Adapter', function () { const result = spec.interpretResponse(validres, request); expect(result.length).to.equal(1); expect(result[0]['price']).to.equal(0.9); - expect(result[0]['adserverTargeting']['oz_ozappnexus_adId']).to.equal('2899ec066a91ff8-0-oz-1'); + expect(result[0]['adserverTargeting']['oz_ozappnexus_adId']).to.equal('2899ec066a91ff8-0-1'); }); 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)); @@ -2623,7 +2431,7 @@ describe('ozone Adapter', function () { 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']['oz_ozappnexus_adId']).to.equal('3025f169863b7f8-0-oz-2'); + expect(result[1]['adserverTargeting']['oz_ozappnexus_adId']).to.equal('3025f169863b7f8-0-2'); // change the bid values so a different second bid for an impid by the same bidder gets dropped validres = JSON.parse(JSON.stringify(multiResponse1)); validres.body.seatbid[0].bid[1].price = 1.1; @@ -2633,7 +2441,7 @@ describe('ozone Adapter', function () { 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']['oz_ozappnexus_adId']).to.equal('3025f169863b7f8-0-oz-1'); + expect(result[1]['adserverTargeting']['oz_ozappnexus_adId']).to.equal('3025f169863b7f8-0-1'); }); }); @@ -2656,20 +2464,6 @@ describe('ozone Adapter', function () { expect(result[0].url).to.include('gdpr=1'); expect(result[0].url).to.include('gdpr_consent=BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA'); }); - it('should append ccpa (usp data)', function() { - // get the cookie bag populated - spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', gdpr1, '1YYN'); - expect(result).to.be.an('array'); - expect(result[0].url).to.include('usp_consent=1YYN'); - }); - it.only('should use "" if no usp is sent to cookieSync', function() { - // get the cookie bag populated - spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', gdpr1); - expect(result).to.be.an('array'); - expect(result[0].url).to.include('usp_consent=&'); - }); }); describe('video object utils', function () {