diff --git a/integrationExamples/gpt/fledge_example.html b/integrationExamples/gpt/fledge_example.html
new file mode 100644
index 00000000000..5059e03daef
--- /dev/null
+++ b/integrationExamples/gpt/fledge_example.html
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+ Prebid.js FLEDGE+GPT Example
+
+ Div-1
+
+
+
+
+
diff --git a/integrationExamples/gpt/prebidServer_fledge_example.html b/integrationExamples/gpt/prebidServer_fledge_example.html
new file mode 100644
index 00000000000..8523c0f2920
--- /dev/null
+++ b/integrationExamples/gpt/prebidServer_fledge_example.html
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+ Prebid.js FLEDGE+GPT Example
+
+ Div-1
+
+
+
+
+
diff --git a/libraries/ortbConverter/processors/video.js b/libraries/ortbConverter/processors/video.js
index 5fe411e6bcf..c38231d9002 100644
--- a/libraries/ortbConverter/processors/video.js
+++ b/libraries/ortbConverter/processors/video.js
@@ -6,6 +6,7 @@ import {sizesToFormat} from '../lib/sizes.js';
const ORTB_VIDEO_PARAMS = new Set([
'pos',
'placement',
+ 'plcmt',
'api',
'mimes',
'protocols',
diff --git a/modules/adnuntiusBidAdapter.js b/modules/adnuntiusBidAdapter.js
index c3cd1963248..e59d12eadad 100644
--- a/modules/adnuntiusBidAdapter.js
+++ b/modules/adnuntiusBidAdapter.js
@@ -6,6 +6,7 @@ import { getStorageManager } from '../src/storageManager.js';
const BIDDER_CODE = 'adnuntius';
const ENDPOINT_URL = 'https://ads.adnuntius.delivery/i';
+const ENDPOINT_URL_EUROPE = 'https://europe.delivery.adnuntius.com/i';
const GVLID = 855;
const DEFAULT_VAST_VERSION = 'vast4'
// const DEFAULT_NATIVE = 'native'
@@ -130,10 +131,11 @@ export const spec = {
const network = networkKeys[j];
const networkRequest = [...request]
if (network.indexOf('_video') > -1) { networkRequest.push('tt=' + DEFAULT_VAST_VERSION) }
+ const requestURL = gdprApplies ? ENDPOINT_URL_EUROPE : ENDPOINT_URL
// if (network.indexOf('_native') > -1) { networkRequest.push('tt=' + DEFAULT_NATIVE) }
requests.push({
method: 'POST',
- url: ENDPOINT_URL + '?' + networkRequest.join('&'),
+ url: requestURL + '?' + networkRequest.join('&'),
data: JSON.stringify(networks[network]),
bid: bidRequests[network]
});
diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js
index 8f499e1e31e..cf3763be9c8 100644
--- a/modules/appnexusBidAdapter.js
+++ b/modules/appnexusBidAdapter.js
@@ -333,14 +333,16 @@ export const spec = {
payload.referrer_detection = refererinfo;
}
- const hasAdPodBid = find(bidRequests, hasAdPod);
- if (hasAdPodBid) {
- bidRequests.filter(hasAdPod).forEach(adPodBid => {
- const adPodTags = createAdPodRequest(tags, adPodBid);
- // don't need the original adpod placement because it's in adPodTags
- const nonPodTags = payload.tags.filter(tag => tag.uuid !== adPodBid.bidId);
- payload.tags = [...nonPodTags, ...adPodTags];
- });
+ if (FEATURES.VIDEO) {
+ const hasAdPodBid = find(bidRequests, hasAdPod);
+ if (hasAdPodBid) {
+ bidRequests.filter(hasAdPod).forEach(adPodBid => {
+ const adPodTags = createAdPodRequest(tags, adPodBid);
+ // don't need the original adpod placement because it's in adPodTags
+ const nonPodTags = payload.tags.filter(tag => tag.uuid !== adPodBid.bidId);
+ payload.tags = [...nonPodTags, ...adPodTags];
+ });
+ }
}
if (bidRequests[0].userId) {
@@ -653,7 +655,7 @@ function newBid(serverBid, rtbBid, bidderRequest) {
bid.meta = Object.assign({}, bid.meta, { brandId: rtbBid.brand_id });
}
- if (rtbBid.rtb.video) {
+ if (FEATURES.VIDEO && rtbBid.rtb.video) {
// shared video properties used for all 3 contexts
Object.assign(bid, {
width: rtbBid.rtb.video.player_width,
@@ -865,107 +867,111 @@ function bidToTag(bid) {
}
}
- const videoMediaType = deepAccess(bid, `mediaTypes.${VIDEO}`);
- const context = deepAccess(bid, 'mediaTypes.video.context');
-
- if (videoMediaType && context === 'adpod') {
- tag.hb_source = 7;
- } else {
- tag.hb_source = 1;
- }
- if (bid.mediaType === VIDEO || videoMediaType) {
- tag.ad_types.push(VIDEO);
- }
-
- // instream gets vastUrl, outstream gets vastXml
- if (bid.mediaType === VIDEO || (videoMediaType && context !== 'outstream')) {
- tag.require_asset_url = true;
- }
+ if (FEATURES.VIDEO) {
+ const videoMediaType = deepAccess(bid, `mediaTypes.${VIDEO}`);
+ const context = deepAccess(bid, 'mediaTypes.video.context');
- if (bid.params.video) {
- tag.video = {};
- // place any valid video params on the tag
- Object.keys(bid.params.video)
- .filter(param => includes(VIDEO_TARGETING, param))
- .forEach(param => {
- switch (param) {
- case 'context':
- case 'playback_method':
- let type = bid.params.video[param];
- type = (isArray(type)) ? type[0] : type;
- tag.video[param] = VIDEO_MAPPING[param][type];
- break;
- // Deprecating tags[].video.frameworks in favor of tags[].video_frameworks
- case 'frameworks':
- break;
- default:
- tag.video[param] = bid.params.video[param];
- }
- });
+ if (videoMediaType && context === 'adpod') {
+ tag.hb_source = 7;
+ } else {
+ tag.hb_source = 1;
+ }
+ if (bid.mediaType === VIDEO || videoMediaType) {
+ tag.ad_types.push(VIDEO);
+ }
- if (bid.params.video.frameworks && isArray(bid.params.video.frameworks)) {
- tag['video_frameworks'] = bid.params.video.frameworks;
+ // instream gets vastUrl, outstream gets vastXml
+ if (bid.mediaType === VIDEO || (videoMediaType && context !== 'outstream')) {
+ tag.require_asset_url = true;
}
- }
- // use IAB ORTB values if the corresponding values weren't already set by bid.params.video
- if (videoMediaType) {
- tag.video = tag.video || {};
- Object.keys(videoMediaType)
- .filter(param => includes(VIDEO_RTB_TARGETING, param))
- .forEach(param => {
- switch (param) {
- case 'minduration':
- case 'maxduration':
- if (typeof tag.video[param] !== 'number') tag.video[param] = videoMediaType[param];
- break;
- case 'skip':
- if (typeof tag.video['skippable'] !== 'boolean') tag.video['skippable'] = (videoMediaType[param] === 1);
- break;
- case 'skipafter':
- if (typeof tag.video['skipoffset'] !== 'number') tag.video['skippoffset'] = videoMediaType[param];
- break;
- case 'playbackmethod':
- if (typeof tag.video['playback_method'] !== 'number') {
- let type = videoMediaType[param];
+ if (bid.params.video) {
+ tag.video = {};
+ // place any valid video params on the tag
+ Object.keys(bid.params.video)
+ .filter(param => includes(VIDEO_TARGETING, param))
+ .forEach(param => {
+ switch (param) {
+ case 'context':
+ case 'playback_method':
+ let type = bid.params.video[param];
type = (isArray(type)) ? type[0] : type;
+ tag.video[param] = VIDEO_MAPPING[param][type];
+ break;
+ // Deprecating tags[].video.frameworks in favor of tags[].video_frameworks
+ case 'frameworks':
+ break;
+ default:
+ tag.video[param] = bid.params.video[param];
+ }
+ });
- // we only support iab's options 1-4 at this time.
- if (type >= 1 && type <= 4) {
- tag.video['playback_method'] = type;
- }
- }
- break;
- case 'api':
- if (!tag['video_frameworks'] && isArray(videoMediaType[param])) {
- // need to read thru array; remove 6 (we don't support it), swap 4 <> 5 if found (to match our adserver mapping for these specific values)
- let apiTmp = videoMediaType[param].map(val => {
- let v = (val === 4) ? 5 : (val === 5) ? 4 : val;
-
- if (v >= 1 && v <= 5) {
- return v;
+ if (bid.params.video.frameworks && isArray(bid.params.video.frameworks)) {
+ tag['video_frameworks'] = bid.params.video.frameworks;
+ }
+ }
+
+ // use IAB ORTB values if the corresponding values weren't already set by bid.params.video
+ if (videoMediaType) {
+ tag.video = tag.video || {};
+ Object.keys(videoMediaType)
+ .filter(param => includes(VIDEO_RTB_TARGETING, param))
+ .forEach(param => {
+ switch (param) {
+ case 'minduration':
+ case 'maxduration':
+ if (typeof tag.video[param] !== 'number') tag.video[param] = videoMediaType[param];
+ break;
+ case 'skip':
+ if (typeof tag.video['skippable'] !== 'boolean') tag.video['skippable'] = (videoMediaType[param] === 1);
+ break;
+ case 'skipafter':
+ if (typeof tag.video['skipoffset'] !== 'number') tag.video['skippoffset'] = videoMediaType[param];
+ break;
+ case 'playbackmethod':
+ if (typeof tag.video['playback_method'] !== 'number') {
+ let type = videoMediaType[param];
+ type = (isArray(type)) ? type[0] : type;
+
+ // we only support iab's options 1-4 at this time.
+ if (type >= 1 && type <= 4) {
+ tag.video['playback_method'] = type;
}
- }).filter(v => v);
- tag['video_frameworks'] = apiTmp;
- }
- break;
-
- case 'startdelay':
- case 'placement':
- const contextKey = 'context';
- if (typeof tag.video[contextKey] !== 'number') {
- const placement = videoMediaType['placement'];
- const startdelay = videoMediaType['startdelay'];
- const context = getContextFromPlacement(placement) || getContextFromStartDelay(startdelay);
- tag.video[contextKey] = VIDEO_MAPPING[contextKey][context];
- }
- break;
- }
- });
- }
+ }
+ break;
+ case 'api':
+ if (!tag['video_frameworks'] && isArray(videoMediaType[param])) {
+ // need to read thru array; remove 6 (we don't support it), swap 4 <> 5 if found (to match our adserver mapping for these specific values)
+ let apiTmp = videoMediaType[param].map(val => {
+ let v = (val === 4) ? 5 : (val === 5) ? 4 : val;
+
+ if (v >= 1 && v <= 5) {
+ return v;
+ }
+ }).filter(v => v);
+ tag['video_frameworks'] = apiTmp;
+ }
+ break;
+
+ case 'startdelay':
+ case 'placement':
+ const contextKey = 'context';
+ if (typeof tag.video[contextKey] !== 'number') {
+ const placement = videoMediaType['placement'];
+ const startdelay = videoMediaType['startdelay'];
+ const context = getContextFromPlacement(placement) || getContextFromStartDelay(startdelay);
+ tag.video[contextKey] = VIDEO_MAPPING[contextKey][context];
+ }
+ break;
+ }
+ });
+ }
- if (bid.renderer) {
- tag.video = Object.assign({}, tag.video, { custom_renderer_present: true });
+ if (bid.renderer) {
+ tag.video = Object.assign({}, tag.video, { custom_renderer_present: true });
+ }
+ } else {
+ tag.hb_source = 1;
}
if (bid.params.frameworks && isArray(bid.params.frameworks)) {
diff --git a/modules/bidwatchAnalyticsAdapter.js b/modules/bidwatchAnalyticsAdapter.js
index 0908b02de2e..b6cfa54170c 100644
--- a/modules/bidwatchAnalyticsAdapter.js
+++ b/modules/bidwatchAnalyticsAdapter.js
@@ -2,6 +2,7 @@ import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
import adapterManager from '../src/adapterManager.js';
import CONSTANTS from '../src/constants.json';
import { ajax } from '../src/ajax.js';
+import { getRefererInfo } from '../src/refererDetection.js';
const analyticsType = 'endpoint';
const url = 'URL_TO_SERVER_ENDPOINT';
@@ -145,6 +146,7 @@ function handleBidWon(args) {
});
}
args['cpmIncrement'] = increment;
+ args['referer'] = encodeURIComponent(getRefererInfo().page || getRefererInfo().topmostLocation);
if (typeof saveEvents.bidRequested == 'object' && saveEvents.bidRequested.length > 0 && saveEvents.bidRequested[0].gdprConsent) { args.gdpr = saveEvents.bidRequested[0].gdprConsent; }
ajax(endpoint + '.bidwatch.io/analytics/bid_won', null, JSON.stringify(args), {method: 'POST', withCredentials: true});
}
diff --git a/modules/conversantBidAdapter.js b/modules/conversantBidAdapter.js
index c2ffba8bb48..e17a9fe4021 100644
--- a/modules/conversantBidAdapter.js
+++ b/modules/conversantBidAdapter.js
@@ -124,6 +124,9 @@ export const spec = {
const payload = {
id: requestId,
imp: conversantImps,
+ source: {
+ tid: requestId
+ },
site: {
id: siteId,
mobile: document.querySelector('meta[name="viewport"][content*="width=device-width"]') !== null ? 1 : 0,
diff --git a/modules/emtvBidAdapter.js b/modules/emtvBidAdapter.js
new file mode 100644
index 00000000000..7a2fdae8adf
--- /dev/null
+++ b/modules/emtvBidAdapter.js
@@ -0,0 +1,211 @@
+import { isFn, deepAccess, logMessage, logError } from '../src/utils.js';
+import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
+
+import { registerBidder } from '../src/adapters/bidderFactory.js';
+import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
+import { config } from '../src/config.js';
+
+const BIDDER_CODE = 'emtv';
+const AD_URL = 'https://us-east-ep.engagemedia.tv/pbjs';
+const SYNC_URL = 'https://cs.engagemedia.tv';
+
+function isBidResponseValid(bid) {
+ if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) {
+ return false;
+ }
+
+ switch (bid.mediaType) {
+ case BANNER:
+ return Boolean(bid.width && bid.height && bid.ad);
+ case VIDEO:
+ return Boolean(bid.vastUrl || bid.vastXml);
+ case NATIVE:
+ return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length);
+ default:
+ return false;
+ }
+}
+
+function getPlacementReqData(bid) {
+ const { params, bidId, mediaTypes } = bid;
+ const schain = bid.schain || {};
+ const { placementId, endpointId } = params;
+ const bidfloor = getBidFloor(bid);
+
+ const placement = {
+ bidId,
+ schain,
+ bidfloor
+ };
+
+ if (placementId) {
+ placement.placementId = placementId;
+ placement.type = 'publisher';
+ } else if (endpointId) {
+ placement.endpointId = endpointId;
+ placement.type = 'network';
+ }
+
+ if (mediaTypes && mediaTypes[BANNER]) {
+ placement.adFormat = BANNER;
+ placement.sizes = mediaTypes[BANNER].sizes;
+ } else if (mediaTypes && mediaTypes[VIDEO]) {
+ placement.adFormat = VIDEO;
+ placement.playerSize = mediaTypes[VIDEO].playerSize;
+ placement.minduration = mediaTypes[VIDEO].minduration;
+ placement.maxduration = mediaTypes[VIDEO].maxduration;
+ placement.mimes = mediaTypes[VIDEO].mimes;
+ placement.protocols = mediaTypes[VIDEO].protocols;
+ placement.startdelay = mediaTypes[VIDEO].startdelay;
+ placement.placement = mediaTypes[VIDEO].placement;
+ placement.skip = mediaTypes[VIDEO].skip;
+ placement.skipafter = mediaTypes[VIDEO].skipafter;
+ placement.minbitrate = mediaTypes[VIDEO].minbitrate;
+ placement.maxbitrate = mediaTypes[VIDEO].maxbitrate;
+ placement.delivery = mediaTypes[VIDEO].delivery;
+ placement.playbackmethod = mediaTypes[VIDEO].playbackmethod;
+ placement.api = mediaTypes[VIDEO].api;
+ placement.linearity = mediaTypes[VIDEO].linearity;
+ } else if (mediaTypes && mediaTypes[NATIVE]) {
+ placement.native = mediaTypes[NATIVE];
+ placement.adFormat = NATIVE;
+ }
+
+ return placement;
+}
+
+function getBidFloor(bid) {
+ if (!isFn(bid.getFloor)) {
+ return deepAccess(bid, 'params.bidfloor', 0);
+ }
+
+ try {
+ const bidFloor = bid.getFloor({
+ currency: 'USD',
+ mediaType: '*',
+ size: '*',
+ });
+ return bidFloor.floor;
+ } catch (err) {
+ logError(err);
+ return 0;
+ }
+}
+
+export const spec = {
+ code: BIDDER_CODE,
+ supportedMediaTypes: [BANNER, VIDEO, NATIVE],
+
+ isBidRequestValid: (bid = {}) => {
+ const { params, bidId, mediaTypes } = bid;
+ let valid = Boolean(bidId && params && (params.placementId || params.endpointId));
+
+ if (mediaTypes && mediaTypes[BANNER]) {
+ valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes);
+ } else if (mediaTypes && mediaTypes[VIDEO]) {
+ valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize);
+ } else if (mediaTypes && mediaTypes[NATIVE]) {
+ valid = valid && Boolean(mediaTypes[NATIVE]);
+ } else {
+ valid = false;
+ }
+ return valid;
+ },
+
+ buildRequests: (validBidRequests = [], bidderRequest = {}) => {
+ // convert Native ORTB definition to old-style prebid native definition
+ validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);
+
+ let deviceWidth = 0;
+ let deviceHeight = 0;
+
+ let winLocation;
+ try {
+ const winTop = window.top;
+ deviceWidth = winTop.screen.width;
+ deviceHeight = winTop.screen.height;
+ winLocation = winTop.location;
+ } catch (e) {
+ logMessage(e);
+ winLocation = window.location;
+ }
+
+ const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page;
+ let refferLocation;
+ try {
+ refferLocation = refferUrl && new URL(refferUrl);
+ } catch (e) {
+ logMessage(e);
+ }
+ let location = refferLocation || winLocation;
+ const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : '';
+ const host = location.host;
+ const page = location.pathname;
+ const secure = location.protocol === 'https:' ? 1 : 0;
+ const placements = [];
+ const request = {
+ deviceWidth,
+ deviceHeight,
+ language,
+ secure,
+ host,
+ page,
+ placements,
+ coppa: config.getConfig('coppa') === true ? 1 : 0,
+ ccpa: bidderRequest.uspConsent || undefined,
+ gdpr: bidderRequest.gdprConsent || undefined,
+ tmax: config.getConfig('bidderTimeout')
+ };
+
+ const len = validBidRequests.length;
+ for (let i = 0; i < len; i++) {
+ const bid = validBidRequests[i];
+ placements.push(getPlacementReqData(bid));
+ }
+
+ return {
+ method: 'POST',
+ url: AD_URL,
+ data: request
+ };
+ },
+
+ interpretResponse: (serverResponse) => {
+ let response = [];
+ for (let i = 0; i < serverResponse.body.length; i++) {
+ let resItem = serverResponse.body[i];
+ if (isBidResponseValid(resItem)) {
+ const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : [];
+ resItem.meta = { ...resItem.meta, advertiserDomains };
+
+ response.push(resItem);
+ }
+ }
+ return response;
+ },
+
+ getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => {
+ let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image';
+ let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`;
+ if (gdprConsent && gdprConsent.consentString) {
+ if (typeof gdprConsent.gdprApplies === 'boolean') {
+ syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`;
+ } else {
+ syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`;
+ }
+ }
+ if (uspConsent && uspConsent.consentString) {
+ syncUrl += `&ccpa_consent=${uspConsent.consentString}`;
+ }
+
+ const coppa = config.getConfig('coppa') ? 1 : 0;
+ syncUrl += `&coppa=${coppa}`;
+
+ return [{
+ type: syncType,
+ url: syncUrl
+ }];
+ }
+};
+
+registerBidder(spec);
diff --git a/modules/emtvBidAdapter.md b/modules/emtvBidAdapter.md
new file mode 100644
index 00000000000..ed58ca43294
--- /dev/null
+++ b/modules/emtvBidAdapter.md
@@ -0,0 +1,79 @@
+# Overview
+
+```
+Module Name: EMTV Bidder Adapter
+Module Type: EMTV Bidder Adapter
+Maintainer: support@engagemedia.tv
+```
+
+# Description
+
+Connects to EMTV exchange for bids.
+EMTV bid adapter supports Banner, Video (instream and outstream) and Native.
+
+# Test Parameters
+```
+ var adUnits = [
+ // Will return static test banner
+ {
+ code: 'adunit1',
+ mediaTypes: {
+ banner: {
+ sizes: [ [300, 250], [320, 50] ],
+ }
+ },
+ bids: [
+ {
+ bidder: 'emtv',
+ params: {
+ placementId: 'testBanner',
+ }
+ }
+ ]
+ },
+ {
+ code: 'addunit2',
+ mediaTypes: {
+ video: {
+ playerSize: [ [640, 480] ],
+ context: 'instream',
+ minduration: 5,
+ maxduration: 60,
+ }
+ },
+ bids: [
+ {
+ bidder: 'emtv',
+ params: {
+ placementId: 'testVideo',
+ }
+ }
+ ]
+ },
+ {
+ code: 'addunit3',
+ mediaTypes: {
+ native: {
+ title: {
+ required: true
+ },
+ body: {
+ required: true
+ },
+ icon: {
+ required: true,
+ size: [64, 64]
+ }
+ }
+ },
+ bids: [
+ {
+ bidder: 'emtv',
+ params: {
+ placementId: 'testNative',
+ }
+ }
+ ]
+ }
+ ];
+```
diff --git a/modules/eskimiBidAdapter.js b/modules/eskimiBidAdapter.js
new file mode 100644
index 00000000000..4a00b97614b
--- /dev/null
+++ b/modules/eskimiBidAdapter.js
@@ -0,0 +1,72 @@
+import {registerBidder} from '../src/adapters/bidderFactory.js';
+import {BANNER} from '../src/mediaTypes.js';
+import * as utils from '../src/utils.js';
+import {ortbConverter} from '../libraries/ortbConverter/converter.js'
+
+const BIDDER_CODE = 'eskimi';
+// const ENDPOINT = 'https://hb.eskimi.com/bids'
+const ENDPOINT = 'https://sspback.eskimi.com/bid-request'
+
+const DEFAULT_BID_TTL = 30;
+const DEFAULT_CURRENCY = 'USD';
+const DEFAULT_NET_REVENUE = true;
+const GVLID = 814;
+
+export const spec = {
+ code: BIDDER_CODE,
+ gvlid: GVLID,
+ supportedMediaTypes: [BANNER],
+
+ isBidRequestValid: function (bid) {
+ return !!bid.params.placementId;
+ },
+
+ buildRequests(bidRequests, bidderRequest) {
+ const data = converter.toORTB({bidRequests, bidderRequest})
+
+ let bid = bidRequests.find((b) => b.params.placementId)
+ if (!data.site) data.site = {}
+ data.site.ext = {placementId: bid.params.placementId}
+
+ if (bidderRequest.gdprConsent) {
+ if (!data.user) data.user = {};
+ if (!data.user.ext) data.user.ext = {};
+ if (!data.regs) data.regs = {};
+ if (!data.regs.ext) data.regs.ext = {};
+ data.user.ext.consent = bidderRequest.gdprConsent.consentString;
+ data.regs.ext.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0;
+ }
+
+ return [{
+ method: 'POST',
+ url: ENDPOINT,
+ data,
+ options: {contentType: 'application/json;charset=UTF-8', withCredentials: false}
+ }]
+ },
+
+ interpretResponse(response, request) {
+ return converter.fromORTB({response: response.body, request: request.data}).bids;
+ },
+
+ /**
+ * Register bidder specific code, which will execute if a bid from this bidder won the auction
+ * @param {Bid} bid The bid that won the auction
+ */
+ onBidWon: function (bid) {
+ if (bid.burl) {
+ utils.triggerPixel(bid.burl);
+ }
+ }
+}
+
+const converter = ortbConverter({
+ context: {
+ netRevenue: DEFAULT_NET_REVENUE,
+ ttl: DEFAULT_BID_TTL,
+ currency: DEFAULT_CURRENCY,
+ mediaType: BANNER // TODO: support more types, we should set mtype on the winning bid
+ }
+});
+
+registerBidder(spec);
diff --git a/modules/eskimiBidAdapter.md b/modules/eskimiBidAdapter.md
new file mode 100644
index 00000000000..83ae87fd01b
--- /dev/null
+++ b/modules/eskimiBidAdapter.md
@@ -0,0 +1,34 @@
+# Overview
+
+Module Name: ESKIMI Bidder Adapter
+Module Type: Bidder Adapter
+Maintainer: tech@eskimi.com
+
+# Description
+
+An adapter to get a bid from Eskimi DSP.
+
+# Test Parameters
+```javascript
+ var adUnits = [{
+ code: 'div-gpt-ad-1460505748561-0',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]]
+ }
+ },
+
+ bids: [{
+ bidder: 'eskimi',
+ params: {
+ placementId: 612
+ }
+ }]
+
+ }];
+```
+
+Where:
+
+* placementId - Placement ID of the ad unit (required)
+
diff --git a/modules/gridBidAdapter.js b/modules/gridBidAdapter.js
index 792dc3b15b0..a043483d9b0 100644
--- a/modules/gridBidAdapter.js
+++ b/modules/gridBidAdapter.js
@@ -6,7 +6,10 @@ import {
generateUUID,
mergeDeep,
logWarn,
- parseUrl, isArray, isNumber
+ parseUrl,
+ isArray,
+ isNumber,
+ isStr
} from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { Renderer } from '../src/Renderer.js';
@@ -52,7 +55,12 @@ const ALIAS_CONFIG = {
bidResponseExternal: {
netRevenue: false
}
- }
+ },
+ 'gridNM': {
+ defaultParams: {
+ multiRequest: true
+ }
+ },
};
let hasSynced = false;
@@ -60,7 +68,7 @@ let hasSynced = false;
export const spec = {
code: BIDDER_CODE,
gvlid: GVLID,
- aliases: ['playwire', 'adlivetech', { code: 'trustx', skipPbsAliasing: true }],
+ aliases: ['playwire', 'adlivetech', 'gridNM', { code: 'trustx', skipPbsAliasing: true }],
supportedMediaTypes: [ BANNER, VIDEO ],
/**
* Determines whether or not the given bid request is valid.
@@ -126,8 +134,9 @@ export const spec = {
if (!endpoint) {
endpoint = ALIAS_CONFIG[bid.bidder] && ALIAS_CONFIG[bid.bidder].endpoint;
}
- const { params: { uid, keywords, forceBidder, multiRequest }, mediaTypes, bidId, adUnitCode, rtd, ortb2Imp } = bid;
- const { secid, pubid, source, content: bidParamsContent } = bid.params;
+ const { params, mediaTypes, bidId, adUnitCode, rtd, ortb2Imp } = bid;
+ const { defaultParams } = ALIAS_CONFIG[bid.bidder] || {};
+ const { secid, pubid, source, uid, keywords, forceBidder, multiRequest, content: bidParamsContent, video: videoParams } = { ...defaultParams, ...params };
const bidFloor = _getFloor(mediaTypes || {}, bid);
const jwTargeting = rtd && rtd.jwplayer && rtd.jwplayer.targeting;
if (jwTargeting && !content && jwTargeting.content) {
@@ -178,7 +187,7 @@ export const spec = {
}
}
if (mediaTypes && mediaTypes[VIDEO]) {
- const video = createVideoRequest(bid, mediaTypes[VIDEO]);
+ const video = createVideoRequest(videoParams, mediaTypes[VIDEO], bid.sizes);
if (video) {
impObj.video = video;
}
@@ -588,27 +597,41 @@ function _addBidResponse(serverBid, bidRequest, bidResponses, RendererConst, bid
}
}
-function createVideoRequest(bid, mediaType) {
- const { playerSize, mimes, durationRangeSec, protocols } = mediaType;
- const size = (playerSize || bid.sizes || [])[0];
- if (!size) return;
+function createVideoRequest(videoParams, mediaType, bidSizes) {
+ const { mind, maxd, size, playerSize, protocols, durationRangeSec = [], ...videoData } = { ...mediaType, ...videoParams };
+ if (size && isStr(size)) {
+ const sizeArray = size.split('x');
+ if (sizeArray.length === 2 && parseInt(sizeArray[0]) && parseInt(sizeArray[1])) {
+ videoData.w = parseInt(sizeArray[0]);
+ videoData.h = parseInt(sizeArray[1]);
+ }
+ }
+ if (!videoData.w || !videoData.h) {
+ const pSizesString = (playerSize || bidSizes || []).toString();
+ const pSizeString = (pSizesString.match(/^\d+,\d+/) || [])[0];
+ const pSize = pSizeString && pSizeString.split(',').map((d) => parseInt(d));
+ if (pSize && pSize.length === 2) {
+ Object.assign(videoData, parseGPTSingleSizeArrayToRtbSize(pSize));
+ }
+ }
- let result = parseGPTSingleSizeArrayToRtbSize(size);
+ if (!videoData.w || !videoData.h) return;
- if (mimes) {
- result.mimes = mimes;
- }
+ const minDur = mind || durationRangeSec[0] || videoData.minduration;
+ const maxDur = maxd || durationRangeSec[1] || videoData.maxduration;
- if (durationRangeSec && durationRangeSec.length === 2) {
- result.minduration = durationRangeSec[0];
- result.maxduration = durationRangeSec[1];
+ if (minDur) {
+ videoData.minduration = minDur;
+ }
+ if (maxDur) {
+ videoData.maxduration = maxDur;
}
if (protocols && protocols.length) {
- result.protocols = protocols;
+ videoData.protocols = protocols;
}
- return result;
+ return videoData;
}
function createBannerRequest(bid, mediaType) {
diff --git a/modules/gridNMBidAdapter.js b/modules/gridNMBidAdapter.js
deleted file mode 100644
index 36038d521bd..00000000000
--- a/modules/gridNMBidAdapter.js
+++ /dev/null
@@ -1,422 +0,0 @@
-import {
- isStr,
- deepAccess,
- isArray,
- isNumber,
- logError,
- logWarn,
- parseGPTSingleSizeArrayToRtbSize,
- mergeDeep
-} from '../src/utils.js';
-import { registerBidder } from '../src/adapters/bidderFactory.js';
-import { Renderer } from '../src/Renderer.js';
-import { VIDEO } from '../src/mediaTypes.js';
-import { config } from '../src/config.js';
-
-const BIDDER_CODE = 'gridNM';
-const ENDPOINT_URL = 'https://grid.bidswitch.net/hbjson';
-const SYNC_URL = 'https://x.bidswitch.net/sync?ssp=themediagrid';
-const TIME_TO_LIVE = 360;
-const RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js';
-
-let hasSynced = false;
-
-const LOG_ERROR_MESS = {
- noAdm: 'Bid from response has no adm parameter - ',
- noPrice: 'Bid from response has no price parameter - ',
- wrongContentType: 'Bid from response has wrong content_type parameter - ',
- noBid: 'Array of bid objects is empty',
- noPlacementCode: 'Can\'t find in requested bids the bid with auid - ',
- emptyUids: 'Uids should be not empty',
- emptySeatbid: 'Seatbid array from response has empty item',
- emptyResponse: 'Response is empty',
- hasEmptySeatbidArray: 'Response has empty seatbid array',
- hasNoArrayOfBids: 'Seatbid from response has no array of bid objects - '
-};
-
-export const spec = {
- code: BIDDER_CODE,
- supportedMediaTypes: [ VIDEO ],
- /**
- * Determines whether or not the given bid request is valid.
- *
- * @param {BidRequest} bid The bid params to validate.
- * @return boolean True if this is a valid bid, and false otherwise.
- */
- isBidRequestValid: function(bid) {
- let invalid =
- !bid.params.source || !isStr(bid.params.source) ||
- !bid.params.secid || !isStr(bid.params.secid) ||
- !bid.params.pubid || !isStr(bid.params.pubid);
-
- const video = deepAccess(bid, 'mediaTypes.video') || {};
- const { protocols = video.protocols, mimes = video.mimes } = deepAccess(bid, 'params.video') || {};
- if (!invalid) {
- invalid = !protocols || !mimes;
- }
- if (!invalid) {
- invalid = !isArray(mimes) || !mimes.length || mimes.filter((it) => !(it && isStr(it))).length;
- if (!invalid) {
- invalid = !isArray(protocols) || !protocols.length || protocols.filter((it) => !(isNumber(it) && it > 0 && !(it % 1))).length;
- }
- }
- return !invalid;
- },
- /**
- * Make a server request from the list of BidRequests.
- *
- * @param {BidRequest[]} validBidRequests - an array of bids
- * @param {bidderRequest} bidderRequest bidder request object
- * @return ServerRequest Info describing the request to the server.
- */
- buildRequests: function(validBidRequests, bidderRequest) {
- const bids = validBidRequests || [];
- const requests = [];
- let { bidderRequestId, auctionId, gdprConsent, uspConsent, timeout, refererInfo } = bidderRequest || {};
-
- const referer = refererInfo ? encodeURIComponent(refererInfo.page) : '';
-
- bids.forEach(bid => {
- let user;
- let userExt;
-
- const schain = bid.schain;
- const userIdAsEids = bid.userIdAsEids;
-
- if (!bidderRequestId) {
- bidderRequestId = bid.bidderRequestId;
- }
- if (!auctionId) {
- auctionId = bid.auctionId;
- }
- const {
- params: { floorcpm, source, secid, pubid, content, video },
- mediaTypes, bidId, adUnitCode, rtd, ortb2Imp, sizes
- } = bid;
-
- const bidFloor = _getFloor(mediaTypes || {}, bid, isNumber(floorcpm) && floorcpm);
- const jwTargeting = rtd && rtd.jwplayer && rtd.jwplayer.targeting;
-
- const siteContent = content || (jwTargeting && jwTargeting.content);
-
- const impObj = {
- id: bidId.toString(),
- tagid: secid.toString(),
- video: createVideoForImp(mergeDeep({}, video, mediaTypes && mediaTypes.video), sizes),
- ext: {
- divid: adUnitCode.toString()
- }
- };
-
- if (ortb2Imp && ortb2Imp.ext && ortb2Imp.ext.data) {
- impObj.ext.data = ortb2Imp.ext.data;
- if (impObj.ext.data.adserver && impObj.ext.data.adserver.adslot) {
- impObj.ext.gpid = impObj.ext.data.adserver.adslot.toString();
- } else {
- impObj.ext.gpid = ortb2Imp.ext.data.pbadslot && ortb2Imp.ext.data.pbadslot.toString();
- }
- }
-
- if (bidFloor) {
- impObj.bidfloor = bidFloor;
- }
-
- const imp = [impObj];
-
- const reqSource = {
- tid: auctionId && auctionId.toString(),
- ext: {
- wrapper: 'Prebid_js',
- wrapper_version: '$prebid.version$'
- }
- };
-
- if (schain) {
- reqSource.ext.schain = schain;
- }
-
- const bidderTimeout = timeout;
- const tmax = timeout ? Math.min(bidderTimeout, timeout) : bidderTimeout;
-
- const request = {
- id: bidderRequestId && bidderRequestId.toString(),
- site: {
- page: referer,
- publisher: {
- id: pubid,
- },
- },
- source: reqSource,
- tmax,
- imp,
- };
-
- if (siteContent) {
- request.site.content = siteContent;
- }
-
- if (gdprConsent && gdprConsent.consentString) {
- userExt = { consent: gdprConsent.consentString };
- }
-
- if (userIdAsEids && userIdAsEids.length) {
- userExt = userExt || {};
- userExt.eids = [...userIdAsEids];
- }
-
- if (userExt && Object.keys(userExt).length) {
- user = user || {};
- user.ext = userExt;
- }
-
- const ortb2UserData = deepAccess(bidderRequest, 'ortb2.user.data');
- if (ortb2UserData && ortb2UserData.length) {
- if (!user) {
- user = { data: [] };
- }
- user = mergeDeep(user, {
- data: [...ortb2UserData]
- });
- }
-
- if (user) {
- request.user = user;
- }
- const site = deepAccess(bidderRequest, 'ortb2.site');
- if (site) {
- const data = deepAccess(site, 'content.data');
- if (data && data.length) {
- const siteContent = request.site.content || {};
- request.site.content = mergeDeep(siteContent, { data });
- }
- }
-
- if (gdprConsent && gdprConsent.gdprApplies) {
- request.regs = {
- ext: {
- gdpr: gdprConsent.gdprApplies ? 1 : 0
- }
- };
- }
-
- if (uspConsent) {
- if (!request.regs) {
- request.regs = { ext: {} };
- }
- request.regs.ext.us_privacy = uspConsent;
- }
-
- if (config.getConfig('coppa') === true) {
- if (!request.regs) {
- request.regs = {};
- }
- request.regs.coppa = 1;
- }
-
- requests.push({
- method: 'POST',
- url: ENDPOINT_URL + '?no_mapping=1&sp=' + source,
- bid: bid,
- data: request
- });
- });
-
- return requests;
- },
- /**
- * Unpack the response from the server into a list of bids.
- *
- * @param {*} serverResponse A successful response from the server.
- * @param {*} bidRequest
- * @return {Bid[]} An array of bids which were nested inside the server.
- */
- interpretResponse: function(serverResponse, bidRequest) {
- serverResponse = serverResponse && serverResponse.body;
- const bidResponses = [];
-
- let errorMessage;
-
- if (!serverResponse) errorMessage = LOG_ERROR_MESS.emptyResponse;
- else if (serverResponse.seatbid && !serverResponse.seatbid.length) {
- errorMessage = LOG_ERROR_MESS.hasEmptySeatbidArray;
- }
-
- if (!errorMessage && serverResponse.seatbid) {
- const serverBid = _getBidFromResponse(serverResponse.seatbid[0]);
- if (serverBid) {
- if (!serverBid.adm && !serverBid.nurl) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid);
- else if (!serverBid.price) errorMessage = LOG_ERROR_MESS.noPrice + JSON.stringify(serverBid);
- else if (serverBid.content_type !== 'video') errorMessage = LOG_ERROR_MESS.wrongContentType + serverBid.content_type;
- if (!errorMessage) {
- const bid = bidRequest.bid;
- const bidResponse = {
- requestId: bid.bidId,
- cpm: serverBid.price,
- width: serverBid.w,
- height: serverBid.h,
- creativeId: serverBid.auid || bid.bidderRequestId,
- currency: 'USD',
- netRevenue: true,
- ttl: TIME_TO_LIVE,
- dealId: serverBid.dealid,
- mediaType: VIDEO,
- meta: {
- advertiserDomains: serverBid.adomain ? serverBid.adomain : []
- }
- };
-
- if (serverBid.adm) {
- bidResponse.vastXml = serverBid.adm;
- bidResponse.adResponse = {
- content: bidResponse.vastXml
- };
- } else if (serverBid.nurl) {
- bidResponse.vastUrl = serverBid.nurl;
- }
-
- if (!bid.renderer && (!bid.mediaTypes || !bid.mediaTypes.video || bid.mediaTypes.video.context === 'outstream')) {
- bidResponse.renderer = createRenderer(bidResponse, {
- id: bid.bidId,
- url: RENDERER_URL
- });
- }
- bidResponses.push(bidResponse);
- }
- }
- }
- if (errorMessage) logError(errorMessage);
- return bidResponses;
- },
- getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) {
- if (!hasSynced && syncOptions.pixelEnabled) {
- let params = '';
-
- if (gdprConsent && typeof gdprConsent.consentString === 'string') {
- if (typeof gdprConsent.gdprApplies === 'boolean') {
- params += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`;
- } else {
- params += `&gdpr_consent=${gdprConsent.consentString}`;
- }
- }
- if (uspConsent) {
- params += `&us_privacy=${uspConsent}`;
- }
-
- hasSynced = true;
- return {
- type: 'image',
- url: SYNC_URL + params
- };
- }
- }
-};
-
-/**
- * Gets bidfloor
- * @param {Object} mediaTypes
- * @param {Object} bid
- * @param {Number} floor
- * @returns {Number} floor
- */
-function _getFloor (mediaTypes, bid, floor) {
- const curMediaType = mediaTypes.video ? 'video' : 'banner';
-
- if (typeof bid.getFloor === 'function') {
- const floorInfo = bid.getFloor({
- currency: 'USD',
- mediaType: curMediaType,
- size: bid.sizes.map(([w, h]) => ({w, h}))
- });
-
- if (typeof floorInfo === 'object' &&
- floorInfo.currency === 'USD' &&
- !isNaN(parseFloat(floorInfo.floor))) {
- floor = Math.max(floor, parseFloat(floorInfo.floor));
- }
- }
-
- return floor;
-}
-
-function _getBidFromResponse(respItem) {
- if (!respItem) {
- logError(LOG_ERROR_MESS.emptySeatbid);
- } else if (!respItem.bid) {
- logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem));
- } else if (!respItem.bid[0]) {
- logError(LOG_ERROR_MESS.noBid);
- }
- return respItem && respItem.bid && respItem.bid[0];
-}
-
-function outstreamRender (bid) {
- bid.renderer.push(() => {
- window.ANOutstreamVideo.renderAd({
- targetId: bid.adUnitCode,
- adResponse: bid.adResponse
- });
- });
-}
-
-function createRenderer (bid, rendererParams) {
- const renderer = Renderer.install({
- id: rendererParams.id,
- url: rendererParams.url,
- loaded: false
- });
-
- try {
- renderer.setRender(outstreamRender);
- } catch (err) {
- logWarn('Prebid Error calling setRender on renderer', err);
- }
-
- return renderer;
-}
-
-function createVideoForImp({ mind, maxd, size, ...paramsVideo }, bidSizes) {
- if (size && isStr(size)) {
- const sizeArray = size.split('x');
- if (sizeArray.length === 2 && parseInt(sizeArray[0]) && parseInt(sizeArray[1])) {
- paramsVideo.w = parseInt(sizeArray[0]);
- paramsVideo.h = parseInt(sizeArray[1]);
- }
- }
-
- if (!paramsVideo.w || !paramsVideo.h) {
- const playerSizes = paramsVideo.playerSize && paramsVideo.playerSize.length === 2 ? paramsVideo.playerSize : bidSizes;
- if (playerSizes) {
- const playerSize = playerSizes[0];
- if (playerSize) {
- Object.assign(paramsVideo, parseGPTSingleSizeArrayToRtbSize(playerSize));
- }
- }
- }
-
- if (paramsVideo.playerSize) {
- delete paramsVideo.playerSize;
- }
-
- const durationRangeSec = paramsVideo.durationRangeSec || [];
- const minDur = mind || durationRangeSec[0] || paramsVideo.minduration;
- const maxDur = maxd || durationRangeSec[1] || paramsVideo.maxduration;
-
- if (minDur) {
- paramsVideo.minduration = minDur;
- }
- if (maxDur) {
- paramsVideo.maxduration = maxDur;
- }
-
- return paramsVideo;
-}
-
-export function resetUserSync() {
- hasSynced = false;
-}
-
-export function getSyncUrl() {
- return SYNC_URL;
-}
-
-registerBidder(spec);
diff --git a/modules/gridNMBidAdapter.md b/modules/gridNMBidAdapter.md
deleted file mode 100644
index 6decdde7f4c..00000000000
--- a/modules/gridNMBidAdapter.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# Overview
-
-Module Name: The Grid Media Bidder Adapter
-Module Type: Bidder Adapter
-Maintainer: grid-tech@themediagrid.com
-
-# Description
-
-Module that connects to Grid demand source to fetch bids.
-Grid bid adapter supports Banner and Video (instream and outstream).
-
-# Test Parameters
-```
- var adUnits = [
- {
- code: 'test-div',
- mediaTypes: {
- video: {
- playerSize: [728, 90],
- context: 'outstream'
- }
- },
- bids: [
- {
- bidder: "gridNM",
- params: {
- source: 'jwp',
- secid: '11',
- pubid: '22',
- video: {
- mimes: ['video/mp4', 'video/x-ms-wmv'],
- protocols: [1,2,3,4,5,6]
- }
- }
- }
- ]
- }
- ];
-```
diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js
index e791d933352..06f96edca30 100644
--- a/modules/ixBidAdapter.js
+++ b/modules/ixBidAdapter.js
@@ -195,6 +195,9 @@ function bidToVideoImp(bid) {
// populate imp level transactionId
imp.ext.tid = deepAccess(bid, 'ortb2Imp.ext.tid');
+ // AdUnit-Specific First Party Data
+ addAdUnitFPD(imp, bid)
+
// copy all video properties to imp object
for (const adUnitProperty in videoAdUnitRef) {
if (VIDEO_PARAMS_ALLOW_LIST.indexOf(adUnitProperty) !== -1 && !imp.video.hasOwnProperty(adUnitProperty)) {
@@ -268,6 +271,9 @@ function bidToNativeImp(bid) {
// populate imp level transactionId
imp.ext.tid = deepAccess(bid, 'ortb2Imp.ext.tid');
+ // AdUnit-Specific First Party Data
+ addAdUnitFPD(imp, bid)
+
_applyFloor(bid, imp, NATIVE);
return imp;
@@ -956,6 +962,11 @@ function addImpressions(impressions, transactionIds, r, adUnitIndex) {
_bannerImpression.bidfloorcur = impressionObjects[0].bidfloorcur;
}
+ const adUnitFPD = impressions[transactionIds[adUnitIndex]].adUnitFPD
+ if (adUnitFPD) {
+ _bannerImpression.ext.data = adUnitFPD;
+ }
+
r.imp.push(_bannerImpression);
} else {
// set imp.ext.gpid to resolved gpid for each imp
@@ -1011,6 +1022,19 @@ function addFPD(bidderRequest, r, fpd, site, user) {
return r;
}
+/**
+ * Adds First-Party Data (FPD) from the bid object to the imp object.
+ *
+ * @param {Object} imp - The imp object, representing an impression in the OpenRTB format.
+ * @param {Object} bid - The bid object, containing information about the bid request.
+ */
+function addAdUnitFPD(imp, bid) {
+ const adUnitFPD = deepAccess(bid, 'ortb2Imp.ext.data');
+ if (adUnitFPD) {
+ deepSetValue(imp, 'ext.data', adUnitFPD)
+ }
+}
+
/**
* addIdentifiersInfo adds indentifier info to ixDaig.
*
@@ -1196,6 +1220,12 @@ function createBannerImps(validBidRequest, missingBannerSizes, bannerImps) {
bannerImps[validBidRequest.transactionId].tagId = deepAccess(validBidRequest, 'params.tagId');
bannerImps[validBidRequest.transactionId].pos = deepAccess(validBidRequest, 'mediaTypes.banner.pos');
+ // AdUnit-Specific First Party Data
+ const adUnitFPD = deepAccess(validBidRequest, 'ortb2Imp.ext.data');
+ if (adUnitFPD) {
+ bannerImps[validBidRequest.transactionId].adUnitFPD = adUnitFPD;
+ }
+
const sid = deepAccess(validBidRequest, 'params.id');
if (sid && (typeof sid === 'string' || typeof sid === 'number')) {
bannerImps[validBidRequest.transactionId].sid = String(sid);
diff --git a/modules/kargoBidAdapter.js b/modules/kargoBidAdapter.js
index ecc40b26aa2..b612c88bb12 100644
--- a/modules/kargoBidAdapter.js
+++ b/modules/kargoBidAdapter.js
@@ -47,7 +47,7 @@ const SUA_ATTRIBUTES = [
const CERBERUS = Object.freeze({
KEY: 'krg_crb',
- SYNC_URL: 'https://crb.kargo.com/api/v1/initsyncrnd/{UUID}?seed={SEED}&idx={INDEX}&gdpr={GDPR}&gdpr_consent={GDPR_CONSENT}&us_privacy={US_PRIVACY}',
+ SYNC_URL: 'https://crb.kargo.com/api/v1/initsyncrnd/{UUID}?seed={SEED}&idx={INDEX}&gdpr={GDPR}&gdpr_consent={GDPR_CONSENT}&us_privacy={US_PRIVACY}&gpp={GPP_STRING}&gpp_sid={GPP_SID}',
SYNC_COUNT: 5,
PAGE_VIEW_ID: 'pageViewId',
PAGE_VIEW_TIMESTAMP: 'pageViewTimestamp',
@@ -94,7 +94,7 @@ function buildRequests(validBidRequests, bidderRequest) {
]
},
imp: impressions,
- user: getUserIds(tdidAdapter, bidderRequest.uspConsent, bidderRequest.gdprConsent, firstBidRequest.userIdAsEids),
+ user: getUserIds(tdidAdapter, bidderRequest.uspConsent, bidderRequest.gdprConsent, firstBidRequest.userIdAsEids, bidderRequest.gppConsent),
});
const reqCount = getRequestCount()
@@ -229,7 +229,7 @@ function interpretResponse(response, bidRequest) {
return bidResponses;
}
-function getUserSyncs(syncOptions, responses, gdprConsent, usPrivacy) {
+function getUserSyncs(syncOptions, _, gdprConsent, usPrivacy, gppConsent) {
const syncs = [];
const seed = _generateRandomUUID();
const clientId = getClientId();
@@ -237,6 +237,9 @@ function getUserSyncs(syncOptions, responses, gdprConsent, usPrivacy) {
var gdpr = (gdprConsent && gdprConsent.gdprApplies) ? 1 : 0;
var gdprConsentString = (gdprConsent && gdprConsent.consentString) ? gdprConsent.consentString : '';
+ var gppString = (gppConsent && gppConsent.consentString) ? gppConsent.consentString : '';
+ var gppApplicableSections = (gppConsent && gppConsent.applicableSections && Array.isArray(gppConsent.applicableSections)) ? gppConsent.applicableSections.join(',') : '';
+
// don't sync if opted out via usPrivacy
if (typeof usPrivacy == 'string' && usPrivacy.length == 4 && usPrivacy[0] == 1 && usPrivacy[2] == 'Y') {
return syncs;
@@ -251,6 +254,8 @@ function getUserSyncs(syncOptions, responses, gdprConsent, usPrivacy) {
.replace('{GDPR}', gdpr)
.replace('{GDPR_CONSENT}', gdprConsentString)
.replace('{US_PRIVACY}', usPrivacy || '')
+ .replace('{GPP_STRING}', gppString)
+ .replace('{GPP_SID}', gppApplicableSections)
});
}
}
@@ -329,7 +334,7 @@ function getLocalStorageSafely(key) {
}
}
-function getUserIds(tdidAdapter, usp, gdpr, eids) {
+function getUserIds(tdidAdapter, usp, gdpr, eids, gpp) {
const crb = spec._getCrb();
const userIds = {
crbIDs: crb.syncIds || {}
@@ -375,6 +380,19 @@ function getUserIds(tdidAdapter, usp, gdpr, eids) {
userIds.sharedIDEids = eids;
}
+ if (gpp) {
+ const parsedGPP = {}
+ if (gpp && gpp.consentString) {
+ parsedGPP.gppString = gpp.consentString
+ }
+ if (gpp && gpp.applicableSections) {
+ parsedGPP.applicableSections = gpp.applicableSections
+ }
+ if (!isEmpty(parsedGPP)) {
+ userIds.gpp = parsedGPP
+ }
+ }
+
return userIds;
}
diff --git a/modules/kueezRtbBidAdapter.js b/modules/kueezRtbBidAdapter.js
index 3bd468a581f..ef53ed9baf4 100644
--- a/modules/kueezRtbBidAdapter.js
+++ b/modules/kueezRtbBidAdapter.js
@@ -77,6 +77,8 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) {
const pId = extractPID(params);
const subDomain = extractSubDomain(params);
+ const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid', deepAccess(bid, 'ortb2Imp.ext.data.pbadslot', ''));
+
if (isFn(bid.getFloor)) {
const floorInfo = bid.getFloor({
currency: 'USD',
@@ -105,6 +107,7 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) {
res: `${screen.width}x${screen.height}`,
schain: schain,
mediaTypes: mediaTypes,
+ gpid: gpid,
auctionId: auctionId,
transactionId: transactionId,
bidderRequestId: bidderRequestId,
@@ -204,7 +207,7 @@ function interpretResponse(serverResponse, request) {
try {
results.forEach(result => {
- const {creativeId, ad, price, exp, width, height, currency, advertiserDomains, mediaType = BANNER} = result;
+ const {creativeId, ad, price, exp, width, height, currency, metaData, advertiserDomains, mediaType = BANNER} = result;
if (!ad || !price) {
return;
}
@@ -218,11 +221,20 @@ function interpretResponse(serverResponse, request) {
currency: currency || CURRENCY,
netRevenue: true,
ttl: exp || TTL_SECONDS,
- meta: {
- advertiserDomains: advertiserDomains || []
- }
};
+ if (metaData) {
+ Object.assign(response, {
+ meta: metaData
+ })
+ } else {
+ Object.assign(response, {
+ meta: {
+ advertiserDomains: advertiserDomains || []
+ }
+ })
+ }
+
if (mediaType === BANNER) {
Object.assign(response, {
ad: ad,
diff --git a/modules/mediasquareBidAdapter.js b/modules/mediasquareBidAdapter.js
index 819ff280e35..4076cd6927a 100644
--- a/modules/mediasquareBidAdapter.js
+++ b/modules/mediasquareBidAdapter.js
@@ -4,6 +4,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
import {Renderer} from '../src/Renderer.js';
+import { getRefererInfo } from '../src/refererDetection.js';
const BIDDER_CODE = 'mediasquare';
const BIDDER_URL_PROD = 'https://pbs-front.mediasquare.fr/'
@@ -170,7 +171,7 @@ export const spec = {
*/
onBidWon: function(bid) {
// fires a pixel to confirm a winning bid
- let params = {'pbjs': '$prebid.version$'};
+ let params = { pbjs: '$prebid.version$', referer: encodeURIComponent(getRefererInfo().page || getRefererInfo().topmostLocation) };
let endpoint = document.location.search.match(/msq_test=true/) ? BIDDER_URL_TEST : BIDDER_URL_PROD;
let paramsToSearchFor = ['cpm', 'size', 'mediaType', 'currency', 'creativeId', 'adUnitCode', 'timeToRespond', 'requestId', 'auctionId', 'originalCpm', 'originalCurrency'];
if (bid.hasOwnProperty('mediasquare')) {
diff --git a/modules/minutemediaplusBidAdapter.js b/modules/minutemediaplusBidAdapter.js
index c07f227bcfa..bd7874c405b 100644
--- a/modules/minutemediaplusBidAdapter.js
+++ b/modules/minutemediaplusBidAdapter.js
@@ -77,6 +77,8 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) {
const pId = extractPID(params);
const subDomain = extractSubDomain(params);
+ const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid', deepAccess(bid, 'ortb2Imp.ext.data.pbadslot', ''));
+
if (isFn(bid.getFloor)) {
const floorInfo = bid.getFloor({
currency: 'USD',
@@ -105,6 +107,7 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) {
res: `${screen.width}x${screen.height}`,
schain: schain,
mediaTypes: mediaTypes,
+ gpid: gpid,
auctionId: auctionId,
transactionId: transactionId,
bidderRequestId: bidderRequestId,
@@ -204,7 +207,7 @@ function interpretResponse(serverResponse, request) {
try {
results.forEach(result => {
- const {creativeId, ad, price, exp, width, height, currency, advertiserDomains, mediaType = BANNER} = result;
+ const {creativeId, ad, price, exp, width, height, currency, metaData, advertiserDomains, mediaType = BANNER} = result;
if (!ad || !price) {
return;
}
@@ -218,11 +221,20 @@ function interpretResponse(serverResponse, request) {
currency: currency || CURRENCY,
netRevenue: true,
ttl: exp || TTL_SECONDS,
- meta: {
- advertiserDomains: advertiserDomains || []
- }
};
+ if (metaData) {
+ Object.assign(response, {
+ meta: metaData
+ })
+ } else {
+ Object.assign(response, {
+ meta: {
+ advertiserDomains: advertiserDomains || []
+ }
+ })
+ }
+
if (mediaType === BANNER) {
Object.assign(response, {
ad: ad,
diff --git a/modules/missenaBidAdapter.js b/modules/missenaBidAdapter.js
index f461440c5a1..33fa6857e85 100644
--- a/modules/missenaBidAdapter.js
+++ b/modules/missenaBidAdapter.js
@@ -8,7 +8,7 @@ const EVENTS_DOMAIN = 'events.missena.io';
const EVENTS_DOMAIN_DEV = 'events.staging.missena.xyz';
export const spec = {
- aliases: [BIDDER_CODE],
+ aliases: ['msna'],
code: BIDDER_CODE,
gvlid: 687,
supportedMediaTypes: [BANNER],
diff --git a/modules/nativoBidAdapter.js b/modules/nativoBidAdapter.js
index a92168492d0..c62a74e6d6c 100644
--- a/modules/nativoBidAdapter.js
+++ b/modules/nativoBidAdapter.js
@@ -1,6 +1,7 @@
import { deepAccess, isEmpty } from '../src/utils.js'
import { registerBidder } from '../src/adapters/bidderFactory.js'
import { BANNER } from '../src/mediaTypes.js'
+import { getGlobal } from '../src/prebidGlobal.js'
// import { config } from 'src/config'
const BIDDER_CODE = 'nativo'
@@ -14,6 +15,8 @@ const SUPPORTED_AD_TYPES = [BANNER]
const FLOOR_PRICE_CURRENCY = 'USD'
const PRICE_FLOOR_WILDCARD = '*'
+const localPbjsRef = getGlobal()
+
/**
* Keep track of bid data by keys
* @returns {Object} - Map of bid data that can be referenced by multiple keys
@@ -133,6 +136,9 @@ export const spec = {
* @return ServerRequest Info describing the request to the server.
*/
buildRequests: function (validBidRequests, bidderRequest) {
+ const requestData = new RequestData()
+ requestData.addBidRequestDataSource(new UserEIDs())
+
// Parse values from bid requests
const placementIds = new Set()
const bidDataMap = BidDataMap()
@@ -166,6 +172,8 @@ export const spec = {
if (bidRequestFloorPriceData) {
floorPriceData[bidRequest.adUnitCode] = bidRequestFloorPriceData
}
+
+ requestData.processBidRequestData(bidRequest, bidderRequest)
})
bidRequestMap[bidderRequest.bidderRequestId] = bidDataMap
@@ -174,6 +182,10 @@ export const spec = {
// Build basic required QS Params
let params = [
+ // Prebid version
+ {
+ key: 'ntv_pbv', value: localPbjsRef.version
+ },
// Prebid request id
{ key: 'ntv_pb_rid', value: bidderRequest.bidderRequestId },
// Ad unit data
@@ -255,9 +267,12 @@ export const spec = {
params.unshift({ key: 'us_privacy', value: bidderRequest.uspConsent })
}
+ const qsParamStrings = [requestData.getRequestDataQueryString(), arrayToQS(params)]
+ const requestUrl = buildRequestUrl(BIDDER_ENDPOINT, qsParamStrings)
+
let serverRequest = {
method: 'GET',
- url: BIDDER_ENDPOINT + arrayToQS(params),
+ url: requestUrl
}
return serverRequest
@@ -404,13 +419,6 @@ export const spec = {
return syncs
},
- /**
- * Will be called when an adpater timed out for an auction.
- * Adapter can fire a ajax or pixel call to register a timeout at thier end.
- * @param {Object} timeoutData - Timeout specific data
- */
- onTimeout: function (timeoutData) {},
-
/**
* Will be called when a bid from the adapter won the auction.
* @param {Object} bid - The bid that won the auction
@@ -425,12 +433,6 @@ export const spec = {
appendFilterData(campaignsToFilter, ext.campaignsToFilter)
},
- /**
- * Will be called when the adserver targeting has been set for a bid from the adapter.
- * @param {Object} bidder - The bid of which the targeting has been set
- */
- onSetTargeting: function (bid) {},
-
/**
* Maps Prebid's bidId to Nativo's placementId values per unique bidderRequestId
* @param {String} bidderRequestId - The unique ID value associated with the bidderRequest
@@ -451,6 +453,78 @@ export const spec = {
registerBidder(spec)
// Utils
+export class RequestData {
+ constructor() {
+ this.bidRequestDataSources = []
+ }
+
+ addBidRequestDataSource(bidRequestDataSource) {
+ if (!(bidRequestDataSource instanceof BidRequestDataSource)) return
+
+ this.bidRequestDataSources.push(bidRequestDataSource)
+ }
+
+ processBidRequestData(bidRequest, bidderRequest) {
+ for (let bidRequestDataSource of this.bidRequestDataSources) {
+ bidRequestDataSource.processBidRequestData(bidRequest, bidderRequest)
+ }
+ }
+
+ getRequestDataQueryString() {
+ if (this.bidRequestDataSources.length == 0) return
+
+ const queryParams = this.bidRequestDataSources.map(dataSource => dataSource.getRequestQueryString()).filter(queryString => queryString !== '')
+ return queryParams.join('&')
+ }
+}
+
+export class BidRequestDataSource {
+ constructor() {
+ this.type = 'BidRequestDataSource'
+ }
+ processBidRequestData(bidRequest, bidderRequest) { }
+ getRequestQueryString() { return '' }
+}
+
+export class UserEIDs extends BidRequestDataSource {
+ constructor() {
+ super()
+ this.type = 'UserEIDs'
+ this.qsParam = new QueryStringParam('ntv_pb_eid')
+ this.eids = []
+ }
+
+ processBidRequestData(bidRequest, bidderRequest) {
+ if (bidRequest.userIdAsEids === undefined || this.eids.length > 0) return
+ this.eids = bidRequest.userIdAsEids
+ }
+
+ getRequestQueryString() {
+ if (this.eids.length === 0) return ''
+
+ const encodedValueArray = encodeToBase64(this.eids)
+ this.qsParam.value = encodedValueArray
+ return this.qsParam.toString()
+ }
+}
+
+export class QueryStringParam {
+ constructor(key, value) {
+ this.key = key
+ this.value = value
+ }
+}
+
+QueryStringParam.prototype.toString = function () {
+ return `${this.key}=${this.value}`
+}
+
+export function encodeToBase64(value) {
+ try {
+ return btoa(JSON.stringify(value))
+ } catch (err) { }
+}
+
export function parseFloorPriceData(bidRequest) {
if (typeof bidRequest.getFloor !== 'function') return
@@ -589,12 +663,9 @@ function appendQSParamString(str, key, value) {
* @returns
*/
function arrayToQS(arr) {
- return (
- '?' +
- arr.reduce((value, obj) => {
- return appendQSParamString(value, obj.key, obj.value)
- }, '')
- )
+ return arr.reduce((value, obj) => {
+ return appendQSParamString(value, obj.key, obj.value)
+ }, '')
}
/**
@@ -615,6 +686,24 @@ function getLargestSize(sizes, method = area) {
})
}
+/**
+ * Build the final request url
+ */
+export function buildRequestUrl(baseUrl, qsParamStringArray = []) {
+ if (qsParamStringArray.length === 0 || !Array.isArray(qsParamStringArray)) return baseUrl
+
+ const nonEmptyQSParamStrings = qsParamStringArray.filter(qsParamString => qsParamString.trim() !== '')
+
+ if (nonEmptyQSParamStrings.length === 0) return baseUrl
+
+ let requestUrl = `${baseUrl}?${nonEmptyQSParamStrings[0]}`
+ for (let i = 1; i < nonEmptyQSParamStrings.length; i++) {
+ requestUrl += `&${nonEmptyQSParamStrings[i]}`
+ }
+
+ return requestUrl
+}
+
/**
* Calculate the area
* @param {Array} size - [width, height]
@@ -645,7 +734,7 @@ export function getPageUrlFromBidRequest(bidRequest) {
try {
const url = new URL(paramPageUrl)
return url.href
- } catch (err) {}
+ } catch (err) { }
}
export function hasProtocol(url) {
diff --git a/modules/pairIdSystem.js b/modules/pairIdSystem.js
new file mode 100644
index 00000000000..4d73d4efb7e
--- /dev/null
+++ b/modules/pairIdSystem.js
@@ -0,0 +1,79 @@
+/**
+ * This module adds PAIR Id to the User ID module
+ * The {@link module:modules/userId} module is required
+ * @module modules/pairIdSystem
+ * @requires module:modules/userId
+ */
+
+import { submodule } from '../src/hook.js';
+import {getStorageManager} from '../src/storageManager.js'
+import { logError } from '../src/utils.js';
+import {MODULE_TYPE_UID} from '../src/activities/modules.js';
+
+const MODULE_NAME = 'pairId';
+const PAIR_ID_KEY = 'pairId';
+const DEFAULT_LIVERAMP_PAIR_ID_KEY = '_lr_pairId';
+
+export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME});
+
+function pairIdFromLocalStorage(key) {
+ return storage.localStorageIsEnabled ? storage.getDataFromLocalStorage(key) : null;
+}
+
+function pairIdFromCookie(key) {
+ return storage.cookiesAreEnabled ? storage.getCookie(key) : null;
+}
+
+/** @type {Submodule} */
+export const pairIdSubmodule = {
+ /**
+ * used to link submodule with config
+ * @type {string}
+ */
+ name: MODULE_NAME,
+ /**
+ * decode the stored id value for passing to bid requests
+ * @function
+ * @param { string | undefined } value
+ * @returns {{pairId:string} | undefined }
+ */
+ decode(value) {
+ return value && Array.isArray(value) ? {'pairId': value} : undefined
+ },
+ /**
+ * performs action to obtain id and return a value in the callback's response argument
+ * @function
+ * @returns {id: string | undefined }
+ */
+ getId(config) {
+ const pairIdsString = pairIdFromLocalStorage(PAIR_ID_KEY) || pairIdFromCookie(PAIR_ID_KEY)
+ let ids = []
+ if (pairIdsString && typeof pairIdsString == 'string') {
+ try {
+ ids = ids.concat(JSON.parse(atob(pairIdsString)))
+ } catch (error) {
+ logError(error)
+ }
+ }
+
+ const configParams = (config && config.params) || {};
+ if (configParams && configParams.liveramp) {
+ let LRStorageLocation = configParams.liveramp.storageKey || DEFAULT_LIVERAMP_PAIR_ID_KEY
+ const liverampValue = pairIdFromLocalStorage(LRStorageLocation) || pairIdFromCookie(LRStorageLocation)
+ try {
+ const obj = JSON.parse(atob(liverampValue));
+ ids = ids.concat(obj.envelope);
+ } catch (error) {
+ logError(error)
+ }
+ }
+
+ if (ids.length == 0) {
+ logError('PairId not found.')
+ return undefined;
+ }
+ return {'id': ids};
+ }
+};
+
+submodule('userId', pairIdSubmodule);
diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js
index 43a688f20e9..edfee7a0b6d 100644
--- a/modules/pubmaticBidAdapter.js
+++ b/modules/pubmaticBidAdapter.js
@@ -534,7 +534,7 @@ function _createBannerRequest(bid) {
export function checkVideoPlacement(videoData, adUnitCode) {
// Check for video.placement property. If property is missing display log message.
- if (!deepAccess(videoData, 'placement')) {
+ if (FEATURES.VIDEO && !deepAccess(videoData, 'placement')) {
logWarn(MSG_VIDEO_PLACEMENT_MISSING + ' for ' + adUnitCode);
};
}
@@ -543,7 +543,7 @@ function _createVideoRequest(bid) {
var videoData = mergeDeep(deepAccess(bid.mediaTypes, 'video'), bid.params.video);
var videoObj;
- if (videoData !== UNDEFINED) {
+ if (FEATURES.VIDEO && videoData !== UNDEFINED) {
videoObj = {};
checkVideoPlacement(videoData, bid.adUnitCode);
for (var key in VIDEO_CUSTOM_PARAMS) {
@@ -673,7 +673,7 @@ function _createImpressionObject(bid) {
isInvalidNativeRequest = false;
}
break;
- case VIDEO:
+ case FEATURES.VIDEO && VIDEO:
videoObj = _createVideoRequest(bid);
if (videoObj !== UNDEFINED) {
impObj.video = videoObj;
@@ -709,7 +709,7 @@ function _createImpressionObject(bid) {
return impObj.hasOwnProperty(BANNER) ||
impObj.hasOwnProperty(NATIVE) ||
- impObj.hasOwnProperty(VIDEO) ? impObj : UNDEFINED;
+ (FEATURES.VIDEO && impObj.hasOwnProperty(VIDEO)) ? impObj : UNDEFINED;
}
function _addImpressionFPD(imp, bid) {
@@ -810,7 +810,7 @@ function _checkMediaType(bid, newBid) {
var videoRegex = new RegExp(/VAST\s+version/);
if (adm.indexOf('span class="PubAPIAd"') >= 0) {
newBid.mediaType = BANNER;
- } else if (videoRegex.test(adm)) {
+ } else if (FEATURES.VIDEO && videoRegex.test(adm)) {
newBid.mediaType = VIDEO;
} else {
try {
@@ -896,7 +896,10 @@ function _assignRenderer(newBid, request) {
for (let bidderRequestBidsIndex = 0; bidderRequestBidsIndex < request.bidderRequest.bids.length; bidderRequestBidsIndex++) {
if (request.bidderRequest.bids[bidderRequestBidsIndex].bidId === newBid.requestId) {
bidParams = request.bidderRequest.bids[bidderRequestBidsIndex].params;
- context = request.bidderRequest.bids[bidderRequestBidsIndex].mediaTypes[VIDEO].context;
+
+ if (FEATURES.VIDEO) {
+ context = request.bidderRequest.bids[bidderRequestBidsIndex].mediaTypes[VIDEO].context;
+ }
adUnitCode = request.bidderRequest.bids[bidderRequestBidsIndex].adUnitCode;
}
}
@@ -916,7 +919,7 @@ function _assignRenderer(newBid, request) {
* @returns
*/
export function assignDealTier(newBid, bid, request) {
- if (!bid?.ext?.prebiddealpriority) return;
+ if (!bid?.ext?.prebiddealpriority || !FEATURES.VIDEO) return;
const bidRequest = getBidRequest(newBid.requestId, [request.bidderRequest]);
const videoObj = deepAccess(bidRequest, 'mediaTypes.video');
if (videoObj?.context != ADPOD) return;
@@ -999,7 +1002,7 @@ export const spec = {
return false;
}
// video ad validation
- if (bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(VIDEO)) {
+ if (FEATURES.VIDEO && bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(VIDEO)) {
// bid.mediaTypes.video.mimes OR bid.params.video.mimes should be present and must be a non-empty array
let mediaTypesVideoMimes = deepAccess(bid.mediaTypes, 'video.mimes');
let paramsVideoMimes = deepAccess(bid, 'params.video.mimes');
@@ -1284,7 +1287,7 @@ export const spec = {
switch (newBid.mediaType) {
case BANNER:
break;
- case VIDEO:
+ case FEATURES.VIDEO && VIDEO:
newBid.width = bid.hasOwnProperty('w') ? bid.w : req.video.w;
newBid.height = bid.hasOwnProperty('h') ? bid.h : req.video.h;
newBid.vastXml = bid.adm;
diff --git a/modules/rtbhouseBidAdapter.js b/modules/rtbhouseBidAdapter.js
index 5c3d430aadf..c4264d2920d 100644
--- a/modules/rtbhouseBidAdapter.js
+++ b/modules/rtbhouseBidAdapter.js
@@ -479,7 +479,7 @@ function interpretNativeBid(serverBid) {
function interpretNativeAd(adm) {
const native = JSON.parse(adm).native;
const result = {
- clickUrl: encodeURIComponent(native.link.url),
+ clickUrl: encodeURI(native.link.url),
impressionTrackers: native.imptrackers
};
native.assets.forEach(asset => {
@@ -489,14 +489,14 @@ function interpretNativeAd(adm) {
break;
case OPENRTB.NATIVE.ASSET_ID.IMAGE:
result.image = {
- url: encodeURIComponent(asset.img.url),
+ url: encodeURI(asset.img.url),
width: asset.img.w,
height: asset.img.h
};
break;
case OPENRTB.NATIVE.ASSET_ID.ICON:
result.icon = {
- url: encodeURIComponent(asset.img.url),
+ url: encodeURI(asset.img.url),
width: asset.img.w,
height: asset.img.h
};
diff --git a/modules/userId/eids.js b/modules/userId/eids.js
index 2f2d1ca7514..fa8e6f7647c 100644
--- a/modules/userId/eids.js
+++ b/modules/userId/eids.js
@@ -45,6 +45,12 @@ export const USER_IDS_CONFIG = {
atype: 1
},
+ // pairId
+ 'pairId': {
+ source: 'google.com',
+ atype: 571187
+ },
+
// justId
'justId': {
source: 'justtag.com',
diff --git a/modules/vidoomyBidAdapter.js b/modules/vidoomyBidAdapter.js
index 29128998fd1..c9ac9fae0f4 100644
--- a/modules/vidoomyBidAdapter.js
+++ b/modules/vidoomyBidAdapter.js
@@ -1,20 +1,21 @@
-import { logError, deepAccess, parseSizesInput } from '../src/utils.js';
+import {deepAccess, logError, parseSizesInput} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {config} from '../src/config.js';
-import { Renderer } from '../src/Renderer.js';
-import { INSTREAM, OUTSTREAM } from '../src/video.js';
+import {Renderer} from '../src/Renderer.js';
+import {INSTREAM, OUTSTREAM} from '../src/video.js';
const ENDPOINT = `https://d.vidoomy.com/api/rtbserver/prebid/`;
const BIDDER_CODE = 'vidoomy';
const GVLID = 380;
const COOKIE_SYNC_FALLBACK_URLS = [
- 'https://x.bidswitch.net/sync?ssp=vidoomy',
- 'https://ib.adnxs.com/getuid?https%3A%2F%2Fa-prebid.vidoomy.com%2Fsetuid%3Fbidder%3Dadnxs%26gdpr%3D{{GDPR}}%26gdpr_consent%3D{{GDPR_CONSENT}}%26uid%3D%24UID',
+ 'https://x.bidswitch.net/sync?ssp=vidoomy&gdpr={{GDPR}}&gdpr_consent={{GDPR_CONSENT}}&us_privacy=',
'https://pixel-sync.sitescout.com/dmp/pixelSync?nid=120&gdpr={{GDPR}}&gdpr_consent={{GDPR_CONSENT}}&redir=https%3A%2F%2Fa.vidoomy.com%2Fapi%2Frtbserver%2Fcookie%3Fi%3DCEN%26uid%3D%7BuserId%7D',
'https://cm.adform.net/cookie?redirect_url=https%3A%2F%2Fa-prebid.vidoomy.com%2Fsetuid%3Fbidder%3Dadf%26gdpr%3D{{GDPR}}%26gdpr_consent%3D{{GDPR_CONSENT}}%26uid%3D%24UID',
- 'https://ups.analytics.yahoo.com/ups/58531/occ?gdpr={{GDPR}}&gdpr_consent={{GDPR_CONSENT}}'
+ 'https://pixel.rubiconproject.com/exchange/sync.php?p=pbs-vidoomy&gdpr={{GDPR}}&gdpr_consent={{GDPR_CONSENT}}&us_privacy=',
+ 'https://rtb.openx.net/sync/prebid?gdpr={{GDPR}}&gdpr_consent={{GDPR_CONSENT}}&r=https%3A%2F%2Fa-prebid.vidoomy.com%2Fsetuid%3Fbidder%3Dopenx%26uid%3D$%7BUID%7D',
+ 'https://ads.pubmatic.com/AdServer/js/user_sync.html?gdpr={{GDPR}}&gdpr_consent={{GDPR_CONSENT}}&us_privacy=&predirect=https%3A%2F%2Fa-prebid.vidoomy.com%2Fsetuid%3Fbidder%3Dpubmatic%26gdpr%3D{{GDPR}}%26gdpr_consent%3D{{GDPR_CONSENT}}%26uid%3D'
];
const isBidRequestValid = bid => {
@@ -128,6 +129,20 @@ const buildRequests = (validBidRequests, bidderRequest) => {
const bidfloor = deepAccess(bid, `params.bidfloor`, 0);
const floor = getBidFloor(bid, adType, sizes, bidfloor);
+ const ortb2 = bidderRequest.ortb2 || {
+ bcat: [],
+ badv: [],
+ bapp: [],
+ btype: [],
+ battr: []
+ };
+
+ let eids;
+ const userEids = deepAccess(bid, 'userIdAsEids');
+ if (Array.isArray(userEids) && userEids.length > 0) {
+ eids = JSON.stringify(userEids) || '';
+ }
+
const queryParams = {
id: bid.params.id,
adtype: adType,
@@ -141,13 +156,19 @@ const buildRequests = (validBidRequests, bidderRequest) => {
pid: bid.params.pid,
requestId: bid.bidId,
schain: serializeSupplyChainObj(bid.schain) || '',
+ eids: eids || '',
bidfloor: floor,
d: getDomainWithoutSubdomain(hostname), // 'vidoomy.com',
// TODO: does the fallback make sense here?
sp: encodeURIComponent(bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation),
usp: bidderRequest.uspConsent || '',
coppa: !!config.getConfig('coppa'),
- videoContext: videoContext || ''
+ videoContext: videoContext || '',
+ bcat: ortb2.bcat || bid.params.bcat || [],
+ badv: ortb2.badv || bid.params.badv || [],
+ bapp: ortb2.bapp || bid.params.bapp || [],
+ btype: ortb2.btype || bid.params.btype || [],
+ battr: ortb2.battr || bid.params.battr || []
};
if (bidderRequest.gdprConsent) {
@@ -253,7 +274,7 @@ const interpretResponse = (serverResponse, bidRequest) => {
}
};
-function getUserSyncs (syncOptions, responses, gdprConsent, uspConsent) {
+function getUserSyncs(syncOptions, responses, gdprConsent, uspConsent) {
if (syncOptions.iframeEnabled || syncOptions.pixelEnabled) {
const pixelType = syncOptions.pixelEnabled ? 'image' : 'iframe';
const urls = deepAccess(responses, '0.body.pixels') || COOKIE_SYNC_FALLBACK_URLS;
@@ -280,7 +301,7 @@ export const spec = {
registerBidder(spec);
-function getDomainWithoutSubdomain (hostname) {
+function getDomainWithoutSubdomain(hostname) {
const parts = hostname.split('.');
const newParts = [];
for (let i = parts.length - 1; i >= 0; i--) {
diff --git a/modules/vidoomyBidAdapter.md b/modules/vidoomyBidAdapter.md
index d91ace5a7b9..b4095606d9b 100644
--- a/modules/vidoomyBidAdapter.md
+++ b/modules/vidoomyBidAdapter.md
@@ -27,7 +27,12 @@ var adUnits = [
params: {
id: '123123',
pid: '123123',
- bidfloor: 0.5 // This is optional
+ bidfloor: 0.5, // This is optional
+ bcat: ['IAB1-1'], // Optional - default is []
+ badv: ['example.com'], // Optional - default is []
+ bapp: ['app.com'], // Optional - default is []
+ btype: [1, 2, 3], // Optional - default is []
+ battr: [1, 2, 3] // Optional - default is []
}
}
]
@@ -52,7 +57,12 @@ var adUnits = [
params: {
id: '123123',
pid: '123123',
- bidfloor: 0.5 // This is optional
+ bidfloor: 0.5, // This is optional
+ bcat: ['IAB1-1'], // Optional - default is []
+ badv: ['example.com'], // Optional - default is []
+ bapp: ['app.com'], // Optional - default is []
+ btype: [1, 2, 3], // Optional - default is []
+ battr: [1, 2, 3] // Optional - default is []
}
}
]
diff --git a/modules/yieldmoBidAdapter.js b/modules/yieldmoBidAdapter.js
index 526e1911a06..bef453cb4ad 100644
--- a/modules/yieldmoBidAdapter.js
+++ b/modules/yieldmoBidAdapter.js
@@ -68,6 +68,7 @@ export const spec = {
const videoBidRequests = bidRequests.filter(request => hasVideoMediaType(request));
let serverRequests = [];
const eids = getEids(bidRequests[0]) || [];
+
if (bannerBidRequests.length > 0) {
let serverRequest = {
pbav: '$prebid.version$',
@@ -80,7 +81,9 @@ export const spec = {
userConsent: JSON.stringify({
// case of undefined, stringify will remove param
gdprApplies: deepAccess(bidderRequest, 'gdprConsent.gdprApplies') || '',
- cmp: deepAccess(bidderRequest, 'gdprConsent.consentString') || ''
+ cmp: deepAccess(bidderRequest, 'gdprConsent.consentString') || '',
+ gpp: deepAccess(bidderRequest, 'gppConsent.gppString') || '',
+ gpp_sid: deepAccess(bidderRequest, 'gppConsent.applicableSections') || []
}),
us_privacy: deepAccess(bidderRequest, 'uspConsent') || ''
};
@@ -514,12 +517,19 @@ function openRtbSite(bidRequest, bidderRequest) {
*/
function populateOpenRtbGdpr(openRtbRequest, bidderRequest) {
const gdpr = bidderRequest.gdprConsent;
- if (gdpr && 'gdprApplies' in gdpr) {
- deepSetValue(openRtbRequest, 'regs.ext.gdpr', gdpr.gdprApplies ? 1 : 0);
- deepSetValue(openRtbRequest, 'user.ext.consent', gdpr.consentString);
+ const gpp = deepAccess(bidderRequest, 'gppConsent.gppString');
+ const gppsid = deepAccess(bidderRequest, 'gppConsent.applicableSections');
+ if (gpp) {
+ deepSetValue(openRtbRequest, 'regs.ext.gpp', gpp);
+ } else {
+ deepSetValue(openRtbRequest, 'regs.ext.gdpr', gdpr && gdpr.gdprApplies ? 1 : 0);
+ deepSetValue(openRtbRequest, 'user.ext.consent', gdpr && gdpr.consentString ? gdpr.consentString : '');
+ }
+ if (gppsid && gppsid.length > 0) {
+ deepSetValue(openRtbRequest, 'regs.ext.gpp_sid', gppsid);
}
const uspConsent = deepAccess(bidderRequest, 'uspConsent');
- if (uspConsent) {
+ if (!gpp && uspConsent) {
deepSetValue(openRtbRequest, 'regs.ext.us_privacy', uspConsent);
}
}
diff --git a/package-lock.json b/package-lock.json
index 54442c348e0..7baf4ab3094 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "prebid.js",
- "version": "7.46.0-pre",
+ "version": "7.47.0-pre",
"lockfileVersion": 2,
"requires": true,
"packages": {
diff --git a/package.json b/package.json
index 7ebcb655ed7..df9a5551c50 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "prebid.js",
- "version": "7.46.0-pre",
+ "version": "7.47.0-pre",
"description": "Header Bidding Management Library",
"main": "src/prebid.js",
"scripts": {
diff --git a/src/config.js b/src/config.js
index 0922a2a2bea..48909d677e9 100644
--- a/src/config.js
+++ b/src/config.js
@@ -66,158 +66,109 @@ export function newConfig() {
function resetConfig() {
defaults = {};
- let newConfig = {
- // `debug` is equivalent to legacy `pbjs.logging` property
- _debug: DEFAULT_DEBUG,
- get debug() {
- return this._debug;
- },
- set debug(val) {
- this._debug = val;
- },
- // default timeout for all bids
- _bidderTimeout: DEFAULT_BIDDER_TIMEOUT,
- get bidderTimeout() {
- return this._bidderTimeout;
- },
- set bidderTimeout(val) {
- this._bidderTimeout = val;
- },
+ function getProp(name) {
+ return props[name].val;
+ }
- _publisherDomain: null,
- get publisherDomain() {
- return this._publisherDomain;
- },
- set publisherDomain(val) {
- logWarn('publisherDomain is deprecated and has no effect since v7 - use pageUrl instead')
- this._publisherDomain = val;
- },
+ function setProp(name, val) {
+ props[name].val = val;
+ }
- // calls existing function which may be moved after deprecation
- _priceGranularity: GRANULARITY_OPTIONS.MEDIUM,
- set priceGranularity(val) {
- if (validatePriceGranularity(val)) {
- if (typeof val === 'string') {
- this._priceGranularity = (hasGranularity(val)) ? val : GRANULARITY_OPTIONS.MEDIUM;
- } else if (isPlainObject(val)) {
- this._customPriceBucket = val;
- this._priceGranularity = GRANULARITY_OPTIONS.CUSTOM;
- logMessage('Using custom price granularity');
+ const props = {
+ publisherDomain: {
+ set(val) {
+ if (val != null) {
+ logWarn('publisherDomain is deprecated and has no effect since v7 - use pageUrl instead')
}
+ setProp('publisherDomain', val);
}
},
- get priceGranularity() {
- return this._priceGranularity;
- },
-
- _customPriceBucket: {},
- get customPriceBucket() {
- return this._customPriceBucket;
- },
-
- /**
- * mediaTypePriceGranularity
- * @type {MediaTypePriceGranularity}
- */
- _mediaTypePriceGranularity: {},
-
- get mediaTypePriceGranularity() {
- return this._mediaTypePriceGranularity;
- },
- set mediaTypePriceGranularity(val) {
- this._mediaTypePriceGranularity = Object.keys(val).reduce((aggregate, item) => {
- if (validatePriceGranularity(val[item])) {
+ priceGranularity: {
+ val: GRANULARITY_OPTIONS.MEDIUM,
+ set(val) {
+ if (validatePriceGranularity(val)) {
if (typeof val === 'string') {
- aggregate[item] = (hasGranularity(val[item])) ? val[item] : this._priceGranularity;
+ setProp('priceGranularity', (hasGranularity(val)) ? val : GRANULARITY_OPTIONS.MEDIUM);
} else if (isPlainObject(val)) {
- aggregate[item] = val[item];
- logMessage(`Using custom price granularity for ${item}`);
+ setProp('customPriceBucket', val);
+ setProp('priceGranularity', GRANULARITY_OPTIONS.CUSTOM)
+ logMessage('Using custom price granularity');
}
- } else {
- logWarn(`Invalid price granularity for media type: ${item}`);
}
- return aggregate;
- }, {});
- },
-
- _sendAllBids: DEFAULT_ENABLE_SEND_ALL_BIDS,
- get enableSendAllBids() {
- return this._sendAllBids;
+ }
},
- set enableSendAllBids(val) {
- this._sendAllBids = val;
+ customPriceBucket: {
+ val: {},
+ set() {}
},
-
- _useBidCache: DEFAULT_BID_CACHE,
- get useBidCache() {
- return this._useBidCache;
+ mediaTypePriceGranularity: {
+ val: {},
+ set(val) {
+ val != null && setProp('mediaTypePriceGranularity', Object.keys(val).reduce((aggregate, item) => {
+ if (validatePriceGranularity(val[item])) {
+ if (typeof val === 'string') {
+ aggregate[item] = (hasGranularity(val[item])) ? val[item] : getProp('priceGranularity');
+ } else if (isPlainObject(val)) {
+ aggregate[item] = val[item];
+ logMessage(`Using custom price granularity for ${item}`);
+ }
+ } else {
+ logWarn(`Invalid price granularity for media type: ${item}`);
+ }
+ return aggregate;
+ }, {}));
+ }
},
- set useBidCache(val) {
- this._useBidCache = val;
+ bidderSequence: {
+ val: DEFAULT_BIDDER_SEQUENCE,
+ set(val) {
+ if (VALID_ORDERS[val]) {
+ setProp('bidderSequence', val);
+ } else {
+ logWarn(`Invalid order: ${val}. Bidder Sequence was not set.`);
+ }
+ }
},
+ auctionOptions: {
+ val: {},
+ set(val) {
+ if (validateauctionOptions(val)) {
+ setProp('auctionOptions', val);
+ }
+ }
+ }
+ }
+ let newConfig = {
+ // `debug` is equivalent to legacy `pbjs.logging` property
+ debug: DEFAULT_DEBUG,
+ bidderTimeout: DEFAULT_BIDDER_TIMEOUT,
+ enableSendAllBids: DEFAULT_ENABLE_SEND_ALL_BIDS,
+ useBidCache: DEFAULT_BID_CACHE,
/**
* deviceAccess set to false will disable setCookie, getCookie, hasLocalStorage
* @type {boolean}
*/
- _deviceAccess: DEFAULT_DEVICE_ACCESS,
- get deviceAccess() {
- return this._deviceAccess;
- },
- set deviceAccess(val) {
- this._deviceAccess = val;
- },
-
- _bidderSequence: DEFAULT_BIDDER_SEQUENCE,
- get bidderSequence() {
- return this._bidderSequence;
- },
- set bidderSequence(val) {
- if (VALID_ORDERS[val]) {
- this._bidderSequence = val;
- } else {
- logWarn(`Invalid order: ${val}. Bidder Sequence was not set.`);
- }
- },
+ deviceAccess: DEFAULT_DEVICE_ACCESS,
// timeout buffer to adjust for bidder CDN latency
- _timeoutBuffer: DEFAULT_TIMEOUTBUFFER,
- get timeoutBuffer() {
- return this._timeoutBuffer;
- },
- set timeoutBuffer(val) {
- this._timeoutBuffer = val;
- },
-
- _disableAjaxTimeout: DEFAULT_DISABLE_AJAX_TIMEOUT,
- get disableAjaxTimeout() {
- return this._disableAjaxTimeout;
- },
- set disableAjaxTimeout(val) {
- this._disableAjaxTimeout = val;
- },
+ timeoutBuffer: DEFAULT_TIMEOUTBUFFER,
+ disableAjaxTimeout: DEFAULT_DISABLE_AJAX_TIMEOUT,
// default max nested iframes for referer detection
- _maxNestedIframes: DEFAULT_MAX_NESTED_IFRAMES,
- get maxNestedIframes() {
- return this._maxNestedIframes;
- },
- set maxNestedIframes(val) {
- this._maxNestedIframes = val;
- },
-
- _auctionOptions: {},
- get auctionOptions() {
- return this._auctionOptions;
- },
- set auctionOptions(val) {
- if (validateauctionOptions(val)) {
- this._auctionOptions = val;
- }
- },
+ maxNestedIframes: DEFAULT_MAX_NESTED_IFRAMES,
};
+ Object.defineProperties(newConfig,
+ Object.fromEntries(Object.entries(props)
+ .map(([k, def]) => [k, Object.assign({
+ get: getProp.bind(null, k),
+ set: setProp.bind(null, k),
+ enumerable: true,
+ }, def)]))
+ );
+
if (config) {
callSubscribers(
Object.keys(config).reduce((memo, topic) => {
diff --git a/test/spec/modules/1plusXRtdProvider_spec.js b/test/spec/modules/1plusXRtdProvider_spec.js
index 496c005f470..8657c37d7d8 100644
--- a/test/spec/modules/1plusXRtdProvider_spec.js
+++ b/test/spec/modules/1plusXRtdProvider_spec.js
@@ -332,15 +332,16 @@ describe('1plusXRtdProvider', () => {
}
it('correctly builds URLs if gdpr parameters are present', () => {
- const url1 = getPapiUrl(customer)
- const url2 = getPapiUrl(customer, extractConsent(consent))
- expect(['&consent_string=myConsent&gdpr_applies=1', '&gdpr_applies=1&consent_string=myConsent']).to.contain(url2.replace(url1, ''))
+ const url1 = getPapiUrl(customer);
+ const url2 = getPapiUrl(customer, extractConsent(consent));
+ expect(['&consent_string=myConsent&gdpr_applies=1', '&gdpr_applies=1&consent_string=myConsent']).to.contain(url2.replace(url1, ''));
})
- it('correctly builds URLs if fpid parameters are present')
- const url1 = getPapiUrl(customer)
- const url2 = getPapiUrl(customer, {}, 'my_first_party_id')
- expect(url2.replace(url1, '')).to.equal('&fpid=my_first_party_id')
+ it('correctly builds URLs if fpid parameters are present', () => {
+ const url1 = getPapiUrl(customer);
+ const url2 = getPapiUrl(customer, {}, 'my_first_party_id');
+ expect(url2.replace(url1, '')).to.equal('&fpid=my_first_party_id');
+ })
})
describe('updateBidderConfig', () => {
diff --git a/test/spec/modules/adagioBidAdapter_spec.js b/test/spec/modules/adagioBidAdapter_spec.js
index 759b16a81bb..adba79ddc96 100644
--- a/test/spec/modules/adagioBidAdapter_spec.js
+++ b/test/spec/modules/adagioBidAdapter_spec.js
@@ -1481,31 +1481,6 @@ describe('Adagio bid adapter', () => {
});
});
- describe.skip('optional params auto detection', function() {
- it('should auto detect adUnitElementId when GPT is used', function() {
- sandbox.stub(utils, 'getGptSlotInfoForAdUnitCode').withArgs('banner').returns({divId: 'gpt-banner'});
- expect(adagio.autoDetectAdUnitElementId('banner')).to.eq('gpt-banner');
- });
- });
-
- describe.skip('print number handling', function() {
- it('should return 1 if no adunit-code found. This means it is the first auction', function() {
- sandbox.stub(adagio, 'getPageviewId').returns('abc-def');
- expect(adagio.computePrintNumber('adunit-code')).to.eql(1);
- });
-
- it('should increment the adunit print number when the adunit-code has already been used for an other auction', function() {
- sandbox.stub(adagio, 'getPageviewId').returns('abc-def');
-
- window.top.ADAGIO.adUnits['adunit-code'] = {
- pageviewId: 'abc-def',
- printNumber: 1,
- };
-
- expect(adagio.computePrintNumber('adunit-code')).to.eql(2);
- });
- });
-
describe('site information using refererDetection or window.top', function() {
it('should returns domain, page and window.referrer in a window.top context', function() {
const bidderRequest = new BidderRequestBuilder({
diff --git a/test/spec/modules/adnuntiusBidAdapter_spec.js b/test/spec/modules/adnuntiusBidAdapter_spec.js
index 150e013af98..153565eb3ca 100644
--- a/test/spec/modules/adnuntiusBidAdapter_spec.js
+++ b/test/spec/modules/adnuntiusBidAdapter_spec.js
@@ -8,6 +8,7 @@ import { getStorageManager } from 'src/storageManager.js';
describe('adnuntiusBidAdapter', function () {
const URL = 'https://ads.adnuntius.delivery/i?tzo=';
+ const EURO_URL = 'https://europe.delivery.adnuntius.com/i?tzo=';
const GVLID = 855;
const usi = utils.generateUUID()
const meta = [{ key: 'usi', value: usi }]
@@ -35,7 +36,7 @@ describe('adnuntiusBidAdapter', function () {
const ENDPOINT_URL_VIDEO = `${URL}${tzo}&format=json&userId=${usi}&tt=vast4`;
const ENDPOINT_URL_NOCOOKIE = `${URL}${tzo}&format=json&userId=${usi}&noCookies=true`;
const ENDPOINT_URL_SEGMENTS = `${URL}${tzo}&format=json&segments=segment1,segment2,segment3&userId=${usi}`;
- const ENDPOINT_URL_CONSENT = `${URL}${tzo}&format=json&consentString=consentString&userId=${usi}`;
+ const ENDPOINT_URL_CONSENT = `${EURO_URL}${tzo}&format=json&consentString=consentString&userId=${usi}`;
const adapter = newBidder(spec);
const bidderRequests = [
diff --git a/test/spec/modules/appnexusBidAdapter_spec.js b/test/spec/modules/appnexusBidAdapter_spec.js
index 9e88e2875c7..1603c6e9397 100644
--- a/test/spec/modules/appnexusBidAdapter_spec.js
+++ b/test/spec/modules/appnexusBidAdapter_spec.js
@@ -257,11 +257,15 @@ describe('AppNexusAdapter', function () {
transactionId: '04f2659e-c005-4eb1-a57c-fa93145e3843'
}];
- let types = ['banner', 'video'];
+ let types = ['banner'];
if (FEATURES.NATIVE) {
types.push('native');
}
+ if (FEATURES.VIDEO) {
+ types.push('video');
+ }
+
types.forEach(type => {
getAdUnitsStub.callsFake(function (...args) {
return adUnits;
@@ -290,122 +294,303 @@ describe('AppNexusAdapter', function () {
expect(payload.tags[0].ad_types).to.not.exist;
});
- it('should populate the ad_types array on outstream requests', function () {
- const bidRequest = Object.assign({}, bidRequests[0]);
- bidRequest.mediaTypes = {};
- bidRequest.mediaTypes.video = { context: 'outstream' };
+ if (FEATURES.VIDEO) {
+ it('should populate the ad_types array on outstream requests', function () {
+ const bidRequest = Object.assign({}, bidRequests[0]);
+ bidRequest.mediaTypes = {};
+ bidRequest.mediaTypes.video = { context: 'outstream' };
- const request = spec.buildRequests([bidRequest]);
- const payload = JSON.parse(request.data);
+ const request = spec.buildRequests([bidRequest]);
+ const payload = JSON.parse(request.data);
- expect(payload.tags[0].ad_types).to.deep.equal(['video']);
- expect(payload.tags[0].hb_source).to.deep.equal(1);
- });
+ expect(payload.tags[0].ad_types).to.deep.equal(['video']);
+ expect(payload.tags[0].hb_source).to.deep.equal(1);
+ });
- it('sends bid request to ENDPOINT via POST', function () {
- const request = spec.buildRequests(bidRequests);
- expect(request.url).to.equal(ENDPOINT);
- expect(request.method).to.equal('POST');
- });
+ it('should attach valid video params to the tag', function () {
+ let bidRequest = Object.assign({},
+ bidRequests[0],
+ {
+ params: {
+ placementId: '10433394',
+ video: {
+ id: 123,
+ minduration: 100,
+ foobar: 'invalid'
+ }
+ }
+ }
+ );
- it('should attach valid video params to the tag', function () {
- let bidRequest = Object.assign({},
- bidRequests[0],
- {
+ const request = spec.buildRequests([bidRequest]);
+ const payload = JSON.parse(request.data);
+ expect(payload.tags[0].video).to.deep.equal({
+ id: 123,
+ minduration: 100
+ });
+ expect(payload.tags[0].hb_source).to.deep.equal(1);
+ });
+
+ it('should include ORTB video values when video params were not set', function () {
+ let bidRequest = deepClone(bidRequests[0]);
+ bidRequest.params = {
+ placementId: '1234235',
+ video: {
+ skippable: true,
+ playback_method: ['auto_play_sound_off', 'auto_play_sound_unknown'],
+ context: 'outstream'
+ }
+ };
+ bidRequest.mediaTypes = {
+ video: {
+ playerSize: [640, 480],
+ context: 'outstream',
+ mimes: ['video/mp4'],
+ skip: 0,
+ minduration: 5,
+ api: [1, 5, 6],
+ playbackmethod: [2, 4]
+ }
+ };
+
+ const request = spec.buildRequests([bidRequest]);
+ const payload = JSON.parse(request.data);
+
+ expect(payload.tags[0].video).to.deep.equal({
+ minduration: 5,
+ playback_method: 2,
+ skippable: true,
+ context: 4
+ });
+ expect(payload.tags[0].video_frameworks).to.deep.equal([1, 4])
+ });
+
+ it('should add video property when adUnit includes a renderer', function () {
+ const videoData = {
+ mediaTypes: {
+ video: {
+ context: 'outstream',
+ mimes: ['video/mp4']
+ }
+ },
params: {
placementId: '10433394',
video: {
- id: 123,
- minduration: 100,
- foobar: 'invalid'
+ skippable: true,
+ playback_method: ['auto_play_sound_off']
}
}
- }
- );
+ };
- const request = spec.buildRequests([bidRequest]);
- const payload = JSON.parse(request.data);
- expect(payload.tags[0].video).to.deep.equal({
- id: 123,
- minduration: 100
- });
- expect(payload.tags[0].hb_source).to.deep.equal(1);
- });
+ let bidRequest1 = deepClone(bidRequests[0]);
+ bidRequest1 = Object.assign({}, bidRequest1, videoData, {
+ renderer: {
+ url: 'https://test.renderer.url',
+ render: function () { }
+ }
+ });
- it('should include ORTB video values when video params were not set', function () {
- let bidRequest = deepClone(bidRequests[0]);
- bidRequest.params = {
- placementId: '1234235',
- video: {
+ let bidRequest2 = deepClone(bidRequests[0]);
+ bidRequest2.adUnitCode = 'adUnit_code_2';
+ bidRequest2 = Object.assign({}, bidRequest2, videoData);
+
+ const request = spec.buildRequests([bidRequest1, bidRequest2]);
+ const payload = JSON.parse(request.data);
+ expect(payload.tags[0].video).to.deep.equal({
skippable: true,
- playback_method: ['auto_play_sound_off', 'auto_play_sound_unknown'],
- context: 'outstream'
- }
- };
- bidRequest.mediaTypes = {
- video: {
- playerSize: [640, 480],
- context: 'outstream',
- mimes: ['video/mp4'],
- skip: 0,
- minduration: 5,
- api: [1, 5, 6],
- playbackmethod: [2, 4]
- }
- };
+ playback_method: 2,
+ custom_renderer_present: true
+ });
+ expect(payload.tags[1].video).to.deep.equal({
+ skippable: true,
+ playback_method: 2
+ });
+ });
- const request = spec.buildRequests([bidRequest]);
- const payload = JSON.parse(request.data);
+ it('should duplicate adpod placements into batches and set correct maxduration', function () {
+ let bidRequest = Object.assign({},
+ bidRequests[0],
+ {
+ params: { placementId: '14542875' }
+ },
+ {
+ mediaTypes: {
+ video: {
+ context: 'adpod',
+ playerSize: [640, 480],
+ adPodDurationSec: 300,
+ durationRangeSec: [15, 30],
+ }
+ }
+ }
+ );
- expect(payload.tags[0].video).to.deep.equal({
- minduration: 5,
- playback_method: 2,
- skippable: true,
- context: 4
+ const request = spec.buildRequests([bidRequest]);
+ const payload1 = JSON.parse(request[0].data);
+ const payload2 = JSON.parse(request[1].data);
+
+ // 300 / 15 = 20 total
+ expect(payload1.tags.length).to.equal(15);
+ expect(payload2.tags.length).to.equal(5);
+
+ expect(payload1.tags[0]).to.deep.equal(payload1.tags[1]);
+ expect(payload1.tags[0].video.maxduration).to.equal(30);
+
+ expect(payload2.tags[0]).to.deep.equal(payload1.tags[1]);
+ expect(payload2.tags[0].video.maxduration).to.equal(30);
});
- expect(payload.tags[0].video_frameworks).to.deep.equal([1, 4])
- });
- it('should add video property when adUnit includes a renderer', function () {
- const videoData = {
- mediaTypes: {
- video: {
- context: 'outstream',
- mimes: ['video/mp4']
+ it('should round down adpod placements when numbers are uneven', function () {
+ let bidRequest = Object.assign({},
+ bidRequests[0],
+ {
+ params: { placementId: '14542875' }
+ },
+ {
+ mediaTypes: {
+ video: {
+ context: 'adpod',
+ playerSize: [640, 480],
+ adPodDurationSec: 123,
+ durationRangeSec: [45],
+ }
+ }
}
- },
- params: {
- placementId: '10433394',
- video: {
- skippable: true,
- playback_method: ['auto_play_sound_off']
+ );
+
+ const request = spec.buildRequests([bidRequest]);
+ const payload = JSON.parse(request.data);
+ expect(payload.tags.length).to.equal(2);
+ });
+
+ it('should duplicate adpod placements when requireExactDuration is set', function () {
+ let bidRequest = Object.assign({},
+ bidRequests[0],
+ {
+ params: { placementId: '14542875' }
+ },
+ {
+ mediaTypes: {
+ video: {
+ context: 'adpod',
+ playerSize: [640, 480],
+ adPodDurationSec: 300,
+ durationRangeSec: [15, 30],
+ requireExactDuration: true,
+ }
+ }
}
- }
- };
+ );
- let bidRequest1 = deepClone(bidRequests[0]);
- bidRequest1 = Object.assign({}, bidRequest1, videoData, {
- renderer: {
- url: 'https://test.renderer.url',
- render: function () { }
- }
+ // 20 total placements with 15 max impressions = 2 requests
+ const request = spec.buildRequests([bidRequest]);
+ expect(request.length).to.equal(2);
+
+ // 20 spread over 2 requests = 15 in first request, 5 in second
+ const payload1 = JSON.parse(request[0].data);
+ const payload2 = JSON.parse(request[1].data);
+ expect(payload1.tags.length).to.equal(15);
+ expect(payload2.tags.length).to.equal(5);
+
+ // 10 placements should have max/min at 15
+ // 10 placemenst should have max/min at 30
+ const payload1tagsWith15 = payload1.tags.filter(tag => tag.video.maxduration === 15);
+ const payload1tagsWith30 = payload1.tags.filter(tag => tag.video.maxduration === 30);
+ expect(payload1tagsWith15.length).to.equal(10);
+ expect(payload1tagsWith30.length).to.equal(5);
+
+ // 5 placemenst with min/max at 30 were in the first request
+ // so 5 remaining should be in the second
+ const payload2tagsWith30 = payload2.tags.filter(tag => tag.video.maxduration === 30);
+ expect(payload2tagsWith30.length).to.equal(5);
});
- let bidRequest2 = deepClone(bidRequests[0]);
- bidRequest2.adUnitCode = 'adUnit_code_2';
- bidRequest2 = Object.assign({}, bidRequest2, videoData);
+ it('should set durations for placements when requireExactDuration is set and numbers are uneven', function () {
+ let bidRequest = Object.assign({},
+ bidRequests[0],
+ {
+ params: { placementId: '14542875' }
+ },
+ {
+ mediaTypes: {
+ video: {
+ context: 'adpod',
+ playerSize: [640, 480],
+ adPodDurationSec: 105,
+ durationRangeSec: [15, 30, 60],
+ requireExactDuration: true,
+ }
+ }
+ }
+ );
- const request = spec.buildRequests([bidRequest1, bidRequest2]);
- const payload = JSON.parse(request.data);
- expect(payload.tags[0].video).to.deep.equal({
- skippable: true,
- playback_method: 2,
- custom_renderer_present: true
+ const request = spec.buildRequests([bidRequest]);
+ const payload = JSON.parse(request.data);
+ expect(payload.tags.length).to.equal(7);
+
+ const tagsWith15 = payload.tags.filter(tag => tag.video.maxduration === 15);
+ const tagsWith30 = payload.tags.filter(tag => tag.video.maxduration === 30);
+ const tagsWith60 = payload.tags.filter(tag => tag.video.maxduration === 60);
+ expect(tagsWith15.length).to.equal(3);
+ expect(tagsWith30.length).to.equal(3);
+ expect(tagsWith60.length).to.equal(1);
});
- expect(payload.tags[1].video).to.deep.equal({
- skippable: true,
- playback_method: 2
+
+ it('should break adpod request into batches', function () {
+ let bidRequest = Object.assign({},
+ bidRequests[0],
+ {
+ params: { placementId: '14542875' }
+ },
+ {
+ mediaTypes: {
+ video: {
+ context: 'adpod',
+ playerSize: [640, 480],
+ adPodDurationSec: 225,
+ durationRangeSec: [5],
+ }
+ }
+ }
+ );
+
+ const request = spec.buildRequests([bidRequest]);
+ const payload1 = JSON.parse(request[0].data);
+ const payload2 = JSON.parse(request[1].data);
+ const payload3 = JSON.parse(request[2].data);
+
+ expect(payload1.tags.length).to.equal(15);
+ expect(payload2.tags.length).to.equal(15);
+ expect(payload3.tags.length).to.equal(15);
+ });
+
+ it('should contain hb_source value for adpod', function () {
+ let bidRequest = Object.assign({},
+ bidRequests[0],
+ {
+ params: { placementId: '14542875' }
+ },
+ {
+ mediaTypes: {
+ video: {
+ context: 'adpod',
+ playerSize: [640, 480],
+ adPodDurationSec: 300,
+ durationRangeSec: [15, 30],
+ }
+ }
+ }
+ );
+ const request = spec.buildRequests([bidRequest])[0];
+ const payload = JSON.parse(request.data);
+ expect(payload.tags[0].hb_source).to.deep.equal(7);
});
+ } // VIDEO
+
+ it('sends bid request to ENDPOINT via POST', function () {
+ const request = spec.buildRequests(bidRequests);
+ expect(request.url).to.equal(ENDPOINT);
+ expect(request.method).to.equal('POST');
});
it('should attach valid user params to the tag', function () {
@@ -486,185 +671,6 @@ describe('AppNexusAdapter', function () {
expect(payload.tags[0].reserve).to.exist.and.to.equal(3);
});
- it('should duplicate adpod placements into batches and set correct maxduration', function () {
- let bidRequest = Object.assign({},
- bidRequests[0],
- {
- params: { placement_id: '14542875' }
- },
- {
- mediaTypes: {
- video: {
- context: 'adpod',
- playerSize: [640, 480],
- adPodDurationSec: 300,
- durationRangeSec: [15, 30],
- }
- }
- }
- );
-
- const request = spec.buildRequests([bidRequest]);
- const payload1 = JSON.parse(request[0].data);
- const payload2 = JSON.parse(request[1].data);
-
- // 300 / 15 = 20 total
- expect(payload1.tags.length).to.equal(15);
- expect(payload2.tags.length).to.equal(5);
-
- expect(payload1.tags[0]).to.deep.equal(payload1.tags[1]);
- expect(payload1.tags[0].video.maxduration).to.equal(30);
-
- expect(payload2.tags[0]).to.deep.equal(payload1.tags[1]);
- expect(payload2.tags[0].video.maxduration).to.equal(30);
- });
-
- it('should round down adpod placements when numbers are uneven', function () {
- let bidRequest = Object.assign({},
- bidRequests[0],
- {
- params: { placement_id: '14542875' }
- },
- {
- mediaTypes: {
- video: {
- context: 'adpod',
- playerSize: [640, 480],
- adPodDurationSec: 123,
- durationRangeSec: [45],
- }
- }
- }
- );
-
- const request = spec.buildRequests([bidRequest]);
- const payload = JSON.parse(request.data);
- expect(payload.tags.length).to.equal(2);
- });
-
- it('should duplicate adpod placements when requireExactDuration is set', function () {
- let bidRequest = Object.assign({},
- bidRequests[0],
- {
- params: { placement_id: '14542875' }
- },
- {
- mediaTypes: {
- video: {
- context: 'adpod',
- playerSize: [640, 480],
- adPodDurationSec: 300,
- durationRangeSec: [15, 30],
- requireExactDuration: true,
- }
- }
- }
- );
-
- // 20 total placements with 15 max impressions = 2 requests
- const request = spec.buildRequests([bidRequest]);
- expect(request.length).to.equal(2);
-
- // 20 spread over 2 requests = 15 in first request, 5 in second
- const payload1 = JSON.parse(request[0].data);
- const payload2 = JSON.parse(request[1].data);
- expect(payload1.tags.length).to.equal(15);
- expect(payload2.tags.length).to.equal(5);
-
- // 10 placements should have max/min at 15
- // 10 placemenst should have max/min at 30
- const payload1tagsWith15 = payload1.tags.filter(tag => tag.video.maxduration === 15);
- const payload1tagsWith30 = payload1.tags.filter(tag => tag.video.maxduration === 30);
- expect(payload1tagsWith15.length).to.equal(10);
- expect(payload1tagsWith30.length).to.equal(5);
-
- // 5 placemenst with min/max at 30 were in the first request
- // so 5 remaining should be in the second
- const payload2tagsWith30 = payload2.tags.filter(tag => tag.video.maxduration === 30);
- expect(payload2tagsWith30.length).to.equal(5);
- });
-
- it('should set durations for placements when requireExactDuration is set and numbers are uneven', function () {
- let bidRequest = Object.assign({},
- bidRequests[0],
- {
- params: { placement_id: '14542875' }
- },
- {
- mediaTypes: {
- video: {
- context: 'adpod',
- playerSize: [640, 480],
- adPodDurationSec: 105,
- durationRangeSec: [15, 30, 60],
- requireExactDuration: true,
- }
- }
- }
- );
-
- const request = spec.buildRequests([bidRequest]);
- const payload = JSON.parse(request.data);
- expect(payload.tags.length).to.equal(7);
-
- const tagsWith15 = payload.tags.filter(tag => tag.video.maxduration === 15);
- const tagsWith30 = payload.tags.filter(tag => tag.video.maxduration === 30);
- const tagsWith60 = payload.tags.filter(tag => tag.video.maxduration === 60);
- expect(tagsWith15.length).to.equal(3);
- expect(tagsWith30.length).to.equal(3);
- expect(tagsWith60.length).to.equal(1);
- });
-
- it('should break adpod request into batches', function () {
- let bidRequest = Object.assign({},
- bidRequests[0],
- {
- params: { placement_id: '14542875' }
- },
- {
- mediaTypes: {
- video: {
- context: 'adpod',
- playerSize: [640, 480],
- adPodDurationSec: 225,
- durationRangeSec: [5],
- }
- }
- }
- );
-
- const request = spec.buildRequests([bidRequest]);
- const payload1 = JSON.parse(request[0].data);
- const payload2 = JSON.parse(request[1].data);
- const payload3 = JSON.parse(request[2].data);
-
- expect(payload1.tags.length).to.equal(15);
- expect(payload2.tags.length).to.equal(15);
- expect(payload3.tags.length).to.equal(15);
- });
-
- it('should contain hb_source value for adpod', function () {
- let bidRequest = Object.assign({},
- bidRequests[0],
- {
- params: { placement_id: '14542875' }
- },
- {
- mediaTypes: {
- video: {
- context: 'adpod',
- playerSize: [640, 480],
- adPodDurationSec: 300,
- durationRangeSec: [15, 30],
- }
- }
- }
- );
- const request = spec.buildRequests([bidRequest])[0];
- const payload = JSON.parse(request.data);
- expect(payload.tags[0].hb_source).to.deep.equal(7);
- });
-
it('should contain hb_source value for other media', function () {
let bidRequest = Object.assign({},
bidRequests[0],
@@ -1392,27 +1398,31 @@ describe('AppNexusAdapter', function () {
});
it('should populate iab_support object at the root level if omid support is detected', function () {
- // with bid.params.frameworks
- let bidRequest_A = Object.assign({}, bidRequests[0], {
- params: {
- frameworks: [1, 2, 5, 6],
- video: {
- frameworks: [1, 2, 5, 6]
+ let request, payload;
+
+ if (FEATURES.VIDEO) {
+ // with bid.params.frameworks
+ let bidRequest_A = Object.assign({}, bidRequests[0], {
+ params: {
+ frameworks: [1, 2, 5, 6],
+ video: {
+ frameworks: [1, 2, 5, 6]
+ }
}
- }
- });
- let request = spec.buildRequests([bidRequest_A]);
- let payload = JSON.parse(request.data);
- expect(payload.iab_support).to.be.an('object');
- expect(payload.iab_support).to.deep.equal({
- omidpn: 'Appnexus',
- omidpv: '$prebid.version$'
- });
- expect(payload.tags[0].banner_frameworks).to.be.an('array');
- expect(payload.tags[0].banner_frameworks).to.deep.equal([1, 2, 5, 6]);
- expect(payload.tags[0].video_frameworks).to.be.an('array');
- expect(payload.tags[0].video_frameworks).to.deep.equal([1, 2, 5, 6]);
- expect(payload.tags[0].video.frameworks).to.not.exist;
+ });
+ request = spec.buildRequests([bidRequest_A]);
+ payload = JSON.parse(request.data);
+ expect(payload.iab_support).to.be.an('object');
+ expect(payload.iab_support).to.deep.equal({
+ omidpn: 'Appnexus',
+ omidpv: '$prebid.version$'
+ });
+ expect(payload.tags[0].banner_frameworks).to.be.an('array');
+ expect(payload.tags[0].banner_frameworks).to.deep.equal([1, 2, 5, 6]);
+ expect(payload.tags[0].video_frameworks).to.be.an('array');
+ expect(payload.tags[0].video_frameworks).to.deep.equal([1, 2, 5, 6]);
+ expect(payload.tags[0].video.frameworks).to.not.exist;
+ }
// without bid.params.frameworks
const bidRequest_B = Object.assign({}, bidRequests[0]);
@@ -1422,19 +1432,21 @@ describe('AppNexusAdapter', function () {
expect(payload.tags[0].banner_frameworks).to.not.exist;
expect(payload.tags[0].video_frameworks).to.not.exist;
- // with video.frameworks but it is not an array
- const bidRequest_C = Object.assign({}, bidRequests[0], {
- params: {
- video: {
- frameworks: "'1', '2', '3', '6'"
+ if (FEATURES.VIDEO) {
+ // with video.frameworks but it is not an array
+ const bidRequest_C = Object.assign({}, bidRequests[0], {
+ params: {
+ video: {
+ frameworks: "'1', '2', '3', '6'"
+ }
}
- }
- });
- request = spec.buildRequests([bidRequest_C]);
- payload = JSON.parse(request.data);
- expect(payload.iab_support).to.not.exist;
- expect(payload.tags[0].banner_frameworks).to.not.exist;
- expect(payload.tags[0].video_frameworks).to.not.exist;
+ });
+ request = spec.buildRequests([bidRequest_C]);
+ payload = JSON.parse(request.data);
+ expect(payload.iab_support).to.not.exist;
+ expect(payload.tags[0].banner_frameworks).to.not.exist;
+ expect(payload.tags[0].video_frameworks).to.not.exist;
+ }
});
})
@@ -1591,116 +1603,118 @@ describe('AppNexusAdapter', function () {
expect(result.length).to.equal(0);
});
- it('handles outstream video responses', function () {
- let response = {
- 'tags': [{
- 'uuid': '84ab500420319d',
- 'ads': [{
- 'ad_type': 'video',
- 'cpm': 0.500000,
- 'notify_url': 'imptracker.com',
- 'rtb': {
- 'video': {
- 'content': ''
- }
- },
- 'javascriptTrackers': ''
+ if (FEATURES.VIDEO) {
+ it('handles outstream video responses', function () {
+ let response = {
+ 'tags': [{
+ 'uuid': '84ab500420319d',
+ 'ads': [{
+ 'ad_type': 'video',
+ 'cpm': 0.500000,
+ 'notify_url': 'imptracker.com',
+ 'rtb': {
+ 'video': {
+ 'content': ''
+ }
+ },
+ 'javascriptTrackers': ''
+ }]
}]
- }]
- };
- let bidderRequest = {
- bids: [{
- bidId: '84ab500420319d',
- adUnitCode: 'code',
- mediaTypes: {
- video: {
- context: 'outstream'
+ };
+ let bidderRequest = {
+ bids: [{
+ bidId: '84ab500420319d',
+ adUnitCode: 'code',
+ mediaTypes: {
+ video: {
+ context: 'outstream'
+ }
}
- }
- }]
- }
+ }]
+ }
- let result = spec.interpretResponse({ body: response }, { bidderRequest });
- expect(result[0]).to.have.property('vastXml');
- expect(result[0]).to.have.property('vastImpUrl');
- expect(result[0]).to.have.property('mediaType', 'video');
- });
+ let result = spec.interpretResponse({ body: response }, { bidderRequest });
+ expect(result[0]).to.have.property('vastXml');
+ expect(result[0]).to.have.property('vastImpUrl');
+ expect(result[0]).to.have.property('mediaType', 'video');
+ });
- it('handles instream video responses', function () {
- let response = {
- 'tags': [{
- 'uuid': '84ab500420319d',
- 'ads': [{
- 'ad_type': 'video',
- 'cpm': 0.500000,
- 'notify_url': 'imptracker.com',
- 'rtb': {
- 'video': {
- 'asset_url': 'https://sample.vastURL.com/here/vid'
- }
- },
- 'javascriptTrackers': ''
+ it('handles instream video responses', function () {
+ let response = {
+ 'tags': [{
+ 'uuid': '84ab500420319d',
+ 'ads': [{
+ 'ad_type': 'video',
+ 'cpm': 0.500000,
+ 'notify_url': 'imptracker.com',
+ 'rtb': {
+ 'video': {
+ 'asset_url': 'https://sample.vastURL.com/here/vid'
+ }
+ },
+ 'javascriptTrackers': ''
+ }]
}]
- }]
- };
- let bidderRequest = {
- bids: [{
- bidId: '84ab500420319d',
- adUnitCode: 'code',
- mediaTypes: {
- video: {
- context: 'instream'
+ };
+ let bidderRequest = {
+ bids: [{
+ bidId: '84ab500420319d',
+ adUnitCode: 'code',
+ mediaTypes: {
+ video: {
+ context: 'instream'
+ }
}
- }
- }]
- }
+ }]
+ }
- let result = spec.interpretResponse({ body: response }, { bidderRequest });
- expect(result[0]).to.have.property('vastUrl');
- expect(result[0]).to.have.property('vastImpUrl');
- expect(result[0]).to.have.property('mediaType', 'video');
- });
+ let result = spec.interpretResponse({ body: response }, { bidderRequest });
+ expect(result[0]).to.have.property('vastUrl');
+ expect(result[0]).to.have.property('vastImpUrl');
+ expect(result[0]).to.have.property('mediaType', 'video');
+ });
- it('handles adpod responses', function () {
- let response = {
- 'tags': [{
- 'uuid': '84ab500420319d',
- 'ads': [{
- 'ad_type': 'video',
- 'brand_category_id': 10,
- 'cpm': 0.500000,
- 'notify_url': 'imptracker.com',
- 'rtb': {
- 'video': {
- 'asset_url': 'https://sample.vastURL.com/here/adpod',
- 'duration_ms': 30000,
+ it('handles adpod responses', function () {
+ let response = {
+ 'tags': [{
+ 'uuid': '84ab500420319d',
+ 'ads': [{
+ 'ad_type': 'video',
+ 'brand_category_id': 10,
+ 'cpm': 0.500000,
+ 'notify_url': 'imptracker.com',
+ 'rtb': {
+ 'video': {
+ 'asset_url': 'https://sample.vastURL.com/here/adpod',
+ 'duration_ms': 30000,
+ }
+ },
+ 'viewability': {
+ 'config': ''
}
- },
- 'viewability': {
- 'config': ''
- }
+ }]
}]
- }]
- };
+ };
- let bidderRequest = {
- bids: [{
- bidId: '84ab500420319d',
- adUnitCode: 'code',
- mediaTypes: {
- video: {
- context: 'adpod'
+ let bidderRequest = {
+ bids: [{
+ bidId: '84ab500420319d',
+ adUnitCode: 'code',
+ mediaTypes: {
+ video: {
+ context: 'adpod'
+ }
}
- }
- }]
- };
- bfStub.returns('1');
+ }]
+ };
+ bfStub.returns('1');
- let result = spec.interpretResponse({ body: response }, { bidderRequest });
- expect(result[0]).to.have.property('vastUrl');
- expect(result[0].video.context).to.equal('adpod');
- expect(result[0].video.durationSeconds).to.equal(30);
- });
+ let result = spec.interpretResponse({ body: response }, { bidderRequest });
+ expect(result[0]).to.have.property('vastUrl');
+ expect(result[0].video.context).to.equal('adpod');
+ expect(result[0].video.durationSeconds).to.equal(30);
+ });
+ }
if (FEATURES.NATIVE) {
it('handles native responses', function () {
@@ -1758,59 +1772,61 @@ describe('AppNexusAdapter', function () {
});
}
- it('supports configuring outstream renderers', function () {
- const outstreamResponse = deepClone(response);
- outstreamResponse.tags[0].ads[0].rtb.video = {};
- outstreamResponse.tags[0].ads[0].renderer_url = 'renderer.js';
+ if (FEATURES.VIDEO) {
+ it('supports configuring outstream renderers', function () {
+ const outstreamResponse = deepClone(response);
+ outstreamResponse.tags[0].ads[0].rtb.video = {};
+ outstreamResponse.tags[0].ads[0].renderer_url = 'renderer.js';
- const bidderRequest = {
- bids: [{
- bidId: '3db3773286ee59',
- renderer: {
- options: {
- adText: 'configured'
- }
- },
- mediaTypes: {
- video: {
- context: 'outstream'
+ const bidderRequest = {
+ bids: [{
+ bidId: '3db3773286ee59',
+ renderer: {
+ options: {
+ adText: 'configured'
+ }
+ },
+ mediaTypes: {
+ video: {
+ context: 'outstream'
+ }
}
- }
- }]
- };
+ }]
+ };
- const result = spec.interpretResponse({ body: outstreamResponse }, { bidderRequest });
- expect(result[0].renderer.config).to.deep.equal(
- bidderRequest.bids[0].renderer.options
- );
- });
+ const result = spec.interpretResponse({ body: outstreamResponse }, { bidderRequest });
+ expect(result[0].renderer.config).to.deep.equal(
+ bidderRequest.bids[0].renderer.options
+ );
+ });
- it('should add deal_priority and deal_code', function () {
- let responseWithDeal = deepClone(response);
- responseWithDeal.tags[0].ads[0].ad_type = 'video';
- responseWithDeal.tags[0].ads[0].deal_priority = 5;
- responseWithDeal.tags[0].ads[0].deal_code = '123';
- responseWithDeal.tags[0].ads[0].rtb.video = {
- duration_ms: 1500,
- player_width: 640,
- player_height: 340,
- };
+ it('should add deal_priority and deal_code', function () {
+ let responseWithDeal = deepClone(response);
+ responseWithDeal.tags[0].ads[0].ad_type = 'video';
+ responseWithDeal.tags[0].ads[0].deal_priority = 5;
+ responseWithDeal.tags[0].ads[0].deal_code = '123';
+ responseWithDeal.tags[0].ads[0].rtb.video = {
+ duration_ms: 1500,
+ player_width: 640,
+ player_height: 340,
+ };
- let bidderRequest = {
- bids: [{
- bidId: '3db3773286ee59',
- adUnitCode: 'code',
- mediaTypes: {
- video: {
- context: 'adpod'
+ let bidderRequest = {
+ bids: [{
+ bidId: '3db3773286ee59',
+ adUnitCode: 'code',
+ mediaTypes: {
+ video: {
+ context: 'adpod'
+ }
}
- }
- }]
- }
- let result = spec.interpretResponse({ body: responseWithDeal }, { bidderRequest });
- expect(Object.keys(result[0].appnexus)).to.include.members(['buyerMemberId', 'dealPriority', 'dealCode']);
- expect(result[0].video.dealTier).to.equal(5);
- });
+ }]
+ }
+ let result = spec.interpretResponse({ body: responseWithDeal }, { bidderRequest });
+ expect(Object.keys(result[0].appnexus)).to.include.members(['buyerMemberId', 'dealPriority', 'dealCode']);
+ expect(result[0].video.dealTier).to.equal(5);
+ });
+ }
it('should add advertiser id', function () {
let responseAdvertiserId = deepClone(response);
diff --git a/test/spec/modules/axonixBidAdapter_spec.js b/test/spec/modules/axonixBidAdapter_spec.js
index 37f409e5769..c1cc6d46fb2 100644
--- a/test/spec/modules/axonixBidAdapter_spec.js
+++ b/test/spec/modules/axonixBidAdapter_spec.js
@@ -286,26 +286,6 @@ describe('AxonixBidAdapter', function () {
});
});
- describe.skip('buildRequests: can handle native ad requests', function () {
- it('creates ServerRequests pointing to the correct region and endpoint if it changes', function () {
- // loop:
- // set supply id
- // set region/endpoint in ssp config
- // call buildRequests, validate request (url, method, supply id)
- expect.fail('Not implemented');
- });
-
- it('creates ServerRequests pointing to default endpoint if missing', function () {
- // no endpoint in config means default value openrtb.axonix.com
- expect.fail('Not implemented');
- });
-
- it('creates ServerRequests pointing to default region if missing', function () {
- // no region in config means default value us-east-1
- expect.fail('Not implemented');
- });
- });
-
describe('interpretResponse', function () {
it('considers corner cases', function() {
expect(spec.interpretResponse(null)).to.be.an('array').that.is.empty;
@@ -331,13 +311,6 @@ describe('AxonixBidAdapter', function () {
expect(response).to.be.an('array').that.is.not.empty;
expect(response[0]).to.equal(VIDEO_RESPONSE.body[0]);
});
-
- it.skip('parses 1 native responses', function () {
- // passing 1 valid native in a response generates an array with 1 correct prebid response
- // examine mediaType:native, native element
- // check nativeBidIsValid from {@link file://./../../../src/native.js}
- expect.fail('Not implemented');
- });
});
describe('onBidWon', function () {
diff --git a/test/spec/modules/big-richmediaBidAdapter_spec.js b/test/spec/modules/big-richmediaBidAdapter_spec.js
index b2ee0725d49..f01e261ef9f 100644
--- a/test/spec/modules/big-richmediaBidAdapter_spec.js
+++ b/test/spec/modules/big-richmediaBidAdapter_spec.js
@@ -92,40 +92,42 @@ describe('bigRichMediaAdapterTests', function () {
expect(payload.tags[0].sizes).to.have.lengthOf(3);
});
- it('should build video bid request', function() {
- const bidRequest = deepClone(bidRequests[0]);
- bidRequest.params = {
- placementId: '1234235',
- video: {
- skippable: true,
- playback_method: ['auto_play_sound_off', 'auto_play_sound_unknown'],
- context: 'outstream',
- format: 'sticky-top'
- }
- };
- bidRequest.mediaTypes = {
- video: {
- playerSize: [640, 480],
- context: 'outstream',
- mimes: ['video/mp4'],
- skip: 0,
- minduration: 5,
- api: [1, 5, 6],
- playbackmethod: [2, 4]
- }
- };
+ if (FEATURES.VIDEO) {
+ it('should build video bid request', function() {
+ const bidRequest = deepClone(bidRequests[0]);
+ bidRequest.params = {
+ placementId: '1234235',
+ video: {
+ skippable: true,
+ playback_method: ['auto_play_sound_off', 'auto_play_sound_unknown'],
+ context: 'outstream',
+ format: 'sticky-top'
+ }
+ };
+ bidRequest.mediaTypes = {
+ video: {
+ playerSize: [640, 480],
+ context: 'outstream',
+ mimes: ['video/mp4'],
+ skip: 0,
+ minduration: 5,
+ api: [1, 5, 6],
+ playbackmethod: [2, 4]
+ }
+ };
- const request = spec.buildRequests([bidRequest]);
- const payload = JSON.parse(request.data);
+ const request = spec.buildRequests([bidRequest]);
+ const payload = JSON.parse(request.data);
- expect(payload.tags[0].video).to.deep.equal({
- minduration: 5,
- playback_method: 2,
- skippable: true,
- context: 4
+ expect(payload.tags[0].video).to.deep.equal({
+ minduration: 5,
+ playback_method: 2,
+ skippable: true,
+ context: 4
+ });
+ expect(payload.tags[0].video_frameworks).to.deep.equal([1, 4])
});
- expect(payload.tags[0].video_frameworks).to.deep.equal([1, 4])
- });
+ }
});
describe('interpretResponse', function () {
@@ -227,42 +229,44 @@ describe('bigRichMediaAdapterTests', function () {
expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0]));
});
- it('handles outstream video responses', function () {
- const response = {
- 'tags': [{
- 'uuid': '84ab500420319d',
- 'ads': [{
- 'ad_type': 'video',
- 'cpm': 0.500000,
- 'notify_url': 'imptracker.com',
- 'rtb': {
- 'video': {
- 'content': ''
- }
- },
- 'javascriptTrackers': ''
+ if (FEATURES.VIDEO) {
+ it('handles outstream video responses', function () {
+ const response = {
+ 'tags': [{
+ 'uuid': '84ab500420319d',
+ 'ads': [{
+ 'ad_type': 'video',
+ 'cpm': 0.500000,
+ 'notify_url': 'imptracker.com',
+ 'rtb': {
+ 'video': {
+ 'content': ''
+ }
+ },
+ 'javascriptTrackers': ''
+ }]
}]
- }]
- };
- const bidderRequest = {
- bids: [{
- bidId: '84ab500420319d',
- adUnitCode: 'code',
- mediaTypes: {
- video: {
- context: 'outstream'
+ };
+ const bidderRequest = {
+ bids: [{
+ bidId: '84ab500420319d',
+ adUnitCode: 'code',
+ mediaTypes: {
+ video: {
+ context: 'outstream'
+ }
}
- }
- }]
- }
+ }]
+ }
- const result = spec.interpretResponse({ body: response }, {bidderRequest});
- expect(result[0]).not.to.have.property('vastXml');
- expect(result[0]).not.to.have.property('vastUrl');
- expect(result[0]).to.have.property('width', 1);
- expect(result[0]).to.have.property('height', 1);
- expect(result[0]).to.have.property('mediaType', 'banner');
- });
+ const result = spec.interpretResponse({ body: response }, {bidderRequest});
+ expect(result[0]).not.to.have.property('vastXml');
+ expect(result[0]).not.to.have.property('vastUrl');
+ expect(result[0]).to.have.property('width', 1);
+ expect(result[0]).to.have.property('height', 1);
+ expect(result[0]).to.have.property('mediaType', 'banner');
+ });
+ }
});
describe('getUserSyncs', function() {
diff --git a/test/spec/modules/conversantBidAdapter_spec.js b/test/spec/modules/conversantBidAdapter_spec.js
index 261414f336d..bda5d8daca7 100644
--- a/test/spec/modules/conversantBidAdapter_spec.js
+++ b/test/spec/modules/conversantBidAdapter_spec.js
@@ -263,6 +263,7 @@ describe('Conversant adapter tests', function() {
const payload = request.data;
expect(payload).to.have.property('id', 'req000');
+ expect(payload.source).to.have.property('tid', 'req000');
expect(payload).to.have.property('at', 1);
expect(payload).to.have.property('imp');
expect(payload.imp).to.be.an('array').with.lengthOf(8);
diff --git a/test/spec/modules/emtvBidAdapter_spec.js b/test/spec/modules/emtvBidAdapter_spec.js
new file mode 100644
index 00000000000..4f95a0cc094
--- /dev/null
+++ b/test/spec/modules/emtvBidAdapter_spec.js
@@ -0,0 +1,400 @@
+import { expect } from 'chai';
+import { spec } from '../../../modules/emtvBidAdapter.js';
+import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js';
+import { getUniqueIdentifierStr } from '../../../src/utils.js';
+
+const bidder = 'emtv'
+const adUrl = 'https://us-east-ep.engagemedia.tv/pbjs';
+const syncUrl = 'https://cs.engagemedia.tv';
+
+describe('EMTVBidAdapter', function () {
+ const bids = [
+ {
+ bidId: getUniqueIdentifierStr(),
+ bidder: bidder,
+ mediaTypes: {
+ [BANNER]: {
+ sizes: [[300, 250]]
+ }
+ },
+ params: {
+ placementId: 'testBanner',
+ }
+ },
+ {
+ bidId: getUniqueIdentifierStr(),
+ bidder: bidder,
+ mediaTypes: {
+ [VIDEO]: {
+ playerSize: [[300, 300]],
+ minduration: 5,
+ maxduration: 60
+ }
+ },
+ params: {
+ placementId: 'testVideo',
+ }
+ },
+ {
+ bidId: getUniqueIdentifierStr(),
+ bidder: bidder,
+ mediaTypes: {
+ [NATIVE]: {
+ native: {
+ title: {
+ required: true
+ },
+ body: {
+ required: true
+ },
+ icon: {
+ required: true,
+ size: [64, 64]
+ }
+ }
+ }
+ },
+ params: {
+ placementId: 'testNative',
+ }
+ }
+ ];
+
+ const invalidBid = {
+ bidId: getUniqueIdentifierStr(),
+ bidder: bidder,
+ mediaTypes: {
+ [BANNER]: {
+ sizes: [[300, 250]]
+ }
+ },
+ params: {
+
+ }
+ }
+
+ const bidderRequest = {
+ uspConsent: '1---',
+ gdprConsent: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw',
+ refererInfo: {
+ referer: 'https://test.com'
+ }
+ };
+
+ describe('isBidRequestValid', function () {
+ it('Should return true if there are bidId, params and key parameters present', function () {
+ expect(spec.isBidRequestValid(bids[0])).to.be.true;
+ });
+ it('Should return false if at least one of parameters is not present', function () {
+ expect(spec.isBidRequestValid(invalidBid)).to.be.false;
+ });
+ });
+
+ describe('buildRequests', function () {
+ let serverRequest = spec.buildRequests(bids, bidderRequest);
+
+ it('Creates a ServerRequest object with method, URL and data', function () {
+ expect(serverRequest).to.exist;
+ expect(serverRequest.method).to.exist;
+ expect(serverRequest.url).to.exist;
+ expect(serverRequest.data).to.exist;
+ });
+
+ it('Returns POST method', function () {
+ expect(serverRequest.method).to.equal('POST');
+ });
+
+ it('Returns valid URL', function () {
+ expect(serverRequest.url).to.equal(adUrl);
+ });
+
+ it('Returns general data valid', function () {
+ let data = serverRequest.data;
+ expect(data).to.be.an('object');
+ expect(data).to.have.all.keys('deviceWidth',
+ 'deviceHeight',
+ 'language',
+ 'secure',
+ 'host',
+ 'page',
+ 'placements',
+ 'coppa',
+ 'ccpa',
+ 'gdpr',
+ 'tmax'
+ );
+ expect(data.deviceWidth).to.be.a('number');
+ expect(data.deviceHeight).to.be.a('number');
+ expect(data.language).to.be.a('string');
+ expect(data.secure).to.be.within(0, 1);
+ expect(data.host).to.be.a('string');
+ expect(data.page).to.be.a('string');
+ expect(data.coppa).to.be.a('number');
+ expect(data.gdpr).to.be.a('string');
+ expect(data.ccpa).to.be.a('string');
+ expect(data.tmax).to.be.a('number');
+ expect(data.placements).to.have.lengthOf(3);
+ });
+
+ it('Returns valid placements', function () {
+ const { placements } = serverRequest.data;
+ for (let i = 0, len = placements.length; i < len; i++) {
+ const placement = placements[i];
+ expect(placement.placementId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']);
+ expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]);
+ expect(placement.bidId).to.be.a('string');
+ expect(placement.schain).to.be.an('object');
+ expect(placement.bidfloor).to.exist.and.to.equal(0);
+ expect(placement.type).to.exist.and.to.equal('publisher');
+
+ if (placement.adFormat === BANNER) {
+ expect(placement.sizes).to.be.an('array');
+ }
+ switch (placement.adFormat) {
+ case BANNER:
+ expect(placement.sizes).to.be.an('array');
+ break;
+ case VIDEO:
+ expect(placement.playerSize).to.be.an('array');
+ expect(placement.minduration).to.be.an('number');
+ expect(placement.maxduration).to.be.an('number');
+ break;
+ case NATIVE:
+ expect(placement.native).to.be.an('object');
+ break;
+ }
+ }
+ });
+
+ it('Returns data with gdprConsent and without uspConsent', function () {
+ delete bidderRequest.uspConsent;
+ serverRequest = spec.buildRequests(bids, bidderRequest);
+ let data = serverRequest.data;
+ expect(data.gdpr).to.exist;
+ expect(data.gdpr).to.be.a('string');
+ expect(data.gdpr).to.equal(bidderRequest.gdprConsent);
+ expect(data.ccpa).to.not.exist;
+ delete bidderRequest.gdprConsent;
+ });
+
+ it('Returns data with uspConsent and without gdprConsent', function () {
+ bidderRequest.uspConsent = '1---';
+ delete bidderRequest.gdprConsent;
+ serverRequest = spec.buildRequests(bids, bidderRequest);
+ let data = serverRequest.data;
+ expect(data.ccpa).to.exist;
+ expect(data.ccpa).to.be.a('string');
+ expect(data.ccpa).to.equal(bidderRequest.uspConsent);
+ expect(data.gdpr).to.not.exist;
+ });
+
+ it('Returns empty data if no valid requests are passed', function () {
+ serverRequest = spec.buildRequests([], bidderRequest);
+ let data = serverRequest.data;
+ expect(data.placements).to.be.an('array').that.is.empty;
+ });
+ });
+
+ describe('interpretResponse', function () {
+ it('Should interpret banner response', function () {
+ const banner = {
+ body: [{
+ mediaType: 'banner',
+ width: 300,
+ height: 250,
+ cpm: 0.4,
+ ad: 'Test',
+ requestId: '23fhj33i987f',
+ ttl: 120,
+ creativeId: '2',
+ netRevenue: true,
+ currency: 'USD',
+ dealId: '1',
+ meta: {
+ advertiserDomains: ['google.com'],
+ advertiserId: 1234
+ }
+ }]
+ };
+ let bannerResponses = spec.interpretResponse(banner);
+ expect(bannerResponses).to.be.an('array').that.is.not.empty;
+ let dataItem = bannerResponses[0];
+ expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId',
+ 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta');
+ expect(dataItem.requestId).to.equal(banner.body[0].requestId);
+ expect(dataItem.cpm).to.equal(banner.body[0].cpm);
+ expect(dataItem.width).to.equal(banner.body[0].width);
+ expect(dataItem.height).to.equal(banner.body[0].height);
+ expect(dataItem.ad).to.equal(banner.body[0].ad);
+ expect(dataItem.ttl).to.equal(banner.body[0].ttl);
+ expect(dataItem.creativeId).to.equal(banner.body[0].creativeId);
+ expect(dataItem.netRevenue).to.be.true;
+ expect(dataItem.currency).to.equal(banner.body[0].currency);
+ expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains');
+ });
+ it('Should interpret video response', function () {
+ const video = {
+ body: [{
+ vastUrl: 'test.com',
+ mediaType: 'video',
+ cpm: 0.5,
+ requestId: '23fhj33i987f',
+ ttl: 120,
+ creativeId: '2',
+ netRevenue: true,
+ currency: 'USD',
+ dealId: '1',
+ meta: {
+ advertiserDomains: ['google.com'],
+ advertiserId: 1234
+ }
+ }]
+ };
+ let videoResponses = spec.interpretResponse(video);
+ expect(videoResponses).to.be.an('array').that.is.not.empty;
+
+ let dataItem = videoResponses[0];
+ expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId',
+ 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta');
+ expect(dataItem.requestId).to.equal('23fhj33i987f');
+ expect(dataItem.cpm).to.equal(0.5);
+ expect(dataItem.vastUrl).to.equal('test.com');
+ expect(dataItem.ttl).to.equal(120);
+ expect(dataItem.creativeId).to.equal('2');
+ expect(dataItem.netRevenue).to.be.true;
+ expect(dataItem.currency).to.equal('USD');
+ expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains');
+ });
+ it('Should interpret native response', function () {
+ const native = {
+ body: [{
+ mediaType: 'native',
+ native: {
+ clickUrl: 'test.com',
+ title: 'Test',
+ image: 'test.com',
+ impressionTrackers: ['test.com'],
+ },
+ ttl: 120,
+ cpm: 0.4,
+ requestId: '23fhj33i987f',
+ creativeId: '2',
+ netRevenue: true,
+ currency: 'USD',
+ meta: {
+ advertiserDomains: ['google.com'],
+ advertiserId: 1234
+ }
+ }]
+ };
+ let nativeResponses = spec.interpretResponse(native);
+ expect(nativeResponses).to.be.an('array').that.is.not.empty;
+
+ let dataItem = nativeResponses[0];
+ expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native', 'meta');
+ expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image')
+ expect(dataItem.requestId).to.equal('23fhj33i987f');
+ expect(dataItem.cpm).to.equal(0.4);
+ expect(dataItem.native.clickUrl).to.equal('test.com');
+ expect(dataItem.native.title).to.equal('Test');
+ expect(dataItem.native.image).to.equal('test.com');
+ expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty;
+ expect(dataItem.native.impressionTrackers[0]).to.equal('test.com');
+ expect(dataItem.ttl).to.equal(120);
+ expect(dataItem.creativeId).to.equal('2');
+ expect(dataItem.netRevenue).to.be.true;
+ expect(dataItem.currency).to.equal('USD');
+ expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains');
+ });
+ it('Should return an empty array if invalid banner response is passed', function () {
+ const invBanner = {
+ body: [{
+ width: 300,
+ cpm: 0.4,
+ ad: 'Test',
+ requestId: '23fhj33i987f',
+ ttl: 120,
+ creativeId: '2',
+ netRevenue: true,
+ currency: 'USD',
+ dealId: '1'
+ }]
+ };
+
+ let serverResponses = spec.interpretResponse(invBanner);
+ expect(serverResponses).to.be.an('array').that.is.empty;
+ });
+ it('Should return an empty array if invalid video response is passed', function () {
+ const invVideo = {
+ body: [{
+ mediaType: 'video',
+ cpm: 0.5,
+ requestId: '23fhj33i987f',
+ ttl: 120,
+ creativeId: '2',
+ netRevenue: true,
+ currency: 'USD',
+ dealId: '1'
+ }]
+ };
+ let serverResponses = spec.interpretResponse(invVideo);
+ expect(serverResponses).to.be.an('array').that.is.empty;
+ });
+ it('Should return an empty array if invalid native response is passed', function () {
+ const invNative = {
+ body: [{
+ mediaType: 'native',
+ clickUrl: 'test.com',
+ title: 'Test',
+ impressionTrackers: ['test.com'],
+ ttl: 120,
+ requestId: '23fhj33i987f',
+ creativeId: '2',
+ netRevenue: true,
+ currency: 'USD',
+ }]
+ };
+ let serverResponses = spec.interpretResponse(invNative);
+ expect(serverResponses).to.be.an('array').that.is.empty;
+ });
+ it('Should return an empty array if invalid response is passed', function () {
+ const invalid = {
+ body: [{
+ ttl: 120,
+ creativeId: '2',
+ netRevenue: true,
+ currency: 'USD',
+ dealId: '1'
+ }]
+ };
+ let serverResponses = spec.interpretResponse(invalid);
+ expect(serverResponses).to.be.an('array').that.is.empty;
+ });
+ });
+
+ describe('getUserSyncs', function() {
+ it('Should return array of objects with proper sync config , include GDPR', function() {
+ const syncData = spec.getUserSyncs({}, {}, {
+ consentString: 'ALL',
+ gdprApplies: true,
+ }, {});
+ expect(syncData).to.be.an('array').which.is.not.empty;
+ expect(syncData[0]).to.be.an('object')
+ expect(syncData[0].type).to.be.a('string')
+ expect(syncData[0].type).to.equal('image')
+ expect(syncData[0].url).to.be.a('string')
+ expect(syncData[0].url).to.equal(`${syncUrl}/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0`)
+ });
+ it('Should return array of objects with proper sync config , include CCPA', function() {
+ const syncData = spec.getUserSyncs({}, {}, {}, {
+ consentString: '1---'
+ });
+ expect(syncData).to.be.an('array').which.is.not.empty;
+ expect(syncData[0]).to.be.an('object')
+ expect(syncData[0].type).to.be.a('string')
+ expect(syncData[0].type).to.equal('image')
+ expect(syncData[0].url).to.be.a('string')
+ expect(syncData[0].url).to.equal(`${syncUrl}/image?pbjs=1&ccpa_consent=1---&coppa=0`)
+ });
+ });
+});
diff --git a/test/spec/modules/eskimiBidAdapter_spec.js b/test/spec/modules/eskimiBidAdapter_spec.js
new file mode 100644
index 00000000000..4622b374de5
--- /dev/null
+++ b/test/spec/modules/eskimiBidAdapter_spec.js
@@ -0,0 +1,155 @@
+import {expect} from 'chai';
+import {spec} from 'modules/eskimiBidAdapter.js';
+
+const REQUEST = {
+ 'bidderCode': 'eskimi',
+ 'auctionId': 'auctionId-56a2-4f71-9098-720a68f2f708',
+ 'bidderRequestId': 'requestId',
+ 'bidRequest': [{
+ 'bidder': 'eskimi',
+ 'params': {
+ 'placementId': 1003000,
+ 'accId': 123
+ },
+ 'sizes': [
+ [300, 250]
+ ],
+ 'bidId': 'bidId1',
+ 'adUnitCode': 'adUnitCode1',
+ 'bidderRequestId': 'bidderRequestId',
+ 'auctionId': 'auctionId-56a2-4f71-9098-720a68f2f708'
+ },
+ {
+ 'bidder': 'eskimi',
+ 'params': {
+ 'placementId': 1003001,
+ 'accId': 123
+ },
+ 'sizes': [
+ [300, 250]
+ ],
+ 'bidId': 'bidId2',
+ 'adUnitCode': 'adUnitCode2',
+ 'bidderRequestId': 'bidderRequestId',
+ 'auctionId': 'auctionId-56a2-4f71-9098-720a68f2f708'
+ }],
+ 'start': 1487883186070,
+ 'auctionStart': 1487883186069,
+ 'timeout': 3000
+};
+
+const RESPONSE = {
+ 'headers': null,
+ 'body': {
+ 'id': 'requestId',
+ 'seatbid': [
+ {
+ 'bid': [
+ {
+ 'id': 'bidId1',
+ 'impid': 'bidId1',
+ 'price': 0.18,
+ 'adm': '',
+ 'adid': '144762342',
+ 'adomain': [
+ 'https://dummydomain.com'
+ ],
+ 'iurl': 'iurl',
+ 'cid': '109',
+ 'crid': 'creativeId',
+ 'cat': [],
+ 'w': 300,
+ 'h': 250,
+ 'ext': {
+ 'prebid': {
+ 'type': 'banner'
+ },
+ 'bidder': {
+ 'eskimi': {
+ 'brand_id': 334553,
+ 'auction_id': 514667951122925701,
+ 'bidder_id': 2,
+ 'bid_ad_type': 0
+ }
+ }
+ }
+ }
+ ],
+ 'seat': 'seat'
+ }
+ ]
+ }
+};
+
+describe('Eskimi bid adapter', function () {
+ describe('isBidRequestValid', function () {
+ it('should accept request if placementId is passed', function () {
+ let bid = {
+ bidder: 'eskimi',
+ params: {
+ placementId: 123
+ }
+ };
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
+ });
+ it('reject requests without params', function () {
+ let bid = {
+ bidder: 'eskimi',
+ params: {}
+ };
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
+ });
+ });
+
+ describe('buildRequests', function () {
+ it('creates request data', function () {
+ let request = spec.buildRequests(REQUEST.bidRequest, REQUEST)[0];
+ expect(request).to.exist.and.to.be.a('object');
+ const payload = request.data;
+ expect(payload.imp[0]).to.have.property('id', REQUEST.bidRequest[0].bidId);
+ expect(payload.imp[1]).to.have.property('id', REQUEST.bidRequest[1].bidId);
+ });
+
+ it('has gdpr data if applicable', function () {
+ const req = Object.assign({}, REQUEST, {
+ gdprConsent: {
+ consentString: 'consentString',
+ gdprApplies: true,
+ }
+ });
+ let request = spec.buildRequests(REQUEST.bidRequest, req)[0];
+
+ const payload = request.data;
+ expect(payload.user.ext).to.have.property('consent', req.gdprConsent.consentString);
+ expect(payload.regs.ext).to.have.property('gdpr', 1);
+ });
+ });
+
+ describe('interpretResponse', function () {
+ it('has bids', function () {
+ let request = spec.buildRequests(REQUEST.bidRequest, REQUEST)[0];
+ let bids = spec.interpretResponse(RESPONSE, request);
+ expect(bids).to.be.an('array').that.is.not.empty;
+ validateBidOnIndex(0);
+
+ function validateBidOnIndex(index) {
+ expect(bids[index]).to.have.property('currency', 'USD');
+ expect(bids[index]).to.have.property('requestId', RESPONSE.body.seatbid[0].bid[index].id);
+ expect(bids[index]).to.have.property('cpm', RESPONSE.body.seatbid[0].bid[index].price);
+ expect(bids[index]).to.have.property('width', RESPONSE.body.seatbid[0].bid[index].w);
+ expect(bids[index]).to.have.property('height', RESPONSE.body.seatbid[0].bid[index].h);
+ expect(bids[index]).to.have.property('ad', RESPONSE.body.seatbid[0].bid[index].adm);
+ expect(bids[index]).to.have.property('creativeId', RESPONSE.body.seatbid[0].bid[index].crid);
+ expect(bids[index]).to.have.property('ttl', 30);
+ expect(bids[index]).to.have.property('netRevenue', true);
+ }
+ });
+
+ it('handles empty response', function () {
+ let request = spec.buildRequests(REQUEST.bidRequest, REQUEST)[0];
+ const EMPTY_RESP = Object.assign({}, RESPONSE, {'body': {}});
+ const bids = spec.interpretResponse(EMPTY_RESP, request);
+ expect(bids).to.be.empty;
+ });
+ });
+});
diff --git a/test/spec/modules/gridBidAdapter_spec.js b/test/spec/modules/gridBidAdapter_spec.js
index 1cafdf6134f..2ef604dd097 100644
--- a/test/spec/modules/gridBidAdapter_spec.js
+++ b/test/spec/modules/gridBidAdapter_spec.js
@@ -480,6 +480,14 @@ describe('TheMediaGrid Adapter', function () {
'h': 600,
'protocols': [1, 2, 3],
'mimes': ['video/mp4', 'video/webm', 'application/javascript', 'video/ogg'],
+ 'context': 'instream',
+ 'maxduration': 30,
+ 'minduration': 0,
+ 'api': [1, 2],
+ 'skip': 1,
+ 'placement': 1,
+ 'playbackmethod': 1,
+ 'startdelay': 0
}
}, {
'id': bidRequests[3].bidId,
diff --git a/test/spec/modules/gridNMBidAdapter_spec.js b/test/spec/modules/gridNMBidAdapter_spec.js
deleted file mode 100644
index e4f06a451d2..00000000000
--- a/test/spec/modules/gridNMBidAdapter_spec.js
+++ /dev/null
@@ -1,636 +0,0 @@
-import { expect } from 'chai';
-import { spec, resetUserSync, getSyncUrl } from 'modules/gridNMBidAdapter.js';
-import { newBidder } from 'src/adapters/bidderFactory.js';
-
-describe('TheMediaGridNM Adapter', function () {
- const adapter = newBidder(spec);
-
- describe('inherited functions', function () {
- it('exists and is a function', function () {
- expect(adapter.callBids).to.exist.and.to.be.a('function');
- });
- });
-
- describe('isBidRequestValid', function () {
- let bid = {
- 'bidder': 'gridNM',
- 'params': {
- 'source': 'jwp',
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'mimes': ['video/mp4', 'video/x-ms-wmv'],
- 'protocols': [1, 2, 3, 4, 5, 6]
- }
- },
- 'adUnitCode': 'adunit-code',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475',
- };
-
- it('should return true when required params found', function () {
- expect(spec.isBidRequestValid(bid)).to.equal(true);
- });
-
- it('should return false when required params are not passed', function () {
- const paramsList = [
- {
- 'source': 'jwp',
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'protocols': [1, 2, 3, 4, 5, 6]
- }
- },
- {
- 'source': 'jwp',
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'mimes': ['video/mp4', 'video/x-ms-wmv'],
- }
- },
- {
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'mimes': ['video/mp4', 'video/x-ms-wmv'],
- 'protocols': [1, 2, 3, 4, 5, 6]
- }
- },
- {
- 'source': 'jwp',
- 'pubid': '22',
- 'video': {
- 'mimes': ['video/mp4', 'video/x-ms-wmv'],
- 'protocols': [1, 2, 3, 4, 5, 6]
- }
- },
- {
- 'source': 'jwp',
- 'secid': '11',
- 'video': {
- 'mimes': ['video/mp4', 'video/x-ms-wmv'],
- 'protocols': [1, 2, 3, 4, 5, 6]
- }
- }
- ];
- paramsList.forEach((params) => {
- const invalidBid = Object.assign({}, bid);
- delete invalidBid.params;
- invalidBid.params = params;
- expect(spec.isBidRequestValid(invalidBid)).to.equal(false);
- });
- });
-
- it('should return false when required params has invalid values', function () {
- const paramsList = [
- {
- 'source': 'jwp',
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'mimes': ['video/mp4', 'video/x-ms-wmv'],
- 'protocols': '1,2,3,4,5'
- }
- },
- {
- 'source': 'jwp',
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'mimes': [1, 2],
- 'protocols': [1, 2, 3, 4, 5]
- }
- },
- {
- 'source': 'jwp',
- 'secid': 11,
- 'pubid': '22',
- 'video': {
- 'mimes': ['video/mp4', 'video/x-ms-wmv'],
- 'protocols': [1, 2, 3, 4, 5]
- }
- },
- {
- 'source': 111,
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'mimes': ['video/mp4', 'video/x-ms-wmv'],
- 'protocols': [1, 2, 3, 4, 5]
- }
- }
- ];
-
- paramsList.forEach((params) => {
- const invalidBid = Object.assign({}, bid);
- delete invalidBid.params;
- invalidBid.params = params;
- expect(spec.isBidRequestValid(invalidBid)).to.equal(false);
- });
- });
-
- it('should return true when required params is absent, but available in mediaTypes', function () {
- const paramsList = [
- {
- 'source': 'jwp',
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'protocols': [1, 2, 3, 4, 5, 6]
- }
- },
- {
- 'source': 'jwp',
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'mimes': ['video/mp4', 'video/x-ms-wmv'],
- }
- }
- ];
-
- const mediaTypes = {
- video: {
- mimes: ['video/mp4', 'video/x-ms-wmv'],
- playerSize: [200, 300],
- protocols: [1, 2, 3, 4, 5, 6]
- }
- };
-
- paramsList.forEach((params) => {
- const validBid = Object.assign({}, bid);
- delete validBid.params;
- validBid.params = params;
- validBid.mediaTypes = mediaTypes;
- expect(spec.isBidRequestValid(validBid)).to.equal(true);
- });
- });
- });
-
- describe('buildRequests', function () {
- function parseRequestUrl(url) {
- const res = {};
- url.replace(/^[^\?]+\?/, '').split('&').forEach((it) => {
- const couple = it.split('=');
- res[couple[0]] = decodeURIComponent(couple[1]);
- });
- return res;
- }
- const bidderRequest = {
- bidderRequestId: '22edbae2733bf6',
- auctionId: '1d1a030790a475',
- timeout: 3000,
- refererInfo: { page: 'https://example.com' }
- };
- const referrer = encodeURIComponent(bidderRequest.refererInfo.page);
- let bidRequests = [
- {
- 'bidder': 'gridNM',
- 'params': {
- 'source': 'jwp',
- 'floorcpm': 2,
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'mimes': ['video/mp4', 'video/x-ms-wmv'],
- 'protocols': [1, 2, 3, 4, 5, 6]
- }
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475',
- },
- {
- 'bidder': 'gridNM',
- 'params': {
- 'source': 'jwp',
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'mimes': ['video/mp4'],
- 'protocols': [1, 2, 3],
- 'skip': 1
- }
- },
- 'adUnitCode': 'adunit-code-2',
- 'sizes': [[728, 90]],
- 'bidId': '3150ccb55da321',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475',
- }
- ];
-
- it('if content and segment is present in jwTargeting, payload must have right params', function () {
- const jsContent = {id: 'test_jw_content_id'};
- const jsSegments = ['test_seg_1', 'test_seg_2'];
- const bidRequestsWithJwTargeting = bidRequests.map((bid) => {
- return Object.assign({
- rtd: {
- jwplayer: {
- targeting: {
- segments: jsSegments,
- content: jsContent
- }
- }
- }
- }, bid);
- });
- const requests = spec.buildRequests(bidRequestsWithJwTargeting, bidderRequest);
- requests.forEach((req, i) => {
- const payload = req.data;
- expect(req).to.have.property('data');
- expect(payload).to.have.property('site');
- expect(payload.site.content).to.deep.equal(jsContent);
- });
- });
-
- it('should attach valid params to the tag', function () {
- const requests = spec.buildRequests(bidRequests, bidderRequest);
- const requestsSizes = ['300x250,300x600', '728x90'];
- requests.forEach((req, i) => {
- expect(req.url).to.be.an('string');
- const payload = parseRequestUrl(req.url);
- expect(payload).to.have.property('no_mapping', '1');
- expect(payload).to.have.property('sp', 'jwp');
-
- const sizes = { w: bidRequests[i].sizes[0][0], h: bidRequests[i].sizes[0][1] };
- const impObj = {
- 'id': bidRequests[i].bidId,
- 'tagid': bidRequests[i].params.secid,
- 'ext': {'divid': bidRequests[i].adUnitCode},
- 'video': Object.assign(sizes, bidRequests[i].params.video)
- };
-
- if (bidRequests[i].params.floorcpm) {
- impObj.bidfloor = bidRequests[i].params.floorcpm;
- }
-
- expect(req.data).to.deep.equal({
- 'id': bidderRequest.bidderRequestId,
- 'site': {
- 'page': referrer,
- 'publisher': {
- 'id': bidRequests[i].params.pubid
- }
- },
- 'tmax': bidderRequest.timeout,
- 'source': {
- 'tid': bidderRequest.auctionId,
- 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'}
- },
- 'imp': [impObj]
- });
- });
- });
-
- it('should attach valid params from mediaTypes', function () {
- const mediaTypes = {
- video: {
- skipafter: 10,
- minduration: 10,
- maxduration: 100,
- protocols: [1, 3, 4],
- playerSize: [[300, 250]]
- }
- };
- const bidRequest = Object.assign({ mediaTypes }, bidRequests[0]);
- const req = spec.buildRequests([bidRequest], bidderRequest)[0];
- const expectedVideo = {
- 'skipafter': 10,
- 'minduration': 10,
- 'maxduration': 100,
- 'mimes': ['video/mp4', 'video/x-ms-wmv'],
- 'protocols': [1, 2, 3, 4, 5, 6],
- 'w': 300,
- 'h': 250
- };
-
- expect(req.url).to.be.an('string');
- const payload = parseRequestUrl(req.url);
- expect(payload).to.have.property('no_mapping', '1');
- expect(payload).to.have.property('sp', 'jwp');
- expect(req.data).to.deep.equal({
- 'id': bidderRequest.bidderRequestId,
- 'site': {
- 'page': referrer,
- 'publisher': {
- 'id': bidRequest.params.pubid
- }
- },
- 'tmax': bidderRequest.timeout,
- 'source': {
- 'tid': bidderRequest.auctionId,
- 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'}
- },
- 'imp': [{
- 'id': bidRequest.bidId,
- 'bidfloor': bidRequest.params.floorcpm,
- 'tagid': bidRequest.params.secid,
- 'ext': {'divid': bidRequest.adUnitCode},
- 'video': expectedVideo
- }]
- });
- });
-
- it('if gdprConsent is present payload must have gdpr params', function () {
- const gdprBidderRequest = Object.assign({gdprConsent: {consentString: 'AAA', gdprApplies: true}}, bidderRequest);
- const request = spec.buildRequests([bidRequests[0]], gdprBidderRequest)[0];
- const payload = request.data;
- expect(request).to.have.property('data');
- expect(payload).to.have.property('user');
- expect(payload.user).to.have.property('ext');
- expect(payload.user.ext).to.have.property('consent', 'AAA');
- expect(payload).to.have.property('regs');
- expect(payload.regs).to.have.property('ext');
- expect(payload.regs.ext).to.have.property('gdpr', 1);
- });
-
- it('if usPrivacy is present payload must have us_privacy param', function () {
- const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest);
- const request = spec.buildRequests([bidRequests[0]], bidderRequestWithUSP)[0];
- const payload = request.data;
- expect(payload).to.have.property('regs');
- expect(payload.regs).to.have.property('ext');
- expect(payload.regs.ext).to.have.property('us_privacy', '1YNN');
- });
- });
-
- describe('interpretResponse', function () {
- const responses = [
- {'bid': [{'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'content_type': 'video', 'h': 250, 'w': 300, 'dealid': 11}], 'seat': '2'},
- {'bid': [{'price': 0.5, 'adm': '\n<\/Ad>\n<\/VAST>', 'content_type': 'video', 'h': 600, 'w': 300, adomain: ['my_domain.ru']}], 'seat': '2'},
- {'bid': [{'price': 2.00, 'nurl': 'https://some_test_vast_url.com', 'content_type': 'video', 'adomain': ['example.com'], 'w': 300, 'h': 600}], 'seat': '2'},
- {'bid': [{'price': 0, 'h': 250, 'w': 300}], 'seat': '2'},
- {'bid': [{'price': 0, 'adm': '\n<\/Ad>\n<\/VAST>', 'h': 250, 'w': 300}], 'seat': '2'},
- undefined,
- {'bid': [], 'seat': '2'},
- {'seat': '2'},
- ];
-
- it('should get correct video bid response', function () {
- const bidRequests = [
- {
- 'bidder': 'gridNM',
- 'params': {
- 'source': 'jwp',
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'mimes': ['video/mp4', 'video/x-ms-wmv'],
- 'protocols': [1, 2, 3, 4, 5, 6]
- }
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '659423fff799cb',
- 'bidderRequestId': '5f2009617a7c0a',
- 'auctionId': '1cbd2feafe5e8b',
- 'mediaTypes': {
- 'video': {
- 'context': 'instream'
- }
- }
- },
- {
- 'bidder': 'gridNM',
- 'params': {
- 'source': 'jwp',
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'mimes': ['video/mp4'],
- 'protocols': [1, 2, 3, 4, 5],
- 'skip': 1
- }
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '2bc598e42b6a',
- 'bidderRequestId': '1e8b5a465f404',
- 'auctionId': '1cbd2feafe5e8b',
- 'mediaTypes': {
- 'video': {
- 'context': 'instream'
- }
- }
- },
- {
- 'bidder': 'gridNM',
- 'params': {
- 'source': 'jwp',
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'mimes': ['video/mp4'],
- 'protocols': [1, 2, 3],
- }
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '127f4b12a432c',
- 'bidderRequestId': 'a75bc868f32',
- 'auctionId': '1cbd2feafe5e8b',
- 'mediaTypes': {
- 'video': {
- 'context': 'instream'
- }
- }
- }
- ];
- const requests = spec.buildRequests(bidRequests);
- const expectedResponse = [
- {
- 'requestId': '659423fff799cb',
- 'cpm': 1.15,
- 'creativeId': '5f2009617a7c0a',
- 'dealId': 11,
- 'width': 300,
- 'height': 250,
- 'currency': 'USD',
- 'mediaType': 'video',
- 'netRevenue': true,
- 'ttl': 360,
- 'vastXml': '\n<\/Ad>\n<\/VAST>',
- 'meta': {
- 'advertiserDomains': []
- },
- 'adResponse': {
- 'content': '\n<\/Ad>\n<\/VAST>'
- }
- },
- {
- 'requestId': '2bc598e42b6a',
- 'cpm': 0.5,
- 'creativeId': '1e8b5a465f404',
- 'dealId': undefined,
- 'width': 300,
- 'height': 600,
- 'currency': 'USD',
- 'mediaType': 'video',
- 'netRevenue': true,
- 'ttl': 360,
- 'vastXml': '\n<\/Ad>\n<\/VAST>',
- 'meta': {
- 'advertiserDomains': ['my_domain.ru']
- },
- 'adResponse': {
- 'content': '\n<\/Ad>\n<\/VAST>'
- }
- },
- {
- 'requestId': '127f4b12a432c',
- 'cpm': 2.00,
- 'creativeId': 'a75bc868f32',
- 'dealId': undefined,
- 'width': 300,
- 'height': 600,
- 'currency': 'USD',
- 'mediaType': 'video',
- 'netRevenue': true,
- 'ttl': 360,
- 'meta': {
- advertiserDomains: ['example.com']
- },
- 'vastUrl': 'https://some_test_vast_url.com',
- }
- ];
-
- requests.forEach((req, i) => {
- const result = spec.interpretResponse({'body': {'seatbid': [responses[i]]}}, req);
- expect(result[0]).to.deep.equal(expectedResponse[i]);
- });
- });
-
- it('handles wrong and nobid responses', function () {
- responses.slice(3).forEach((resp) => {
- const request = spec.buildRequests([{
- 'bidder': 'gridNM',
- 'params': {
- 'source': 'jwp',
- 'secid': '11',
- 'pubid': '22',
- 'video': {
- 'mimes': ['video/mp4'],
- 'protocols': [1, 2, 3, 4, 5],
- 'skip': 1
- }
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '2bc598e42b6a',
- 'bidderRequestId': '39d74f5b71464',
- 'auctionId': '1cbd2feafe5e8b',
- 'meta': {
- 'advertiserDomains': []
- },
- 'mediaTypes': {
- 'video': {
- 'context': 'instream'
- }
- }
- }]);
- const result = spec.interpretResponse({'body': {'seatbid': [resp]}}, request[0]);
- expect(result.length).to.equal(0);
- });
- });
- });
-
- describe('user sync', function () {
- const syncUrl = getSyncUrl();
-
- beforeEach(function () {
- resetUserSync();
- });
-
- it('should register the Emily iframe', function () {
- let syncs = spec.getUserSyncs({
- pixelEnabled: true
- });
-
- expect(syncs).to.deep.equal({type: 'image', url: syncUrl});
- });
-
- it('should not register the Emily iframe more than once', function () {
- let syncs = spec.getUserSyncs({
- pixelEnabled: true
- });
- expect(syncs).to.deep.equal({type: 'image', url: syncUrl});
-
- // when called again, should still have only been called once
- syncs = spec.getUserSyncs();
- expect(syncs).to.equal(undefined);
- });
-
- it('should pass gdpr params if consent is true', function () {
- expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {
- gdprApplies: true, consentString: 'foo'
- })).to.deep.equal({
- type: 'image', url: `${syncUrl}&gdpr=1&gdpr_consent=foo`
- });
- });
-
- it('should pass gdpr params if consent is false', function () {
- expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {
- gdprApplies: false, consentString: 'foo'
- })).to.deep.equal({
- type: 'image', url: `${syncUrl}&gdpr=0&gdpr_consent=foo`
- });
- });
-
- it('should pass gdpr param gdpr_consent only when gdprApplies is undefined', function () {
- expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {
- consentString: 'foo'
- })).to.deep.equal({
- type: 'image', url: `${syncUrl}&gdpr_consent=foo`
- });
- });
-
- it('should pass no params if gdpr consentString is not defined', function () {
- expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {})).to.deep.equal({
- type: 'image', url: syncUrl
- });
- });
-
- it('should pass no params if gdpr consentString is a number', function () {
- expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {
- consentString: 0
- })).to.deep.equal({
- type: 'image', url: syncUrl
- });
- });
-
- it('should pass no params if gdpr consentString is null', function () {
- expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {
- consentString: null
- })).to.deep.equal({
- type: 'image', url: syncUrl
- });
- });
-
- it('should pass no params if gdpr consentString is a object', function () {
- expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {
- consentString: {}
- })).to.deep.equal({
- type: 'image', url: syncUrl
- });
- });
-
- it('should pass no params if gdpr is not defined', function () {
- expect(spec.getUserSyncs({ pixelEnabled: true }, {}, undefined)).to.deep.equal({
- type: 'image', url: syncUrl
- });
- });
-
- it('should pass usPrivacy param if it is available', function() {
- expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {}, '1YNN')).to.deep.equal({
- type: 'image', url: `${syncUrl}&us_privacy=1YNN`
- });
- });
- });
-});
diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js
index 8ea3b9dc522..149c4c44c21 100644
--- a/test/spec/modules/ixBidAdapter_spec.js
+++ b/test/spec/modules/ixBidAdapter_spec.js
@@ -1703,6 +1703,63 @@ describe('IndexexchangeAdapter', function () {
expect(r.regs.gpp_sid).to.be.an('array');
expect(r.regs.gpp_sid).to.include(1);
});
+
+ it('should add adunit specific data to imp ext for banner', function () {
+ const AD_UNIT_CODE = '/19968336/some-adunit-path';
+ const validBids = utils.deepClone(DEFAULT_BANNER_VALID_BID);
+ validBids[0].ortb2Imp = {
+ ext: {
+ data: {
+ adserver: {
+ name: 'gam banner',
+ adslot: AD_UNIT_CODE
+ }
+ }
+ }
+ };
+ const requests = spec.buildRequests(validBids, DEFAULT_OPTION);
+ const imp = extractPayload(requests[0]).imp[0];
+ expect(deepAccess(imp, 'ext.data.adserver.name')).to.equal('gam banner');
+ expect(deepAccess(imp, 'ext.data.adserver.adslot')).to.equal(AD_UNIT_CODE);
+ });
+
+ it('should add adunit specific data to imp ext for native', function () {
+ const AD_UNIT_CODE = '/19968336/some-adunit-path';
+ const validBids = utils.deepClone(DEFAULT_NATIVE_VALID_BID);
+ validBids[0].ortb2Imp = {
+ ext: {
+ data: {
+ adserver: {
+ name: 'gam native',
+ adslot: AD_UNIT_CODE
+ }
+ }
+ }
+ };
+ const requests = spec.buildRequests(validBids, DEFAULT_OPTION);
+ const imp = extractPayload(requests[0]).imp[0];
+ expect(deepAccess(imp, 'ext.data.adserver.name')).to.equal('gam native');
+ expect(deepAccess(imp, 'ext.data.adserver.adslot')).to.equal(AD_UNIT_CODE);
+ });
+
+ it('should add adunit specific data to imp ext for video', function () {
+ const AD_UNIT_CODE = '/19968336/some-adunit-path';
+ const validBids = utils.deepClone(DEFAULT_VIDEO_VALID_BID);
+ validBids[0].ortb2Imp = {
+ ext: {
+ data: {
+ adserver: {
+ name: 'gam video',
+ adslot: AD_UNIT_CODE
+ }
+ }
+ }
+ };
+ const requests = spec.buildRequests(validBids, DEFAULT_OPTION);
+ const imp = extractPayload(requests[0]).imp[0];
+ expect(deepAccess(imp, 'ext.data.adserver.name')).to.equal('gam video');
+ expect(deepAccess(imp, 'ext.data.adserver.adslot')).to.equal(AD_UNIT_CODE);
+ });
});
describe('buildRequests', function () {
diff --git a/test/spec/modules/kargoBidAdapter_spec.js b/test/spec/modules/kargoBidAdapter_spec.js
index 260ac6c2132..d692cc67e26 100644
--- a/test/spec/modules/kargoBidAdapter_spec.js
+++ b/test/spec/modules/kargoBidAdapter_spec.js
@@ -524,9 +524,7 @@ describe('kargo adapter tests', function () {
}
const reqCount = requestCount++;
- if (reqCount > 0) {
- base.requestCount = reqCount
- }
+ base.requestCount = reqCount
if (expectedCRB != null) {
if (expectedCRB.rawCRB != null) {
@@ -894,8 +892,8 @@ describe('kargo adapter tests', function () {
});
});
- function getUserSyncsWhenAllowed(gdprConsent, usPrivacy) {
- return spec.getUserSyncs({iframeEnabled: true}, null, gdprConsent, usPrivacy);
+ function getUserSyncsWhenAllowed(gdprConsent, usPrivacy, gppConsent) {
+ return spec.getUserSyncs({iframeEnabled: true}, null, gdprConsent, usPrivacy, gppConsent);
}
function getUserSyncsWhenForbidden() {
@@ -910,17 +908,17 @@ describe('kargo adapter tests', function () {
shouldSimulateOutdatedBrowser = true;
}
- function getSyncUrl(index, gdprApplies, gdprConsentString, usPrivacy) {
+ function getSyncUrl(index, gdprApplies, gdprConsentString, usPrivacy, gpp, gppSid) {
return {
type: 'iframe',
- url: `https://crb.kargo.com/api/v1/initsyncrnd/${clientId}?seed=3205e885-8d37-4139-b47e-f82cff268000&idx=${index}&gdpr=${gdprApplies}&gdpr_consent=${gdprConsentString}&us_privacy=${usPrivacy}`
+ url: `https://crb.kargo.com/api/v1/initsyncrnd/${clientId}?seed=3205e885-8d37-4139-b47e-f82cff268000&idx=${index}&gdpr=${gdprApplies}&gdpr_consent=${gdprConsentString}&us_privacy=${usPrivacy}&gpp=${gpp}&gpp_sid=${gppSid}`
};
}
- function getSyncUrls(gdprApplies, gdprConsentString, usPrivacy) {
+ function getSyncUrls(gdprApplies, gdprConsentString, usPrivacy, gpp, gppSid) {
var syncs = [];
for (var i = 0; i < 5; i++) {
- syncs[i] = getSyncUrl(i, gdprApplies || 0, gdprConsentString || '', usPrivacy || '');
+ syncs[i] = getSyncUrl(i, gdprApplies || 0, gdprConsentString || '', usPrivacy || '', gpp || '', gppSid || '');
}
return syncs;
}
@@ -957,6 +955,11 @@ describe('kargo adapter tests', function () {
safelyRun(() => expect(getUserSyncsWhenAllowed({ gdprApplies: true, consentString: 'consentstring' })).to.deep.equal(getSyncUrls(1, 'consentstring', '')));
});
+ it('pass through gpp consent', function () {
+ turnOnClientId();
+ safelyRun(() => expect(getUserSyncsWhenAllowed(null, null, { consentString: 'gppString', applicableSections: [-1] })).to.deep.equal(getSyncUrls('', '', '', 'gppString', '-1')));
+ });
+
it('no user syncs when there is outdated browser', function() {
turnOnClientId();
simulateOutdatedBrowser();
diff --git a/test/spec/modules/kueezRtbBidAdapter_spec.js b/test/spec/modules/kueezRtbBidAdapter_spec.js
index 2f48fd6df8c..fc7219d2ee7 100644
--- a/test/spec/modules/kueezRtbBidAdapter_spec.js
+++ b/test/spec/modules/kueezRtbBidAdapter_spec.js
@@ -43,7 +43,12 @@ const BID = {
'bidderWinsCount': 1,
'requestId': 'b0777d85-d061-450e-9bc7-260dd54bbb7a',
'schain': 'a0819c69-005b-41ed-af06-1be1e0aefefc',
- 'mediaTypes': [BANNER]
+ 'mediaTypes': [BANNER],
+ 'ortb2Imp': {
+ 'ext': {
+ 'gpid': '0123456789'
+ }
+ }
};
const VIDEO_BID = {
@@ -315,7 +320,8 @@ describe('KueezRtbBidAdapter', function () {
protocols: [2, 3, 5, 6],
startdelay: 0
}
- }
+ },
+ gpid: ''
}
});
});
@@ -373,6 +379,7 @@ describe('KueezRtbBidAdapter', function () {
schain: BID.schain,
res: `${window.top.screen.width}x${window.top.screen.height}`,
mediaTypes: [BANNER],
+ gpid: '0123456789',
uqs: getTopWindowQueryParams(),
'ext.param1': 'loremipsum',
'ext.param2': 'dolorsitamet',
@@ -448,6 +455,19 @@ describe('KueezRtbBidAdapter', function () {
});
});
+ it('should get meta from response metaData', function () {
+ const serverResponse = utils.deepClone(SERVER_RESPONSE);
+ serverResponse.body.results[0].metaData = {
+ advertiserDomains: ['kueezrtb.com'],
+ agencyName: 'Agency Name',
+ };
+ const responses = adapter.interpretResponse(serverResponse, REQUEST);
+ expect(responses[0].meta).to.deep.equal({
+ advertiserDomains: ['kueezrtb.com'],
+ agencyName: 'Agency Name'
+ });
+ });
+
it('should return an array of interpreted video responses', function () {
const responses = adapter.interpretResponse(VIDEO_SERVER_RESPONSE, REQUEST);
expect(responses).to.have.length(1);
diff --git a/test/spec/modules/minutemediaplusBidAdapter_spec.js b/test/spec/modules/minutemediaplusBidAdapter_spec.js
index 000ddb2778d..e19323c794f 100644
--- a/test/spec/modules/minutemediaplusBidAdapter_spec.js
+++ b/test/spec/modules/minutemediaplusBidAdapter_spec.js
@@ -43,7 +43,12 @@ const BID = {
'bidderWinsCount': 1,
'requestId': 'b0777d85-d061-450e-9bc7-260dd54bbb7a',
'schain': 'a0819c69-005b-41ed-af06-1be1e0aefefc',
- 'mediaTypes': [BANNER]
+ 'mediaTypes': [BANNER],
+ 'ortb2Imp': {
+ 'ext': {
+ 'gpid': '1234567890'
+ }
+ }
};
const VIDEO_BID = {
@@ -315,7 +320,8 @@ describe('MinuteMediaPlus Bid Adapter', function () {
protocols: [2, 3, 5, 6],
startdelay: 0
}
- }
+ },
+ gpid: ''
}
});
});
@@ -373,6 +379,7 @@ describe('MinuteMediaPlus Bid Adapter', function () {
schain: BID.schain,
res: `${window.top.screen.width}x${window.top.screen.height}`,
mediaTypes: [BANNER],
+ gpid: '1234567890',
uqs: getTopWindowQueryParams(),
'ext.param1': 'loremipsum',
'ext.param2': 'dolorsitamet',
@@ -448,6 +455,19 @@ describe('MinuteMediaPlus Bid Adapter', function () {
});
});
+ it('should get meta from response metaData', function () {
+ const serverResponse = utils.deepClone(SERVER_RESPONSE);
+ serverResponse.body.results[0].metaData = {
+ advertiserDomains: ['minutemedia-prebid.com'],
+ agencyName: 'Agency Name',
+ };
+ const responses = adapter.interpretResponse(serverResponse, REQUEST);
+ expect(responses[0].meta).to.deep.equal({
+ advertiserDomains: ['minutemedia-prebid.com'],
+ agencyName: 'Agency Name'
+ });
+ });
+
it('should return an array of interpreted video responses', function () {
const responses = adapter.interpretResponse(VIDEO_SERVER_RESPONSE, REQUEST);
expect(responses).to.have.length(1);
diff --git a/test/spec/modules/nativoBidAdapter_spec.js b/test/spec/modules/nativoBidAdapter_spec.js
index 4d70e6f7071..51e78d1f6d6 100644
--- a/test/spec/modules/nativoBidAdapter_spec.js
+++ b/test/spec/modules/nativoBidAdapter_spec.js
@@ -8,6 +8,10 @@ import {
getPageUrlFromBidRequest,
hasProtocol,
addProtocol,
+ BidRequestDataSource,
+ RequestData,
+ UserEIDs,
+ buildRequestUrl,
} from '../../../modules/nativoBidAdapter'
describe('bidDataMap', function () {
@@ -120,6 +124,7 @@ describe('nativoBidAdapterTests', function () {
expect(request.url).to.be.a('string')
expect(request.url).to.include('?')
+ expect(request.url).to.include('ntv_pbv')
expect(request.url).to.include('ntv_ptd')
expect(request.url).to.include('ntv_pb_rid')
expect(request.url).to.include('ntv_ppc')
@@ -731,3 +736,99 @@ describe('getPageUrlFromBidRequest', () => {
expect(url).not.to.be.undefined
})
})
+
+describe('RequestData', () => {
+ describe('addBidRequestDataSource', () => {
+ it('Adds a BidRequestDataSource', () => {
+ const requestData = new RequestData()
+ const testBidRequestDataSource = new BidRequestDataSource()
+
+ requestData.addBidRequestDataSource(testBidRequestDataSource)
+
+ expect(requestData.bidRequestDataSources.length == 1)
+ })
+
+ it("Doeasn't add a non BidRequestDataSource", () => {
+ const requestData = new RequestData()
+
+ requestData.addBidRequestDataSource({})
+ requestData.addBidRequestDataSource('test')
+ requestData.addBidRequestDataSource(1)
+ requestData.addBidRequestDataSource(true)
+
+ expect(requestData.bidRequestDataSources.length == 0)
+ })
+ })
+
+ describe('getRequestDataString', () => {
+ it("Doesn't append empty query strings", () => {
+ const requestData = new RequestData()
+ const testBidRequestDataSource = new BidRequestDataSource()
+
+ requestData.addBidRequestDataSource(testBidRequestDataSource)
+
+ let qs = requestData.getRequestDataQueryString()
+ expect(qs).to.be.empty
+
+ testBidRequestDataSource.getRequestQueryString = () => {
+ return 'ntv_test=true'
+ }
+ qs = requestData.getRequestDataQueryString()
+ expect(qs).to.be.equal('ntv_test=true')
+ })
+ })
+})
+
+describe('UserEIDs', () => {
+ const userEids = new UserEIDs()
+ const eids = [{ 'testId': 1111 }]
+
+ describe('processBidRequestData', () => {
+ it('Processes bid request without eids', () => {
+ userEids.processBidRequestData({})
+
+ expect(userEids.eids).to.be.empty
+ })
+
+ it('Processed bid request with eids', () => {
+ userEids.processBidRequestData({ userIdAsEids: eids })
+
+ expect(userEids.eids).to.not.be.empty
+ })
+ })
+
+ describe('getRequestQueryString', () => {
+ it('Correctly prints out QS param string', () => {
+ const qs = userEids.getRequestQueryString()
+ const value = qs.slice(11)
+
+ expect(qs).to.include('ntv_pb_eid=')
+ try {
+ expect(JSON.parse(value)).to.be.equal(eids)
+ } catch (err) { }
+ })
+ })
+})
+
+describe('buildRequestUrl', () => {
+ const baseUrl = 'https://www.testExchange.com'
+ it('Returns baseUrl if no QS strings passed', () => {
+ const url = buildRequestUrl(baseUrl)
+ expect(url).to.be.equal(baseUrl)
+ })
+
+ it('Returns baseUrl if empty QS strings passed', () => {
+ const url = buildRequestUrl(baseUrl, ['', '', ''])
+ expect(url).to.be.equal(baseUrl)
+ })
+
+ it('Returns baseUrl + QS params if QS strings passed', () => {
+ const url = buildRequestUrl(baseUrl, ['ntv_ptd=123456&ntv_test=true', 'ntv_foo=bar'])
+ expect(url).to.be.equal(`${baseUrl}?ntv_ptd=123456&ntv_test=true&ntv_foo=bar`)
+ })
+
+ it('Returns baseUrl + QS params if mixed QS strings passed', () => {
+ const url = buildRequestUrl(baseUrl, ['ntv_ptd=123456&ntv_test=true', '', '', 'ntv_foo=bar'])
+ expect(url).to.be.equal(`${baseUrl}?ntv_ptd=123456&ntv_test=true&ntv_foo=bar`)
+ })
+})
diff --git a/test/spec/modules/ooloAnalyticsAdapter_spec.js b/test/spec/modules/ooloAnalyticsAdapter_spec.js
index a6030e972ce..2515c713b14 100644
--- a/test/spec/modules/ooloAnalyticsAdapter_spec.js
+++ b/test/spec/modules/ooloAnalyticsAdapter_spec.js
@@ -194,7 +194,7 @@ describe('oolo Prebid Analytic', () => {
})
const conf = {}
- const pbjsConfig = config.getConfig()
+ const pbjsConfig = JSON.parse(JSON.stringify(config.getConfig()))
Object.keys(pbjsConfig).forEach(key => {
if (key[0] !== '_') {
diff --git a/test/spec/modules/pairIdSystem_spec.js b/test/spec/modules/pairIdSystem_spec.js
new file mode 100644
index 00000000000..4f75666affe
--- /dev/null
+++ b/test/spec/modules/pairIdSystem_spec.js
@@ -0,0 +1,68 @@
+import { storage, pairIdSubmodule } from 'modules/pairIdSystem.js';
+import * as utils from 'src/utils.js';
+
+describe('pairId', function () {
+ let sandbox;
+ let logErrorStub;
+
+ beforeEach(() => {
+ sandbox = sinon.sandbox.create();
+ logErrorStub = sandbox.stub(utils, 'logError');
+ });
+ afterEach(() => {
+ sandbox.restore();
+ });
+
+ it('should log an error if no ID is found when getId', function() {
+ pairIdSubmodule.getId({ params: {} });
+ expect(logErrorStub.calledOnce).to.be.true;
+ });
+
+ it('should read pairId from local storage if exists', function() {
+ let pairIds = ['test-pair-id1', 'test-pair-id2', 'test-pair-id3'];
+ sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('pairId').returns(btoa(JSON.stringify(pairIds)));
+
+ let id = pairIdSubmodule.getId({ params: {} });
+ expect(id).to.be.deep.equal({id: pairIds});
+ });
+
+ it('should read pairId from cookie if exists', function() {
+ let pairIds = ['test-pair-id4', 'test-pair-id5', 'test-pair-id6'];
+ sandbox.stub(storage, 'getCookie').withArgs('pairId').returns(btoa(JSON.stringify(pairIds)));
+
+ let id = pairIdSubmodule.getId({ params: {} });
+ expect(id).to.be.deep.equal({id: pairIds});
+ });
+
+ it('should read pairId from default liveramp envelope local storage key if configured', function() {
+ let pairIds = ['test-pair-id1', 'test-pair-id2', 'test-pair-id3'];
+ sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('_lr_pairId').returns(btoa(JSON.stringify({'envelope': pairIds})));
+ let id = pairIdSubmodule.getId({
+ params: {
+ liveramp: {}
+ }})
+ expect(id).to.be.deep.equal({id: pairIds})
+ })
+
+ it('should read pairId from default liveramp envelope cookie entry if configured', function() {
+ let pairIds = ['test-pair-id4', 'test-pair-id5', 'test-pair-id6'];
+ sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('_lr_pairId').returns(btoa(JSON.stringify({'envelope': pairIds})));
+ let id = pairIdSubmodule.getId({
+ params: {
+ liveramp: {}
+ }})
+ expect(id).to.be.deep.equal({id: pairIds})
+ })
+
+ it('should read pairId from specified liveramp envelope cookie entry if configured with storageKey', function() {
+ let pairIds = ['test-pair-id7', 'test-pair-id8', 'test-pair-id9'];
+ sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('lr_pairId_custom').returns(btoa(JSON.stringify({'envelope': pairIds})));
+ let id = pairIdSubmodule.getId({
+ params: {
+ liveramp: {
+ storageKey: 'lr_pairId_custom'
+ }
+ }})
+ expect(id).to.be.deep.equal({id: pairIds})
+ })
+});
diff --git a/test/spec/modules/pubCommonId_spec.js b/test/spec/modules/pubCommonId_spec.js
index a46ff26c4b8..7c539014cc5 100644
--- a/test/spec/modules/pubCommonId_spec.js
+++ b/test/spec/modules/pubCommonId_spec.js
@@ -233,23 +233,6 @@ describe('Publisher Common ID', function () {
});
});
});
-
- it.skip('disable auto create', function() {
- setConfig({
- create: false
- });
-
- const config = getPubcidConfig();
- expect(config.create).to.be.false;
- expect(config.typeEnabled).to.equal('html5');
-
- let adUnits = getAdUnits();
- let innerAdUnits;
- requestBidHook((config) => { innerAdUnits = config.adUnits }, {adUnits});
-
- const pubcid = localStorage.getItem(ID_NAME);
- expect(pubcid).to.be.null;
- });
});
describe('Invoking requestBid', function () {
diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js
index 66bcf42bb0f..3198fe406e7 100644
--- a/test/spec/modules/pubmaticBidAdapter_spec.js
+++ b/test/spec/modules/pubmaticBidAdapter_spec.js
@@ -850,12 +850,86 @@ describe('PubMatic adapter', function () {
expect(isValid).to.equal(true);
});
- it('should check for context if video is present', function() {
- let bid = {
+ if (FEATURES.VIDEO) {
+ it('should check for context if video is present', function() {
+ let bid = {
+ 'bidder': 'pubmatic',
+ 'params': {
+ 'adSlot': 'SLOT_NHB1@728x90',
+ 'publisherId': '5890'
+ },
+ 'mediaTypes': {
+ 'video': {
+ 'playerSize': [
+ [640, 480]
+ ],
+ 'protocols': [1, 2, 5],
+ 'context': 'instream',
+ 'mimes': ['video/flv'],
+ 'skippable': false,
+ 'skip': 1,
+ 'linearity': 2
+ }
+ },
+ 'adUnitCode': 'video1',
+ 'transactionId': '803e3750-0bbe-4ffe-a548-b6eca15087bf',
+ 'sizes': [
+ [640, 480]
+ ],
+ 'bidId': '2c95df014cfe97',
+ 'bidderRequestId': '1fe59391566442',
+ 'auctionId': '3a4118ef-fb96-4416-b0b0-3cfc1cebc142',
+ 'src': 'client',
+ 'bidRequestsCount': 1,
+ 'bidderRequestsCount': 1,
+ 'bidderWinsCount': 0
+ },
+ isValid = spec.isBidRequestValid(bid);
+ expect(isValid).to.equal(true);
+ })
+
+ it('should return false if context is not present in video', function() {
+ let bid = {
+ 'bidder': 'pubmatic',
+ 'params': {
+ 'adSlot': 'SLOT_NHB1@728x90',
+ 'publisherId': '5890'
+ },
+ 'mediaTypes': {
+ 'video': {
+ 'w': 640,
+ 'h': 480,
+ 'protocols': [1, 2, 5],
+ 'mimes': ['video/flv'],
+ 'skippable': false,
+ 'skip': 1,
+ 'linearity': 2
+ }
+ },
+ 'adUnitCode': 'video1',
+ 'transactionId': '803e3750-0bbe-4ffe-a548-b6eca15087bf',
+ 'sizes': [
+ [640, 480]
+ ],
+ 'bidId': '2c95df014cfe97',
+ 'bidderRequestId': '1fe59391566442',
+ 'auctionId': '3a4118ef-fb96-4416-b0b0-3cfc1cebc142',
+ 'src': 'client',
+ 'bidRequestsCount': 1,
+ 'bidderRequestsCount': 1,
+ 'bidderWinsCount': 0
+ },
+ isValid = spec.isBidRequestValid(bid);
+ expect(isValid).to.equal(false);
+ })
+
+ it('bid.mediaTypes.video.mimes OR bid.params.video.mimes should be present and must be a non-empty array', function() {
+ let bid = {
'bidder': 'pubmatic',
'params': {
'adSlot': 'SLOT_NHB1@728x90',
- 'publisherId': '5890'
+ 'publisherId': '5890',
+ 'video': {}
},
'mediaTypes': {
'video': {
@@ -864,42 +938,6 @@ describe('PubMatic adapter', function () {
],
'protocols': [1, 2, 5],
'context': 'instream',
- 'mimes': ['video/flv'],
- 'skippable': false,
- 'skip': 1,
- 'linearity': 2
- }
- },
- 'adUnitCode': 'video1',
- 'transactionId': '803e3750-0bbe-4ffe-a548-b6eca15087bf',
- 'sizes': [
- [640, 480]
- ],
- 'bidId': '2c95df014cfe97',
- 'bidderRequestId': '1fe59391566442',
- 'auctionId': '3a4118ef-fb96-4416-b0b0-3cfc1cebc142',
- 'src': 'client',
- 'bidRequestsCount': 1,
- 'bidderRequestsCount': 1,
- 'bidderWinsCount': 0
- },
- isValid = spec.isBidRequestValid(bid);
- expect(isValid).to.equal(true);
- })
-
- it('should return false if context is not present in video', function() {
- let bid = {
- 'bidder': 'pubmatic',
- 'params': {
- 'adSlot': 'SLOT_NHB1@728x90',
- 'publisherId': '5890'
- },
- 'mediaTypes': {
- 'video': {
- 'w': 640,
- 'h': 480,
- 'protocols': [1, 2, 5],
- 'mimes': ['video/flv'],
'skippable': false,
'skip': 1,
'linearity': 2
@@ -917,160 +955,124 @@ describe('PubMatic adapter', function () {
'bidRequestsCount': 1,
'bidderRequestsCount': 1,
'bidderWinsCount': 0
- },
- isValid = spec.isBidRequestValid(bid);
- expect(isValid).to.equal(false);
- })
-
- it('bid.mediaTypes.video.mimes OR bid.params.video.mimes should be present and must be a non-empty array', function() {
- let bid = {
- 'bidder': 'pubmatic',
- 'params': {
- 'adSlot': 'SLOT_NHB1@728x90',
- 'publisherId': '5890',
- 'video': {}
- },
- 'mediaTypes': {
- 'video': {
- 'playerSize': [
- [640, 480]
- ],
- 'protocols': [1, 2, 5],
- 'context': 'instream',
- 'skippable': false,
- 'skip': 1,
- 'linearity': 2
- }
- },
- 'adUnitCode': 'video1',
- 'transactionId': '803e3750-0bbe-4ffe-a548-b6eca15087bf',
- 'sizes': [
- [640, 480]
- ],
- 'bidId': '2c95df014cfe97',
- 'bidderRequestId': '1fe59391566442',
- 'auctionId': '3a4118ef-fb96-4416-b0b0-3cfc1cebc142',
- 'src': 'client',
- 'bidRequestsCount': 1,
- 'bidderRequestsCount': 1,
- 'bidderWinsCount': 0
- };
+ };
- delete bid.params.video.mimes; // Undefined
- bid.mediaTypes.video.mimes = 'string'; // NOT array
- expect(spec.isBidRequestValid(bid)).to.equal(false);
+ delete bid.params.video.mimes; // Undefined
+ bid.mediaTypes.video.mimes = 'string'; // NOT array
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
- delete bid.params.video.mimes; // Undefined
- delete bid.mediaTypes.video.mimes; // Undefined
- expect(spec.isBidRequestValid(bid)).to.equal(false);
+ delete bid.params.video.mimes; // Undefined
+ delete bid.mediaTypes.video.mimes; // Undefined
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
- delete bid.params.video.mimes; // Undefined
- bid.mediaTypes.video.mimes = ['video/flv']; // Valid
- expect(spec.isBidRequestValid(bid)).to.equal(true);
+ delete bid.params.video.mimes; // Undefined
+ bid.mediaTypes.video.mimes = ['video/flv']; // Valid
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
- delete bid.mediaTypes.video.mimes; // mediaTypes.video.mimes undefined
- bid.params.video = {mimes: 'string'}; // NOT array
- expect(spec.isBidRequestValid(bid)).to.equal(false);
+ delete bid.mediaTypes.video.mimes; // mediaTypes.video.mimes undefined
+ bid.params.video = {mimes: 'string'}; // NOT array
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
- delete bid.mediaTypes.video.mimes; // mediaTypes.video.mimes undefined
- delete bid.params.video.mimes; // Undefined
- expect(spec.isBidRequestValid(bid)).to.equal(false);
+ delete bid.mediaTypes.video.mimes; // mediaTypes.video.mimes undefined
+ delete bid.params.video.mimes; // Undefined
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
- delete bid.mediaTypes.video.mimes; // mediaTypes.video.mimes undefined
- bid.params.video.mimes = ['video/flv']; // Valid
- expect(spec.isBidRequestValid(bid)).to.equal(true);
+ delete bid.mediaTypes.video.mimes; // mediaTypes.video.mimes undefined
+ bid.params.video.mimes = ['video/flv']; // Valid
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
- delete bid.mediaTypes.video.mimes; // Undefined
- bid.params.video.mimes = ['video/flv']; // Valid
- expect(spec.isBidRequestValid(bid)).to.equal(true);
+ delete bid.mediaTypes.video.mimes; // Undefined
+ bid.params.video.mimes = ['video/flv']; // Valid
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
- delete bid.mediaTypes.video.mimes; // Undefined
- delete bid.params.video.mimes; // Undefined
- expect(spec.isBidRequestValid(bid)).to.equal(false);
- });
+ delete bid.mediaTypes.video.mimes; // Undefined
+ delete bid.params.video.mimes; // Undefined
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
+ });
- it('checks on bid.params.outstreamAU & bid.renderer & bid.mediaTypes.video.renderer', function() {
- const getThebid = function() {
- let bid = utils.deepClone(validOutstreamBidRequest.bids[0]);
- bid.params.outstreamAU = 'pubmatic-test';
- bid.renderer = ' '; // we are only checking if this key is set or not
- bid.mediaTypes.video.renderer = ' '; // we are only checking if this key is set or not
- return bid;
- }
+ it('checks on bid.params.outstreamAU & bid.renderer & bid.mediaTypes.video.renderer', function() {
+ const getThebid = function() {
+ let bid = utils.deepClone(validOutstreamBidRequest.bids[0]);
+ bid.params.outstreamAU = 'pubmatic-test';
+ bid.renderer = ' '; // we are only checking if this key is set or not
+ bid.mediaTypes.video.renderer = ' '; // we are only checking if this key is set or not
+ return bid;
+ }
- // true: when all are present
- // mdiatype: outstream
- // bid.params.outstreamAU : Y
- // bid.renderer : Y
- // bid.mediaTypes.video.renderer : Y
- let bid = getThebid();
- expect(spec.isBidRequestValid(bid)).to.equal(true);
-
- // true: atleast one is present; 3 cases
- // mdiatype: outstream
- // bid.params.outstreamAU : Y
- // bid.renderer : N
- // bid.mediaTypes.video.renderer : N
- bid = getThebid();
- delete bid.renderer;
- delete bid.mediaTypes.video.renderer;
- expect(spec.isBidRequestValid(bid)).to.equal(true);
-
- // true: atleast one is present; 3 cases
- // mdiatype: outstream
- // bid.params.outstreamAU : N
- // bid.renderer : Y
- // bid.mediaTypes.video.renderer : N
- bid = getThebid();
- delete bid.params.outstreamAU;
- delete bid.mediaTypes.video.renderer;
- expect(spec.isBidRequestValid(bid)).to.equal(true);
-
- // true: atleast one is present; 3 cases
- // mdiatype: outstream
- // bid.params.outstreamAU : N
- // bid.renderer : N
- // bid.mediaTypes.video.renderer : Y
- bid = getThebid();
- delete bid.params.outstreamAU;
- delete bid.renderer;
- expect(spec.isBidRequestValid(bid)).to.equal(true);
-
- // false: none present; only outstream
- // mdiatype: outstream
- // bid.params.outstreamAU : N
- // bid.renderer : N
- // bid.mediaTypes.video.renderer : N
- bid = getThebid();
- delete bid.params.outstreamAU;
- delete bid.renderer;
- delete bid.mediaTypes.video.renderer;
- expect(spec.isBidRequestValid(bid)).to.equal(false);
-
- // true: none present; outstream + Banner
- // mdiatype: outstream, banner
- // bid.params.outstreamAU : N
- // bid.renderer : N
- // bid.mediaTypes.video.renderer : N
- bid = getThebid();
- delete bid.params.outstreamAU;
- delete bid.renderer;
- delete bid.mediaTypes.video.renderer;
- bid.mediaTypes.banner = {sizes: [ [300, 250], [300, 600] ]};
- expect(spec.isBidRequestValid(bid)).to.equal(true);
-
- // true: none present; outstream + Native
- // mdiatype: outstream, native
- // bid.params.outstreamAU : N
- // bid.renderer : N
- // bid.mediaTypes.video.renderer : N
- bid = getThebid();
- delete bid.params.outstreamAU;
- delete bid.renderer;
- delete bid.mediaTypes.video.renderer;
- bid.mediaTypes.native = {}
- expect(spec.isBidRequestValid(bid)).to.equal(true);
- });
+ // true: when all are present
+ // mdiatype: outstream
+ // bid.params.outstreamAU : Y
+ // bid.renderer : Y
+ // bid.mediaTypes.video.renderer : Y
+ let bid = getThebid();
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
+
+ // true: atleast one is present; 3 cases
+ // mdiatype: outstream
+ // bid.params.outstreamAU : Y
+ // bid.renderer : N
+ // bid.mediaTypes.video.renderer : N
+ bid = getThebid();
+ delete bid.renderer;
+ delete bid.mediaTypes.video.renderer;
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
+
+ // true: atleast one is present; 3 cases
+ // mdiatype: outstream
+ // bid.params.outstreamAU : N
+ // bid.renderer : Y
+ // bid.mediaTypes.video.renderer : N
+ bid = getThebid();
+ delete bid.params.outstreamAU;
+ delete bid.mediaTypes.video.renderer;
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
+
+ // true: atleast one is present; 3 cases
+ // mdiatype: outstream
+ // bid.params.outstreamAU : N
+ // bid.renderer : N
+ // bid.mediaTypes.video.renderer : Y
+ bid = getThebid();
+ delete bid.params.outstreamAU;
+ delete bid.renderer;
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
+
+ // false: none present; only outstream
+ // mdiatype: outstream
+ // bid.params.outstreamAU : N
+ // bid.renderer : N
+ // bid.mediaTypes.video.renderer : N
+ bid = getThebid();
+ delete bid.params.outstreamAU;
+ delete bid.renderer;
+ delete bid.mediaTypes.video.renderer;
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
+
+ // true: none present; outstream + Banner
+ // mdiatype: outstream, banner
+ // bid.params.outstreamAU : N
+ // bid.renderer : N
+ // bid.mediaTypes.video.renderer : N
+ bid = getThebid();
+ delete bid.params.outstreamAU;
+ delete bid.renderer;
+ delete bid.mediaTypes.video.renderer;
+ bid.mediaTypes.banner = {sizes: [ [300, 250], [300, 600] ]};
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
+
+ // true: none present; outstream + Native
+ // mdiatype: outstream, native
+ // bid.params.outstreamAU : N
+ // bid.renderer : N
+ // bid.mediaTypes.video.renderer : N
+ bid = getThebid();
+ delete bid.params.outstreamAU;
+ delete bid.renderer;
+ delete bid.mediaTypes.video.renderer;
+ bid.mediaTypes.native = {}
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
+ });
+ }
});
describe('Request formation', function () {
@@ -1116,18 +1118,6 @@ describe('PubMatic adapter', function () {
expect(data.test).to.equal(undefined);
});
- // disabled this test case as it refreshes the whole suite when in karma watch mode
- // todo: needs a fix
- xit('test flag set to 1 when pubmaticTest=true is present in page url', function() {
- window.location.href += '#pubmaticTest=true';
- // now all the test cases below will have window.location.href with #pubmaticTest=true
- let request = spec.buildRequests(bidRequests, {
- auctionId: 'new-auction-id'
- });
- let data = JSON.parse(request.data);
- expect(data.test).to.equal(1);
- });
-
it('Request params check', function () {
let request = spec.buildRequests(bidRequests, {
auctionId: 'new-auction-id'
@@ -2055,29 +2045,31 @@ describe('PubMatic adapter', function () {
expect(data.bidfloor).to.equal(undefined);
});
- it('ignore floormodule o/p if floor is not number', function() {
- floorModuleTestData.banner['300x250'].floor = 'Not-a-Number';
- floorModuleTestData.banner['300x600'].floor = 'Not-a-Number';
- newRequest[0].params.kadfloor = undefined;
- let request = spec.buildRequests(newRequest, {
- auctionId: 'new-auction-id'
+ if (FEATURES.VIDEO) {
+ it('ignore floormodule o/p if floor is not number', function() {
+ floorModuleTestData.banner['300x250'].floor = 'Not-a-Number';
+ floorModuleTestData.banner['300x600'].floor = 'Not-a-Number';
+ newRequest[0].params.kadfloor = undefined;
+ let request = spec.buildRequests(newRequest, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+ data = data.imp[0];
+ expect(data.bidfloor).to.equal(2.5); // video will be lowest now
});
- let data = JSON.parse(request.data);
- data = data.imp[0];
- expect(data.bidfloor).to.equal(2.5); // video will be lowest now
- });
- it('ignore floormodule o/p if currency is not matched', function() {
- floorModuleTestData.banner['300x250'].currency = 'INR';
- floorModuleTestData.banner['300x600'].currency = 'INR';
- newRequest[0].params.kadfloor = undefined;
- let request = spec.buildRequests(newRequest, {
- auctionId: 'new-auction-id'
+ it('ignore floormodule o/p if currency is not matched', function() {
+ floorModuleTestData.banner['300x250'].currency = 'INR';
+ floorModuleTestData.banner['300x600'].currency = 'INR';
+ newRequest[0].params.kadfloor = undefined;
+ let request = spec.buildRequests(newRequest, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+ data = data.imp[0];
+ expect(data.bidfloor).to.equal(2.5); // video will be lowest now
});
- let data = JSON.parse(request.data);
- data = data.imp[0];
- expect(data.bidfloor).to.equal(2.5); // video will be lowest now
- });
+ }
it('kadfloor is not passed, use minimum from floorModule', function() {
newRequest[0].params.kadfloor = undefined;
@@ -2556,114 +2548,6 @@ describe('PubMatic adapter', function () {
});
});
- it('Request params check for video ad', function () {
- let request = spec.buildRequests(videoBidRequests, {
- auctionId: 'new-auction-id'
- });
- let data = JSON.parse(request.data);
- expect(data.imp[0].video).to.exist;
- expect(data.imp[0].tagid).to.equal('Div1');
- expect(data.imp[0]['video']['mimes']).to.exist.and.to.be.an('array');
- expect(data.imp[0]['video']['mimes'][0]).to.equal(videoBidRequests[0].params.video['mimes'][0]);
- expect(data.imp[0]['video']['mimes'][1]).to.equal(videoBidRequests[0].params.video['mimes'][1]);
- expect(data.imp[0]['video']['minduration']).to.equal(videoBidRequests[0].params.video['minduration']);
- expect(data.imp[0]['video']['maxduration']).to.equal(videoBidRequests[0].params.video['maxduration']);
- expect(data.imp[0]['video']['startdelay']).to.equal(videoBidRequests[0].params.video['startdelay']);
-
- expect(data.imp[0]['video']['playbackmethod']).to.exist.and.to.be.an('array');
- expect(data.imp[0]['video']['playbackmethod'][0]).to.equal(videoBidRequests[0].params.video['playbackmethod'][0]);
- expect(data.imp[0]['video']['playbackmethod'][1]).to.equal(videoBidRequests[0].params.video['playbackmethod'][1]);
-
- expect(data.imp[0]['video']['api']).to.exist.and.to.be.an('array');
- expect(data.imp[0]['video']['api'][0]).to.equal(videoBidRequests[0].params.video['api'][0]);
- expect(data.imp[0]['video']['api'][1]).to.equal(videoBidRequests[0].params.video['api'][1]);
-
- expect(data.imp[0]['video']['protocols']).to.exist.and.to.be.an('array');
- expect(data.imp[0]['video']['protocols'][0]).to.equal(videoBidRequests[0].params.video['protocols'][0]);
- expect(data.imp[0]['video']['protocols'][1]).to.equal(videoBidRequests[0].params.video['protocols'][1]);
-
- expect(data.imp[0]['video']['battr']).to.exist.and.to.be.an('array');
- expect(data.imp[0]['video']['battr'][0]).to.equal(videoBidRequests[0].params.video['battr'][0]);
- expect(data.imp[0]['video']['battr'][1]).to.equal(videoBidRequests[0].params.video['battr'][1]);
-
- expect(data.imp[0]['video']['linearity']).to.equal(videoBidRequests[0].params.video['linearity']);
- expect(data.imp[0]['video']['placement']).to.equal(videoBidRequests[0].params.video['placement']);
- expect(data.imp[0]['video']['minbitrate']).to.equal(videoBidRequests[0].params.video['minbitrate']);
- expect(data.imp[0]['video']['maxbitrate']).to.equal(videoBidRequests[0].params.video['maxbitrate']);
-
- 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]);
- });
-
- it('Request params check for 1 banner and 1 video ad', function () {
- let request = spec.buildRequests(multipleMediaRequests, {
- auctionId: 'new-auction-id'
- });
- let data = JSON.parse(request.data);
-
- expect(data.imp).to.be.an('array')
- expect(data.imp).with.length.above(1);
-
- expect(data.at).to.equal(1); // auction type
- expect(data.cur[0]).to.equal('USD'); // currency
- expect(data.site.domain).to.be.a('string'); // domain should be set
- expect(data.site.page).to.equal(multipleMediaRequests[0].params.kadpageurl); // forced pageURL
- expect(data.site.publisher.id).to.equal(multipleMediaRequests[0].params.publisherId); // publisher Id
- expect(data.user.yob).to.equal(parseInt(multipleMediaRequests[0].params.yob)); // YOB
- expect(data.user.gender).to.equal(multipleMediaRequests[0].params.gender); // Gender
- expect(data.device.geo.lat).to.equal(parseFloat(multipleMediaRequests[0].params.lat)); // Latitude
- expect(data.device.geo.lon).to.equal(parseFloat(multipleMediaRequests[0].params.lon)); // Lognitude
- expect(data.user.geo.lat).to.equal(parseFloat(multipleMediaRequests[0].params.lat)); // Latitude
- expect(data.user.geo.lon).to.equal(parseFloat(multipleMediaRequests[0].params.lon)); // Lognitude
- expect(data.ext.wrapper.wv).to.equal($$REPO_AND_VERSION$$); // Wrapper Version
- expect(data.ext.wrapper.transactionId).to.equal(multipleMediaRequests[0].transactionId); // Prebid TransactionId
- expect(data.ext.wrapper.wiid).to.equal(multipleMediaRequests[0].params.wiid); // OpenWrap: Wrapper Impression ID
- expect(data.ext.wrapper.profile).to.equal(parseInt(multipleMediaRequests[0].params.profId)); // OpenWrap: Wrapper Profile ID
- expect(data.ext.wrapper.version).to.equal(parseInt(multipleMediaRequests[0].params.verId)); // OpenWrap: Wrapper Profile Version ID
-
- // banner imp object check
- expect(data.imp[0].id).to.equal(multipleMediaRequests[0].bidId); // Prebid bid id is passed as id
- expect(data.imp[0].bidfloor).to.equal(parseFloat(multipleMediaRequests[0].params.kadfloor)); // kadfloor
- expect(data.imp[0].tagid).to.equal('/15671365/DMDemo'); // tagid
- expect(data.imp[0].banner.w).to.equal(300); // width
- expect(data.imp[0].banner.h).to.equal(250); // height
- expect(data.imp[0].ext.pmZoneId).to.equal(multipleMediaRequests[0].params.pmzoneid.split(',').slice(0, 50).map(id => id.trim()).join()); // pmzoneid
-
- // video imp object check
- expect(data.imp[1].video).to.exist;
- expect(data.imp[1].tagid).to.equal('Div1');
- expect(data.imp[1]['video']['mimes']).to.exist.and.to.be.an('array');
- expect(data.imp[1]['video']['mimes'][0]).to.equal(multipleMediaRequests[1].params.video['mimes'][0]);
- expect(data.imp[1]['video']['mimes'][1]).to.equal(multipleMediaRequests[1].params.video['mimes'][1]);
- expect(data.imp[1]['video']['minduration']).to.equal(multipleMediaRequests[1].params.video['minduration']);
- expect(data.imp[1]['video']['maxduration']).to.equal(multipleMediaRequests[1].params.video['maxduration']);
- expect(data.imp[1]['video']['startdelay']).to.equal(multipleMediaRequests[1].params.video['startdelay']);
-
- expect(data.imp[1]['video']['playbackmethod']).to.exist.and.to.be.an('array');
- expect(data.imp[1]['video']['playbackmethod'][0]).to.equal(multipleMediaRequests[1].params.video['playbackmethod'][0]);
- expect(data.imp[1]['video']['playbackmethod'][1]).to.equal(multipleMediaRequests[1].params.video['playbackmethod'][1]);
-
- expect(data.imp[1]['video']['api']).to.exist.and.to.be.an('array');
- expect(data.imp[1]['video']['api'][0]).to.equal(multipleMediaRequests[1].params.video['api'][0]);
- expect(data.imp[1]['video']['api'][1]).to.equal(multipleMediaRequests[1].params.video['api'][1]);
-
- expect(data.imp[1]['video']['protocols']).to.exist.and.to.be.an('array');
- expect(data.imp[1]['video']['protocols'][0]).to.equal(multipleMediaRequests[1].params.video['protocols'][0]);
- expect(data.imp[1]['video']['protocols'][1]).to.equal(multipleMediaRequests[1].params.video['protocols'][1]);
-
- expect(data.imp[1]['video']['battr']).to.exist.and.to.be.an('array');
- expect(data.imp[1]['video']['battr'][0]).to.equal(multipleMediaRequests[1].params.video['battr'][0]);
- expect(data.imp[1]['video']['battr'][1]).to.equal(multipleMediaRequests[1].params.video['battr'][1]);
-
- expect(data.imp[1]['video']['linearity']).to.equal(multipleMediaRequests[1].params.video['linearity']);
- expect(data.imp[1]['video']['placement']).to.equal(multipleMediaRequests[1].params.video['placement']);
- expect(data.imp[1]['video']['minbitrate']).to.equal(multipleMediaRequests[1].params.video['minbitrate']);
- expect(data.imp[1]['video']['maxbitrate']).to.equal(multipleMediaRequests[1].params.video['maxbitrate']);
-
- expect(data.imp[1]['video']['w']).to.equal(multipleMediaRequests[1].mediaTypes.video.playerSize[0]);
- expect(data.imp[1]['video']['h']).to.equal(multipleMediaRequests[1].mediaTypes.video.playerSize[1]);
- });
-
it('should pass device.sua if present in bidderRequest fpd ortb2 object', function () {
const suaObject = {'source': 2, 'platform': {'brand': 'macOS', 'version': ['12', '4', '0']}, 'browsers': [{'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']}], 'mobile': 0, 'model': '', 'bitness': '64', 'architecture': 'x86'};
let request = spec.buildRequests(multipleMediaRequests, {
@@ -2723,127 +2607,6 @@ describe('PubMatic adapter', function () {
expect(data.imp[0]['native']['request']).to.exist.and.to.equal(validnativeBidImpressionWithAllParams.native.request);
});
- it('Request params - should handle banner and video format in single adunit', function() {
- let request = spec.buildRequests(bannerAndVideoBidRequests, {
- auctionId: 'new-auction-id'
- });
- let data = JSON.parse(request.data);
- data = data.imp[0];
- expect(data.banner).to.exist;
- expect(data.banner.w).to.equal(300);
- expect(data.banner.h).to.equal(250);
- expect(data.banner.format).to.exist;
- expect(data.banner.format.length).to.equal(bannerAndVideoBidRequests[0].mediaTypes.banner.sizes.length);
-
- // Case: when size is not present in adslo
- bannerAndVideoBidRequests[0].params.adSlot = '/15671365/DMDemo';
- request = spec.buildRequests(bannerAndVideoBidRequests, {
- auctionId: 'new-auction-id'
- });
- data = JSON.parse(request.data);
- data = data.imp[0];
- expect(data.banner).to.exist;
- expect(data.banner.w).to.equal(bannerAndVideoBidRequests[0].mediaTypes.banner.sizes[0][0]);
- expect(data.banner.h).to.equal(bannerAndVideoBidRequests[0].mediaTypes.banner.sizes[0][1]);
- expect(data.banner.format).to.exist;
- expect(data.banner.format.length).to.equal(bannerAndVideoBidRequests[0].mediaTypes.banner.sizes.length - 1);
-
- expect(data.video).to.exist;
- expect(data.video.w).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[0]);
- expect(data.video.h).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[1]);
- });
-
- it('Request params - banner and video req in single adslot - should ignore banner imp if banner size is set to fluid and send video imp object', function () {
- /* Adslot configured for banner and video.
- banner size is set to [['fluid'], [300, 250]]
- adslot specifies a size as 300x250
- => banner imp object should have primary w and h set to 300 and 250. fluid is ignored
- */
- bannerAndVideoBidRequests[0].mediaTypes.banner.sizes = [['fluid'], [160, 600]];
-
- let request = spec.buildRequests(bannerAndVideoBidRequests, {
- auctionId: 'new-auction-id'
- });
- let data = JSON.parse(request.data);
- data = data.imp[0];
-
- expect(data.banner).to.exist;
- expect(data.banner.w).to.equal(300);
- expect(data.banner.h).to.equal(250);
- expect(data.banner.format).to.exist;
- expect(data.banner.format[0].w).to.equal(160);
- expect(data.banner.format[0].h).to.equal(600);
-
- /* Adslot configured for banner and video.
- banner size is set to [['fluid'], [300, 250]]
- adslot does not specify any size
- => banner imp object should have primary w and h set to 300 and 250. fluid is ignored
- */
- bannerAndVideoBidRequests[0].mediaTypes.banner.sizes = [['fluid'], [160, 600]];
- bannerAndVideoBidRequests[0].params.adSlot = '/15671365/DMDemo';
-
- request = spec.buildRequests(bannerAndVideoBidRequests, {
- auctionId: 'new-auction-id'
- });
- data = JSON.parse(request.data);
- data = data.imp[0];
-
- expect(data.banner).to.exist;
- expect(data.banner.w).to.equal(160);
- expect(data.banner.h).to.equal(600);
- expect(data.banner.format).to.not.exist;
-
- /* Adslot configured for banner and video.
- banner size is set to [[728 90], ['fluid'], [300, 250]]
- adslot does not specify any size
- => banner imp object should have primary w and h set to 728 and 90.
- banner.format should have 300, 250 set in it
- fluid is ignore
- */
-
- bannerAndVideoBidRequests[0].mediaTypes.banner.sizes = [[728, 90], ['fluid'], [300, 250]];
- request = spec.buildRequests(bannerAndVideoBidRequests, {
- auctionId: 'new-auction-id'
- });
- data = JSON.parse(request.data);
- data = data.imp[0];
-
- expect(data.banner).to.exist;
- expect(data.banner.w).to.equal(728);
- expect(data.banner.h).to.equal(90);
- expect(data.banner.format).to.exist;
- expect(data.banner.format[0].w).to.equal(300);
- expect(data.banner.format[0].h).to.equal(250);
-
- /* Adslot configured for banner and video.
- banner size is set to [['fluid']]
- adslot does not specify any size
- => banner object should not be sent in the request. only video should be sent.
- */
-
- bannerAndVideoBidRequests[0].mediaTypes.banner.sizes = [['fluid']];
- request = spec.buildRequests(bannerAndVideoBidRequests, {
- auctionId: 'new-auction-id'
- });
- data = JSON.parse(request.data);
- data = data.imp[0];
-
- expect(data.banner).to.not.exist;
- expect(data.video).to.exist;
- });
-
- it('Request params - should not contain banner imp if mediaTypes.banner is not present and sizes is specified in bid.sizes', function() {
- delete bannerAndVideoBidRequests[0].mediaTypes.banner;
- bannerAndVideoBidRequests[0].params.sizes = [300, 250];
-
- let request = spec.buildRequests(bannerAndVideoBidRequests, {
- auctionId: 'new-auction-id'
- });
- let data = JSON.parse(request.data);
- data = data.imp[0];
- expect(data.banner).to.not.exist;
- });
-
it('Request params - should handle banner and native format in single adunit', function() {
let request = spec.buildRequests(bannerAndNativeBidRequests, {
auctionId: 'new-auction-id'
@@ -2861,58 +2624,6 @@ describe('PubMatic adapter', function () {
expect(data.native.request).to.exist;
});
- it('Request params - should handle video and native format in single adunit', function() {
- let request = spec.buildRequests(videoAndNativeBidRequests, {
- auctionId: 'new-auction-id'
- });
- let data = JSON.parse(request.data);
- data = data.imp[0];
-
- expect(data.video).to.exist;
- expect(data.video.w).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[0]);
- expect(data.video.h).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[1]);
-
- expect(data.native).to.exist;
- expect(data.native.request).to.exist;
- });
-
- it('Request params - should handle banner, video and native format in single adunit', function() {
- let request = spec.buildRequests(bannerVideoAndNativeBidRequests, {
- auctionId: 'new-auction-id'
- });
- let data = JSON.parse(request.data);
- data = data.imp[0];
-
- expect(data.banner).to.exist;
- expect(data.banner.w).to.equal(300);
- expect(data.banner.h).to.equal(250);
- expect(data.banner.format).to.exist;
- expect(data.banner.format.length).to.equal(bannerAndNativeBidRequests[0].mediaTypes.banner.sizes.length);
-
- expect(data.video).to.exist;
- expect(data.video.w).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[0]);
- expect(data.video.h).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[1]);
-
- expect(data.native).to.exist;
- expect(data.native.request).to.exist;
- });
-
- it('Request params - should not add banner object if mediaTypes.banner is missing, but adunits.sizes is present', function() {
- delete bannerAndNativeBidRequests[0].mediaTypes.banner;
- bannerAndNativeBidRequests[0].sizes = [729, 90];
-
- let request = spec.buildRequests(bannerAndNativeBidRequests, {
- auctionId: 'new-auction-id'
- });
- let data = JSON.parse(request.data);
- data = data.imp[0];
-
- expect(data.banner).to.not.exist;
-
- expect(data.native).to.exist;
- expect(data.native.request).to.exist;
- });
-
it('Request params - banner and native multiformat request - should have native object incase of invalid config present', function() {
bannerAndNativeBidRequests[0].mediaTypes.native = {
title: { required: true },
@@ -2936,115 +2647,399 @@ describe('PubMatic adapter', function () {
expect(data.native).to.exist;
});
- it('Request params - video and native multiformat request - should have native object incase of invalid config present', function() {
- videoAndNativeBidRequests[0].mediaTypes.native = {
- title: { required: true },
- image: { required: true },
- sponsoredBy: { required: true },
- clickUrl: { required: true }
- };
- videoAndNativeBidRequests[0].nativeParams = {
- title: { required: true },
- image: { required: true },
- sponsoredBy: { required: true },
- clickUrl: { required: true }
- }
- let request = spec.buildRequests(videoAndNativeBidRequests, {
+ it('Request params - should not add banner object if mediaTypes.banner is missing, but adunits.sizes is present', function() {
+ delete bannerAndNativeBidRequests[0].mediaTypes.banner;
+ bannerAndNativeBidRequests[0].sizes = [729, 90];
+
+ let request = spec.buildRequests(bannerAndNativeBidRequests, {
auctionId: 'new-auction-id'
});
let data = JSON.parse(request.data);
data = data.imp[0];
- expect(data.video).to.exist;
+ expect(data.banner).to.not.exist;
+
expect(data.native).to.exist;
+ expect(data.native.request).to.exist;
});
- it('should build video impression if video params are present in adunit.mediaTypes instead of bid.params', function() {
- let videoReq = [{
- 'bidder': 'pubmatic',
- 'params': {
- 'adSlot': 'SLOT_NHB1@728x90',
- 'publisherId': '5890',
- },
- 'mediaTypes': {
- 'video': {
- 'playerSize': [
- [640, 480]
- ],
- 'protocols': [1, 2, 5],
- 'context': 'instream',
- 'mimes': ['video/flv'],
- 'skip': 1,
- 'linearity': 2
- }
- },
- 'adUnitCode': 'video1',
- 'transactionId': 'adc36682-887c-41e9-9848-8b72c08332c0',
- 'sizes': [
- [640, 480]
- ],
- 'bidId': '21b59b1353ba82',
- 'bidderRequestId': '1a08245305e6dd',
- 'auctionId': 'bad3a743-7491-4d19-9a96-b0a69dd24a67',
- 'src': 'client',
- 'bidRequestsCount': 1,
- 'bidderRequestsCount': 1,
- 'bidderWinsCount': 0
- }]
- let request = spec.buildRequests(videoReq, {
- auctionId: 'new-auction-id'
+ if (FEATURES.VIDEO) {
+ it('Request params - should not contain banner imp if mediaTypes.banner is not present and sizes is specified in bid.sizes', function() {
+ delete bannerAndVideoBidRequests[0].mediaTypes.banner;
+ bannerAndVideoBidRequests[0].params.sizes = [300, 250];
+
+ let request = spec.buildRequests(bannerAndVideoBidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+ data = data.imp[0];
+ expect(data.banner).to.not.exist;
});
- let data = JSON.parse(request.data);
- data = data.imp[0];
- expect(data.video).to.exist;
- });
- it('should build video impression with overwriting video params present in adunit.mediaTypes with bid.params', function() {
- let videoReq = [{
- 'bidder': 'pubmatic',
- 'params': {
- 'adSlot': 'SLOT_NHB1@728x90',
- 'publisherId': '5890',
- 'video': {
- 'mimes': ['video/mp4'],
- 'protocols': [1, 2, 5],
- 'linearity': 1
- }
- },
- 'mediaTypes': {
- 'video': {
- 'playerSize': [
- [640, 480]
- ],
- 'protocols': [1, 2, 5],
- 'context': 'instream',
- 'mimes': ['video/flv'],
- 'skip': 1,
- 'linearity': 2
- }
- },
- 'adUnitCode': 'video1',
- 'transactionId': 'adc36682-887c-41e9-9848-8b72c08332c0',
- 'sizes': [
- [640, 480]
- ],
- 'bidId': '21b59b1353ba82',
- 'bidderRequestId': '1a08245305e6dd',
- 'auctionId': 'bad3a743-7491-4d19-9a96-b0a69dd24a67',
- 'src': 'client',
- 'bidRequestsCount': 1,
- 'bidderRequestsCount': 1,
- 'bidderWinsCount': 0
- }]
- let request = spec.buildRequests(videoReq, {
- auctionId: 'new-auction-id'
+ it('Request params check for 1 banner and 1 video ad', function () {
+ let request = spec.buildRequests(multipleMediaRequests, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+
+ expect(data.imp).to.be.an('array')
+ expect(data.imp).with.length.above(1);
+
+ expect(data.at).to.equal(1); // auction type
+ expect(data.cur[0]).to.equal('USD'); // currency
+ expect(data.site.domain).to.be.a('string'); // domain should be set
+ expect(data.site.page).to.equal(multipleMediaRequests[0].params.kadpageurl); // forced pageURL
+ expect(data.site.publisher.id).to.equal(multipleMediaRequests[0].params.publisherId); // publisher Id
+ expect(data.user.yob).to.equal(parseInt(multipleMediaRequests[0].params.yob)); // YOB
+ expect(data.user.gender).to.equal(multipleMediaRequests[0].params.gender); // Gender
+ expect(data.device.geo.lat).to.equal(parseFloat(multipleMediaRequests[0].params.lat)); // Latitude
+ expect(data.device.geo.lon).to.equal(parseFloat(multipleMediaRequests[0].params.lon)); // Lognitude
+ expect(data.user.geo.lat).to.equal(parseFloat(multipleMediaRequests[0].params.lat)); // Latitude
+ expect(data.user.geo.lon).to.equal(parseFloat(multipleMediaRequests[0].params.lon)); // Lognitude
+ expect(data.ext.wrapper.wv).to.equal($$REPO_AND_VERSION$$); // Wrapper Version
+ expect(data.ext.wrapper.transactionId).to.equal(multipleMediaRequests[0].transactionId); // Prebid TransactionId
+ expect(data.ext.wrapper.wiid).to.equal(multipleMediaRequests[0].params.wiid); // OpenWrap: Wrapper Impression ID
+ expect(data.ext.wrapper.profile).to.equal(parseInt(multipleMediaRequests[0].params.profId)); // OpenWrap: Wrapper Profile ID
+ expect(data.ext.wrapper.version).to.equal(parseInt(multipleMediaRequests[0].params.verId)); // OpenWrap: Wrapper Profile Version ID
+
+ // banner imp object check
+ expect(data.imp[0].id).to.equal(multipleMediaRequests[0].bidId); // Prebid bid id is passed as id
+ expect(data.imp[0].bidfloor).to.equal(parseFloat(multipleMediaRequests[0].params.kadfloor)); // kadfloor
+ expect(data.imp[0].tagid).to.equal('/15671365/DMDemo'); // tagid
+ expect(data.imp[0].banner.w).to.equal(300); // width
+ expect(data.imp[0].banner.h).to.equal(250); // height
+ expect(data.imp[0].ext.pmZoneId).to.equal(multipleMediaRequests[0].params.pmzoneid.split(',').slice(0, 50).map(id => id.trim()).join()); // pmzoneid
+
+ // video imp object check
+ expect(data.imp[1].video).to.exist;
+ expect(data.imp[1].tagid).to.equal('Div1');
+ expect(data.imp[1]['video']['mimes']).to.exist.and.to.be.an('array');
+ expect(data.imp[1]['video']['mimes'][0]).to.equal(multipleMediaRequests[1].params.video['mimes'][0]);
+ expect(data.imp[1]['video']['mimes'][1]).to.equal(multipleMediaRequests[1].params.video['mimes'][1]);
+ expect(data.imp[1]['video']['minduration']).to.equal(multipleMediaRequests[1].params.video['minduration']);
+ expect(data.imp[1]['video']['maxduration']).to.equal(multipleMediaRequests[1].params.video['maxduration']);
+ expect(data.imp[1]['video']['startdelay']).to.equal(multipleMediaRequests[1].params.video['startdelay']);
+
+ expect(data.imp[1]['video']['playbackmethod']).to.exist.and.to.be.an('array');
+ expect(data.imp[1]['video']['playbackmethod'][0]).to.equal(multipleMediaRequests[1].params.video['playbackmethod'][0]);
+ expect(data.imp[1]['video']['playbackmethod'][1]).to.equal(multipleMediaRequests[1].params.video['playbackmethod'][1]);
+
+ expect(data.imp[1]['video']['api']).to.exist.and.to.be.an('array');
+ expect(data.imp[1]['video']['api'][0]).to.equal(multipleMediaRequests[1].params.video['api'][0]);
+ expect(data.imp[1]['video']['api'][1]).to.equal(multipleMediaRequests[1].params.video['api'][1]);
+
+ expect(data.imp[1]['video']['protocols']).to.exist.and.to.be.an('array');
+ expect(data.imp[1]['video']['protocols'][0]).to.equal(multipleMediaRequests[1].params.video['protocols'][0]);
+ expect(data.imp[1]['video']['protocols'][1]).to.equal(multipleMediaRequests[1].params.video['protocols'][1]);
+
+ expect(data.imp[1]['video']['battr']).to.exist.and.to.be.an('array');
+ expect(data.imp[1]['video']['battr'][0]).to.equal(multipleMediaRequests[1].params.video['battr'][0]);
+ expect(data.imp[1]['video']['battr'][1]).to.equal(multipleMediaRequests[1].params.video['battr'][1]);
+
+ expect(data.imp[1]['video']['linearity']).to.equal(multipleMediaRequests[1].params.video['linearity']);
+ expect(data.imp[1]['video']['placement']).to.equal(multipleMediaRequests[1].params.video['placement']);
+ expect(data.imp[1]['video']['minbitrate']).to.equal(multipleMediaRequests[1].params.video['minbitrate']);
+ expect(data.imp[1]['video']['maxbitrate']).to.equal(multipleMediaRequests[1].params.video['maxbitrate']);
+
+ expect(data.imp[1]['video']['w']).to.equal(multipleMediaRequests[1].mediaTypes.video.playerSize[0]);
+ expect(data.imp[1]['video']['h']).to.equal(multipleMediaRequests[1].mediaTypes.video.playerSize[1]);
});
- let data = JSON.parse(request.data);
- data = data.imp[0];
- expect(data.video).to.exist;
- expect(data.video.linearity).to.equal(1);
- });
+ // ================================================
+ it('Request params - should handle banner and video format in single adunit', function() {
+ let request = spec.buildRequests(bannerAndVideoBidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+ data = data.imp[0];
+ expect(data.banner).to.exist;
+ expect(data.banner.w).to.equal(300);
+ expect(data.banner.h).to.equal(250);
+ expect(data.banner.format).to.exist;
+ expect(data.banner.format.length).to.equal(bannerAndVideoBidRequests[0].mediaTypes.banner.sizes.length);
+
+ // Case: when size is not present in adslo
+ bannerAndVideoBidRequests[0].params.adSlot = '/15671365/DMDemo';
+ request = spec.buildRequests(bannerAndVideoBidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ data = JSON.parse(request.data);
+ data = data.imp[0];
+ expect(data.banner).to.exist;
+ expect(data.banner.w).to.equal(bannerAndVideoBidRequests[0].mediaTypes.banner.sizes[0][0]);
+ expect(data.banner.h).to.equal(bannerAndVideoBidRequests[0].mediaTypes.banner.sizes[0][1]);
+ expect(data.banner.format).to.exist;
+ expect(data.banner.format.length).to.equal(bannerAndVideoBidRequests[0].mediaTypes.banner.sizes.length - 1);
+
+ expect(data.video).to.exist;
+ expect(data.video.w).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[0]);
+ expect(data.video.h).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[1]);
+ });
+
+ it('Request params - should handle banner, video and native format in single adunit', function() {
+ let request = spec.buildRequests(bannerVideoAndNativeBidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+ data = data.imp[0];
+
+ expect(data.banner).to.exist;
+ expect(data.banner.w).to.equal(300);
+ expect(data.banner.h).to.equal(250);
+ expect(data.banner.format).to.exist;
+ expect(data.banner.format.length).to.equal(bannerAndNativeBidRequests[0].mediaTypes.banner.sizes.length);
+
+ expect(data.video).to.exist;
+ expect(data.video.w).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[0]);
+ expect(data.video.h).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[1]);
+
+ expect(data.native).to.exist;
+ expect(data.native.request).to.exist;
+ });
+
+ it('Request params - should handle video and native format in single adunit', function() {
+ let request = spec.buildRequests(videoAndNativeBidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+ data = data.imp[0];
+
+ expect(data.video).to.exist;
+ expect(data.video.w).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[0]);
+ expect(data.video.h).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[1]);
+
+ expect(data.native).to.exist;
+ expect(data.native.request).to.exist;
+ });
+
+ it('Request params - banner and video req in single adslot - should ignore banner imp if banner size is set to fluid and send video imp object', function () {
+ /* Adslot configured for banner and video.
+ banner size is set to [['fluid'], [300, 250]]
+ adslot specifies a size as 300x250
+ => banner imp object should have primary w and h set to 300 and 250. fluid is ignored
+ */
+ bannerAndVideoBidRequests[0].mediaTypes.banner.sizes = [['fluid'], [160, 600]];
+
+ let request = spec.buildRequests(bannerAndVideoBidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+ data = data.imp[0];
+
+ expect(data.banner).to.exist;
+ expect(data.banner.w).to.equal(300);
+ expect(data.banner.h).to.equal(250);
+ expect(data.banner.format).to.exist;
+ expect(data.banner.format[0].w).to.equal(160);
+ expect(data.banner.format[0].h).to.equal(600);
+
+ /* Adslot configured for banner and video.
+ banner size is set to [['fluid'], [300, 250]]
+ adslot does not specify any size
+ => banner imp object should have primary w and h set to 300 and 250. fluid is ignored
+ */
+ bannerAndVideoBidRequests[0].mediaTypes.banner.sizes = [['fluid'], [160, 600]];
+ bannerAndVideoBidRequests[0].params.adSlot = '/15671365/DMDemo';
+
+ request = spec.buildRequests(bannerAndVideoBidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ data = JSON.parse(request.data);
+ data = data.imp[0];
+
+ expect(data.banner).to.exist;
+ expect(data.banner.w).to.equal(160);
+ expect(data.banner.h).to.equal(600);
+ expect(data.banner.format).to.not.exist;
+
+ /* Adslot configured for banner and video.
+ banner size is set to [[728 90], ['fluid'], [300, 250]]
+ adslot does not specify any size
+ => banner imp object should have primary w and h set to 728 and 90.
+ banner.format should have 300, 250 set in it
+ fluid is ignore
+ */
+
+ bannerAndVideoBidRequests[0].mediaTypes.banner.sizes = [[728, 90], ['fluid'], [300, 250]];
+ request = spec.buildRequests(bannerAndVideoBidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ data = JSON.parse(request.data);
+ data = data.imp[0];
+
+ expect(data.banner).to.exist;
+ expect(data.banner.w).to.equal(728);
+ expect(data.banner.h).to.equal(90);
+ expect(data.banner.format).to.exist;
+ expect(data.banner.format[0].w).to.equal(300);
+ expect(data.banner.format[0].h).to.equal(250);
+
+ /* Adslot configured for banner and video.
+ banner size is set to [['fluid']]
+ adslot does not specify any size
+ => banner object should not be sent in the request. only video should be sent.
+ */
+
+ bannerAndVideoBidRequests[0].mediaTypes.banner.sizes = [['fluid']];
+ request = spec.buildRequests(bannerAndVideoBidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ data = JSON.parse(request.data);
+ data = data.imp[0];
+
+ expect(data.banner).to.not.exist;
+ expect(data.video).to.exist;
+ });
+
+ it('Request params - video and native multiformat request - should have native object incase of invalid config present', function() {
+ videoAndNativeBidRequests[0].mediaTypes.native = {
+ title: { required: true },
+ image: { required: true },
+ sponsoredBy: { required: true },
+ clickUrl: { required: true }
+ };
+ videoAndNativeBidRequests[0].nativeParams = {
+ title: { required: true },
+ image: { required: true },
+ sponsoredBy: { required: true },
+ clickUrl: { required: true }
+ }
+ let request = spec.buildRequests(videoAndNativeBidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+ data = data.imp[0];
+
+ expect(data.video).to.exist;
+ expect(data.native).to.exist;
+ });
+
+ it('should build video impression if video params are present in adunit.mediaTypes instead of bid.params', function() {
+ let videoReq = [{
+ 'bidder': 'pubmatic',
+ 'params': {
+ 'adSlot': 'SLOT_NHB1@728x90',
+ 'publisherId': '5890',
+ },
+ 'mediaTypes': {
+ 'video': {
+ 'playerSize': [
+ [640, 480]
+ ],
+ 'protocols': [1, 2, 5],
+ 'context': 'instream',
+ 'mimes': ['video/flv'],
+ 'skip': 1,
+ 'linearity': 2
+ }
+ },
+ 'adUnitCode': 'video1',
+ 'transactionId': 'adc36682-887c-41e9-9848-8b72c08332c0',
+ 'sizes': [
+ [640, 480]
+ ],
+ 'bidId': '21b59b1353ba82',
+ 'bidderRequestId': '1a08245305e6dd',
+ 'auctionId': 'bad3a743-7491-4d19-9a96-b0a69dd24a67',
+ 'src': 'client',
+ 'bidRequestsCount': 1,
+ 'bidderRequestsCount': 1,
+ 'bidderWinsCount': 0
+ }]
+ let request = spec.buildRequests(videoReq, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+ data = data.imp[0];
+ expect(data.video).to.exist;
+ });
+
+ it('should build video impression with overwriting video params present in adunit.mediaTypes with bid.params', function() {
+ let videoReq = [{
+ 'bidder': 'pubmatic',
+ 'params': {
+ 'adSlot': 'SLOT_NHB1@728x90',
+ 'publisherId': '5890',
+ 'video': {
+ 'mimes': ['video/mp4'],
+ 'protocols': [1, 2, 5],
+ 'linearity': 1
+ }
+ },
+ 'mediaTypes': {
+ 'video': {
+ 'playerSize': [
+ [640, 480]
+ ],
+ 'protocols': [1, 2, 5],
+ 'context': 'instream',
+ 'mimes': ['video/flv'],
+ 'skip': 1,
+ 'linearity': 2
+ }
+ },
+ 'adUnitCode': 'video1',
+ 'transactionId': 'adc36682-887c-41e9-9848-8b72c08332c0',
+ 'sizes': [
+ [640, 480]
+ ],
+ 'bidId': '21b59b1353ba82',
+ 'bidderRequestId': '1a08245305e6dd',
+ 'auctionId': 'bad3a743-7491-4d19-9a96-b0a69dd24a67',
+ 'src': 'client',
+ 'bidRequestsCount': 1,
+ 'bidderRequestsCount': 1,
+ 'bidderWinsCount': 0
+ }]
+ let request = spec.buildRequests(videoReq, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+ data = data.imp[0];
+
+ expect(data.video).to.exist;
+ expect(data.video.linearity).to.equal(1);
+ });
+
+ it('Request params check for video ad', function () {
+ let request = spec.buildRequests(videoBidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+ expect(data.imp[0].video).to.exist;
+ expect(data.imp[0].tagid).to.equal('Div1');
+ expect(data.imp[0]['video']['mimes']).to.exist.and.to.be.an('array');
+ expect(data.imp[0]['video']['mimes'][0]).to.equal(videoBidRequests[0].params.video['mimes'][0]);
+ expect(data.imp[0]['video']['mimes'][1]).to.equal(videoBidRequests[0].params.video['mimes'][1]);
+ expect(data.imp[0]['video']['minduration']).to.equal(videoBidRequests[0].params.video['minduration']);
+ expect(data.imp[0]['video']['maxduration']).to.equal(videoBidRequests[0].params.video['maxduration']);
+ expect(data.imp[0]['video']['startdelay']).to.equal(videoBidRequests[0].params.video['startdelay']);
+
+ expect(data.imp[0]['video']['playbackmethod']).to.exist.and.to.be.an('array');
+ expect(data.imp[0]['video']['playbackmethod'][0]).to.equal(videoBidRequests[0].params.video['playbackmethod'][0]);
+ expect(data.imp[0]['video']['playbackmethod'][1]).to.equal(videoBidRequests[0].params.video['playbackmethod'][1]);
+
+ expect(data.imp[0]['video']['api']).to.exist.and.to.be.an('array');
+ expect(data.imp[0]['video']['api'][0]).to.equal(videoBidRequests[0].params.video['api'][0]);
+ expect(data.imp[0]['video']['api'][1]).to.equal(videoBidRequests[0].params.video['api'][1]);
+
+ expect(data.imp[0]['video']['protocols']).to.exist.and.to.be.an('array');
+ expect(data.imp[0]['video']['protocols'][0]).to.equal(videoBidRequests[0].params.video['protocols'][0]);
+ expect(data.imp[0]['video']['protocols'][1]).to.equal(videoBidRequests[0].params.video['protocols'][1]);
+
+ expect(data.imp[0]['video']['battr']).to.exist.and.to.be.an('array');
+ expect(data.imp[0]['video']['battr'][0]).to.equal(videoBidRequests[0].params.video['battr'][0]);
+ expect(data.imp[0]['video']['battr'][1]).to.equal(videoBidRequests[0].params.video['battr'][1]);
+
+ expect(data.imp[0]['video']['linearity']).to.equal(videoBidRequests[0].params.video['linearity']);
+ expect(data.imp[0]['video']['placement']).to.equal(videoBidRequests[0].params.video['placement']);
+ expect(data.imp[0]['video']['minbitrate']).to.equal(videoBidRequests[0].params.video['minbitrate']);
+ expect(data.imp[0]['video']['maxbitrate']).to.equal(videoBidRequests[0].params.video['maxbitrate']);
+
+ 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]);
+ });
+ }
});
it('Request params dctr check', function () {
@@ -3573,14 +3568,6 @@ describe('PubMatic adapter', function () {
expect(response[0].mediaType).to.equal('banner');
});
- it('should check for valid video mediaType in case of multiformat request', function() {
- let request = spec.buildRequests(videoBidRequests, {
- auctionId: 'new-auction-id'
- });
- let response = spec.interpretResponse(videoBidResponse, request);
- expect(response[0].mediaType).to.equal('video');
- });
-
it('should check for valid native mediaType in case of multiformat request', function() {
let request = spec.buildRequests(nativeBidRequests, {
auctionId: 'new-auction-id'
@@ -3590,28 +3577,6 @@ describe('PubMatic adapter', function () {
expect(response[0].mediaType).to.equal('native');
});
- it('should assign renderer if bid is video and request is for outstream', function() {
- let request = spec.buildRequests(outstreamBidRequest, validOutstreamBidRequest);
- let response = spec.interpretResponse(outstreamVideoBidResponse, request);
- expect(response[0].renderer).to.exist;
- });
-
- it('should not assign renderer if bidderRequest is not present', function() {
- let request = spec.buildRequests(outstreamBidRequest, {
- auctionId: 'new-auction-id'
- });
- let response = spec.interpretResponse(outstreamVideoBidResponse, request);
- expect(response[0].renderer).to.not.exist;
- });
-
- it('should not assign renderer if bid is video and request is for instream', function() {
- let request = spec.buildRequests(videoBidRequests, {
- auctionId: 'new-auction-id'
- });
- let response = spec.interpretResponse(videoBidResponse, request);
- expect(response[0].renderer).to.not.exist;
- });
-
it('should not assign renderer if bid is native', function() {
let request = spec.buildRequests(nativeBidRequests, {
auctionId: 'new-auction-id'
@@ -3628,154 +3593,186 @@ describe('PubMatic adapter', function () {
expect(response[0].renderer).to.not.exist;
});
- it('should assign mediaType by reading bid.ext.mediaType', function() {
- let newvideoRequests = [{
- 'bidder': 'pubmatic',
- 'params': {
- 'adSlot': 'SLOT_NHB1@728x90',
- 'publisherId': '5670',
- 'video': {
- 'mimes': ['video/mp4'],
- 'skippable': true,
- 'protocols': [1, 2, 5],
- 'linearity': 1
- }
- },
- 'mediaTypes': {
- 'video': {
- 'playerSize': [
- [640, 480]
- ],
- 'protocols': [1, 2, 5],
- 'context': 'instream',
- 'mimes': ['video/flv'],
- 'skippable': false,
- 'skip': 1,
- 'linearity': 2
- }
- },
- 'adUnitCode': 'video1',
- 'transactionId': '803e3750-0bbe-4ffe-a548-b6eca15087bf',
- 'sizes': [
- [640, 480]
- ],
- 'bidId': '2c95df014cfe97',
- 'bidderRequestId': '1fe59391566442',
- 'auctionId': '3a4118ef-fb96-4416-b0b0-3cfc1cebc142',
- 'src': 'client',
- 'bidRequestsCount': 1,
- 'bidderRequestsCount': 1,
- 'bidderWinsCount': 0
- }];
- let newvideoBidResponses = {
- 'body': {
- 'id': '1621441141473',
- 'cur': 'USD',
- 'customdata': 'openrtb1',
- 'ext': {
- 'buyid': 'myBuyId'
+ if (FEATURES.VIDEO) {
+ it('should check for valid video mediaType in case of multiformat request', function() {
+ let request = spec.buildRequests(videoBidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ let response = spec.interpretResponse(videoBidResponse, request);
+ expect(response[0].mediaType).to.equal('video');
+ });
+
+ it('should assign renderer if bid is video and request is for outstream', function() {
+ let request = spec.buildRequests(outstreamBidRequest, validOutstreamBidRequest);
+ let response = spec.interpretResponse(outstreamVideoBidResponse, request);
+ expect(response[0].renderer).to.exist;
+ });
+
+ it('should not assign renderer if bidderRequest is not present', function() {
+ let request = spec.buildRequests(outstreamBidRequest, {
+ auctionId: 'new-auction-id'
+ });
+ let response = spec.interpretResponse(outstreamVideoBidResponse, request);
+ expect(response[0].renderer).to.not.exist;
+ });
+
+ it('should not assign renderer if bid is video and request is for instream', function() {
+ let request = spec.buildRequests(videoBidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ let response = spec.interpretResponse(videoBidResponse, request);
+ expect(response[0].renderer).to.not.exist;
+ });
+
+ it('should assign mediaType by reading bid.ext.mediaType', function() {
+ let newvideoRequests = [{
+ 'bidder': 'pubmatic',
+ 'params': {
+ 'adSlot': 'SLOT_NHB1@728x90',
+ 'publisherId': '5670',
+ 'video': {
+ 'mimes': ['video/mp4'],
+ 'skippable': true,
+ 'protocols': [1, 2, 5],
+ 'linearity': 1
+ }
},
- 'seatbid': [{
- 'bid': [{
- 'id': '2c95df014cfe97',
- 'impid': '2c95df014cfe97',
- 'price': 4.2,
- 'cid': 'test1',
- 'crid': 'test2',
- 'adm': "Acudeo CompatibleVAST 2.0 Instream Test 1VAST 2.0 Instream Test 1",
- 'w': 0,
- 'h': 0,
- 'dealId': 'ASEA-MS-KLY-TTD-DESKTOP-ID-VID-6S-030420',
- 'ext': {
- 'bidtype': 1
- }
- }],
+ 'mediaTypes': {
+ 'video': {
+ 'playerSize': [
+ [640, 480]
+ ],
+ 'protocols': [1, 2, 5],
+ 'context': 'instream',
+ 'mimes': ['video/flv'],
+ 'skippable': false,
+ 'skip': 1,
+ 'linearity': 2
+ }
+ },
+ 'adUnitCode': 'video1',
+ 'transactionId': '803e3750-0bbe-4ffe-a548-b6eca15087bf',
+ 'sizes': [
+ [640, 480]
+ ],
+ 'bidId': '2c95df014cfe97',
+ 'bidderRequestId': '1fe59391566442',
+ 'auctionId': '3a4118ef-fb96-4416-b0b0-3cfc1cebc142',
+ 'src': 'client',
+ 'bidRequestsCount': 1,
+ 'bidderRequestsCount': 1,
+ 'bidderWinsCount': 0
+ }];
+ let newvideoBidResponses = {
+ 'body': {
+ 'id': '1621441141473',
+ 'cur': 'USD',
+ 'customdata': 'openrtb1',
'ext': {
'buyid': 'myBuyId'
- }
- }]
- },
- 'headers': {}
- }
- let newrequest = spec.buildRequests(newvideoRequests, {
- auctionId: 'new-auction-id'
- });
- let newresponse = spec.interpretResponse(newvideoBidResponses, newrequest);
- expect(newresponse[0].mediaType).to.equal('video')
- })
+ },
+ 'seatbid': [{
+ 'bid': [{
+ 'id': '2c95df014cfe97',
+ 'impid': '2c95df014cfe97',
+ 'price': 4.2,
+ 'cid': 'test1',
+ 'crid': 'test2',
+ 'adm': "Acudeo CompatibleVAST 2.0 Instream Test 1VAST 2.0 Instream Test 1",
+ 'w': 0,
+ 'h': 0,
+ 'dealId': 'ASEA-MS-KLY-TTD-DESKTOP-ID-VID-6S-030420',
+ 'ext': {
+ 'bidtype': 1
+ }
+ }],
+ 'ext': {
+ 'buyid': 'myBuyId'
+ }
+ }]
+ },
+ 'headers': {}
+ }
+ let newrequest = spec.buildRequests(newvideoRequests, {
+ auctionId: 'new-auction-id'
+ });
+ let newresponse = spec.interpretResponse(newvideoBidResponses, newrequest);
+ expect(newresponse[0].mediaType).to.equal('video')
+ })
- it('should assign mediaType even if bid.ext.mediaType does not exists', function() {
- let newvideoRequests = [{
- 'bidder': 'pubmatic',
- 'params': {
- 'adSlot': 'SLOT_NHB1@728x90',
- 'publisherId': '5670',
- 'video': {
- 'mimes': ['video/mp4'],
- 'skippable': true,
- 'protocols': [1, 2, 5],
- 'linearity': 1
- }
- },
- 'mediaTypes': {
- 'video': {
- 'playerSize': [
- [640, 480]
- ],
- 'protocols': [1, 2, 5],
- 'context': 'instream',
- 'mimes': ['video/flv'],
- 'skippable': false,
- 'skip': 1,
- 'linearity': 2
- }
- },
- 'adUnitCode': 'video1',
- 'transactionId': '803e3750-0bbe-4ffe-a548-b6eca15087bf',
- 'sizes': [
- [640, 480]
- ],
- 'bidId': '2c95df014cfe97',
- 'bidderRequestId': '1fe59391566442',
- 'auctionId': '3a4118ef-fb96-4416-b0b0-3cfc1cebc142',
- 'src': 'client',
- 'bidRequestsCount': 1,
- 'bidderRequestsCount': 1,
- 'bidderWinsCount': 0
- }];
- let newvideoBidResponses = {
- 'body': {
- 'id': '1621441141473',
- 'cur': 'USD',
- 'customdata': 'openrtb1',
- 'ext': {
- 'buyid': 'myBuyId'
+ it('should assign mediaType even if bid.ext.mediaType does not exists', function() {
+ let newvideoRequests = [{
+ 'bidder': 'pubmatic',
+ 'params': {
+ 'adSlot': 'SLOT_NHB1@728x90',
+ 'publisherId': '5670',
+ 'video': {
+ 'mimes': ['video/mp4'],
+ 'skippable': true,
+ 'protocols': [1, 2, 5],
+ 'linearity': 1
+ }
},
- 'seatbid': [{
- 'bid': [{
- 'id': '2c95df014cfe97',
- 'impid': '2c95df014cfe97',
- 'price': 4.2,
- 'cid': 'test1',
- 'crid': 'test2',
- 'adm': "Acudeo CompatibleVAST 2.0 Instream Test 1VAST 2.0 Instream Test 1",
- 'w': 0,
- 'h': 0,
- 'dealId': 'ASEA-MS-KLY-TTD-DESKTOP-ID-VID-6S-030420'
- }],
+ 'mediaTypes': {
+ 'video': {
+ 'playerSize': [
+ [640, 480]
+ ],
+ 'protocols': [1, 2, 5],
+ 'context': 'instream',
+ 'mimes': ['video/flv'],
+ 'skippable': false,
+ 'skip': 1,
+ 'linearity': 2
+ }
+ },
+ 'adUnitCode': 'video1',
+ 'transactionId': '803e3750-0bbe-4ffe-a548-b6eca15087bf',
+ 'sizes': [
+ [640, 480]
+ ],
+ 'bidId': '2c95df014cfe97',
+ 'bidderRequestId': '1fe59391566442',
+ 'auctionId': '3a4118ef-fb96-4416-b0b0-3cfc1cebc142',
+ 'src': 'client',
+ 'bidRequestsCount': 1,
+ 'bidderRequestsCount': 1,
+ 'bidderWinsCount': 0
+ }];
+ let newvideoBidResponses = {
+ 'body': {
+ 'id': '1621441141473',
+ 'cur': 'USD',
+ 'customdata': 'openrtb1',
'ext': {
'buyid': 'myBuyId'
- }
- }]
- },
- 'headers': {}
- }
- let newrequest = spec.buildRequests(newvideoRequests, {
- auctionId: 'new-auction-id'
+ },
+ 'seatbid': [{
+ 'bid': [{
+ 'id': '2c95df014cfe97',
+ 'impid': '2c95df014cfe97',
+ 'price': 4.2,
+ 'cid': 'test1',
+ 'crid': 'test2',
+ 'adm': "Acudeo CompatibleVAST 2.0 Instream Test 1VAST 2.0 Instream Test 1",
+ 'w': 0,
+ 'h': 0,
+ 'dealId': 'ASEA-MS-KLY-TTD-DESKTOP-ID-VID-6S-030420'
+ }],
+ 'ext': {
+ 'buyid': 'myBuyId'
+ }
+ }]
+ },
+ 'headers': {}
+ }
+ let newrequest = spec.buildRequests(newvideoRequests, {
+ auctionId: 'new-auction-id'
+ });
+ let newresponse = spec.interpretResponse(newvideoBidResponses, newrequest);
+ expect(newresponse[0].mediaType).to.equal('video')
});
- let newresponse = spec.interpretResponse(newvideoBidResponses, newrequest);
- expect(newresponse[0].mediaType).to.equal('video')
- });
+ }
});
describe('Preapare metadata', function () {
@@ -3955,26 +3952,55 @@ describe('PubMatic adapter', function () {
});
});
- describe('Checking for Video.Placement property', function() {
- let sandbox, utilsMock;
- const adUnit = 'Div1';
- const msg_placement_missing = 'Video.Placement param missing for Div1';
- let videoData = {
- battr: [6, 7],
- skipafter: 15,
- maxduration: 50,
- context: 'instream',
- playerSize: [640, 480],
- skip: 0,
- connectiontype: [1, 2, 6],
- skipmin: 10,
- minduration: 10,
- mimes: ['video/mp4', 'video/x-flv'],
- }
+ if (FEATURES.VIDEO) {
+ describe('Checking for Video.Placement property', function() {
+ let sandbox, utilsMock;
+ const adUnit = 'Div1';
+ const msg_placement_missing = 'Video.Placement param missing for Div1';
+ let videoData = {
+ battr: [6, 7],
+ skipafter: 15,
+ maxduration: 50,
+ context: 'instream',
+ playerSize: [640, 480],
+ skip: 0,
+ connectiontype: [1, 2, 6],
+ skipmin: 10,
+ minduration: 10,
+ mimes: ['video/mp4', 'video/x-flv'],
+ }
+ beforeEach(() => {
+ utilsMock = sinon.mock(utils);
+ sandbox = sinon.sandbox.create();
+ sandbox.spy(utils, 'logWarn');
+ });
+
+ afterEach(() => {
+ utilsMock.restore();
+ sandbox.restore();
+ })
+
+ it('should log Video.Placement param missing', function() {
+ checkVideoPlacement(videoData, adUnit);
+ sinon.assert.calledWith(utils.logWarn, msg_placement_missing);
+ })
+ it('shoud not log Video.Placement param missing', function() {
+ videoData['placement'] = 1;
+ checkVideoPlacement(videoData, adUnit);
+ sinon.assert.neverCalledWith(utils.logWarn, msg_placement_missing);
+ })
+ });
+ }
+ });
+
+ if (FEATURES.VIDEO) {
+ describe('Video request params', function() {
+ let sandbox, utilsMock, newVideoRequest;
beforeEach(() => {
utilsMock = sinon.mock(utils);
sandbox = sinon.sandbox.create();
sandbox.spy(utils, 'logWarn');
+ newVideoRequest = utils.deepClone(videoBidRequests)
});
afterEach(() => {
@@ -3982,112 +4008,87 @@ describe('PubMatic adapter', function () {
sandbox.restore();
})
- it('should log Video.Placement param missing', function() {
- checkVideoPlacement(videoData, adUnit);
- sinon.assert.calledWith(utils.logWarn, msg_placement_missing);
- })
- it('shoud not log Video.Placement param missing', function() {
- videoData['placement'] = 1;
- checkVideoPlacement(videoData, adUnit);
- sinon.assert.neverCalledWith(utils.logWarn, msg_placement_missing);
- })
- });
- });
+ it('Should log warning if video params from mediaTypes and params obj of bid are not present', function () {
+ delete newVideoRequest[0].mediaTypes.video;
+ delete newVideoRequest[0].params.video;
- describe('Video request params', function() {
- let sandbox, utilsMock, newVideoRequest;
- beforeEach(() => {
- utilsMock = sinon.mock(utils);
- sandbox = sinon.sandbox.create();
- sandbox.spy(utils, 'logWarn');
- newVideoRequest = utils.deepClone(videoBidRequests)
- });
-
- afterEach(() => {
- utilsMock.restore();
- sandbox.restore();
- })
-
- it('Should log warning if video params from mediaTypes and params obj of bid are not present', function () {
- delete newVideoRequest[0].mediaTypes.video;
- delete newVideoRequest[0].params.video;
+ let request = spec.buildRequests(newVideoRequest, {
+ auctionId: 'new-auction-id'
+ });
- let request = spec.buildRequests(newVideoRequest, {
- auctionId: 'new-auction-id'
+ sinon.assert.calledOnce(utils.logWarn);
+ expect(request).to.equal(undefined);
});
- sinon.assert.calledOnce(utils.logWarn);
- expect(request).to.equal(undefined);
- });
-
- it('Should consider video params from mediaType object of bid', function () {
- delete newVideoRequest[0].params.video;
+ it('Should consider video params from mediaType object of bid', function () {
+ delete newVideoRequest[0].params.video;
- let request = spec.buildRequests(newVideoRequest, {
- auctionId: 'new-auction-id'
- });
- let data = JSON.parse(request.data);
- expect(data.imp[0].video).to.exist;
- 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.imp[0]['video']['battr']).to.equal(undefined);
- });
-
- describe('Assign Deal Tier (i.e. prebidDealPriority)', function () {
- let videoSeatBid, request, newBid;
- // let data = JSON.parse(request.data);
- beforeEach(function () {
- videoSeatBid = videoBidResponse.body.seatbid[0].bid[0];
- // const adpodValidOutstreamBidRequest = validOutstreamBidRequest.bids[0].mediaTypes.video.context = 'adpod';
- request = spec.buildRequests(bidRequests, validOutstreamBidRequest);
- newBid = {
- requestId: '47acc48ad47af5'
- };
- videoSeatBid.ext = videoSeatBid.ext || {};
- videoSeatBid.ext.video = videoSeatBid.ext.video || {};
- // videoBidRequests[0].mediaTypes.video = videoBidRequests[0].mediaTypes.video || {};
- });
-
- it('should not assign video object if deal priority is missing', function () {
- assignDealTier(newBid, videoSeatBid, request);
- expect(newBid.video).to.equal(undefined);
- expect(newBid.video).to.not.exist;
- });
-
- it('should not assign video object if context is not a adpod', function () {
- videoSeatBid.ext.prebiddealpriority = 5;
- assignDealTier(newBid, videoSeatBid, request);
- expect(newBid.video).to.equal(undefined);
- expect(newBid.video).to.not.exist;
+ let request = spec.buildRequests(newVideoRequest, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+ expect(data.imp[0].video).to.exist;
+ 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.imp[0]['video']['battr']).to.equal(undefined);
});
- describe('when video deal tier object is present', function () {
+ describe('Assign Deal Tier (i.e. prebidDealPriority)', function () {
+ let videoSeatBid, request, newBid;
+ // let data = JSON.parse(request.data);
beforeEach(function () {
- videoSeatBid.ext.prebiddealpriority = 5;
- request.bidderRequest.bids[0].mediaTypes.video = {
- ...request.bidderRequest.bids[0].mediaTypes.video,
- context: 'adpod',
- maxduration: 50
+ videoSeatBid = videoBidResponse.body.seatbid[0].bid[0];
+ // const adpodValidOutstreamBidRequest = validOutstreamBidRequest.bids[0].mediaTypes.video.context = 'adpod';
+ request = spec.buildRequests(bidRequests, validOutstreamBidRequest);
+ newBid = {
+ requestId: '47acc48ad47af5'
};
+ videoSeatBid.ext = videoSeatBid.ext || {};
+ videoSeatBid.ext.video = videoSeatBid.ext.video || {};
+ // videoBidRequests[0].mediaTypes.video = videoBidRequests[0].mediaTypes.video || {};
});
- it('should set video deal tier object, when maxduration is present in ext', function () {
+ it('should not assign video object if deal priority is missing', function () {
assignDealTier(newBid, videoSeatBid, request);
- expect(newBid.video.durationSeconds).to.equal(50);
- expect(newBid.video.context).to.equal('adpod');
- expect(newBid.video.dealTier).to.equal(5);
+ expect(newBid.video).to.equal(undefined);
+ expect(newBid.video).to.not.exist;
});
- it('should set video deal tier object, when duration is present in ext', function () {
- videoSeatBid.ext.video.duration = 20;
+ it('should not assign video object if context is not a adpod', function () {
+ videoSeatBid.ext.prebiddealpriority = 5;
assignDealTier(newBid, videoSeatBid, request);
- expect(newBid.video.durationSeconds).to.equal(20);
- expect(newBid.video.context).to.equal('adpod');
- expect(newBid.video.dealTier).to.equal(5);
+ expect(newBid.video).to.equal(undefined);
+ expect(newBid.video).to.not.exist;
+ });
+
+ describe('when video deal tier object is present', function () {
+ beforeEach(function () {
+ videoSeatBid.ext.prebiddealpriority = 5;
+ request.bidderRequest.bids[0].mediaTypes.video = {
+ ...request.bidderRequest.bids[0].mediaTypes.video,
+ context: 'adpod',
+ maxduration: 50
+ };
+ });
+
+ it('should set video deal tier object, when maxduration is present in ext', function () {
+ assignDealTier(newBid, videoSeatBid, request);
+ expect(newBid.video.durationSeconds).to.equal(50);
+ expect(newBid.video.context).to.equal('adpod');
+ expect(newBid.video.dealTier).to.equal(5);
+ });
+
+ it('should set video deal tier object, when duration is present in ext', function () {
+ videoSeatBid.ext.video.duration = 20;
+ assignDealTier(newBid, videoSeatBid, request);
+ expect(newBid.video.durationSeconds).to.equal(20);
+ expect(newBid.video.context).to.equal('adpod');
+ expect(newBid.video.dealTier).to.equal(5);
+ });
});
});
});
- });
+ }
describe('Marketplace params', function () {
let sandbox, utilsMock, newBidRequests, newBidResponses;
diff --git a/test/spec/modules/realvuAnalyticsAdapter_spec.js b/test/spec/modules/realvuAnalyticsAdapter_spec.js
index e51a4e2e3a2..aa17a2c7c75 100644
--- a/test/spec/modules/realvuAnalyticsAdapter_spec.js
+++ b/test/spec/modules/realvuAnalyticsAdapter_spec.js
@@ -81,11 +81,6 @@ describe('RealVu', function() {
result = realvuAnalyticsAdapter.checkIn(bid, ''); // test invalid partnerId ''
});
- it.skip('isInView returns "yes"', () => {
- let inview = realvuAnalyticsAdapter.isInView('ad1');
- expect(inview).to.equal('yes');
- });
-
it('isInView return "NA"', function () {
const adUnitCode = '1234';
let result = realvuAnalyticsAdapter.isInView(adUnitCode);
diff --git a/test/spec/modules/rtbhouseBidAdapter_spec.js b/test/spec/modules/rtbhouseBidAdapter_spec.js
index 792d3ab0a9e..70011cbf244 100644
--- a/test/spec/modules/rtbhouseBidAdapter_spec.js
+++ b/test/spec/modules/rtbhouseBidAdapter_spec.js
@@ -631,10 +631,10 @@ describe('RTBHouseAdapter', () => {
expect(bids[0].meta.advertiserDomains).to.deep.equal(['rtbhouse.com']);
expect(bids[0].native).to.deep.equal({
title: 'Title text',
- clickUrl: encodeURIComponent('https://example.com'),
+ clickUrl: encodeURI('https://example.com'),
impressionTrackers: ['https://example.com/imptracker'],
image: {
- url: encodeURIComponent('https://example.com/image.jpg'),
+ url: encodeURI('https://example.com/image.jpg'),
width: 150,
height: 50
},
diff --git a/test/spec/modules/vidoomyBidAdapter_spec.js b/test/spec/modules/vidoomyBidAdapter_spec.js
index 607fdf4b5b8..38fa872e6b8 100644
--- a/test/spec/modules/vidoomyBidAdapter_spec.js
+++ b/test/spec/modules/vidoomyBidAdapter_spec.js
@@ -162,6 +162,29 @@ describe('vidoomyBidAdapter', function() {
expect(request[0].data.schain).to.eq(serializedForm);
});
+ it('should return standard json formated eids', function () {
+ const eids = [{
+ source: 'pubcid.org',
+ uids: [
+ {
+ id: 'some-random-id-value-1',
+ atype: 1
+ }
+ ]
+ },
+ {
+ source: 'adserver.org',
+ uids: [{
+ id: 'some-random-id-value-2',
+ atype: 1
+ }]
+ }]
+ bidRequests[0].userIdAsEids = eids
+ const bidRequest = spec.buildRequests(bidRequests, bidderRequest);
+ expect(bidRequest[0].data).to.include.any.keys('eids');
+ expect(JSON.parse(bidRequest[0].data.eids)).to.eql(eids);
+ });
+
it('should set the bidfloor if getFloor module is undefined but static bidfloor is present', function () {
const request = { ...bidRequests[0], params: { bidfloor: 2.5 } }
const req = spec.buildRequests([request], bidderRequest)[0];
@@ -196,6 +219,55 @@ describe('vidoomyBidAdapter', function() {
expect(bidRequest.data.bidfloor).to.equal(bidfloor);
});
});
+
+ describe('badv, bcat, bapp, btype, battr', function () {
+ const bidderRequestNew = {
+ ...bidderRequest,
+ bcat: ['EX1', 'EX2', 'EX3'],
+ badv: ['site.com'],
+ bapp: ['app.com'],
+ btype: [1, 2, 3],
+ battr: [1, 2, 3]
+ }
+ const request = spec.buildRequests(bidRequests, bidderRequestNew);
+ it('should have badv, bcat, bapp, btype, battr in request', function () {
+ expect(request[0].data).to.include.any.keys('badv');
+ expect(request[0].data).to.include.any.keys('bcat');
+ expect(request[0].data).to.include.any.keys('bapp');
+ expect(request[0].data).to.include.any.keys('btype');
+ expect(request[0].data).to.include.any.keys('battr');
+ })
+
+ it('should have equal badv, bcat, bapp, btype, battr in request', function () {
+ expect(request[0].badv).to.deep.equal(bidderRequest.refererInfo.badv);
+ expect(request[0].bcat).to.deep.equal(bidderRequest.refererInfo.bcat);
+ expect(request[0].bapp).to.deep.equal(bidderRequest.refererInfo.bapp);
+ expect(request[0].btype).to.deep.equal(bidderRequest.refererInfo.btype);
+ expect(request[0].battr).to.deep.equal(bidderRequest.refererInfo.battr);
+ })
+ })
+
+ describe('first party data', function () {
+ const bidderRequest2 = {
+ ...bidderRequest,
+ ortb2: {
+ bcat: ['EX1', 'EX2', 'EX3'],
+ badv: ['site.com'],
+ bapp: ['app.com'],
+ btype: [1, 2, 3],
+ battr: [1, 2, 3]
+ }
+ }
+ const request = spec.buildRequests(bidRequests, bidderRequest2);
+
+ it('should have badv, bcat, bapp, btype, battr in request and equal to bidderRequest.ortb2', function () {
+ expect(request[0].data.bcat).to.deep.equal(bidderRequest2.ortb2.bcat)
+ expect(request[0].data.badv).to.deep.equal(bidderRequest2.ortb2.badv)
+ expect(request[0].data.bapp).to.deep.equal(bidderRequest2.ortb2.bapp);
+ expect(request[0].data.btype).to.deep.equal(bidderRequest2.ortb2.btype);
+ expect(request[0].data.battr).to.deep.equal(bidderRequest2.ortb2.battr);
+ });
+ });
});
describe('interpretResponse', function () {
diff --git a/test/spec/modules/yieldmoBidAdapter_spec.js b/test/spec/modules/yieldmoBidAdapter_spec.js
index d6bf15ff9d4..3706f770da8 100644
--- a/test/spec/modules/yieldmoBidAdapter_spec.js
+++ b/test/spec/modules/yieldmoBidAdapter_spec.js
@@ -212,7 +212,7 @@ describe('YieldmoAdapter', function () {
expect(data.hasOwnProperty('h')).to.be.true;
expect(data.hasOwnProperty('w')).to.be.true;
expect(data.hasOwnProperty('pubcid')).to.be.true;
- expect(data.userConsent).to.equal('{"gdprApplies":"","cmp":""}');
+ expect(data.userConsent).to.equal('{"gdprApplies":"","cmp":"","gpp":"","gpp_sid":[]}');
expect(data.us_privacy).to.equal('');
});
@@ -262,6 +262,24 @@ describe('YieldmoAdapter', function () {
JSON.stringify({
gdprApplies: true,
cmp: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==',
+ gpp: '',
+ gpp_sid: [],
+ })
+ );
+ });
+
+ it('should add gpp information to request if available', () => {
+ const gppConsent = {
+ 'gppString': 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==',
+ 'applicableSections': [8]
+ };
+ const data = buildAndGetData([mockBannerBid()], 0, mockBidderRequest({gppConsent}));
+ expect(data.userConsent).equal(
+ JSON.stringify({
+ gdprApplies: '',
+ cmp: '',
+ gpp: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==',
+ gpp_sid: [8],
})
);
});
diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js
index b069b13fc37..820d87ef49c 100644
--- a/test/spec/unit/pbjs_api_spec.js
+++ b/test/spec/unit/pbjs_api_spec.js
@@ -888,16 +888,32 @@ describe('Unit: Prebid Module', function () {
it('should only apply price granularity if bid media type matches', function () {
initTestConfig({
- adUnits: [ createAdUnit('div-gpt-ad-1460505748561-0', 'video') ],
+ adUnits: [createAdUnit('div-gpt-ad-1460505748561-0')],
adUnitCodes: ['div-gpt-ad-1460505748561-0']
});
- response = videoResponse;
+ response = bannerResponse;
response.tags[0].ads[0].cpm = 3.4288;
auction.callBids(cbTimeout);
let bidTargeting = targeting.getAllTargeting();
- expect(bidTargeting['div-gpt-ad-1460505748561-0'][CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]).to.equal('3.00');
+ expect(bidTargeting['div-gpt-ad-1460505748561-0'][CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]).to.equal('3.25');
+
+ if (FEATURES.VIDEO) {
+ ajaxStub.restore();
+
+ initTestConfig({
+ adUnits: [createAdUnit('div-gpt-ad-1460505748561-0', 'video')],
+ adUnitCodes: ['div-gpt-ad-1460505748561-0']
+ });
+
+ response = videoResponse;
+ response.tags[0].ads[0].cpm = 3.4288;
+
+ auction.callBids(cbTimeout);
+ let bidTargeting = targeting.getAllTargeting();
+ expect(bidTargeting['div-gpt-ad-1460505748561-0'][CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]).to.equal('3.00');
+ }
});
});
diff --git a/test/test_index.js b/test/test_index.js
index 04d1412860b..ce9b671be89 100644
--- a/test/test_index.js
+++ b/test/test_index.js
@@ -1,4 +1,3 @@
-
[it, describe].forEach((ob) => {
ob.only = function () {
[
@@ -7,8 +6,19 @@
// eslint-disable-next-line no-console
].forEach(l => console.error(l))
throw new Error('do not use .only()')
- }
-})
+ };
+});
+
+[it, describe].forEach((ob) => {
+ ob.skip = function () {
+ [
+ 'describe.skip and it.skip are disabled,',
+ 'because they pollute the pipeline test output',
+ // eslint-disable-next-line no-console
+ ].forEach(l => console.error(l))
+ throw new Error('do not use .skip()')
+ };
+});
require('./test_deps.js');