diff --git a/libraries/adtelligentUtils/adtelligentUtils.js b/libraries/adtelligentUtils/adtelligentUtils.js index c2543fa4cae..9769102ed69 100644 --- a/libraries/adtelligentUtils/adtelligentUtils.js +++ b/libraries/adtelligentUtils/adtelligentUtils.js @@ -65,8 +65,8 @@ export function createTag(bidRequests, adapterRequest) { if (deepAccess(adapterRequest, 'uspConsent')) { tag.USP = deepAccess(adapterRequest, 'uspConsent'); } - if (deepAccess(bidRequests[0], 'schain')) { - tag.Schain = deepAccess(bidRequests[0], 'schain'); + if (deepAccess(adapterRequest, 'ortb2.source.ext.schain')) { + tag.Schain = deepAccess(adapterRequest, 'ortb2.source.ext.schain'); } if (deepAccess(bidRequests[0], 'userId')) { tag.UserIds = deepAccess(bidRequests[0], 'userId'); diff --git a/libraries/braveUtils/buildAndInterpret.js b/libraries/braveUtils/buildAndInterpret.js index 8dda7f6060c..39491b0582d 100644 --- a/libraries/braveUtils/buildAndInterpret.js +++ b/libraries/braveUtils/buildAndInterpret.js @@ -30,7 +30,7 @@ export const buildRequests = (validBidRequests, bidderRequest, endpointURL, defa prepareConsents(data, bidderRequest); prepareEids(data, validBidRequests[0]); - if (validBidRequests[0].schain) data.source = { ext: { schain: validBidRequests[0].schain } }; + if (bidderRequest?.ortb2?.source?.ext?.schain) data.source = { ext: { schain: bidderRequest.ortb2.source.ext.schain } }; return { method: 'POST', url: endpoint, data }; }; diff --git a/libraries/precisoUtils/bidUtilsCommon.js b/libraries/precisoUtils/bidUtilsCommon.js index a8ea97efcaf..8017ea15d1f 100644 --- a/libraries/precisoUtils/bidUtilsCommon.js +++ b/libraries/precisoUtils/bidUtilsCommon.js @@ -67,7 +67,7 @@ export const buildBidRequests = (adurl) => (validBidRequests = [], bidderRequest const placement = { placementId: bid.params.placementId, bidId: bid.bidId, - schain: bid.schain || {}, + schain: bid?.ortb2?.source?.ext?.schain || {}, bidfloor: getBidFloor(bid) }; diff --git a/libraries/riseUtils/index.js b/libraries/riseUtils/index.js index 511bfc2f5eb..075b6ad4672 100644 --- a/libraries/riseUtils/index.js +++ b/libraries/riseUtils/index.js @@ -427,8 +427,8 @@ export function generateGeneralParams(generalObject, bidderRequest, adapterVersi generalParams.ifa = generalBidParams.ifa; } - if (generalObject.schain) { - generalParams.schain = getSupplyChain(generalObject.schain); + if (bidderRequest?.ortb2?.source?.ext?.schain) { + generalParams.schain = getSupplyChain(bidderRequest.ortb2.source.ext.schain); } if (bidderRequest && bidderRequest.refererInfo) { diff --git a/libraries/teqblazeUtils/bidderUtils.js b/libraries/teqblazeUtils/bidderUtils.js index 84010adbbd6..88c7a4c54a3 100644 --- a/libraries/teqblazeUtils/bidderUtils.js +++ b/libraries/teqblazeUtils/bidderUtils.js @@ -35,9 +35,9 @@ const getBidFloor = (bid) => { } }; -const createBasePlacement = (bid) => { +const createBasePlacement = (bid, bidderRequest) => { const { bidId, mediaTypes, transactionId, userIdAsEids } = bid; - const schain = bid.schain || {}; + const schain = bidderRequest?.ortb2?.source?.ext?.schain || {}; const bidfloor = getBidFloor(bid); const placement = { @@ -253,7 +253,7 @@ export const getUserSyncs = (syncUrl) => (syncOptions, serverResponses, gdprCons export const buildPlacementProcessingFunction = (config) => (bid, bidderRequest) => { const addPlacementType = config?.addPlacementType ?? defaultPlacementType; - const placement = createBasePlacement(bid); + const placement = createBasePlacement(bid, bidderRequest); addPlacementType(bid, bidderRequest, placement); diff --git a/libraries/xeUtils/bidderUtils.js b/libraries/xeUtils/bidderUtils.js index b75d315684d..0d45067756f 100644 --- a/libraries/xeUtils/bidderUtils.js +++ b/libraries/xeUtils/bidderUtils.js @@ -48,7 +48,7 @@ export function buildRequests(validBidRequests, bidderRequest, endpoint) { request.auctionId = req.ortb2?.source?.tid; request.transactionId = req.ortb2Imp?.ext?.tid; request.sizes = parseSizesInput(getAdUnitSizes(req)); - request.schain = req.schain; + request.schain = bidderRequest?.ortb2?.source?.ext?.schain; request.location = { page: refererInfo.page, location: refererInfo.location, diff --git a/modules/33acrossBidAdapter.js b/modules/33acrossBidAdapter.js index 9feca97d425..1d86d3897e7 100644 --- a/modules/33acrossBidAdapter.js +++ b/modules/33acrossBidAdapter.js @@ -316,9 +316,9 @@ function _createServerRequest({ bidRequests, gdprConsent = {}, uspConsent, gppCo } }; - if (firstBidRequest.schain) { + if (firstBidRequest.ortb2?.source?.ext?.schain) { ttxRequest.source = setExtensions(ttxRequest.source, { - 'schain': firstBidRequest.schain + 'schain': firstBidRequest.ortb2.source.ext.schain }); } diff --git a/modules/adagioBidAdapter.js b/modules/adagioBidAdapter.js index c68ffc0d674..721da83eb12 100644 --- a/modules/adagioBidAdapter.js +++ b/modules/adagioBidAdapter.js @@ -155,7 +155,7 @@ function _getUspConsent(bidderRequest) { } function _getSchain(bidRequest) { - return deepAccess(bidRequest, 'schain'); + return deepAccess(bidRequest, 'ortb2.source.ext.schain'); } function _getEids(bidRequest) { diff --git a/modules/adfBidAdapter.js b/modules/adfBidAdapter.js index d3e8e05848b..98bd352147f 100644 --- a/modules/adfBidAdapter.js +++ b/modules/adfBidAdapter.js @@ -72,7 +72,7 @@ export const spec = { const currency = getCurrencyFromBidderRequest(bidderRequest); const cur = currency && [ currency ]; const eids = setOnAny(validBidRequests, 'userIdAsEids'); - const schain = setOnAny(validBidRequests, 'schain'); + const schain = setOnAny(validBidRequests, 'ortb2.source.ext.schain'); if (eids) { deepSetValue(user, 'ext.eids', eids); diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js index e87075c1433..b7f61dcbbdb 100644 --- a/modules/adkernelBidAdapter.js +++ b/modules/adkernelBidAdapter.js @@ -133,7 +133,7 @@ export const spec = { buildRequests: function (bidRequests, bidderRequest) { let impGroups = groupImpressionsByHostZone(bidRequests, bidderRequest.refererInfo); let requests = []; - let schain = bidRequests[0].schain; + let schain = bidRequests[0]?.ortb2?.source?.ext?.schain; _each(impGroups, impGroup => { let {host, zoneId, imps} = impGroup; const request = buildRtbRequest(imps, bidderRequest, schain); diff --git a/modules/admaticBidAdapter.js b/modules/admaticBidAdapter.js index 9cc2182c6bf..eae365d4383 100644 --- a/modules/admaticBidAdapter.js +++ b/modules/admaticBidAdapter.js @@ -112,8 +112,9 @@ export const spec = { payload.regs.ext.uspIab = bidderRequest.uspConsent; } - if (validBidRequests[0].schain) { - const schain = mapSchain(validBidRequests[0].schain); + const bidSchain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (bidSchain) { + const schain = mapSchain(bidSchain); if (schain) { payload.schain = schain; } diff --git a/modules/adotBidAdapter.js b/modules/adotBidAdapter.js index 266d7095a11..6f218ebd6f3 100644 --- a/modules/adotBidAdapter.js +++ b/modules/adotBidAdapter.js @@ -123,7 +123,7 @@ function getOpenRTBSiteObject(bidderRequest) { id: publisherId }, ext: { - schain: bidderRequest.schain + schain: bidderRequest?.ortb2?.source?.ext?.schain } }; } diff --git a/modules/adspiritBidAdapter.js b/modules/adspiritBidAdapter.js index 3dcd0b06be4..2d1ceb5902d 100644 --- a/modules/adspiritBidAdapter.js +++ b/modules/adspiritBidAdapter.js @@ -1,288 +1,289 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE } from '../src/mediaTypes.js'; -import { getGlobal } from '../src/prebidGlobal.js'; -const { getWinDimensions } = utils; -const RTB_URL = '/rtb/getbid.php?rtbprovider=prebid'; -const SCRIPT_URL = '/adasync.min.js'; - -export const spec = { - - code: 'adspirit', - aliases: ['twiago'], - supportedMediaTypes: [BANNER, NATIVE], - - isBidRequestValid: function (bid) { - let host = spec.getBidderHost(bid); - if (!host || !bid.params.placementId) { - return false; - } - return true; - }, - getScriptUrl: function () { - return SCRIPT_URL; - }, - buildRequests: function (validBidRequests, bidderRequest) { - let requests = []; - let prebidVersion = getGlobal().version; - const win = getWinDimensions(); - - for (let i = 0; i < validBidRequests.length; i++) { - let bidRequest = validBidRequests[i]; - bidRequest.adspiritConId = spec.genAdConId(bidRequest); - let reqUrl = spec.getBidderHost(bidRequest); - let placementId = utils.getBidIdParameter('placementId', bidRequest.params); - const eids = spec.getEids(bidRequest); - - reqUrl = '//' + reqUrl + RTB_URL + - '&pid=' + placementId + - '&ref=' + encodeURIComponent(bidderRequest.refererInfo.topmostLocation) + - '&scx=' + (win.screen?.width || 0) + - '&scy=' + (win.screen?.height || 0) + - '&wcx=' + win.innerWidth + - '&wcy=' + win.innerHeight + - '&async=' + bidRequest.adspiritConId + - '&t=' + Math.round(Math.random() * 100000); - - let gdprApplies = bidderRequest.gdprConsent ? (bidderRequest.gdprConsent.gdprApplies ? 1 : 0) : 0; - let gdprConsentString = bidderRequest.gdprConsent ? encodeURIComponent(bidderRequest.gdprConsent.consentString) : ''; - - if (bidderRequest.gdprConsent) { - reqUrl += '&gdpr=' + gdprApplies + '&gdpr_consent=' + gdprConsentString; - } - - let openRTBRequest = { - id: bidderRequest.auctionId, - at: 1, - cur: ['EUR'], - imp: [{ - id: bidRequest.bidId, - bidfloor: bidRequest.params.bidfloor !== undefined ? parseFloat(bidRequest.params.bidfloor) : 0, - bidfloorcur: 'EUR', - secure: 1, - banner: (bidRequest.mediaTypes.banner && bidRequest.mediaTypes.banner.sizes?.length > 0) ? { - format: bidRequest.mediaTypes.banner.sizes.map(size => ({ - w: size[0], - h: size[1] - })) - } : undefined, - native: (bidRequest.mediaTypes.native) ? { - request: JSON.stringify({ - ver: '1.2', - assets: bidRequest.mediaTypes.native.ortb?.assets?.length - ? bidRequest.mediaTypes.native.ortb.assets - : [ - { id: 1, required: 1, title: { len: 100 } }, - { id: 2, required: 1, img: { type: 3, wmin: 1200, hmin: 627, mimes: ['image/png', 'image/gif', 'image/jpeg'] } }, - { id: 4, required: 1, data: {type: 2, len: 150} }, - { id: 3, required: 0, data: {type: 12, len: 50} }, - { id: 6, required: 0, data: {type: 1, len: 50} }, - { id: 5, required: 0, img: { type: 1, wmin: 50, hmin: 50, mimes: ['image/png', 'image/gif', 'image/jpeg'] } } - - ] - }) - } : undefined, - ext: { - placementId: bidRequest.params.placementId - } - }], - - site: { - id: bidRequest.params.siteId || '', - domain: new URL(bidderRequest.refererInfo.topmostLocation).hostname, - page: bidderRequest.refererInfo.topmostLocation, - publisher: { - id: bidRequest.params.publisherId || '', - name: bidRequest.params.publisherName || '' - } - }, - user: { - data: bidRequest.userData || [], - ext: { - eids: eids, - consent: gdprConsentString || '' - } - }, - device: { - ua: navigator.userAgent, - language: (navigator.language || '').split('-')[0], - w: win.innerWidth, - h: win.innerHeight, - geo: { - lat: bidderRequest?.geo?.lat || 0, - lon: bidderRequest?.geo?.lon || 0, - country: bidderRequest?.geo?.country || '' - } - }, - regs: { - ext: { - gdpr: gdprApplies ? 1 : 0, - gdpr_consent: gdprConsentString || '' - } - }, - ext: { - oat: 1, - prebidVersion: prebidVersion, - adUnitCode: { - prebidVersion: prebidVersion, - code: bidRequest.adUnitCode, - mediaTypes: bidRequest.mediaTypes - } - } - }; - - - if (bidRequest.schain) { - openRTBRequest.source = { - ext: { - schain: bidRequest.schain - } - }; - } - requests.push({ - method: 'POST', - url: reqUrl, - data: JSON.stringify(openRTBRequest), - headers: { 'Content-Type': 'application/json' }, - bidRequest: bidRequest - }); - } - - return requests; - }, - getEids: function (bidRequest) { - return utils.deepAccess(bidRequest, 'userIdAsEids') || []; - }, - interpretResponse: function (serverResponse, bidRequest) { - const bidResponses = []; - const bidObj = bidRequest.bidRequest; - let host = spec.getBidderHost(bidObj); - - if (!serverResponse || !serverResponse.body) { - utils.logWarn(`adspirit: Empty response from bidder`); - return []; - } - - if (serverResponse.body.seatbid) { - serverResponse.body.seatbid.forEach(seat => { - seat.bid.forEach(bid => { - const bidResponse = { - requestId: bidObj.bidId, - cpm: bid.price, - width: bid.w || 1, - height: bid.h || 1, - creativeId: bid.crid || bid.impid, - currency: serverResponse.body.cur || 'EUR', - netRevenue: true, - ttl: bid.exp || 300, - meta: { - advertiserDomains: bid.adomain || [] - } - }; - - let adm = bid.adm; - if (typeof adm === 'string' && adm.trim().startsWith('{')) { - adm = JSON.parse(adm || '{}'); - if (typeof adm !== 'object') adm = null; - } - - if (adm?.native?.assets) { - const getAssetValue = (id, type) => { - const assetList = adm.native.assets.filter(a => a.id === id); - if (assetList.length === 0) return ''; - return assetList[0][type]?.text || assetList[0][type]?.value || assetList[0][type]?.url || ''; - }; - - const duplicateTracker = {}; - - bidResponse.native = { - title: getAssetValue(1, 'title'), - body: getAssetValue(4, 'data'), - cta: getAssetValue(3, 'data'), - image: { url: getAssetValue(2, 'img') || '' }, - icon: { url: getAssetValue(5, 'img') || '' }, - sponsoredBy: getAssetValue(6, 'data'), - clickUrl: adm.native.link?.url || '', - impressionTrackers: Array.isArray(adm.native.imptrackers) ? adm.native.imptrackers : [] - }; - - const predefinedAssetIds = Object.entries(bidResponse.native) - .filter(([key, value]) => key !== 'clickUrl' && key !== 'impressionTrackers') - .map(([key, value]) => adm.native.assets.find(asset => - typeof value === 'object' ? value.url === asset?.img?.url : value === asset?.data?.value - )?.id) - .filter(id => id !== undefined); - - adm.native.assets.forEach(asset => { - const type = Object.keys(asset).find(k => k !== 'id'); - - if (!duplicateTracker[asset.id]) { - duplicateTracker[asset.id] = 1; - } else { - duplicateTracker[asset.id]++; - } - - if (predefinedAssetIds.includes(asset.id) && duplicateTracker[asset.id] === 1) return; - - if (type && asset[type]) { - const value = asset[type].text || asset[type].value || asset[type].url || ''; - - if (type === 'img') { - bidResponse.native[`image_${asset.id}_extra${duplicateTracker[asset.id] - 1}`] = { - url: value, width: asset.img.w || null, height: asset.img.h || null - }; - } else { - bidResponse.native[`data_${asset.id}_extra${duplicateTracker[asset.id] - 1}`] = value; - } - } - }); - - bidResponse.mediaType = NATIVE; - } - - bidResponses.push(bidResponse); - }); - }); - } else { - let adData = serverResponse.body; - let cpm = adData.cpm; - - if (!cpm) return []; - const bidResponse = { - requestId: bidObj.bidId, - cpm: cpm, - width: adData.w, - height: adData.h, - creativeId: bidObj.params.placementId, - currency: 'EUR', - netRevenue: true, - ttl: 300, - meta: { - advertiserDomains: adData.adomain || [] - } - }; - let adm = '' + adData.adm; - bidResponse.ad = adm; - bidResponse.mediaType = BANNER; - - bidResponses.push(bidResponse); - } - - return bidResponses; - }, - getBidderHost: function (bid) { - if (bid.bidder === 'adspirit') { - return utils.getBidIdParameter('host', bid.params); - } - if (bid.bidder === 'twiago') { - return 'a.twiago.com'; - } - return null; - }, - - genAdConId: function (bid) { - return bid.bidder + Math.round(Math.random() * 100000); - } -}; - -registerBidder(spec); +import * as utils from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +const { getWinDimensions } = utils; +const RTB_URL = '/rtb/getbid.php?rtbprovider=prebid'; +const SCRIPT_URL = '/adasync.min.js'; + +export const spec = { + + code: 'adspirit', + aliases: ['twiago'], + supportedMediaTypes: [BANNER, NATIVE], + + isBidRequestValid: function (bid) { + let host = spec.getBidderHost(bid); + if (!host || !bid.params.placementId) { + return false; + } + return true; + }, + getScriptUrl: function () { + return SCRIPT_URL; + }, + buildRequests: function (validBidRequests, bidderRequest) { + let requests = []; + let prebidVersion = getGlobal().version; + const win = getWinDimensions(); + + for (let i = 0; i < validBidRequests.length; i++) { + let bidRequest = validBidRequests[i]; + bidRequest.adspiritConId = spec.genAdConId(bidRequest); + let reqUrl = spec.getBidderHost(bidRequest); + let placementId = utils.getBidIdParameter('placementId', bidRequest.params); + const eids = spec.getEids(bidRequest); + + reqUrl = '//' + reqUrl + RTB_URL + + '&pid=' + placementId + + '&ref=' + encodeURIComponent(bidderRequest.refererInfo.topmostLocation) + + '&scx=' + (win.screen?.width || 0) + + '&scy=' + (win.screen?.height || 0) + + '&wcx=' + win.innerWidth + + '&wcy=' + win.innerHeight + + '&async=' + bidRequest.adspiritConId + + '&t=' + Math.round(Math.random() * 100000); + + let gdprApplies = bidderRequest.gdprConsent ? (bidderRequest.gdprConsent.gdprApplies ? 1 : 0) : 0; + let gdprConsentString = bidderRequest.gdprConsent ? encodeURIComponent(bidderRequest.gdprConsent.consentString) : ''; + + if (bidderRequest.gdprConsent) { + reqUrl += '&gdpr=' + gdprApplies + '&gdpr_consent=' + gdprConsentString; + } + + let openRTBRequest = { + id: bidderRequest.auctionId, + at: 1, + cur: ['EUR'], + imp: [{ + id: bidRequest.bidId, + bidfloor: bidRequest.params.bidfloor !== undefined ? parseFloat(bidRequest.params.bidfloor) : 0, + bidfloorcur: 'EUR', + secure: 1, + banner: (bidRequest.mediaTypes.banner && bidRequest.mediaTypes.banner.sizes?.length > 0) ? { + format: bidRequest.mediaTypes.banner.sizes.map(size => ({ + w: size[0], + h: size[1] + })) + } : undefined, + native: (bidRequest.mediaTypes.native) ? { + request: JSON.stringify({ + ver: '1.2', + assets: bidRequest.mediaTypes.native.ortb?.assets?.length + ? bidRequest.mediaTypes.native.ortb.assets + : [ + { id: 1, required: 1, title: { len: 100 } }, + { id: 2, required: 1, img: { type: 3, wmin: 1200, hmin: 627, mimes: ['image/png', 'image/gif', 'image/jpeg'] } }, + { id: 4, required: 1, data: {type: 2, len: 150} }, + { id: 3, required: 0, data: {type: 12, len: 50} }, + { id: 6, required: 0, data: {type: 1, len: 50} }, + { id: 5, required: 0, img: { type: 1, wmin: 50, hmin: 50, mimes: ['image/png', 'image/gif', 'image/jpeg'] } } + + ] + }) + } : undefined, + ext: { + placementId: bidRequest.params.placementId + } + }], + + site: { + id: bidRequest.params.siteId || '', + domain: new URL(bidderRequest.refererInfo.topmostLocation).hostname, + page: bidderRequest.refererInfo.topmostLocation, + publisher: { + id: bidRequest.params.publisherId || '', + name: bidRequest.params.publisherName || '' + } + }, + user: { + data: bidRequest.userData || [], + ext: { + eids: eids, + consent: gdprConsentString || '' + } + }, + device: { + ua: navigator.userAgent, + language: (navigator.language || '').split('-')[0], + w: win.innerWidth, + h: win.innerHeight, + geo: { + lat: bidderRequest?.geo?.lat || 0, + lon: bidderRequest?.geo?.lon || 0, + country: bidderRequest?.geo?.country || '' + } + }, + regs: { + ext: { + gdpr: gdprApplies ? 1 : 0, + gdpr_consent: gdprConsentString || '' + } + }, + ext: { + oat: 1, + prebidVersion: prebidVersion, + adUnitCode: { + prebidVersion: prebidVersion, + code: bidRequest.adUnitCode, + mediaTypes: bidRequest.mediaTypes + } + } + }; + + + const schain = bidRequest?.ortb2?.source?.ext?.schain; + if (schain) { + openRTBRequest.source = { + ext: { + schain: schain + } + }; + } + requests.push({ + method: 'POST', + url: reqUrl, + data: JSON.stringify(openRTBRequest), + headers: { 'Content-Type': 'application/json' }, + bidRequest: bidRequest + }); + } + + return requests; + }, + getEids: function (bidRequest) { + return utils.deepAccess(bidRequest, 'userIdAsEids') || []; + }, + interpretResponse: function (serverResponse, bidRequest) { + const bidResponses = []; + const bidObj = bidRequest.bidRequest; + let host = spec.getBidderHost(bidObj); + + if (!serverResponse || !serverResponse.body) { + utils.logWarn(`adspirit: Empty response from bidder`); + return []; + } + + if (serverResponse.body.seatbid) { + serverResponse.body.seatbid.forEach(seat => { + seat.bid.forEach(bid => { + const bidResponse = { + requestId: bidObj.bidId, + cpm: bid.price, + width: bid.w || 1, + height: bid.h || 1, + creativeId: bid.crid || bid.impid, + currency: serverResponse.body.cur || 'EUR', + netRevenue: true, + ttl: bid.exp || 300, + meta: { + advertiserDomains: bid.adomain || [] + } + }; + + let adm = bid.adm; + if (typeof adm === 'string' && adm.trim().startsWith('{')) { + adm = JSON.parse(adm || '{}'); + if (typeof adm !== 'object') adm = null; + } + + if (adm?.native?.assets) { + const getAssetValue = (id, type) => { + const assetList = adm.native.assets.filter(a => a.id === id); + if (assetList.length === 0) return ''; + return assetList[0][type]?.text || assetList[0][type]?.value || assetList[0][type]?.url || ''; + }; + + const duplicateTracker = {}; + + bidResponse.native = { + title: getAssetValue(1, 'title'), + body: getAssetValue(4, 'data'), + cta: getAssetValue(3, 'data'), + image: { url: getAssetValue(2, 'img') || '' }, + icon: { url: getAssetValue(5, 'img') || '' }, + sponsoredBy: getAssetValue(6, 'data'), + clickUrl: adm.native.link?.url || '', + impressionTrackers: Array.isArray(adm.native.imptrackers) ? adm.native.imptrackers : [] + }; + + const predefinedAssetIds = Object.entries(bidResponse.native) + .filter(([key, value]) => key !== 'clickUrl' && key !== 'impressionTrackers') + .map(([key, value]) => adm.native.assets.find(asset => + typeof value === 'object' ? value.url === asset?.img?.url : value === asset?.data?.value + )?.id) + .filter(id => id !== undefined); + + adm.native.assets.forEach(asset => { + const type = Object.keys(asset).find(k => k !== 'id'); + + if (!duplicateTracker[asset.id]) { + duplicateTracker[asset.id] = 1; + } else { + duplicateTracker[asset.id]++; + } + + if (predefinedAssetIds.includes(asset.id) && duplicateTracker[asset.id] === 1) return; + + if (type && asset[type]) { + const value = asset[type].text || asset[type].value || asset[type].url || ''; + + if (type === 'img') { + bidResponse.native[`image_${asset.id}_extra${duplicateTracker[asset.id] - 1}`] = { + url: value, width: asset.img.w || null, height: asset.img.h || null + }; + } else { + bidResponse.native[`data_${asset.id}_extra${duplicateTracker[asset.id] - 1}`] = value; + } + } + }); + + bidResponse.mediaType = NATIVE; + } + + bidResponses.push(bidResponse); + }); + }); + } else { + let adData = serverResponse.body; + let cpm = adData.cpm; + + if (!cpm) return []; + const bidResponse = { + requestId: bidObj.bidId, + cpm: cpm, + width: adData.w, + height: adData.h, + creativeId: bidObj.params.placementId, + currency: 'EUR', + netRevenue: true, + ttl: 300, + meta: { + advertiserDomains: adData.adomain || [] + } + }; + let adm = '' + adData.adm; + bidResponse.ad = adm; + bidResponse.mediaType = BANNER; + + bidResponses.push(bidResponse); + } + + return bidResponses; + }, + getBidderHost: function (bid) { + if (bid.bidder === 'adspirit') { + return utils.getBidIdParameter('host', bid.params); + } + if (bid.bidder === 'twiago') { + return 'a.twiago.com'; + } + return null; + }, + + genAdConId: function (bid) { + return bid.bidder + Math.round(Math.random() * 100000); + } +}; + +registerBidder(spec); diff --git a/modules/adstirBidAdapter.js b/modules/adstirBidAdapter.js index a0c67ddac7e..6fadf632c0e 100644 --- a/modules/adstirBidAdapter.js +++ b/modules/adstirBidAdapter.js @@ -40,7 +40,7 @@ export const spec = { gdpr: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies', false), usp: (bidderRequest.uspConsent || '1---') !== '1---', eids: utils.deepAccess(r, 'userIdAsEids', []), - schain: serializeSchain(utils.deepAccess(r, 'schain', null)), + schain: serializeSchain(utils.deepAccess(r, 'ortb2.source.ext.schain', null)), pbVersion: '$prebid.version$', }), } diff --git a/modules/adtrgtmeBidAdapter.js b/modules/adtrgtmeBidAdapter.js index 9432031e77e..f3f648c6f2d 100644 --- a/modules/adtrgtmeBidAdapter.js +++ b/modules/adtrgtmeBidAdapter.js @@ -86,7 +86,7 @@ function createORTB(bR, bid) { hb: 1, bidderver: BIDDER_VERSION, prebidjsver: PREBIDJS_VERSION, - ...(bid?.schain && { schain: bid.schain }), + ...(bid?.ortb2?.source?.ext?.schain && { schain: bid?.ortb2?.source?.ext?.schain }), }, fd: 1, }, @@ -99,7 +99,7 @@ function createORTB(bR, bid) { }, }; - if (bid?.schain) { + if (bid?.ortb2?.source?.ext?.schain) { oR.source.ext.schain.nodes[0].rid = oR.id; } diff --git a/modules/adtrueBidAdapter.js b/modules/adtrueBidAdapter.js index a6186d6129f..c9037aeb743 100644 --- a/modules/adtrueBidAdapter.js +++ b/modules/adtrueBidAdapter.js @@ -514,8 +514,9 @@ export const spec = { payload.test = 1; } // adding schain object - if (validBidRequests[0].schain) { - deepSetValue(payload, 'source.ext.schain', validBidRequests[0].schain); + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + deepSetValue(payload, 'source.ext.schain', schain); } // Attaching GDPR Consent Params if (bidderRequest && bidderRequest.gdprConsent) { diff --git a/modules/advertisingBidAdapter.js b/modules/advertisingBidAdapter.js index 930a4dcd16d..665096fb19d 100644 --- a/modules/advertisingBidAdapter.js +++ b/modules/advertisingBidAdapter.js @@ -60,7 +60,7 @@ export const spec = { openRtbBidRequest.tmax = tmax; } - const schain = validBidReqs[0].schain; + const schain = validBidReqs[0]?.ortb2?.source?.ext?.schain; if (schain) { openRtbBidRequest.source = { ext: { schain } }; } diff --git a/modules/adyoulikeBidAdapter.js b/modules/adyoulikeBidAdapter.js index e2187782be2..3fb8da35e71 100644 --- a/modules/adyoulikeBidAdapter.js +++ b/modules/adyoulikeBidAdapter.js @@ -87,8 +87,9 @@ export const spec = { if (typeof bidReq.getFloor === 'function') { accumulator[bidReq.bidId].Pricing = getFloor(bidReq, size, mediatype); } - if (bidReq.schain) { - accumulator[bidReq.bidId].SChain = bidReq.schain; + const schain = bidReq?.ortb2?.source?.ext?.schain; + if (schain) { + accumulator[bidReq.bidId].SChain = schain; } if (!eids && bidReq.userIdAsEids && bidReq.userIdAsEids.length) { eids = bidReq.userIdAsEids; diff --git a/modules/ajaBidAdapter.js b/modules/ajaBidAdapter.js index 699dfd6fa04..a06c1a873fc 100644 --- a/modules/ajaBidAdapter.js +++ b/modules/ajaBidAdapter.js @@ -67,7 +67,8 @@ export const spec = { queryString = tryAppendQueryString(queryString, 'prebid_id', bidRequest.bidId); queryString = tryAppendQueryString(queryString, 'prebid_ver', '$prebid.version$'); queryString = tryAppendQueryString(queryString, 'page_url', pageUrl); - queryString = tryAppendQueryString(queryString, 'schain', spec.serializeSupplyChain(bidRequest.schain || [])) + const schain = bidRequest?.ortb2?.source?.ext?.schain; + queryString = tryAppendQueryString(queryString, 'schain', spec.serializeSupplyChain(schain || [])) const adFormatIDs = pickAdFormats(bidRequest) if (adFormatIDs && adFormatIDs.length > 0) { diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index f52c3ec7703..36a2600294c 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -64,7 +64,7 @@ export const spec = { bidIds, referer: bidderRequest.refererInfo.page, signature: alkimiConfig && alkimiConfig.signature, - schain: validBidRequests[0].schain, + schain: validBidRequests[0]?.ortb2?.source?.ext?.schain, cpp: config.getConfig('coppa') ? 1 : 0, device: { dnt: getDNT() ? 1 : 0, diff --git a/modules/amxBidAdapter.js b/modules/amxBidAdapter.js index 9a3c61135a0..8afab28378f 100644 --- a/modules/amxBidAdapter.js +++ b/modules/amxBidAdapter.js @@ -184,7 +184,7 @@ function convertRequest(bid) { aw: size[0], ah: size[1], tf: 0, - sc: bid.schain || {}, + sc: bid?.ortb2?.source?.ext?.schain || {}, f: ensureFloor(getFloor(bid)), rtb: bid.ortb2Imp, }; diff --git a/modules/apacdexBidAdapter.js b/modules/apacdexBidAdapter.js index 83119052f3a..912f37e35c8 100644 --- a/modules/apacdexBidAdapter.js +++ b/modules/apacdexBidAdapter.js @@ -48,8 +48,9 @@ export const spec = { test = config.getConfig('debug'); validBidRequests.forEach(bidReq => { - if (bidReq.schain) { - schain = schain || bidReq.schain + const bidSchain = bidReq?.ortb2?.source?.ext?.schain; + if (bidSchain) { + schain = schain || bidSchain } if (bidReq.userIdAsEids) { diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index db37362d3a4..ceeae762bc6 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -238,7 +238,7 @@ export const spec = { const memberIdBid = ((bidRequests) || []).find(hasMemberId); const member = memberIdBid ? parseInt(memberIdBid.params.member, 10) : 0; - const schain = bidRequests[0].schain; + const schain = bidRequests[0]?.ortb2?.source?.ext?.schain; const omidSupport = ((bidRequests) || []).find(hasOmidSupport); const payload = { diff --git a/modules/appushBidAdapter.js b/modules/appushBidAdapter.js index ec742120582..f06dc0f2c13 100644 --- a/modules/appushBidAdapter.js +++ b/modules/appushBidAdapter.js @@ -27,7 +27,7 @@ function isBidResponseValid(bid) { function getPlacementReqData(bid) { const { params, bidId, mediaTypes } = bid; - const schain = bid.schain || {}; + const schain = bid?.ortb2?.source?.ext?.schain || {}; const { placementId, endpointId } = params; const bidfloor = getBidFloor(bid); diff --git a/modules/audiencerunBidAdapter.js b/modules/audiencerunBidAdapter.js index df3bbda6a53..4d60ee244a3 100644 --- a/modules/audiencerunBidAdapter.js +++ b/modules/audiencerunBidAdapter.js @@ -143,7 +143,7 @@ export const spec = { }; payload.uspConsent = deepAccess(bidderRequest, 'uspConsent'); - payload.schain = deepAccess(bidRequests, '0.schain'); + payload.schain = deepAccess(bidRequests, '0.ortb2.source.ext.schain'); payload.userId = deepAccess(bidRequests, '0.userIdAsEids') || [] if (bidderRequest && bidderRequest.gdprConsent) { diff --git a/modules/beachfrontBidAdapter.js b/modules/beachfrontBidAdapter.js index 59d4d5976be..403a8d1129c 100644 --- a/modules/beachfrontBidAdapter.js +++ b/modules/beachfrontBidAdapter.js @@ -328,8 +328,9 @@ function createVideoRequestData(bid, bidderRequest) { deepSetValue(payload, 'regs.gpp_sid', applicableSections); } - if (bid.schain) { - deepSetValue(payload, 'source.ext.schain', bid.schain); + const schain = bid?.ortb2?.source?.ext?.schain; + if (schain) { + deepSetValue(payload, 'source.ext.schain', schain); } if (eids.length > 0) { @@ -389,8 +390,9 @@ function createBannerRequestData(bids, bidderRequest) { payload.gppSid = applicableSections; } - if (bids[0] && bids[0].schain) { - payload.schain = bids[0].schain; + const schain = bids[0]?.ortb2?.source?.ext?.schain; + if (schain) { + payload.schain = schain; } SUPPORTED_USER_IDS.forEach(({ key, queryParam }) => { diff --git a/modules/betweenBidAdapter.js b/modules/betweenBidAdapter.js index c81c49bc0d9..782ecf42984 100644 --- a/modules/betweenBidAdapter.js +++ b/modules/betweenBidAdapter.js @@ -85,8 +85,9 @@ export const spec = { } } - if (i.schain) { - params.schain = encodeToBase64WebSafe(JSON.stringify(i.schain)); + const schain = i?.ortb2?.source?.ext?.schain; + if (schain) { + params.schain = encodeToBase64WebSafe(JSON.stringify(schain)); } // TODO: is 'page' the right value here? diff --git a/modules/bliinkBidAdapter.js b/modules/bliinkBidAdapter.js index 2020fda84a5..62c2cc47872 100644 --- a/modules/bliinkBidAdapter.js +++ b/modules/bliinkBidAdapter.js @@ -218,7 +218,7 @@ export const buildRequests = (validBidRequests, bidderRequest) => { ect: getEffectiveConnectionType(), }; - const schain = deepAccess(validBidRequests[0], 'schain') + const schain = deepAccess(validBidRequests[0], 'ortb2.source.ext.schain') const eids = getUserIds(validBidRequests) const device = bidderRequest.ortb2?.device if (schain) { diff --git a/modules/bridBidAdapter.js b/modules/bridBidAdapter.js index c9840ad57f8..afe9442e3ac 100644 --- a/modules/bridBidAdapter.js +++ b/modules/bridBidAdapter.js @@ -99,9 +99,10 @@ export const spec = { }; }; - if (bidRequests[0].schain) { + const schain = bidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { postBody.source = { - ext: { schain: bidRequests[0].schain } + ext: { schain: schain } }; } diff --git a/modules/brightMountainMediaBidAdapter.js b/modules/brightMountainMediaBidAdapter.js index 5e5b062889d..1047ec931cc 100644 --- a/modules/brightMountainMediaBidAdapter.js +++ b/modules/brightMountainMediaBidAdapter.js @@ -81,7 +81,8 @@ export const spec = { oRTBRequest.imp[0].bidfloor = getFloor(bid, size); oRTBRequest.user = getUserIdAsEids(bid.userIdAsEids) - oRTBRequest.source = getSchain(bid.schain) + const schain = bid?.ortb2?.source?.ext?.schain; + oRTBRequest.source = getSchain(schain) requestData.push({ method: 'POST', diff --git a/modules/browsiBidAdapter.js b/modules/browsiBidAdapter.js index fa1cacaa568..cb256254e12 100644 --- a/modules/browsiBidAdapter.js +++ b/modules/browsiBidAdapter.js @@ -43,7 +43,8 @@ export const spec = { const requests = []; const {refererInfo, bidderRequestId, gdprConsent, uspConsent} = bidderRequest; validBidRequests.forEach(bidRequest => { - const {bidId, adUnitCode, auctionId, ortb2Imp, schain, params} = bidRequest; + const {bidId, adUnitCode, auctionId, ortb2Imp, params} = bidRequest; + const schain = bidRequest?.ortb2?.source?.ext?.schain; const video = getVideoMediaType(bidRequest); const request = { diff --git a/modules/cadentApertureMXBidAdapter.js b/modules/cadentApertureMXBidAdapter.js index 7776583bcda..32103ffd540 100644 --- a/modules/cadentApertureMXBidAdapter.js +++ b/modules/cadentApertureMXBidAdapter.js @@ -185,10 +185,11 @@ export const cadentAdapter = { return cadentData; }, getSupplyChain: (bidderRequest, cadentData) => { - if (bidderRequest.bids[0] && bidderRequest.bids[0].schain) { + const schain = bidderRequest.bids[0]?.ortb2?.source?.ext?.schain; + if (bidderRequest.bids[0] && schain) { cadentData.source = { ext: { - schain: bidderRequest.bids[0].schain + schain: schain } }; } diff --git a/modules/carodaBidAdapter.js b/modules/carodaBidAdapter.js index 3060501ba8d..75af70da4ff 100644 --- a/modules/carodaBidAdapter.js +++ b/modules/carodaBidAdapter.js @@ -49,7 +49,7 @@ export const spec = { const test = getFirstWithKey(validBidRequests, 'params.test'); const currency = getCurrencyFromBidderRequest(bidderRequest); const eids = getFirstWithKey(validBidRequests, 'userIdAsEids'); - const schain = getFirstWithKey(validBidRequests, 'schain'); + const schain = getFirstWithKey(validBidRequests, 'ortb2.source.ext.schain'); const request = { // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781 auctionId: bidderRequest.auctionId, diff --git a/modules/colossussspBidAdapter.js b/modules/colossussspBidAdapter.js index e93d6a2de27..66093ddd480 100644 --- a/modules/colossussspBidAdapter.js +++ b/modules/colossussspBidAdapter.js @@ -144,8 +144,9 @@ export const spec = { floor: {} }; - if (bid.schain) { - placement.schain = bid.schain; + const schain = bid?.ortb2?.source?.ext?.schain; + if (schain) { + placement.schain = schain; } let gpid = deepAccess(bid, 'ortb2Imp.ext.gpid'); if (gpid) { diff --git a/modules/connectadBidAdapter.js b/modules/connectadBidAdapter.js index f214bf5ca2c..5bad4879beb 100644 --- a/modules/connectadBidAdapter.js +++ b/modules/connectadBidAdapter.js @@ -67,8 +67,9 @@ export const spec = { } // adding schain object - if (validBidRequests[0].schain) { - deepSetValue(data, 'source.ext.schain', validBidRequests[0].schain); + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + deepSetValue(data, 'source.ext.schain', schain); } // Attaching GDPR Consent Params diff --git a/modules/consumableBidAdapter.js b/modules/consumableBidAdapter.js index e01078890f9..b85322e4eb7 100644 --- a/modules/consumableBidAdapter.js +++ b/modules/consumableBidAdapter.js @@ -82,8 +82,9 @@ export const spec = { data.ccpa = bidderRequest.uspConsent; } - if (bidderRequest && bidderRequest.schain) { - data.schain = bidderRequest.schain; + const schain = bidderRequest?.ortb2?.source?.ext?.schain; + if (schain) { + data.schain = schain; } if (config.getConfig('coppa')) { diff --git a/modules/cpmstarBidAdapter.js b/modules/cpmstarBidAdapter.js index 772cb8c537c..b9d61eaf543 100755 --- a/modules/cpmstarBidAdapter.js +++ b/modules/cpmstarBidAdapter.js @@ -71,8 +71,8 @@ export const spec = { url.searchParams.set('requestid', bidRequest.bidId); url.searchParams.set('referer', referer); - if (bidRequest.schain && bidRequest.schain.nodes) { - var schain = bidRequest.schain; + const schain = bidRequest?.ortb2?.source?.ext?.schain; + if (schain && schain.nodes) { var schainString = ''; schainString += schain.ver + ',' + schain.complete; for (var i2 = 0; i2 < schain.nodes.length; i2++) { diff --git a/modules/craftBidAdapter.js b/modules/craftBidAdapter.js index 6ba5ffa038d..d4b45153fca 100644 --- a/modules/craftBidAdapter.js +++ b/modules/craftBidAdapter.js @@ -27,7 +27,7 @@ export const spec = { bidRequests = convertOrtbRequestToProprietaryNative(bidRequests); const bidRequest = bidRequests[0]; const tags = bidRequests.map(bidToTag); - const schain = bidRequest.schain; + const schain = bidRequest?.ortb2?.source?.ext?.schain; const payload = { tags: [...tags], ua: navigator.userAgent, diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js index 3cd974b2b13..3a80779fbf5 100644 --- a/modules/datablocksBidAdapter.js +++ b/modules/datablocksBidAdapter.js @@ -357,7 +357,7 @@ export const spec = { domain: window.location.host, // TODO: is 'page' the right value here? page: bidderRequest.refererInfo.page, - schain: validRequests[0].schain || {}, + schain: validRequests[0]?.ortb2?.source?.ext?.schain || {}, ext: { p_domain: bidderRequest.refererInfo.domain, rt: bidderRequest.refererInfo.reachedTop, diff --git a/modules/dianomiBidAdapter.js b/modules/dianomiBidAdapter.js index 5e43bf955ef..a91c5d777cd 100644 --- a/modules/dianomiBidAdapter.js +++ b/modules/dianomiBidAdapter.js @@ -121,7 +121,7 @@ export const spec = { const currency = getCurrencyFromBidderRequest(bidderRequest); const cur = currency && [currency]; const eids = setOnAny(validBidRequests, 'userIdAsEids'); - const schain = setOnAny(validBidRequests, 'schain'); + const schain = setOnAny(validBidRequests, 'ortb2.source.ext.schain'); const imp = validBidRequests.map((bid, id) => { bid.netRevenue = pt; diff --git a/modules/digitalMatterBidAdapter.js b/modules/digitalMatterBidAdapter.js index 34cf84eb9d3..e5acd9e98de 100644 --- a/modules/digitalMatterBidAdapter.js +++ b/modules/digitalMatterBidAdapter.js @@ -36,7 +36,7 @@ export const spec = { } const device = getDevice(common.device); - const schain = getByKey(validBidRequests, 'schain'); + const schain = getByKey(validBidRequests, 'ortb2.source.ext.schain'); const eids = getByKey(validBidRequests, 'userIdAsEids'); const currency = config.getConfig('currency') const cur = currency && [currency]; diff --git a/modules/distroscaleBidAdapter.js b/modules/distroscaleBidAdapter.js index be52023a0e0..911ac0dba35 100644 --- a/modules/distroscaleBidAdapter.js +++ b/modules/distroscaleBidAdapter.js @@ -197,8 +197,9 @@ export const spec = { } // adding schain object - if (validBidRequests[0].schain) { - deepSetValue(payload, 'source.schain', validBidRequests[0].schain); + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + deepSetValue(payload, 'source.ext.schain', schain); } // Attaching GDPR Consent Params diff --git a/modules/dspxBidAdapter.js b/modules/dspxBidAdapter.js index b72991617c6..54a1d240bc7 100644 --- a/modules/dspxBidAdapter.js +++ b/modules/dspxBidAdapter.js @@ -149,8 +149,9 @@ export const spec = { } // schain - if (bidRequest.schain) { - payload.schain = bidRequest.schain; + const schain = bidRequest?.ortb2?.source?.ext?.schain; + if (schain) { + payload.schain = schain; } // fill userId params diff --git a/modules/eplanningBidAdapter.js b/modules/eplanningBidAdapter.js index 5b3f55b9da6..a739ddc0e3c 100644 --- a/modules/eplanningBidAdapter.js +++ b/modules/eplanningBidAdapter.js @@ -41,7 +41,7 @@ export const spec = { const method = 'GET'; const dfpClientId = '1'; const sec = 'ROS'; - const schain = bidRequests[0].schain; + const schain = bidRequests[0]?.ortb2?.source?.ext?.schain; let url; let params; const urlConfig = getUrlConfig(bidRequests); diff --git a/modules/fluctBidAdapter.js b/modules/fluctBidAdapter.js index 8ed1b52bdb6..78d574ed43b 100644 --- a/modules/fluctBidAdapter.js +++ b/modules/fluctBidAdapter.js @@ -93,8 +93,9 @@ export const spec = { data.params = request.params; - if (request.schain) { - data.schain = request.schain; + const schain = request?.ortb2?.source?.ext?.schain; + if (schain) { + data.schain = schain; } const searchParams = new URLSearchParams({ diff --git a/modules/freewheel-sspBidAdapter.js b/modules/freewheel-sspBidAdapter.js index fc85edc483b..d30be635a50 100644 --- a/modules/freewheel-sspBidAdapter.js +++ b/modules/freewheel-sspBidAdapter.js @@ -399,7 +399,7 @@ export const spec = { } // Add schain object - var schain = currentBidRequest.schain; + var schain = currentBidRequest?.ortb2?.source?.ext?.schain; if (schain) { try { requestParams.schain = JSON.stringify(schain); diff --git a/modules/gamoshiBidAdapter.js b/modules/gamoshiBidAdapter.js index 798cb5acca9..fe0eb5238a5 100644 --- a/modules/gamoshiBidAdapter.js +++ b/modules/gamoshiBidAdapter.js @@ -112,8 +112,9 @@ export const spec = { deepSetValue(rtbBidRequest, 'regs.ext.gdpr', gdprConsent.consent_required === true ? 1 : 0); deepSetValue(rtbBidRequest, 'user.ext.consent', gdprConsent.consent_string); - if (validBidRequests[0].schain) { - deepSetValue(rtbBidRequest, 'source.ext.schain', validBidRequests[0].schain); + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + deepSetValue(rtbBidRequest, 'source.ext.schain', schain); } if (bidderRequest && bidderRequest.uspConsent) { diff --git a/modules/greenbidsBidAdapter.js b/modules/greenbidsBidAdapter.js index 0ece04fe11f..6dc0364df0d 100644 --- a/modules/greenbidsBidAdapter.js +++ b/modules/greenbidsBidAdapter.js @@ -76,8 +76,9 @@ export const spec = { const firstBidRequest = validBidRequests[0]; - if (firstBidRequest.schain) { - payload.schain = firstBidRequest.schain; + const schain = firstBidRequest?.ortb2?.source?.ext?.schain; + if (schain) { + payload.schain = schain; } hydratePayloadWithGppConsentData(payload, bidderRequest.gppConsent); diff --git a/modules/gridBidAdapter.js b/modules/gridBidAdapter.js index 244981ba94f..e860c292f93 100644 --- a/modules/gridBidAdapter.js +++ b/modules/gridBidAdapter.js @@ -115,7 +115,7 @@ export const spec = { bidderRequestId = bid.bidderRequestId; } if (!schain) { - schain = bid.schain; + schain = bid?.ortb2?.source?.ext?.schain; } if (!userIdAsEids) { userIdAsEids = bid.userIdAsEids; @@ -184,8 +184,10 @@ export const spec = { wrapper_version: '$prebid.version$' } }; - if (bid.schain) { - reqSource.ext.schain = bid.schain; + // Check for schain in the new location + const schain = bid?.ortb2?.source?.ext?.schain; + if (schain) { + reqSource.ext.schain = schain; } const request = { id: bid.bidderRequestId && bid.bidderRequestId.toString(), diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index ddf16e28c8f..df78ba808b8 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -366,7 +366,6 @@ function buildRequests(validBidRequests, bidderRequest) { bidId, mediaTypes = {}, params = {}, - schain, userId = {}, ortb2Imp, adUnitCode = '' @@ -489,6 +488,7 @@ function buildRequests(validBidRequests, bidderRequest) { if (coppa) { data.coppa = coppa; } + const schain = bidRequest?.ortb2?.source?.ext?.schain; if (schain && schain.nodes) { data.schain = _serializeSupplyChainObj(schain); } diff --git a/modules/holidBidAdapter.js b/modules/holidBidAdapter.js index abc8e0b403c..58172e204e1 100644 --- a/modules/holidBidAdapter.js +++ b/modules/holidBidAdapter.js @@ -32,7 +32,11 @@ export const spec = { return validBidRequests.map((bid) => { const requestData = { ...bid.ortb2, - source: { schain: bid.schain }, + source: { + ext: { + schain: bid?.ortb2?.source?.ext?.schain + } + }, id: bidderRequest.bidderRequestId, imp: [getImp(bid)], tmax: TMAX, diff --git a/modules/impactifyBidAdapter.js b/modules/impactifyBidAdapter.js index 38a57c4724a..7be716f4089 100644 --- a/modules/impactifyBidAdapter.js +++ b/modules/impactifyBidAdapter.js @@ -137,7 +137,7 @@ function createOpenRtbRequest(validBidRequests, bidderRequest) { } // Set SChain in request - let schain = deepAccess(validBidRequests, '0.schain'); + let schain = deepAccess(validBidRequests, '0.ortb2.source.ext.schain'); if (schain) request.source.ext = { schain: schain }; // Set Eids diff --git a/modules/insticatorBidAdapter.js b/modules/insticatorBidAdapter.js index f26cb8d311b..2aab5a9df03 100644 --- a/modules/insticatorBidAdapter.js +++ b/modules/insticatorBidAdapter.js @@ -355,9 +355,10 @@ function buildUser(bid) { } function extractSchain(bids, requestId) { - if (!bids || bids.length === 0 || !bids[0].schain) return; + if (!bids || bids.length === 0) return; - const schain = bids[0].schain; + const schain = bids[0]?.ortb2?.source?.ext?.schain; + if (!schain) return; if (schain && schain.nodes && schain.nodes.length && schain.nodes[0]) { schain.nodes[0].rid = requestId; } diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js index 065f891e234..c0185411f78 100644 --- a/modules/ixBidAdapter.js +++ b/modules/ixBidAdapter.js @@ -174,7 +174,7 @@ function setDisplayManager(imp, bid) { renderer = deepAccess(bid, 'renderer'); } - if (deepAccess(bid, 'schain', false)) { + if (deepAccess(bid, 'ortb2.source.ext.schain', false)) { imp.displaymanager = 'pbjs_wrapper'; } else if (renderer && typeof (renderer) === 'object') { if (renderer.url !== undefined) { @@ -860,9 +860,11 @@ function enrichRequest(r, bidderRequest, impressions, validBidRequests, userEids } // if an schain is provided, send it along - if (validBidRequests[0].schain) { - r.source.ext = {}; - r.source.ext.schain = validBidRequests[0].schain; + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + r.source = r.source || {}; + r.source.ext = r.source.ext || {}; + r.source.ext.schain = schain; } if (userEids.length > 0) { diff --git a/modules/jixieBidAdapter.js b/modules/jixieBidAdapter.js index d4901b097c5..b0c47d2f841 100644 --- a/modules/jixieBidAdapter.js +++ b/modules/jixieBidAdapter.js @@ -209,7 +209,7 @@ export const spec = { let ids = fetchIds_(jxCfg); let eids = []; let miscDims = internal.getMiscDims(); - let schain = deepAccess(validBidRequests[0], 'schain'); + let schain = deepAccess(validBidRequests[0], 'ortb2.source.ext.schain'); let eids1 = validBidRequests[0].userIdAsEids; // all available user ids are sent to our backend in the standard array layout: diff --git a/modules/justpremiumBidAdapter.js b/modules/justpremiumBidAdapter.js index 2ed2d544a34..081a3f44a27 100644 --- a/modules/justpremiumBidAdapter.js +++ b/modules/justpremiumBidAdapter.js @@ -69,8 +69,9 @@ export const spec = { jp_adapter: JP_ADAPTER_VERSION } - if (validBidRequests[0].schain) { - payload.schain = validBidRequests[0].schain; + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + payload.schain = schain; } const payloadString = JSON.stringify(payload) diff --git a/modules/jwplayerBidAdapter.js b/modules/jwplayerBidAdapter.js index c58eed8ffb8..20fd585a08c 100644 --- a/modules/jwplayerBidAdapter.js +++ b/modules/jwplayerBidAdapter.js @@ -185,8 +185,9 @@ function getBidAdapter() { deepSetValue(openrtbRequest, 'regs.ext.us_privacy', bidderRequest.uspConsent); } - if (bidRequest.schain) { - deepSetValue(openrtbRequest, 'source.schain', bidRequest.schain); + const schain = bidRequest?.ortb2?.source?.ext?.schain; + if (schain) { + deepSetValue(openrtbRequest, 'source.schain', schain); } openrtbRequest.tmax = bidderRequest.timeout || 200; diff --git a/modules/kargoBidAdapter.js b/modules/kargoBidAdapter.js index 229949ddaf3..cd6573869fd 100644 --- a/modules/kargoBidAdapter.js +++ b/modules/kargoBidAdapter.js @@ -104,9 +104,10 @@ function buildRequests(validBidRequests, bidderRequest) { krakenParams.site = { cat: firstBidRequest.ortb2.site.cat }; } - // Add schain - if (firstBidRequest.schain && firstBidRequest.schain.nodes) { - krakenParams.schain = firstBidRequest.schain + // Add schain - check for schain in the new location + const schain = firstBidRequest?.ortb2?.source?.ext?.schain; + if (schain && schain.nodes) { + krakenParams.schain = schain } // Add user data object if available diff --git a/modules/kubientBidAdapter.js b/modules/kubientBidAdapter.js index 8ccfa4ab059..b66b4e851d5 100644 --- a/modules/kubientBidAdapter.js +++ b/modules/kubientBidAdapter.js @@ -49,8 +49,9 @@ export const spec = { adSlot.video = bid.mediaTypes.video; } - if (bid.schain) { - adSlot.schain = bid.schain; + const schain = bid?.ortb2?.source?.ext?.schain; + if (schain) { + adSlot.schain = schain; } let data = { diff --git a/modules/lemmaDigitalBidAdapter.js b/modules/lemmaDigitalBidAdapter.js index d8a9614d5c0..c2b9af2bb5f 100644 --- a/modules/lemmaDigitalBidAdapter.js +++ b/modules/lemmaDigitalBidAdapter.js @@ -483,7 +483,7 @@ export var spec = { return { pchain: params.pchain, ext: { - schain: request.schain + schain: request?.ortb2?.source?.ext?.schain }, }; } diff --git a/modules/limelightDigitalBidAdapter.js b/modules/limelightDigitalBidAdapter.js index bf170738d65..d5318440cc2 100644 --- a/modules/limelightDigitalBidAdapter.js +++ b/modules/limelightDigitalBidAdapter.js @@ -179,7 +179,7 @@ function buildPlacement(bidRequest) { ortb2Imp: bidRequest.ortb2Imp, publisherId: bidRequest.params.publisherId, userIdAsEids: bidRequest.userIdAsEids, - supplyChain: bidRequest.schain, + supplyChain: bidRequest?.ortb2?.source?.ext?.schain, custom1: bidRequest.params.custom1, custom2: bidRequest.params.custom2, custom3: bidRequest.params.custom3, diff --git a/modules/livewrappedBidAdapter.js b/modules/livewrappedBidAdapter.js index 9276671bf87..cdddfd688e9 100644 --- a/modules/livewrappedBidAdapter.js +++ b/modules/livewrappedBidAdapter.js @@ -63,7 +63,7 @@ export const spec = { const ifa = ((bidRequests) || []).find(hasIfaParam); const bundle = ((bidRequests) || []).find(hasBundleParam); const tid = ((bidRequests) || []).find(hasTidParam); - const schain = bidRequests[0].schain; + const schain = bidRequests[0]?.ortb2?.source?.ext?.schain; let ortb2 = bidderRequest.ortb2; const eids = handleEids(bidRequests); bidUrl = bidUrl ? bidUrl.params.bidUrl : URL; diff --git a/modules/lkqdBidAdapter.js b/modules/lkqdBidAdapter.js index a92e431f80a..535dbbf759b 100644 --- a/modules/lkqdBidAdapter.js +++ b/modules/lkqdBidAdapter.js @@ -110,10 +110,11 @@ export const spec = { requestData.device.ifa = bid.params.idfa || bid.params.aid; } - if (bid.schain) { + const schain = bid?.ortb2?.source?.ext?.schain; + if (schain) { requestData.source = { ext: { - schain: bid.schain + schain: schain } }; } else if (bid.params.schain) { diff --git a/modules/lockerdomeBidAdapter.js b/modules/lockerdomeBidAdapter.js index 5038eadce30..e0be50e6d1c 100644 --- a/modules/lockerdomeBidAdapter.js +++ b/modules/lockerdomeBidAdapter.js @@ -12,7 +12,8 @@ export const spec = { let schain; const adUnitBidRequests = bidRequests.map(function (bid) { - if (bid.schain) schain = schain || bid.schain; + const bidSchain = bid?.ortb2?.source?.ext?.schain; + if (bidSchain) schain = schain || bidSchain; return { requestId: bid.bidId, adUnitCode: bid.adUnitCode, diff --git a/modules/loganBidAdapter.js b/modules/loganBidAdapter.js index 4e2652e452f..dd092813eb1 100644 --- a/modules/loganBidAdapter.js +++ b/modules/loganBidAdapter.js @@ -39,7 +39,7 @@ export const spec = { const placement = { placementId: bid.params.placementId, bidId: bid.bidId, - schain: bid.schain || {}, + schain: bid?.ortb2?.source?.ext?.schain || {}, bidfloor: getBidFloor(bid) }; const mediaType = bid.mediaTypes; diff --git a/modules/logicadBidAdapter.js b/modules/logicadBidAdapter.js index 8cf4a8352de..2b78082c184 100644 --- a/modules/logicadBidAdapter.js +++ b/modules/logicadBidAdapter.js @@ -104,8 +104,9 @@ function newBidRequest(bidRequest, bidderRequest) { data.userData = userData; } - if (bidRequest.schain) { - data.schain = bidRequest.schain; + const schain = bidRequest?.ortb2?.source?.ext?.schain; + if (schain) { + data.schain = schain; } return data; diff --git a/modules/luceadBidAdapter.js b/modules/luceadBidAdapter.js index ffc2307bcb8..703384b9e6d 100755 --- a/modules/luceadBidAdapter.js +++ b/modules/luceadBidAdapter.js @@ -75,7 +75,7 @@ function buildRequests(bidRequests, bidderRequest) { sizes: bidRequest.sizes, media_types: bidRequest.mediaTypes, placement_id: bidRequest.params.placementId, - schain: bidRequest.schain, + schain: bidRequest?.ortb2?.source?.ext?.schain, }; }), }), diff --git a/modules/marsmediaBidAdapter.js b/modules/marsmediaBidAdapter.js index 81e78ba87b1..850ed6eaa3a 100644 --- a/modules/marsmediaBidAdapter.js +++ b/modules/marsmediaBidAdapter.js @@ -207,8 +207,9 @@ function MarsmediaAdapter() { } } }; - if (BRs[0].schain) { - deepSetValue(bid, 'source.ext.schain', BRs[0].schain); + const schain = BRs[0]?.ortb2?.source?.ext?.schain; + if (schain) { + deepSetValue(bid, 'source.ext.schain', schain); } if (bidderRequest.uspConsent) { deepSetValue(bid, 'regs.ext.us_privacy', bidderRequest.uspConsent) diff --git a/modules/mediafuseBidAdapter.js b/modules/mediafuseBidAdapter.js index 022e569bb86..a951a53db19 100644 --- a/modules/mediafuseBidAdapter.js +++ b/modules/mediafuseBidAdapter.js @@ -186,7 +186,7 @@ export const spec = { const memberIdBid = ((bidRequests) || []).find(hasMemberId); const member = memberIdBid ? parseInt(memberIdBid.params.member, 10) : 0; - const schain = bidRequests[0].schain; + const schain = bidRequests[0]?.ortb2?.source?.ext?.schain; const omidSupport = ((bidRequests) || []).find(hasOmidSupport); const payload = { diff --git a/modules/mediakeysBidAdapter.js b/modules/mediakeysBidAdapter.js index bdf7b5f8537..f4979bea396 100644 --- a/modules/mediakeysBidAdapter.js +++ b/modules/mediakeysBidAdapter.js @@ -618,8 +618,9 @@ export const spec = { payload.imp.push(imp); }); - if (validBidRequests[0].schain) { - deepSetValue(payload, 'source.ext.schain', validBidRequests[0].schain); + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + deepSetValue(payload, 'source.ext.schain', schain); } if (bidderRequest && bidderRequest.gdprConsent) { diff --git a/modules/medianetBidAdapter.js b/modules/medianetBidAdapter.js index 757ab9f81aa..9f2cf150d51 100644 --- a/modules/medianetBidAdapter.js +++ b/modules/medianetBidAdapter.js @@ -162,7 +162,7 @@ function extParams(bidRequest, bidderRequests) { const gdpr = deepAccess(bidderRequests, 'gdprConsent'); const uspConsent = deepAccess(bidderRequests, 'uspConsent'); const userId = deepAccess(bidRequest, 'userId'); - const sChain = deepAccess(bidRequest, 'schain') || {}; + const sChain = deepAccess(bidRequest, 'ortb2.source.ext.schain') || {}; const windowSize = spec.getWindowSize(); const gdprApplies = !!(gdpr && gdpr.gdprApplies); const uspApplies = !!(uspConsent); diff --git a/modules/mediasquareBidAdapter.js b/modules/mediasquareBidAdapter.js index 59cff8ace55..d75cf18e729 100644 --- a/modules/mediasquareBidAdapter.js +++ b/modules/mediasquareBidAdapter.js @@ -89,7 +89,7 @@ export const spec = { }; } if (bidderRequest.uspConsent) { payload.uspConsent = bidderRequest.uspConsent; } - if (bidderRequest.schain) { payload.schain = bidderRequest.schain; } + if (bidderRequest?.ortb2?.source?.ext?.schain) { payload.schain = bidderRequest.ortb2.source.ext.schain; } if (bidderRequest.userIdAsEids) { payload.eids = bidderRequest.userIdAsEids }; if (bidderRequest.ortb2?.regs?.ext?.dsa) { payload.dsa = bidderRequest.ortb2.regs.ext.dsa } if (bidderRequest.ortb2) { payload.ortb2 = bidderRequest.ortb2 } diff --git a/modules/mgidBidAdapter.js b/modules/mgidBidAdapter.js index 86cd3fb8250..7a0856a2859 100644 --- a/modules/mgidBidAdapter.js +++ b/modules/mgidBidAdapter.js @@ -304,7 +304,7 @@ export const spec = { deepSetValue(request, 'regs.coppa', 1); } } - const schain = setOnAny(validBidRequests, 'schain'); + const schain = setOnAny(validBidRequests, 'ortb2.source.ext.schain'); if (schain) { deepSetValue(request, 'source.ext.schain', schain); } diff --git a/modules/michaoBidAdapter.js b/modules/michaoBidAdapter.js index 56c073cddde..ff95b509b3b 100644 --- a/modules/michaoBidAdapter.js +++ b/modules/michaoBidAdapter.js @@ -217,8 +217,9 @@ const converter = ortbConverter({ 'site.ext.michao.site', bidRequest.params.site.toString() ); - if (bidRequest?.schain) { - deepSetValue(openRTBBidRequest, 'source.schain', bidRequest.schain); + const schain = bidRequest?.ortb2?.source?.ext?.schain; + if (schain) { + deepSetValue(openRTBBidRequest, 'source.schain', schain); } if (bidRequest.params?.partner) { diff --git a/modules/missenaBidAdapter.js b/modules/missenaBidAdapter.js index 0d2054ca09f..fc7bdaaf5c7 100644 --- a/modules/missenaBidAdapter.js +++ b/modules/missenaBidAdapter.js @@ -68,7 +68,7 @@ function toPayload(bidRequest, bidderRequest) { payload.floor = bidFloor?.floor; payload.floor_currency = bidFloor?.currency; payload.currency = getCurrencyFromBidderRequest(bidderRequest); - payload.schain = bidRequest.schain; + payload.schain = bidRequest?.ortb2?.source?.ext?.schain; payload.autoplay = isAutoplayEnabled() === true ? 1 : 0; payload.screen = { height: getWinDimensions().screen.height, width: getWinDimensions().screen.width }; payload.viewport = getViewportSize(); diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index d4886e9d2ac..a6f90c272f4 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -508,8 +508,7 @@ function getDeviceObj() { } export function getSourceObj(validBidRequests, bidderRequest) { - const schain = validBidRequests?.[0]?.schain || - (bidderRequest?.ortb2?.source && (bidderRequest?.ortb2?.source?.schain || bidderRequest?.ortb2?.source?.ext?.schain)); + const schain = validBidRequests?.[0]?.ortb2?.source?.ext?.schain || bidderRequest?.ortb2?.source?.schain || bidderRequest?.ortb2?.source?.ext?.schain; if (!schain) return; diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js index 921fbb25d8a..8b7f9cae319 100644 --- a/modules/nobidBidAdapter.js +++ b/modules/nobidBidAdapter.js @@ -86,10 +86,11 @@ function nobidBuildRequests(bids, bidderRequest) { return gppConsent; } var schain = function(bids) { - if (bids && bids.length > 0) { - return bids[0].schain + try { + return bids[0]?.ortb2?.source?.ext?.schain; + } catch (e) { + return null; } - return null; } var coppa = function() { if (config.getConfig('coppa') === true) { diff --git a/modules/omsBidAdapter.js b/modules/omsBidAdapter.js index 0b9ac002bb0..20a9336b7e3 100644 --- a/modules/omsBidAdapter.js +++ b/modules/omsBidAdapter.js @@ -114,8 +114,9 @@ function buildRequests(bidReqs, bidderRequest) { deepSetValue(payload, 'regs.coppa', 1); } - if (bidReqs?.[0]?.schain) { - deepSetValue(payload, 'source.ext.schain', bidReqs[0].schain) + const schain = bidReqs?.[0]?.ortb2?.source?.ext?.schain; + if (schain) { + deepSetValue(payload, 'source.ext.schain', schain) } if (bidderRequest?.ortb2?.user) { diff --git a/modules/onetagBidAdapter.js b/modules/onetagBidAdapter.js index 656bb50fa2a..0fa73a8631d 100644 --- a/modules/onetagBidAdapter.js +++ b/modules/onetagBidAdapter.js @@ -132,8 +132,9 @@ function buildRequests(validBidRequests, bidderRequest) { if (validBidRequests && validBidRequests.length !== 0 && validBidRequests[0].userIdAsEids) { payload.userId = validBidRequests[0].userIdAsEids; } - if (validBidRequests && validBidRequests.length !== 0 && validBidRequests[0].schain && isSchainValid(validBidRequests[0].schain)) { - payload.schain = validBidRequests[0].schain; + const schain = validBidRequests?.[0]?.ortb2?.source?.ext?.schain; + if (validBidRequests && validBidRequests.length !== 0 && schain && isSchainValid(schain)) { + payload.schain = schain; } try { if (storage.hasLocalStorage()) { diff --git a/modules/opscoBidAdapter.js b/modules/opscoBidAdapter.js index 2ad14227804..4ddb548c0f1 100644 --- a/modules/opscoBidAdapter.js +++ b/modules/opscoBidAdapter.js @@ -59,9 +59,10 @@ export const spec = { deepSetValue(payload, 'user.ext.eids', eids); } - const schainData = deepAccess(validBidRequests[0], 'schain.nodes'); + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + const schainData = schain?.nodes; if (isArray(schainData) && schainData.length > 0) { - deepSetValue(payload, 'source.ext.schain', validBidRequests[0].schain); + deepSetValue(payload, 'source.ext.schain', schain); } if (bidderRequest.uspConsent) { diff --git a/modules/optidigitalBidAdapter.js b/modules/optidigitalBidAdapter.js index b51c8ef4403..7f86dd93d6c 100755 --- a/modules/optidigitalBidAdapter.js +++ b/modules/optidigitalBidAdapter.js @@ -74,8 +74,9 @@ export const spec = { payload.pageTemplate = validBidRequests[0].params.pageTemplate; } - if (validBidRequests[0].schain) { - payload.schain = validBidRequests[0].schain; + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + payload.schain = schain; } const gdpr = deepAccess(bidderRequest, 'gdprConsent'); diff --git a/modules/ozoneBidAdapter.js b/modules/ozoneBidAdapter.js index ead659a7f3b..1992cfcefe5 100644 --- a/modules/ozoneBidAdapter.js +++ b/modules/ozoneBidAdapter.js @@ -330,8 +330,8 @@ export const spec = { deepSetValue(obj, `ext.${whitelabelBidder}.customData.0.targeting`, fpd.site); } } - if (!schain && deepAccess(ozoneBidRequest, 'schain')) { - schain = ozoneBidRequest.schain; + if (!schain && deepAccess(ozoneBidRequest, 'ortb2.source.ext.schain')) { + schain = ozoneBidRequest.ortb2.source.ext.schain; } let gpid = deepAccess(ozoneBidRequest, 'ortb2Imp.ext.gpid'); if (gpid) { diff --git a/modules/pixfutureBidAdapter.js b/modules/pixfutureBidAdapter.js index 72b97b69f7c..ff2d50398e0 100644 --- a/modules/pixfutureBidAdapter.js +++ b/modules/pixfutureBidAdapter.js @@ -74,7 +74,7 @@ export const spec = { }); } - const schain = validBidRequests[0].schain; + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; const payload = { tags: [...tags], diff --git a/modules/prebidServerBidAdapter/ortbConverter.js b/modules/prebidServerBidAdapter/ortbConverter.js index b78c59b2756..003bf2e9235 100644 --- a/modules/prebidServerBidAdapter/ortbConverter.js +++ b/modules/prebidServerBidAdapter/ortbConverter.js @@ -205,13 +205,9 @@ const PBS_CONVERTER = ortbConverter({ if (fpdConfigs.length) { deepSetValue(ortbRequest, 'ext.prebid.bidderconfig', fpdConfigs); } - }, - extPrebidAliases(orig, ortbRequest, proxyBidderRequest, context) { - // override alias processing to do it for each bidder in the request - context.actualBidderRequests.forEach(req => orig(ortbRequest, req, context)); - }, - sourceExtSchain(orig, ortbRequest, proxyBidderRequest, context) { - // pass schains in ext.prebid.schains + + // Handle schain information after FPD processing + // Collect schains from bidder requests and organize into ext.prebid.schains let chains = ortbRequest?.ext?.prebid?.schains || []; const chainBidders = new Set(chains.flatMap((item) => item.bidders)); @@ -221,7 +217,7 @@ const PBS_CONVERTER = ortbConverter({ .filter((req) => !chainBidders.has(req.bidderCode)) // schain defined in s2sConfig.extPrebid takes precedence .map((req) => ({ bidders: [req.bidderCode], - schain: req?.bids?.[0]?.schain + schain: req?.bids?.[0]?.ortb2?.source?.schain }))) .filter(({bidders, schain}) => bidders?.length > 0 && schain) .reduce((chains, {bidders, schain}) => { @@ -237,6 +233,10 @@ const PBS_CONVERTER = ortbConverter({ if (chains.length) { deepSetValue(ortbRequest, 'ext.prebid.schains', chains); } + }, + extPrebidAliases(orig, ortbRequest, proxyBidderRequest, context) { + // override alias processing to do it for each bidder in the request + context.actualBidderRequests.forEach(req => orig(ortbRequest, req, context)); } }, [RESPONSE]: { diff --git a/modules/prismaBidAdapter.js b/modules/prismaBidAdapter.js index efa390bc9bd..8506d29f82b 100644 --- a/modules/prismaBidAdapter.js +++ b/modules/prismaBidAdapter.js @@ -79,7 +79,8 @@ export const spec = { payload.gdprConsent = ''; } if (bidderRequest.uspConsent) { payload.uspConsent = bidderRequest.uspConsent; } - if (bidderRequest.schain) { payload.schain = bidderRequest.schain; } + const schain = bidderRequest?.ortb2?.source?.ext?.schain; + if (schain) { payload.schain = schain; } if (userEids !== null) payload.userEids = userEids; }; payload.connectionType = getConnectionType(); diff --git a/modules/pubgeniusBidAdapter.js b/modules/pubgeniusBidAdapter.js index 19260e65e60..7cb4d2df127 100644 --- a/modules/pubgeniusBidAdapter.js +++ b/modules/pubgeniusBidAdapter.js @@ -71,7 +71,7 @@ export const spec = { deepSetValue(data, 'regs.ext.us_privacy', usp); } - const schain = bidRequests[0].schain; + const schain = bidRequests[0]?.ortb2?.source?.ext?.schain; if (schain) { deepSetValue(data, 'source.ext.schain', schain); } diff --git a/modules/pubwiseBidAdapter.js b/modules/pubwiseBidAdapter.js index 291b637749a..01734e514b5 100644 --- a/modules/pubwiseBidAdapter.js +++ b/modules/pubwiseBidAdapter.js @@ -254,9 +254,10 @@ export const spec = { // passing transactionId in source.tid deepSetValue(payload, 'source.tid', bidderRequest?.ortb2?.source?.tid); - // schain - if (validBidRequests[0].schain) { - deepSetValue(payload, 'source.ext.schain', validBidRequests[0].schain); + // schain - check for schain in the new location + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + deepSetValue(payload, 'source.ext.schain', schain); } // gdpr consent diff --git a/modules/qwarryBidAdapter.js b/modules/qwarryBidAdapter.js index 4b3e8fa8a19..73191f099a0 100644 --- a/modules/qwarryBidAdapter.js +++ b/modules/qwarryBidAdapter.js @@ -29,7 +29,7 @@ export const spec = { requestId: bidderRequest.bidderRequestId, bids, referer: bidderRequest.refererInfo.page, - schain: validBidRequests[0].schain + schain: validBidRequests[0]?.ortb2?.source?.ext?.schain } if (bidderRequest && bidderRequest.gdprConsent) { diff --git a/modules/rhythmoneBidAdapter.js b/modules/rhythmoneBidAdapter.js index 3ab8b79df81..f710c1a079e 100644 --- a/modules/rhythmoneBidAdapter.js +++ b/modules/rhythmoneBidAdapter.js @@ -168,10 +168,11 @@ function RhythmOneBidAdapter() { } } }; - if (BRs[0].schain) { + const schain = BRs[0]?.ortb2?.source?.ext?.schain; + if (schain) { bid.source = { 'ext': { - 'schain': BRs[0].schain + 'schain': schain } } } diff --git a/modules/richaudienceBidAdapter.js b/modules/richaudienceBidAdapter.js index 9bd395fc166..a241b2fa19e 100644 --- a/modules/richaudienceBidAdapter.js +++ b/modules/richaudienceBidAdapter.js @@ -54,7 +54,7 @@ export const spec = { scr_rsl: raiGetResolution(), cpuc: (typeof window.navigator != 'undefined' ? window.navigator.hardwareConcurrency : null), kws: bid.params.keywords, - schain: bid.schain, + schain: bid?.ortb2?.source?.ext?.schain, gpid: raiSetPbAdSlot(bid), dsa: setDSA(bid), userData: deepAccess(bid, 'ortb2.user.data') diff --git a/modules/rtbhouseBidAdapter.js b/modules/rtbhouseBidAdapter.js index 5ce384d4f3d..fe43d462ddd 100644 --- a/modules/rtbhouseBidAdapter.js +++ b/modules/rtbhouseBidAdapter.js @@ -53,8 +53,9 @@ export const spec = { request.regs = {ext: {gdpr: gdpr}}; request.user = {ext: {consent: consentStr}}; } - if (validBidRequests[0].schain) { - const schain = mapSchain(validBidRequests[0].schain); + const bidSchain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (bidSchain) { + const schain = mapSchain(bidSchain); if (schain) { request.ext = { schain: schain, diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index 516a1112025..d320e2710ba 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -617,8 +617,9 @@ export const spec = { } // if SupplyChain is supplied and contains all required fields - if (bidRequest.schain && hasValidSupplyChainParams(bidRequest.schain)) { - data.rp_schain = spec.serializeSupplyChain(bidRequest.schain); + const schain = bidRequest?.ortb2?.source?.ext?.schain; + if (schain && hasValidSupplyChainParams(schain)) { + data.rp_schain = spec.serializeSupplyChain(schain); } return data; diff --git a/modules/schain.js b/modules/schain.js deleted file mode 100644 index 726679b133f..00000000000 --- a/modules/schain.js +++ /dev/null @@ -1,207 +0,0 @@ -import {config} from '../src/config.js'; -import adapterManager from '../src/adapterManager.js'; -import { - _each, - deepAccess, - deepClone, - deepSetValue, - isArray, - isInteger, - isNumber, - isPlainObject, - isStr, - logError, - logWarn -} from '../src/utils.js'; -import {registerOrtbProcessor, REQUEST} from '../src/pbjsORTB.js'; - -// https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/supplychainobject.md - -const schainErrorPrefix = 'Invalid schain object found: '; -const shouldBeAString = ' should be a string'; -const shouldBeAnInteger = ' should be an Integer'; -const shouldBeAnObject = ' should be an object'; -const shouldBeAnArray = ' should be an Array'; -const MODE = { - STRICT: 'strict', - RELAXED: 'relaxed', - OFF: 'off' -}; -const MODES = []; // an array of modes -_each(MODE, mode => MODES.push(mode)); - -// validate the supply chain object -export function isSchainObjectValid(schainObject, returnOnError) { - let failPrefix = 'Detected something wrong within an schain config:'; - let failMsg = ''; - - function appendFailMsg(msg) { - failMsg += '\n' + msg; - } - - function printFailMsg() { - if (returnOnError === true) { - logError(failPrefix, schainObject, failMsg); - } else { - logWarn(failPrefix, schainObject, failMsg); - } - } - - if (!isPlainObject(schainObject)) { - appendFailMsg(`schain.config` + shouldBeAnObject); - printFailMsg(); - if (returnOnError) return false; - } - - // complete: Integer - if (!isNumber(schainObject.complete) || !isInteger(schainObject.complete)) { - appendFailMsg(`schain.config.complete` + shouldBeAnInteger); - } - - // ver: String - if (!isStr(schainObject.ver)) { - appendFailMsg(`schain.config.ver` + shouldBeAString); - } - - // ext: Object [optional] - if (schainObject.hasOwnProperty('ext')) { - if (!isPlainObject(schainObject.ext)) { - appendFailMsg(`schain.config.ext` + shouldBeAnObject); - } - } - - // nodes: Array of objects - if (!isArray(schainObject.nodes)) { - appendFailMsg(`schain.config.nodes` + shouldBeAnArray); - printFailMsg(); - if (returnOnError) return false; - } else { - schainObject.nodes.forEach((node, index) => { - // asi: String - if (!isStr(node.asi)) { - appendFailMsg(`schain.config.nodes[${index}].asi` + shouldBeAString); - } - - // sid: String - if (!isStr(node.sid)) { - appendFailMsg(`schain.config.nodes[${index}].sid` + shouldBeAString); - } - - // hp: Integer - if (!isNumber(node.hp) || !isInteger(node.hp)) { - appendFailMsg(`schain.config.nodes[${index}].hp` + shouldBeAnInteger); - } - - // rid: String [Optional] - if (node.hasOwnProperty('rid')) { - if (!isStr(node.rid)) { - appendFailMsg(`schain.config.nodes[${index}].rid` + shouldBeAString); - } - } - - // name: String [Optional] - if (node.hasOwnProperty('name')) { - if (!isStr(node.name)) { - appendFailMsg(`schain.config.nodes[${index}].name` + shouldBeAString); - } - } - - // domain: String [Optional] - if (node.hasOwnProperty('domain')) { - if (!isStr(node.domain)) { - appendFailMsg(`schain.config.nodes[${index}].domain` + shouldBeAString); - } - } - - // ext: Object [Optional] - if (node.hasOwnProperty('ext')) { - if (!isPlainObject(node.ext)) { - appendFailMsg(`schain.config.nodes[${index}].ext` + shouldBeAnObject); - } - } - }); - } - - if (failMsg.length > 0) { - printFailMsg(); - if (returnOnError) { - return false; - } - } - - return true; -} - -export function isValidSchainConfig(schainObject) { - if (schainObject === undefined) { - return false; - } - if (!isPlainObject(schainObject)) { - logError(schainErrorPrefix + 'the following schain config will not be used as schain is not an object.', schainObject); - return false; - } - return true; -} - -function resolveSchainConfig(schainObject, bidder) { - let mode = MODE.STRICT; - - if (isValidSchainConfig(schainObject)) { - if (isStr(schainObject.validation) && MODES.indexOf(schainObject.validation) != -1) { - mode = schainObject.validation; - } - if (mode === MODE.OFF) { - // no need to validate - return schainObject.config; - } else { - // if strict mode and config is invalid, reject config + throw error; otherwise allow config to go through - if (isSchainObjectValid(schainObject.config, !!(mode === MODE.STRICT))) { - return schainObject.config; - } else { - logError(schainErrorPrefix + `due to the 'strict' validation setting, this schain config will not be passed to bidder '${bidder}'. See above error for details.`); - } - } - } - return null; -} - -export function makeBidRequestsHook(fn, bidderRequests) { - function getSchainForBidder(bidder) { - let bidderSchain = bidderConfigs[bidder] && bidderConfigs[bidder].schain; - return bidderSchain || globalSchainConfig; - } - - const globalSchainConfig = config.getConfig('schain'); - const bidderConfigs = config.getBidderConfig(); - - bidderRequests.forEach(bidderRequest => { - let bidder = bidderRequest.bidderCode; - let schainConfig = getSchainForBidder(bidder); - - bidderRequest.bids.forEach(bid => { - let result = resolveSchainConfig(schainConfig, bidder); - if (result) { - bid.schain = deepClone(result); - } - }); - }); - - fn(bidderRequests); -} - -export function init() { - adapterManager.makeBidRequests.after(makeBidRequestsHook); -} - -init() - -export function setOrtbSourceExtSchain(ortbRequest, bidderRequest, context) { - if (!deepAccess(ortbRequest, 'source.ext.schain')) { - const schain = deepAccess(context, 'bidRequests.0.schain'); - if (schain) { - deepSetValue(ortbRequest, 'source.ext.schain', schain); - } - } -} - -registerOrtbProcessor({type: REQUEST, name: 'sourceExtSchain', fn: setOrtbSourceExtSchain}); diff --git a/modules/schain.md b/modules/schain.md deleted file mode 100644 index f43cf0f0d07..00000000000 --- a/modules/schain.md +++ /dev/null @@ -1,51 +0,0 @@ -# schain module - -Aggregators who manage Prebid wrappers on behalf of multiple publishers and handle payment on behalf of the publishers -need to declare their intermediary status in the Supply Chain Object. As the Supply Chain Object spec prohibits SSPs from adding -upstream intermediaries, Prebid requests in this case need to come with the schain information. In this use case, it's cumbersome -to have every bidder in the wrapper separately configured the same schain information. - -Refer: -- https://iabtechlab.com/sellers-json/ -- https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/supplychainobject.md - -## Sample code for passing the schain object -``` -pbjs.setConfig( { - "schain": { - "validation": "strict", - "config": { - "ver":"1.0", - "complete": 1, - "nodes": [ - { - "asi":"indirectseller.com", - "sid":"00001", - "hp":1 - }, - - { - "asi":"indirectseller-2.com", - "sid":"00002", - "hp":1 - } - ] - } - } -}); -``` - -## Workflow -The schain module is not enabled by default as it may not be necessary for all publishers. -If required, schain module can be included as following -``` - $ gulp build --modules=schain,pubmaticBidAdapter,openxBidAdapter,rubiconBidAdapter,sovrnBidAdapter -``` -The schain module will validate the schain object passed using pbjs.setConfig API. -If the schain object is valid then it will be passed on to bidders/adapters in ```validBidRequests[].schain``` -You may refer pubmaticBidAdapter implementaion for the same. - -## Validation modes -- ```strict```: It is the default validation mode. In this mode, schain object will not be passed to adapters if it is invalid. Errors are thrown for invalid schain object. -- ```relaxed```: In this mode, errors are thrown for an invalid schain object but the invalid schain object is still passed to adapters. -- ```off```: In this mode, no validations are performed and schain object is passed as is to adapters. diff --git a/modules/seedtagBidAdapter.js b/modules/seedtagBidAdapter.js index 745fd4d7088..3c6b69d3cdc 100644 --- a/modules/seedtagBidAdapter.js +++ b/modules/seedtagBidAdapter.js @@ -320,8 +320,9 @@ export const spec = { payload['uspConsent'] = bidderRequest.uspConsent; } - if (validBidRequests[0].schain) { - payload.schain = validBidRequests[0].schain; + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + payload.schain = schain; } let coppa = config.getConfig('coppa'); diff --git a/modules/sharethroughBidAdapter.js b/modules/sharethroughBidAdapter.js index 5c5c8fe6eec..ab63b2f36e8 100644 --- a/modules/sharethroughBidAdapter.js +++ b/modules/sharethroughBidAdapter.js @@ -57,7 +57,7 @@ export const sharethroughAdapterSpec = { ext: { version: '$prebid.version$', str: VERSION, - schain: bidRequests[0].schain, + schain: bidRequests[0]?.ortb2?.source?.ext?.schain, }, }, bcat: deepAccess(bidderRequest.ortb2, 'bcat') || bidRequests[0].params.bcat || [], diff --git a/modules/smaatoBidAdapter.js b/modules/smaatoBidAdapter.js index e75c91b4015..cecbd6fa162 100644 --- a/modules/smaatoBidAdapter.js +++ b/modules/smaatoBidAdapter.js @@ -338,7 +338,7 @@ const converter = ortbConverter({ request.source = { ext: { - schain: bidRequest.schain + schain: bidRequest?.ortb2?.source?.ext?.schain } }; request.ext = { diff --git a/modules/smartadserverBidAdapter.js b/modules/smartadserverBidAdapter.js index 790b94165cb..73073e3da31 100644 --- a/modules/smartadserverBidAdapter.js +++ b/modules/smartadserverBidAdapter.js @@ -204,7 +204,7 @@ export const spec = { timeout: config.getConfig('bidderTimeout'), bidId: bid.bidId, prebidVersion: '$prebid.version$', - schain: spec.serializeSupplyChain(bid.schain), + schain: spec.serializeSupplyChain(bid?.ortb2?.source?.ext?.schain), sda: sellerDefinedAudience, sdc: sellerDefinedContext }; diff --git a/modules/smartxBidAdapter.js b/modules/smartxBidAdapter.js index 1442199cd6d..55254e9bd82 100644 --- a/modules/smartxBidAdapter.js +++ b/modules/smartxBidAdapter.js @@ -216,11 +216,12 @@ export const spec = { userExt.fpc = pubcid; } - // Add schain object if available - if (bid && bid.schain) { + // Add schain object if available from the new location + const schain = bid?.ortb2?.source?.ext?.schain; + if (bid && schain) { requestPayload['source'] = { ext: { - schain: bid.schain + schain: schain } }; } diff --git a/modules/smartyadsBidAdapter.js b/modules/smartyadsBidAdapter.js index de7c61b7163..67904d10fe6 100644 --- a/modules/smartyadsBidAdapter.js +++ b/modules/smartyadsBidAdapter.js @@ -63,8 +63,9 @@ export const spec = { traffic: traff, publisherId: bid.params.accountid }); - if (bid.schain) { - placements.schain = bid.schain; + const schain = bid?.ortb2?.source?.ext?.schain; + if (schain) { + placements.schain = schain; } } diff --git a/modules/smilewantedBidAdapter.js b/modules/smilewantedBidAdapter.js index a78c60f8308..cbde1229ac8 100644 --- a/modules/smilewantedBidAdapter.js +++ b/modules/smilewantedBidAdapter.js @@ -84,7 +84,7 @@ export const spec = { */ positionType: bid.params.positionType || '', prebidVersion: '$prebid.version$', - schain: serializeSupplyChain(bid.schain, ['asi', 'sid', 'hp', 'rid', 'name', 'domain', 'ext']), + schain: serializeSupplyChain(bid?.ortb2?.source?.ext?.schain, ['asi', 'sid', 'hp', 'rid', 'name', 'domain', 'ext']), }; const floor = getBidFloor(bid); diff --git a/modules/snigelBidAdapter.js b/modules/snigelBidAdapter.js index 60d5becac36..55a8d4d5246 100644 --- a/modules/snigelBidAdapter.js +++ b/modules/snigelBidAdapter.js @@ -58,7 +58,7 @@ export const spec = { uspConsent: deepAccess(bidderRequest, 'uspConsent'), coppa: getConfig('coppa'), eids: deepAccess(bidRequests, '0.userIdAsEids'), - schain: deepAccess(bidRequests, '0.schain'), + schain: deepAccess(bidRequests, '0.ortb2.source.ext.schain'), page: getPage(bidderRequest), topframe: inIframe() === true ? 0 : 1, device: { diff --git a/modules/sonobiBidAdapter.js b/modules/sonobiBidAdapter.js index b67b0029179..efde29b8cc9 100644 --- a/modules/sonobiBidAdapter.js +++ b/modules/sonobiBidAdapter.js @@ -133,8 +133,9 @@ export const spec = { } } - if (validBidRequests[0].schain) { - payload.schain = JSON.stringify(validBidRequests[0].schain); + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + payload.schain = JSON.stringify(schain); } const eids = deepAccess(validBidRequests[0], 'userIdAsEids'); diff --git a/modules/sovrnBidAdapter.js b/modules/sovrnBidAdapter.js index 49d7924537f..b117f53d083 100644 --- a/modules/sovrnBidAdapter.js +++ b/modules/sovrnBidAdapter.js @@ -86,8 +86,9 @@ export const spec = { }) } - if (bid.schain) { - schain = schain || bid.schain + const bidSchain = bid?.ortb2?.source?.ext?.schain; + if (bidSchain) { + schain = schain || bidSchain } iv = iv || getBidIdParameter('iv', bid.params) diff --git a/modules/sspBCBidAdapter.js b/modules/sspBCBidAdapter.js index 4da5ba87633..4e759ddf4b9 100644 --- a/modules/sspBCBidAdapter.js +++ b/modules/sspBCBidAdapter.js @@ -628,7 +628,7 @@ const spec = { const ref = bidderRequest.refererInfo.ref; const { source = {}, regs = {} } = ortb2 || {}; - source.schain = setOnAny(validBidRequests, 'schain'); + source.schain = setOnAny(validBidRequests, 'ortb2.source.ext.schain'); const payload = { id: bidderRequest.bidderRequestId, diff --git a/modules/stroeerCoreBidAdapter.js b/modules/stroeerCoreBidAdapter.js index e1254e0992e..1b664aefd8d 100644 --- a/modules/stroeerCoreBidAdapter.js +++ b/modules/stroeerCoreBidAdapter.js @@ -55,7 +55,7 @@ export const spec = { mpa: isMainPageAccessible(), timeout: bidderRequest.timeout - (Date.now() - bidderRequest.auctionStart), url: refererInfo.page, - schain: anyBid.schain + schain: anyBid?.ortb2?.source?.ext?.schain }; const userIds = anyBid.userId; diff --git a/modules/stvBidAdapter.js b/modules/stvBidAdapter.js index 2687cbf5b37..646ef591246 100644 --- a/modules/stvBidAdapter.js +++ b/modules/stvBidAdapter.js @@ -69,8 +69,9 @@ export const spec = { if (!isVideoRequest(bidRequest)) { payload._f = 'html'; } - if (bidRequest.schain) { - payload.schain = serializeSChain(bidRequest.schain); + const schain = bidRequest?.ortb2?.source?.ext?.schain; + if (schain) { + payload.schain = serializeSChain(schain); } else { delete payload.schain; } diff --git a/modules/targetVideoBidAdapter.js b/modules/targetVideoBidAdapter.js index c149e80749d..c911e0dc7cb 100644 --- a/modules/targetVideoBidAdapter.js +++ b/modules/targetVideoBidAdapter.js @@ -98,9 +98,10 @@ export const spec = { }; }; - if (bidRequests[0].schain) { + const schain = bidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { payload.source = { - ext: { schain: bidRequests[0].schain } + ext: { schain: schain } }; } @@ -110,7 +111,7 @@ export const spec = { case BANNER: { const tags = bidRequests.map(createVideoTag); - const schain = bidRequests[0].schain; + const schain = bidRequests[0]?.ortb2?.source?.ext?.schain; const payload = { tags, diff --git a/modules/teadsBidAdapter.js b/modules/teadsBidAdapter.js index 2db1da57500..73b6b421dc1 100644 --- a/modules/teadsBidAdapter.js +++ b/modules/teadsBidAdapter.js @@ -87,8 +87,9 @@ export const spec = { const firstBidRequest = validBidRequests[0]; - if (firstBidRequest.schain) { - payload.schain = firstBidRequest.schain; + const schain = firstBidRequest?.ortb2?.source?.ext?.schain; + if (schain) { + payload.schain = schain; } let gpp = bidderRequest.gppConsent; diff --git a/modules/themoneytizerBidAdapter.js b/modules/themoneytizerBidAdapter.js index 9f187478fa7..11a609b7874 100644 --- a/modules/themoneytizerBidAdapter.js +++ b/modules/themoneytizerBidAdapter.js @@ -33,7 +33,7 @@ export const spec = { ortb2: bidderRequest.ortb2, eids: bidRequest.userIdAsEids, id: bidRequest.auctionId, - schain: bidRequest.schain, + schain: bidRequest?.ortb2?.source?.ext?.schain, version: '$prebid.version$', excl_sync: window.tmzrBidderExclSync }; diff --git a/modules/tripleliftBidAdapter.js b/modules/tripleliftBidAdapter.js index 0c8bd330e11..aa2865c5251 100644 --- a/modules/tripleliftBidAdapter.js +++ b/modules/tripleliftBidAdapter.js @@ -154,7 +154,7 @@ function _filterSid(sid) { function _buildPostBody(bidRequests, bidderRequest) { let data = {}; - let { schain } = bidRequests[0]; + const schain = bidRequests[0]?.ortb2?.source?.ext?.schain; const globalFpd = _getGlobalFpd(bidderRequest); data.imp = bidRequests.map(function(bidRequest, index) { diff --git a/modules/ttdBidAdapter.js b/modules/ttdBidAdapter.js index e780c467441..d3b05232c3d 100644 --- a/modules/ttdBidAdapter.js +++ b/modules/ttdBidAdapter.js @@ -81,8 +81,9 @@ function getSource(validBidRequests, bidderRequest) { let source = { tid: bidderRequest?.ortb2?.source?.tid, }; - if (validBidRequests[0].schain) { - utils.deepSetValue(source, 'ext.schain', validBidRequests[0].schain); + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + utils.deepSetValue(source, 'ext.schain', schain); } return source; } diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index f62e4bc53a9..f2b35e992d7 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -262,7 +262,8 @@ function getRequestData(bid, bidderRequest) { const language = navigator.language; const dnt = (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0; const userIdTdid = (bid.userId && bid.userId.tdid) ? bid.userId.tdid : ''; - const supplyChain = getSupplyChain(bid.schain); + const schain = bid?.ortb2?.source?.ext?.schain; + const supplyChain = getSupplyChain(schain); const bidFloor = getFloor(bid, size, bid.mediaTypes); const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid'); // general bid data diff --git a/modules/undertoneBidAdapter.js b/modules/undertoneBidAdapter.js index ceedc8aa321..e2888af7c1e 100644 --- a/modules/undertoneBidAdapter.js +++ b/modules/undertoneBidAdapter.js @@ -68,8 +68,9 @@ export const spec = { 'uids': validBidRequests[0].userId, 'pageSize': pageSizeArray }; - if (validBidRequests[0].schain) { - commons.schain = validBidRequests[0].schain; + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + commons.schain = schain; } const payload = { 'x-ut-hb-params': [], diff --git a/modules/validationFpdModule/config.js b/modules/validationFpdModule/config.js index c87265fa1df..89201f55ed4 100644 --- a/modules/validationFpdModule/config.js +++ b/modules/validationFpdModule/config.js @@ -145,5 +145,38 @@ export const ORTB_MAP = { type: TYPES.object, isArray: true, childType: TYPES.string + }, + source: { + type: TYPES.object, + children: { + ext: { + type: TYPES.object, + isArray: false + }, + schain: { + type: TYPES.object, + children: { + complete: { type: TYPES.number }, + ver: { type: TYPES.string }, + nodes: { + type: TYPES.object, + isArray: true, + childType: TYPES.object, + required: ['asi', 'sid', 'hp'], + children: { + asi: { type: TYPES.string }, + sid: { type: TYPES.string }, + hp: { type: TYPES.number }, + rid: { type: TYPES.string }, + name: { type: TYPES.string }, + domain: { type: TYPES.string }, + ext: { type: TYPES.object } + } + }, + ext: { type: TYPES.object } + }, + required: ['complete', 'nodes', 'ver'] + } + } } } diff --git a/modules/vdoaiBidAdapter.js b/modules/vdoaiBidAdapter.js index 6ef5b6ebb3e..a570b6a43f3 100644 --- a/modules/vdoaiBidAdapter.js +++ b/modules/vdoaiBidAdapter.js @@ -169,7 +169,7 @@ function vdoBuildPlacement(vdoBidRequest) { ortb2Imp: vdoBidRequest.ortb2Imp, publisherId: vdoBidRequest.params.publisherId, userIdAsEids: vdoBidRequest.userIdAsEids, - supplyChain: vdoBidRequest.schain, + supplyChain: vdoBidRequest?.ortb2?.source?.ext?.schain, custom1: vdoBidRequest.params.custom1, custom2: vdoBidRequest.params.custom2, custom3: vdoBidRequest.params.custom3, diff --git a/modules/videobyteBidAdapter.js b/modules/videobyteBidAdapter.js index 09c2f747dc6..dca559806fd 100644 --- a/modules/videobyteBidAdapter.js +++ b/modules/videobyteBidAdapter.js @@ -251,8 +251,9 @@ function buildRequestData(bidRequest, bidderRequest) { } // adding schain object - if (bidRequest.schain) { - deepSetValue(openrtbRequest, 'source.ext.schain', bidRequest.schain); + const schain = bidRequest?.ortb2?.source?.ext?.schain; + if (schain) { + deepSetValue(openrtbRequest, 'source.ext.schain', schain); openrtbRequest.source.ext.schain.nodes[0].rid = openrtbRequest.id; } diff --git a/modules/vidoomyBidAdapter.js b/modules/vidoomyBidAdapter.js index 894d3191311..ef1b092c658 100644 --- a/modules/vidoomyBidAdapter.js +++ b/modules/vidoomyBidAdapter.js @@ -158,7 +158,7 @@ const buildRequests = (validBidRequests, bidderRequest) => { dt: /Mobi/.test(navigator.userAgent) ? 2 : 1, pid: bid.params.pid, requestId: bid.bidId, - schain: serializeSupplyChainObj(bid.schain) || '', + schain: serializeSupplyChainObj(bid?.ortb2?.source?.ext?.schain) || '', eids: eids || '', bidfloor: floor, d: getDomainWithoutSubdomain(hostname), // 'vidoomy.com', diff --git a/modules/viouslyBidAdapter.js b/modules/viouslyBidAdapter.js index f0a10f936b9..07d7874973e 100644 --- a/modules/viouslyBidAdapter.js +++ b/modules/viouslyBidAdapter.js @@ -132,8 +132,9 @@ export const spec = { } // Schain - if (validBidRequests[0].schain) { - payload.schain = validBidRequests[0].schain; + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + payload.schain = schain; } // Currency payload.currency_code = CURRENCY; diff --git a/modules/visxBidAdapter.js b/modules/visxBidAdapter.js index 510106845db..f305a3d3889 100644 --- a/modules/visxBidAdapter.js +++ b/modules/visxBidAdapter.js @@ -87,7 +87,8 @@ export const spec = { imp.push(impObj); bidsMap[bid.bidId] = bid; } - const { params: { uid }, schain, userId, userIdAsEids } = bid; + const { params: { uid }, userId, userIdAsEids } = bid; + const schain = bid?.ortb2?.source?.ext?.schain; if (!payloadSchain && schain) { payloadSchain = schain; } diff --git a/modules/voxBidAdapter.js b/modules/voxBidAdapter.js index 3497f3cee07..32e7f4b85c0 100644 --- a/modules/voxBidAdapter.js +++ b/modules/voxBidAdapter.js @@ -27,7 +27,7 @@ function buildBidRequests(validBidRequests, bidderRequest) { const params = bid.params; const bidRequest = { floorInfo, - schain: bid.schain, + schain: bid?.ortb2?.source?.ext?.schain, userId: bid.userId, bidId: bid.bidId, // TODO: fix transactionId leak: https://github.com/prebid/Prebid.js/issues/9781 diff --git a/modules/vuukleBidAdapter.js b/modules/vuukleBidAdapter.js index f3ab2562ef4..6dd5709fe78 100644 --- a/modules/vuukleBidAdapter.js +++ b/modules/vuukleBidAdapter.js @@ -31,7 +31,7 @@ export const spec = { rnd: Math.random(), bidId: bid.bidId, source: 'pbjs', - schain: JSON.stringify(bid.schain), + schain: JSON.stringify(bid?.ortb2?.source?.ext?.schain), requestId: bid.bidderRequestId, tmax: bidderRequest.timeout, gdpr: (bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) ? 1 : 0, diff --git a/modules/winrBidAdapter.js b/modules/winrBidAdapter.js index 06c6f808244..61e12cdc1b4 100644 --- a/modules/winrBidAdapter.js +++ b/modules/winrBidAdapter.js @@ -193,7 +193,7 @@ export const spec = { const memberIdBid = ((bidRequests) || []).find(hasMemberId); const member = memberIdBid ? parseInt(memberIdBid.params.member, 10) : 0; - const schain = bidRequests[0].schain; + const schain = bidRequests[0]?.ortb2?.source?.ext?.schain; const payload = { tags: [...tags], diff --git a/modules/yahooAdsBidAdapter.js b/modules/yahooAdsBidAdapter.js index 6e67df84b2f..a72deab51ae 100644 --- a/modules/yahooAdsBidAdapter.js +++ b/modules/yahooAdsBidAdapter.js @@ -328,9 +328,9 @@ function generateOpenRtbObject(bidderRequest, bid) { outBoundBidRequest = appendFirstPartyData(outBoundBidRequest, bid); }; - const schainData = deepAccess(bid, 'schain.nodes'); - if (isArray(schainData) && schainData.length > 0) { - outBoundBidRequest.source.ext.schain = bid.schain; + const schain = bid?.ortb2?.source?.ext?.schain; + if (schain && isArray(schain.nodes) && schain.nodes.length > 0) { + outBoundBidRequest.source.ext.schain = schain; outBoundBidRequest.source.ext.schain.nodes[0].rid = outBoundBidRequest.id; }; diff --git a/modules/yieldlabBidAdapter.js b/modules/yieldlabBidAdapter.js index 37d1de25240..42633be8730 100644 --- a/modules/yieldlabBidAdapter.js +++ b/modules/yieldlabBidAdapter.js @@ -75,8 +75,9 @@ export const spec = { query[prop] = bid.params.customParams[prop]; } } - if (bid.schain && isPlainObject(bid.schain) && Array.isArray(bid.schain.nodes)) { - query.schain = createSchainString(bid.schain); + const schain = bid?.ortb2?.source?.ext?.schain; + if (schain && isPlainObject(schain) && Array.isArray(schain.nodes)) { + query.schain = createSchainString(schain); } const iabContent = getContentObject(bid); diff --git a/modules/yieldliftBidAdapter.js b/modules/yieldliftBidAdapter.js index d4cafd77c2d..ba53f2a6340 100644 --- a/modules/yieldliftBidAdapter.js +++ b/modules/yieldliftBidAdapter.js @@ -57,8 +57,9 @@ export const spec = { }; // adding schain object - if (validBidRequests[0].schain) { - deepSetValue(openrtbRequest, 'source.ext.schain', validBidRequests[0].schain); + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { + deepSetValue(openrtbRequest, 'source.ext.schain', schain); } // Attaching GDPR Consent Params diff --git a/modules/yieldmoBidAdapter.js b/modules/yieldmoBidAdapter.js index b4aec7982b6..973cdcd4e93 100644 --- a/modules/yieldmoBidAdapter.js +++ b/modules/yieldmoBidAdapter.js @@ -138,8 +138,9 @@ export const spec = { if (criteoId) { serverRequest.cri_prebid = criteoId; } - if (request.schain) { - serverRequest.schain = JSON.stringify(request.schain); + const schain = deepAccess(request, 'ortb2.source.ext.schain'); + if (schain) { + serverRequest.schain = JSON.stringify(schain); } if (deepAccess(request, 'params.lr_env')) { serverRequest.ats_envelope = request.params.lr_env; @@ -413,7 +414,7 @@ function getId(request, idType) { * @return Object OpenRTB request object */ function openRtbRequest(bidRequests, bidderRequest) { - const schain = bidRequests[0].schain; + const schain = bidRequests[0]?.ortb2?.source?.ext?.schain; let openRtbRequest = { id: bidRequests[0].bidderRequestId, tmax: bidderRequest.timeout || 400, diff --git a/modules/zeta_global_sspBidAdapter.js b/modules/zeta_global_sspBidAdapter.js index 62e60db020f..04655b39499 100644 --- a/modules/zeta_global_sspBidAdapter.js +++ b/modules/zeta_global_sspBidAdapter.js @@ -178,11 +178,12 @@ export const spec = { deepSetValue(payload, 'regs.ext.us_privacy', bidderRequest.uspConsent); } - // schain - if (validBidRequests[0].schain) { + // schain - check for schain in the new location + const schain = validBidRequests[0]?.ortb2?.source?.ext?.schain; + if (schain) { payload.source = { ext: { - schain: validBidRequests[0].schain + schain: schain } } } diff --git a/src/adapterManager.js b/src/adapterManager.js index f6b3d85b351..0db1e28d33a 100644 --- a/src/adapterManager.js +++ b/src/adapterManager.js @@ -40,6 +40,7 @@ import { import {getRefererInfo} from './refererDetection.js'; import {GDPR_GVLIDS, gdprDataHandler, gppDataHandler, uspDataHandler, } from './consentHandler.js'; import * as events from './events.js'; +import {moveSchainToExt} from './fpd/schain.js'; import {EVENTS, S2S} from './constants.js'; import {useMetrics} from './utils/perfMetrics.js'; import {auctionManager} from './auctionManager.js'; @@ -323,8 +324,10 @@ adapterManager.makeBidRequests = hook('sync', function (adUnits, auctionStart, a ? s2sActivityParams : activityParams(MODULE_TYPE_BIDDER, bidderRequest.bidderCode) ); + const merged = mergeDeep({source: {tid: auctionId}}, ortb2, bidderOrtb2[bidderRequest.bidderCode]); moveUserEidsToExt(merged); + moveSchainToExt(merged, bidderOrtb2[bidderRequest.bidderCode]); const fpd = Object.freeze(redact.ortb2(merged)); bidderRequest.ortb2 = fpd; bidderRequest.bids = bidderRequest.bids.map((bid) => { diff --git a/src/fpd/schain.js b/src/fpd/schain.js new file mode 100644 index 00000000000..f2e6d3761a6 --- /dev/null +++ b/src/fpd/schain.js @@ -0,0 +1,85 @@ +/** + * This module handles supply chain (schain) processing and relocation + * between different locations in the ortb2 structure + */ +import {config} from '../config.js'; +import {deepClone, logInfo} from '../utils.js'; + +/** + * Applies schain from config to ortb2 fragments with precedence rules + * @param {Object} ortb2Fragments - The ortb2 fragments object + * @returns {Object} - The updated ortb2Fragments object + */ +export function schainPrecedence(ortb2Fragments) { + if (!ortb2Fragments) return ortb2Fragments; + + // Apply global schain config if available + // config's schain will have more precedence over ortb2.source.schain + const globalSchainConfig = config.getConfig('schain'); + if (globalSchainConfig && globalSchainConfig.config) { + if (!ortb2Fragments?.global?.source?.schain) { + logInfo('Applying global schain config with precedence'); + applySchainToPath(ortb2Fragments, 'global.source', globalSchainConfig.config); + } else { + logInfo('Preserving existing global.source.schain from ortb2'); + } + } + + // Apply bidder-specific schain configs + const bidderConfigs = config.getBidderConfig(); + if (!bidderConfigs) return ortb2Fragments; + + Object.entries(bidderConfigs) + .filter(([_, cfg]) => cfg.schain) + .forEach(([bidderCode, cfg]) => { + const bidderPath = `bidder.${bidderCode}.source`; + const hasSchain = ortb2Fragments?.bidder?.[bidderCode]?.source?.schain; + + if (!hasSchain) { + logInfo(`Applying bidder schain config for ${bidderCode}`); + applySchainToPath(ortb2Fragments, bidderPath, cfg.schain?.config); + } else { + logInfo(`Preserving existing schain for bidder ${bidderCode} from ortb2`); + } + }); + + return ortb2Fragments; +} + +/** + * Helper function to apply schain to a specific path in ortb2Fragments + * @param {Object} fragments - The ortb2 fragments object + * @param {String} path - Dot-notation path where to apply the schain + * @param {Object} schainConfig - The schain configuration to apply + */ +function applySchainToPath(fragments, path, schainConfig) { + const parts = path.split('.'); + let current = fragments; + + // Create path if it doesn't exist + parts.forEach(part => { + current[part] = current[part] || {}; + current = current[part]; + }); + + // Apply the schain config + current.schain = deepClone(schainConfig); +} + +/** + * Relocates schain from source.schain to source.ext.schain + * @param {Object} fpd - The first-party data object + * @returns {Object} - The updated FPD object + */ +export function moveSchainToExt(fpd, bidderOrtb2) { + if (!fpd?.source?.schain) return fpd; + + // Ensure source.ext exists + fpd.source.ext = fpd.source.ext || {}; + + // Move schain to the new location and remove from original + fpd.source.ext.schain = bidderOrtb2?.source?.schain || fpd.source.schain; + delete fpd.source.schain; + + return fpd; +} diff --git a/src/prebid.js b/src/prebid.js index de19204e71f..d5ac6e16c8d 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -37,6 +37,7 @@ import * as events from './events.js'; import {newMetrics, useMetrics} from './utils/perfMetrics.js'; import {defer, PbPromise} from './utils/promise.js'; import {enrichFPD} from './fpd/enrichment.js'; +import {schainPrecedence} from './fpd/schain.js'; import {allConsent} from './consentHandler.js'; import { insertLocatorFrame, @@ -586,10 +587,13 @@ pbjsInstance.requestBids = (function() { adUnitCodes = adUnits && adUnits.map(unit => unit.code); } adUnitCodes = adUnitCodes.filter(uniques); - const ortb2Fragments = { + let ortb2Fragments = { global: mergeDeep({}, config.getAnyConfig('ortb2') || {}, ortb2 || {}), bidder: Object.fromEntries(Object.entries(config.getBidderConfig()).map(([bidder, cfg]) => [bidder, deepClone(cfg.ortb2)]).filter(([_, ortb2]) => ortb2 != null)) } + // Apply schain precedence rules before enrichment + ortb2Fragments = schainPrecedence(ortb2Fragments); + return enrichFPD(PbPromise.resolve(ortb2Fragments.global)).then(global => { ortb2Fragments.global = global; return startAuction({bidsBackHandler, timeout: cbTimeout, adUnits, adUnitCodes, labels, auctionId, ttlBuffer, ortb2Fragments, metrics, defer}); diff --git a/test/spec/fpd/schain_spec.js b/test/spec/fpd/schain_spec.js new file mode 100644 index 00000000000..8532c6e0892 --- /dev/null +++ b/test/spec/fpd/schain_spec.js @@ -0,0 +1,385 @@ +import {expect} from 'chai/index.js'; +import * as utils from 'src/utils.js'; +import {config} from 'src/config.js'; +import {schainPrecedence, moveSchainToExt} from 'src/fpd/schain.js'; + +describe('Supply Chain fpd', function() { + const SAMPLE_SCHAIN = { + ver: '1.0', + complete: 1, + nodes: [{ asi: 'example.com', sid: '00001', hp: 1 }] + }; + + const SAMPLE_SCHAIN_2 = { + ver: '2.0', + complete: 1, + nodes: [{ asi: 'bidder.com', sid: '00002', hp: 1 }] + }; + + let sandbox; + let logInfoStub; + let configGetConfigStub; + let configGetBidderConfigStub; + + beforeEach(function() { + sandbox = sinon.createSandbox(); + logInfoStub = sandbox.stub(utils, 'logInfo'); + configGetConfigStub = sandbox.stub(config, 'getConfig'); + configGetBidderConfigStub = sandbox.stub(config, 'getBidderConfig'); + }); + + afterEach(function() { + sandbox.restore(); + }); + + + describe('schainPrecedence', function() { + describe('preserves existing schain values', function() { + it('should preserve existing global.source.schain', function() { + const existingSchain = { + ver: '1.0', + complete: 1, + nodes: [{ asi: 'existing.com', sid: '99999', hp: 1 }] + }; + + const input = { + global: { + source: { + schain: existingSchain + } + } + }; + + const schainConfig = { + config: SAMPLE_SCHAIN + }; + + configGetConfigStub.returns(schainConfig); + configGetBidderConfigStub.returns(null); + + const result = schainPrecedence(input); + + expect(result.global.source.schain).to.deep.equal(existingSchain); + expect(result.global.source.schain).to.not.deep.equal(SAMPLE_SCHAIN); + expect(logInfoStub.calledWith('Preserving existing global.source.schain from ortb2')).to.be.true; + }); + + it('should preserve existing bidder-specific schain ', function() { + const existingBidderSchain = { + ver: '3.0', + complete: 1, + nodes: [{ asi: 'existingbidder.com', sid: '88888', hp: 1 }] + }; + + const input = { + bidder: { + 'bidderA': { + source: { + schain: existingBidderSchain + } + } + } + }; + + const bidderConfigs = { + 'bidderA': { + schain: { + config: SAMPLE_SCHAIN + } + } + }; + + configGetConfigStub.returns(null); + configGetBidderConfigStub.returns(bidderConfigs); + + const result = schainPrecedence(input); + + expect(result.bidder.bidderA.source.schain).to.deep.equal(existingBidderSchain); + expect(result.bidder.bidderA.source.schain).to.not.deep.equal(SAMPLE_SCHAIN); + expect(logInfoStub.calledWith('Preserving existing schain for bidder bidderA from ortb2')).to.be.true; + }); + }); + + describe('handles edge cases', function() { + it('should handle edge cases and no-op scenarios', function() { + expect(schainPrecedence(null)).to.be.null; + expect(schainPrecedence(undefined)).to.be.undefined; + expect(schainPrecedence({})).to.deep.equal({}); + + const input = { + global: { + source: { + tid: '123' + } + } + }; + configGetConfigStub.returns(null); + configGetBidderConfigStub.returns(null); + + const result = schainPrecedence(input); + expect(result).to.deep.equal(input); + expect(logInfoStub.called).to.be.false; + }); + }); + + describe('global schain config handling', function() { + let input; + + beforeEach(function() { + input = { + global: { + source: {} + } + }; + configGetBidderConfigStub.returns(null); + }); + + it('should correctly handle different global schain config scenarios', function() { + const validSchainConfig = { + config: SAMPLE_SCHAIN + }; + configGetConfigStub.returns(validSchainConfig); + + let result = schainPrecedence(input); + expect(result.global.source.schain).to.deep.equal(SAMPLE_SCHAIN); + expect(logInfoStub.calledWith('Applying global schain config with precedence')).to.be.true; + + logInfoStub.reset(); + input = { global: { source: {} } }; + + const invalidSchainConfig = { + validation: 'strict' + }; + configGetConfigStub.returns(invalidSchainConfig); + + result = schainPrecedence(input); + expect(result.global.source.schain).to.be.undefined; + }); + }); + + describe('bidder-specific schain config handling', function() { + let input; + + beforeEach(function() { + input = { + global: {}, + bidder: {} + }; + configGetConfigStub.returns(null); + logInfoStub.reset(); + }); + + it('should handle various bidder-specific schain scenarios', function() { + const singleBidderConfig = { + 'bidderA': { + schain: { + config: SAMPLE_SCHAIN + } + } + }; + configGetBidderConfigStub.returns(singleBidderConfig); + + let result = schainPrecedence(input); + expect(result.bidder.bidderA.source.schain).to.deep.equal(SAMPLE_SCHAIN); + expect(logInfoStub.calledWith('Applying bidder schain config for bidderA')).to.be.true; + + logInfoStub.reset(); + input = { global: {}, bidder: {} }; + + const multiBidderConfig = { + 'bidderA': { + schain: { + config: SAMPLE_SCHAIN + } + }, + 'bidderB': { + schain: { + config: SAMPLE_SCHAIN_2 + } + }, + 'bidderC': { + } + }; + configGetBidderConfigStub.returns(multiBidderConfig); + + result = schainPrecedence(input); + expect(result.bidder.bidderA.source.schain).to.deep.equal(SAMPLE_SCHAIN); + expect(result.bidder.bidderB.source.schain).to.deep.equal(SAMPLE_SCHAIN_2); + expect(result.bidder.bidderC).to.be.undefined; + expect(logInfoStub.calledWith('Applying bidder schain config for bidderA')).to.be.true; + expect(logInfoStub.calledWith('Applying bidder schain config for bidderB')).to.be.true; + + logInfoStub.reset(); + input = { global: {}, bidder: {} }; + + const invalidBidderConfig = { + 'bidderA': { + schain: { + validation: 'strict' + } + } + }; + configGetBidderConfigStub.returns(invalidBidderConfig); + + result = schainPrecedence(input); + expect(result.bidder.bidderA.source.schain).to.deep.equal({}); + }); + }); + + // Test case: both global and bidder-specific schain configs + it('should apply both global and bidder-specific schain configs', function() { + const input = { + global: {}, + bidder: {} + }; + const globalSchainConfig = { + config: { + ver: '1.0', + complete: 1, + nodes: [{ asi: 'global.com', sid: '00001', hp: 1 }] + } + }; + const bidderConfigs = { + 'bidderA': { + schain: { + config: { + ver: '1.0', + complete: 1, + nodes: [{ asi: 'bidderA.com', sid: '00001', hp: 1 }] + } + } + } + }; + configGetConfigStub.returns(globalSchainConfig); + configGetBidderConfigStub.returns(bidderConfigs); + + const result = schainPrecedence(input); + expect(result.global.source.schain).to.deep.equal(globalSchainConfig.config); + expect(result.bidder.bidderA.source.schain).to.deep.equal(bidderConfigs.bidderA.schain.config); + }); + }); + + describe('moveSchainToExt', function() { + it('should handle various input scenarios correctly', function() { + expect(moveSchainToExt(null)).to.be.null; + expect(moveSchainToExt(undefined)).to.be.undefined; + + const inputNoSource = { user: { id: '123' } }; + expect(moveSchainToExt(inputNoSource)).to.deep.equal(inputNoSource); + + const inputNoSchain = { source: { tid: '123' } }; + expect(moveSchainToExt(inputNoSchain)).to.deep.equal(inputNoSchain); + + const basicInput = { + source: { + tid: '123', + schain: SAMPLE_SCHAIN + } + }; + let result = moveSchainToExt(basicInput); + expect(result.source.schain).to.be.undefined; + expect(result.source.ext.schain).to.deep.equal(SAMPLE_SCHAIN); + expect(result.source.tid).to.equal('123'); + + const inputWithExt = { + source: { + tid: '123', + schain: SAMPLE_SCHAIN, + ext: { + dchain: { ver: '1.0' } + } + } + }; + result = moveSchainToExt(inputWithExt); + expect(result.source.schain).to.be.undefined; + expect(result.source.ext.schain).to.deep.equal(SAMPLE_SCHAIN); + expect(result.source.ext.dchain).to.deep.equal({ ver: '1.0' }); + }); + + describe('bidderOrtb2 parameter handling', function() { + const createFreshFpd = () => ({ + source: { + tid: '123', + schain: SAMPLE_SCHAIN + } + }); + + it('should handle bidderOrtb2 parameter variations', function() { + const bidderOrtb2WithSchain = { + source: { + schain: SAMPLE_SCHAIN_2 + } + }; + + let fpd = createFreshFpd(); + let result = moveSchainToExt(fpd, bidderOrtb2WithSchain); + expect(result.source.schain).to.be.undefined; + expect(result.source.ext.schain).to.deep.equal(SAMPLE_SCHAIN_2); + + const bidderOrtb2WithoutSchain = { + source: {} + }; + + fpd = createFreshFpd(); + result = moveSchainToExt(fpd, bidderOrtb2WithoutSchain); + expect(result.source.schain).to.be.undefined; + expect(result.source.ext.schain).to.deep.equal(SAMPLE_SCHAIN); + + fpd = createFreshFpd(); + result = moveSchainToExt(fpd, null); + expect(result.source.schain).to.be.undefined; + expect(result.source.ext.schain).to.deep.equal(SAMPLE_SCHAIN); + }); + }); + }); + + describe('Integration', function() { + it('should handle the full schain workflow with both global and bidder configs', function() { + const ortb2Fragments = { + global: { + source: { + tid: '123' + } + }, + bidder: { + 'bidderA': { + source: {} + } + } + }; + + configGetConfigStub.returns({ config: SAMPLE_SCHAIN }); + configGetBidderConfigStub.returns({ + 'bidderA': { + schain: { + config: SAMPLE_SCHAIN_2 + } + } + }); + + const updatedFragments = schainPrecedence(ortb2Fragments); + + expect(updatedFragments.global.source.schain).to.deep.equal(SAMPLE_SCHAIN); + expect(updatedFragments.bidder.bidderA.source.schain).to.deep.equal(SAMPLE_SCHAIN_2); + + const merged = { + source: { + tid: '123', + schain: SAMPLE_SCHAIN + } + }; + + const bidderOrtb2 = { + source: { + schain: SAMPLE_SCHAIN_2 + } + }; + + const finalFpd = moveSchainToExt(merged, bidderOrtb2); + + expect(finalFpd.source.schain).to.be.undefined; + expect(finalFpd.source.ext.schain).to.deep.equal(SAMPLE_SCHAIN_2); + expect(finalFpd.source.tid).to.equal('123'); + }); + }); +}); diff --git a/test/spec/modules/33acrossBidAdapter_spec.js b/test/spec/modules/33acrossBidAdapter_spec.js index d4ad0184a17..828178c4ac3 100644 --- a/test/spec/modules/33acrossBidAdapter_spec.js +++ b/test/spec/modules/33acrossBidAdapter_spec.js @@ -1420,7 +1420,7 @@ describe('33acrossBidAdapter:', function () { ]; schainValues.forEach((schain) => { - bidRequests[0].schain = schain; + bidRequests[0].ortb2.source = {ext: {schain: schain}}; const ttxRequest = new TtxRequestBuilder() .withBanner() diff --git a/test/spec/modules/BTBidAdapter_spec.js b/test/spec/modules/BTBidAdapter_spec.js index 2ec0acc424e..18f99929037 100644 --- a/test/spec/modules/BTBidAdapter_spec.js +++ b/test/spec/modules/BTBidAdapter_spec.js @@ -12,7 +12,6 @@ import 'modules/consentManagementUsp.js'; import 'modules/consentManagementGpp.js'; import 'modules/tcfControl.js'; import 'modules/gppControl_usnat.js'; -import 'modules/schain.js'; describe('BT Bid Adapter', () => { const ENDPOINT_URL = 'https://pbs.btloader.com/openrtb2/auction'; diff --git a/test/spec/modules/ViouslyBidAdapter_spec.js b/test/spec/modules/ViouslyBidAdapter_spec.js index f8cd686581c..1a1767e7491 100644 --- a/test/spec/modules/ViouslyBidAdapter_spec.js +++ b/test/spec/modules/ViouslyBidAdapter_spec.js @@ -238,7 +238,13 @@ describe('ViouslyAdapter', function () { }; let bid = mergeDeep(deepClone(VALID_BID_VIDEO), { - schain: schain + ortb2: { + source: { + ext: { + schain: schain + } + } + } }); let requests = mergeDeep(deepClone(VALID_REQUEST_VIDEO), { diff --git a/test/spec/modules/adagioBidAdapter_spec.js b/test/spec/modules/adagioBidAdapter_spec.js index 102812b88cf..ba47463bbff 100644 --- a/test/spec/modules/adagioBidAdapter_spec.js +++ b/test/spec/modules/adagioBidAdapter_spec.js @@ -618,12 +618,13 @@ describe('Adagio bid adapter', () => { }; it('should add the schain if available at bidder level', function() { - const bid01 = new BidRequestBuilder({ schain }).withParams().build(); + const bid01 = new BidRequestBuilder({ ortb2: { source: { ext: { schain } } } }).withParams().build(); const bidderRequest = new BidderRequestBuilder().build(); const requests = spec.buildRequests([bid01], bidderRequest); expect(requests[0].data).to.have.all.keys(expectedDataKeys); + expect(requests[0].data.schain).to.exist; expect(requests[0].data.schain).to.deep.equal(schain); }); diff --git a/test/spec/modules/adfBidAdapter_spec.js b/test/spec/modules/adfBidAdapter_spec.js index 2b8009a5d72..0363ef01e06 100644 --- a/test/spec/modules/adfBidAdapter_spec.js +++ b/test/spec/modules/adfBidAdapter_spec.js @@ -330,10 +330,16 @@ describe('Adf adapter', function () { let validBidRequests = [{ bidId: 'bidId', params: {}, - schain: { - validation: 'strict', - config: { - ver: '1.0' + ortb2: { + source: { + ext: { + schain: { + validation: 'strict', + config: { + ver: '1.0' + } + } + } } } }]; diff --git a/test/spec/modules/adipoloBidAdapter_spec.js b/test/spec/modules/adipoloBidAdapter_spec.js index 6764d7d20d8..a166d87d0f0 100644 --- a/test/spec/modules/adipoloBidAdapter_spec.js +++ b/test/spec/modules/adipoloBidAdapter_spec.js @@ -120,18 +120,20 @@ describe('adipoloBidAdapter', () => { it('should build request with schain', function () { const schainRequest = deepClone(defaultRequest); - schainRequest.schain = { - validation: 'strict', - config: { - ver: '1.0' + const bidderRequest = { + ortb2: { + source: { + ext: { + schain: { + ver: '1.0' + } + } + } } }; - const request = JSON.parse(spec.buildRequests([schainRequest], {}).data)[0]; + const request = JSON.parse(spec.buildRequests([schainRequest], bidderRequest).data)[0]; expect(request).to.have.property('schain').and.to.deep.equal({ - validation: 'strict', - config: { - ver: '1.0' - } + ver: '1.0' }); }); diff --git a/test/spec/modules/adotBidAdapter_spec.js b/test/spec/modules/adotBidAdapter_spec.js index df628088bb0..3cb2975d0e8 100644 --- a/test/spec/modules/adotBidAdapter_spec.js +++ b/test/spec/modules/adotBidAdapter_spec.js @@ -28,7 +28,7 @@ describe('Adot Adapter', function () { it('should build request (banner)', function () { const bidderRequestId = 'bidderRequestId'; const validBidRequests = [{ bidderRequestId, mediaTypes: {} }, { bidderRequestId, bidId: 'bidId', mediaTypes: { banner: { sizes: [[300, 250]] } }, params: { placementId: 'placementId', adUnitCode: 200 } }]; - const bidderRequest = { position: 2, refererInfo: { page: 'http://localhost.com', domain: 'localhost.com' }, gdprConsent: { consentString: 'consentString', gdprApplies: true }, userId: { pubProvidedId: 'userId' }, schain: { ver: '1.0' } }; + const bidderRequest = { position: 2, refererInfo: { page: 'http://localhost.com', domain: 'localhost.com' }, gdprConsent: { consentString: 'consentString', gdprApplies: true }, userId: { pubProvidedId: 'userId' }, ortb2: { source: { ext: { schain: { ver: '1.0' } } } } }; const request = spec.buildRequests(validBidRequests, bidderRequest); const buildBidRequestResponse = { @@ -77,7 +77,7 @@ describe('Adot Adapter', function () { it('should build request (native)', function () { const bidderRequestId = 'bidderRequestId'; const validBidRequests = [{ bidderRequestId, mediaTypes: {} }, { bidderRequestId, bidId: 'bidId', mediaTypes: { native: { title: { required: true, len: 50, sizes: [[300, 250]] }, wrong: {}, image: {} } }, params: { placementId: 'placementId', adUnitCode: 200 } }]; - const bidderRequest = { position: 2, refererInfo: { page: 'http://localhost.com', domain: 'localhost.com' }, gdprConsent: { consentString: 'consentString', gdprApplies: true }, userId: { pubProvidedId: 'userId' }, schain: { ver: '1.0' } }; + const bidderRequest = { position: 2, refererInfo: { page: 'http://localhost.com', domain: 'localhost.com' }, gdprConsent: { consentString: 'consentString', gdprApplies: true }, userId: { pubProvidedId: 'userId' }, ortb2: { source: { ext: { schain: { ver: '1.0' } } } } }; const request = spec.buildRequests(validBidRequests, bidderRequest); const buildBidRequestResponse = { @@ -125,7 +125,7 @@ describe('Adot Adapter', function () { it('should build request (video)', function () { const bidderRequestId = 'bidderRequestId'; const validBidRequests = [{ bidderRequestId, mediaTypes: {} }, { bidderRequestId, bidId: 'bidId', mediaTypes: { video: { playerSize: [[300, 250]], minduration: 1, maxduration: 2, api: 'api', linearity: 'linearity', mimes: [], plcmt: '1', playbackmethod: 'playbackmethod', protocols: 'protocol', startdelay: 'startdelay' } }, params: { placementId: 'placementId', adUnitCode: 200 } }]; - const bidderRequest = { position: 2, refererInfo: { page: 'http://localhost.com', domain: 'localhost.com' }, gdprConsent: { consentString: 'consentString', gdprApplies: true }, userId: { pubProvidedId: 'userId' }, schain: { ver: '1.0' } }; + const bidderRequest = { position: 2, refererInfo: { page: 'http://localhost.com', domain: 'localhost.com' }, gdprConsent: { consentString: 'consentString', gdprApplies: true }, userId: { pubProvidedId: 'userId' }, ortb2: { source: { ext: { schain: { ver: '1.0' } } } } }; const request = spec.buildRequests(validBidRequests, bidderRequest); const buildBidRequestResponse = { diff --git a/test/spec/modules/adspiritBidAdapter_spec.js b/test/spec/modules/adspiritBidAdapter_spec.js index b0c98fd922f..1d39e4897c1 100644 --- a/test/spec/modules/adspiritBidAdapter_spec.js +++ b/test/spec/modules/adspiritBidAdapter_spec.js @@ -154,16 +154,22 @@ describe('Adspirit Bidder Spec', function () { mediaTypes: { banner: { sizes: [[300, 250]] } }, - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'publisher.com', - sid: '1234', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'publisher.com', + sid: '1234', + hp: 1 + } + ] + } } - ] + } } } ]; @@ -174,7 +180,7 @@ describe('Adspirit Bidder Spec', function () { const requestData = JSON.parse(request.data); expect(requestData.source).to.exist; expect(requestData.source.ext).to.exist; - expect(requestData.source.ext.schain).to.deep.equal(bidRequest[0].schain); + expect(requestData.source.ext.schain).to.deep.equal(bidRequest[0].ortb2.source.ext.schain); }); it('should correctly handle bidfloor values (valid, missing, and non-numeric)', function () { const bidRequest = [ diff --git a/test/spec/modules/adstirBidAdapter_spec.js b/test/spec/modules/adstirBidAdapter_spec.js index a62dce8af97..cbcb4ea0511 100644 --- a/test/spec/modules/adstirBidAdapter_spec.js +++ b/test/spec/modules/adstirBidAdapter_spec.js @@ -279,7 +279,7 @@ describe('AdstirAdapter', function () { }; const serializedSchain = '1.0,1!exchange1.example,1234%21abcd,1,bid-request-1,publisher%2C%20Inc.,publisher.example!exchange2.example,abcd,1,bid-request-2,intermediary,intermediary.example'; - const [ request ] = spec.buildRequests([utils.mergeDeep(utils.deepClone(validBidRequests[0]), { schain })], bidderRequest); + const [ request ] = spec.buildRequests([utils.mergeDeep(utils.deepClone(validBidRequests[0]), { ortb2: { source: { ext: { schain } } } })], bidderRequest); const d = JSON.parse(request.data); expect(d.schain).to.deep.equal(serializedSchain); }); @@ -305,7 +305,7 @@ describe('AdstirAdapter', function () { }; const serializedSchain = '1.0,1!exchange1.example,1234%21abcd,1,,,!,,,,,!exchange2.example,abcd,1,,,'; - const [ request ] = spec.buildRequests([utils.mergeDeep(utils.deepClone(validBidRequests[0]), { schain })], bidderRequest); + const [ request ] = spec.buildRequests([utils.mergeDeep(utils.deepClone(validBidRequests[0]), { ortb2: { source: { ext: { schain } } } })], bidderRequest); const d = JSON.parse(request.data); expect(d.schain).to.deep.equal(serializedSchain); }); diff --git a/test/spec/modules/adtargetBidAdapter_spec.js b/test/spec/modules/adtargetBidAdapter_spec.js index d1221d24022..3548833d757 100644 --- a/test/spec/modules/adtargetBidAdapter_spec.js +++ b/test/spec/modules/adtargetBidAdapter_spec.js @@ -8,7 +8,6 @@ const DISPLAY_REQUEST = { 'params': { 'aid': 12345 }, - 'schain': { ver: 1 }, 'userId': { criteo: 2 }, 'mediaTypes': { 'banner': { 'sizes': [300, 250] } }, 'bidderRequestId': '7101db09af0db2', @@ -95,7 +94,16 @@ const displayBidderRequestWithConsents = { gdprApplies: true, consentString: 'test' }, - uspConsent: 'iHaveIt' + uspConsent: 'iHaveIt', + ortb2: { + source: { + ext: { + schain: { + ver: '1.0' + } + } + } + } }; const videoEqResponse = [{ @@ -284,7 +292,7 @@ describe('adtargetBidAdapter', () => { expect(bidRequestWithPubSettingsData.Coppa).to.be.equal(1); }) it('sets Schain', () => { - expect(bidRequestWithPubSettingsData.Schain).to.be.deep.equal(DISPLAY_REQUEST.schain); + expect(bidRequestWithPubSettingsData.Schain).to.be.deep.equal(displayBidderRequestWithConsents.ortb2.source.ext.schain); }) it('sets UserId\'s', () => { expect(bidRequestWithPubSettingsData.UserIds).to.be.deep.equal(DISPLAY_REQUEST.userId); diff --git a/test/spec/modules/adtelligentBidAdapter_spec.js b/test/spec/modules/adtelligentBidAdapter_spec.js index b12744d3a28..9773f685bf1 100644 --- a/test/spec/modules/adtelligentBidAdapter_spec.js +++ b/test/spec/modules/adtelligentBidAdapter_spec.js @@ -20,13 +20,12 @@ const aliasEP = { 'stellormedia': 'https://ghb.ads.stellormedia.com/v2/auction/', }; -const DEFAULT_ADATPER_REQ = { bidderCode: 'adtelligent' }; +const DEFAULT_ADATPER_REQ = { bidderCode: 'adtelligent', ortb2: { source: { ext: { schain: { ver: 1 } } } } }; const DISPLAY_REQUEST = { 'bidder': 'adtelligent', 'params': { 'aid': 12345 }, - 'schain': { ver: 1 }, 'userId': { criteo: 2 }, 'mediaTypes': { 'banner': { 'sizes': [300, 250] } }, 'bidderRequestId': '7101db09af0db2', diff --git a/test/spec/modules/adtrgtmeBidAdapter_spec.js b/test/spec/modules/adtrgtmeBidAdapter_spec.js index 925f5763c5d..b4abd2709a4 100644 --- a/test/spec/modules/adtrgtmeBidAdapter_spec.js +++ b/test/spec/modules/adtrgtmeBidAdapter_spec.js @@ -266,7 +266,7 @@ describe('Adtrgtme Bid Adapter:', () => { hp: 1 }] }; - bidRequest.schain = globalSchain; + bidRequest.ortb2 = { source: { ext: { schain: globalSchain } } }; const data = spec.buildRequests(validBR, bidderRequest)[0].data; const schain = data.source.ext.schain; expect(schain.nodes.length).to.equal(1); diff --git a/test/spec/modules/adtrueBidAdapter_spec.js b/test/spec/modules/adtrueBidAdapter_spec.js index df8f9013534..4efc8d69707 100644 --- a/test/spec/modules/adtrueBidAdapter_spec.js +++ b/test/spec/modules/adtrueBidAdapter_spec.js @@ -33,22 +33,28 @@ describe('AdTrueBidAdapter', function () { tid: '92489f71-1bf2-49a0-adf9-000cea934729', } }, - schain: { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, + ortb2: { + source: { + ext: { + schain: { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'indirectseller.com', + 'sid': '00001', + 'hp': 1 + }, - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 2 + { + 'asi': 'indirectseller-2.com', + 'sid': '00002', + 'hp': 1 + } + ] + } } - ] + } } } ]; @@ -291,7 +297,7 @@ describe('AdTrueBidAdapter', function () { expect(data.imp[0].tagid).to.equal(bidRequests[0].params.zoneId); // zoneId expect(data.imp[0].banner.w).to.equal(300); // width expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.source.ext.schain).to.deep.equal(bidRequests[0].schain); + expect(data.source.ext.schain).to.deep.equal(bidRequests[0].ortb2.source.ext.schain); }); it('Request params check with GDPR Consent', function () { let bidRequest = { @@ -314,7 +320,7 @@ describe('AdTrueBidAdapter', function () { expect(data.imp[0].tagid).to.equal(bidRequests[0].params.zoneId); // zoneId expect(data.imp[0].banner.w).to.equal(300); // width expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.source.ext.schain).to.deep.equal(bidRequests[0].schain); + expect(data.source.ext.schain).to.deep.equal(bidRequests[0].ortb2.source.ext.schain); }); it('Request params check with USP/CCPA Consent', function () { let bidRequest = { @@ -334,7 +340,7 @@ describe('AdTrueBidAdapter', function () { expect(data.imp[0].tagid).to.equal(bidRequests[0].params.zoneId); // zoneId expect(data.imp[0].banner.w).to.equal(300); // width expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.source.ext.schain).to.deep.equal(bidRequests[0].schain); + expect(data.source.ext.schain).to.deep.equal(bidRequests[0].ortb2.source.ext.schain); }); it('should NOT include coppa flag in bid request if coppa config is not present', () => { diff --git a/test/spec/modules/advertisingBidAdapter_spec.js b/test/spec/modules/advertisingBidAdapter_spec.js index bb4edc9ab05..d73df844d1f 100644 --- a/test/spec/modules/advertisingBidAdapter_spec.js +++ b/test/spec/modules/advertisingBidAdapter_spec.js @@ -878,16 +878,22 @@ describe('advertisingBidAdapter ', function () { bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0, - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '00001', + hp: 1 + } + ] + } } - ] + } } }; let bidderRequest = { diff --git a/test/spec/modules/adyoulikeBidAdapter_spec.js b/test/spec/modules/adyoulikeBidAdapter_spec.js index 367fc62c719..d67ba92ff8a 100644 --- a/test/spec/modules/adyoulikeBidAdapter_spec.js +++ b/test/spec/modules/adyoulikeBidAdapter_spec.js @@ -99,18 +99,24 @@ describe('Adyoulike Adapter', function () { } }, }, - 'schain': { - validation: 'strict', - config: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1 + 'ortb2': { + 'source': { + 'ext': { + 'schain': { + validation: 'strict', + config: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '00001', + hp: 1 + } + ] + } } - ] + } } }, ortb2Imp: { @@ -682,7 +688,7 @@ describe('Adyoulike Adapter', function () { expect(payload.gdprConsent.consentString).to.exist.and.to.equal(consentString); expect(payload.gdprConsent.consentRequired).to.exist.and.to.be.true; expect(payload.uspConsent).to.exist.and.to.equal(uspConsentData); - expect(payload.Bids.bid_id_0.SChain).to.exist.and.to.deep.equal(bidRequestWithSinglePlacement[0].schain); + expect(payload.Bids.bid_id_0.SChain).to.exist.and.to.deep.equal(bidRequestWithSinglePlacement[0].ortb2.source.ext.schain); }); it('should not set a default value for gdpr consentRequired', function () { diff --git a/test/spec/modules/ajaBidAdapter_spec.js b/test/spec/modules/ajaBidAdapter_spec.js index bd2bdd3e407..82c6d1bab65 100644 --- a/test/spec/modules/ajaBidAdapter_spec.js +++ b/test/spec/modules/ajaBidAdapter_spec.js @@ -66,6 +66,32 @@ describe('AjaAdapter', function () { ext: { cdep: 'example_label_1' } + }, + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'exchange1.com', + sid: '1234', + hp: 1, + rid: 'bid-request-1', + name: 'publisher', + domain: 'publisher.com' + }, + { + asi: 'exchange2.com', + sid: 'abcd', + hp: 1, + rid: 'bid-request-2', + name: 'intermediary', + domain: 'intermediary.com' + } + ] + } + } } }, ortb2Imp: { @@ -74,28 +100,7 @@ describe('AjaAdapter', function () { gpid: '/1111/homepage#300x250' } }, - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'exchange1.com', - sid: '1234', - hp: 1, - rid: 'bid-request-1', - name: 'publisher', - domain: 'publisher.com' - }, - { - asi: 'exchange2.com', - sid: 'abcd', - hp: 1, - rid: 'bid-request-2', - name: 'intermediary', - domain: 'intermediary.com' - } - ] - }, + } ]; const serializedSchain = encodeURIComponent('1.0,1!exchange1.com,1234,1,bid-request-1,publisher,publisher.com!exchange2.com,abcd,1,bid-request-2,intermediary,intermediary.com') diff --git a/test/spec/modules/alkimiBidAdapter_spec.js b/test/spec/modules/alkimiBidAdapter_spec.js index d642afd2b26..d2a6a4dcada 100644 --- a/test/spec/modules/alkimiBidAdapter_spec.js +++ b/test/spec/modules/alkimiBidAdapter_spec.js @@ -35,14 +35,20 @@ const REQUEST = { 'atype': 1 }] }], - 'schain': { - ver: '1.0', - complete: 1, - nodes: [{ - asi: 'alkimi-onboarding.com', - sid: '00001', - hp: 1 - }] + 'ortb2': { + 'source': { + 'ext': { + 'schain': { + ver: '1.0', + complete: 1, + nodes: [{ + asi: 'alkimi-onboarding.com', + sid: '00001', + hp: 1 + }] + } + } + } } } @@ -153,7 +159,7 @@ describe('alkimiBidAdapter', function () { expect(bidderRequest.method).to.equal('POST') expect(bidderRequest.data.requestId).to.not.equal(undefined) expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') - expect(bidderRequest.data.schain).to.deep.contains({ ver: '1.0', complete: 1, nodes: [{ asi: 'alkimi-onboarding.com', sid: '00001', hp: 1 }] }) + expect(bidderRequest.data.schain).to.deep.equal({ ver: '1.0', complete: 1, nodes: [{ asi: 'alkimi-onboarding.com', sid: '00001', hp: 1 }] }) expect(bidderRequest.data.signRequest.bids).to.deep.contains({ token: 'e64782a4-8e68-4c38-965b-80ccf115d46f', bidFloor: 0.1, sizes: [{ width: 300, height: 250 }], playerSizes: [], impMediaTypes: ['Banner'], adUnitCode: 'bannerAdUnitCode', instl: undefined, exp: undefined, banner: { sizes: [[300, 250]] }, video: undefined, ext: { gpid: '/111/banner#300x250', tid: 'e64782a4-8e68-4c38-965b-80ccf115d46a' } }) expect(bidderRequest.data.signRequest.randomUUID).to.equal(undefined) expect(bidderRequest.data.bidIds).to.deep.contains('456') diff --git a/test/spec/modules/amxBidAdapter_spec.js b/test/spec/modules/amxBidAdapter_spec.js index 680579aa299..5aa0c0f09d3 100644 --- a/test/spec/modules/amxBidAdapter_spec.js +++ b/test/spec/modules/amxBidAdapter_spec.js @@ -115,7 +115,7 @@ const sampleBidRequestVideo = { ...sampleBidRequestBase, bidId: sampleRequestId + '_video', sizes: [[300, 150]], - schain: schainConfig, + ortb2: { source: { ext: { schain: schainConfig } } }, mediaTypes: { [VIDEO]: { sizes: [[360, 250]], diff --git a/test/spec/modules/anyclipBidAdapter_spec.js b/test/spec/modules/anyclipBidAdapter_spec.js index 3ec81d60546..a25c285e6c4 100644 --- a/test/spec/modules/anyclipBidAdapter_spec.js +++ b/test/spec/modules/anyclipBidAdapter_spec.js @@ -128,18 +128,20 @@ describe('anyclipBidAdapter', () => { it('should build request with schain', function () { const schainRequest = deepClone(defaultRequest); - schainRequest.schain = { - validation: 'strict', - config: { - ver: '1.0' + const bidderRequest = { + ortb2: { + source: { + ext: { + schain: { + ver: '1.0' + } + } + } } }; - const request = JSON.parse(spec.buildRequests([schainRequest], {}).data)[0]; + const request = JSON.parse(spec.buildRequests([schainRequest], bidderRequest).data)[0]; expect(request).to.have.property('schain').and.to.deep.equal({ - validation: 'strict', - config: { - ver: '1.0' - } + ver: '1.0' }); }); diff --git a/test/spec/modules/apacdexBidAdapter_spec.js b/test/spec/modules/apacdexBidAdapter_spec.js index d005934d062..e10b7468695 100644 --- a/test/spec/modules/apacdexBidAdapter_spec.js +++ b/test/spec/modules/apacdexBidAdapter_spec.js @@ -183,21 +183,27 @@ describe('ApacdexBidAdapter', function () { userSync.canBidderRegisterSync.restore(); }); let bidRequest = [{ - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 0 - }, - ] + 'ortb2': { + 'source': { + 'ext': { + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'indirectseller.com', + 'sid': '00001', + 'hp': 1 + }, + { + 'asi': 'indirectseller-2.com', + 'sid': '00002', + 'hp': 0 + }, + ] + } + } + } }, 'bidder': 'apacdex', 'params': { @@ -314,7 +320,7 @@ describe('ApacdexBidAdapter', function () { }) it('should return a properly formatted request with schain defined', function () { const bidRequests = spec.buildRequests(bidRequest, bidderRequests); - expect(bidRequests.data.schain).to.deep.equal(bidRequest[0].schain) + expect(bidRequests.data.schain).to.deep.equal(bidRequest[0].ortb2.source.ext.schain) }); it('should return a properly formatted request with eids defined', function () { const bidRequests = spec.buildRequests(bidRequest, bidderRequests); diff --git a/test/spec/modules/appnexusBidAdapter_spec.js b/test/spec/modules/appnexusBidAdapter_spec.js index 8298f1b56bc..36707601cab 100644 --- a/test/spec/modules/appnexusBidAdapter_spec.js +++ b/test/spec/modules/appnexusBidAdapter_spec.js @@ -1462,16 +1462,22 @@ describe('AppNexusAdapter', function () { it('should populate schain if available', function () { const bidRequest = Object.assign({}, bidRequests[0], { - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - 'asi': 'blob.com', - 'sid': '001', - 'hp': 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + 'asi': 'blob.com', + 'sid': '001', + 'hp': 1 + } + ] + } } - ] + } } }); diff --git a/test/spec/modules/audiencerunBidAdapter_spec.js b/test/spec/modules/audiencerunBidAdapter_spec.js index 65349409e5e..04a0194af54 100644 --- a/test/spec/modules/audiencerunBidAdapter_spec.js +++ b/test/spec/modules/audiencerunBidAdapter_spec.js @@ -239,17 +239,23 @@ describe('AudienceRun bid adapter tests', function () { it('should add schain object if available', function() { const bid = Object.assign({}, bidRequest) - bid.schain = { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'directseller.com', - sid: '00001', - rid: 'BidRequest1', - hp: 1, - }, - ], + bid.ortb2 = { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'directseller.com', + sid: '00001', + rid: 'BidRequest1', + hp: 1, + }, + ], + } + } + } }; const request = spec.buildRequests([bid]); diff --git a/test/spec/modules/beachfrontBidAdapter_spec.js b/test/spec/modules/beachfrontBidAdapter_spec.js index 2e766487951..a881928a017 100644 --- a/test/spec/modules/beachfrontBidAdapter_spec.js +++ b/test/spec/modules/beachfrontBidAdapter_spec.js @@ -327,7 +327,7 @@ describe('BeachfrontAdapter', function () { }; const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { video: {} }; - bidRequest.schain = schain; + bidRequest.ortb2 = { source: { ext: { schain: schain } } }; const requests = spec.buildRequests([ bidRequest ], {}); const data = requests[0].data; expect(data.source.ext.schain).to.deep.equal(schain); @@ -565,7 +565,7 @@ describe('BeachfrontAdapter', function () { }; const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { banner: {} }; - bidRequest.schain = schain; + bidRequest.ortb2 = { source: { ext: { schain: schain } } }; const requests = spec.buildRequests([ bidRequest ], {}); const data = requests[0].data; expect(data.schain).to.deep.equal(schain); diff --git a/test/spec/modules/blastoBidAdapter_spec.js b/test/spec/modules/blastoBidAdapter_spec.js index 2efdd5ad286..7a2c94f3b14 100644 --- a/test/spec/modules/blastoBidAdapter_spec.js +++ b/test/spec/modules/blastoBidAdapter_spec.js @@ -13,7 +13,6 @@ import 'modules/multibid/index.js'; import 'modules/priceFloors.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; -import 'modules/schain.js'; const SIMPLE_BID_REQUEST = { bidder: 'blasto', diff --git a/test/spec/modules/bliinkBidAdapter_spec.js b/test/spec/modules/bliinkBidAdapter_spec.js index 9568c893b13..7c9694affd5 100644 --- a/test/spec/modules/bliinkBidAdapter_spec.js +++ b/test/spec/modules/bliinkBidAdapter_spec.js @@ -809,16 +809,22 @@ const testsBuildRequests = [ fn: spec.buildRequests( [ { - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'ssp.test', - sid: '00001', - hp: 1, - }, - ], + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'ssp.test', + sid: '00001', + hp: 1, + }, + ], + } + } + } }, }, ], diff --git a/test/spec/modules/bridBidAdapter_spec.js b/test/spec/modules/bridBidAdapter_spec.js index 20a6542707b..a97e56c5ba0 100644 --- a/test/spec/modules/bridBidAdapter_spec.js +++ b/test/spec/modules/bridBidAdapter_spec.js @@ -50,7 +50,7 @@ describe('Brid Bid Adapter', function() { }; let videoRequestCloned = deepClone(videoRequest); - videoRequestCloned[0].schain = globalSchain; + videoRequestCloned[0].ortb2 = { source: { ext: { schain: globalSchain } } }; const request = spec.buildRequests(videoRequestCloned, videoRequestCloned[0]); expect(request).to.not.be.empty; diff --git a/test/spec/modules/bridgeuppBidAdapter_spec.js b/test/spec/modules/bridgeuppBidAdapter_spec.js index 89164b1948f..a9e7b329cc9 100644 --- a/test/spec/modules/bridgeuppBidAdapter_spec.js +++ b/test/spec/modules/bridgeuppBidAdapter_spec.js @@ -242,7 +242,9 @@ describe('bridgeuppBidAdapter_spec', function () { const ortb2 = { source: { pchain: 'sonarads', - schain: expectedSchain + ext: { + schain: expectedSchain + } } }; const bidRequests = [ @@ -261,7 +263,7 @@ describe('bridgeuppBidAdapter_spec', function () { }, ]; const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({...bidderRequest, ortb2})).data; - expect(ortbRequest.source.schain).to.deep.equal(expectedSchain); + expect(ortbRequest.source.ext.schain).to.deep.equal(expectedSchain); expect(ortbRequest.source.pchain).to.equal('sonarads'); }); diff --git a/test/spec/modules/brightMountainMediaBidAdapter_spec.js b/test/spec/modules/brightMountainMediaBidAdapter_spec.js index 5e433abebd8..58c0d5f5e3c 100644 --- a/test/spec/modules/brightMountainMediaBidAdapter_spec.js +++ b/test/spec/modules/brightMountainMediaBidAdapter_spec.js @@ -26,17 +26,23 @@ describe('brightMountainMediaBidAdapter_spec', function () { floor: 0.5, } }, - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'directseller.com', - sid: '00001', - rid: 'BidRequest1', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'directseller.com', + sid: '00001', + rid: 'BidRequest1', + hp: 1 + } + ] + } } - ] + } }, userIdAsEids: [ { diff --git a/test/spec/modules/browsiBidAdapter_spec.js b/test/spec/modules/browsiBidAdapter_spec.js index 9693972fd7f..4c585ca71b3 100644 --- a/test/spec/modules/browsiBidAdapter_spec.js +++ b/test/spec/modules/browsiBidAdapter_spec.js @@ -69,7 +69,13 @@ describe('browsi Bid Adapter Test', function () { tid: '1234567-3456-4562-7689-98765434B', } }, - 'schain': {}, + 'ortb2': { + 'source': { + 'ext': { + 'schain': {} + } + } + }, 'mediaTypes': {video: {playerSize: [640, 480]}} } ]; @@ -117,7 +123,7 @@ describe('browsi Bid Adapter Test', function () { aUCode: inputRequest.adUnitCode, aID: inputRequest.auctionId, tID: inputRequest.ortb2Imp.ext.tid, - schain: inputRequest.schain, + schain: inputRequest.ortb2?.source?.ext?.schain, params: inputRequest.params } } diff --git a/test/spec/modules/cadentApertureMXBidAdapter_spec.js b/test/spec/modules/cadentApertureMXBidAdapter_spec.js index c5d68f6ab81..16e2bc66b40 100644 --- a/test/spec/modules/cadentApertureMXBidAdapter_spec.js +++ b/test/spec/modules/cadentApertureMXBidAdapter_spec.js @@ -377,23 +377,29 @@ describe('cadent_aperture_mx Adapter', function () { it('should add schain object to request', function() { const schainBidderRequest = utils.deepClone(bidderRequest); - schainBidderRequest.bids[0].schain = { - 'complete': 1, - 'ver': '1.0', - 'nodes': [ - { - 'asi': 'testing.com', - 'sid': 'abc', - 'hp': 1 + schainBidderRequest.bids[0].ortb2 = { + source: { + ext: { + schain: { + 'complete': 1, + 'ver': '1.0', + 'nodes': [ + { + 'asi': 'testing.com', + 'sid': 'abc', + 'hp': 1 + } + ] + } } - ] + } }; let request = spec.buildRequests(schainBidderRequest.bids, schainBidderRequest); request = JSON.parse(request.data); expect(request.source.ext.schain).to.exist; expect(request.source.ext.schain).to.have.property('complete', 1); expect(request.source.ext.schain).to.have.property('ver', '1.0'); - expect(request.source.ext.schain.nodes[0].asi).to.equal(schainBidderRequest.bids[0].schain.nodes[0].asi); + expect(request.source.ext.schain.nodes[0].asi).to.equal(schainBidderRequest.bids[0].ortb2.source.ext.schain.nodes[0].asi); }); it('should add liveramp identitylink id to request', () => { diff --git a/test/spec/modules/carodaBidAdapter_spec.js b/test/spec/modules/carodaBidAdapter_spec.js index 780c81ebe9f..7fa0827b3bf 100644 --- a/test/spec/modules/carodaBidAdapter_spec.js +++ b/test/spec/modules/carodaBidAdapter_spec.js @@ -109,10 +109,16 @@ describe('Caroda adapter', function () { const validBidRequests = [{ bid_id: 'bidId', params: {}, - schain: { - validation: 'strict', - config: { - ver: '1.0' + ortb2: { + source: { + ext: { + schain: { + validation: 'strict', + config: { + ver: '1.0' + } + } + } } } }]; diff --git a/test/spec/modules/colossussspBidAdapter_spec.js b/test/spec/modules/colossussspBidAdapter_spec.js index 9f675592951..69b3dc556f0 100644 --- a/test/spec/modules/colossussspBidAdapter_spec.js +++ b/test/spec/modules/colossussspBidAdapter_spec.js @@ -24,19 +24,25 @@ describe('ColossussspAdapter', function () { data: {} } }, - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '0', - hp: 1, - rid: 'bidrequestid', - // name: 'alladsallthetime', - domain: 'example.com' + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'example.com', + sid: '0', + hp: 1, + rid: 'bidrequestid', + // name: 'alladsallthetime', + domain: 'example.com' + } + ] + } } - ] + } } }; let bidderRequest = { diff --git a/test/spec/modules/connectadBidAdapter_spec.js b/test/spec/modules/connectadBidAdapter_spec.js index f067d801c5e..030c21c13d7 100644 --- a/test/spec/modules/connectadBidAdapter_spec.js +++ b/test/spec/modules/connectadBidAdapter_spec.js @@ -372,16 +372,22 @@ describe('ConnectAd Adapter', function () { it('should populate schain', function () { const bidRequest = Object.assign({}, bidRequests[0], { - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - 'asi': 'reseller1.com', - 'sid': 'absc1', - 'hp': 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + 'asi': 'reseller1.com', + 'sid': 'absc1', + 'hp': 1 + } + ] + } } - ] + } } }); diff --git a/test/spec/modules/consumableBidAdapter_spec.js b/test/spec/modules/consumableBidAdapter_spec.js index aa3eee990c2..eff4e9e0526 100644 --- a/test/spec/modules/consumableBidAdapter_spec.js +++ b/test/spec/modules/consumableBidAdapter_spec.js @@ -33,22 +33,6 @@ const BIDDER_REQUEST_1 = { transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' } ], - schain: { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 2 - }, - ] - }, gdprConsent: { consentString: 'consent-test', gdprApplies: false @@ -70,6 +54,26 @@ const BIDDER_REQUEST_1 = { ortb2: { device: { language: 'en' + }, + source: { + ext: { + schain: { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'indirectseller.com', + 'sid': '00001', + 'hp': 1 + }, + { + 'asi': 'indirectseller-2.com', + 'sid': '00002', + 'hp': 2 + }, + ] + } + } } } }; @@ -488,7 +492,7 @@ describe('Consumable BidAdapter', function () { let request = spec.buildRequests(BIDDER_REQUEST_1.bidRequest, BIDDER_REQUEST_1); let data = JSON.parse(request.data); - expect(data.schain).to.deep.equal(BIDDER_REQUEST_1.schain) + expect(data.schain).to.deep.equal(BIDDER_REQUEST_1.ortb2.source.ext.schain) }); it('should not contain schain if it does not exist in the bidRequest', function () { diff --git a/test/spec/modules/conversantBidAdapter_spec.js b/test/spec/modules/conversantBidAdapter_spec.js index 8978ac00342..cb07ff422f9 100644 --- a/test/spec/modules/conversantBidAdapter_spec.js +++ b/test/spec/modules/conversantBidAdapter_spec.js @@ -9,7 +9,6 @@ import 'modules/userId/index.js'; // handles eids import 'modules/priceFloors.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; -import 'modules/schain.js'; // handles schain import {hook} from '../../../src/hook.js' import {BANNER} from '../../../src/mediaTypes'; @@ -450,10 +449,22 @@ describe('Conversant adapter tests', function() { it('Verify supply chain data', () => { const bidderRequest = {refererInfo: {page: 'http://test.com?a=b&c=123'}}; const schain = {complete: 1, ver: '1.0', nodes: [{asi: 'bidderA.com', sid: '00001', hp: 1}]}; + + // Add schain to bidderRequest + bidderRequest.ortb2 = { + source: { + ext: {schain: schain} + } + }; + const bidsWithSchain = bidRequests.map((bid) => { return Object.assign({ - schain: schain - }, bid); + ortb2: { + source: { + ext: {schain: schain} + } + } + }, bid); }); const request = spec.buildRequests(bidsWithSchain, bidderRequest); const payload = request.data; diff --git a/test/spec/modules/cpmstarBidAdapter_spec.js b/test/spec/modules/cpmstarBidAdapter_spec.js index f9b1ba59cde..c1c773d5047 100755 --- a/test/spec/modules/cpmstarBidAdapter_spec.js +++ b/test/spec/modules/cpmstarBidAdapter_spec.js @@ -131,21 +131,27 @@ describe('Cpmstar Bid Adapter', function () { it('should produce a request with support for OpenRTB SupplyChain', function () { var reqs = deepClone(valid_bid_requests); - reqs[0].schain = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'exchange1.com', - 'sid': '1234', - 'hp': 1 - }, - { - 'asi': 'exchange2.com', - 'sid': 'abcd', - 'hp': 1 + reqs[0].ortb2 = { + source: { + ext: { + schain: { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'exchange1.com', + 'sid': '1234', + 'hp': 1 + }, + { + 'asi': 'exchange2.com', + 'sid': 'abcd', + 'hp': 1 + } + ] + } } - ] + } }; var requests = spec.buildRequests(reqs, bidderRequest); expect(requests[0]).to.have.property('url'); diff --git a/test/spec/modules/criteoBidAdapter_spec.js b/test/spec/modules/criteoBidAdapter_spec.js index 960755ee71f..322e0716040 100755 --- a/test/spec/modules/criteoBidAdapter_spec.js +++ b/test/spec/modules/criteoBidAdapter_spec.js @@ -10,7 +10,7 @@ import 'modules/userId/index.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; import 'modules/consentManagementGpp.js'; -import 'modules/schain.js'; + import {hook} from '../../../src/hook'; describe('The Criteo bidding adapter', function () { @@ -1219,14 +1219,18 @@ describe('The Criteo bidding adapter', function () { expect(ortbRequest.regs.ext.dsa).to.deep.equal(dsa); }); - it('should properly build a request with schain object', async function () { + it('should properly build a request with schain object', function () { const expectedSchain = { someProperty: 'someValue' }; const bidRequests = [ { bidder: 'criteo', - schain: expectedSchain, + ortb2: { + source: { + ext: {schain: expectedSchain} + } + }, adUnitCode: 'bid-123', mediaTypes: { banner: { @@ -1238,9 +1242,19 @@ describe('The Criteo bidding adapter', function () { }, }, ]; + + // Create a modified bidderRequest with schain + const modifiedBidderRequest = { + ...bidderRequest, + ortb2: { + source: { + ext: {schain: expectedSchain} + } + } + }; - const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)).data; - expect(ortbRequest.source.ext.schain).to.equal(expectedSchain); + const ortbRequest = spec.buildRequests(bidRequests, modifiedBidderRequest).data; + expect(ortbRequest.source.ext.schain).to.deep.equal(expectedSchain); }); it('should properly build a request with bcat field', async function () { diff --git a/test/spec/modules/dianomiBidAdapter_spec.js b/test/spec/modules/dianomiBidAdapter_spec.js index ef9283d3dad..a0cb1be68de 100644 --- a/test/spec/modules/dianomiBidAdapter_spec.js +++ b/test/spec/modules/dianomiBidAdapter_spec.js @@ -284,11 +284,17 @@ describe('Dianomi adapter', () => { { bidId: 'bidId', params: { smartadId: 1234 }, - schain: { - validation: 'strict', - config: { - ver: '1.0', - }, + ortb2: { + source: { + ext: { + schain: { + validation: 'strict', + config: { + ver: '1.0', + }, + } + } + } }, }, ]; diff --git a/test/spec/modules/digitalMatterBidAdapter_spec.js b/test/spec/modules/digitalMatterBidAdapter_spec.js index 87056588cd9..12ff5d89c0b 100644 --- a/test/spec/modules/digitalMatterBidAdapter_spec.js +++ b/test/spec/modules/digitalMatterBidAdapter_spec.js @@ -117,10 +117,16 @@ describe('Digital Matter BidAdapter', function () { it('should pass supply chain object', function () { let validBidRequests = { ...bid, - schain: { - validation: 'strict', - config: { - ver: '1.0' + ortb2: { + source: { + ext: { + schain: { + validation: 'strict', + config: { + ver: '1.0' + } + } + } } } }; diff --git a/test/spec/modules/driftpixelBidAdapter_spec.js b/test/spec/modules/driftpixelBidAdapter_spec.js index 057ca1c7e9f..a7b5a164996 100644 --- a/test/spec/modules/driftpixelBidAdapter_spec.js +++ b/test/spec/modules/driftpixelBidAdapter_spec.js @@ -128,18 +128,20 @@ describe('driftpixelBidAdapter', () => { it('should build request with schain', function () { const schainRequest = deepClone(defaultRequest); - schainRequest.schain = { - validation: 'strict', - config: { - ver: '1.0' + const bidderRequest = { + ortb2: { + source: { + ext: { + schain: { + ver: '1.0' + } + } + } } }; - const request = JSON.parse(spec.buildRequests([schainRequest], {}).data)[0]; + const request = JSON.parse(spec.buildRequests([schainRequest], bidderRequest).data)[0]; expect(request).to.have.property('schain').and.to.deep.equal({ - validation: 'strict', - config: { - ver: '1.0' - } + ver: '1.0' }); }); diff --git a/test/spec/modules/dspxBidAdapter_spec.js b/test/spec/modules/dspxBidAdapter_spec.js index ad7bc827837..fb135142744 100644 --- a/test/spec/modules/dspxBidAdapter_spec.js +++ b/test/spec/modules/dspxBidAdapter_spec.js @@ -110,18 +110,24 @@ describe('dspxAdapter', function () { 'crumbs': { 'pubcid': 'e09ab6a3-ae74-4f01-b2e8-81b141d6dc61' }, - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'example.com', - 'sid': '0', - 'hp': 1, - 'rid': 'bidrequestid', - 'domain': 'example.com' + 'ortb2': { + 'source': { + 'ext': { + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'example.com', + 'sid': '0', + 'hp': 1, + 'rid': 'bidrequestid', + 'domain': 'example.com' + } + ] + } } - ] + } } }, { diff --git a/test/spec/modules/eplanningBidAdapter_spec.js b/test/spec/modules/eplanningBidAdapter_spec.js index efb2f4a4cbb..ee9a1ea5f82 100644 --- a/test/spec/modules/eplanningBidAdapter_spec.js +++ b/test/spec/modules/eplanningBidAdapter_spec.js @@ -62,19 +62,25 @@ describe('E-Planning Adapter', function () { }, 'adUnitCode': ADUNIT_CODE2, 'sizes': [[300, 250], [300, 600]], - 'schain': { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'directseller.com', - sid: '00001', - rid: 'BidRequest1', - hp: 1, - name: 'publisher', - domain: 'publisher.com' + 'ortb2': { + 'source': { + 'ext': { + 'schain': { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'directseller.com', + sid: '00001', + rid: 'BidRequest1', + hp: 1, + name: 'publisher', + domain: 'publisher.com' + } + ] + } } - ] + } } }; const validBidWithSchainNodes = { @@ -85,35 +91,41 @@ describe('E-Planning Adapter', function () { }, 'adUnitCode': ADUNIT_CODE2, 'sizes': [[300, 250], [300, 600]], - 'schain': { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'directseller.com', - sid: '00001', - rid: 'BidRequest1', - hp: 1, - name: 'publisher', - domain: 'publisher.com' - }, - { - asi: 'reseller.com', - sid: 'aaaaa', - rid: 'BidRequest2', - hp: 1, - name: 'publisher2', - domain: 'publisher2.com' - }, - { - asi: 'reseller3.com', - sid: 'aaaaab', - rid: 'BidRequest3', - hp: 1, - name: 'publisher3', - domain: 'publisher3.com' + 'ortb2': { + 'source': { + 'ext': { + 'schain': { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'directseller.com', + sid: '00001', + rid: 'BidRequest1', + hp: 1, + name: 'publisher', + domain: 'publisher.com' + }, + { + asi: 'reseller.com', + sid: 'aaaaa', + rid: 'BidRequest2', + hp: 1, + name: 'publisher2', + domain: 'publisher2.com' + }, + { + asi: 'reseller3.com', + sid: 'aaaaab', + rid: 'BidRequest3', + hp: 1, + name: 'publisher3', + domain: 'publisher3.com' + } + ] + } } - ] + } } }; const ML = '1'; @@ -796,7 +808,7 @@ describe('E-Planning Adapter', function () { }); it('should return sch parameter', function () { let bidRequests = [validBidWithSchain], schainExpected, schain; - schain = validBidWithSchain.schain; + schain = validBidWithSchain.ortb2.source.ext.schain; schainExpected = schain.ver + ',' + schain.complete + '!' + schain.nodes.map(node => node.asi + ',' + node.sid + ',' + node.hp + ',' + node.rid + ',' + node.name + ',' + node.domain).join('!'); const data = spec.buildRequests(bidRequests, bidderRequest).data; expect(data.sch).to.deep.equal(schainExpected); diff --git a/test/spec/modules/escalaxBidAdapter_spec.js b/test/spec/modules/escalaxBidAdapter_spec.js index 6238e6cb208..3e539cc1bdc 100644 --- a/test/spec/modules/escalaxBidAdapter_spec.js +++ b/test/spec/modules/escalaxBidAdapter_spec.js @@ -12,7 +12,6 @@ import 'modules/multibid/index.js'; import 'modules/priceFloors.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; -import 'modules/schain.js'; const SIMPLE_BID_REQUEST = { bidder: 'escalax', diff --git a/test/spec/modules/fluctBidAdapter_spec.js b/test/spec/modules/fluctBidAdapter_spec.js index 82edcdac79e..e55e3f4bedc 100644 --- a/test/spec/modules/fluctBidAdapter_spec.js +++ b/test/spec/modules/fluctBidAdapter_spec.js @@ -338,16 +338,22 @@ describe('fluctAdapter', function () { // this should be done by schain.js const bidRequests2 = bidRequests.map( (bidReq) => Object.assign({}, bidReq, { - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: 'publisher-id', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'example.com', + sid: 'publisher-id', + hp: 1 + } + ] + } } - ] + } } }) ); diff --git a/test/spec/modules/freewheel-sspBidAdapter_spec.js b/test/spec/modules/freewheel-sspBidAdapter_spec.js index 94b7f04b637..e96208c3b16 100644 --- a/test/spec/modules/freewheel-sspBidAdapter_spec.js +++ b/test/spec/modules/freewheel-sspBidAdapter_spec.js @@ -102,18 +102,24 @@ describe('freewheelSSP BidAdapter Test', () => { 'bidId': '30b31c1838de1e', 'bidderRequestId': '22edbae2733bf6', 'auctionId': '1d1a030790a475', - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'example.com', - 'sid': '0', - 'hp': 1, - 'rid': 'bidrequestid', - 'domain': 'example.com' + 'ortb2': { + 'source': { + 'ext': { + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'example.com', + 'sid': '0', + 'hp': 1, + 'rid': 'bidrequestid', + 'domain': 'example.com' + } + ] + } } - ] + } } } ]; diff --git a/test/spec/modules/gamoshiBidAdapter_spec.js b/test/spec/modules/gamoshiBidAdapter_spec.js index 8f9818ed901..270c0f7c2aa 100644 --- a/test/spec/modules/gamoshiBidAdapter_spec.js +++ b/test/spec/modules/gamoshiBidAdapter_spec.js @@ -56,7 +56,13 @@ describe('GamoshiAdapter', () => { consentString: 'some string', gdprApplies: true }, - schain: schainConfig, + ortb2: { + source: { + ext: { + schain: schainConfig + } + } + }, uspConsent: 'gamoshiCCPA' }; @@ -339,7 +345,7 @@ describe('GamoshiAdapter', () => { expect(response.data.imp[0].bidfloor).to.equal(0); expect(response.data.imp[0].bidfloorcur).to.equal('USD'); expect(response.data.regs.ext.us_privacy).to.equal('gamoshiCCPA');// USP/CCPAs - expect(response.data.source.ext.schain).to.deep.equal(bidRequest2.schain); + expect(response.data.source.ext.schain).to.deep.equal(bidRequest2.ortb2.source.ext.schain); const bidRequestWithInstlEquals1 = utils.deepClone(bidRequest); bidRequestWithInstlEquals1.params.instl = 1; diff --git a/test/spec/modules/gridBidAdapter_spec.js b/test/spec/modules/gridBidAdapter_spec.js index e9ad45de45c..d35e8d8dbe8 100644 --- a/test/spec/modules/gridBidAdapter_spec.js +++ b/test/spec/modules/gridBidAdapter_spec.js @@ -540,7 +540,13 @@ describe('TheMediaGrid Adapter', function () { }; const bidRequestsWithSChain = bidRequests.map((bid) => { return Object.assign({ - schain: schain + ortb2: { + source: { + ext: { + schain: schain + } + } + } }, bid); }); const [request] = spec.buildRequests(bidRequestsWithSChain, bidderRequest); diff --git a/test/spec/modules/gumgumBidAdapter_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js index 8618b647d25..f497e49350a 100644 --- a/test/spec/modules/gumgumBidAdapter_spec.js +++ b/test/spec/modules/gumgumBidAdapter_spec.js @@ -171,27 +171,33 @@ describe('gumgumAdapter', function () { adUnitCode: 'adunit-code', sizes: sizesArray, bidId: '30b31c1838de1e', - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'exchange1.com', - sid: '1234', - hp: 1, - rid: 'bid-request-1', - name: 'publisher', - domain: 'publisher.com' - }, - { - asi: 'exchange2.com', - sid: 'abcd', - hp: 1, - rid: 'bid-request-2', - name: 'intermediary', - domain: 'intermediary.com' + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'exchange1.com', + sid: '1234', + hp: 1, + rid: 'bid-request-1', + name: 'publisher', + domain: 'publisher.com' + }, + { + asi: 'exchange2.com', + sid: 'abcd', + hp: 1, + rid: 'bid-request-2', + name: 'intermediary', + domain: 'intermediary.com' + } + ] + } } - ] + } } } ]; diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index adbf30bb5f1..c7c074795f0 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -12,7 +12,6 @@ import 'modules/multibid/index.js'; import 'modules/priceFloors.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; -import 'modules/schain.js'; import {decorateAdUnitsWithNativeParams} from '../../../src/native.js'; import {hook} from '../../../src/hook.js'; import {addFPDToBidderRequest} from '../../helpers/fpd.js'; @@ -553,8 +552,25 @@ describe('Improve Digital Adapter Tests', function () { it('should add schain', function () { const schain = '{"ver":"1.0","complete":1,"nodes":[{"asi":"headerlift.com","sid":"xyz","hp":1}]}'; const bidRequest = Object.assign({}, simpleBidRequest); - bidRequest.schain = schain; - const request = spec.buildRequests([bidRequest], bidderRequestReferrer)[0]; + + // Add schain to both locations in the bid + bidRequest.ortb2 = { + source: { + ext: {schain: schain} + } + }; + + // Add schain to bidderRequest as well + const modifiedBidderRequest = { + ...bidderRequestReferrer, + ortb2: { + source: { + ext: {schain: schain} + } + } + }; + + const request = spec.buildRequests([bidRequest], modifiedBidderRequest)[0]; const payload = JSON.parse(request.data); expect(payload.source.ext.schain).to.equal(schain); }); diff --git a/test/spec/modules/insticatorBidAdapter_spec.js b/test/spec/modules/insticatorBidAdapter_spec.js index d6daceddd6e..31df4714d58 100644 --- a/test/spec/modules/insticatorBidAdapter_spec.js +++ b/test/spec/modules/insticatorBidAdapter_spec.js @@ -46,17 +46,23 @@ describe('InsticatorBidAdapter', function () { gpid: '1111/homepage' } }, - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'insticator.com', - sid: '00001', - hp: 1, - rid: bidderRequestId + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'insticator.com', + sid: '00001', + hp: 1, + rid: bidderRequestId + } + ] + } } - ] + } }, userIdAsEids: [ { diff --git a/test/spec/modules/iqxBidAdapter_spec.js b/test/spec/modules/iqxBidAdapter_spec.js index 553bfa4a87d..8ca6fce841c 100644 --- a/test/spec/modules/iqxBidAdapter_spec.js +++ b/test/spec/modules/iqxBidAdapter_spec.js @@ -117,18 +117,20 @@ describe('iqxBidAdapter', () => { it('should build request with schain', function () { const schainRequest = deepClone(defaultRequest); - schainRequest.schain = { - validation: 'strict', - config: { - ver: '1.0' + const bidderRequest = { + ortb2: { + source: { + ext: { + schain: { + ver: '1.0' + } + } + } } }; - const request = JSON.parse(spec.buildRequests([schainRequest], {}).data)[0]; + const request = JSON.parse(spec.buildRequests([schainRequest], bidderRequest).data)[0]; expect(request).to.have.property('schain').and.to.deep.equal({ - validation: 'strict', - config: { - ver: '1.0' - } + ver: '1.0' }); }); diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js index 69a052f0e4e..a792a806e08 100644 --- a/test/spec/modules/ixBidAdapter_spec.js +++ b/test/spec/modules/ixBidAdapter_spec.js @@ -130,7 +130,13 @@ describe('IndexexchangeAdapter', function () { bidId: '1a2b3c4e', bidderRequestId: '11a22b33c44e', auctionId: '1aa2bb3cc4de', - schain: SAMPLE_SCHAIN + ortb2: { + source: { + ext: { + schain: SAMPLE_SCHAIN + } + } + } } ]; @@ -157,7 +163,13 @@ describe('IndexexchangeAdapter', function () { bidId: '1a2b3c4d', bidderRequestId: '11a22b33c44d', auctionId: '1aa2bb3cc4dd', - schain: SAMPLE_SCHAIN + ortb2: { + source: { + ext: { + schain: SAMPLE_SCHAIN + } + } + } } ]; @@ -185,7 +197,13 @@ describe('IndexexchangeAdapter', function () { bidId: '1a2b3c4d', bidderRequestId: '11a22b33c44d', auctionId: '1aa2bb3cc4dd', - schain: SAMPLE_SCHAIN + ortb2: { + source: { + ext: { + schain: SAMPLE_SCHAIN + } + } + } } ]; @@ -214,7 +232,13 @@ describe('IndexexchangeAdapter', function () { bidId: '1a2b3c4d', bidderRequestId: '11a22b33c44d', auctionId: '1aa2bb3cc4dd', - schain: SAMPLE_SCHAIN + ortb2: { + source: { + ext: { + schain: SAMPLE_SCHAIN + } + } + } } ]; @@ -239,7 +263,13 @@ describe('IndexexchangeAdapter', function () { bidId: '1a2b3c4d', bidderRequestId: '11a22b33c44d', auctionId: '1aa2bb3cc4dd', - schain: SAMPLE_SCHAIN + ortb2: { + source: { + ext: { + schain: SAMPLE_SCHAIN + } + } + } } ]; @@ -273,7 +303,13 @@ describe('IndexexchangeAdapter', function () { bidId: '1a2b3c4e', bidderRequestId: '11a22b33c44e', auctionId: '1aa2bb3cc4de', - schain: SAMPLE_SCHAIN + ortb2: { + source: { + ext: { + schain: SAMPLE_SCHAIN + } + } + } } ]; @@ -311,7 +347,13 @@ describe('IndexexchangeAdapter', function () { bidId: '1a2b3c4e', bidderRequestId: '11a22b33c44e', auctionId: '1aa2bb3cc4de', - schain: SAMPLE_SCHAIN + ortb2: { + source: { + ext: { + schain: SAMPLE_SCHAIN + } + } + } } ]; @@ -349,7 +391,13 @@ describe('IndexexchangeAdapter', function () { bidId: '1a2b3c4e', bidderRequestId: '11a22b33c44e', auctionId: '1aa2bb3cc4de', - schain: SAMPLE_SCHAIN + ortb2: { + source: { + ext: { + schain: SAMPLE_SCHAIN + } + } + } } ]; @@ -383,7 +431,13 @@ describe('IndexexchangeAdapter', function () { bidId: '1a2b3c4e', bidderRequestId: '11a22b33c44e', auctionId: '1aa2bb3cc4de', - schain: SAMPLE_SCHAIN + ortb2: { + source: { + ext: { + schain: SAMPLE_SCHAIN + } + } + } } ]; @@ -427,7 +481,13 @@ describe('IndexexchangeAdapter', function () { bidId: '1a2b3c4e', bidderRequestId: '11a22b33c44e', auctionId: '1aa2bb3cc4de', - schain: SAMPLE_SCHAIN + ortb2: { + source: { + ext: { + schain: SAMPLE_SCHAIN + } + } + } } ]; @@ -499,7 +559,13 @@ describe('IndexexchangeAdapter', function () { bidId: '1a2b3c4e', bidderRequestId: '11a22b33c44e', auctionId: '1aa2bb3cc4de', - schain: SAMPLE_SCHAIN + ortb2: { + source: { + ext: { + schain: SAMPLE_SCHAIN + } + } + } } ]; @@ -546,7 +612,13 @@ describe('IndexexchangeAdapter', function () { bidId: '1a2b3c4f', bidderRequestId: '11a22b33c44f', auctionId: '1aa2bb3cc4df', - schain: SAMPLE_SCHAIN + ortb2: { + source: { + ext: { + schain: SAMPLE_SCHAIN + } + } + } } ]; @@ -587,7 +659,13 @@ describe('IndexexchangeAdapter', function () { bidId: '1a2b3c4e', bidderRequestId: '11a22b33c44e', auctionId: '1aa2bb3cc4de', - schain: SAMPLE_SCHAIN + ortb2: { + source: { + ext: { + schain: SAMPLE_SCHAIN + } + } + } } ]; @@ -2074,7 +2152,9 @@ describe('IndexexchangeAdapter', function () { describe('buildRequests', function () { const bidWithoutSchain = utils.deepClone(DEFAULT_BANNER_VALID_BID); - delete bidWithoutSchain[0].schain; + if (bidWithoutSchain[0].ortb2 && bidWithoutSchain[0].ortb2.source && bidWithoutSchain[0].ortb2.source.ext) { + delete bidWithoutSchain[0].ortb2.source.ext.schain; + } const GPID = '/19968336/some-adunit-path'; let request, requestUrl, requestMethod, payloadData, requestWithoutSchain, payloadWithoutSchain; @@ -2682,7 +2762,9 @@ describe('IndexexchangeAdapter', function () { const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID); bid[0].mediaTypes.video.context = 'outstream'; bid[0].mediaTypes.video.w = [[300, 143]]; - bid[0].schain = undefined; + if (bid[0].ortb2 && bid[0].ortb2.source && bid[0].ortb2.source.ext) { + delete bid[0].ortb2.source.ext.schain; + } const request = spec.buildRequests(bid); const videoImpression = extractPayload(request[0]).imp[0]; expect(videoImpression.displaymanager).to.equal('ix'); @@ -2695,7 +2777,9 @@ describe('IndexexchangeAdapter', function () { url: 'http://publisherplayer.js', render: () => { } }; - bid[0].schain = undefined; + if (bid[0].ortb2 && bid[0].ortb2.source && bid[0].ortb2.source.ext) { + delete bid[0].ortb2.source.ext.schain; + } const request = spec.buildRequests(bid); const videoImpression = extractPayload(request[0]).imp[0]; expect(videoImpression.displaymanager).to.equal('http://publisherplayer.js'); @@ -2708,7 +2792,9 @@ describe('IndexexchangeAdapter', function () { url: 'publisherplayer.js', render: () => { } }; - bid[0].schain = undefined; + if (bid[0].ortb2 && bid[0].ortb2.source && bid[0].ortb2.source.ext) { + delete bid[0].ortb2.source.ext.schain; + } const request = spec.buildRequests(bid); const videoImpression = extractPayload(request[0]).imp[0]; expect(videoImpression.displaymanager).to.be.undefined; @@ -2721,7 +2807,9 @@ describe('IndexexchangeAdapter', function () { url: 'http://js-sec.indexww.rendererplayer.com', render: () => { } }; - bid[0].schain = undefined; + if (bid[0].ortb2 && bid[0].ortb2.source && bid[0].ortb2.source.ext) { + delete bid[0].ortb2.source.ext.schain; + } const request = spec.buildRequests(bid); const videoImpression = extractPayload(request[0]).imp[0]; expect(videoImpression.displaymanager).to.equal('ix'); @@ -2733,7 +2821,9 @@ describe('IndexexchangeAdapter', function () { bid[0].mediaTypes.video.renderer = { render: () => { } }; - bid[0].schain = undefined; + if (bid[0].ortb2 && bid[0].ortb2.source && bid[0].ortb2.source.ext) { + delete bid[0].ortb2.source.ext.schain; + } const request = spec.buildRequests(bid); const videoImpression = extractPayload(request[0]).imp[0]; expect(videoImpression.displaymanager).to.be.undefined; @@ -2742,7 +2832,13 @@ describe('IndexexchangeAdapter', function () { const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID); bid[0].mediaTypes.video.context = 'outstream'; bid[0].mediaTypes.video.w = [[300, 143]]; - bid[0].schain = SAMPLE_SCHAIN; + bid[0].ortb2 = { + source: { + ext: { + schain: SAMPLE_SCHAIN + } + } + }; const request = spec.buildRequests(bid); const videoImpression = extractPayload(request[0]).imp[0]; expect(videoImpression.displaymanager).to.equal('pbjs_wrapper'); diff --git a/test/spec/modules/jixieBidAdapter_spec.js b/test/spec/modules/jixieBidAdapter_spec.js index 5428fd0db0f..422c1c470ed 100644 --- a/test/spec/modules/jixieBidAdapter_spec.js +++ b/test/spec/modules/jixieBidAdapter_spec.js @@ -369,7 +369,15 @@ describe('jixie Adapter', function () { hp: 1 }] }; - const oneSpecialBidReq = Object.assign({}, bidRequests_[0], { schain: schain }); + const oneSpecialBidReq = Object.assign({}, bidRequests_[0], { + ortb2: { + source: { + ext: { + schain: schain + } + } + } + }); const request = spec.buildRequests([oneSpecialBidReq], bidderRequest_); const payload = JSON.parse(request.data); expect(payload.schain).to.deep.equal(schain); diff --git a/test/spec/modules/justpremiumBidAdapter_spec.js b/test/spec/modules/justpremiumBidAdapter_spec.js index b08be01461b..8133d903df7 100644 --- a/test/spec/modules/justpremiumBidAdapter_spec.js +++ b/test/spec/modules/justpremiumBidAdapter_spec.js @@ -46,7 +46,13 @@ describe('justpremium adapter', function () { zone: 28313, allow: ['lb', 'wp'] }, - schain: schainConfig + ortb2: { + source: { + ext: { + schain: schainConfig + } + } + } }, { adUnitCode: 'div-gpt-ad-1471513102552-2', diff --git a/test/spec/modules/jwplayerBidAdapter_spec.js b/test/spec/modules/jwplayerBidAdapter_spec.js index e19790a9670..ae456919238 100644 --- a/test/spec/modules/jwplayerBidAdapter_spec.js +++ b/test/spec/modules/jwplayerBidAdapter_spec.js @@ -148,16 +148,22 @@ describe('jwplayerBidAdapter', function() { playbackend: 2 } }, - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'publisher.com', - sid: '00001', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'publisher.com', + sid: '00001', + hp: 1 + } + ] + } } - ] + } }, bidRequestsCount: 1, adUnitCode: 'testAdUnitCode', diff --git a/test/spec/modules/kargoBidAdapter_spec.js b/test/spec/modules/kargoBidAdapter_spec.js index 2a92b347bcb..2b9c0e2ec64 100644 --- a/test/spec/modules/kargoBidAdapter_spec.js +++ b/test/spec/modules/kargoBidAdapter_spec.js @@ -512,39 +512,57 @@ describe('kargo adapter tests', function() { schain: {} }, { ...minimumBidParams, - schain: { - complete: 1, - nodes: [{ - asi: 'test-page.com', - hp: 1, - rid: '57bdd953-6e57-4d5b-9351-ed67ca238890', - sid: '8190248274' - }] + ortb2: { + source: { + ext: { + schain: { + complete: 1, + nodes: [{ + asi: 'test-page.com', + hp: 1, + rid: '57bdd953-6e57-4d5b-9351-ed67ca238890', + sid: '8190248274' + }] + } + } + } } }]); expect(payload.schain).to.be.undefined; payload = getPayloadFromTestBids([{ ...minimumBidParams, - schain: { - complete: 1, - nodes: [{ - asi: 'test-page.com', - hp: 1, - rid: '57bdd953-6e57-4d5b-9351-ed67ca238890', - sid: '8190248274' - }] + ortb2: { + source: { + ext: { + schain: { + complete: 1, + nodes: [{ + asi: 'test-page.com', + hp: 1, + rid: '57bdd953-6e57-4d5b-9351-ed67ca238890', + sid: '8190248274' + }] + } + } + } } }, { ...minimumBidParams, - schain: { - complete: 1, - nodes: [{ - asi: 'test-page-2.com', - hp: 1, - rid: 'other-rid', - sid: 'other-sid' - }] + ortb2: { + source: { + ext: { + schain: { + complete: 1, + nodes: [{ + asi: 'test-page-2.com', + hp: 1, + rid: 'other-rid', + sid: 'other-sid' + }] + } + } + } } }]); expect(payload.schain).to.deep.equal({ diff --git a/test/spec/modules/kubientBidAdapter_spec.js b/test/spec/modules/kubientBidAdapter_spec.js index a6241aa8d41..71136c2c8cd 100644 --- a/test/spec/modules/kubientBidAdapter_spec.js +++ b/test/spec/modules/kubientBidAdapter_spec.js @@ -30,18 +30,24 @@ describe('KubientAdapter', function () { } }, transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62', - schain: { - ver: '1.1', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '0', - hp: 1, - rid: 'bidrequestid', - domain: 'example.com' + ortb2: { + source: { + ext: { + schain: { + ver: '1.1', + complete: 1, + nodes: [ + { + asi: 'example.com', + sid: '0', + hp: 1, + rid: 'bidrequestid', + domain: 'example.com' + } + ] + } } - ] + } } }; let bidVideo = { @@ -67,18 +73,24 @@ describe('KubientAdapter', function () { } }, transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e61', - schain: { - ver: '1.1', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '0', - hp: 1, - rid: 'bidrequestid', - domain: 'example.com' + ortb2: { + source: { + ext: { + schain: { + ver: '1.1', + complete: 1, + nodes: [ + { + asi: 'example.com', + sid: '0', + hp: 1, + rid: 'bidrequestid', + domain: 'example.com' + } + ] + } } - ] + } } }; let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; diff --git a/test/spec/modules/lemmaDigitalBidAdapter_spec.js b/test/spec/modules/lemmaDigitalBidAdapter_spec.js index ab4c3259671..67e8ea0fb9d 100644 --- a/test/spec/modules/lemmaDigitalBidAdapter_spec.js +++ b/test/spec/modules/lemmaDigitalBidAdapter_spec.js @@ -59,7 +59,7 @@ describe('lemmaDigitalBidAdapter', function () { [300, 250], [300, 600] ], - schain: schainConfig + ortb2: { source: { ext: { schain: schainConfig } } } }]; videoBidRequests = [{ code: 'video1', @@ -84,7 +84,7 @@ describe('lemmaDigitalBidAdapter', function () { maxduration: 30 } }, - schain: schainConfig + ortb2: { source: { ext: { schain: schainConfig } } } }]; bidResponses = { 'body': { @@ -227,7 +227,7 @@ describe('lemmaDigitalBidAdapter', function () { expect(data.imp[0].tagid).to.equal('1'); // tagid expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency); expect(data.imp[0].bidfloor).to.equal(bidRequests[0].params.bidFloor); - expect(data.source.ext.schain).to.deep.equal(bidRequests[0].schain); + expect(data.source.ext.schain).to.deep.equal(bidRequests[0].ortb2.source.ext.schain); }); it('Set sizes from mediaTypes object', function () { @@ -245,7 +245,7 @@ describe('lemmaDigitalBidAdapter', function () { }); it('Check device, source object not present', function () { let newBannerRequest = utils.deepClone(bidRequests); - delete newBannerRequest[0].schain; + delete newBannerRequest[0].ortb2; let request = spec.buildRequests(newBannerRequest); let data = JSON.parse(request.data); delete data.device; @@ -461,7 +461,7 @@ describe('lemmaDigitalBidAdapter', function () { expect(data.imp[0]['video']['maxduration']).to.equal(videoBidRequests[0].params.video['maxduration']); expect(data.imp[0]['video']['w']).to.equal(videoBidRequests[0].mediaTypes.video.playerSize[0]); expect(data.imp[0]['video']['h']).to.equal(videoBidRequests[0].mediaTypes.video.playerSize[1]); - expect(data.source.ext.schain).to.deep.equal(videoBidRequests[0].schain); + expect(data.source.ext.schain).to.deep.equal(videoBidRequests[0].ortb2.source.ext.schain); }); describe('setting imp.floor using floorModule', function () { /* diff --git a/test/spec/modules/limelightDigitalBidAdapter_spec.js b/test/spec/modules/limelightDigitalBidAdapter_spec.js index c84586e9064..ef94070bb9b 100644 --- a/test/spec/modules/limelightDigitalBidAdapter_spec.js +++ b/test/spec/modules/limelightDigitalBidAdapter_spec.js @@ -43,16 +43,22 @@ describe('limelightDigitalAdapter', function () { ] } ], - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '1', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'example.com', + sid: '1', + hp: 1 + } + ] + } } - ] + } } } const bid2 = { @@ -91,21 +97,27 @@ describe('limelightDigitalAdapter', function () { ] } ], - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '1', - hp: 1 - }, - { - asi: 'example1.com', - sid: '2', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'example.com', + sid: '1', + hp: 1 + }, + { + asi: 'example1.com', + sid: '2', + hp: 1 + } + ] + } } - ] + } } } const bid3 = { @@ -148,16 +160,22 @@ describe('limelightDigitalAdapter', function () { ] } ], - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '1', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'example.com', + sid: '1', + hp: 1 + } + ] + } } - ] + } } } const bid4 = { @@ -198,16 +216,22 @@ describe('limelightDigitalAdapter', function () { ] } ], - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '1', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'example.com', + sid: '1', + hp: 1 + } + ] + } } - ] + } } } @@ -739,6 +763,6 @@ function validateAdUnit(adUnit, bid) { })); expect(adUnit.publisherId).to.equal(bid.params.publisherId); expect(adUnit.userIdAsEids).to.deep.equal(bid.userIdAsEids); - expect(adUnit.supplyChain).to.deep.equal(bid.schain); + expect(adUnit.supplyChain).to.deep.equal(bid.ortb2.source.ext.schain); expect(adUnit.ortb2Imp).to.deep.equal(bid.ortb2Imp); } diff --git a/test/spec/modules/livewrappedBidAdapter_spec.js b/test/spec/modules/livewrappedBidAdapter_spec.js index e6e23cfef35..3b4fddc7b9b 100644 --- a/test/spec/modules/livewrappedBidAdapter_spec.js +++ b/test/spec/modules/livewrappedBidAdapter_spec.js @@ -1315,7 +1315,10 @@ describe('Livewrapped adapter tests', function () { ] }; - testbidRequest.bids[0].schain = schain; + testbidRequest.bids[0].ortb2 = testbidRequest.bids[0].ortb2 || {}; + testbidRequest.bids[0].ortb2.source = testbidRequest.bids[0].ortb2.source || {}; + testbidRequest.bids[0].ortb2.source.ext = testbidRequest.bids[0].ortb2.source.ext || {}; + testbidRequest.bids[0].ortb2.source.ext.schain = schain; let result = spec.buildRequests(testbidRequest.bids, testbidRequest); let data = JSON.parse(result.data); diff --git a/test/spec/modules/lm_kiviadsBidAdapter_spec.js b/test/spec/modules/lm_kiviadsBidAdapter_spec.js index b6c4ae9bc4b..32b8d56309b 100644 --- a/test/spec/modules/lm_kiviadsBidAdapter_spec.js +++ b/test/spec/modules/lm_kiviadsBidAdapter_spec.js @@ -117,18 +117,20 @@ describe('lm_kiviadsBidAdapter', () => { it('should build request with schain', function () { const schainRequest = deepClone(defaultRequest); - schainRequest.schain = { - validation: 'strict', - config: { - ver: '1.0' + const bidderRequest = { + ortb2: { + source: { + ext: { + schain: { + ver: '1.0' + } + } + } } }; - const request = JSON.parse(spec.buildRequests([schainRequest], {}).data)[0]; + const request = JSON.parse(spec.buildRequests([schainRequest], bidderRequest).data)[0]; expect(request).to.have.property('schain').and.to.deep.equal({ - validation: 'strict', - config: { - ver: '1.0' - } + ver: '1.0' }); }); diff --git a/test/spec/modules/lockerdomeBidAdapter_spec.js b/test/spec/modules/lockerdomeBidAdapter_spec.js index d65837c39ab..ffbeb1c9340 100644 --- a/test/spec/modules/lockerdomeBidAdapter_spec.js +++ b/test/spec/modules/lockerdomeBidAdapter_spec.js @@ -18,16 +18,22 @@ describe('LockerDomeAdapter', function () { bidId: '2652ca954bce9', bidderRequestId: '14a54fade69854', auctionId: 'd4c83108-615d-4c2c-9384-dac9ffd4fd72', - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '00001', + hp: 1 + } + ] + } } - ] + } } }, { bidder: 'lockerdome', @@ -44,16 +50,22 @@ describe('LockerDomeAdapter', function () { bidId: '4510f2834773ce', bidderRequestId: '14a54fade69854', auctionId: 'd4c83108-615d-4c2c-9384-dac9ffd4fd72', - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '00001', + hp: 1 + } + ] + } } - ] + } } }]; diff --git a/test/spec/modules/logicadBidAdapter_spec.js b/test/spec/modules/logicadBidAdapter_spec.js index eb7800077b4..6aeb97af9e3 100644 --- a/test/spec/modules/logicadBidAdapter_spec.js +++ b/test/spec/modules/logicadBidAdapter_spec.js @@ -84,19 +84,23 @@ describe('LogicadAdapter', function () { name: 'cd.ladsp.com' } ] + }, + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'exchange1.com', + sid: '1234', + hp: 1 + } + ] + } + } } }, - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'exchange1.com', - sid: '1234', - hp: 1 - } - ] - } }]; const nativeBidRequests = [{ bidder: 'logicad', diff --git a/test/spec/modules/marsmediaBidAdapter_spec.js b/test/spec/modules/marsmediaBidAdapter_spec.js index ca3876703c8..ea0d0592f59 100644 --- a/test/spec/modules/marsmediaBidAdapter_spec.js +++ b/test/spec/modules/marsmediaBidAdapter_spec.js @@ -612,7 +612,13 @@ describe('marsmedia adapter tests', function () { 'auctionId': '18fd8b8b0bd757', 'bidRequestsCount': 1, 'bidId': '51ef8751f9aead', - 'schain': schain + 'ortb2': { + 'source': { + 'ext': { + 'schain': schain + } + } + } } ]; diff --git a/test/spec/modules/mediafuseBidAdapter_spec.js b/test/spec/modules/mediafuseBidAdapter_spec.js index bc943a9c129..4d627da216f 100644 --- a/test/spec/modules/mediafuseBidAdapter_spec.js +++ b/test/spec/modules/mediafuseBidAdapter_spec.js @@ -846,16 +846,22 @@ describe('MediaFuseAdapter', function () { it('should populate schain if available', function () { const bidRequest = Object.assign({}, bidRequests[0], { - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - 'asi': 'blob.com', - 'sid': '001', - 'hp': 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + 'asi': 'blob.com', + 'sid': '001', + 'hp': 1 + } + ] + } } - ] + } } }); diff --git a/test/spec/modules/mediakeysBidAdapter_spec.js b/test/spec/modules/mediakeysBidAdapter_spec.js index f6bd5c917ad..55fa9bfb858 100644 --- a/test/spec/modules/mediakeysBidAdapter_spec.js +++ b/test/spec/modules/mediakeysBidAdapter_spec.js @@ -451,7 +451,10 @@ describe('mediakeysBidAdapter', function () { ], }; const bidRequests = [utils.deepClone(bid)]; - bidRequests[0].schain = schain; + bidRequests[0].ortb2 = bidRequests[0].ortb2 || {}; + bidRequests[0].ortb2.source = bidRequests[0].ortb2.source || {}; + bidRequests[0].ortb2.source.ext = bidRequests[0].ortb2.source.ext || {}; + bidRequests[0].ortb2.source.ext.schain = schain; const request = spec.buildRequests(bidRequests, bidderRequest); const data = request.data; expect(data.source.ext.schain).to.equal(schain); diff --git a/test/spec/modules/mgidBidAdapter_spec.js b/test/spec/modules/mgidBidAdapter_spec.js index 180b0dc723e..38d2fd135bb 100644 --- a/test/spec/modules/mgidBidAdapter_spec.js +++ b/test/spec/modules/mgidBidAdapter_spec.js @@ -398,11 +398,14 @@ describe('Mgid bid adapter', function () { sizes: [[300, 250]] } }; - bid.schain = ['schain1', 'schain2']; + bid.ortb2 = bid.ortb2 || {}; + bid.ortb2.source = bid.ortb2.source || {}; + bid.ortb2.source.ext = bid.ortb2.source.ext || {}; + bid.ortb2.source.ext.schain = ['schain1', 'schain2']; let bidRequests = [bid]; const request = spec.buildRequests(bidRequests); const data = JSON.parse(request.data); - expect(data.source).to.deep.equal({ext: {schain: bid.schain}}); + expect(data.source).to.deep.equal({ext: {schain: bid.ortb2.source.ext.schain}}); }); it('should handle userId', function () { let bid = Object.assign({}, abid); diff --git a/test/spec/modules/minutemediaBidAdapter_spec.js b/test/spec/modules/minutemediaBidAdapter_spec.js index 4e5cd4883d3..ce3ab6dd9d7 100644 --- a/test/spec/modules/minutemediaBidAdapter_spec.js +++ b/test/spec/modules/minutemediaBidAdapter_spec.js @@ -369,12 +369,17 @@ describe('minutemediaAdapter', function () { }); it('should have schain param if it is available in the bidRequest', () => { - const schain = { - ver: '1.0', - complete: 1, - nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], + bidderRequest.ortb2 = { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], + } + } + } }; - bidRequests[0].schain = schain; const request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('schain', '1.0,1!indirectseller.com,00001,1,,,'); diff --git a/test/spec/modules/missenaBidAdapter_spec.js b/test/spec/modules/missenaBidAdapter_spec.js index e95903d4791..c29711b4302 100644 --- a/test/spec/modules/missenaBidAdapter_spec.js +++ b/test/spec/modules/missenaBidAdapter_spec.js @@ -31,18 +31,22 @@ describe('Missena Adapter', function () { device: { ext: { cdep: COOKIE_DEPRECATION_LABEL }, }, + source: { + ext: { + schain: { + validation: 'strict', + config: { + ver: '1.0', + }, + }, + }, + }, }, params: { apiKey: API_KEY, placement: 'sticky', formats: ['sticky-banner'], }, - schain: { - validation: 'strict', - config: { - ver: '1.0', - }, - }, getFloor: (inputParams) => { if (inputParams.mediaType === BANNER) { return { diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js index 85143f45df8..53e541efded 100644 --- a/test/spec/modules/nextMillenniumBidAdapter_spec.js +++ b/test/spec/modules/nextMillenniumBidAdapter_spec.js @@ -225,12 +225,18 @@ describe('nextMillenniumBidAdapterTests', () => { title: 'schain is validBidReequest', bidderRequest: {}, validBidRequests: [{ - schain: { - validation: 'strict', - config: { - ver: '1.0', - complete: 1, - nodes: [{asi: 'test.test', sid: '00001', hp: 1}], + ortb2: { + source: { + ext: { + schain: { + validation: 'strict', + config: { + ver: '1.0', + complete: 1, + nodes: [{asi: 'test.test', sid: '00001', hp: 1}], + }, + }, + }, }, }, }], diff --git a/test/spec/modules/nobidBidAdapter_spec.js b/test/spec/modules/nobidBidAdapter_spec.js index 2f2c97eae51..6fe29fa3c3b 100644 --- a/test/spec/modules/nobidBidAdapter_spec.js +++ b/test/spec/modules/nobidBidAdapter_spec.js @@ -937,20 +937,26 @@ describe('Nobid Adapter', function () { bidderRequestId: '22edbae2733bf6', auctionId: '1d1a030790a475', coppa: true, - schain: { - validation: 'strict', - config: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - name: 'name.com', - hp: 1 - } - ] - } + ortb2: { + source: { + ext: { + schain: { + validation: 'strict', + config: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '00001', + name: 'name.com', + hp: 1 + } + ] + } + } + } + } } } ]; diff --git a/test/spec/modules/omsBidAdapter_spec.js b/test/spec/modules/omsBidAdapter_spec.js index e8426930257..a324fa05576 100644 --- a/test/spec/modules/omsBidAdapter_spec.js +++ b/test/spec/modules/omsBidAdapter_spec.js @@ -57,19 +57,25 @@ describe('omsBidAdapter', function () { 'bidId': '5fb26ac22bde4', 'bidderRequestId': '4bf93aeb730cb9', 'auctionId': 'ffe9a1f7-7b67-4bda-a8e0-9ee5dc9f442e', - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'exchange1.com', - 'sid': '1234', - 'hp': 1, - 'rid': 'bid-request-1', - 'name': 'publisher', - 'domain': 'publisher.com' + 'ortb2': { + 'source': { + 'ext': { + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'exchange1.com', + 'sid': '1234', + 'hp': 1, + 'rid': 'bid-request-1', + 'name': 'publisher', + 'domain': 'publisher.com' + } + ] + } } - ] + } }, }]; @@ -150,19 +156,25 @@ describe('omsBidAdapter', function () { 'bidId': '5fb26ac22bde4', 'bidderRequestId': '4bf93aeb730cb9', 'auctionId': 'ffe9a1f7-7b67-4bda-a8e0-9ee5dc9f442e', - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'exchange1.com', - 'sid': '1234', - 'hp': 1, - 'rid': 'bid-request-1', - 'name': 'publisher', - 'domain': 'publisher.com' + 'ortb2': { + 'source': { + 'ext': { + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'exchange1.com', + 'sid': '1234', + 'hp': 1, + 'rid': 'bid-request-1', + 'name': 'publisher', + 'domain': 'publisher.com' + } + ] + } } - ] + } }, } ] diff --git a/test/spec/modules/openwebBidAdapter_spec.js b/test/spec/modules/openwebBidAdapter_spec.js index 9ab8f608598..02945125ca2 100644 --- a/test/spec/modules/openwebBidAdapter_spec.js +++ b/test/spec/modules/openwebBidAdapter_spec.js @@ -378,12 +378,17 @@ describe('openwebAdapter', function () { }); it('should have schain param if it is available in the bidRequest', () => { - const schain = { - ver: '1.0', - complete: 1, - nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], + bidderRequest.ortb2 = { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], + } + } + } }; - bidRequests[0].schain = schain; const request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('schain', '1.0,1!indirectseller.com,00001,1,,,'); diff --git a/test/spec/modules/openxBidAdapter_spec.js b/test/spec/modules/openxBidAdapter_spec.js index 18e26b7612e..ead908b531b 100644 --- a/test/spec/modules/openxBidAdapter_spec.js +++ b/test/spec/modules/openxBidAdapter_spec.js @@ -12,7 +12,6 @@ import 'modules/multibid/index.js'; import 'modules/priceFloors.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; -import 'modules/schain.js'; import 'modules/paapi.js'; import {deepClone} from 'src/utils.js'; @@ -1106,13 +1105,24 @@ describe('OpenxRtbAdapter', function () { bidId: 'test-bid-id-1', bidderRequestId: 'test-bid-request-1', auctionId: 'test-auction-1', - schain: schainConfig + ortb2: {source: { + schain: schainConfig, + ext: {schain: schainConfig} + }} }]; + + // Add schain to mockBidderRequest as well + mockBidderRequest.ortb2 = { + source: { + schain: schainConfig, + ext: {schain: schainConfig} + } + }; }); it('should send a supply chain object', function () { const request = spec.buildRequests(bidRequests, mockBidderRequest); - expect(request[0].data.source.ext.schain).to.equal(schainConfig); + expect(request[0].data.source.ext.schain).to.deep.equal(schainConfig); }); it('should send the supply chain object with the right version', function () { diff --git a/test/spec/modules/opscoBidAdapter_spec.js b/test/spec/modules/opscoBidAdapter_spec.js index 38cacff8f82..77051f56de1 100644 --- a/test/spec/modules/opscoBidAdapter_spec.js +++ b/test/spec/modules/opscoBidAdapter_spec.js @@ -134,7 +134,10 @@ describe('opscoBidAdapter', function () { it('should send schain in the payload if present', function () { const schain = {'ver': '1.0', 'complete': 1, 'nodes': [{'asi': 'exchange1.com', 'sid': '1234', 'hp': 1}]}; - validBid.schain = schain; + validBid.ortb2 = validBid.ortb2 || {}; + validBid.ortb2.source = validBid.ortb2.source || {}; + validBid.ortb2.source.ext = validBid.ortb2.source.ext || {}; + validBid.ortb2.source.ext.schain = schain; const request = spec.buildRequests([validBid], bidderRequest); expect(JSON.parse(request.data).source.ext.schain).to.deep.equal(schain); }); diff --git a/test/spec/modules/optidigitalBidAdapter_spec.js b/test/spec/modules/optidigitalBidAdapter_spec.js index 273b29001d1..dfaab4d5372 100755 --- a/test/spec/modules/optidigitalBidAdapter_spec.js +++ b/test/spec/modules/optidigitalBidAdapter_spec.js @@ -222,14 +222,20 @@ describe('optidigitalAdapterTests', function () { it('should add schain object to payload if exists', function () { const bidRequest = Object.assign({}, validBidRequests[0], { - schain: { - ver: '1.0', - complete: 1, - nodes: [{ - asi: 'examplewebsite.com', - sid: '00001', - hp: 1 - }] + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [{ + asi: 'examplewebsite.com', + sid: '00001', + hp: 1 + }] + } + } + } } }); const request = spec.buildRequests([bidRequest], bidderRequest); diff --git a/test/spec/modules/ozoneBidAdapter_spec.js b/test/spec/modules/ozoneBidAdapter_spec.js index b2b494b04c6..d23cb39c5cb 100644 --- a/test/spec/modules/ozoneBidAdapter_spec.js +++ b/test/spec/modules/ozoneBidAdapter_spec.js @@ -3151,7 +3151,10 @@ describe('ozone Adapter', function () { } ] }; - br[0]['schain'] = schainConfigObject; + br[0].ortb2 = br[0].ortb2 || {}; + br[0].ortb2.source = br[0].ortb2.source || {}; + br[0].ortb2.source.ext = br[0].ortb2.source.ext || {}; + br[0].ortb2.source.ext.schain = schainConfigObject; const request = spec.buildRequests(br, validBidderRequest); const data = JSON.parse(request.data); expect(data.source.ext).to.haveOwnProperty('schain'); diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js index e27e4635d47..253727cf174 100644 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -24,7 +24,6 @@ import 'modules/priceFloors.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; import 'modules/consentManagementGpp.js'; -import 'modules/schain.js'; import 'modules/paapi.js'; import * as redactor from 'src/activities/redactor.js'; import * as activityRules from 'src/activities/rules.js'; @@ -2421,14 +2420,18 @@ describe('S2S Adapter', function () { it('should have extPrebid.schains present on req object if bidder specific schains were configured with pbjs', function () { let bidRequest = utils.deepClone(BID_REQUESTS); - bidRequest[0].bids[0].schain = { - complete: 1, - nodes: [{ - asi: 'test.com', - hp: 1, - sid: '11111' - }], - ver: '1.0' + bidRequest[0].bids[0].ortb2 = { + source: { + schain: { + complete: 1, + nodes: [{ + asi: 'test.com', + hp: 1, + sid: '11111' + }], + ver: '1.0' + } + } }; adapter.callBids(REQUEST, bidRequest, addBidResponse, done, ajax); @@ -2511,14 +2514,18 @@ describe('S2S Adapter', function () { it('should add a bidder name to pbs schain if the schain is equal to a pbjs one but the pbjs bidder name is not in the bidder array on the pbs side', function () { let bidRequest = utils.deepClone(BID_REQUESTS); - bidRequest[0].bids[0].schain = { - complete: 1, - nodes: [{ - asi: 'test.com', - hp: 1, - sid: '11111' - }], - ver: '1.0' + bidRequest[0].bids[0].ortb2 = { + source: { + schain: { + complete: 1, + nodes: [{ + asi: 'test.com', + hp: 1, + sid: '11111' + }], + ver: '1.0' + } + } }; bidRequest[0].bids[1] = { diff --git a/test/spec/modules/pubgeniusBidAdapter_spec.js b/test/spec/modules/pubgeniusBidAdapter_spec.js index e1d579aaa4a..5475a58d317 100644 --- a/test/spec/modules/pubgeniusBidAdapter_spec.js +++ b/test/spec/modules/pubgeniusBidAdapter_spec.js @@ -295,7 +295,10 @@ describe('pubGENIUS adapter', () => { } ] }; - bidRequest.schain = deepClone(schain); + bidRequest.ortb2 = bidRequest.ortb2 || {}; + bidRequest.ortb2.source = bidRequest.ortb2.source || {}; + bidRequest.ortb2.source.ext = bidRequest.ortb2.source.ext || {}; + bidRequest.ortb2.source.ext.schain = deepClone(schain); expectedRequest.data.source = { ext: { schain: deepClone(schain) }, }; diff --git a/test/spec/modules/publirBidAdapter_spec.js b/test/spec/modules/publirBidAdapter_spec.js index 60840b82efb..0265fbb4020 100644 --- a/test/spec/modules/publirBidAdapter_spec.js +++ b/test/spec/modules/publirBidAdapter_spec.js @@ -215,12 +215,17 @@ describe('publirAdapter', function () { }); it('should have schain param if it is available in the bidRequest', () => { - const schain = { - ver: '1.0', - complete: 1, - nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], + bidderRequest.ortb2 = { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], + } + } + } }; - bidRequests[0].schain = schain; const request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('schain', '1.0,1!indirectseller.com,00001,1,,,'); diff --git a/test/spec/modules/pulsepointBidAdapter_spec.js b/test/spec/modules/pulsepointBidAdapter_spec.js index 263bf08851f..818acea7791 100644 --- a/test/spec/modules/pulsepointBidAdapter_spec.js +++ b/test/spec/modules/pulsepointBidAdapter_spec.js @@ -6,7 +6,6 @@ import {deepClone} from '../../../src/utils'; import 'modules/consentManagementTcf'; import 'modules/consentManagementUsp'; import 'modules/userId/index'; -import 'modules/schain'; describe('PulsePoint Adapter Tests', function () { const slotConfigs = [{ @@ -135,7 +134,7 @@ describe('PulsePoint Adapter Tests', function () { bidfloor: 1.5, badv: ['cocacola.com', 'lays.com'] }, - schain: { + ortb2: {source: {ext: {schain: { 'ver': '1.0', 'complete': 1, 'nodes': [ @@ -148,7 +147,7 @@ describe('PulsePoint Adapter Tests', function () { 'domain': 'publisher.com' } ] - }, + }}}} }]; const bidderRequest = { @@ -466,8 +465,31 @@ describe('PulsePoint Adapter Tests', function () { expect(ortbRequest.imp[0].ext).to.be.undefined; }); - it('Verify schain parameters', async function () { - const request = spec.buildRequests(schainParamsSlotConfig, await addFPDToBidderRequest(bidderRequest)); + it('Verify schain parameters', function () { + const modifiedBidderRequest = { + ...bidderRequest, + ortb2: { + source: { + ext: { + schain: { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'exchange1.com', + 'sid': '1234', + 'hp': 1, + 'rid': 'bid-request-1', + 'name': 'publisher', + 'domain': 'publisher.com' + } + ] + } + } + } + } + }; + const request = spec.buildRequests(schainParamsSlotConfig, modifiedBidderRequest); const ortbRequest = request.data; expect(ortbRequest).to.not.equal(null); expect(ortbRequest.source).to.not.equal(null); diff --git a/test/spec/modules/qwarryBidAdapter_spec.js b/test/spec/modules/qwarryBidAdapter_spec.js index 5d48d92066a..fef013f8ce6 100644 --- a/test/spec/modules/qwarryBidAdapter_spec.js +++ b/test/spec/modules/qwarryBidAdapter_spec.js @@ -10,14 +10,20 @@ const REQUEST = { zoneToken: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7 }, - 'schain': { - ver: '1.0', - complete: 1, - nodes: [{ - asi: 'qwarry.com', - sid: '00001', - hp: 1 - }] + 'ortb2': { + 'source': { + 'ext': { + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [{ + 'asi': 'qwarry.com', + 'sid': '00001', + 'hp': 1 + }] + } + } + } } } diff --git a/test/spec/modules/r2b2BidAdapter_spec.js b/test/spec/modules/r2b2BidAdapter_spec.js index 63850b78c40..f9040798abc 100644 --- a/test/spec/modules/r2b2BidAdapter_spec.js +++ b/test/spec/modules/r2b2BidAdapter_spec.js @@ -1,7 +1,6 @@ import {expect} from 'chai'; import {spec, internal as r2b2, internal} from 'modules/r2b2BidAdapter.js'; import * as utils from '../../../src/utils'; -import 'modules/schain.js'; import 'modules/userId/index.js'; function encodePlacementIds (ids) { @@ -91,9 +90,9 @@ describe('R2B2 adapter', function () { } }, site: {}, - device: {} + device: {}, + source: {ext: {schain: schain}} }, - schain }, { bidder: 'r2b2', params: { @@ -128,9 +127,9 @@ describe('R2B2 adapter', function () { } }, site: {}, - device: {} + device: {}, + source: {ext: {schain: schain}} }, - schain }]; bidderRequest = { bidderCode: 'r2b2', @@ -150,7 +149,8 @@ describe('R2B2 adapter', function () { } }, site: {}, - device: {} + device: {}, + source: {ext: {schain: schain}} }, gdprConsent: { consentString: 'consent-string', diff --git a/test/spec/modules/rhythmoneBidAdapter_spec.js b/test/spec/modules/rhythmoneBidAdapter_spec.js index 359b02db37e..77ae6266eda 100644 --- a/test/spec/modules/rhythmoneBidAdapter_spec.js +++ b/test/spec/modules/rhythmoneBidAdapter_spec.js @@ -704,7 +704,13 @@ describe('rhythmone adapter tests', function () { 'auctionId': '18fd8b8b0bd757', 'bidRequestsCount': 1, 'bidId': '51ef8751f9aead', - 'schain': schain + 'ortb2': { + 'source': { + 'ext': { + 'schain': schain + } + } + } } ]; diff --git a/test/spec/modules/richaudienceBidAdapter_spec.js b/test/spec/modules/richaudienceBidAdapter_spec.js index e4fd11d8604..b5209266762 100644 --- a/test/spec/modules/richaudienceBidAdapter_spec.js +++ b/test/spec/modules/richaudienceBidAdapter_spec.js @@ -817,18 +817,24 @@ describe('Richaudience adapter tests', function () { }] } - DEFAULT_PARAMS_NEW_SIZES[0].schain = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [{ - 'asi': 'richaudience.com', - 'sid': '00001', - 'hp': 1 - }, { - 'asi': 'richaudience-2.com', - 'sid': '00002', - 'hp': 1 - }] + DEFAULT_PARAMS_NEW_SIZES[0].ortb2 = { + source: { + ext: { + schain: { + 'ver': '1.0', + 'complete': 1, + 'nodes': [{ + 'asi': 'richaudience.com', + 'sid': '00001', + 'hp': 1 + }, { + 'asi': 'richaudience-2.com', + 'sid': '00002', + 'hp': 1 + }] + } + } + } } const request = spec.buildRequests(DEFAULT_PARAMS_NEW_SIZES, { diff --git a/test/spec/modules/riseBidAdapter_spec.js b/test/spec/modules/riseBidAdapter_spec.js index a3fef50f825..bb7e07bd69e 100644 --- a/test/spec/modules/riseBidAdapter_spec.js +++ b/test/spec/modules/riseBidAdapter_spec.js @@ -395,12 +395,17 @@ describe('riseAdapter', function () { }); it('should have schain param if it is available in the bidRequest', () => { - const schain = { - ver: '1.0', - complete: 1, - nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], + bidderRequest.ortb2 = { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], + } + } + } }; - bidRequests[0].schain = schain; const request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('schain', '1.0,1!indirectseller.com,00001,1,,,'); diff --git a/test/spec/modules/rtbhouseBidAdapter_spec.js b/test/spec/modules/rtbhouseBidAdapter_spec.js index dded1fe15a0..e88545b5ba4 100644 --- a/test/spec/modules/rtbhouseBidAdapter_spec.js +++ b/test/spec/modules/rtbhouseBidAdapter_spec.js @@ -91,17 +91,23 @@ describe('RTBHouseAdapter', () => { 'tid': 'ortb2Imp-transaction-id-1' } }, - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'directseller.com', - 'sid': '00001', - 'rid': 'BidRequest1', - 'hp': 1 + 'ortb2': { + 'source': { + 'ext': { + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'directseller.com', + 'sid': '00001', + 'rid': 'BidRequest1', + 'hp': 1 + } + ] + } } - ] + } } } ]; @@ -274,7 +280,10 @@ describe('RTBHouseAdapter', () => { it('should not include invalid schain', () => { const bidRequest = Object.assign([], bidRequests); - bidRequest[0].schain = { + bidRequest[0].ortb2 = bidRequest[0].ortb2 || {}; + bidRequest[0].ortb2.source = bidRequest[0].ortb2.source || {}; + bidRequest[0].ortb2.source.ext = bidRequest[0].ortb2.source.ext || {}; + bidRequest[0].ortb2.source.ext.schain = { 'nodes': [{ 'unknown_key': 1 }] diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js index 391f046d43a..6aa45b1af73 100644 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -11,7 +11,6 @@ import { } from 'modules/rubiconBidAdapter.js'; import {config} from 'src/config.js'; import * as utils from 'src/utils.js'; -import 'modules/schain.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; import 'modules/userId/index.js'; @@ -130,6 +129,9 @@ describe('the rubicon adapter', function () { tid: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b', } }, + ortb2: { + source: {} + } } ], start: 1472239426002, @@ -4655,7 +4657,8 @@ describe('the rubicon adapter', function () { beforeEach(() => { bidRequests = getBidderRequest(); schainConfig = getSupplyChainConfig(); - bidRequests.bids[0].schain = schainConfig; + bidRequests.bids[0].ortb2.source.ext = bidRequests.bids[0].ortb2.source.ext || {}; + bidRequests.bids[0].ortb2.source.ext.schain = schainConfig; }); it('should properly serialize schain object with correct delimiters', () => { @@ -4674,14 +4677,14 @@ describe('the rubicon adapter', function () { const results = spec.buildRequests(bidRequests.bids, bidRequests); const schain = new URLSearchParams(results[0].data).get('rp_schain').split('!'); const version = schain.shift().split(',')[0]; - expect(version).to.equal(bidRequests.bids[0].schain.ver); + expect(version).to.equal(bidRequests.bids[0].ortb2.source.ext.schain.ver); }); it('should send the correct value for complete in schain', () => { const results = spec.buildRequests(bidRequests.bids, bidRequests); const schain = new URLSearchParams(results[0].data).get('rp_schain').split('!'); const complete = schain.shift().split(',')[1]; - expect(complete).to.equal(String(bidRequests.bids[0].schain.complete)); + expect(complete).to.equal(String(bidRequests.bids[0].ortb2.source.ext.schain.complete)); }); it('should send available params in the right order', () => { @@ -4702,7 +4705,7 @@ describe('the rubicon adapter', function () { it('should copy the schain JSON to to bid.source.ext.schain', () => { const bidderRequest = createVideoBidderRequest(); const schain = getSupplyChainConfig(); - bidderRequest.bids[0].schain = schain; + bidderRequest.bids[0].ortb2.source.ext = { schain: schain }; const request = spec.buildRequests(bidderRequest.bids, bidderRequest); expect(request[0].data.source.ext.schain).to.deep.equal(schain); }); diff --git a/test/spec/modules/schain_spec.js b/test/spec/modules/schain_spec.js deleted file mode 100644 index eb8e35749db..00000000000 --- a/test/spec/modules/schain_spec.js +++ /dev/null @@ -1,496 +0,0 @@ -import { isValidSchainConfig, isSchainObjectValid, makeBidRequestsHook } from '../../../modules/schain.js'; -import { deepClone } from '../../../src/utils.js'; -import {config} from '../../../src/config.js'; -import { expect } from 'chai'; - -describe('#isValidSchainConfig: module config validation', function() { - it('if config is undefined or not an objct then return false', function() { - expect(isValidSchainConfig()).to.false; - expect(isValidSchainConfig('')).to.false; - expect(isValidSchainConfig([])).to.false; - expect(isValidSchainConfig(12)).to.false; - expect(isValidSchainConfig(3.14)).to.false; - }) - - it('if config is an object then return true', function() { - expect(isValidSchainConfig({})).to.true; - }) -}); - -describe('#isSchainObjectValid: schain object validation', function() { - let schainConfig; - - beforeEach(function() { - schainConfig = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, - - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 2 - } - ] - }; - }); - - it('Return true for correct config', function() { - expect(isSchainObjectValid(schainConfig, true)).to.true; - }); - - it('Return false for string config', function() { - schainConfig = JSON.stringify(schainConfig); - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if complete param is not an Integer', function() { - schainConfig.complete = 1; // integer - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.complete = '1'; // string - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.complete = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.complete = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.complete; // undefined - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.complete = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.complete = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if version param is not a String', function() { - schainConfig.ver = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.ver = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.ver = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.ver; // undefined - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.ver = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.ver = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if ext param is not an Object', function() { - schainConfig.ext = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.ext = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.ext = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.true; - delete schainConfig.ext; // undefined // param is optional thus this will result true - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.ext = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.ext = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes param is not an Array', function() { - // by default schainConfig.nodes is array - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.nodes; // undefined - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes[].asi is not a String', function() { - schainConfig.nodes[0].asi = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].asi = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].asi = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.nodes[0].asi; // undefined - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].asi = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].asi = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes[].sid is not a String', function() { - schainConfig.nodes[1].sid = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].sid = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].sid = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.nodes[0].sid; // undefined - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].sid = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].sid = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes[].hp is not an Integer', function() { - schainConfig.nodes[0].hp = '1'; // string - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].hp = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].hp = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.nodes[0].hp; // undefined - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].hp = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].hp = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes[].rid is not a String', function() { - schainConfig.nodes[1].rid = 'rid value'; // string - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes[1].rid = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].rid = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].rid = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.nodes[1].rid; // undefined // param is optional thus this will result true - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes[1].rid = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].rid = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes[].name is not a String', function() { - schainConfig.nodes[0].name = 'name value'; // string - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes[0].name = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].name = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].name = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.nodes[0].name; // undefined // param is optional thus this will result true - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes[0].name = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].name = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes[].domain is not a String', function() { - schainConfig.nodes[1].domain = 'domain value'; // string - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes[1].domain = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].domain = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].domain = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.nodes[1].domain; // undefined // param is optional thus this will result true - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes[1].domain = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].domain = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes[].ext param is not an Object', function() { - schainConfig.nodes[0].ext = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].ext = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].ext = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.true; - delete schainConfig.nodes[0].ext; // undefined // param is optional thus this will result true - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes[0].ext = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].ext = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Relaxed mode: Returns true even for invalid config if second argument is set to false', function() { - schainConfig = { - 'ver': 1.0, // invalid - 'complete': '1', // invalid - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': 1, // invalid - 'hp': '1' // invalid - }, - - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 2 - } - ] - }; - expect(isSchainObjectValid(schainConfig, false)).to.true; - - schainConfig = {}; - expect(isSchainObjectValid(schainConfig, false)).to.true; - }) -}); - -describe('#makeBidRequestsHook', function() { - const bidderRequests = [ - { - 'bidderCode': 'rubicon', - 'bids': [ - { - 'bidder': 'rubicon', - 'params': { - 'accountId': 14062, - 'siteId': 70608, - 'zoneId': 498816 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '2e6d166eb869c3' - - } - ], - }, - { - 'bidderCode': 'districtm', - 'bids': [ - { - 'bidder': 'districtm', - 'params': { - 'placementId': 13144370 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '41cdeddf7b6905' - } - ], - }, - { - 'bidderCode': 'appnexus', - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '626cc7f1c4ccfc' - } - ], - - } - ]; - - const globalSchainConfig = { - 'schain': { - 'validation': 'off', - 'config': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, - - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 1 - } - ] - } - } - }; - - const goodStrictBidderConfig = { - bidders: ['appnexus'], - config: { - 'schain': { - 'validation': 'strict', - 'config': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'myoverride1.com', - 'sid': '00001', - 'hp': 1, - 'name': 'node1' - }, - { - 'asi': 'myoverride2.com', - 'sid': '00001', - 'hp': 1, - 'name': 'node2' - } - ] - } - } - } - } - - const badStrictBidderConfig = { - bidders: ['appnexus'], - config: { - 'schain': { - 'validation': 'strict', - 'config': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'myoverride1.com', - 'sid': 1, - 'hp': 1, - 'name': 342 - }, - { - 'asi': 'myoverride2.com', - 'sid': 2, - 'hp': 1, - 'name': '342' - } - ] - } - } - } - }; - - const goodRelaxedBidderConfig = { - bidders: ['districtm'], - config: { - 'schain': { - 'validation': 'relaxed', - 'config': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'myoverride.com', - 'sid': '00001', - 'hp': 1, - 'name': 'goodConfig' - } - ] - } - } - } - }; - - const badRelaxedBidderConfig = { - bidders: ['districtm'], - config: { - 'schain': { - 'validation': 'relaxed', - 'config': { - 'ver': 1, - 'complete': 1, - 'nodes': [ - { - 'asi': 'myoverride.com', - 'sid': 1, - 'hp': 1 - } - ] - } - } - } - }; - - beforeEach(function () { - config.setConfig(globalSchainConfig); - }); - - afterEach(function () { - config.resetConfig(); - - config.setBidderConfig({ - bidders: ['districtm'], - config: { - schain: null - } - }); - - config.setBidderConfig({ - bidders: ['appnexus'], - config: { - schain: null - } - }); - }); - - it('should properly read from bidder schain + global schain configs', function() { - function testCallback(bidderRequests) { - expect(bidderRequests[0].bids[0].schain).to.exist; - expect(bidderRequests[0].bids[0].schain).to.deep.equal(globalSchainConfig.schain.config); - expect(bidderRequests[1].bids[0].schain).to.exist; - expect(bidderRequests[1].bids[0].schain).to.deep.equal(goodRelaxedBidderConfig.config.schain.config); - expect(bidderRequests[2].bids[0].schain).to.exist; - expect(bidderRequests[2].bids[0].schain).to.deep.equal(goodStrictBidderConfig.config.schain.config); - } - - const testBidderRequests = deepClone(bidderRequests); - config.setBidderConfig(goodStrictBidderConfig); - config.setBidderConfig(goodRelaxedBidderConfig); - - makeBidRequestsHook(testCallback, testBidderRequests); - }); - - it('should not share the same schain object between different bid requests', (done) => { - config.setBidderConfig(goodStrictBidderConfig); - makeBidRequestsHook((requests) => { - requests[0].bids[0].schain.field = 'value'; - expect(requests[1].bids[0].schain.field).to.not.exist; - done(); - }, deepClone(bidderRequests)) - }); - - it('should reject bad strict config but allow a bad relaxed config for bidders trying to override it', function () { - function testCallback(bidderRequests) { - expect(bidderRequests[0].bids[0].schain).to.exist; - expect(bidderRequests[0].bids[0].schain).to.deep.equal(globalSchainConfig.schain.config); - expect(bidderRequests[1].bids[0].schain).to.exist; - expect(bidderRequests[1].bids[0].schain).to.deep.equal(badRelaxedBidderConfig.config.schain.config); - expect(bidderRequests[2].bids[0].schain).to.be.undefined; - } - - const testBidderRequests = deepClone(bidderRequests); - config.setBidderConfig(badStrictBidderConfig); - config.setBidderConfig(badRelaxedBidderConfig); - - makeBidRequestsHook(testCallback, testBidderRequests); - }); -}); diff --git a/test/spec/modules/seedtagBidAdapter_spec.js b/test/spec/modules/seedtagBidAdapter_spec.js index b64c8675647..96491b3a8ee 100644 --- a/test/spec/modules/seedtagBidAdapter_spec.js +++ b/test/spec/modules/seedtagBidAdapter_spec.js @@ -448,7 +448,10 @@ describe('Seedtag Adapter', function () { // duplicate const bidRequests = JSON.parse(JSON.stringify(validBidRequests)); - bidRequests[0].schain = schain; + bidRequests[0].ortb2 = bidRequests[0].ortb2 || {}; + bidRequests[0].ortb2.source = bidRequests[0].ortb2.source || {}; + bidRequests[0].ortb2.source.ext = bidRequests[0].ortb2.source.ext || {}; + bidRequests[0].ortb2.source.ext.schain = schain; const request = spec.buildRequests(bidRequests, bidderRequest); diff --git a/test/spec/modules/sharethroughBidAdapter_spec.js b/test/spec/modules/sharethroughBidAdapter_spec.js index 2c05799f602..a54fe3f710c 100644 --- a/test/spec/modules/sharethroughBidAdapter_spec.js +++ b/test/spec/modules/sharethroughBidAdapter_spec.js @@ -191,17 +191,23 @@ describe('sharethrough adapter spec', function () { crumbs: { pubcid: 'fake-pubcid-in-crumbs-obj', }, - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'directseller.com', - sid: '00001', - rid: 'BidRequest1', - hp: 1, - }, - ], + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'directseller.com', + sid: '00001', + rid: 'BidRequest1', + hp: 1, + }, + ], + } + } + } }, getFloor: () => ({ currency: 'USD', floor: 42 }), }, @@ -321,7 +327,7 @@ describe('sharethrough adapter spec', function () { expect(openRtbReq.source.tid).to.equal(bidderRequest.ortb2.source.tid); expect(openRtbReq.source.ext.version).not.to.be.undefined; expect(openRtbReq.source.ext.str).not.to.be.undefined; - expect(openRtbReq.source.ext.schain).to.deep.equal(bidRequests[0].schain); + expect(openRtbReq.source.ext.schain).to.deep.equal(bidRequests[0].ortb2.source.ext.schain); expect(openRtbReq.bcat).to.deep.equal(bidRequests[0].params.bcat); expect(openRtbReq.badv).to.deep.equal(bidRequests[0].params.badv); diff --git a/test/spec/modules/shinezBidAdapter_spec.js b/test/spec/modules/shinezBidAdapter_spec.js index d4ad99359bb..1927ebe8597 100644 --- a/test/spec/modules/shinezBidAdapter_spec.js +++ b/test/spec/modules/shinezBidAdapter_spec.js @@ -313,12 +313,17 @@ describe('shinezAdapter', function () { }); it('should have schain param if it is available in the bidRequest', () => { - const schain = { - ver: '1.0', - complete: 1, - nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], + bidderRequest.ortb2 = { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], + } + } + } }; - bidRequests[0].schain = schain; const request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('schain', '1.0,1!indirectseller.com,00001,1,,,'); diff --git a/test/spec/modules/showheroes-bsBidAdapter_spec.js b/test/spec/modules/showheroes-bsBidAdapter_spec.js index 07211ca37cc..0a1462d9b66 100644 --- a/test/spec/modules/showheroes-bsBidAdapter_spec.js +++ b/test/spec/modules/showheroes-bsBidAdapter_spec.js @@ -4,7 +4,6 @@ import { addFPDToBidderRequest } from '../../helpers/fpd.js'; import 'modules/priceFloors.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; -import 'modules/schain.js'; import { VIDEO } from 'src/mediaTypes.js' const bidderRequest = { @@ -99,10 +98,18 @@ describe('shBidAdapter', () => { bids: [bidRequestVideoV2], ...bidderRequest, ...gdpr, - ...schain, ...{uspConsent: uspConsent}, + ortb2: { + source: { + ext: {schain: schain.schain.config} + } + } + }; + bidRequest.ortb2 = { + source: { + ext: {schain: schain.schain.config} + } }; - bidRequest.schain = schain.schain.config; const getFloorResponse = {currency: 'EUR', floor: 3}; bidRequest.getFloor = () => getFloorResponse; const request = spec.buildRequests([bidRequest], await addFPDToBidderRequest(fullRequest)); @@ -110,7 +117,7 @@ describe('shBidAdapter', () => { expect(payload.regs.ext.gdpr).to.eql(Number(gdpr.gdprConsent.gdprApplies)); expect(payload.regs.ext.us_privacy).to.eql(uspConsent); expect(payload.user.ext.consent).to.eql(gdpr.gdprConsent.consentString); - expect(payload.source.ext.schain).to.eql(bidRequest.schain); + expect(payload.source.ext.schain).to.deep.equal(bidRequest.ortb2.source.ext.schain); expect(payload.test).to.eql(0); expect(payload.imp[0].bidfloor).eql(3); expect(payload.imp[0].bidfloorcur).eql('EUR'); diff --git a/test/spec/modules/silvermobBidAdapter_spec.js b/test/spec/modules/silvermobBidAdapter_spec.js index b9bf32462d8..b967efdd9b5 100644 --- a/test/spec/modules/silvermobBidAdapter_spec.js +++ b/test/spec/modules/silvermobBidAdapter_spec.js @@ -13,7 +13,6 @@ import 'modules/multibid/index.js'; import 'modules/priceFloors.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; -import 'modules/schain.js'; const SIMPLE_BID_REQUEST = { bidder: 'silvermob', diff --git a/test/spec/modules/smaatoBidAdapter_spec.js b/test/spec/modules/smaatoBidAdapter_spec.js index 6d117f829f9..f5b1c2827b2 100644 --- a/test/spec/modules/smaatoBidAdapter_spec.js +++ b/test/spec/modules/smaatoBidAdapter_spec.js @@ -10,7 +10,6 @@ import 'modules/multibid/index.js'; import 'modules/priceFloors.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; -import 'modules/schain.js'; const IMAGE_SYNC_URL = 'https://s.ad.smaato.net/c/?adExInit=p' const IFRAME_SYNC_URL = 'https://s.ad.smaato.net/i/?adExInit=p' @@ -1272,7 +1271,15 @@ describe('smaatoBidAdapterTest', () => { } ] }; - const bidRequestWithSchain = Object.assign({}, singleBannerBidRequest, {schain: schain}); + const bidRequestWithSchain = Object.assign({}, singleBannerBidRequest, { + ortb2: { + source: { + ext: { + schain: schain + } + } + } + }); const reqs = spec.buildRequests([bidRequestWithSchain], defaultBidderRequest); diff --git a/test/spec/modules/smartxBidAdapter_spec.js b/test/spec/modules/smartxBidAdapter_spec.js index d8ddf7a398b..f548151e31b 100644 --- a/test/spec/modules/smartxBidAdapter_spec.js +++ b/test/spec/modules/smartxBidAdapter_spec.js @@ -337,15 +337,21 @@ describe('The smartx adapter', function () { it('should pass schain param', function () { var request; - bid.schain = { - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1 + bid.ortb2 = { + source: { + ext: { + schain: { + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '00001', + hp: 1 + } + ] + } } - ] + } } request = spec.buildRequests([bid], bidRequestObj)[0]; diff --git a/test/spec/modules/smilewantedBidAdapter_spec.js b/test/spec/modules/smilewantedBidAdapter_spec.js index 183ec4a5001..7c1e007c6a7 100644 --- a/test/spec/modules/smilewantedBidAdapter_spec.js +++ b/test/spec/modules/smilewantedBidAdapter_spec.js @@ -116,7 +116,13 @@ const DISPLAY_REQUEST_WITH_SCHAIN = [{ tid: 'trans_abcd1234', } }, - schain: SCHAIN, + ortb2: { + source: { + ext: { + schain: SCHAIN + } + } + }, }]; const BID_RESPONSE_DISPLAY = { diff --git a/test/spec/modules/sonobiBidAdapter_spec.js b/test/spec/modules/sonobiBidAdapter_spec.js index 27707d5b7d4..78d538c77d2 100644 --- a/test/spec/modules/sonobiBidAdapter_spec.js +++ b/test/spec/modules/sonobiBidAdapter_spec.js @@ -267,21 +267,27 @@ describe('SonobiBidAdapter', function () { sandbox.restore(); }); let bidRequest = [{ - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 0 - }, - ] + 'ortb2': { + 'source': { + 'ext': { + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'indirectseller.com', + 'sid': '00001', + 'hp': 1 + }, + { + 'asi': 'indirectseller-2.com', + 'sid': '00002', + 'hp': 0 + }, + ] + } + } + } }, 'bidder': 'sonobi', 'params': { @@ -564,7 +570,7 @@ describe('SonobiBidAdapter', function () { it('should return a properly formatted request with schain defined', function () { const bidRequests = spec.buildRequests(bidRequest, bidderRequests); - expect(JSON.parse(decodeURIComponent(bidRequests.data.schain))).to.deep.equal(bidRequest[0].schain) + expect(JSON.parse(decodeURIComponent(bidRequests.data.schain))).to.deep.equal(bidRequest[0].ortb2.source.ext.schain) }); it('should return a properly formatted request with eids as a JSON-encoded set of eids', function () { diff --git a/test/spec/modules/sovrnBidAdapter_spec.js b/test/spec/modules/sovrnBidAdapter_spec.js index 05d18a0bb98..2ed79808356 100644 --- a/test/spec/modules/sovrnBidAdapter_spec.js +++ b/test/spec/modules/sovrnBidAdapter_spec.js @@ -529,17 +529,23 @@ describe('sovrnBidAdapter', function() { it('should add schain if present', function() { const schainRequest = { ...baseBidRequest, - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'directseller.com', - sid: '00001', - rid: 'BidRequest1', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'directseller.com', + sid: '00001', + rid: 'BidRequest1', + hp: 1 + } + ] + } } - ] + } } } const schainRequests = [schainRequest, baseBidRequest] diff --git a/test/spec/modules/sspBCBidAdapter_spec.js b/test/spec/modules/sspBCBidAdapter_spec.js index ceaad85faac..32f99096156 100644 --- a/test/spec/modules/sspBCBidAdapter_spec.js +++ b/test/spec/modules/sspBCBidAdapter_spec.js @@ -663,7 +663,7 @@ describe('SSPBC adapter', function () { }, ] } - const bidWithSupplyChain = Object.assign(bids[0], { schain: supplyChain }); + const bidWithSupplyChain = Object.assign(bids[0], { ortb2: { source: { ext: { schain: supplyChain } } } }); const requestWithSupplyChain = spec.buildRequests([bidWithSupplyChain], bidRequest); const payloadWithSupplyChain = requestWithSupplyChain ? JSON.parse(requestWithSupplyChain.data) : { site: false, imp: false }; diff --git a/test/spec/modules/stackadaptBidAdapter_spec.js b/test/spec/modules/stackadaptBidAdapter_spec.js index ea86adf28ca..b55bc8d75c9 100644 --- a/test/spec/modules/stackadaptBidAdapter_spec.js +++ b/test/spec/modules/stackadaptBidAdapter_spec.js @@ -914,8 +914,19 @@ describe('stackadaptBidAdapter', function () { 'ver': '1.0' }; - clonedBidRequests[0].schain = schain; + clonedBidRequests[0].ortb2 = { + source: { + ext: {schain: schain} + } + }; clonedBidderRequest.bids = clonedBidRequests; + + // Add schain to bidderRequest as well + clonedBidderRequest.ortb2 = { + source: { + ext: {schain: schain} + } + }; const ortbRequest = spec.buildRequests(clonedBidRequests, clonedBidderRequest).data; expect(ortbRequest.source.ext.schain).to.deep.equal(schain); diff --git a/test/spec/modules/stnBidAdapter_spec.js b/test/spec/modules/stnBidAdapter_spec.js index 98859385828..18089f64f44 100644 --- a/test/spec/modules/stnBidAdapter_spec.js +++ b/test/spec/modules/stnBidAdapter_spec.js @@ -370,12 +370,17 @@ describe('stnAdapter', function () { }); it('should have schain param if it is available in the bidRequest', () => { - const schain = { - ver: '1.0', - complete: 1, - nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], + bidderRequest.ortb2 = { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], + } + } + } }; - bidRequests[0].schain = schain; const request = spec.buildRequests(bidRequests, bidderRequest); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('schain', '1.0,1!indirectseller.com,00001,1,,,'); diff --git a/test/spec/modules/stroeerCoreBidAdapter_spec.js b/test/spec/modules/stroeerCoreBidAdapter_spec.js index e3347ccd413..fe9a193ad92 100644 --- a/test/spec/modules/stroeerCoreBidAdapter_spec.js +++ b/test/spec/modules/stroeerCoreBidAdapter_spec.js @@ -702,7 +702,12 @@ describe('stroeerCore bid adapter', function () { }); const bidReq = buildBidderRequest(); - bidReq.bids.forEach(bid => bid.schain = schain); + bidReq.bids.forEach(bid => { + bid.ortb2 = bid.ortb2 || {}; + bid.ortb2.source = bid.ortb2.source || {}; + bid.ortb2.source.ext = bid.ortb2.source.ext || {}; + bid.ortb2.source.ext.schain = schain; + }); const serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq); assert.deepEqual(serverRequestInfo.data.schain, schain); diff --git a/test/spec/modules/stvBidAdapter_spec.js b/test/spec/modules/stvBidAdapter_spec.js index 7a5e287057b..44effebb0e5 100644 --- a/test/spec/modules/stvBidAdapter_spec.js +++ b/test/spec/modules/stvBidAdapter_spec.js @@ -60,17 +60,23 @@ describe('stvAdapter', function() { 'bidderRequestId': '22edbae2733bf61', 'auctionId': '1d1a030790a475', 'adUnitCode': 'testDiv1', - 'schain': { - 'ver': '1.0', - 'complete': 0, - 'nodes': [ - { - 'asi': 'reseller.com', - 'sid': 'aaaaa', - 'rid': 'BidRequest4', - 'hp': 1 + 'ortb2': { + 'source': { + 'ext': { + 'schain': { + 'ver': '1.0', + 'complete': 0, + 'nodes': [ + { + 'asi': 'reseller.com', + 'sid': 'aaaaa', + 'rid': 'BidRequest4', + 'hp': 1 + } + ] + } } - ] + } }, 'userIdAsEids': [ { diff --git a/test/spec/modules/targetVideoBidAdapter_spec.js b/test/spec/modules/targetVideoBidAdapter_spec.js index f2c59d29031..8d9cb5bf18b 100644 --- a/test/spec/modules/targetVideoBidAdapter_spec.js +++ b/test/spec/modules/targetVideoBidAdapter_spec.js @@ -82,7 +82,13 @@ describe('TargetVideo Bid Adapter', function() { }; let videoRequestCloned = deepClone(videoRequest); - videoRequestCloned[0].schain = globalSchain; + videoRequestCloned[0].ortb2 = { + source: { + ext: { + schain: globalSchain + } + } + }; const request = spec.buildRequests(videoRequestCloned, defaultBidderRequest); expect(request).to.not.be.empty; diff --git a/test/spec/modules/teadsBidAdapter_spec.js b/test/spec/modules/teadsBidAdapter_spec.js index 5ce96e21a20..511be25b49f 100644 --- a/test/spec/modules/teadsBidAdapter_spec.js +++ b/test/spec/modules/teadsBidAdapter_spec.js @@ -743,14 +743,20 @@ describe('teadsBidAdapter', () => { it('should add schain info to payload if available', function () { const bidRequest = Object.assign({}, bidRequests[0], { - schain: { - ver: '1.0', - complete: 1, - nodes: [{ - asi: 'example.com', - sid: '00001', - hp: 1 - }] + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [{ + asi: 'example.com', + sid: '00001', + hp: 1 + }] + } + } + } } }); diff --git a/test/spec/modules/trafficgateBidAdapter_spec.js b/test/spec/modules/trafficgateBidAdapter_spec.js index fec467309ab..902604f0927 100644 --- a/test/spec/modules/trafficgateBidAdapter_spec.js +++ b/test/spec/modules/trafficgateBidAdapter_spec.js @@ -11,7 +11,6 @@ import 'modules/multibid/index.js'; import 'modules/priceFloors.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; -import 'modules/schain.js'; import 'modules/paapi.js'; import {deepClone} from 'src/utils.js'; @@ -932,13 +931,22 @@ describe('TrafficgateOpenxRtbAdapter', function () { bidId: 'test-bid-id-1', bidderRequestId: 'test-bid-request-1', auctionId: 'test-auction-1', - schain: schainConfig + ortb2: {source: { + ext: {schain: schainConfig} + }} }]; + + // Add schain to mockBidderRequest as well + mockBidderRequest.ortb2 = { + source: { + ext: {schain: schainConfig} + } + }; }); it('should send a supply chain object', function () { const request = spec.buildRequests(bidRequests, mockBidderRequest); - expect(request[0].data.source.ext.schain).to.equal(schainConfig); + expect(request[0].data.source.ext.schain).to.deep.equal(schainConfig); }); it('should send the supply chain object with the right version', function () { diff --git a/test/spec/modules/tripleliftBidAdapter_spec.js b/test/spec/modules/tripleliftBidAdapter_spec.js index 216142ab02e..14c6b9e1142 100644 --- a/test/spec/modules/tripleliftBidAdapter_spec.js +++ b/test/spec/modules/tripleliftBidAdapter_spec.js @@ -143,7 +143,13 @@ describe('triplelift adapter', function () { transactionId: '173f49a8-7549-4218-a23c-e7ba59b47229', auctionId: '1d1a030790a475', userId: {}, - schain, + ortb2: { + source: { + ext: { + schain + } + } + }, ortb2Imp: { ext: { tid: '173f49a8-7549-4218-a23c-e7ba59b47229' @@ -177,7 +183,13 @@ describe('triplelift adapter', function () { bidderRequestId: '22edbae2733bf6', auctionId: '1d1a030790a475', userId: {}, - schain, + ortb2: { + source: { + ext: { + schain + } + } + }, ortb2Imp: { ext: { data: { @@ -253,7 +265,13 @@ describe('triplelift adapter', function () { bidderRequestId: '22edbae2733bf6', auctionId: '1d1a030790a475', userId: {}, - schain, + ortb2: { + source: { + ext: { + schain + } + } + }, ortb2Imp: { misc: { test: 1 @@ -899,7 +917,7 @@ describe('triplelift adapter', function () { expect(payload.ext.schain).to.deep.equal(schain); }); it('should not create root level ext when schain is not present', function() { - bidRequests[0].schain = undefined; + delete bidRequests[0].ortb2.source.ext.schain; const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); const { data: payload } = request; expect(payload.ext).to.deep.equal(undefined); diff --git a/test/spec/modules/ttdBidAdapter_spec.js b/test/spec/modules/ttdBidAdapter_spec.js index 31569ccc176..8e6102f9977 100644 --- a/test/spec/modules/ttdBidAdapter_spec.js +++ b/test/spec/modules/ttdBidAdapter_spec.js @@ -547,7 +547,7 @@ describe('ttdBidAdapter', function () { }] }; let clonedBannerBidRequests = deepClone(baseBannerBidRequests); - clonedBannerBidRequests[0].schain = schain; + clonedBannerBidRequests[0].ortb2 = { source: { ext: { schain: schain } } }; const requestBody = testBuildRequests(clonedBannerBidRequests, baseBidderRequest).data; expect(requestBody.source.ext.schain).to.deep.equal(schain); diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js index 998e0db6fe8..10241687e14 100644 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -39,19 +39,25 @@ const validBannerBidReq = { } }, userId: userId, - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'exchange1.com', - 'sid': '1234', - 'hp': 1, - 'rid': 'bid-request-1', - 'name': 'publisher', - 'domain': 'publisher.com' + ortb2: { + source: { + ext: { + schain: { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'exchange1.com', + 'sid': '1234', + 'hp': 1, + 'rid': 'bid-request-1', + 'name': 'publisher', + 'domain': 'publisher.com' + } + ] + } } - ] + } } }; diff --git a/test/spec/modules/undertoneBidAdapter_spec.js b/test/spec/modules/undertoneBidAdapter_spec.js index ed3108c2749..808071be8db 100644 --- a/test/spec/modules/undertoneBidAdapter_spec.js +++ b/test/spec/modules/undertoneBidAdapter_spec.js @@ -116,7 +116,7 @@ const bidReq = [{ sizes: [[1, 1]], bidId: '453cf42d72bb3c', auctionId: '6c22f5a5-59df-4dc6-b92c-f433bcf0a874', - schain: schainObj + ortb2: { source: { ext: { schain: schainObj } } } }]; const supplyChainedBidReqs = [{ @@ -129,7 +129,7 @@ const supplyChainedBidReqs = [{ sizes: [[300, 250], [300, 600]], bidId: '263be71e91dd9d', auctionId: '9ad1fa8d-2297-4660-a018-b39945054746', - schain: schainObj + ortb2: { source: { ext: { schain: schainObj } } } }, { adUnitCode: 'div-gpt-ad-1460505748561-0', bidder: BIDDER_CODE, diff --git a/test/spec/modules/vdoaiBidAdapter_spec.js b/test/spec/modules/vdoaiBidAdapter_spec.js index 1cd361730a9..be2b8fe7386 100644 --- a/test/spec/modules/vdoaiBidAdapter_spec.js +++ b/test/spec/modules/vdoaiBidAdapter_spec.js @@ -43,16 +43,22 @@ describe('vdoaiBidAdapter', function () { ] } ], - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '1', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'example.com', + sid: '1', + hp: 1 + } + ] + } } - ] + } } } const bid2 = { @@ -91,21 +97,27 @@ describe('vdoaiBidAdapter', function () { ] } ], - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '1', - hp: 1 - }, - { - asi: 'example1.com', - sid: '2', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'example.com', + sid: '1', + hp: 1 + }, + { + asi: 'example1.com', + sid: '2', + hp: 1 + } + ] + } } - ] + } } } const bid3 = { @@ -148,16 +160,22 @@ describe('vdoaiBidAdapter', function () { ] } ], - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '1', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'example.com', + sid: '1', + hp: 1 + } + ] + } } - ] + } } } const bid4 = { @@ -198,16 +216,22 @@ describe('vdoaiBidAdapter', function () { ] } ], - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '1', - hp: 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'example.com', + sid: '1', + hp: 1 + } + ] + } } - ] + } } } @@ -739,6 +763,6 @@ function validateAdUnit(adUnit, bid) { })); expect(adUnit.publisherId).to.equal(bid.params.publisherId); expect(adUnit.userIdAsEids).to.deep.equal(bid.userIdAsEids); - expect(adUnit.supplyChain).to.deep.equal(bid.schain); + expect(adUnit.supplyChain).to.deep.equal(bid.ortb2?.source?.ext?.schain); expect(adUnit.ortb2Imp).to.deep.equal(bid.ortb2Imp); } diff --git a/test/spec/modules/videobyteBidAdapter_spec.js b/test/spec/modules/videobyteBidAdapter_spec.js index 7844e2bd1be..838e56ab801 100644 --- a/test/spec/modules/videobyteBidAdapter_spec.js +++ b/test/spec/modules/videobyteBidAdapter_spec.js @@ -196,7 +196,10 @@ describe('VideoByteBidAdapter', function () { hp: 1 }] }; - bidRequest.schain = globalSchain; + bidRequest.ortb2 = bidRequest.ortb2 || {}; + bidRequest.ortb2.source = bidRequest.ortb2.source || {}; + bidRequest.ortb2.source.ext = bidRequest.ortb2.source.ext || {}; + bidRequest.ortb2.source.ext.schain = globalSchain; const requests = spec.buildRequests([bidRequest], bidderRequest); const data = JSON.parse(requests[0].data); const schain = data.source.ext.schain; diff --git a/test/spec/modules/vidoomyBidAdapter_spec.js b/test/spec/modules/vidoomyBidAdapter_spec.js index 6f7c0beb29f..b05fbe43e8a 100644 --- a/test/spec/modules/vidoomyBidAdapter_spec.js +++ b/test/spec/modules/vidoomyBidAdapter_spec.js @@ -74,32 +74,38 @@ describe('vidoomyBidAdapter', function() { 'sizes': [[300, 250], [200, 100]] } }, - 'schain': { - ver: '1.0', - complete: 1, - nodes: [ - { - 'asi': 'exchange1.com', - 'sid': '1234!abcd', - 'hp': 1, - 'rid': 'bid-request-1', - 'name': 'publisher, Inc.', - 'domain': 'publisher.com' - }, - { - 'asi': 'exchange2.com', - 'sid': 'abcd', - 'hp': 1 - }, - { - 'asi': 'exchange2.com', - 'sid': 'abcd', - 'hp': 1, - 'rid': 'bid-request-2', - 'name': 'intermediary', - 'domain': 'intermediary.com' + 'ortb2': { + 'source': { + 'ext': { + 'schain': { + ver: '1.0', + complete: 1, + nodes: [ + { + 'asi': 'exchange1.com', + 'sid': '1234!abcd', + 'hp': 1, + 'rid': 'bid-request-1', + 'name': 'publisher, Inc.', + 'domain': 'publisher.com' + }, + { + 'asi': 'exchange2.com', + 'sid': 'abcd', + 'hp': 1 + }, + { + 'asi': 'exchange2.com', + 'sid': 'abcd', + 'hp': 1, + 'rid': 'bid-request-2', + 'name': 'intermediary', + 'domain': 'intermediary.com' + } + ] + } } - ] + } } }, { diff --git a/test/spec/modules/visxBidAdapter_spec.js b/test/spec/modules/visxBidAdapter_spec.js index 923ff7e86b2..c8b15527ab6 100755 --- a/test/spec/modules/visxBidAdapter_spec.js +++ b/test/spec/modules/visxBidAdapter_spec.js @@ -597,7 +597,7 @@ describe('VisxAdapter', function () { it('if schain is present payload must have schain param', function () { const schainBidRequests = [ - Object.assign({schain: schainObject}, bidRequests[0]), + Object.assign({ortb2: {source: {ext: {schain: schainObject}}}}, bidRequests[0]), bidRequests[1], bidRequests[2] ]; diff --git a/test/spec/modules/voxBidAdapter_spec.js b/test/spec/modules/voxBidAdapter_spec.js index 65752837b23..c2fe6abc4db 100644 --- a/test/spec/modules/voxBidAdapter_spec.js +++ b/test/spec/modules/voxBidAdapter_spec.js @@ -212,10 +212,16 @@ describe('VOX Adapter', function() { it('should set schain if not specified', function () { const requests = validBidRequests.map(bid => ({ ...bid, - schain: { - validation: 'strict', - config: { - ver: '1.0' + ortb2: { + source: { + ext: { + schain: { + validation: 'strict', + config: { + ver: '1.0' + } + } + } } } })) diff --git a/test/spec/modules/winrBidAdapter_spec.js b/test/spec/modules/winrBidAdapter_spec.js index 6246912d318..59e06b61405 100644 --- a/test/spec/modules/winrBidAdapter_spec.js +++ b/test/spec/modules/winrBidAdapter_spec.js @@ -470,16 +470,22 @@ describe('WinrAdapter', function () { it('should populate schain if available', function () { const bidRequest = Object.assign({}, bidRequests[0], { - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - 'asi': 'blob.com', - 'sid': '001', - 'hp': 1 + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + 'asi': 'blob.com', + 'sid': '001', + 'hp': 1 + } + ] + } } - ] + } } }); diff --git a/test/spec/modules/xeBidAdapter_spec.js b/test/spec/modules/xeBidAdapter_spec.js index c4e91d9943c..651d4cb0a6b 100644 --- a/test/spec/modules/xeBidAdapter_spec.js +++ b/test/spec/modules/xeBidAdapter_spec.js @@ -128,18 +128,20 @@ describe('xeBidAdapter', () => { it('should build request with schain', function () { const schainRequest = deepClone(defaultRequest); - schainRequest.schain = { - validation: 'strict', - config: { - ver: '1.0' + const bidderRequest = { + ortb2: { + source: { + ext: { + schain: { + ver: '1.0' + } + } + } } }; - const request = JSON.parse(spec.buildRequests([schainRequest], {}).data)[0]; + const request = JSON.parse(spec.buildRequests([schainRequest], bidderRequest).data)[0]; expect(request).to.have.property('schain').and.to.deep.equal({ - validation: 'strict', - config: { - ver: '1.0' - } + ver: '1.0' }); }); diff --git a/test/spec/modules/yahooAdsBidAdapter_spec.js b/test/spec/modules/yahooAdsBidAdapter_spec.js index f8ed7693f3f..7909fe141b7 100644 --- a/test/spec/modules/yahooAdsBidAdapter_spec.js +++ b/test/spec/modules/yahooAdsBidAdapter_spec.js @@ -424,7 +424,10 @@ describe('Yahoo Advertising Bid Adapter:', () => { complete: 1, nodes: [] }; - bidRequest.schain = globalSchain; + bidRequest.ortb2 = bidRequest.ortb2 || {}; + bidRequest.ortb2.source = bidRequest.ortb2.source || {}; + bidRequest.ortb2.source.ext = bidRequest.ortb2.source.ext || {}; + bidRequest.ortb2.source.ext.schain = globalSchain; const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data; const schain = data.source.ext.schain; expect(schain).to.be.undefined; @@ -442,7 +445,10 @@ describe('Yahoo Advertising Bid Adapter:', () => { hp: 1 }] }; - bidRequest.schain = globalSchain; + bidRequest.ortb2 = bidRequest.ortb2 || {}; + bidRequest.ortb2.source = bidRequest.ortb2.source || {}; + bidRequest.ortb2.source.ext = bidRequest.ortb2.source.ext || {}; + bidRequest.ortb2.source.ext.schain = globalSchain; const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data; const schain = data.source.ext.schain; expect(schain.nodes.length).to.equal(1); diff --git a/test/spec/modules/yieldlabBidAdapter_spec.js b/test/spec/modules/yieldlabBidAdapter_spec.js index 92fd20fb37d..7ce61de834c 100644 --- a/test/spec/modules/yieldlabBidAdapter_spec.js +++ b/test/spec/modules/yieldlabBidAdapter_spec.js @@ -52,22 +52,28 @@ const DEFAULT_REQUEST = () => ({ atype: 2, }], }], - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '1', - hp: 1, - }, - { - asi: 'indirectseller2.com', - name: 'indirectseller2 name with comma , and bang !', - sid: '2', - hp: 1, - }, - ], + ortb2: { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '1', + hp: 1, + }, + { + asi: 'indirectseller2.com', + name: 'indirectseller2 name with comma , and bang !', + sid: '2', + hp: 1, + }, + ], + } + } + } }, }); @@ -430,7 +436,7 @@ describe('yieldlabBidAdapter', () => { it('passes unencoded schain string to bid request when complete == 0', () => { const schainRequest = DEFAULT_REQUEST(); - schainRequest.schain.complete = 0; // + schainRequest.ortb2.source.ext.schain.complete = 0; const request = spec.buildRequests([schainRequest]); expect(request.url).to.include('schain=1.0,0!indirectseller.com,1,1,,,,!indirectseller2.com,2,1,,indirectseller2%20name%20with%20comma%20%2C%20and%20bang%20%21,,'); }); diff --git a/test/spec/modules/yieldmoBidAdapter_spec.js b/test/spec/modules/yieldmoBidAdapter_spec.js index db7ebdbbc34..f55308a2c10 100644 --- a/test/spec/modules/yieldmoBidAdapter_spec.js +++ b/test/spec/modules/yieldmoBidAdapter_spec.js @@ -304,7 +304,7 @@ describe('YieldmoAdapter', function () { complete: 1, nodes: [{asi: 'indirectseller.com', sid: '00001', hp: 1}], }; - const data = buildAndGetData([mockBannerBid({schain})]); + const data = buildAndGetData([mockBannerBid({ortb2: {source: {ext: {schain}}}})]); expect(data.schain).equal(JSON.stringify(schain)); }); @@ -631,7 +631,7 @@ describe('YieldmoAdapter', function () { hp: 1 }], }; - expect(buildAndGetData([mockVideoBid({schain})]).schain).to.deep.equal(schain); + expect(buildAndGetData([mockVideoBid({ortb2: {source: {ext: {schain}}}})]).schain).to.deep.equal(schain); }); it('should add gpid to the video request', function () { diff --git a/test/spec/modules/zeta_global_sspBidAdapter_spec.js b/test/spec/modules/zeta_global_sspBidAdapter_spec.js index 0a4e86e27ab..e031f99dc4e 100644 --- a/test/spec/modules/zeta_global_sspBidAdapter_spec.js +++ b/test/spec/modules/zeta_global_sspBidAdapter_spec.js @@ -126,12 +126,16 @@ describe('Zeta Ssp Bid Adapter', function () { gdprApplies: 1, consentString: 'consentString' }, - schain: schain, uspConsent: 'someCCPAString', params: params, userIdAsEids: eids, timeout: 500, ortb2: { + source: { + ext: { + schain: schain + } + }, bcat: ['CAT1'], badv: ['test1.com'], site: { @@ -191,7 +195,13 @@ describe('Zeta Ssp Bid Adapter', function () { gdprApplies: 1, consentString: 'consentString' }, - schain: schain, + ortb2: { + source: { + ext: { + schain: schain + } + } + }, uspConsent: 'someCCPAString', params: params, userIdAsEids: eids, diff --git a/test/spec/ortbConverter/schain_spec.js b/test/spec/ortbConverter/schain_spec.js deleted file mode 100644 index 8eeef445948..00000000000 --- a/test/spec/ortbConverter/schain_spec.js +++ /dev/null @@ -1,33 +0,0 @@ -import {setOrtbSourceExtSchain} from '../../../modules/schain.js'; - -describe('pbjs - ortb source.ext.schain', () => { - it('sets schain from request', () => { - const req = {}; - setOrtbSourceExtSchain(req, {}, { - bidRequests: [{schain: {s: 'chain'}}] - }); - expect(req.source.ext.schain).to.eql({s: 'chain'}); - }); - - it('does not set it if missing', () => { - const req = {}; - setOrtbSourceExtSchain(req, {}, {bidRequests: [{}]}); - expect(req).to.eql({}); - }) - - it('does not set it if already in request', () => { - const req = { - source: { - ext: { - schain: {s: 'chain'} - } - } - } - setOrtbSourceExtSchain(req, {}, { - bidRequests: [{ - schain: {other: 'chain'} - }] - }); - expect(req.source.ext.schain).to.eql({s: 'chain'}); - }) -});