diff --git a/integrationExamples/gpt/userId_example.html b/integrationExamples/gpt/userId_example.html
index 9e1cd01f8fa..085b89e9f58 100644
--- a/integrationExamples/gpt/userId_example.html
+++ b/integrationExamples/gpt/userId_example.html
@@ -174,7 +174,8 @@
expires: 60
}
}],
- syncDelay: 5000
+ syncDelay: 5000,
+ auctionDelay: 1000
}
});
pbjs.addAdUnits(adUnits);
diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js
index 7c48458f474..a5f8f65634d 100644
--- a/modules/adkernelBidAdapter.js
+++ b/modules/adkernelBidAdapter.js
@@ -23,7 +23,7 @@ const VERSION = '1.3';
export const spec = {
code: 'adkernel',
- aliases: ['headbidding', 'adsolut', 'oftmediahb'],
+ aliases: ['headbidding', 'adsolut', 'oftmediahb', 'audiencemedia'],
supportedMediaTypes: [BANNER, VIDEO],
isBidRequestValid: function(bidRequest) {
return 'params' in bidRequest &&
diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js
index 5b682f747e2..5fe2add5ba8 100644
--- a/modules/appnexusBidAdapter.js
+++ b/modules/appnexusBidAdapter.js
@@ -116,6 +116,7 @@ export const spec = {
const memberIdBid = find(bidRequests, hasMemberId);
const member = memberIdBid ? parseInt(memberIdBid.params.member, 10) : 0;
+ const schain = bidRequests[0].schain;
const payload = {
tags: [...tags],
@@ -123,7 +124,8 @@ export const spec = {
sdk: {
source: SOURCE,
version: '$prebid.version$'
- }
+ },
+ schain: schain
};
if (member > 0) {
diff --git a/modules/conversantBidAdapter.js b/modules/conversantBidAdapter.js
deleted file mode 100644
index 90865493d8d..00000000000
--- a/modules/conversantBidAdapter.js
+++ /dev/null
@@ -1,292 +0,0 @@
-import * as utils from '../src/utils';
-import {registerBidder} from '../src/adapters/bidderFactory';
-import { BANNER, VIDEO } from '../src/mediaTypes';
-
-const BIDDER_CODE = 'conversant';
-const URL = '//web.hb.ad.cpe.dotomi.com/s2s/header/24';
-const VERSION = '2.2.4';
-
-export const spec = {
- code: BIDDER_CODE,
- aliases: ['cnvr'], // short code
- supportedMediaTypes: [BANNER, 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) {
- if (!bid || !bid.params) {
- utils.logWarn(BIDDER_CODE + ': Missing bid parameters');
- return false;
- }
-
- if (!utils.isStr(bid.params.site_id)) {
- utils.logWarn(BIDDER_CODE + ': site_id must be specified as a string')
- return false;
- }
-
- if (isVideoRequest(bid)) {
- if (!bid.params.mimes) {
- // Give a warning but let it pass
- utils.logWarn(BIDDER_CODE + ': mimes should be specified for videos');
- } else if (!utils.isArray(bid.params.mimes) || !bid.params.mimes.every(s => utils.isStr(s))) {
- utils.logWarn(BIDDER_CODE + ': mimes must be an array of strings');
- return false;
- }
- }
-
- return true;
- },
-
- /**
- * Make a server request from the list of BidRequests.
- *
- * @param {BidRequest[]} validBidRequests - an array of bids
- * @return {ServerRequest} Info describing the request to the server.
- */
- buildRequests: function(validBidRequests, bidderRequest) {
- const loc = utils.getTopWindowLocation();
- const page = loc.href;
- const isPageSecure = (loc.protocol === 'https:') ? 1 : 0;
- let siteId = '';
- let requestId = '';
- let pubcid = null;
-
- const conversantImps = validBidRequests.map(function(bid) {
- const bidfloor = utils.getBidIdParameter('bidfloor', bid.params);
- const secure = isPageSecure || (utils.getBidIdParameter('secure', bid.params) ? 1 : 0);
-
- siteId = utils.getBidIdParameter('site_id', bid.params);
- requestId = bid.auctionId;
-
- const imp = {
- id: bid.bidId,
- secure: secure,
- bidfloor: bidfloor || 0,
- displaymanager: 'Prebid.js',
- displaymanagerver: VERSION
- };
-
- copyOptProperty(bid.params.tag_id, imp, 'tagid');
-
- if (isVideoRequest(bid)) {
- const videoData = utils.deepAccess(bid, 'mediaTypes.video') || {};
- const format = convertSizes(videoData.playerSize || bid.sizes);
- const video = {};
-
- if (format && format[0]) {
- copyOptProperty(format[0].w, video, 'w');
- copyOptProperty(format[0].h, video, 'h');
- }
-
- copyOptProperty(bid.params.position, video, 'pos');
- copyOptProperty(bid.params.mimes || videoData.mimes, video, 'mimes');
- copyOptProperty(bid.params.maxduration, video, 'maxduration');
- copyOptProperty(bid.params.protocols || videoData.protocols, video, 'protocols');
- copyOptProperty(bid.params.api || videoData.api, video, 'api');
-
- imp.video = video;
- } else {
- const bannerData = utils.deepAccess(bid, 'mediaTypes.banner') || {};
- const format = convertSizes(bannerData.sizes || bid.sizes);
- const banner = {format: format};
-
- copyOptProperty(bid.params.position, banner, 'pos');
-
- imp.banner = banner;
- }
-
- if (bid.userId && bid.userId.pubcid) {
- pubcid = bid.userId.pubcid;
- } else if (bid.crumbs && bid.crumbs.pubcid) {
- pubcid = bid.crumbs.pubcid;
- }
-
- return imp;
- });
-
- const payload = {
- id: requestId,
- imp: conversantImps,
- site: {
- id: siteId,
- mobile: document.querySelector('meta[name="viewport"][content*="width=device-width"]') !== null ? 1 : 0,
- page: page
- },
- device: getDevice(),
- at: 1
- };
-
- let userExt = {};
-
- // Add GDPR flag and consent string
- if (bidderRequest && bidderRequest.gdprConsent) {
- userExt.consent = bidderRequest.gdprConsent.consentString;
-
- if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') {
- payload.regs = {
- ext: {
- gdpr: (bidderRequest.gdprConsent.gdprApplies ? 1 : 0)
- }
- };
- }
- }
-
- // Add common id if available
- if (pubcid) {
- userExt.fpc = pubcid;
- }
-
- // Only add the user object if it's not empty
- if (!utils.isEmpty(userExt)) {
- payload.user = {ext: userExt};
- }
-
- return {
- method: 'POST',
- url: URL,
- data: payload,
- };
- },
- /**
- * Unpack the response from the server into a list of bids.
- *
- * @param {*} serverResponse A successful response from the server.
- * @return {Bid[]} An array of bids which were nested inside the server.
- */
- interpretResponse: function(serverResponse, bidRequest) {
- const bidResponses = [];
- const requestMap = {};
- serverResponse = serverResponse.body;
-
- if (bidRequest && bidRequest.data && bidRequest.data.imp) {
- utils._each(bidRequest.data.imp, imp => requestMap[imp.id] = imp);
- }
-
- if (serverResponse && utils.isArray(serverResponse.seatbid)) {
- utils._each(serverResponse.seatbid, function(bidList) {
- utils._each(bidList.bid, function(conversantBid) {
- const responseCPM = parseFloat(conversantBid.price);
- if (responseCPM > 0.0 && conversantBid.impid) {
- const responseAd = conversantBid.adm || '';
- const responseNurl = conversantBid.nurl || '';
- const request = requestMap[conversantBid.impid];
-
- const bid = {
- requestId: conversantBid.impid,
- currency: serverResponse.cur || 'USD',
- cpm: responseCPM,
- creativeId: conversantBid.crid || '',
- ttl: 300,
- netRevenue: true
- };
-
- if (request.video) {
- bid.vastUrl = responseAd;
- bid.mediaType = 'video';
- bid.width = request.video.w;
- bid.height = request.video.h;
- } else {
- bid.ad = responseAd + '';
- bid.width = conversantBid.w;
- bid.height = conversantBid.h;
- }
-
- bidResponses.push(bid);
- }
- })
- });
- }
-
- return bidResponses;
- },
-
- /**
- * Covert bid param types for S2S
- * @param {Object} params bid params
- * @param {Boolean} isOpenRtb boolean to check openrtb2 protocol
- * @return {Object} params bid params
- */
- transformBidParams: function(params, isOpenRtb) {
- return utils.convertTypes({
- 'site_id': 'string',
- 'secure': 'number',
- 'mobile': 'number'
- }, params);
- }
-};
-
-/**
- * Determine do-not-track state
- *
- * @returns {boolean}
- */
-function getDNT() {
- return navigator.doNotTrack === '1' || window.doNotTrack === '1' || navigator.msDoNoTrack === '1' || navigator.doNotTrack === 'yes';
-}
-
-/**
- * Return openrtb device object that includes ua, width, and height.
- *
- * @returns {Device} Openrtb device object
- */
-function getDevice() {
- const language = navigator.language ? 'language' : 'userLanguage';
- return {
- h: screen.height,
- w: screen.width,
- dnt: getDNT() ? 1 : 0,
- language: navigator[language].split('-')[0],
- make: navigator.vendor ? navigator.vendor : '',
- ua: navigator.userAgent
- };
-}
-
-/**
- * Convert arrays of widths and heights to an array of objects with w and h properties.
- *
- * [[300, 250], [300, 600]] => [{w: 300, h: 250}, {w: 300, h: 600}]
- *
- * @param {number[2][]|number[2]} bidSizes - arrays of widths and heights
- * @returns {object[]} Array of objects with w and h
- */
-function convertSizes(bidSizes) {
- let format;
- if (Array.isArray(bidSizes)) {
- if (bidSizes.length === 2 && typeof bidSizes[0] === 'number' && typeof bidSizes[1] === 'number') {
- format = [{w: bidSizes[0], h: bidSizes[1]}];
- } else {
- format = utils._map(bidSizes, d => { return {w: d[0], h: d[1]}; });
- }
- }
-
- return format;
-}
-
-/**
- * Check if it's a video bid request
- *
- * @param {BidRequest} bid - Bid request generated from ad slots
- * @returns {boolean} True if it's a video bid
- */
-function isVideoRequest(bid) {
- return bid.mediaType === 'video' || !!utils.deepAccess(bid, 'mediaTypes.video');
-}
-
-/**
- * Copy property if exists from src to dst
- *
- * @param {object} src - source object
- * @param {object} dst - destination object
- * @param {string} dstName - destination property name
- */
-function copyOptProperty(src, dst, dstName) {
- if (src) {
- dst[dstName] = src;
- }
-}
-
-registerBidder(spec);
diff --git a/modules/conversantBidAdapter.md b/modules/conversantBidAdapter.md
deleted file mode 100644
index 3ce83d8c893..00000000000
--- a/modules/conversantBidAdapter.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Overview
-
-- Module Name: Conversant Bidder Adapter
-- Module Type: Bidder Adapter
-- Maintainer: mediapsr@conversantmedia.com
-
-# Description
-
-Module that connects to Conversant's demand sources. Supports banners and videos.
-
-# Test Parameters
-```
-var adUnits = [
- {
- code: 'banner-test-div',
- sizes: [[300, 250]],
- bids: [{
- bidder: "conversant",
- params: {
- site_id: '108060'
- }
- }]
- },{
- code: 'video-test-div',
- mediaTypes: {
- video: {
- context: 'instream',
- playerSize: [640, 480]
- }
- },
- bids: [{
- bidder: "conversant",
- params: {
- site_id: '108060',
- api: [2],
- protocols: [1, 2],
- mimes: ['video/mp4']
- }
- }]
- }];
-```
diff --git a/modules/criteoBidAdapter.js b/modules/criteoBidAdapter.js
deleted file mode 100644
index 559c02cd4a9..00000000000
--- a/modules/criteoBidAdapter.js
+++ /dev/null
@@ -1,421 +0,0 @@
-import { loadExternalScript } from '../src/adloader';
-import { registerBidder } from '../src/adapters/bidderFactory';
-import { config } from '../src/config';
-import { BANNER, VIDEO } from '../src/mediaTypes';
-import { parse } from '../src/url';
-import * as utils from '../src/utils';
-import find from 'core-js/library/fn/array/find';
-import JSEncrypt from 'jsencrypt/bin/jsencrypt';
-import sha256 from 'crypto-js/sha256';
-
-export const ADAPTER_VERSION = 20;
-const BIDDER_CODE = 'criteo';
-const CDB_ENDPOINT = '//bidder.criteo.com/cdb';
-const CRITEO_VENDOR_ID = 91;
-const PROFILE_ID_INLINE = 207;
-export const PROFILE_ID_PUBLISHERTAG = 185;
-
-// Unminified source code can be found in: https://github.com/Prebid-org/prebid-js-external-js-criteo/blob/master/dist/prod.js
-const PUBLISHER_TAG_URL = '//static.criteo.net/js/ld/publishertag.prebid.js';
-
-export const FAST_BID_PUBKEY = `-----BEGIN PUBLIC KEY-----
-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO1BjAITkFTtP0IMzmF7qsqhpu
-y1dGaTPHnjMU9mRZsrnfR3C0sEN5pYEzEcFRPnkJjJuhH8Rnh5+CE+LcKg0Z8ZZ7
-OmOSj0/qnYTAYCu0cR5LiyWG79KlIgUyMbp92ulGg24gAyGrVn4+v/4c53WlOEUp
-4YWvb82G0CD5NcDNpQIDAQAB
------END PUBLIC KEY-----`;
-
-/** @type {BidderSpec} */
-export const spec = {
- code: BIDDER_CODE,
- supportedMediaTypes: [ BANNER, VIDEO ],
-
- /**
- * @param {object} bid
- * @return {boolean}
- */
- isBidRequestValid: (bid) => {
- // either one of zoneId or networkId should be set
- if (!(bid && bid.params && (bid.params.zoneId || bid.params.networkId))) {
- return false;
- }
-
- // video media types requires some mandatory params
- if (hasVideoMediaType(bid)) {
- if (!hasValidVideoMediaType(bid)) {
- return false;
- }
- }
-
- return true;
- },
-
- /**
- * @param {BidRequest[]} bidRequests
- * @param {*} bidderRequest
- * @return {ServerRequest}
- */
- buildRequests: (bidRequests, bidderRequest) => {
- let url;
- let data;
-
- Object.assign(bidderRequest, { ceh: config.getConfig('criteo.ceh') });
-
- // If publisher tag not already loaded try to get it from fast bid
- if (!publisherTagAvailable()) {
- window.Criteo = window.Criteo || {};
- window.Criteo.usePrebidEvents = false;
-
- tryGetCriteoFastBid();
-
- // Reload the PublisherTag after the timeout to ensure FastBid is up-to-date and tracking done properly
- setTimeout(() => {
- loadExternalScript(PUBLISHER_TAG_URL, BIDDER_CODE);
- }, bidderRequest.timeout);
- }
-
- if (publisherTagAvailable()) {
- const adapter = new Criteo.PubTag.Adapters.Prebid(PROFILE_ID_PUBLISHERTAG, ADAPTER_VERSION, bidRequests, bidderRequest, '$prebid.version$');
- url = adapter.buildCdbUrl();
- data = adapter.buildCdbRequest();
- } else {
- const context = buildContext(bidRequests);
- url = buildCdbUrl(context);
- data = buildCdbRequest(context, bidRequests, bidderRequest);
- }
-
- if (data) {
- return { method: 'POST', url, data, bidRequests };
- }
- },
-
- /**
- * @param {*} response
- * @param {ServerRequest} request
- * @return {Bid[]}
- */
- interpretResponse: (response, request) => {
- const body = response.body || response;
-
- if (publisherTagAvailable()) {
- const adapter = Criteo.PubTag.Adapters.Prebid.GetAdapter(request);
- if (adapter) {
- return adapter.interpretResponse(body, request);
- }
- }
-
- const bids = [];
-
- if (body && body.slots && utils.isArray(body.slots)) {
- body.slots.forEach(slot => {
- const bidRequest = find(request.bidRequests, b => b.adUnitCode === slot.impid && (!b.params.zoneId || parseInt(b.params.zoneId) === slot.zoneid));
- const bidId = bidRequest.bidId;
- const bid = {
- requestId: bidId,
- adId: slot.bidId || utils.getUniqueIdentifierStr(),
- cpm: slot.cpm,
- currency: slot.currency,
- netRevenue: true,
- ttl: slot.ttl || 60,
- creativeId: bidId,
- width: slot.width,
- height: slot.height,
- dealId: slot.dealCode,
- }
- if (slot.native) {
- bid.ad = createNativeAd(bidId, slot.native, bidRequest.params.nativeCallback);
- } else if (slot.video) {
- bid.vastUrl = slot.displayurl;
- bid.mediaType = VIDEO;
- } else {
- bid.ad = slot.creative;
- }
- bids.push(bid);
- });
- }
-
- return bids;
- },
-
- /**
- * @param {TimedOutBid} timeoutData
- */
- onTimeout: (timeoutData) => {
- if (publisherTagAvailable()) {
- const adapter = Criteo.PubTag.Adapters.Prebid.GetAdapter(timeoutData.auctionId);
- adapter.handleBidTimeout();
- }
- },
-
- /**
- * @param {Bid} bid
- */
- onBidWon: (bid) => {
- if (publisherTagAvailable()) {
- const adapter = Criteo.PubTag.Adapters.Prebid.GetAdapter(bid.auctionId);
- adapter.handleBidWon(bid);
- }
- },
-
- /**
- * @param {Bid} bid
- */
- onSetTargeting: (bid) => {
- if (publisherTagAvailable()) {
- const adapter = Criteo.PubTag.Adapters.Prebid.GetAdapter(bid.auctionId);
- adapter.handleSetTargeting(bid);
- }
- },
-};
-
-/**
- * @return {boolean}
- */
-function publisherTagAvailable() {
- return typeof Criteo !== 'undefined' && Criteo.PubTag && Criteo.PubTag.Adapters && Criteo.PubTag.Adapters.Prebid;
-}
-
-/**
- * @param {BidRequest[]} bidRequests
- * @return {CriteoContext}
- */
-function buildContext(bidRequests) {
- const url = utils.getTopWindowUrl();
- const queryString = parse(url).search;
-
- const context = {
- url: url,
- debug: queryString['pbt_debug'] === '1',
- noLog: queryString['pbt_nolog'] === '1',
- amp: false,
- };
-
- bidRequests.forEach(bidRequest => {
- if (bidRequest.params.integrationMode === 'amp') {
- context.amp = true;
- }
- })
-
- return context;
-}
-
-/**
- * @param {CriteoContext} context
- * @return {string}
- */
-function buildCdbUrl(context) {
- let url = CDB_ENDPOINT;
- url += '?profileId=' + PROFILE_ID_INLINE;
- url += '&av=' + String(ADAPTER_VERSION);
- url += '&wv=' + encodeURIComponent('$prebid.version$');
- url += '&cb=' + String(Math.floor(Math.random() * 99999999999));
-
- if (context.amp) {
- url += '&im=1';
- }
- if (context.debug) {
- url += '&debug=1';
- }
- if (context.noLog) {
- url += '&nolog=1';
- }
-
- return url;
-}
-
-/**
- * @param {CriteoContext} context
- * @param {BidRequest[]} bidRequests
- * @return {*}
- */
-function buildCdbRequest(context, bidRequests, bidderRequest) {
- let networkId;
- const request = {
- publisher: {
- url: context.url,
- },
- slots: bidRequests.map(bidRequest => {
- networkId = bidRequest.params.networkId || networkId;
- const slot = {
- impid: bidRequest.adUnitCode,
- transactionid: bidRequest.transactionId,
- auctionId: bidRequest.auctionId,
- sizes: getBannerSizes(bidRequest),
- };
- if (bidRequest.params.zoneId) {
- slot.zoneid = bidRequest.params.zoneId;
- }
- if (bidRequest.params.publisherSubId) {
- slot.publishersubid = bidRequest.params.publisherSubId;
- }
- if (bidRequest.params.nativeCallback) {
- slot.native = true;
- }
- if (hasVideoMediaType(bidRequest)) {
- const video = {
- playersizes: getVideoSizes(bidRequest),
- mimes: bidRequest.mediaTypes.video.mimes,
- protocols: bidRequest.mediaTypes.video.protocols,
- maxduration: bidRequest.mediaTypes.video.maxduration,
- api: bidRequest.mediaTypes.video.api
- }
-
- video.skip = bidRequest.params.video.skip;
- video.placement = bidRequest.params.video.placement;
- video.minduration = bidRequest.params.video.minduration;
- video.playbackmethod = bidRequest.params.video.playbackmethod;
- video.startdelay = bidRequest.params.video.startdelay;
-
- slot.video = video;
- }
- return slot;
- }),
- };
- if (networkId) {
- request.publisher.networkid = networkId;
- }
- request.user = {};
- if (bidderRequest && bidderRequest.ceh) {
- request.user.ceh = bidderRequest.ceh;
- }
- if (bidderRequest && bidderRequest.gdprConsent) {
- request.gdprConsent = {};
- if (typeof bidderRequest.gdprConsent.gdprApplies !== 'undefined') {
- request.gdprConsent.gdprApplies = !!(bidderRequest.gdprConsent.gdprApplies);
- }
- if (bidderRequest.gdprConsent.vendorData && bidderRequest.gdprConsent.vendorData.vendorConsents &&
- typeof bidderRequest.gdprConsent.vendorData.vendorConsents[ CRITEO_VENDOR_ID.toString(10) ] !== 'undefined') {
- request.gdprConsent.consentGiven = !!(bidderRequest.gdprConsent.vendorData.vendorConsents[ CRITEO_VENDOR_ID.toString(10) ]);
- }
- if (typeof bidderRequest.gdprConsent.consentString !== 'undefined') {
- request.gdprConsent.consentData = bidderRequest.gdprConsent.consentString;
- }
- }
- return request;
-}
-
-function getVideoSizes(bidRequest) {
- return parseSizes(utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'));
-}
-
-function getBannerSizes(bidRequest) {
- return parseSizes(utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes);
-}
-
-function parseSize(size) {
- return size[0] + 'x' + size[1];
-}
-
-function parseSizes(sizes) {
- if (Array.isArray(sizes[0])) { // is there several sizes ? (ie. [[728,90],[200,300]])
- return sizes.map(size => parseSize(size));
- }
-
- return [parseSize(sizes)]; // or a single one ? (ie. [728,90])
-}
-
-function hasVideoMediaType(bidRequest) {
- if (utils.deepAccess(bidRequest, 'params.video') === undefined) {
- return false;
- }
- return utils.deepAccess(bidRequest, 'mediaTypes.video') !== undefined;
-}
-
-function hasValidVideoMediaType(bidRequest) {
- let isValid = true;
-
- var requiredMediaTypesParams = ['mimes', 'playerSize', 'maxduration', 'protocols', 'api'];
-
- requiredMediaTypesParams.forEach(function(param) {
- if (utils.deepAccess(bidRequest, 'mediaTypes.video.' + param) === undefined) {
- isValid = false;
- utils.logError('Criteo Bid Adapter: mediaTypes.video.' + param + ' is required');
- }
- });
-
- var requiredParams = ['skip', 'placement', 'playbackmethod'];
-
- requiredParams.forEach(function(param) {
- if (utils.deepAccess(bidRequest, 'params.video.' + param) === undefined) {
- isValid = false;
- utils.logError('Criteo Bid Adapter: params.video.' + param + ' is required');
- }
- });
-
- if (isValid) {
- // We do not support long form for now, also we have to check that context & placement are consistent
- if (bidRequest.mediaTypes.video.context == 'instream' && bidRequest.params.video.placement === 1) {
- return true;
- } else if (bidRequest.mediaTypes.video.context == 'outstream' && bidRequest.params.video.placement !== 1) {
- return true;
- }
- }
-
- return false;
-}
-
-/**
- * @param {string} id
- * @param {*} payload
- * @param {*} callback
- * @return {string}
- */
-function createNativeAd(id, payload, callback) {
- // Store the callback and payload in a global object to be later accessed from the creative
- window.criteo_prebid_native_slots = window.criteo_prebid_native_slots || {};
- window.criteo_prebid_native_slots[id] = { callback, payload };
-
- // The creative is in an iframe so we have to get the callback and payload
- // from the parent window (doesn't work with safeframes)
- return ``;
-}
-
-/**
- * @return {boolean}
- */
-export function tryGetCriteoFastBid() {
- try {
- const fastBidStorageKey = 'criteo_fast_bid';
- const hashPrefix = '// Hash: ';
- const fastBidFromStorage = localStorage.getItem(fastBidStorageKey);
-
- if (fastBidFromStorage !== null) {
- // The value stored must contain the file's encrypted hash as first line
- const firstLineEndPosition = fastBidFromStorage.indexOf('\n');
- const firstLine = fastBidFromStorage.substr(0, firstLineEndPosition).trim();
-
- if (firstLine.substr(0, hashPrefix.length) !== hashPrefix) {
- utils.logWarn('No hash found in FastBid');
- localStorage.removeItem(fastBidStorageKey);
- } else {
- // Remove the hash part from the locally stored value
- const publisherTagHash = firstLine.substr(hashPrefix.length);
- const publisherTag = fastBidFromStorage.substr(firstLineEndPosition + 1);
-
- var jsEncrypt = new JSEncrypt();
- jsEncrypt.setPublicKey(FAST_BID_PUBKEY);
- if (jsEncrypt.verify(publisherTag, publisherTagHash, sha256)) {
- utils.logInfo('Using Criteo FastBid');
- eval(publisherTag); // eslint-disable-line no-eval
- } else {
- utils.logWarn('Invalid Criteo FastBid found');
- localStorage.removeItem(fastBidStorageKey);
- }
- }
- }
- } catch (e) {
- // Unable to get fast bid
- }
-}
-
-registerBidder(spec);
diff --git a/modules/criteoBidAdapter.md b/modules/criteoBidAdapter.md
deleted file mode 100644
index e4c441c758d..00000000000
--- a/modules/criteoBidAdapter.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# Overview
-
-Module Name: Criteo Bidder Adapter
-Module Type: Bidder Adapter
-Maintainer: pi-direct@criteo.com
-
-# Description
-
-Module that connects to Criteo's demand sources.
-
-# Test Parameters
-```
- var adUnits = [
- {
- code: 'banner-ad-div',
- sizes: [[300, 250], [728, 90]],
- bids: [
- {
- bidder: 'criteo',
- params: {
- zoneId: 497747
- }
- }
- ]
- }
- ];
-```
-
-# Additional Config (Optional)
-Set the "ceh" property to provides the user's hashed email if available
-```
- pbjs.setConfig({
- criteo: {
- ceh: 'hashed mail'
- }
- });
-```
\ No newline at end of file
diff --git a/modules/criteortusIdSystem.js b/modules/criteortusIdSystem.js
index 02edf0ef06e..8486bfae9f3 100644
--- a/modules/criteortusIdSystem.js
+++ b/modules/criteortusIdSystem.js
@@ -36,7 +36,7 @@ export const criteortusIdSubmodule = {
* performs action to obtain id and return a value in the callback's response argument
* @function
* @param {SubmoduleParams} [configParams]
- * @returns {function(callback:function)}
+ * @returns {IdResponse|undefined}
*/
getId(configParams) {
if (!configParams || !utils.isPlainObject(configParams.clientIdentifier)) {
@@ -46,10 +46,10 @@ export const criteortusIdSubmodule = {
let uid = utils.getCookie(key);
if (uid) {
- return uid;
+ return {id: uid};
} else {
let userIds = {};
- return function(callback) {
+ const resp = function(callback) {
let bidders = Object.keys(configParams.clientIdentifier);
function afterAllResponses() {
@@ -97,7 +97,8 @@ export const criteortusIdSubmodule = {
})
);
})
- }
+ };
+ return {callback: resp};
}
}
};
diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js
index aa427c6eae1..3e9bf219c75 100644
--- a/modules/datablocksBidAdapter.js
+++ b/modules/datablocksBidAdapter.js
@@ -1,6 +1,6 @@
import * as utils from '../src/utils';
import { registerBidder } from '../src/adapters/bidderFactory';
-import { BANNER, NATIVE } from '../src/mediaTypes';
+import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes';
import { parse as parseUrl } from '../src/url';
const NATIVE_MAP = {
'body': 2,
@@ -43,12 +43,17 @@ const NATIVE_IMAGE = [{
}
}];
+const VIDEO_PARAMS = ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay',
+ 'placement', 'linearity', 'skip', 'skipmin', 'skipafter', 'sequence', 'battr', 'maxextended',
+ 'minbitrate', 'maxbitrate', 'boxingallowed', 'playbackmethod', 'playbackend', 'delivery',
+ 'pos', 'companionad', 'api', 'companiontype', 'ext'];
+
export const spec = {
- supportedMediaTypes: [BANNER, NATIVE],
+ supportedMediaTypes: [BANNER, NATIVE, VIDEO],
code: 'datablocks',
isBidRequestValid: function(bid) {
return !!(bid.params.host && bid.params.sourceId &&
- bid.mediaTypes && (bid.mediaTypes.banner || bid.mediaTypes.native));
+ bid.mediaTypes && (bid.mediaTypes.banner || bid.mediaTypes.native || bid.mediaTypes.video));
},
buildRequests: function(validBidRequests, bidderRequest) {
if (!validBidRequests.length) { return []; }
@@ -142,6 +147,43 @@ export const spec = {
request: JSON.stringify({native: {assets: nativeAssets}})
};
}
+ } else if (utils.deepAccess(bidRequest, 'mediaTypes.video')) {
+ let video = bidRequest.mediaTypes.video;
+ let sizes = video.playerSize || bidRequest.sizes || [];
+ if (sizes.length && Array.isArray(sizes[0])) {
+ imp.video = {
+ w: sizes[0][0],
+ h: sizes[0][1]
+ };
+ } else if (sizes.length == 2 && !Array.isArray(sizes[0])) {
+ imp.video = {
+ w: sizes[0],
+ h: sizes[1]
+ };
+ } else {
+ return;
+ }
+
+ if (video.durationRangeSec) {
+ if (Array.isArray(video.durationRangeSec)) {
+ if (video.durationRangeSec.length == 1) {
+ imp.video.maxduration = video.durationRangeSec[0];
+ } else if (video.durationRangeSec.length == 2) {
+ imp.video.minduration = video.durationRangeSec[0];
+ imp.video.maxduration = video.durationRangeSec[1];
+ }
+ } else {
+ imp.video.maxduration = video.durationRangeSec;
+ }
+ }
+
+ if (bidRequest.params.video) {
+ Object.keys(bidRequest.params.video).forEach(k => {
+ if (VIDEO_PARAMS.indexOf(k) > -1) {
+ imp.video[k] = bidRequest.params.video[k];
+ }
+ })
+ }
}
let host = bidRequest.params.host;
let sourceId = bidRequest.params.sourceId;
@@ -181,7 +223,6 @@ export const spec = {
}
})
});
-
return requests;
function RtbRequest(device, site, imps) {
@@ -276,6 +317,11 @@ export const spec = {
}
})
br.native = result;
+ } else if (imp.video) {
+ br.mediaType = VIDEO;
+ br.width = rtbBid.w;
+ br.height = rtbBid.h;
+ if (rtbBid.adm) { br.vastXml = rtbBid.adm; } else if (rtbBid.nurl) { br.vastUrl = rtbBid.nurl; }
}
return br;
});
diff --git a/modules/datablocksBidAdapter.md b/modules/datablocksBidAdapter.md
index 7562eee5704..e30cd361974 100644
--- a/modules/datablocksBidAdapter.md
+++ b/modules/datablocksBidAdapter.md
@@ -9,7 +9,7 @@ Maintainer: support@datablocks.net
# Description
Connects to Datablocks Version 5 Platform
-Banner Native and
+Banner Native and Video
# Test Parameters
@@ -47,6 +47,25 @@ Banner Native and
sourceId: 12345,
host: 'prebid.datablocks.net'
}
+ }, {
+ code: 'video-div',
+ mediaTypes : {
+ video: {
+ playerSize:[500,400],
+ durationRangeSec:[15,30],
+ context: "linear"
+ }
+ },
+ bids: [
+ {
+ bidder: 'datablocks',
+ params: {
+ sourceId: 12345,
+ host: 'prebid.datablocks.net',
+ video: {
+ mimes:["video/flv"]
+ }
+ }
}
]
}
diff --git a/modules/dfpAdServerVideo.js b/modules/dfpAdServerVideo.js
index 6f3c23f1f3d..c3f867308d1 100644
--- a/modules/dfpAdServerVideo.js
+++ b/modules/dfpAdServerVideo.js
@@ -101,7 +101,7 @@ export function buildDfpVideoUrl(options) {
return buildUrl({
protocol: 'https',
- host: 'pubads.g.doubleclick.net',
+ host: 'securepubads.g.doubleclick.net',
pathname: '/gampad/ads',
search: queryParams
});
@@ -184,7 +184,7 @@ export function buildAdpodVideoUrl({code, params, callback} = {}) {
const masterTag = buildUrl({
protocol: 'https',
- host: 'pubads.g.doubleclick.net',
+ host: 'securepubads.g.doubleclick.net',
pathname: '/gampad/ads',
search: queryParams
});
diff --git a/modules/digiTrustIdSystem.js b/modules/digiTrustIdSystem.js
index 17f6fd9f737..89557e0917e 100644
--- a/modules/digiTrustIdSystem.js
+++ b/modules/digiTrustIdSystem.js
@@ -342,7 +342,9 @@ export const digiTrustIdSubmodule = {
utils.logError('DigiTrust ID submodule decode error');
}
},
- getId: getDigiTrustId,
+ getId: function (configParams) {
+ return {callback: getDigiTrustId(configParams)};
+ },
_testInit: surfaceTestHook
};
diff --git a/modules/djaxBidAdapter.js b/modules/djaxBidAdapter.js
new file mode 100644
index 00000000000..58f500d2a2b
--- /dev/null
+++ b/modules/djaxBidAdapter.js
@@ -0,0 +1,129 @@
+import { registerBidder } from '../src/adapters/bidderFactory';
+import { config } from '../src/config';
+import * as utils from '../src/utils';
+import {BANNER, VIDEO} from '../src/mediaTypes';
+import { ajax } from '../src/ajax';
+import {Renderer} from '../src/Renderer';
+
+const SUPPORTED_AD_TYPES = [BANNER, VIDEO];
+const BIDDER_CODE = 'djax';
+const DOMAIN = 'https://demo.reviveadservermod.com/headerbidding_adminshare/';
+const RENDERER_URL = '//acdn.adnxs.com/video/outstream/ANOutstreamVideo.js';
+
+function isBidRequestValid(bid) {
+ return (typeof bid.params !== 'undefined' && parseInt(utils.getValue(bid.params, 'publisherId')) > 0);
+}
+
+function buildRequests(validBidRequests) {
+ return {
+ method: 'POST',
+ url: DOMAIN + 'www/admin/plugins/Prebid/getAd.php',
+ options: {
+ withCredentials: false,
+ crossOrigin: true
+ },
+ data: validBidRequests,
+ };
+}
+
+function interpretResponse(serverResponse, request) {
+ const response = serverResponse.body;
+ const bidResponses = [];
+ var bidRequestResponses = [];
+
+ utils._each(response, function(bidAd) {
+ bidAd.adResponse = {
+ content: bidAd.vastXml,
+ height: bidAd.height,
+ width: bidAd.width
+ };
+ bidAd.ttl = config.getConfig('_bidderTimeout')
+ bidAd.renderer = bidAd.context === 'outstream' ? createRenderer(bidAd, {
+ id: bidAd.adUnitCode,
+ url: RENDERER_URL
+ }, bidAd.adUnitCode) : undefined;
+ bidResponses.push(bidAd);
+ });
+
+ bidRequestResponses.push({
+ function: 'saveResponses',
+ request: request,
+ response: bidResponses
+ });
+ sendResponseToServer(bidRequestResponses);
+ return bidResponses;
+}
+
+function outstreamRender(bidAd) {
+ bidAd.renderer.push(() => {
+ window.ANOutstreamVideo.renderAd({
+ sizes: [bidAd.width, bidAd.height],
+ width: bidAd.width,
+ height: bidAd.height,
+ targetId: bidAd.adUnitCode,
+ adResponse: bidAd.adResponse,
+ rendererOptions: {
+ showVolume: false,
+ allowFullscreen: false
+ }
+ });
+ });
+}
+
+function createRenderer(bidAd, rendererParams, adUnitCode) {
+ const renderer = Renderer.install({
+ id: rendererParams.id,
+ url: rendererParams.url,
+ loaded: false,
+ config: {'player_height': bidAd.height, 'player_width': bidAd.width},
+ adUnitCode
+ });
+ try {
+ renderer.setRender(outstreamRender);
+ } catch (err) {
+ utils.logWarn('Prebid Error calling setRender on renderer', err);
+ }
+ return renderer;
+}
+
+function onBidWon(bid) {
+ let wonBids = [];
+ wonBids.push(bid);
+ wonBids[0].function = 'onBidWon';
+ sendResponseToServer(wonBids);
+}
+
+function onTimeout(details) {
+ details.unshift({ 'function': 'onTimeout' });
+ sendResponseToServer(details);
+}
+
+function sendResponseToServer(data) {
+ ajax(DOMAIN + 'www/admin/plugins/Prebid/tracking/track.php', null, JSON.stringify(data), {
+ withCredentials: false,
+ method: 'POST',
+ crossOrigin: true
+ });
+}
+
+function getUserSyncs(syncOptions) {
+ if (syncOptions.iframeEnabled) {
+ return [{
+ type: 'iframe',
+ url: DOMAIN + 'www/admin/plugins/Prebid/userSync.php'
+ }];
+ }
+}
+
+export const spec = {
+ code: BIDDER_CODE,
+ supportedMediaTypes: SUPPORTED_AD_TYPES,
+ isBidRequestValid,
+ buildRequests,
+ interpretResponse,
+ getUserSyncs,
+ onBidWon,
+ onTimeout
+};
+
+registerBidder(spec);
diff --git a/modules/djaxBidAdapter.md b/modules/djaxBidAdapter.md
new file mode 100644
index 00000000000..d597eb59b58
--- /dev/null
+++ b/modules/djaxBidAdapter.md
@@ -0,0 +1,50 @@
+# Overview
+
+```
+Module Name: djax Bid Adapter
+Module Type: Bidder Adapter
+Maintainer : support@djaxtech.com
+```
+
+# Description
+
+Connects to Djax Ad Server for bids.
+
+djax bid adapter supports Banner and Video.
+
+# Test Parameters
+```
+ var adUnits = [
+ //bannner object
+ {
+ code: 'banner-ad-slot',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300,600]],
+ }
+ },
+ bids: [{
+ bidder: 'djax',
+ params: {
+ publisherId: 2
+ }
+ }]
+
+ },
+ //video object
+ {
+ code: 'video-ad-slot',
+ mediaTypes: {
+ video: {
+ context: 'instream',
+ playerSize: [640, 480],
+ },
+ },
+ bids: [{
+ bidder: "djax",
+ params: {
+ publisherId: 2
+ }
+ }]
+ }];
+```
\ No newline at end of file
diff --git a/modules/id5IdSystem.js b/modules/id5IdSystem.js
index 6fb5014c962..6ed56b89d6d 100644
--- a/modules/id5IdSystem.js
+++ b/modules/id5IdSystem.js
@@ -31,7 +31,7 @@ export const id5IdSubmodule = {
* @param {SubmoduleParams} [configParams]
* @param {ConsentData} [consentData]
* @param {(Object|undefined)} cacheIdObj
- * @returns {(Object|function(callback:function))}
+ * @returns {IdResponse|undefined}
*/
getId(configParams, consentData, cacheIdObj) {
if (!configParams || typeof configParams.partner !== 'number') {
@@ -43,7 +43,7 @@ export const id5IdSubmodule = {
const storedUserId = this.decode(cacheIdObj);
const url = `https://id5-sync.com/g/v1/${configParams.partner}.json?1puid=${storedUserId ? storedUserId.id5id : ''}&gdpr=${hasGdpr}&gdpr_consent=${gdprConsentString}`;
- return function (callback) {
+ const resp = function (callback) {
ajax(url, response => {
let responseObj;
if (response) {
@@ -55,7 +55,8 @@ export const id5IdSubmodule = {
}
callback(responseObj);
}, undefined, { method: 'GET', withCredentials: true });
- }
+ };
+ return {callback: resp};
}
};
diff --git a/modules/identityLinkIdSystem.js b/modules/identityLinkIdSystem.js
index 9aca5f85adf..a269799e92a 100644
--- a/modules/identityLinkIdSystem.js
+++ b/modules/identityLinkIdSystem.js
@@ -29,7 +29,7 @@ export const identityLinkSubmodule = {
* performs action to obtain id and return a value in the callback's response argument
* @function
* @param {SubmoduleParams} [configParams]
- * @returns {function(callback:function)}
+ * @returns {IdResponse|undefined}
*/
getId(configParams) {
if (!configParams || typeof configParams.pid !== 'string') {
@@ -38,9 +38,10 @@ export const identityLinkSubmodule = {
}
// use protocol relative urls for http or https
const url = `https://api.rlcdn.com/api/identity/envelope?pid=${configParams.pid}`;
+ let resp;
// if ats library is initialised, use it to retrieve envelope. If not use standard third party endpoint
if (window.ats) {
- return function(callback) {
+ resp = function(callback) {
window.ats.retrieveEnvelope(function (envelope) {
if (envelope) {
callback(JSON.parse(envelope).envelope);
@@ -50,10 +51,11 @@ export const identityLinkSubmodule = {
});
}
} else {
- return function (callback) {
+ resp = function (callback) {
getEnvelope(url, callback);
}
}
+ return {callback: resp};
}
}
// return envelope from third party endpoint
diff --git a/modules/microadBidAdapter.js b/modules/microadBidAdapter.js
index 391be2c465b..0d4da3e72f7 100644
--- a/modules/microadBidAdapter.js
+++ b/modules/microadBidAdapter.js
@@ -4,7 +4,7 @@ import { BANNER } from '../src/mediaTypes';
const BIDDER_CODE = 'microad';
const ENDPOINT_URLS = {
- 'production': '//s-rtb-pb.send.microad.jp/prebid',
+ 'production': 'https://s-rtb-pb.send.microad.jp/prebid',
'test': 'https://rtbtest.send.microad.jp/prebid'
};
export let ENVIRONMENT = 'production';
diff --git a/modules/openxBidAdapter.js b/modules/openxBidAdapter.js
deleted file mode 100644
index a79343ab2ff..00000000000
--- a/modules/openxBidAdapter.js
+++ /dev/null
@@ -1,460 +0,0 @@
-import {config} from '../src/config';
-import {registerBidder} from '../src/adapters/bidderFactory';
-import * as utils from '../src/utils';
-import {userSync} from '../src/userSync';
-import {BANNER, VIDEO} from '../src/mediaTypes';
-import {parse} from '../src/url';
-
-const SUPPORTED_AD_TYPES = [BANNER, VIDEO];
-const BIDDER_CODE = 'openx';
-const BIDDER_CONFIG = 'hb_pb';
-const BIDDER_VERSION = '2.1.9';
-
-let shouldSendBoPixel = true;
-
-export function resetBoPixel() {
- shouldSendBoPixel = true;
-}
-
-export const spec = {
- code: BIDDER_CODE,
- supportedMediaTypes: SUPPORTED_AD_TYPES,
- isBidRequestValid: function (bidRequest) {
- const hasDelDomainOrPlatform = bidRequest.params.delDomain || bidRequest.params.platform;
- if (utils.deepAccess(bidRequest, 'mediaTypes.banner') && hasDelDomainOrPlatform) {
- return !!bidRequest.params.unit || utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes.length') > 0;
- }
-
- return !!(bidRequest.params.unit && hasDelDomainOrPlatform);
- },
- buildRequests: function (bidRequests, bidderRequest) {
- if (bidRequests.length === 0) {
- return [];
- }
-
- let requests = [];
- let [videoBids, bannerBids] = partitionByVideoBids(bidRequests);
-
- // build banner requests
- if (bannerBids.length > 0) {
- requests.push(buildOXBannerRequest(bannerBids, bidderRequest));
- }
- // build video requests
- if (videoBids.length > 0) {
- videoBids.forEach(videoBid => {
- requests.push(buildOXVideoRequest(videoBid, bidderRequest))
- });
- }
-
- return requests;
- },
- interpretResponse: function ({body: oxResponseObj}, serverRequest) {
- let mediaType = getMediaTypeFromRequest(serverRequest);
-
- return mediaType === VIDEO ? createVideoBidResponses(oxResponseObj, serverRequest.payload)
- : createBannerBidResponses(oxResponseObj, serverRequest.payload);
- },
- getUserSyncs: function (syncOptions, responses) {
- if (syncOptions.iframeEnabled || syncOptions.pixelEnabled) {
- let pixelType = syncOptions.iframeEnabled ? 'iframe' : 'image';
- let url = utils.deepAccess(responses, '0.body.ads.pixels') ||
- utils.deepAccess(responses, '0.body.pixels') ||
- '//u.openx.net/w/1.0/pd';
- return [{
- type: pixelType,
- url: url
- }];
- }
- },
- transformBidParams: function(params, isOpenRtb) {
- return utils.convertTypes({
- 'unit': 'string',
- 'customFloor': 'number'
- }, params);
- }
-};
-
-function isVideoRequest(bidRequest) {
- return (utils.deepAccess(bidRequest, 'mediaTypes.video') && !utils.deepAccess(bidRequest, 'mediaTypes.banner')) || bidRequest.mediaType === VIDEO;
-}
-
-function createBannerBidResponses(oxResponseObj, {bids, startTime}) {
- let adUnits = oxResponseObj.ads.ad;
- let bidResponses = [];
- for (let i = 0; i < adUnits.length; i++) {
- let adUnit = adUnits[i];
- let adUnitIdx = parseInt(adUnit.idx, 10);
- let bidResponse = {};
-
- bidResponse.requestId = bids[adUnitIdx].bidId;
-
- if (adUnit.pub_rev) {
- bidResponse.cpm = Number(adUnit.pub_rev) / 1000;
- } else {
- // No fill, do not add the bidresponse
- continue;
- }
- let creative = adUnit.creative[0];
- if (creative) {
- bidResponse.width = creative.width;
- bidResponse.height = creative.height;
- }
- bidResponse.creativeId = creative.id;
- bidResponse.ad = adUnit.html;
- if (adUnit.deal_id) {
- bidResponse.dealId = adUnit.deal_id;
- }
- // default 5 mins
- bidResponse.ttl = 300;
- // true is net, false is gross
- bidResponse.netRevenue = true;
- bidResponse.currency = adUnit.currency;
-
- // additional fields to add
- if (adUnit.tbd) {
- bidResponse.tbd = adUnit.tbd;
- }
- bidResponse.ts = adUnit.ts;
-
- bidResponse.meta = {};
- if (adUnit.brand_id) {
- bidResponse.meta.brandId = adUnit.brand_id;
- }
-
- if (adUnit.adv_id) {
- bidResponse.meta.dspid = adUnit.adv_id;
- }
-
- bidResponses.push(bidResponse);
-
- registerBeacon(BANNER, adUnit, startTime);
- }
- return bidResponses;
-}
-
-function buildQueryStringFromParams(params) {
- for (let key in params) {
- if (params.hasOwnProperty(key)) {
- if (!params[key]) {
- delete params[key];
- }
- }
- }
- return utils._map(Object.keys(params), key => `${key}=${params[key]}`)
- .join('&');
-}
-
-function getViewportDimensions(isIfr) {
- let width;
- let height;
- let tWin = window;
- let tDoc = document;
- let docEl = tDoc.documentElement;
- let body;
-
- if (isIfr) {
- try {
- tWin = window.top;
- tDoc = window.top.document;
- } catch (e) {
- return;
- }
- docEl = tDoc.documentElement;
- body = tDoc.body;
-
- width = tWin.innerWidth || docEl.clientWidth || body.clientWidth;
- height = tWin.innerHeight || docEl.clientHeight || body.clientHeight;
- } else {
- docEl = tDoc.documentElement;
- width = tWin.innerWidth || docEl.clientWidth;
- height = tWin.innerHeight || docEl.clientHeight;
- }
-
- return `${width}x${height}`;
-}
-
-function formatCustomParms(customKey, customParams) {
- let value = customParams[customKey];
- if (utils.isArray(value)) {
- // if value is an array, join them with commas first
- value = value.join(',');
- }
- // return customKey=customValue format, escaping + to . and / to _
- return (customKey.toLowerCase() + '=' + value.toLowerCase()).replace('+', '.').replace('/', '_')
-}
-
-function partitionByVideoBids(bidRequests) {
- return bidRequests.reduce(function (acc, bid) {
- // Fallback to banner ads if nothing specified
- if (isVideoRequest(bid)) {
- acc[0].push(bid);
- } else {
- acc[1].push(bid);
- }
- return acc;
- }, [[], []]);
-}
-
-function getMediaTypeFromRequest(serverRequest) {
- return /avjp$/.test(serverRequest.url) ? VIDEO : BANNER;
-}
-
-function buildCommonQueryParamsFromBids(bids, bidderRequest) {
- const isInIframe = utils.inIframe();
- let defaultParams;
-
- defaultParams = {
- ju: config.getConfig('pageUrl') || utils.getTopWindowUrl(),
- jr: utils.getTopWindowReferrer(),
- ch: document.charSet || document.characterSet,
- res: `${screen.width}x${screen.height}x${screen.colorDepth}`,
- ifr: isInIframe,
- tz: new Date().getTimezoneOffset(),
- tws: getViewportDimensions(isInIframe),
- be: 1,
- bc: bids[0].params.bc || `${BIDDER_CONFIG}_${BIDDER_VERSION}`,
- dddid: utils._map(bids, bid => bid.transactionId).join(','),
- nocache: new Date().getTime()
- };
-
- if (bids[0].params.platform) {
- defaultParams.ph = bids[0].params.platform;
- }
-
- if (utils.deepAccess(bidderRequest, 'gdprConsent')) {
- let gdprConsentConfig = bidderRequest.gdprConsent;
-
- if (gdprConsentConfig.consentString !== undefined) {
- defaultParams.gdpr_consent = gdprConsentConfig.consentString;
- }
-
- if (gdprConsentConfig.gdprApplies !== undefined) {
- defaultParams.gdpr = gdprConsentConfig.gdprApplies ? 1 : 0;
- }
-
- if (config.getConfig('consentManagement.cmpApi') === 'iab') {
- defaultParams.x_gdpr_f = 1;
- }
- }
-
- if ((bids[0].userId && bids[0].userId.pubcid)) {
- defaultParams.pubcid = bids[0].userId.pubcid;
- } else if (bids[0].crumbs && bids[0].crumbs.pubcid) {
- defaultParams.pubcid = bids[0].crumbs.pubcid;
- }
-
- if (bids[0].schain) {
- defaultParams.schain = serializeSupplyChain(bids[0].schain);
- }
-
- return defaultParams;
-}
-
-function serializeSupplyChain(supplyChain) {
- return `${supplyChain.ver},${supplyChain.complete}!${serializeSupplyChainNodes(supplyChain.nodes)}`;
-}
-
-function serializeSupplyChainNodes(supplyChainNodes) {
- const supplyChainNodePropertyOrder = ['asi', 'sid', 'hp', 'rid', 'name', 'domain'];
-
- return supplyChainNodes.map(supplyChainNode => {
- return supplyChainNodePropertyOrder.map(property => supplyChainNode[property] || '')
- .join(',');
- }).join('!');
-}
-
-function buildOXBannerRequest(bids, bidderRequest) {
- let customParamsForAllBids = [];
- let hasCustomParam = false;
- let queryParams = buildCommonQueryParamsFromBids(bids, bidderRequest);
- let auids = utils._map(bids, bid => bid.params.unit);
- queryParams.aus = utils._map(bids, bid => utils.parseSizesInput(bid.sizes).join(',')).join('|');
- queryParams.divIds = utils._map(bids, bid => encodeURIComponent(bid.adUnitCode)).join(',');
-
- if (auids.some(auid => auid)) {
- queryParams.auid = auids.join(',');
- }
-
- if (bids.some(bid => bid.params.doNotTrack)) {
- queryParams.ns = 1;
- }
-
- if (config.getConfig('coppa') === true || bids.some(bid => bid.params.coppa)) {
- queryParams.tfcd = 1;
- }
-
- bids.forEach(function (bid) {
- if (bid.params.customParams) {
- let customParamsForBid = utils._map(Object.keys(bid.params.customParams), customKey => formatCustomParms(customKey, bid.params.customParams));
- let formattedCustomParams = window.btoa(customParamsForBid.join('&'));
- hasCustomParam = true;
- customParamsForAllBids.push(formattedCustomParams);
- } else {
- customParamsForAllBids.push('');
- }
- });
- if (hasCustomParam) {
- queryParams.tps = customParamsForAllBids.join(',');
- }
-
- let customFloorsForAllBids = [];
- let hasCustomFloor = false;
- bids.forEach(function (bid) {
- if (bid.params.customFloor) {
- customFloorsForAllBids.push((Math.round(bid.params.customFloor * 100) / 100) * 1000);
- hasCustomFloor = true;
- } else {
- customFloorsForAllBids.push(0);
- }
- });
- if (hasCustomFloor) {
- queryParams.aumfs = customFloorsForAllBids.join(',');
- }
-
- let url = queryParams.ph
- ? `//u.openx.net/w/1.0/arj`
- : `//${bids[0].params.delDomain}/w/1.0/arj`;
-
- return {
- method: 'GET',
- url: url,
- data: queryParams,
- payload: {'bids': bids, 'startTime': new Date()}
- };
-}
-
-function buildOXVideoRequest(bid, bidderRequest) {
- let oxVideoParams = generateVideoParameters(bid, bidderRequest);
- let url = oxVideoParams.ph
- ? `//u.openx.net/v/1.0/avjp`
- : `//${bid.params.delDomain}/v/1.0/avjp`;
- return {
- method: 'GET',
- url: url,
- data: oxVideoParams,
- payload: {'bid': bid, 'startTime': new Date()}
- };
-}
-
-function generateVideoParameters(bid, bidderRequest) {
- let queryParams = buildCommonQueryParamsFromBids([bid], bidderRequest);
- let oxVideoConfig = utils.deepAccess(bid, 'params.video') || {};
- let context = utils.deepAccess(bid, 'mediaTypes.video.context');
- let playerSize = utils.deepAccess(bid, 'mediaTypes.video.playerSize');
- let width;
- let height;
-
- // normalize config for video size
- if (utils.isArray(bid.sizes) && bid.sizes.length === 2 && !utils.isArray(bid.sizes[0])) {
- width = parseInt(bid.sizes[0], 10);
- height = parseInt(bid.sizes[1], 10);
- } else if (utils.isArray(bid.sizes) && utils.isArray(bid.sizes[0]) && bid.sizes[0].length === 2) {
- width = parseInt(bid.sizes[0][0], 10);
- height = parseInt(bid.sizes[0][1], 10);
- } else if (utils.isArray(playerSize) && playerSize.length === 2) {
- width = parseInt(playerSize[0], 10);
- height = parseInt(playerSize[1], 10);
- }
-
- Object.keys(oxVideoConfig).forEach(function (key) {
- if (key === 'openrtb') {
- oxVideoConfig[key].w = width || oxVideoConfig[key].w;
- oxVideoConfig[key].v = height || oxVideoConfig[key].v;
- queryParams[key] = JSON.stringify(oxVideoConfig[key]);
- } else if (!(key in queryParams) && key !== 'url') {
- // only allow video-related attributes
- queryParams[key] = oxVideoConfig[key];
- }
- });
-
- queryParams.auid = bid.params.unit;
- // override prebid config with openx config if available
- queryParams.vwd = width || oxVideoConfig.vwd;
- queryParams.vht = height || oxVideoConfig.vht;
-
- if (context === 'outstream') {
- queryParams.vos = '101';
- }
-
- if (oxVideoConfig.mimes) {
- queryParams.vmimes = oxVideoConfig.mimes;
- }
-
- return queryParams;
-}
-
-function createVideoBidResponses(response, {bid, startTime}) {
- let bidResponses = [];
-
- if (response !== undefined && response.vastUrl !== '' && response.pub_rev !== '') {
- let vastQueryParams = parse(response.vastUrl).search || {};
- let bidResponse = {};
- bidResponse.requestId = bid.bidId;
- // default 5 mins
- bidResponse.ttl = 300;
- // true is net, false is gross
- bidResponse.netRevenue = true;
- bidResponse.currency = response.currency;
- bidResponse.cpm = Number(response.pub_rev) / 1000;
- bidResponse.width = response.width;
- bidResponse.height = response.height;
- bidResponse.creativeId = response.adid;
- bidResponse.vastUrl = response.vastUrl;
- bidResponse.mediaType = VIDEO;
-
- // enrich adunit with vast parameters
- response.ph = vastQueryParams.ph;
- response.colo = vastQueryParams.colo;
- response.ts = vastQueryParams.ts;
-
- bidResponses.push(bidResponse);
-
- registerBeacon(VIDEO, response, startTime)
- }
-
- return bidResponses;
-}
-
-function registerBeacon(mediaType, adUnit, startTime) {
- // only register beacon once
- if (!shouldSendBoPixel) {
- return;
- }
- shouldSendBoPixel = false;
-
- let bt = config.getConfig('bidderTimeout');
- let beaconUrl;
- if (window.PREBID_TIMEOUT) {
- bt = Math.min(window.PREBID_TIMEOUT, bt);
- }
-
- let beaconParams = {
- bd: +(new Date()) - startTime,
- bp: adUnit.pub_rev,
- br: '0', // may be 0, t, or p
- bs: utils.getTopWindowLocation().hostname,
- bt: bt,
- ts: adUnit.ts
- };
-
- beaconParams.br = beaconParams.bt < beaconParams.bd ? 't' : 'p';
-
- if (mediaType === VIDEO) {
- let url = parse(adUnit.colo);
- beaconParams.ph = adUnit.ph;
- beaconUrl = `//${url.hostname}/w/1.0/bo?${buildQueryStringFromParams(beaconParams)}`
- } else {
- let recordPixel = utils.deepAccess(adUnit, 'creative.0.tracking.impression');
- let boBase = recordPixel.match(/([^?]+\/)ri\?/);
-
- if (boBase && boBase.length > 1) {
- beaconUrl = `${boBase[1]}bo?${buildQueryStringFromParams(beaconParams)}`;
- }
- }
-
- if (beaconUrl) {
- userSync.registerSync('image', BIDDER_CODE, beaconUrl);
- }
-}
-
-registerBidder(spec);
diff --git a/modules/openxBidAdapter.md b/modules/openxBidAdapter.md
deleted file mode 100644
index 965b8ee1948..00000000000
--- a/modules/openxBidAdapter.md
+++ /dev/null
@@ -1,104 +0,0 @@
-# Overview
-
-```
-Module Name: OpenX Bidder Adapter
-Module Type: Bidder Adapter
-Maintainer: team-openx@openx.com
-```
-
-# Description
-
-Module that connects to OpenX's demand sources
-
-# Bid Parameters
-## Banner
-
-| Name | Scope | Type | Description | Example
-| ---- | ----- | ---- | ----------- | -------
-| `delDomain` or `platform` | required | String | OpenX delivery domain or platform id provided by your OpenX representative. | "PUBLISHER-d.openx.net" or "555not5a-real-plat-form-id0123456789"
-| `unit` | required | String | OpenX ad unit ID provided by your OpenX representative. | "1611023122"
-| `customParams` | optional | Object | User-defined targeting key-value pairs. customParams applies to a specific unit. | `{key1: "v1", key2: ["v2","v3"]}`
-| `customFloor` | optional | Number | Minimum price in USD. customFloor applies to a specific unit. For example, use the following value to set a $1.50 floor: 1.50
**WARNING:**
Misuse of this parameter can impact revenue | 1.50
-| `doNotTrack` | optional | Boolean | Prevents advertiser from using data for this user.
**WARNING:**
Request-level setting. May impact revenue. | true
-| `coppa` | optional | Boolean | Enables Child's Online Privacy Protection Act (COPPA) regulations. | true
-
-## Video
-
-| Name | Scope | Type | Description | Example
-| ---- | ----- | ---- | ----------- | -------
-| `unit` | required | String | OpenX ad unit ID provided by your OpenX representative. | "1611023122"
-| `delDomain` | required | String | OpenX delivery domain provided by your OpenX representative. | "PUBLISHER-d.openx.net"
-| `openrtb` | optional | OpenRTB Impression | An OpenRtb Impression with Video subtype properties | `{ imp: [{ video: {mimes: ['video/x-ms-wmv, video/mp4']} }] }`
-
-
-# Example
-```javascript
-var adUnits = [
- {
- code: 'test-div',
- sizes: [[728, 90]], // a display size
- mediaTypes: {'banner': {}},
- bids: [
- {
- bidder: 'openx',
- params: {
- unit: '539439964',
- delDomain: 'se-demo-d.openx.net',
- customParams: {
- key1: 'v1',
- key2: ['v2', 'v3']
- },
- }
- }, {
- bidder: 'openx',
- params: {
- unit: '539439964',
- platform: 'a3aece0c-9e80-4316-8deb-faf804779bd1',
- customParams: {
- key1: 'v1',
- key2: ['v2', 'v3']
- },
- }
- }
- ]
- },
- {
- code: 'video1',
- mediaTypes: {
- video: {
- playerSize: [640, 480],
- context: 'instream'
- }
- },
- bids: [{
- bidder: 'openx',
- params: {
- unit: '1611023124',
- delDomain: 'PUBLISHER-d.openx.net',
- video: {
- mimes: ['video/x-ms-wmv, video/mp4']
- }
- }
- }]
- }
-];
-```
-
-# Configuration
-Add the following code to enable user syncing. By default, Prebid.js version 0.34.0+ turns off user syncing through iframes.
-OpenX strongly recommends enabling user syncing through iframes. This functionality improves DSP user match rates and increases the
-OpenX bid rate and bid price. Be sure to call `pbjs.setConfig()` only once.
-
-```javascript
-pbjs.setConfig({
- userSync: {
- iframeEnabled: true
- }
-});
-```
-
-# Additional Details
-[Banner Ads](https://docs.openx.com/Content/developers/containers/prebid-adapter.html)
-
-[Video Ads](https://docs.openx.com/Content/developers/containers/prebid-video-adapter.html)
-
diff --git a/modules/pubCommonId.js b/modules/pubCommonId.js
index 5b92592f07a..038ad3bef2f 100644
--- a/modules/pubCommonId.js
+++ b/modules/pubCommonId.js
@@ -5,6 +5,9 @@
*/
import * as utils from '../src/utils'
import { config } from '../src/config';
+import events from '../src/events';
+import * as url from '../src/url';
+import CONSTANTS from '../src/constants.json';
const ID_NAME = '_pubcid';
const OPTOUT_NAME = '_pubcid_optout';
@@ -18,7 +21,9 @@ let pubcidConfig = {
enabled: true,
interval: DEFAULT_EXPIRES,
typeEnabled: LOCAL_STORAGE,
- readOnly: false
+ create: true,
+ extend: true,
+ pixelUrl: ''
};
/**
@@ -89,17 +94,16 @@ export function removeStorageItem(key) {
/**
* Read a value either from cookie or local storage
* @param {string} name Name of the item
+ * @param {string} type storage type override
* @returns {string|null} a string if item exists
*/
-function readValue(name) {
+function readValue(name, type) {
let value;
- if (pubcidConfig.typeEnabled === COOKIE) {
+ if (!type) { type = pubcidConfig.typeEnabled; }
+ if (type === COOKIE) {
value = getCookie(name);
- } else if (pubcidConfig.typeEnabled === LOCAL_STORAGE) {
+ } else if (type === LOCAL_STORAGE) {
value = getStorageItem(name);
- if (!value) {
- value = getCookie(name);
- }
}
if (value === 'undefined' || value === 'null') { return null; }
@@ -116,13 +120,37 @@ function readValue(name) {
function writeValue(name, value, expInterval) {
if (name && value) {
if (pubcidConfig.typeEnabled === COOKIE) {
- setCookie(name, value, expInterval);
+ setCookie(name, value, expInterval, 'Lax');
} else if (pubcidConfig.typeEnabled === LOCAL_STORAGE) {
setStorageItem(name, value, expInterval);
}
}
}
+/**
+ * Add a callback at end of auction to fetch a pixel
+ * @param {string} pixelUrl Pixel URL
+ * @param {string} id pubcid
+ * @returns {boolean} True if callback is queued
+ */
+function queuePixelCallback(pixelUrl, id) {
+ if (!pixelUrl) { return false; }
+
+ id = id || '';
+
+ // Use pubcid as a cache buster
+ const urlInfo = url.parse(pixelUrl);
+ urlInfo.search.id = encodeURIComponent('pubcid:' + id);
+ const targetUrl = url.format(urlInfo);
+
+ events.on(CONSTANTS.EVENTS.AUCTION_END, function auctionEndHandler() {
+ events.off(CONSTANTS.EVENTS.AUCTION_END, auctionEndHandler);
+ utils.triggerPixel(targetUrl);
+ });
+
+ return true;
+}
+
export function isPubcidEnabled() { return pubcidConfig.enabled; }
export function getExpInterval() { return pubcidConfig.interval; }
export function getPubcidConfig() { return pubcidConfig; }
@@ -152,15 +180,25 @@ export function requestBidHook(next, config) {
// Otherwise get the existing cookie
pubcid = readValue(ID_NAME);
- if (!pubcidConfig.readOnly) {
- if (!pubcid) {
- pubcid = utils.generateUUID();
+ if (!pubcid) {
+ if (pubcidConfig.create) {
+ // Special handling for local storage to retain previously stored id in cookies
+ if (pubcidConfig.typeEnabled === LOCAL_STORAGE) {
+ pubcid = readValue(ID_NAME, COOKIE);
+ }
+ // Generate a new id
+ if (!pubcid) {
+ pubcid = utils.generateUUID();
+ }
// Update the cookie/storage with the latest expiration date
writeValue(ID_NAME, pubcid, pubcidConfig.interval);
// Only return pubcid if it is saved successfully
pubcid = readValue(ID_NAME);
- } else {
- // Update the cookie/storage with the latest expiration date
+ }
+ queuePixelCallback(pubcidConfig.pixelUrl, pubcid);
+ } else if (pubcidConfig.extend) {
+ // Update the cookie/storage with the latest expiration date
+ if (!queuePixelCallback(pubcidConfig.pixelUrl, pubcid)) {
writeValue(ID_NAME, pubcid, pubcidConfig.interval);
}
}
@@ -177,15 +215,17 @@ export function requestBidHook(next, config) {
});
});
}
+
return next.call(this, config);
}
// Helper to set a cookie
-export function setCookie(name, value, expires) {
+export function setCookie(name, value, expires, sameSite) {
let expTime = new Date();
expTime.setTime(expTime.getTime() + expires * 1000 * 60);
window.document.cookie = name + '=' + encodeURIComponent(value) + ';path=/;expires=' +
- expTime.toGMTString();
+ expTime.toGMTString() +
+ (sameSite ? ';SameSite=' + sameSite : '');
}
// Helper to read a cookie
@@ -202,17 +242,23 @@ export function getCookie(name) {
* @param {boolean} enable Enable or disable pubcid. By default the module is enabled.
* @param {number} expInterval Expiration interval of the cookie in minutes.
* @param {string} type Type of storage to use
- * @param {boolean} readOnly Read but not update id
+ * @param {boolean} create Create the id if missing. Default is true.
+ * @param {boolean} extend Extend the stored value when id is retrieved. Default is true.
+ * @param {string} pixelUrl A pixel URL back to the publisher's own domain that may modify cookie attributes.
*/
-export function setConfig({ enable = true, expInterval = DEFAULT_EXPIRES, type = 'html5,cookie', readOnly = false } = {}) {
- pubcidConfig.enabled = enable;
- pubcidConfig.interval = parseInt(expInterval, 10);
+export function setConfig({ enable, expInterval, type = 'html5,cookie', create, extend, pixelUrl } = {}) {
+ if (enable !== undefined) { pubcidConfig.enabled = enable; }
+
+ if (expInterval !== undefined) { pubcidConfig.interval = parseInt(expInterval, 10); }
+
if (isNaN(pubcidConfig.interval)) {
pubcidConfig.interval = DEFAULT_EXPIRES;
}
- pubcidConfig.readOnly = readOnly;
+ if (create !== undefined) { pubcidConfig.create = create; }
+ if (extend !== undefined) { pubcidConfig.extend = extend; }
+ if (pixelUrl !== undefined) { pubcidConfig.pixelUrl = pixelUrl; }
// Default is to use local storage. Fall back to
// cookie only if local storage is not supported.
@@ -242,7 +288,10 @@ export function setConfig({ enable = true, expInterval = DEFAULT_EXPIRES, type =
export function initPubcid() {
config.getConfig('pubcid', config => setConfig(config.pubcid));
- if (!readValue(OPTOUT_NAME)) {
+ const optout = (utils.cookiesAreEnabled() && readValue(OPTOUT_NAME, COOKIE)) ||
+ (utils.hasLocalStorage() && readValue(OPTOUT_NAME, LOCAL_STORAGE));
+
+ if (!optout) {
$$PREBID_GLOBAL$$.requestBids.before(requestBidHook);
}
}
diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js
deleted file mode 100644
index facecdaa578..00000000000
--- a/modules/pubmaticBidAdapter.js
+++ /dev/null
@@ -1,1021 +0,0 @@
-import * as utils from '../src/utils';
-import { registerBidder } from '../src/adapters/bidderFactory';
-import { BANNER, VIDEO, NATIVE } from '../src/mediaTypes';
-import {config} from '../src/config';
-
-const BIDDER_CODE = 'pubmatic';
-const LOG_WARN_PREFIX = 'PubMatic: ';
-const ENDPOINT = 'https://hbopenbid.pubmatic.com/translator?source=prebid-client';
-const USYNCURL = 'https://ads.pubmatic.com/AdServer/js/showad.js#PIX&kdntuid=1&p=';
-const DEFAULT_CURRENCY = 'USD';
-const AUCTION_TYPE = 1;
-const PUBMATIC_DIGITRUST_KEY = 'nFIn8aLzbd';
-const UNDEFINED = undefined;
-const DEFAULT_WIDTH = 0;
-const DEFAULT_HEIGHT = 0;
-const PREBID_NATIVE_HELP_LINK = 'http://prebid.org/dev-docs/show-native-ads.html';
-const CUSTOM_PARAMS = {
- 'kadpageurl': '', // Custom page url
- 'gender': '', // User gender
- 'yob': '', // User year of birth
- 'lat': '', // User location - Latitude
- 'lon': '', // User Location - Longitude
- 'wiid': '', // OpenWrap Wrapper Impression ID
- 'profId': '', // OpenWrap Legacy: Profile ID
- 'verId': '' // OpenWrap Legacy: version ID
-};
-const DATA_TYPES = {
- 'NUMBER': 'number',
- 'STRING': 'string',
- 'BOOLEAN': 'boolean',
- 'ARRAY': 'array',
- 'OBJECT': 'object'
-};
-const VIDEO_CUSTOM_PARAMS = {
- 'mimes': DATA_TYPES.ARRAY,
- 'minduration': DATA_TYPES.NUMBER,
- 'maxduration': DATA_TYPES.NUMBER,
- 'startdelay': DATA_TYPES.NUMBER,
- 'playbackmethod': DATA_TYPES.ARRAY,
- 'api': DATA_TYPES.ARRAY,
- 'protocols': DATA_TYPES.ARRAY,
- 'w': DATA_TYPES.NUMBER,
- 'h': DATA_TYPES.NUMBER,
- 'battr': DATA_TYPES.ARRAY,
- 'linearity': DATA_TYPES.NUMBER,
- 'placement': DATA_TYPES.NUMBER,
- 'minbitrate': DATA_TYPES.NUMBER,
- 'maxbitrate': DATA_TYPES.NUMBER
-}
-
-const NATIVE_ASSETS = {
- 'TITLE': { ID: 1, KEY: 'title', TYPE: 0 },
- 'IMAGE': { ID: 2, KEY: 'image', TYPE: 0 },
- 'ICON': { ID: 3, KEY: 'icon', TYPE: 0 },
- 'SPONSOREDBY': { ID: 4, KEY: 'sponsoredBy', TYPE: 1 }, // please note that type of SPONSORED is also 1
- 'BODY': { ID: 5, KEY: 'body', TYPE: 2 }, // please note that type of DESC is also set to 2
- 'CLICKURL': { ID: 6, KEY: 'clickUrl', TYPE: 0 },
- 'VIDEO': { ID: 7, KEY: 'video', TYPE: 0 },
- 'EXT': { ID: 8, KEY: 'ext', TYPE: 0 },
- 'DATA': { ID: 9, KEY: 'data', TYPE: 0 },
- 'LOGO': { ID: 10, KEY: 'logo', TYPE: 0 },
- 'SPONSORED': { ID: 11, KEY: 'sponsored', TYPE: 1 }, // please note that type of SPONSOREDBY is also set to 1
- 'DESC': { ID: 12, KEY: 'data', TYPE: 2 }, // please note that type of BODY is also set to 2
- 'RATING': { ID: 13, KEY: 'rating', TYPE: 3 },
- 'LIKES': { ID: 14, KEY: 'likes', TYPE: 4 },
- 'DOWNLOADS': { ID: 15, KEY: 'downloads', TYPE: 5 },
- 'PRICE': { ID: 16, KEY: 'price', TYPE: 6 },
- 'SALEPRICE': { ID: 17, KEY: 'saleprice', TYPE: 7 },
- 'PHONE': { ID: 18, KEY: 'phone', TYPE: 8 },
- 'ADDRESS': { ID: 19, KEY: 'address', TYPE: 9 },
- 'DESC2': { ID: 20, KEY: 'desc2', TYPE: 10 },
- 'DISPLAYURL': { ID: 21, KEY: 'displayurl', TYPE: 11 },
- 'CTA': { ID: 22, KEY: 'cta', TYPE: 12 }
-};
-
-const NATIVE_ASSET_IMAGE_TYPE = {
- 'ICON': 1,
- 'LOGO': 2,
- 'IMAGE': 3
-}
-
-// check if title, image can be added with mandatory field default values
-const NATIVE_MINIMUM_REQUIRED_IMAGE_ASSETS = [
- {
- id: NATIVE_ASSETS.SPONSOREDBY.ID,
- required: true,
- data: {
- type: 1
- }
- },
- {
- id: NATIVE_ASSETS.TITLE.ID,
- required: true,
- },
- {
- id: NATIVE_ASSETS.IMAGE.ID,
- required: true,
- }
-]
-
-const NET_REVENUE = false;
-const dealChannelValues = {
- 1: 'PMP',
- 5: 'PREF',
- 6: 'PMPG'
-};
-
-let publisherId = 0;
-let isInvalidNativeRequest = false;
-let NATIVE_ASSET_ID_TO_KEY_MAP = {};
-let NATIVE_ASSET_KEY_TO_ASSET_MAP = {};
-
-// loading NATIVE_ASSET_ID_TO_KEY_MAP
-utils._each(NATIVE_ASSETS, anAsset => { NATIVE_ASSET_ID_TO_KEY_MAP[anAsset.ID] = anAsset.KEY });
-// loading NATIVE_ASSET_KEY_TO_ASSET_MAP
-utils._each(NATIVE_ASSETS, anAsset => { NATIVE_ASSET_KEY_TO_ASSET_MAP[anAsset.KEY] = anAsset });
-
-function _getDomainFromURL(url) {
- let anchor = document.createElement('a');
- anchor.href = url;
- return anchor.hostname;
-}
-
-function _parseSlotParam(paramName, paramValue) {
- if (!utils.isStr(paramValue)) {
- paramValue && utils.logWarn(LOG_WARN_PREFIX + 'Ignoring param key: ' + paramName + ', expects string-value, found ' + typeof paramValue);
- return UNDEFINED;
- }
-
- switch (paramName) {
- case 'pmzoneid':
- return paramValue.split(',').slice(0, 50).map(id => id.trim()).join();
- case 'kadfloor':
- return parseFloat(paramValue) || UNDEFINED;
- case 'lat':
- return parseFloat(paramValue) || UNDEFINED;
- case 'lon':
- return parseFloat(paramValue) || UNDEFINED;
- case 'yob':
- return parseInt(paramValue) || UNDEFINED;
- default:
- return paramValue;
- }
-}
-
-function _cleanSlot(slotName) {
- if (utils.isStr(slotName)) {
- return slotName.replace(/^\s+/g, '').replace(/\s+$/g, '');
- }
- return '';
-}
-
-function _parseAdSlot(bid) {
- bid.params.adUnit = '';
- bid.params.adUnitIndex = '0';
- bid.params.width = 0;
- bid.params.height = 0;
- bid.params.adSlot = _cleanSlot(bid.params.adSlot);
-
- var slot = bid.params.adSlot;
- var splits = slot.split(':');
-
- slot = splits[0];
- if (splits.length == 2) {
- bid.params.adUnitIndex = splits[1];
- }
- // check if size is mentioned in sizes array. in that case do not check for @ in adslot
- splits = slot.split('@');
- bid.params.adUnit = splits[0];
- if (splits.length > 1) {
- // i.e size is specified in adslot, so consider that and ignore sizes array
- splits = splits[1].split('x');
- if (splits.length != 2) {
- utils.logWarn(LOG_WARN_PREFIX + 'AdSlot Error: adSlot not in required format');
- return;
- }
- bid.params.width = parseInt(splits[0]);
- bid.params.height = parseInt(splits[1]);
- } else if (bid.hasOwnProperty('mediaTypes') &&
- bid.mediaTypes.hasOwnProperty(BANNER) &&
- bid.mediaTypes.banner.hasOwnProperty('sizes')) {
- var i = 0;
- var sizeArray = [];
- for (;i < bid.mediaTypes.banner.sizes.length; i++) {
- if (bid.mediaTypes.banner.sizes[i].length === 2) { // sizes[i].length will not be 2 in case where size is set as fluid, we want to skip that entry
- sizeArray.push(bid.mediaTypes.banner.sizes[i]);
- }
- }
- bid.mediaTypes.banner.sizes = sizeArray;
- if (bid.mediaTypes.banner.sizes.length >= 1) {
- // set the first size in sizes array in bid.params.width and bid.params.height. These will be sent as primary size.
- // The rest of the sizes will be sent in format array.
- bid.params.width = bid.mediaTypes.banner.sizes[0][0];
- bid.params.height = bid.mediaTypes.banner.sizes[0][1];
- bid.mediaTypes.banner.sizes = bid.mediaTypes.banner.sizes.splice(1, bid.mediaTypes.banner.sizes.length - 1);
- }
- }
-}
-
-function _initConf(refererInfo) {
- var conf = {};
- conf.pageURL = utils.getTopWindowUrl();
- if (refererInfo && refererInfo.referer) {
- conf.refURL = refererInfo.referer;
- } else {
- conf.refURL = '';
- }
- return conf;
-}
-
-function _handleCustomParams(params, conf) {
- if (!conf.kadpageurl) {
- conf.kadpageurl = conf.pageURL;
- }
-
- var key, value, entry;
- for (key in CUSTOM_PARAMS) {
- if (CUSTOM_PARAMS.hasOwnProperty(key)) {
- value = params[key];
- if (value) {
- entry = CUSTOM_PARAMS[key];
-
- if (typeof entry === 'object') {
- // will be used in future when we want to process a custom param before using
- // 'keyname': {f: function() {}}
- value = entry.f(value, conf);
- }
-
- if (utils.isStr(value)) {
- conf[key] = value;
- } else {
- utils.logWarn(LOG_WARN_PREFIX + 'Ignoring param : ' + key + ' with value : ' + CUSTOM_PARAMS[key] + ', expects string-value, found ' + typeof value);
- }
- }
- }
- }
- return conf;
-}
-
-function _createOrtbTemplate(conf) {
- return {
- id: '' + new Date().getTime(),
- at: AUCTION_TYPE,
- cur: [DEFAULT_CURRENCY],
- imp: [],
- site: {
- page: conf.pageURL,
- ref: conf.refURL,
- publisher: {}
- },
- device: {
- ua: navigator.userAgent,
- js: 1,
- dnt: (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0,
- h: screen.height,
- w: screen.width,
- language: navigator.language
- },
- user: {},
- ext: {}
- };
-}
-
-function _checkParamDataType(key, value, datatype) {
- var errMsg = 'Ignoring param key: ' + key + ', expects ' + datatype + ', found ' + typeof value;
- var functionToExecute;
- switch (datatype) {
- case DATA_TYPES.BOOLEAN:
- functionToExecute = utils.isBoolean;
- break;
- case DATA_TYPES.NUMBER:
- functionToExecute = utils.isNumber;
- break;
- case DATA_TYPES.STRING:
- functionToExecute = utils.isStr;
- break;
- case DATA_TYPES.ARRAY:
- functionToExecute = utils.isArray;
- break;
- }
- if (functionToExecute(value)) {
- return value;
- }
- utils.logWarn(LOG_WARN_PREFIX + errMsg);
- return UNDEFINED;
-}
-
-function _commonNativeRequestObject(nativeAsset, params) {
- var key = nativeAsset.KEY;
- return {
- id: nativeAsset.ID,
- required: params[key].required ? 1 : 0,
- data: {
- type: nativeAsset.TYPE,
- len: params[key].len,
- ext: params[key].ext
- }
- };
-}
-
-function _createNativeRequest(params) {
- var nativeRequestObject = {
- assets: []
- };
- for (var key in params) {
- if (params.hasOwnProperty(key)) {
- var assetObj = {};
- if (!(nativeRequestObject.assets && nativeRequestObject.assets.length > 0 && nativeRequestObject.assets.hasOwnProperty(key))) {
- switch (key) {
- case NATIVE_ASSETS.TITLE.KEY:
- if (params[key].len || params[key].length) {
- assetObj = {
- id: NATIVE_ASSETS.TITLE.ID,
- required: params[key].required ? 1 : 0,
- title: {
- len: params[key].len || params[key].length,
- ext: params[key].ext
- }
- };
- } else {
- utils.logWarn(LOG_WARN_PREFIX + 'Error: Title Length is required for native ad: ' + JSON.stringify(params));
- }
- break;
- case NATIVE_ASSETS.IMAGE.KEY:
- if (params[key].sizes && params[key].sizes.length > 0) {
- assetObj = {
- id: NATIVE_ASSETS.IMAGE.ID,
- required: params[key].required ? 1 : 0,
- img: {
- type: NATIVE_ASSET_IMAGE_TYPE.IMAGE,
- w: params[key].w || params[key].width || (params[key].sizes ? params[key].sizes[0] : UNDEFINED),
- h: params[key].h || params[key].height || (params[key].sizes ? params[key].sizes[1] : UNDEFINED),
- wmin: params[key].wmin || params[key].minimumWidth || (params[key].minsizes ? params[key].minsizes[0] : UNDEFINED),
- hmin: params[key].hmin || params[key].minimumHeight || (params[key].minsizes ? params[key].minsizes[1] : UNDEFINED),
- mimes: params[key].mimes,
- ext: params[key].ext,
- }
- };
- } else {
- utils.logWarn(LOG_WARN_PREFIX + 'Error: Image sizes is required for native ad: ' + JSON.stringify(params));
- }
- break;
- case NATIVE_ASSETS.ICON.KEY:
- if (params[key].sizes && params[key].sizes.length > 0) {
- assetObj = {
- id: NATIVE_ASSETS.ICON.ID,
- required: params[key].required ? 1 : 0,
- img: {
- type: NATIVE_ASSET_IMAGE_TYPE.ICON,
- w: params[key].w || params[key].width || (params[key].sizes ? params[key].sizes[0] : UNDEFINED),
- h: params[key].h || params[key].height || (params[key].sizes ? params[key].sizes[1] : UNDEFINED),
- }
- };
- } else {
- utils.logWarn(LOG_WARN_PREFIX + 'Error: Icon sizes is required for native ad: ' + JSON.stringify(params));
- };
- break;
- case NATIVE_ASSETS.VIDEO.KEY:
- assetObj = {
- id: NATIVE_ASSETS.VIDEO.ID,
- required: params[key].required ? 1 : 0,
- video: {
- minduration: params[key].minduration,
- maxduration: params[key].maxduration,
- protocols: params[key].protocols,
- mimes: params[key].mimes,
- ext: params[key].ext
- }
- };
- break;
- case NATIVE_ASSETS.EXT.KEY:
- assetObj = {
- id: NATIVE_ASSETS.EXT.ID,
- required: params[key].required ? 1 : 0,
- };
- break;
- case NATIVE_ASSETS.LOGO.KEY:
- assetObj = {
- id: NATIVE_ASSETS.LOGO.ID,
- required: params[key].required ? 1 : 0,
- img: {
- type: NATIVE_ASSET_IMAGE_TYPE.LOGO,
- w: params[key].w || params[key].width || (params[key].sizes ? params[key].sizes[0] : UNDEFINED),
- h: params[key].h || params[key].height || (params[key].sizes ? params[key].sizes[1] : UNDEFINED)
- }
- };
- break;
- case NATIVE_ASSETS.SPONSOREDBY.KEY:
- case NATIVE_ASSETS.BODY.KEY:
- case NATIVE_ASSETS.RATING.KEY:
- case NATIVE_ASSETS.LIKES.KEY:
- case NATIVE_ASSETS.DOWNLOADS.KEY:
- case NATIVE_ASSETS.PRICE.KEY:
- case NATIVE_ASSETS.SALEPRICE.KEY:
- case NATIVE_ASSETS.PHONE.KEY:
- case NATIVE_ASSETS.ADDRESS.KEY:
- case NATIVE_ASSETS.DESC2.KEY:
- case NATIVE_ASSETS.DISPLAYURL.KEY:
- case NATIVE_ASSETS.CTA.KEY:
- assetObj = _commonNativeRequestObject(NATIVE_ASSET_KEY_TO_ASSET_MAP[key], params);
- break;
- }
- }
- }
- if (assetObj && assetObj.id) {
- nativeRequestObject.assets[nativeRequestObject.assets.length] = assetObj;
- }
- };
-
- // for native image adtype prebid has to have few required assests i.e. title,sponsoredBy, image
- // if any of these are missing from the request then request will not be sent
- var requiredAssetCount = NATIVE_MINIMUM_REQUIRED_IMAGE_ASSETS.length;
- var presentrequiredAssetCount = 0;
- NATIVE_MINIMUM_REQUIRED_IMAGE_ASSETS.forEach(ele => {
- var lengthOfExistingAssets = nativeRequestObject.assets.length;
- for (var i = 0; i < lengthOfExistingAssets; i++) {
- if (ele.id == nativeRequestObject.assets[i].id) {
- presentrequiredAssetCount++;
- break;
- }
- }
- });
- if (requiredAssetCount == presentrequiredAssetCount) {
- isInvalidNativeRequest = false;
- } else {
- isInvalidNativeRequest = true;
- }
- return nativeRequestObject;
-}
-
-function _createBannerRequest(bid) {
- var sizes = bid.mediaTypes.banner.sizes;
- var format = [];
- var bannerObj;
- if (sizes !== UNDEFINED && utils.isArray(sizes)) {
- bannerObj = {};
- if (!bid.params.width && !bid.params.height) {
- if (sizes.length === 0) {
- // i.e. since bid.params does not have width or height, and length of sizes is 0, need to ignore this banner imp
- bannerObj = UNDEFINED;
- utils.logWarn(LOG_WARN_PREFIX + 'Error: mediaTypes.banner.size missing for adunit: ' + bid.params.adUnit + '. Ignoring the banner impression in the adunit.');
- return bannerObj;
- } else {
- bannerObj.w = parseInt(sizes[0][0]);
- bannerObj.h = parseInt(sizes[0][1]);
- sizes = sizes.splice(1, sizes.length - 1);
- }
- } else {
- bannerObj.w = bid.params.width;
- bannerObj.h = bid.params.height;
- }
- if (sizes.length > 0) {
- format = [];
- sizes.forEach(function (size) {
- if (size.length > 1) {
- format.push({ w: size[0], h: size[1] });
- }
- });
- if (format.length > 0) {
- bannerObj.format = format;
- }
- }
- bannerObj.pos = 0;
- bannerObj.topframe = utils.inIframe() ? 0 : 1;
- } else {
- utils.logWarn(LOG_WARN_PREFIX + 'Error: mediaTypes.banner.size missing for adunit: ' + bid.params.adUnit + '. Ignoring the banner impression in the adunit.');
- bannerObj = UNDEFINED;
- }
- return bannerObj;
-}
-
-function _createVideoRequest(bid) {
- var videoData = bid.params.video;
- var videoObj;
-
- if (videoData !== UNDEFINED) {
- videoObj = {};
- for (var key in VIDEO_CUSTOM_PARAMS) {
- if (videoData.hasOwnProperty(key)) {
- videoObj[key] = _checkParamDataType(key, videoData[key], VIDEO_CUSTOM_PARAMS[key]);
- }
- }
- // read playersize and assign to h and w.
- if (utils.isArray(bid.mediaTypes.video.playerSize[0])) {
- videoObj.w = parseInt(bid.mediaTypes.video.playerSize[0][0]);
- videoObj.h = parseInt(bid.mediaTypes.video.playerSize[0][1]);
- } else if (utils.isNumber(bid.mediaTypes.video.playerSize[0])) {
- videoObj.w = parseInt(bid.mediaTypes.video.playerSize[0]);
- videoObj.h = parseInt(bid.mediaTypes.video.playerSize[1]);
- }
- if (bid.params.video.hasOwnProperty('skippable')) {
- videoObj.ext = {
- 'video_skippable': bid.params.video.skippable ? 1 : 0
- };
- }
- } else {
- videoObj = UNDEFINED;
- utils.logWarn(LOG_WARN_PREFIX + 'Error: Video config params missing for adunit: ' + bid.params.adUnit + ' with mediaType set as video. Ignoring video impression in the adunit.');
- }
- return videoObj;
-}
-
-function _createImpressionObject(bid, conf) {
- var impObj = {};
- var bannerObj;
- var videoObj;
- var nativeObj = {};
- var sizes = bid.hasOwnProperty('sizes') ? bid.sizes : [];
- var mediaTypes = '';
- var format = [];
-
- impObj = {
- id: bid.bidId,
- tagid: bid.params.adUnit || undefined,
- bidfloor: _parseSlotParam('kadfloor', bid.params.kadfloor),
- secure: 1,
- ext: {
- pmZoneId: _parseSlotParam('pmzoneid', bid.params.pmzoneid)
- },
- bidfloorcur: bid.params.currency ? _parseSlotParam('currency', bid.params.currency) : DEFAULT_CURRENCY
- };
-
- if (bid.hasOwnProperty('mediaTypes')) {
- for (mediaTypes in bid.mediaTypes) {
- switch (mediaTypes) {
- case BANNER:
- bannerObj = _createBannerRequest(bid);
- if (bannerObj !== UNDEFINED) {
- impObj.banner = bannerObj;
- }
- break;
- case NATIVE:
- nativeObj['request'] = JSON.stringify(_createNativeRequest(bid.nativeParams));
- if (!isInvalidNativeRequest) {
- impObj.native = nativeObj;
- } else {
- utils.logWarn(LOG_WARN_PREFIX + 'Error: Error in Native adunit ' + bid.params.adUnit + '. Ignoring the adunit. Refer to ' + PREBID_NATIVE_HELP_LINK + ' for more details.');
- }
- break;
- case VIDEO:
- videoObj = _createVideoRequest(bid);
- if (videoObj !== UNDEFINED) {
- impObj.video = videoObj;
- }
- break;
- }
- }
- } else {
- // mediaTypes is not present, so this is a banner only impression
- // this part of code is required for older testcases with no 'mediaTypes' to run succesfully.
- bannerObj = {
- pos: 0,
- w: bid.params.width,
- h: bid.params.height,
- topframe: utils.inIframe() ? 0 : 1
- };
- if (utils.isArray(sizes) && sizes.length > 1) {
- sizes = sizes.splice(1, sizes.length - 1);
- sizes.forEach(size => {
- format.push({
- w: size[0],
- h: size[1]
- });
- });
- bannerObj.format = format;
- }
- impObj.banner = bannerObj;
- }
-
- return impObj.hasOwnProperty(BANNER) ||
- impObj.hasOwnProperty(NATIVE) ||
- impObj.hasOwnProperty(VIDEO) ? impObj : UNDEFINED;
-}
-
-function _getDigiTrustObject(key) {
- function getDigiTrustId() {
- let digiTrustUser = window.DigiTrust && (config.getConfig('digiTrustId') || window.DigiTrust.getUser({member: key}));
- return (digiTrustUser && digiTrustUser.success && digiTrustUser.identity) || null;
- }
- let digiTrustId = getDigiTrustId();
- // Verify there is an ID and this user has not opted out
- if (!digiTrustId || (digiTrustId.privacy && digiTrustId.privacy.optout)) {
- return null;
- }
- return digiTrustId;
-}
-
-function _handleDigitrustId(eids) {
- let digiTrustId = _getDigiTrustObject(PUBMATIC_DIGITRUST_KEY);
- if (digiTrustId !== null) {
- eids.push({
- 'source': 'digitru.st',
- 'uids': [{
- 'id': digiTrustId.id || '',
- 'atype': 1,
- 'ext': {
- 'keyv': parseInt(digiTrustId.keyv) || 0
- }
- }]
- });
- }
-}
-
-function _handleTTDId(eids, validBidRequests) {
- let ttdId = null;
- let adsrvrOrgId = config.getConfig('adsrvrOrgId');
- if (utils.isStr(utils.deepAccess(validBidRequests, '0.userId.tdid'))) {
- ttdId = validBidRequests[0].userId.tdid;
- } else if (adsrvrOrgId && utils.isStr(adsrvrOrgId.TDID)) {
- ttdId = adsrvrOrgId.TDID;
- }
-
- if (ttdId !== null) {
- eids.push({
- 'source': 'adserver.org',
- 'uids': [{
- 'id': ttdId,
- 'atype': 1,
- 'ext': {
- 'rtiPartner': 'TDID'
- }
- }]
- });
- }
-}
-
-function _handleEids(payload, validBidRequests) {
- let eids = [];
- _handleDigitrustId(eids);
- _handleTTDId(eids, validBidRequests);
- if (eids.length > 0) {
- payload.user.eids = eids;
- }
-}
-
-function _checkMediaType(adm, newBid) {
- // Create a regex here to check the strings
- var admStr = '';
- var videoRegex = new RegExp(/VAST\s+version/);
- if (adm.indexOf('span class="PubAPIAd"') >= 0) {
- newBid.mediaType = BANNER;
- } else if (videoRegex.test(adm)) {
- newBid.mediaType = VIDEO;
- } else {
- try {
- admStr = JSON.parse(adm.replace(/\\/g, ''));
- if (admStr && admStr.native) {
- newBid.mediaType = NATIVE;
- }
- } catch (e) {
- utils.logWarn(LOG_WARN_PREFIX + 'Error: Cannot parse native reponse for ad response: ' + adm);
- }
- }
-}
-
-function _parseNativeResponse(bid, newBid) {
- newBid.native = {};
- if (bid.hasOwnProperty('adm')) {
- var adm = '';
- try {
- adm = JSON.parse(bid.adm.replace(/\\/g, ''));
- } catch (ex) {
- utils.logWarn(LOG_WARN_PREFIX + 'Error: Cannot parse native reponse for ad response: ' + newBid.adm);
- return;
- }
- if (adm && adm.native && adm.native.assets && adm.native.assets.length > 0) {
- newBid.mediaType = NATIVE;
- for (let i = 0, len = adm.native.assets.length; i < len; i++) {
- switch (adm.native.assets[i].id) {
- case NATIVE_ASSETS.TITLE.ID:
- newBid.native.title = adm.native.assets[i].title && adm.native.assets[i].title.text;
- break;
- case NATIVE_ASSETS.IMAGE.ID:
- newBid.native.image = {
- url: adm.native.assets[i].img && adm.native.assets[i].img.url,
- height: adm.native.assets[i].img && adm.native.assets[i].img.h,
- width: adm.native.assets[i].img && adm.native.assets[i].img.w,
- };
- break;
- case NATIVE_ASSETS.ICON.ID:
- newBid.native.icon = {
- url: adm.native.assets[i].img && adm.native.assets[i].img.url,
- height: adm.native.assets[i].img && adm.native.assets[i].img.h,
- width: adm.native.assets[i].img && adm.native.assets[i].img.w,
- };
- break;
- case NATIVE_ASSETS.SPONSOREDBY.ID:
- case NATIVE_ASSETS.BODY.ID:
- case NATIVE_ASSETS.LIKES.ID:
- case NATIVE_ASSETS.DOWNLOADS.ID:
- case NATIVE_ASSETS.PRICE:
- case NATIVE_ASSETS.SALEPRICE.ID:
- case NATIVE_ASSETS.PHONE.ID:
- case NATIVE_ASSETS.ADDRESS.ID:
- case NATIVE_ASSETS.DESC2.ID:
- case NATIVE_ASSETS.CTA.ID:
- case NATIVE_ASSETS.RATING.ID:
- case NATIVE_ASSETS.DISPLAYURL.ID:
- newBid.native[NATIVE_ASSET_ID_TO_KEY_MAP[adm.native.assets[i].id]] = adm.native.assets[i].data && adm.native.assets[i].data.value;
- break;
- }
- }
- newBid.native.clickUrl = adm.native.link && adm.native.link.url;
- newBid.native.clickTrackers = (adm.native.link && adm.native.link.clicktrackers) || [];
- newBid.native.impressionTrackers = adm.native.imptrackers || [];
- newBid.native.jstracker = adm.native.jstracker || [];
- if (!newBid.width) {
- newBid.width = DEFAULT_WIDTH;
- }
- if (!newBid.height) {
- newBid.height = DEFAULT_HEIGHT;
- }
- }
- }
-}
-
-function _blockedIabCategoriesValidation(payload, blockedIabCategories) {
- blockedIabCategories = blockedIabCategories
- .filter(function(category) {
- if (typeof category === 'string') { // only strings
- return true;
- } else {
- utils.logWarn(LOG_WARN_PREFIX + 'bcat: Each category should be a string, ignoring category: ' + category);
- return false;
- }
- })
- .map(category => category.trim()) // trim all
- .filter(function(category, index, arr) { // minimum 3 charaters length
- if (category.length > 3) {
- return arr.indexOf(category) === index; // unique value only
- } else {
- utils.logWarn(LOG_WARN_PREFIX + 'bcat: Each category should have a value of a length of more than 3 characters, ignoring category: ' + category)
- }
- });
- if (blockedIabCategories.length > 0) {
- utils.logWarn(LOG_WARN_PREFIX + 'bcat: Selected: ', blockedIabCategories);
- payload.bcat = blockedIabCategories;
- }
-}
-
-function _handleDealCustomTargetings(payload, dctrArr, validBidRequests) {
- var dctr = '';
- var dctrLen;
- // set dctr value in site.ext, if present in validBidRequests[0], else ignore
- if (dctrArr.length > 0) {
- if (validBidRequests[0].params.hasOwnProperty('dctr')) {
- dctr = validBidRequests[0].params.dctr;
- if (utils.isStr(dctr) && dctr.length > 0) {
- var arr = dctr.split('|');
- dctr = '';
- arr.forEach(val => {
- dctr += (val.length > 0) ? (val.trim() + '|') : '';
- });
- dctrLen = dctr.length;
- if (dctr.substring(dctrLen, dctrLen - 1) === '|') {
- dctr = dctr.substring(0, dctrLen - 1);
- }
- payload.site.ext = {
- key_val: dctr.trim()
- }
- } else {
- utils.logWarn(LOG_WARN_PREFIX + 'Ignoring param : dctr with value : ' + dctr + ', expects string-value, found empty or non-string value');
- }
- if (dctrArr.length > 1) {
- utils.logWarn(LOG_WARN_PREFIX + 'dctr value found in more than 1 adunits. Value from 1st adunit will be picked. Ignoring values from subsequent adunits');
- }
- } else {
- utils.logWarn(LOG_WARN_PREFIX + 'dctr value not found in 1st adunit, ignoring values from subsequent adunits');
- }
- }
-}
-
-export const spec = {
- code: BIDDER_CODE,
- supportedMediaTypes: [BANNER, VIDEO, NATIVE],
- /**
- * Determines whether or not the given bid request is valid. Valid bid request must have placementId and hbid
- *
- * @param {BidRequest} bid The bid params to validate.
- * @return boolean True if this is a valid bid, and false otherwise.
- */
- isBidRequestValid: bid => {
- if (bid && bid.params) {
- if (!utils.isStr(bid.params.publisherId)) {
- utils.logWarn(LOG_WARN_PREFIX + 'Error: publisherId is mandatory and cannot be numeric. Call to OpenBid will not be sent for ad unit: ' + JSON.stringify(bid));
- return false;
- }
- // video ad validation
- if (bid.params.hasOwnProperty('video')) {
- if (!bid.params.video.hasOwnProperty('mimes') || !utils.isArray(bid.params.video.mimes) || bid.params.video.mimes.length === 0) {
- utils.logWarn(LOG_WARN_PREFIX + 'Error: For video ads, mimes is mandatory and must specify atlease 1 mime value. Call to OpenBid will not be sent for ad unit:' + JSON.stringify(bid));
- return false;
- }
- }
- return true;
- }
- return false;
- },
-
- /**
- * Make a server request from the list of BidRequests.
- *
- * @param {validBidRequests[]} - an array of bids
- * @return ServerRequest Info describing the request to the server.
- */
- buildRequests: (validBidRequests, bidderRequest) => {
- var refererInfo;
- if (bidderRequest && bidderRequest.refererInfo) {
- refererInfo = bidderRequest.refererInfo;
- }
- var conf = _initConf(refererInfo);
- var payload = _createOrtbTemplate(conf);
- var bidCurrency = '';
- var dctrArr = [];
- var bid;
- var blockedIabCategories = [];
-
- validBidRequests.forEach(originalBid => {
- bid = utils.deepClone(originalBid);
- bid.params.adSlot = bid.params.adSlot || '';
- _parseAdSlot(bid);
- if (bid.params.hasOwnProperty('video')) {
- // Nothing to do
- } else {
- // If we have a native mediaType configured alongside banner, its ok if the banner size is not set in width and height
- // The corresponding banner imp object will not be generated, but we still want the native object to be sent, hence the following check
- if (!(bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(NATIVE)) && bid.params.width === 0 && bid.params.height === 0) {
- utils.logWarn(LOG_WARN_PREFIX + 'Skipping the non-standard adslot: ', bid.params.adSlot, JSON.stringify(bid));
- return;
- }
- }
- conf.pubId = conf.pubId || bid.params.publisherId;
- conf = _handleCustomParams(bid.params, conf);
- conf.transactionId = bid.transactionId;
- if (bidCurrency === '') {
- bidCurrency = bid.params.currency || UNDEFINED;
- } else if (bid.params.hasOwnProperty('currency') && bidCurrency !== bid.params.currency) {
- utils.logWarn(LOG_WARN_PREFIX + 'Currency specifier ignored. Only one currency permitted.');
- }
- bid.params.currency = bidCurrency;
- // check if dctr is added to more than 1 adunit
- if (bid.params.hasOwnProperty('dctr') && utils.isStr(bid.params.dctr)) {
- dctrArr.push(bid.params.dctr);
- }
- if (bid.params.hasOwnProperty('bcat') && utils.isArray(bid.params.bcat)) {
- blockedIabCategories = blockedIabCategories.concat(bid.params.bcat);
- }
- var impObj = _createImpressionObject(bid, conf);
- if (impObj) {
- payload.imp.push(impObj);
- }
- });
-
- if (payload.imp.length == 0) {
- return;
- }
-
- payload.site.publisher.id = conf.pubId.trim();
- publisherId = conf.pubId.trim();
- payload.ext.wrapper = {};
- payload.ext.wrapper.profile = parseInt(conf.profId) || UNDEFINED;
- payload.ext.wrapper.version = parseInt(conf.verId) || UNDEFINED;
- payload.ext.wrapper.wiid = conf.wiid || UNDEFINED;
- payload.ext.wrapper.wv = $$REPO_AND_VERSION$$;
- payload.ext.wrapper.transactionId = conf.transactionId;
- payload.ext.wrapper.wp = 'pbjs';
- payload.user.gender = (conf.gender ? conf.gender.trim() : UNDEFINED);
- payload.user.geo = {};
- payload.user.geo.lat = _parseSlotParam('lat', conf.lat);
- payload.user.geo.lon = _parseSlotParam('lon', conf.lon);
- payload.user.yob = _parseSlotParam('yob', conf.yob);
- payload.device.geo = payload.user.geo;
- payload.site.page = conf.kadpageurl.trim() || payload.site.page.trim();
- payload.site.domain = _getDomainFromURL(payload.site.page);
-
- // adding schain object
- if (validBidRequests[0].schain) {
- payload.source = {
- ext: {
- schain: validBidRequests[0].schain
- }
- };
- }
-
- // Attaching GDPR Consent Params
- if (bidderRequest && bidderRequest.gdprConsent) {
- payload.user.ext = {
- consent: bidderRequest.gdprConsent.consentString
- };
-
- payload.regs = {
- ext: {
- gdpr: (bidderRequest.gdprConsent.gdprApplies ? 1 : 0)
- }
- };
- }
-
- _handleDealCustomTargetings(payload, dctrArr, validBidRequests);
- _handleEids(payload, validBidRequests);
- _blockedIabCategoriesValidation(payload, blockedIabCategories);
-
- return {
- method: 'POST',
- url: ENDPOINT,
- data: JSON.stringify(payload)
- };
- },
-
- /**
- * Unpack the response from the server into a list of bids.
- *
- * @param {*} response A successful response from the server.
- * @return {Bid[]} An array of bids which were nested inside the server.
- */
- interpretResponse: (response, request) => {
- const bidResponses = [];
- var respCur = DEFAULT_CURRENCY;
- let parsedRequest = JSON.parse(request.data);
- let parsedReferrer = parsedRequest.site && parsedRequest.site.ref ? parsedRequest.site.ref : '';
- try {
- if (response.body && response.body.seatbid && utils.isArray(response.body.seatbid)) {
- // Supporting multiple bid responses for same adSize
- respCur = response.body.cur || respCur;
- response.body.seatbid.forEach(seatbidder => {
- seatbidder.bid &&
- utils.isArray(seatbidder.bid) &&
- seatbidder.bid.forEach(bid => {
- let newBid = {
- requestId: bid.impid,
- cpm: (parseFloat(bid.price) || 0).toFixed(2),
- width: bid.w,
- height: bid.h,
- creativeId: bid.crid || bid.id,
- dealId: bid.dealid,
- currency: respCur,
- netRevenue: NET_REVENUE,
- ttl: 300,
- referrer: parsedReferrer,
- ad: bid.adm
- };
- if (parsedRequest.imp && parsedRequest.imp.length > 0) {
- parsedRequest.imp.forEach(req => {
- if (bid.impid === req.id) {
- _checkMediaType(bid.adm, newBid);
- switch (newBid.mediaType) {
- case BANNER:
- break;
- case 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;
- break;
- case NATIVE:
- _parseNativeResponse(bid, newBid);
- break;
- }
- }
- });
- }
- if (bid.ext && bid.ext.deal_channel) {
- newBid['dealChannel'] = dealChannelValues[bid.ext.deal_channel] || null;
- }
-
- newBid.meta = {};
- if (bid.ext && bid.ext.dspid) {
- newBid.meta.networkId = bid.ext.dspid;
- }
- if (bid.ext && bid.ext.advid) {
- newBid.meta.buyerId = bid.ext.advid;
- }
- if (bid.adomain && bid.adomain.length > 0) {
- newBid.meta.clickUrl = bid.adomain[0];
- }
-
- bidResponses.push(newBid);
- });
- });
- }
- } catch (error) {
- utils.logError(error);
- }
- return bidResponses;
- },
-
- /**
- * Register User Sync.
- */
- getUserSyncs: (syncOptions, responses, gdprConsent) => {
- let syncurl = USYNCURL + publisherId;
-
- // Attaching GDPR Consent Params in UserSync url
- if (gdprConsent) {
- syncurl += '&gdpr=' + (gdprConsent.gdprApplies ? 1 : 0);
- syncurl += '&gdpr_consent=' + encodeURIComponent(gdprConsent.consentString || '');
- }
-
- if (syncOptions.iframeEnabled) {
- return [{
- type: 'iframe',
- url: syncurl
- }];
- } else {
- utils.logWarn(LOG_WARN_PREFIX + 'Please enable iframe based user sync.');
- }
- },
-
- /**
- * Covert bid param types for S2S
- * @param {Object} params bid params
- * @param {Boolean} isOpenRtb boolean to check openrtb2 protocol
- * @return {Object} params bid params
- */
- transformBidParams: function (params, isOpenRtb) {
- return utils.convertTypes({
- 'publisherId': 'string',
- 'adSlot': 'string'
- }, params);
- }
-};
-
-registerBidder(spec);
diff --git a/modules/pubmaticBidAdapter.md b/modules/pubmaticBidAdapter.md
deleted file mode 100644
index 1948acba40f..00000000000
--- a/modules/pubmaticBidAdapter.md
+++ /dev/null
@@ -1,202 +0,0 @@
-# Overview
-
-```
-Module Name: PubMatic Bid Adapter
-Module Type: Bidder Adapter
-Maintainer: header-bidding@pubmatic.com
-```
-
-# Description
-
-Connects to PubMatic exchange for bids.
-
-PubMatic bid adapter supports Video, Banner and Native currently.
-
-# Sample Banner Ad Unit: For Publishers
-```
-var adUnits = [
-{
- code: 'test-div',
- sizes: [
- [300, 250],
- [728, 90]
- ],
- bids: [{
- bidder: 'pubmatic',
- params: {
- publisherId: '156209', // required
- adSlot: 'pubmatic_test2', // optional
- pmzoneid: 'zone1, zone11', // optional
- lat: '40.712775', // optional
- lon: '-74.005973', // optional
- yob: '1982', // optional
- kadpageurl: 'www.test.com', // optional
- gender: 'M', // optional
- kadfloor: '0.50', // optional
- currency: 'AUD', // optional (Value configured only in the 1st adunit will be passed on. < br/> Values if present in subsequent adunits, will be ignored.)
- dctr: 'key1=123|key2=345', // optional (Value configured only in the 1st adunit will be passed on. < br/> Values if present in subsequent adunits, will be ignored.)
- bcat: ['IAB1-5', 'IAB1-7'] // Optional: Blocked IAB Categories. (Values from all slots will be combined and only unique values will be passed. An array of strings only. Each category should be a string of a length of more than 3 characters.)
- }
- }]
-}];
-```
-
-# Sample Video Ad Unit: For Publishers
-```
-var adVideoAdUnits = [
-{
- code: 'test-div-video',
- mediaTypes: {
- video: {
- playerSize: [640, 480], // required
- context: 'instream'
- }
- },
- bids: [{
- bidder: 'pubmatic',
- params: {
- publisherId: '156209', // required
- adSlot: 'pubmatic_video1', // optional
- video: {
- mimes: ['video/mp4','video/x-flv'], // required
- skippable: true, // optional
- minduration: 5, // optional
- maxduration: 30, // optional
- startdelay: 5, // optional
- playbackmethod: [1,3], // optional
- api: [ 1, 2 ], // optional
- protocols: [ 2, 3 ], // optional
- battr: [ 13, 14 ], // optional
- linearity: 1, // optional
- placement: 2, // optional
- minbitrate: 10, // optional
- maxbitrate: 10 // optional
- }
- }
- }]
-}]
-```
-
-# Sample Native Ad Unit: For Publishers
-```
-var adUnits = [
-{
- code: 'test-div',
- mediaTypes: {
- native: {
- image: {
- required: true,
- sizes: [150, 50]
- },
- title: {
- required: true,
- len: 80
- },
- sponsoredBy: {
- required: true
- },
- clickUrl: {
- required: true
- }
- }
- },
- bids: [{
- bidder: 'pubmatic',
- params: {
- publisherId: '156295', // required
- adSlot: 'pubmatic_test2@1x1', // optional
- }
- }]
-}];
-```
-# Sample Configuration for Multi-format Ad Unit: For Publishers
-```
-var adUnits = [
-{
- code: 'test-div',
- mediaTypes: {
- banner: {
- sizes: [
- [300, 250],
- [728, 90]
- ]
- },
- video: {
- playerSize: [640, 480], // required
- context: 'instream'
- },
- native: {
- image: {
- required: true,
- sizes: [150, 50]
- },
- title: {
- required: true,
- len: 80
- },
- sponsoredBy: {
- required: true
- },
- clickUrl: {
- required: true
- }
- }
- },
- bids: [{
- bidder: 'pubmatic',
- params: {
- publisherId: '156209', // required
- adSlot: 'pubmatic_test2@300x250', // optional
- pmzoneid: 'zone1, zone11', // optional
- lat: '40.712775', // optional
- lon: '-74.005973', // optional
- yob: '1982', // optional
- kadpageurl: 'www.test.com', // optional
- gender: 'M', // optional
- kadfloor: '0.50', // optional
- currency: 'AUD', // optional (Value configured only in the 1st adunit will be passed on. < br/> Values if present in subsequent adunits, will be ignored.)
- dctr: 'key1=123|key2=345', // optional (Value configured only in the 1st adunit will be passed on. < br/> Values if present in subsequent adunits, will be ignored.)
- video: {
- mimes: ['video/mp4','video/x-flv'], // required
- skippable: true, // optional
- minduration: 5, // optional
- maxduration: 30, // optional
- startdelay: 5, // optional
- playbackmethod: [1,3], // optional
- api: [ 1, 2 ], // optional
- protocols: [ 2, 3 ], // optional
- battr: [ 13, 14 ], // optional
- linearity: 1, // optional
- placement: 2, // optional
- minbitrate: 10, // optional
- maxbitrate: 10 // optional
- }
- }
- }]
-}];
-```
-
-
-# ## Configuration
-
-PubMatic recommends the UserSync configuration below. Without it, the PubMatic adapter will not able to perform user syncs, which lowers match rate and reduces monetization.
-
-```javascript
-pbjs.setConfig({
- userSync: {
- iframeEnabled: true,
- enabledBidders: ['pubmatic'],
- syncDelay: 6000
- }});
-
-
-For Video ads, prebid cache needs to be enabled for PubMatic adapter.
-pbjs.setConfig({
- debug: true,
- cache: {
- url: 'https://prebid.adnxs.com/pbc/v1/cache'
- }
-});
-
-```
-Note: Combine the above the configuration with any other UserSync configuration. Multiple setConfig() calls overwrite each other and only last call for a given attribute will take effect.
diff --git a/modules/radsBidAdapter.js b/modules/radsBidAdapter.js
new file mode 100644
index 00000000000..026dc3c4af6
--- /dev/null
+++ b/modules/radsBidAdapter.js
@@ -0,0 +1,151 @@
+import * as utils from '../src/utils';
+import {config} from '../src/config';
+import {registerBidder} from '../src/adapters/bidderFactory';
+import { BANNER, VIDEO } from '../src/mediaTypes';
+
+const BIDDER_CODE = 'rads';
+const ENDPOINT_URL = 'https://rads.recognified.net/md.request.php';
+const ENDPOINT_URL_DEV = 'https://dcradn1.online-solution.biz/md.request.php';
+const DEFAULT_VAST_FORMAT = 'vast2';
+
+export const spec = {
+ code: BIDDER_CODE,
+ aliases: ['rads'],
+ supportedMediaTypes: [BANNER, VIDEO],
+ isBidRequestValid: function(bid) {
+ return !!(bid.params.placement);
+ },
+ buildRequests: function(validBidRequests, bidderRequest) {
+ return validBidRequests.map(bidRequest => {
+ const params = bidRequest.params;
+ const videoData = utils.deepAccess(bidRequest, 'mediaTypes.video') || {};
+ const sizes = utils.parseSizesInput(videoData.playerSize || bidRequest.sizes)[0];
+ const [width, height] = sizes.split('x');
+ const placementId = params.placement;
+
+ const rnd = Math.floor(Math.random() * 99999999999);
+ const referrer = encodeURIComponent(bidderRequest.refererInfo.referer);
+ const bidId = bidRequest.bidId;
+ const isDev = params.devMode || false;
+
+ let endpoint = isDev ? ENDPOINT_URL_DEV : ENDPOINT_URL;
+
+ let payload = {};
+ if (isVideoRequest(bidRequest)) {
+ let vastFormat = params.vastFormat || DEFAULT_VAST_FORMAT;
+ payload = {
+ rt: vastFormat,
+ _f: 'prebid_js',
+ _ps: placementId,
+ srw: width,
+ srh: height,
+ idt: 100,
+ rnd: rnd,
+ p: referrer,
+ bid_id: bidId,
+ };
+ } else {
+ payload = {
+ rt: 'bid-response',
+ _f: 'prebid_js',
+ _ps: placementId,
+ srw: width,
+ srh: height,
+ idt: 100,
+ rnd: rnd,
+ p: referrer,
+ bid_id: bidId,
+ };
+ }
+ prepareExtraParams(params, payload);
+
+ return {
+ method: 'GET',
+ url: endpoint,
+ data: objectToQueryString(payload),
+ }
+ });
+ },
+ interpretResponse: function(serverResponse, bidRequest) {
+ const bidResponses = [];
+ const response = serverResponse.body;
+ const crid = response.crid || 0;
+ const cpm = response.cpm / 1000000 || 0;
+ if (cpm !== 0 && crid !== 0) {
+ const dealId = response.dealid || '';
+ const currency = response.currency || 'EUR';
+ const netRevenue = (response.netRevenue === undefined) ? true : response.netRevenue;
+ const bidResponse = {
+ requestId: response.bid_id,
+ cpm: cpm,
+ width: response.width,
+ height: response.height,
+ creativeId: crid,
+ dealId: dealId,
+ currency: currency,
+ netRevenue: netRevenue,
+ ttl: config.getConfig('_bidderTimeout')
+ };
+
+ if (response.vastXml) {
+ bidResponse.vastXml = response.vastXml;
+ bidResponse.mediaType = 'video';
+ } else {
+ bidResponse.ad = response.adTag;
+ }
+
+ bidResponses.push(bidResponse);
+ }
+ return bidResponses;
+ }
+}
+
+function objectToQueryString(obj, prefix) {
+ let str = [];
+ let p;
+ for (p in obj) {
+ if (obj.hasOwnProperty(p)) {
+ let k = prefix ? prefix + '[' + p + ']' : p;
+ let v = obj[p];
+ str.push((v !== null && typeof v === 'object')
+ ? objectToQueryString(v, k)
+ : encodeURIComponent(k) + '=' + encodeURIComponent(v));
+ }
+ }
+ return str.join('&');
+}
+
+/**
+ * Check if it's a video bid request
+ *
+ * @param {BidRequest} bid - Bid request generated from ad slots
+ * @returns {boolean} True if it's a video bid
+ */
+function isVideoRequest(bid) {
+ return bid.mediaType === 'video' || !!utils.deepAccess(bid, 'mediaTypes.video');
+}
+
+function prepareExtraParams(params, payload) {
+ if (params.pfilter !== undefined) {
+ payload.pfilter = params.pfilter;
+ }
+ if (params.bcat !== undefined) {
+ payload.bcat = params.bcat;
+ }
+ if (params.dvt !== undefined) {
+ payload.dvt = params.dvt;
+ }
+
+ if (params.latitude !== undefined) {
+ payload.latitude = params.latitude;
+ }
+
+ if (params.longitude !== undefined) {
+ payload.longitude = params.longitude;
+ }
+ if (params.ip !== undefined) {
+ payload.i = params.ip;
+ }
+}
+
+registerBidder(spec);
diff --git a/modules/radsBidAdapter.md b/modules/radsBidAdapter.md
new file mode 100644
index 00000000000..6e970093154
--- /dev/null
+++ b/modules/radsBidAdapter.md
@@ -0,0 +1,37 @@
+# Overview
+
+```
+Module Name: RADS Bidder Adapter
+Module Type: Bidder Adapter
+Maintainer: prebid@recognified.net
+```
+
+# Description
+
+RADS Bidder Adapter for Prebid.js 1.x
+
+# Test Parameters
+```
+ var adUnits = [
+ {
+ code: "test-div",
+ mediaTypes: {
+ banner: {
+ sizes: [[320, 50]]
+ }
+ },
+ bids: [
+ {
+ bidder: "rads",
+ params: {
+ placement: 3, // placement ID
+ devMode: true // if true: library uses dev server for tests
+ }
+ }
+ ]
+ }
+ ];
+```
+
+Required param field is only `placement`.
+
diff --git a/modules/rubiconAnalyticsAdapter.js b/modules/rubiconAnalyticsAdapter.js
deleted file mode 100644
index 560cab91dca..00000000000
--- a/modules/rubiconAnalyticsAdapter.js
+++ /dev/null
@@ -1,470 +0,0 @@
-import adapter from '../src/AnalyticsAdapter';
-import adapterManager from '../src/adapterManager';
-import CONSTANTS from '../src/constants.json';
-import { ajax } from '../src/ajax';
-import { config } from '../src/config';
-import * as utils from '../src/utils';
-
-const {
- EVENTS: {
- AUCTION_INIT,
- AUCTION_END,
- BID_REQUESTED,
- BID_RESPONSE,
- BIDDER_DONE,
- BID_TIMEOUT,
- BID_WON,
- SET_TARGETING
- },
- STATUS: {
- GOOD,
- NO_BID
- }
-} = CONSTANTS;
-
-let serverConfig;
-config.getConfig('s2sConfig', ({s2sConfig}) => {
- serverConfig = s2sConfig;
-});
-
-export const SEND_TIMEOUT = 3000;
-const DEFAULT_INTEGRATION = 'pbjs';
-
-const cache = {
- auctions: {},
- targeting: {},
- timeouts: {},
-};
-
-function stringProperties(obj) {
- return Object.keys(obj).reduce((newObj, prop) => {
- let value = obj[prop];
- if (typeof value === 'number') {
- value = value.toFixed(3);
- } else if (typeof value !== 'string') {
- value = String(value);
- }
- newObj[prop] = value;
- return newObj;
- }, {});
-}
-
-function sizeToDimensions(size) {
- return {
- width: size.w || size[0],
- height: size.h || size[1]
- };
-}
-
-function validMediaType(type) {
- return ['banner', 'native', 'video'].indexOf(type) !== -1;
-}
-
-function formatSource(src) {
- if (typeof src === 'undefined') {
- src = 'client';
- } else if (src === 's2s') {
- src = 'server';
- }
- return src.toLowerCase();
-}
-
-function sendMessage(auctionId, bidWonId) {
- function formatBid(bid) {
- return utils.pick(bid, [
- 'bidder',
- 'bidId',
- 'status',
- 'error',
- 'source', (source, bid) => {
- if (source) {
- return source;
- }
- return serverConfig && Array.isArray(serverConfig.bidders) && serverConfig.bidders.indexOf(bid.bidder) !== -1
- ? 'server' : 'client'
- },
- 'clientLatencyMillis',
- 'serverLatencyMillis',
- 'params',
- 'bidResponse', bidResponse => bidResponse ? utils.pick(bidResponse, [
- 'bidPriceUSD',
- 'dealId',
- 'dimensions',
- 'mediaType'
- ]) : undefined
- ]);
- }
- function formatBidWon(bid) {
- return Object.assign(formatBid(bid), utils.pick(bid.adUnit, [
- 'adUnitCode',
- 'transactionId',
- 'videoAdFormat', () => bid.videoAdFormat,
- 'mediaTypes'
- ]), {
- adserverTargeting: stringProperties(cache.targeting[bid.adUnit.adUnitCode] || {}),
- bidwonStatus: 'success', // hard-coded for now
- accountId,
- siteId: bid.siteId,
- zoneId: bid.zoneId,
- samplingFactor
- });
- }
- let referrer = config.getConfig('pageUrl') || utils.getTopWindowUrl();
- let message = {
- eventTimeMillis: Date.now(),
- integration: config.getConfig('rubicon.int_type') || DEFAULT_INTEGRATION,
- version: '$prebid.version$',
- referrerUri: referrer
- };
- const wrapperName = config.getConfig('rubicon.wrapperName');
- if (wrapperName) {
- message.wrapperName = wrapperName;
- }
- let auctionCache = cache.auctions[auctionId];
- if (auctionCache && !auctionCache.sent) {
- let adUnitMap = Object.keys(auctionCache.bids).reduce((adUnits, bidId) => {
- let bid = auctionCache.bids[bidId];
- let adUnit = adUnits[bid.adUnit.adUnitCode];
- if (!adUnit) {
- adUnit = adUnits[bid.adUnit.adUnitCode] = utils.pick(bid.adUnit, [
- 'adUnitCode',
- 'transactionId',
- 'mediaTypes',
- 'dimensions',
- 'adserverTargeting', () => stringProperties(cache.targeting[bid.adUnit.adUnitCode] || {})
- ]);
- adUnit.bids = [];
- }
-
- // Add site and zone id if not there and if we found a rubicon bidder
- if ((!adUnit.siteId || !adUnit.zoneId) && rubiconAliases.indexOf(bid.bidder) !== -1) {
- if (utils.deepAccess(bid, 'params.accountId') == accountId) {
- adUnit.accountId = parseInt(accountId);
- adUnit.siteId = parseInt(utils.deepAccess(bid, 'params.siteId'));
- adUnit.zoneId = parseInt(utils.deepAccess(bid, 'params.zoneId'));
- }
- }
-
- if (bid.videoAdFormat && !adUnit.videoAdFormat) {
- adUnit.videoAdFormat = bid.videoAdFormat;
- }
-
- // determine adUnit.status from its bid statuses. Use priority below to determine, higher index is better
- let statusPriority = ['error', 'no-bid', 'success'];
- if (statusPriority.indexOf(bid.status) > statusPriority.indexOf(adUnit.status)) {
- adUnit.status = bid.status;
- }
-
- adUnit.bids.push(formatBid(bid));
-
- return adUnits;
- }, {});
-
- // We need to mark each cached bid response with its appropriate rubicon site-zone id
- // This allows the bidWon events to have these params even in the case of a delayed render
- Object.keys(auctionCache.bids).forEach(function (bidId) {
- let adCode = auctionCache.bids[bidId].adUnit.adUnitCode;
- Object.assign(auctionCache.bids[bidId], utils.pick(adUnitMap[adCode], ['accountId', 'siteId', 'zoneId']));
- });
-
- let auction = {
- clientTimeoutMillis: auctionCache.timeout,
- samplingFactor,
- accountId,
- adUnits: Object.keys(adUnitMap).map(i => adUnitMap[i])
- };
-
- if (serverConfig) {
- auction.serverTimeoutMillis = serverConfig.timeout;
- }
-
- message.auctions = [auction];
-
- let bidsWon = Object.keys(auctionCache.bidsWon).reduce((memo, adUnitCode) => {
- let bidId = auctionCache.bidsWon[adUnitCode];
- if (bidId) {
- memo.push(formatBidWon(auctionCache.bids[bidId]));
- }
- return memo;
- }, []);
-
- if (bidsWon.length > 0) {
- message.bidsWon = bidsWon;
- }
-
- auctionCache.sent = true;
- } else if (bidWonId && auctionCache && auctionCache.bids[bidWonId]) {
- message.bidsWon = [
- formatBidWon(auctionCache.bids[bidWonId])
- ];
- }
-
- ajax(
- this.getUrl(),
- null,
- JSON.stringify(message),
- {
- contentType: 'application/json'
- }
- );
-}
-
-export function parseBidResponse(bid) {
- return utils.pick(bid, [
- 'bidPriceUSD', () => {
- if (typeof bid.currency === 'string' && bid.currency.toUpperCase() === 'USD') {
- return Number(bid.cpm);
- }
- // use currency conversion function if present
- if (typeof bid.getCpmInNewCurrency === 'function') {
- return Number(bid.getCpmInNewCurrency('USD'));
- }
- utils.logWarn('Rubicon Analytics Adapter: Could not determine the bidPriceUSD of the bid ', bid);
- },
- 'dealId',
- 'status',
- 'mediaType',
- 'dimensions', () => utils.pick(bid, [
- 'width',
- 'height'
- ])
- ]);
-}
-
-let samplingFactor = 1;
-let accountId;
-// List of known rubicon aliases
-// This gets updated on auction init to account for any custom aliases present
-let rubiconAliases = ['rubicon'];
-
-/*
- Checks the alias registry for any entries of the rubicon bid adapter.
- adds to the rubiconAliases list if found
-*/
-function setRubiconAliases(aliasRegistry) {
- Object.keys(aliasRegistry).forEach(function (alias) {
- if (aliasRegistry[alias] === 'rubicon') {
- rubiconAliases.push(alias);
- }
- });
-}
-
-let baseAdapter = adapter({analyticsType: 'endpoint'});
-let rubiconAdapter = Object.assign({}, baseAdapter, {
- enableAnalytics(config = {}) {
- let error = false;
- samplingFactor = 1;
-
- if (typeof config.options === 'object') {
- if (config.options.accountId) {
- accountId = Number(config.options.accountId);
- }
- if (config.options.endpoint) {
- this.getUrl = () => config.options.endpoint;
- } else {
- utils.logError('required endpoint missing from rubicon analytics');
- error = true;
- }
- if (typeof config.options.sampling !== 'undefined') {
- samplingFactor = 1 / parseFloat(config.options.sampling);
- }
- if (typeof config.options.samplingFactor !== 'undefined') {
- if (typeof config.options.sampling !== 'undefined') {
- utils.logWarn('Both options.samplingFactor and options.sampling enabled in rubicon analytics, defaulting to samplingFactor');
- }
- samplingFactor = parseFloat(config.options.samplingFactor);
- config.options.sampling = 1 / samplingFactor;
- }
- }
-
- let validSamplingFactors = [1, 10, 20, 40, 100];
- if (validSamplingFactors.indexOf(samplingFactor) === -1) {
- error = true;
- utils.logError('invalid samplingFactor for rubicon analytics: ' + samplingFactor + ', must be one of ' + validSamplingFactors.join(', '));
- } else if (!accountId) {
- error = true;
- utils.logError('required accountId missing for rubicon analytics');
- }
-
- if (!error) {
- baseAdapter.enableAnalytics.call(this, config);
- }
- },
- disableAnalytics() {
- this.getUrl = baseAdapter.getUrl;
- accountId = null;
- baseAdapter.disableAnalytics.apply(this, arguments);
- },
- track({eventType, args}) {
- switch (eventType) {
- case AUCTION_INIT:
- // set the rubicon aliases
- setRubiconAliases(adapterManager.aliasRegistry);
- let cacheEntry = utils.pick(args, [
- 'timestamp',
- 'timeout'
- ]);
- cacheEntry.bids = {};
- cacheEntry.bidsWon = {};
- cache.auctions[args.auctionId] = cacheEntry;
- break;
- case BID_REQUESTED:
- Object.assign(cache.auctions[args.auctionId].bids, args.bids.reduce((memo, bid) => {
- // mark adUnits we expect bidWon events for
- cache.auctions[args.auctionId].bidsWon[bid.adUnitCode] = false;
-
- memo[bid.bidId] = utils.pick(bid, [
- 'bidder', bidder => bidder.toLowerCase(),
- 'bidId',
- 'status', () => 'no-bid', // default a bid to no-bid until response is recieved or bid is timed out
- 'finalSource as source',
- 'params', (params, bid) => {
- switch (bid.bidder) {
- // specify bidder params we want here
- case 'rubicon':
- return utils.pick(params, [
- 'accountId',
- 'siteId',
- 'zoneId'
- ]);
- }
- },
- 'videoAdFormat', (_, cachedBid) => {
- if (cachedBid.bidder === 'rubicon') {
- return ({
- 201: 'pre-roll',
- 202: 'interstitial',
- 203: 'outstream',
- 204: 'mid-roll',
- 205: 'post-roll',
- 207: 'vertical'
- })[utils.deepAccess(bid, 'params.video.size_id')];
- } else {
- let startdelay = parseInt(utils.deepAccess(bid, 'params.video.startdelay'), 10);
- if (!isNaN(startdelay)) {
- if (startdelay > 0) {
- return 'mid-roll';
- }
- return ({
- '0': 'pre-roll',
- '-1': 'mid-roll',
- '-2': 'post-roll'
- })[startdelay]
- }
- }
- },
- 'adUnit', () => utils.pick(bid, [
- 'adUnitCode',
- 'transactionId',
- 'sizes as dimensions', sizes => sizes.map(sizeToDimensions),
- 'mediaTypes', (types) => {
- if (bid.mediaType && validMediaType(bid.mediaType)) {
- return [bid.mediaType];
- }
- if (Array.isArray(types)) {
- return types.filter(validMediaType);
- }
- if (typeof types === 'object') {
- if (!bid.sizes) {
- bid.dimensions = [];
- utils._each(types, (type) =>
- bid.dimensions = bid.dimensions.concat(
- type.sizes.map(sizeToDimensions)
- )
- );
- }
- return Object.keys(types).filter(validMediaType);
- }
- return ['banner'];
- }
- ])
- ]);
- return memo;
- }, {}));
- break;
- case BID_RESPONSE:
- let bid = cache.auctions[args.auctionId].bids[args.requestId];
- if (!bid) {
- utils.logError('Rubicon Anlytics Adapter Error: Could not find associated bid request for bid response with requestId: ', args.requestId);
- break;
- }
- bid.source = formatSource(bid.source || args.source);
- switch (args.getStatusCode()) {
- case GOOD:
- bid.status = 'success';
- delete bid.error; // it's possible for this to be set by a previous timeout
- break;
- case NO_BID:
- bid.status = 'no-bid';
- delete bid.error;
- break;
- default:
- bid.status = 'error';
- bid.error = {
- code: 'request-error'
- };
- }
- bid.clientLatencyMillis = Date.now() - cache.auctions[args.auctionId].timestamp;
- bid.bidResponse = parseBidResponse(args);
- break;
- case BIDDER_DONE:
- args.bids.forEach(bid => {
- let cachedBid = cache.auctions[bid.auctionId].bids[bid.bidId || bid.requestId];
- if (typeof bid.serverResponseTimeMs !== 'undefined') {
- cachedBid.serverLatencyMillis = bid.serverResponseTimeMs;
- }
- if (!cachedBid.status) {
- cachedBid.status = 'no-bid';
- }
- if (!cachedBid.clientLatencyMillis) {
- cachedBid.clientLatencyMillis = Date.now() - cache.auctions[bid.auctionId].timestamp;
- }
- });
- break;
- case SET_TARGETING:
- Object.assign(cache.targeting, args);
- break;
- case BID_WON:
- let auctionCache = cache.auctions[args.auctionId];
- auctionCache.bidsWon[args.adUnitCode] = args.requestId;
-
- // check if this BID_WON missed the boat, if so send by itself
- if (auctionCache.sent === true) {
- sendMessage.call(this, args.auctionId, args.requestId);
- } else if (Object.keys(auctionCache.bidsWon).reduce((memo, adUnitCode) => {
- // only send if we've received bidWon events for all adUnits in auction
- memo = memo && auctionCache.bidsWon[adUnitCode];
- return memo;
- }, true)) {
- clearTimeout(cache.timeouts[args.auctionId]);
- delete cache.timeouts[args.auctionId];
-
- sendMessage.call(this, args.auctionId);
- }
- break;
- case AUCTION_END:
- // start timer to send batched payload just in case we don't hear any BID_WON events
- cache.timeouts[args.auctionId] = setTimeout(() => {
- sendMessage.call(this, args.auctionId);
- }, SEND_TIMEOUT);
- break;
- case BID_TIMEOUT:
- args.forEach(badBid => {
- let auctionCache = cache.auctions[badBid.auctionId];
- let bid = auctionCache.bids[badBid.bidId || badBid.requestId];
- bid.status = 'error';
- bid.error = {
- code: 'timeout-error'
- };
- });
- break;
- }
- }
-});
-
-adapterManager.registerAnalyticsAdapter({
- adapter: rubiconAdapter,
- code: 'rubicon'
-});
-
-export default rubiconAdapter;
diff --git a/modules/schain.js b/modules/schain.js
index a5797ba4b39..45850aabc3d 100644
--- a/modules/schain.js
+++ b/modules/schain.js
@@ -1,6 +1,6 @@
import {config} from '../src/config';
import {getGlobal} from '../src/prebidGlobal';
-import { isNumber, isStr, isArray, isPlainObject, hasOwn, logError, isInteger } from '../src/utils';
+import { isNumber, isStr, isArray, isPlainObject, hasOwn, logError, isInteger, _each } from '../src/utils';
// https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/supplychainobject.md
@@ -14,6 +14,8 @@ const MODE = {
RELAXED: 'relaxed',
OFF: 'off'
};
+const MODES = []; // an array of modes
+_each(MODE, mode => MODES.push(mode));
// validate the supply chain object
export function isSchainObjectValid(schainObject, returnOnError) {
@@ -133,7 +135,7 @@ export function init(config) {
getGlobal().requestBids.before(function(fn, reqBidsConfigObj) {
let schainObject = config.getConfig('schain');
if (isValidSchainConfig(schainObject)) {
- if (isStr(schainObject.validation) && Object.values(MODE).indexOf(schainObject.validation) != -1) {
+ if (isStr(schainObject.validation) && MODES.indexOf(schainObject.validation) != -1) {
mode = schainObject.validation;
}
if (mode === MODE.OFF) {
diff --git a/modules/tripleliftBidAdapter.js b/modules/tripleliftBidAdapter.js
index 2d6b2dce8de..5ed88384b11 100644
--- a/modules/tripleliftBidAdapter.js
+++ b/modules/tripleliftBidAdapter.js
@@ -17,7 +17,7 @@ export const tripleliftAdapterSpec = {
buildRequests: function(bidRequests, bidderRequest) {
let tlCall = STR_ENDPOINT;
- let data = _buildPostBody(bidRequests, bidderRequest);
+ let data = _buildPostBody(bidRequests);
tlCall = utils.tryAppendQueryString(tlCall, 'lib', 'prebid');
tlCall = utils.tryAppendQueryString(tlCall, 'v', '$prebid.version$');
@@ -78,7 +78,7 @@ export const tripleliftAdapterSpec = {
}
}
-function _buildPostBody(bidRequests, bidderRequest) {
+function _buildPostBody(bidRequests) {
let data = {};
data.imp = bidRequests.map(function(bid, index) {
return {
@@ -91,7 +91,11 @@ function _buildPostBody(bidRequests, bidderRequest) {
};
});
- let eids = handleConsortiaUserIds(bidderRequest);
+ let eids = [
+ ...getUnifiedIdEids(bidRequests),
+ ...getIdentityLinkEids(bidRequests)
+ ];
+
if (eids.length > 0) {
data.user = {
ext: {eids}
@@ -101,6 +105,35 @@ function _buildPostBody(bidRequests, bidderRequest) {
return data;
}
+function getUnifiedIdEids(bidRequests) {
+ return getEids(bidRequests, 'tdid', 'adserver.org', 'TDID');
+}
+
+function getIdentityLinkEids(bidRequests) {
+ return getEids(bidRequests, 'idl_env', 'liveramp.com', 'idl');
+}
+
+function getEids(bidRequests, type, source, rtiPartner) {
+ return bidRequests
+ .map(getUserId(type)) // bids -> userIds of a certain type
+ .filter((x) => !!x) // filter out null userIds
+ .map(formatEid(source, rtiPartner)); // userIds -> eid objects
+}
+
+function getUserId(type) {
+ return (bid) => (bid && bid.userId && bid.userId[type]);
+}
+
+function formatEid(source, rtiPartner) {
+ return (id) => ({
+ source,
+ uids: [{
+ id,
+ ext: { rtiPartner }
+ }]
+ });
+}
+
function _sizes(sizeArray) {
let sizes = sizeArray.filter(_isValidSize);
return sizes.map(function(size) {
@@ -115,23 +148,6 @@ function _isValidSize(size) {
return (size.length === 2 && typeof size[0] === 'number' && typeof size[1] === 'number');
}
-function handleConsortiaUserIds(bidderRequest) {
- let eids = [];
- if (bidderRequest.userId && bidderRequest.userId.tdid) {
- eids.push({
- source: 'adserver.org',
- uids: [{
- id: bidderRequest.userId.tdid,
- ext: {
- rtiPartner: 'TDID'
- }
- }]
- });
- }
-
- return eids;
-}
-
function _buildResponseObject(bidderRequest, bid) {
let bidResponse = {};
let width = bid.width || 1;
diff --git a/modules/tripleliftBidAdapter.md b/modules/tripleliftBidAdapter.md
index c10ea3675d4..d5f88a2bece 100644
--- a/modules/tripleliftBidAdapter.md
+++ b/modules/tripleliftBidAdapter.md
@@ -3,7 +3,7 @@
```
Module Name: Triplelift Bid Adapter
Module Type: Bidder Adapter
-Maintainer: csmith+s2s@triplelift.com
+Maintainer: prebid@triplelift.com
```
# Description
diff --git a/modules/turktelekomBidAdapter.js b/modules/turktelekomBidAdapter.js
new file mode 100644
index 00000000000..f2fef1962d0
--- /dev/null
+++ b/modules/turktelekomBidAdapter.js
@@ -0,0 +1,261 @@
+import * as utils from '../src/utils';
+import {registerBidder} from '../src/adapters/bidderFactory';
+import { Renderer } from '../src/Renderer';
+import { VIDEO, BANNER } from '../src/mediaTypes';
+
+const BIDDER_CODE = 'turktelekom';
+const ENDPOINT_URL = '//ssp.programattik.com/hb';
+const TIME_TO_LIVE = 360;
+const ADAPTER_SYNC_URL = '//ssp.programattik.com/sync';
+const RENDERER_URL = '//acdn.adnxs.com/video/outstream/ANOutstreamVideo.js';
+
+const LOG_ERROR_MESS = {
+ noAuid: 'Bid from response has no auid parameter - ',
+ noAdm: 'Bid from response has no adm 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: [ BANNER, 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) {
+ return !!bid.params.uid;
+ },
+ /**
+ * Make a server request from the list of BidRequests.
+ *
+ * @param {BidRequest[]} validBidRequests - an array of bids
+ * @param {bidderRequest} - bidder request object
+ * @return ServerRequest Info describing the request to the server.
+ */
+ buildRequests: function(validBidRequests, bidderRequest) {
+ const auids = [];
+ const bidsMap = {};
+ const slotsMapByUid = {};
+ const sizeMap = {};
+ const bids = validBidRequests || [];
+ let priceType = 'net';
+ let reqId;
+
+ bids.forEach(bid => {
+ if (bid.params.priceType === 'gross') {
+ priceType = 'gross';
+ }
+ reqId = bid.bidderRequestId;
+ const {params: {uid}, adUnitCode} = bid;
+ auids.push(uid);
+ const sizesId = utils.parseSizesInput(bid.sizes);
+
+ if (!slotsMapByUid[uid]) {
+ slotsMapByUid[uid] = {};
+ }
+ const slotsMap = slotsMapByUid[uid];
+ if (!slotsMap[adUnitCode]) {
+ slotsMap[adUnitCode] = {adUnitCode, bids: [bid], parents: []};
+ } else {
+ slotsMap[adUnitCode].bids.push(bid);
+ }
+ const slot = slotsMap[adUnitCode];
+
+ sizesId.forEach((sizeId) => {
+ sizeMap[sizeId] = true;
+ if (!bidsMap[uid]) {
+ bidsMap[uid] = {};
+ }
+
+ if (!bidsMap[uid][sizeId]) {
+ bidsMap[uid][sizeId] = [slot];
+ } else {
+ bidsMap[uid][sizeId].push(slot);
+ }
+ slot.parents.push({parent: bidsMap[uid], key: sizeId, uid});
+ });
+ });
+
+ const payload = {
+ pt: priceType,
+ auids: auids.join(','),
+ sizes: utils.getKeys(sizeMap).join(','),
+ r: reqId,
+ wrapperType: 'Prebid_js',
+ wrapperVersion: '$prebid.version$'
+ };
+
+ if (bidderRequest) {
+ if (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) {
+ payload.u = bidderRequest.refererInfo.referer;
+ }
+ if (bidderRequest.timeout) {
+ payload.wtimeout = bidderRequest.timeout;
+ }
+ if (bidderRequest.gdprConsent) {
+ if (bidderRequest.gdprConsent.consentString) {
+ payload.gdpr_consent = bidderRequest.gdprConsent.consentString;
+ }
+ payload.gdpr_applies =
+ (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean')
+ ? Number(bidderRequest.gdprConsent.gdprApplies) : 1;
+ }
+ }
+
+ return {
+ method: 'GET',
+ url: ENDPOINT_URL,
+ data: utils.parseQueryStringParameters(payload).replace(/\&$/, ''),
+ bidsMap: bidsMap,
+ };
+ },
+ /**
+ * 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, RendererConst = Renderer) {
+ serverResponse = serverResponse && serverResponse.body;
+ const bidResponses = [];
+ const bidsMap = bidRequest.bidsMap;
+ const priceType = bidRequest.data.pt;
+
+ 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) {
+ serverResponse.seatbid.forEach(respItem => {
+ _addBidResponse(_getBidFromResponse(respItem), bidsMap, priceType, bidResponses, RendererConst);
+ });
+ }
+ if (errorMessage) utils.logError(errorMessage);
+ return bidResponses;
+ },
+ getUserSyncs: function(syncOptions) {
+ if (syncOptions.pixelEnabled) {
+ return [{
+ type: 'image',
+ url: ADAPTER_SYNC_URL
+ }];
+ }
+ }
+}
+
+function _getBidFromResponse(respItem) {
+ if (!respItem) {
+ utils.logError(LOG_ERROR_MESS.emptySeatbid);
+ } else if (!respItem.bid) {
+ utils.logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem));
+ } else if (!respItem.bid[0]) {
+ utils.logError(LOG_ERROR_MESS.noBid);
+ }
+ return respItem && respItem.bid && respItem.bid[0];
+}
+
+function _addBidResponse(serverBid, bidsMap, priceType, bidResponses, RendererConst) {
+ if (!serverBid) return;
+ let errorMessage;
+ if (!serverBid.auid) errorMessage = LOG_ERROR_MESS.noAuid + JSON.stringify(serverBid);
+ if (!serverBid.adm) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid);
+ else {
+ const awaitingBids = bidsMap[serverBid.auid];
+ if (awaitingBids) {
+ const sizeId = `${serverBid.w}x${serverBid.h}`;
+ if (awaitingBids[sizeId]) {
+ const slot = awaitingBids[sizeId][0];
+
+ const bid = slot.bids.shift();
+ const bidResponse = {
+ requestId: bid.bidId, // bid.bidderRequestId,
+ bidderCode: spec.code,
+ cpm: serverBid.price,
+ width: serverBid.w,
+ height: serverBid.h,
+ creativeId: serverBid.auid, // bid.bidId,
+ currency: 'TRY',
+ netRevenue: priceType !== 'gross',
+ ttl: TIME_TO_LIVE,
+ dealId: serverBid.dealid
+ };
+ if (serverBid.content_type === 'video') {
+ bidResponse.vastXml = serverBid.adm;
+ bidResponse.mediaType = VIDEO;
+ bidResponse.adResponse = {
+ content: bidResponse.vastXml
+ };
+ if (!bid.renderer && (!bid.mediaTypes || !bid.mediaTypes.video || bid.mediaTypes.video.context === 'outstream')) {
+ bidResponse.renderer = createRenderer(bidResponse, {
+ id: bid.bidId,
+ url: RENDERER_URL
+ }, RendererConst);
+ }
+ } else {
+ bidResponse.ad = serverBid.adm;
+ bidResponse.mediaType = BANNER;
+ }
+
+ bidResponses.push(bidResponse);
+
+ if (!slot.bids.length) {
+ slot.parents.forEach(({parent, key, uid}) => {
+ const index = parent[key].indexOf(slot);
+ if (index > -1) {
+ parent[key].splice(index, 1);
+ }
+ if (!parent[key].length) {
+ delete parent[key];
+ if (!utils.getKeys(parent).length) {
+ delete bidsMap[uid];
+ }
+ }
+ });
+ }
+ }
+ } else {
+ errorMessage = LOG_ERROR_MESS.noPlacementCode + serverBid.auid;
+ }
+ }
+ if (errorMessage) {
+ utils.logError(errorMessage);
+ }
+}
+
+function outstreamRender (bid) {
+ bid.renderer.push(() => {
+ window.ANOutstreamVideo.renderAd({
+ targetId: bid.adUnitCode,
+ adResponse: bid.adResponse
+ });
+ });
+}
+
+function createRenderer (bid, rendererParams, RendererConst) {
+ const rendererInst = RendererConst.install({
+ id: rendererParams.id,
+ url: rendererParams.url,
+ loaded: false
+ });
+
+ try {
+ rendererInst.setRender(outstreamRender);
+ } catch (err) {
+ utils.logWarn('Prebid Error calling setRender on renderer', err);
+ }
+
+ return rendererInst;
+}
+
+registerBidder(spec);
diff --git a/modules/turktelekomBidAdapter.md b/modules/turktelekomBidAdapter.md
new file mode 100644
index 00000000000..360e7f95230
--- /dev/null
+++ b/modules/turktelekomBidAdapter.md
@@ -0,0 +1,49 @@
+# Overview
+
+Module Name: Türk Telekom Bidder Adapter
+Module Type: Bidder Adapter
+Maintainer: turktelssp@gmail.com
+
+# Description
+
+Module that connects to Türk Telekom demand source to fetch bids.
+Türk Telekom Bid Adapter supports Banner and Video (instream and outstream).
+
+# Test Parameters
+```
+ var adUnits = [
+ {
+ code: 'test-div',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300,600]]
+ }
+ },
+ bids: [
+ {
+ bidder: "turktelekom",
+ params: {
+ uid: 17,
+ priceType: 'gross' // by default is 'net'
+ }
+ }
+ ]
+ },{
+ code: 'test-div',
+ mediaTypes: {
+ video: {
+ playerSize: [[640, 360]],
+ context: 'instream'
+ }
+ },
+ bids: [
+ {
+ bidder: "turktelekom",
+ params: {
+ uid: 19
+ }
+ }
+ ]
+ }
+ ];
+```
\ No newline at end of file
diff --git a/modules/userId/index.js b/modules/userId/index.js
index fb7a748b7ec..8302a7a89e3 100644
--- a/modules/userId/index.js
+++ b/modules/userId/index.js
@@ -9,12 +9,27 @@
/**
* @function
- * @summary performs action to obtain id and return a value in the callback's response argument
+ * @summary performs action to obtain id and return a value in the callback's response argument.
+ * If IdResponse#id is defined, then it will be written to the current active storage.
+ * If IdResponse#callback is defined, then it'll called at the end of auction.
+ * It's permissible to return neither, one, or both fields.
* @name Submodule#getId
* @param {SubmoduleParams} configParams
* @param {ConsentData|undefined} consentData
* @param {(Object|undefined)} cacheIdObj
- * @return {(Object|function)} id data or a callback, the callback is called on the auction end event
+ * @return {(IdResponse|undefined)} A response object that contains id and/or callback.
+ */
+
+/**
+ * @function
+ * @summary Similar to Submodule#getId, this optional method returns response to for id that exists already.
+ * If IdResponse#id is defined, then it will be written to the current active storage even if it exists already.
+ * If IdResponse#callback is defined, then it'll called at the end of auction.
+ * It's permissible to return neither, one, or both fields.
+ * @name Submodule#extendId
+ * @param {SubmoduleParams} configParams
+ * @param {Object} storedId - existing id, if any
+ * @return {(IdResponse|function(callback:function))} A response object that contains id and/or callback.
*/
/**
@@ -52,6 +67,9 @@
* @typedef {Object} SubmoduleParams
* @property {(string|undefined)} partner - partner url param value
* @property {(string|undefined)} url - webservice request url used to load Id data
+ * @property {(string|undefined)} pixelUrl - publisher pixel to extend/modify cookies
+ * @property {(boolean|undefined)} create - create id if missing. default is true.
+ * @property {(boolean|undefined)} extend - extend expiration time on each access. default is false.
* @property {(string|undefined)} pid - placement id url param value
*/
@@ -70,6 +88,12 @@
* @property {(boolean|undefined)} gdprApplies
*/
+/**
+ * @typedef {Object} IdResponse
+ * @property {(Object|undefined)} id - id data
+ * @property {(function|undefined)} callback - function that will return an id
+ */
+
import find from 'core-js/library/fn/array/find';
import {config} from '../../src/config';
import events from '../../src/events';
@@ -85,6 +109,7 @@ const MODULE_NAME = 'User ID';
const COOKIE = 'cookie';
const LOCAL_STORAGE = 'html5';
const DEFAULT_SYNC_DELAY = 500;
+const NO_AUCTION_DELAY = 0;
/** @type {string[]} */
let validStorageTypes = [];
@@ -107,6 +132,9 @@ let submoduleRegistry = [];
/** @type {(number|undefined)} */
export let syncDelay;
+/** @type {(number|undefined)} */
+export let auctionDelay;
+
/** @param {Submodule[]} submodules */
export function setSubmoduleRegistry(submodules) {
submoduleRegistry = submodules;
@@ -121,7 +149,7 @@ function setStoredValue(storage, value) {
const valueStr = utils.isPlainObject(value) ? JSON.stringify(value) : value;
const expiresStr = (new Date(Date.now() + (storage.expires * (60 * 60 * 24 * 1000)))).toUTCString();
if (storage.type === COOKIE) {
- utils.setCookie(storage.name, valueStr, expiresStr);
+ utils.setCookie(storage.name, valueStr, expiresStr, 'Lax');
if (typeof storage.refreshInSeconds === 'number') {
utils.setCookie(`${storage.name}_last`, new Date().toUTCString(), expiresStr);
}
@@ -188,12 +216,12 @@ function hasGDPRConsent(consentData) {
/**
* @param {SubmoduleContainer[]} submodules
+ * @param {function} cb - callback for after processing is done.
*/
-function processSubmoduleCallbacks(submodules) {
+function processSubmoduleCallbacks(submodules, cb) {
+ const done = cb ? utils.delayExecution(cb, submodules.length) : function() { };
submodules.forEach(function(submodule) {
submodule.callback(function callbackCompleted(idObj) {
- // clear callback, this prop is used to test if all submodule callbacks are complete below
- submodule.callback = undefined;
// if valid, id data should be saved to cookie/html storage
if (idObj) {
if (submodule.config.storage) {
@@ -204,7 +232,11 @@ function processSubmoduleCallbacks(submodules) {
} else {
utils.logError(`${MODULE_NAME}: ${submodule.submodule.name} - request id responded with an empty value`);
}
+ done();
});
+
+ // clear callback, this prop is used to test if all submodule callbacks are complete below
+ submodule.callback = undefined;
});
}
@@ -248,7 +280,9 @@ function addIdDataToAdUnitBids(adUnits, submodules) {
/**
* This is a common function that will initalize subModules if not already done and it will also execute subModule callbacks
*/
-function initializeSubmodulesAndExecuteCallbacks() {
+function initializeSubmodulesAndExecuteCallbacks(continueAuction) {
+ let delayed = false;
+
// initialize submodules only when undefined
if (typeof initializedSubmodules === 'undefined') {
initializedSubmodules = initSubmodules(submodules, gdprDataHandler.getConsentData());
@@ -257,22 +291,42 @@ function initializeSubmodulesAndExecuteCallbacks() {
const submodulesWithCallbacks = initializedSubmodules.filter(item => utils.isFn(item.callback));
if (submodulesWithCallbacks.length) {
- // wait for auction complete before processing submodule callbacks
- events.on(CONSTANTS.EVENTS.AUCTION_END, function auctionEndHandler() {
- events.off(CONSTANTS.EVENTS.AUCTION_END, auctionEndHandler);
-
- // when syncDelay is zero, process callbacks now, otherwise delay process with a setTimeout
- if (syncDelay > 0) {
- setTimeout(function() {
- processSubmoduleCallbacks(submodulesWithCallbacks);
- }, syncDelay);
- } else {
- processSubmoduleCallbacks(submodulesWithCallbacks);
+ if (continueAuction && auctionDelay > 0) {
+ // delay auction until ids are available
+ delayed = true;
+ let continued = false;
+ const continueCallback = function() {
+ if (!continued) {
+ continued = true;
+ continueAuction();
+ }
}
- });
+ utils.logInfo(`${MODULE_NAME} - auction delayed by ${auctionDelay} at most to fetch ids`);
+ processSubmoduleCallbacks(submodulesWithCallbacks, continueCallback);
+
+ setTimeout(continueCallback, auctionDelay);
+ } else {
+ // wait for auction complete before processing submodule callbacks
+ events.on(CONSTANTS.EVENTS.AUCTION_END, function auctionEndHandler() {
+ events.off(CONSTANTS.EVENTS.AUCTION_END, auctionEndHandler);
+
+ // when syncDelay is zero, process callbacks now, otherwise delay process with a setTimeout
+ if (syncDelay > 0) {
+ setTimeout(function() {
+ processSubmoduleCallbacks(submodulesWithCallbacks);
+ }, syncDelay);
+ } else {
+ processSubmoduleCallbacks(submodulesWithCallbacks);
+ }
+ });
+ }
}
}
}
+
+ if (continueAuction && !delayed) {
+ continueAuction();
+ }
}
/**
@@ -286,11 +340,12 @@ function initializeSubmodulesAndExecuteCallbacks() {
*/
export function requestBidsHook(fn, reqBidsConfigObj) {
// initialize submodules only when undefined
- initializeSubmodulesAndExecuteCallbacks();
- // pass available user id data to bid adapters
- addIdDataToAdUnitBids(reqBidsConfigObj.adUnits || getGlobal().adUnits, initializedSubmodules);
- // calling fn allows prebid to continue processing
- return fn.call(this, reqBidsConfigObj);
+ initializeSubmodulesAndExecuteCallbacks(function() {
+ // pass available user id data to bid adapters
+ addIdDataToAdUnitBids(reqBidsConfigObj.adUnits || getGlobal().adUnits, initializedSubmodules);
+ // calling fn allows prebid to continue processing
+ fn.call(this, reqBidsConfigObj);
+ });
}
/**
@@ -301,7 +356,7 @@ function getUserIds() {
// initialize submodules only when undefined
initializeSubmodulesAndExecuteCallbacks();
return getCombinedSubmoduleIds(initializedSubmodules);
-};
+}
/**
* @param {SubmoduleContainer[]} submodules
@@ -319,39 +374,48 @@ function initSubmodules(submodules, consentData) {
// 1. storage: retrieve user id data from cookie/html storage or with the submodule's getId method
// 2. value: pass directly to bids
if (submodule.config.storage) {
- const storedId = getStoredValue(submodule.config.storage);
- if (storedId) {
- // cache decoded value (this is copied to every adUnit bid)
- submodule.idObj = submodule.submodule.decode(storedId);
- }
+ let storedId = getStoredValue(submodule.config.storage);
+ let response;
+
let refreshNeeded = false;
if (typeof submodule.config.storage.refreshInSeconds === 'number') {
const storedDate = new Date(getStoredValue(submodule.config.storage, 'last'));
refreshNeeded = storedDate && (Date.now() - storedDate.getTime() > submodule.config.storage.refreshInSeconds * 1000);
}
+
if (!storedId || refreshNeeded) {
- // getId will return user id data or a function that will load the data
- const getIdResult = submodule.submodule.getId(submodule.config.params, consentData, storedId);
-
- // If the getId result has a type of function, it is asynchronous and cannot be called until later
- if (typeof getIdResult === 'function') {
- submodule.callback = getIdResult;
- } else if (getIdResult) {
- // A getId result that is not a function is assumed to be valid user id data, which should be saved to users local storage or cookies
- setStoredValue(submodule.config.storage, getIdResult);
- // cache decoded value (this is copied to every adUnit bid)
- submodule.idObj = submodule.submodule.decode(getIdResult);
+ // No previously saved id. Request one from submodule.
+ response = submodule.submodule.getId(submodule.config.params, consentData, storedId);
+ } else if (typeof submodule.submodule.extendId === 'function') {
+ // If the id exists already, give submodule a chance to decide additional actions that need to be taken
+ response = submodule.submodule.extendId(submodule.config.params, storedId);
+ }
+
+ if (utils.isPlainObject(response)) {
+ if (response.id) {
+ // A getId/extendId result assumed to be valid user id data, which should be saved to users local storage or cookies
+ setStoredValue(submodule.config.storage, response.id);
+ storedId = response.id;
+ }
+
+ if (typeof response.callback === 'function') {
+ // Save async callback to be invoked after auction
+ submodule.callback = response.callback;
}
}
+
+ if (storedId) {
+ // cache decoded value (this is copied to every adUnit bid)
+ submodule.idObj = submodule.submodule.decode(storedId);
+ }
} else if (submodule.config.value) {
// cache decoded value (this is copied to every adUnit bid)
submodule.idObj = submodule.config.value;
} else {
- const result = submodule.submodule.getId(submodule.config.params, consentData, undefined);
- if (typeof result === 'function') {
- submodule.callback = result;
- } else {
- submodule.idObj = submodule.submodule.decode();
+ const response = submodule.submodule.getId(submodule.config.params, consentData, undefined);
+ if (utils.isPlainObject(response)) {
+ if (typeof response.callback === 'function') { submodule.callback = response.callback; }
+ if (response.id) { submodule.idObj = submodule.submodule.decode(response.id); }
}
}
carry.push(submodule);
@@ -452,7 +516,7 @@ export function init(config) {
].filter(i => i !== null);
// exit immediately if opt out cookie or local storage keys exists.
- if (validStorageTypes.indexOf(COOKIE) !== -1 && utils.getCookie('_pbjs_id_optout')) {
+ if (validStorageTypes.indexOf(COOKIE) !== -1 && (utils.getCookie('_pbjs_id_optout') || utils.getCookie('_pubcid_optout'))) {
utils.logInfo(`${MODULE_NAME} - opt-out cookie found, exit module`);
return;
}
@@ -468,6 +532,7 @@ export function init(config) {
if (userSync && userSync.userIds) {
configRegistry = userSync.userIds;
syncDelay = utils.isNumber(userSync.syncDelay) ? userSync.syncDelay : DEFAULT_SYNC_DELAY;
+ auctionDelay = utils.isNumber(userSync.auctionDelay) ? userSync.auctionDelay : NO_AUCTION_DELAY;
updateSubmodules();
}
});
diff --git a/modules/userId/pubCommonIdSystem.js b/modules/userId/pubCommonIdSystem.js
index f4d6b41a127..2495f7365d5 100644
--- a/modules/userId/pubCommonIdSystem.js
+++ b/modules/userId/pubCommonIdSystem.js
@@ -6,6 +6,9 @@
*/
import * as utils from '../../src/utils';
+import * as url from '../../src/url';
+
+const PUB_COMMON_ID = 'PublisherCommonId';
/** @type {Submodule} */
export const pubCommonIdSubmodule = {
@@ -14,6 +17,26 @@ export const pubCommonIdSubmodule = {
* @type {string}
*/
name: 'pubCommonId',
+ /**
+ * Return a callback function that calls the pixelUrl with id as a query parameter
+ * @param pixelUrl
+ * @param id
+ * @returns {function}
+ */
+ makeCallback: function (pixelUrl, id = '') {
+ if (!pixelUrl) {
+ return;
+ }
+
+ // Use pubcid as a cache buster
+ const urlInfo = url.parse(pixelUrl);
+ urlInfo.search.id = encodeURIComponent('pubcid:' + id);
+ const targetUrl = url.format(urlInfo);
+
+ return function () {
+ utils.triggerPixel(targetUrl);
+ };
+ },
/**
* decode the stored id value for passing to bid requests
* @function
@@ -26,17 +49,44 @@ export const pubCommonIdSubmodule = {
/**
* performs action to obtain id
* @function
- * @returns {string}
+ * @param {SubmoduleParams} [configParams]
+ * @returns {IdResponse}
+ */
+ getId: function ({create = true, pixelUrl} = {}) {
+ try {
+ if (typeof window[PUB_COMMON_ID] === 'object') {
+ // If the page includes its own pubcid module, then save a copy of id.
+ return {id: window[PUB_COMMON_ID].getId()};
+ }
+ } catch (e) {
+ }
+
+ const newId = (create) ? utils.generateUUID() : undefined;
+ return {
+ id: newId,
+ callback: this.makeCallback(pixelUrl, newId)
+ }
+ },
+ /**
+ * performs action to extend an id
+ * @function
+ * @param {SubmoduleParams} [configParams]
+ * @param {Object} storedId existing id
+ * @returns {IdResponse|undefined}
*/
- getId() {
- // If the page includes its own pubcid object, then use that instead.
- let pubcid;
+ extendId: function({extend = false, pixelUrl} = {}, storedId) {
try {
- if (typeof window['PublisherCommonId'] === 'object') {
- pubcid = window['PublisherCommonId'].getId();
+ if (typeof window[PUB_COMMON_ID] === 'object') {
+ // If the page includes its onw pubcid module, then there is nothing to do.
+ return;
}
- } catch (e) {}
- // check pubcid and return if valid was otherwise create a new id
- return (pubcid) || utils.generateUUID();
+ } catch (e) {
+ }
+
+ if (extend) {
+ // When extending, only one of response fields is needed
+ const callback = this.makeCallback(pixelUrl, storedId);
+ return callback ? {callback: callback} : {id: storedId};
+ }
}
};
diff --git a/modules/userId/unifiedIdSystem.js b/modules/userId/unifiedIdSystem.js
index 1bc369bb9fc..99f04ad8850 100644
--- a/modules/userId/unifiedIdSystem.js
+++ b/modules/userId/unifiedIdSystem.js
@@ -28,7 +28,7 @@ export const unifiedIdSubmodule = {
* performs action to obtain id and return a value in the callback's response argument
* @function
* @param {SubmoduleParams} [configParams]
- * @returns {function(callback:function)}
+ * @returns {IdResponse|undefined}
*/
getId(configParams) {
if (!configParams || (typeof configParams.partner !== 'string' && typeof configParams.url !== 'string')) {
@@ -38,7 +38,7 @@ export const unifiedIdSubmodule = {
// use protocol relative urls for http or https
const url = configParams.url || `//match.adsrvr.org/track/rid?ttd_pid=${configParams.partner}&fmt=json`;
- return function (callback) {
+ const resp = function (callback) {
ajax(url, response => {
let responseObj;
if (response) {
@@ -49,7 +49,8 @@ export const unifiedIdSubmodule = {
}
}
callback(responseObj);
- }, undefined, { method: 'GET', withCredentials: true });
- }
+ }, undefined, {method: 'GET', withCredentials: true});
+ };
+ return {callback: resp};
}
};
diff --git a/modules/userId/userId.md b/modules/userId/userId.md
index 623aeaa160e..d3dcfa67443 100644
--- a/modules/userId/userId.md
+++ b/modules/userId/userId.md
@@ -44,7 +44,8 @@ pbjs.setConfig({
expires: 60
}
}],
- syncDelay: 5000
+ syncDelay: 5000,
+ auctionDelay: 1000
}
});
```
diff --git a/modules/videoNowBidAdapter.js b/modules/videoNowBidAdapter.js
new file mode 100644
index 00000000000..7b358f64939
--- /dev/null
+++ b/modules/videoNowBidAdapter.js
@@ -0,0 +1,191 @@
+import * as utils from '../src/utils'
+import { registerBidder } from '../src/adapters/bidderFactory'
+import { BANNER } from '../src/mediaTypes'
+
+const RTB_URL = 'https://bidder.videonow.ru/prebid'
+
+const BIDDER_CODE = 'videonow'
+const TTL_SECONDS = 60 * 5
+
+function isBidRequestValid(bid) {
+ return !!(bid && bid.params && bid.params.pId)
+}
+
+function buildRequest(bid, bidderRequest) {
+ const { refererInfo } = bidderRequest
+ const { ext, bidId, params, code, sizes } = bid
+ const { pId, bidFloor, cur, placementId, url: rtbUrl } = params || {}
+
+ let url = rtbUrl || RTB_URL
+ url = `${url}${~url.indexOf('?') ? '&' : '?'}profile_id=${pId}`
+
+ const dto = {
+ method: 'POST',
+ url,
+ data: {
+ id: bidId,
+ cpm: bidFloor,
+ code,
+ sizes,
+ cur: cur || 'RUB',
+ placementId,
+ ref: refererInfo && refererInfo.referer,
+ },
+ }
+
+ ext && Object.keys(ext).forEach(key => {
+ dto.data[`ext_${key}`] = ext[key]
+ })
+
+ return dto
+}
+
+function buildRequests(validBidRequests, bidderRequest) {
+ utils.logInfo(`${BIDDER_CODE}. buildRequests`)
+ const requests = []
+ validBidRequests.forEach(validBidRequest => {
+ const request = buildRequest(validBidRequest, bidderRequest)
+ request && requests.push(request)
+ })
+ return requests
+}
+
+function interpretResponse(serverResponse, bidRequest) {
+ if (!serverResponse || !serverResponse.body) {
+ return []
+ }
+ const { id: bidId } = (bidRequest && bidRequest.data) || {}
+ if (!bidId) return []
+
+ const { seatbid, cur, ext } = serverResponse.body
+ if (!seatbid || !seatbid.length) return []
+
+ const { placementId } = ext || {}
+ if (!placementId) return []
+
+ const bids = []
+ seatbid.forEach(sb => {
+ const { bid } = sb
+ bid && bid.length && bid.forEach(b => {
+ const res = createResponseBid(b, bidId, cur, placementId)
+ res && bids.push(res)
+ })
+ })
+
+ return bids
+}
+
+function createResponseBid(bidInfo, bidId, cur, placementId) {
+ const { id, nurl, code, price, crid, ext, ttl, netRevenue, w, h, adm } = bidInfo
+
+ if (!id || !price || !adm) {
+ return null
+ }
+
+ const { init: initPath, module, format } = ext || {}
+ if (!initPath) {
+ utils.logError(`vnInitModulePath is not defined`)
+ return null
+ }
+
+ const { log, min } = module || {}
+
+ if (!min && !log) {
+ utils.logError('module\'s paths are not defined')
+ return null
+ }
+
+ return {
+ requestId: bidId,
+ cpm: price,
+ width: w,
+ height: h,
+ creativeId: crid,
+ currency: cur || 'RUB',
+ netRevenue: netRevenue !== undefined ? netRevenue : true,
+ ttl: ttl || TTL_SECONDS,
+ ad: code,
+ nurl,
+ renderer: {
+ url: min || log,
+ render: function() {
+ const d = window.document
+ const el = placementId && d.getElementById(placementId)
+ if (el) {
+ const pId = 1
+ // prepare data for vn_init script
+ const profileData = {
+ module,
+ dataXml: adm,
+ }
+
+ format && (profileData.format = format)
+
+ // add init data for vn_init on the page
+ const videonow = window.videonow = window.videonow || {}
+ const init = videonow.init = window.videonow.init || {}
+ init[pId] = profileData
+
+ // add vn_init js on the page
+ const scr = document.createElement('script')
+ scr.src = `${initPath}${~initPath.indexOf('?') ? '&' : '?'}profileId=${pId}`
+ el && el.appendChild(scr)
+ } else {
+ utils.logError(`bidAdapter ${BIDDER_CODE}: ${placementId} not found`)
+ }
+ }
+ }
+ }
+}
+
+function getUserSyncs(syncOptions, serverResponses) {
+ const syncs = []
+
+ if (!serverResponses || !serverResponses.length) return syncs
+
+ serverResponses.forEach(response => {
+ const { ext } = (response && response.body) || {}
+ const { pixels, iframes } = ext || {}
+
+ if (syncOptions.iframeEnabled && iframes && iframes.length) {
+ iframes.forEach(i => syncs.push({
+ type: 'iframe',
+ url: i,
+ }),
+ )
+ }
+
+ if (syncOptions.pixelEnabled && pixels && pixels.length) {
+ pixels.forEach(p => syncs.push({
+ type: 'image',
+ url: p,
+ }),
+ )
+ }
+ })
+
+ utils.logInfo(`${BIDDER_CODE} getUserSyncs() syncs=${syncs.length}`)
+ return syncs
+}
+
+function onBidWon(bid) {
+ const { nurl } = bid || {}
+ if (nurl) {
+ const img = document.createElement('img')
+ img.src = utils.replaceAuctionPrice(nurl, bid.cpm)
+ img.style.cssText = 'display:none !important;'
+ document.body.appendChild(img)
+ }
+}
+
+export const spec = {
+ code: BIDDER_CODE,
+ supportedMediaTypes: [BANNER],
+ isBidRequestValid,
+ buildRequests,
+ interpretResponse,
+ getUserSyncs,
+ onBidWon
+}
+
+registerBidder(spec)
diff --git a/modules/videoNowBidAdapter.md b/modules/videoNowBidAdapter.md
new file mode 100644
index 00000000000..2ac2a431378
--- /dev/null
+++ b/modules/videoNowBidAdapter.md
@@ -0,0 +1,35 @@
+# Overview
+
+```
+Module Name: Videonow Bidder Adapter
+Module Type: Bidder Adapter
+Maintainer: info@videonow.ru
+```
+
+# Description
+
+Connect to Videonow for bids.
+
+The Videonow bidder adapter requires setup and approval from the videoNow team.
+Please reach out to your account team or info@videonow.ru for more information.
+
+# Test Parameters
+```javascript
+var adUnits = [
+ // Banner adUnit
+ {
+ code: 'banner-div',
+ mediaTypes: {
+ banner: {
+ sizes: [[640, 480], [300, 250], [336, 280]]
+ }
+ },
+ bids: [{
+ bidder: 'videonow',
+ params: {
+ pId: 1,
+ placementId: '36891'
+ }
+ }]
+ }]
+```
diff --git a/package-lock.json b/package-lock.json
index bb8263638fb..c7256dd8e2d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "prebid.js",
- "version": "2.33.0-pre",
+ "version": "2.35.0-pre",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -14,17 +14,17 @@
}
},
"@babel/core": {
- "version": "7.6.0",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.0.tgz",
- "integrity": "sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.2.tgz",
+ "integrity": "sha512-l8zto/fuoZIbncm+01p8zPSDZu/VuuJhAfA7d/AbzM09WR7iVhavvfNDYCNpo1VvLk6E6xgAoP9P+/EMJHuRkQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.5.5",
- "@babel/generator": "^7.6.0",
- "@babel/helpers": "^7.6.0",
- "@babel/parser": "^7.6.0",
+ "@babel/generator": "^7.6.2",
+ "@babel/helpers": "^7.6.2",
+ "@babel/parser": "^7.6.2",
"@babel/template": "^7.6.0",
- "@babel/traverse": "^7.6.0",
+ "@babel/traverse": "^7.6.2",
"@babel/types": "^7.6.0",
"convert-source-map": "^1.1.0",
"debug": "^4.1.0",
@@ -36,16 +36,15 @@
}
},
"@babel/generator": {
- "version": "7.6.0",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.0.tgz",
- "integrity": "sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz",
+ "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==",
"dev": true,
"requires": {
"@babel/types": "^7.6.0",
"jsesc": "^2.5.1",
"lodash": "^4.17.13",
- "source-map": "^0.5.0",
- "trim-right": "^1.0.1"
+ "source-map": "^0.5.0"
}
},
"@babel/helper-annotate-as-pure": {
@@ -241,13 +240,13 @@
}
},
"@babel/helpers": {
- "version": "7.6.0",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.0.tgz",
- "integrity": "sha512-W9kao7OBleOjfXtFGgArGRX6eCP0UEcA2ZWEWNkJdRZnHhW4eEbeswbG3EwaRsnQUAEGWYgMq1HsIXuNNNy2eQ==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.2.tgz",
+ "integrity": "sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA==",
"dev": true,
"requires": {
"@babel/template": "^7.6.0",
- "@babel/traverse": "^7.6.0",
+ "@babel/traverse": "^7.6.2",
"@babel/types": "^7.6.0"
}
},
@@ -263,9 +262,9 @@
}
},
"@babel/parser": {
- "version": "7.6.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.0.tgz",
- "integrity": "sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz",
+ "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==",
"dev": true
},
"@babel/plugin-proposal-async-generator-functions": {
@@ -300,9 +299,9 @@
}
},
"@babel/plugin-proposal-object-rest-spread": {
- "version": "7.5.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz",
- "integrity": "sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz",
+ "integrity": "sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0",
@@ -320,14 +319,14 @@
}
},
"@babel/plugin-proposal-unicode-property-regex": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz",
- "integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.6.2.tgz",
+ "integrity": "sha512-NxHETdmpeSCtiatMRYWVJo7266rrvAC3DTeG5exQBIH/fMIUK7ejDNznBbn3HQl/o9peymRRg7Yqkx6PdUXmMw==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-regex": "^7.4.4",
- "regexpu-core": "^4.5.4"
+ "regexpu-core": "^4.6.0"
}
},
"@babel/plugin-syntax-async-generators": {
@@ -405,9 +404,9 @@
}
},
"@babel/plugin-transform-block-scoping": {
- "version": "7.6.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.0.tgz",
- "integrity": "sha512-tIt4E23+kw6TgL/edACZwP1OUKrjOTyMrFMLoT5IOFrfMRabCgekjqFd5o6PaAMildBu46oFkekIdMuGkkPEpA==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.2.tgz",
+ "integrity": "sha512-zZT8ivau9LOQQaOGC7bQLQOT4XPkPXgN2ERfUgk1X8ql+mVkLc4E8eKk+FO3o0154kxzqenWCorfmEXpEZcrSQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0",
@@ -449,14 +448,14 @@
}
},
"@babel/plugin-transform-dotall-regex": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz",
- "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.6.2.tgz",
+ "integrity": "sha512-KGKT9aqKV+9YMZSkowzYoYEiHqgaDhGmPNZlZxX6UeHC4z30nC1J9IrZuGqbYFB1jaIGdv91ujpze0exiVK8bA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-regex": "^7.4.4",
- "regexpu-core": "^4.5.4"
+ "regexpu-core": "^4.6.0"
}
},
"@babel/plugin-transform-duplicate-keys": {
@@ -560,12 +559,12 @@
}
},
"@babel/plugin-transform-named-capturing-groups-regex": {
- "version": "7.6.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.0.tgz",
- "integrity": "sha512-jem7uytlmrRl3iCAuQyw8BpB4c4LWvSpvIeXKpMb+7j84lkx4m4mYr5ErAcmN5KM7B6BqrAvRGjBIbbzqCczew==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.2.tgz",
+ "integrity": "sha512-xBdB+XOs+lgbZc2/4F5BVDVcDNS4tcSKQc96KmlqLEAwz6tpYPEvPdmDfvVG0Ssn8lAhronaRs6Z6KSexIpK5g==",
"dev": true,
"requires": {
- "regexp-tree": "^0.1.13"
+ "regexpu-core": "^4.6.0"
}
},
"@babel/plugin-transform-new-target": {
@@ -635,9 +634,9 @@
}
},
"@babel/plugin-transform-spread": {
- "version": "7.2.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz",
- "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz",
+ "integrity": "sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
@@ -673,20 +672,20 @@
}
},
"@babel/plugin-transform-unicode-regex": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz",
- "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.6.2.tgz",
+ "integrity": "sha512-orZI6cWlR3nk2YmYdb0gImrgCUwb5cBUwjf6Ks6dvNVvXERkwtJWOQaEOjPiu0Gu1Tq6Yq/hruCZZOOi9F34Dw==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-regex": "^7.4.4",
- "regexpu-core": "^4.5.4"
+ "regexpu-core": "^4.6.0"
}
},
"@babel/preset-env": {
- "version": "7.6.0",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.6.0.tgz",
- "integrity": "sha512-1efzxFv/TcPsNXlRhMzRnkBFMeIqBBgzwmZwlFDw5Ubj0AGLeufxugirwZmkkX/ayi3owsSqoQ4fw8LkfK9SYg==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.6.2.tgz",
+ "integrity": "sha512-Ru7+mfzy9M1/YTEtlDS8CD45jd22ngb9tXnn64DvQK3ooyqSw9K4K9DUWmYknTTVk4TqygL9dqCrZgm1HMea/Q==",
"dev": true,
"requires": {
"@babel/helper-module-imports": "^7.0.0",
@@ -694,9 +693,9 @@
"@babel/plugin-proposal-async-generator-functions": "^7.2.0",
"@babel/plugin-proposal-dynamic-import": "^7.5.0",
"@babel/plugin-proposal-json-strings": "^7.2.0",
- "@babel/plugin-proposal-object-rest-spread": "^7.5.5",
+ "@babel/plugin-proposal-object-rest-spread": "^7.6.2",
"@babel/plugin-proposal-optional-catch-binding": "^7.2.0",
- "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.6.2",
"@babel/plugin-syntax-async-generators": "^7.2.0",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-syntax-json-strings": "^7.2.0",
@@ -705,11 +704,11 @@
"@babel/plugin-transform-arrow-functions": "^7.2.0",
"@babel/plugin-transform-async-to-generator": "^7.5.0",
"@babel/plugin-transform-block-scoped-functions": "^7.2.0",
- "@babel/plugin-transform-block-scoping": "^7.6.0",
+ "@babel/plugin-transform-block-scoping": "^7.6.2",
"@babel/plugin-transform-classes": "^7.5.5",
"@babel/plugin-transform-computed-properties": "^7.2.0",
"@babel/plugin-transform-destructuring": "^7.6.0",
- "@babel/plugin-transform-dotall-regex": "^7.4.4",
+ "@babel/plugin-transform-dotall-regex": "^7.6.2",
"@babel/plugin-transform-duplicate-keys": "^7.5.0",
"@babel/plugin-transform-exponentiation-operator": "^7.2.0",
"@babel/plugin-transform-for-of": "^7.4.4",
@@ -720,7 +719,7 @@
"@babel/plugin-transform-modules-commonjs": "^7.6.0",
"@babel/plugin-transform-modules-systemjs": "^7.5.0",
"@babel/plugin-transform-modules-umd": "^7.2.0",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.6.0",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.6.2",
"@babel/plugin-transform-new-target": "^7.4.4",
"@babel/plugin-transform-object-super": "^7.5.5",
"@babel/plugin-transform-parameters": "^7.4.4",
@@ -728,11 +727,11 @@
"@babel/plugin-transform-regenerator": "^7.4.5",
"@babel/plugin-transform-reserved-words": "^7.2.0",
"@babel/plugin-transform-shorthand-properties": "^7.2.0",
- "@babel/plugin-transform-spread": "^7.2.0",
+ "@babel/plugin-transform-spread": "^7.6.2",
"@babel/plugin-transform-sticky-regex": "^7.2.0",
"@babel/plugin-transform-template-literals": "^7.4.4",
"@babel/plugin-transform-typeof-symbol": "^7.2.0",
- "@babel/plugin-transform-unicode-regex": "^7.4.4",
+ "@babel/plugin-transform-unicode-regex": "^7.6.2",
"@babel/types": "^7.6.0",
"browserslist": "^4.6.0",
"core-js-compat": "^3.1.1",
@@ -753,16 +752,16 @@
}
},
"@babel/traverse": {
- "version": "7.6.0",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.0.tgz",
- "integrity": "sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz",
+ "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.5.5",
- "@babel/generator": "^7.6.0",
+ "@babel/generator": "^7.6.2",
"@babel/helper-function-name": "^7.1.0",
"@babel/helper-split-export-declaration": "^7.4.4",
- "@babel/parser": "^7.6.0",
+ "@babel/parser": "^7.6.2",
"@babel/types": "^7.6.0",
"debug": "^4.1.0",
"globals": "^11.1.0",
@@ -3033,9 +3032,9 @@
}
},
"buffer": {
- "version": "5.4.2",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.2.tgz",
- "integrity": "sha512-iy9koArjAFCzGnx3ZvNA6Z0clIbbFgbdWQ0mKD3hO0krOrZh8UgA6qMKcZvwLJxS+D6iVR76+5/pV56yMNYTag==",
+ "version": "5.4.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz",
+ "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==",
"dev": true,
"requires": {
"base64-js": "^1.0.2",
@@ -3229,9 +3228,9 @@
}
},
"caniuse-lite": {
- "version": "1.0.30000989",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz",
- "integrity": "sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw==",
+ "version": "1.0.30000997",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000997.tgz",
+ "integrity": "sha512-BQLFPIdj2ntgBNWp9Q64LGUIEmvhKkzzHhUHR3CD5A9Lb7ZKF20/+sgadhFap69lk5XmK1fTUleDclaRFvgVUA==",
"dev": true
},
"caseless": {
@@ -3524,9 +3523,9 @@
"dev": true
},
"colors": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
- "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==",
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+ "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
"dev": true
},
"combine-lists": {
@@ -4720,9 +4719,9 @@
"dev": true
},
"electron-to-chromium": {
- "version": "1.3.254",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.254.tgz",
- "integrity": "sha512-7I5/OkgR6JKy6RFLJeru0kc0RMmmMu1UnkHBKInFKRrg1/4EQKIqOaUqITSww/SZ1LqWwp1qc/LLoIGy449eYw==",
+ "version": "1.3.266",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.266.tgz",
+ "integrity": "sha512-UTuTZ4v8T0gLPHI7U75PXLQePWI65MTS3mckRrnLCkNljHvsutbYs+hn2Ua/RFul3Jt/L3Ht2rLP+dU/AlBfrQ==",
"dev": true
},
"elliptic": {
@@ -4759,9 +4758,9 @@
"dev": true
},
"end-of-stream": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
- "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dev": true,
"requires": {
"once": "^1.4.0"
@@ -4881,13 +4880,12 @@
}
},
"error": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz",
- "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/error/-/error-7.2.0.tgz",
+ "integrity": "sha512-M6t3j3Vt3uDicrViMP5fLq2AeADNrCVFD8Oj4Qt2MHsX0mPYG7D5XdnEfSdRpaHQzjAJ19wu+I1mw9rQYMTAPg==",
"dev": true,
"requires": {
- "string-template": "~0.2.1",
- "xtend": "~4.0.0"
+ "string-template": "~0.2.1"
}
},
"error-ex": {
@@ -5571,9 +5569,9 @@
}
},
"eventemitter3": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
- "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz",
+ "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==",
"dev": true
},
"events": {
@@ -8113,9 +8111,9 @@
}
},
"handlebars": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.2.0.tgz",
- "integrity": "sha512-Kb4xn5Qh1cxAKvQnzNWZ512DhABzyFNmsaJf3OAkWNa4NkaqWcNI8Tao8Tasi0/F4JD9oyG0YxuFyvyR57d+Gw==",
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.3.1.tgz",
+ "integrity": "sha512-c0HoNHzDiHpBt4Kqe99N8tdLPKAnGCQ73gYMPWtAYM4PwGnf7xl8PBUHJqh9ijlzt2uQKaSRxbXRt+rZ7M2/kA==",
"dev": true,
"requires": {
"neo-async": "^2.6.0",
@@ -8444,12 +8442,12 @@
"dev": true
},
"http-proxy": {
- "version": "1.17.0",
- "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz",
- "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==",
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz",
+ "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==",
"dev": true,
"requires": {
- "eventemitter3": "^3.0.0",
+ "eventemitter3": "^4.0.0",
"follow-redirects": "^1.0.0",
"requires-port": "^1.0.0"
}
@@ -9002,9 +9000,9 @@
"dev": true
},
"is-wsl": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.0.tgz",
- "integrity": "sha512-pFTjpv/x5HRj8kbZ/Msxi9VrvtOMRBqaDi3OIcbwPI3OuH+r3lLxVWukLITBaOGJIbA/w2+M1eVmVa4XNQlAmQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz",
+ "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==",
"dev": true
},
"isarray": {
@@ -11033,9 +11031,9 @@
}
},
"node-releases": {
- "version": "1.1.30",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.30.tgz",
- "integrity": "sha512-BHcr1g6NeUH12IL+X3Flvs4IOnl1TL0JczUhEZjDE+FXXPQcVCNr8NEPb01zqGxzhTpdyJL5GXemaCW7aw6Khw==",
+ "version": "1.1.32",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.32.tgz",
+ "integrity": "sha512-VhVknkitq8dqtWoluagsGPn3dxTvN9fwgR59fV3D7sLBHe0JfDramsMI8n8mY//ccq/Kkrf8ZRHRpsyVZ3qw1A==",
"dev": true,
"requires": {
"semver": "^5.3.0"
@@ -11506,9 +11504,9 @@
}
},
"parse-asn1": {
- "version": "5.1.4",
- "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz",
- "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==",
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz",
+ "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==",
"dev": true,
"requires": {
"asn1.js": "^4.0.0",
@@ -12416,12 +12414,6 @@
"safe-regex": "^1.1.0"
}
},
- "regexp-tree": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.13.tgz",
- "integrity": "sha512-hwdV/GQY5F8ReLZWO+W1SRoN5YfpOKY6852+tBFcma72DKBIcHjPRIlIvQN35bCOljuAfP2G2iB0FC/w236mUw==",
- "dev": true
- },
"regexpp": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
@@ -12429,9 +12421,9 @@
"dev": true
},
"regexpu-core": {
- "version": "4.5.5",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.5.tgz",
- "integrity": "sha512-FpI67+ky9J+cDizQUJlIlNZFKual/lUkFr1AG6zOCpwZ9cLrg8UUVakyUQJD7fCDIe9Z2nwTQJNPyonatNmDFQ==",
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz",
+ "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==",
"dev": true,
"requires": {
"regenerate": "^1.4.0",
@@ -14244,9 +14236,9 @@
"dev": true
},
"type": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/type/-/type-1.0.3.tgz",
- "integrity": "sha512-51IMtNfVcee8+9GJvj0spSuFcZHe9vSib6Xtgsny1Km9ugyz2mbS08I3rsUIRYgJohFRFU1160sgRodYz378Hg==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
"dev": true
},
"type-check": {
@@ -15402,9 +15394,9 @@
}
},
"webpack-bundle-analyzer": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.4.1.tgz",
- "integrity": "sha512-Bs8D/1zF+17lhqj2OYmzi7HEVYqEVxu7lCO9Ff8BwajenOU0vAwEoV8e4ICCPNZAcqR1PCR/7o2SkW+cnCmF0A==",
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.5.1.tgz",
+ "integrity": "sha512-CDdaT3TTu4F9X3tcDq6PNJOiNGgREOM0WdN2vVAoUUn+M6NLB5kJ543HImCWbrDwOpbpGARSwU8r+u0Pl367kA==",
"dev": true,
"requires": {
"acorn": "^6.0.7",
diff --git a/package.json b/package.json
index 314323914a1..967dcede83c 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "prebid.js",
- "version": "2.34.0-pre",
+ "version": "2.35.0-pre",
"description": "Header Bidding Management Library",
"main": "src/prebid.js",
"scripts": {
diff --git a/src/prebid.js b/src/prebid.js
index efa1198d36c..14c63651ba5 100644
--- a/src/prebid.js
+++ b/src/prebid.js
@@ -276,18 +276,15 @@ $$PREBID_GLOBAL$$.setTargetingForAst = function(adUnitCodes) {
events.emit(SET_TARGETING, targeting.getAllTargeting());
};
-function emitAdRenderFail(reason, message, bid) {
- const data = {};
-
- data.reason = reason;
- data.message = message;
- if (bid) {
- data.bid = bid;
- }
+function emitAdRenderFail({ reason, message, bid, id }) {
+ const data = { reason, message };
+ if (bid) data.bid = bid;
+ if (id) data.adId = id;
utils.logError(message);
events.emit(AD_RENDER_FAILED, data);
}
+
/**
* This function will render the ad (based on params) in the given iframe document passed through.
* Note that doc SHOULD NOT be the parent document page as we can't doc.write() asynchronously
@@ -323,7 +320,7 @@ $$PREBID_GLOBAL$$.renderAd = function (doc, id) {
executeRenderer(renderer, bid);
} else if ((doc === document && !utils.inIframe()) || mediaType === 'video') {
const message = `Error trying to write ad. Ad render call ad id ${id} was prevented from writing to the main document.`;
- emitAdRenderFail(PREVENT_WRITING_ON_MAIN_DOCUMENT, message, bid);
+ emitAdRenderFail({ reason: PREVENT_WRITING_ON_MAIN_DOCUMENT, message, bid, id });
} else if (ad) {
// will check if browser is firefox and below version 67, if so execute special doc.open()
// for details see: https://github.com/prebid/Prebid.js/pull/3524
@@ -352,19 +349,19 @@ $$PREBID_GLOBAL$$.renderAd = function (doc, id) {
utils.callBurl(bid);
} else {
const message = `Error trying to write ad. No ad for bid response id: ${id}`;
- emitAdRenderFail(NO_AD, message, bid);
+ emitAdRenderFail({ reason: NO_AD, message, bid, id });
}
} else {
const message = `Error trying to write ad. Cannot find ad by given id : ${id}`;
- emitAdRenderFail(CANNOT_FIND_AD, message);
+ emitAdRenderFail({ reason: CANNOT_FIND_AD, message, id });
}
} catch (e) {
const message = `Error trying to write ad Id :${id} to the page:${e.message}`;
- emitAdRenderFail(EXCEPTION, message);
+ emitAdRenderFail({ reason: EXCEPTION, message, id });
}
} else {
const message = `Error trying to write ad Id :${id} to the page. Missing document or adId`;
- emitAdRenderFail(MISSING_DOC_OR_ADID, message);
+ emitAdRenderFail({ reason: MISSING_DOC_OR_ADID, message, id });
}
};
diff --git a/src/userSync.js b/src/userSync.js
index e2bd4e3f04a..aaa79f6a42f 100644
--- a/src/userSync.js
+++ b/src/userSync.js
@@ -8,7 +8,8 @@ config.setDefaults({
syncEnabled: true,
pixelEnabled: true,
syncsPerBidder: 5,
- syncDelay: 3000
+ syncDelay: 3000,
+ auctionDelay: 0
}
});
diff --git a/src/utils.js b/src/utils.js
index 21a1943b1a1..2caaedc4164 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -918,8 +918,8 @@ export function getCookie(name) {
return m ? decodeURIComponent(m[2]) : null;
}
-export function setCookie(key, value, expires) {
- document.cookie = `${key}=${encodeURIComponent(value)}${(expires !== '') ? `; expires=${expires}` : ''}; path=/`;
+export function setCookie(key, value, expires, sameSite) {
+ document.cookie = `${key}=${encodeURIComponent(value)}${(expires !== '') ? `; expires=${expires}` : ''}; path=/${sameSite ? `; SameSite=${sameSite}` : ''}`;
}
/**
diff --git a/test/fixtures/fixtures.js b/test/fixtures/fixtures.js
index 2637bb30de6..2a0a7638fc4 100644
--- a/test/fixtures/fixtures.js
+++ b/test/fixtures/fixtures.js
@@ -53,11 +53,14 @@ export function getBidRequests() {
90
]
],
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [[728, 90], [970, 90]]
+ }
+ },
'bidId': '392b5a6b05d648',
'bidderRequestId': '2946b569352ef2',
'auctionId': '1863e370099523',
- 'startTime': 1462918897462,
- 'status': 1,
'transactionId': 'fsafsa'
},
{
@@ -76,11 +79,14 @@ export function getBidRequests() {
600
]
],
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [[728, 90], [970, 90]]
+ }
+ },
'bidId': '4dccdc37746135',
'bidderRequestId': '2946b569352ef2',
'auctionId': '1863e370099523',
- 'startTime': 1462918897463,
- 'status': 1,
'transactionId': 'fsafsa'
}
],
@@ -108,6 +114,11 @@ export function getBidRequests() {
600
]
],
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [[300, 250], [300, 600]]
+ }
+ },
'bidId': '6d11aa2d5b3659',
'bidderRequestId': '5e1525bae3eb11',
'auctionId': '1863e370099523',
@@ -157,6 +168,11 @@ export function getBidRequests() {
600
]
],
+ 'mediaType': {
+ 'banner': {
+ 'sizes': [[300, 250], [300, 600]]
+ }
+ },
'bidId': '96aff279720d39',
'bidderRequestId': '8778750ee15a77',
'auctionId': '1863e370099523',
@@ -186,10 +202,14 @@ export function getBidRequests() {
600
]
],
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [[300, 250], [300, 600]]
+ }
+ },
'bidId': '1144e2f0de84363',
'bidderRequestId': '107f5e6e98dcf09',
'auctionId': '1863e370099523',
- 'startTime': 1462918897477,
'transactionId': 'fsafsa'
}
],
@@ -216,10 +236,14 @@ export function getBidRequests() {
600
]
],
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [[300, 250], [300, 600]]
+ }
+ },
'bidId': '135e89c039705da',
'bidderRequestId': '12eeded736650b4',
'auctionId': '1863e370099523',
- 'status': 1,
'transactionId': 'fsafsa'
}
],
@@ -246,11 +270,14 @@ export function getBidRequests() {
600
]
],
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [[300, 250], [300, 600]]
+ }
+ },
'bidId': '17dd1d869bed44e',
'bidderRequestId': '167c4d79b615948',
'auctionId': '1863e370099523',
- 'startTime': 1462918897480,
- 'status': 1,
'transactionId': 'fsafsa'
}
],
@@ -277,11 +304,14 @@ export function getBidRequests() {
600
]
],
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [[300, 250], [300, 600]]
+ }
+ },
'bidId': '192c8c1df0f5d1d',
'bidderRequestId': '18bed198c172a69',
'auctionId': '1863e370099523',
- 'startTime': 1462918897481,
- 'status': 1,
'transactionId': 'fsafsa'
}
],
@@ -308,6 +338,11 @@ export function getBidRequests() {
600
]
],
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [[300, 250], [300, 600]]
+ }
+ },
'bidId': '21ae8131ec04f6e',
'bidderRequestId': '20d0d30333715a7',
'auctionId': '1863e370099523',
@@ -323,6 +358,7 @@ export function getBidResponses() {
return [
{
'bidderCode': 'triplelift',
+ 'mediaType': 'banner',
'width': 0,
'height': 0,
'statusMessage': 'Bid available',
@@ -354,6 +390,7 @@ export function getBidResponses() {
},
{
'bidderCode': 'appnexus',
+ 'mediaType': 'banner',
'width': 300,
'height': 250,
'statusMessage': 'Bid available',
@@ -387,6 +424,7 @@ export function getBidResponses() {
},
{
'bidderCode': 'appnexus',
+ 'mediaType': 'banner',
'width': 728,
'height': 90,
'statusMessage': 'Bid available',
@@ -420,6 +458,7 @@ export function getBidResponses() {
},
{
'bidderCode': 'pagescience',
+ 'mediaType': 'banner',
'width': 300,
'height': 250,
'statusMessage': 'Bid available',
@@ -452,6 +491,7 @@ export function getBidResponses() {
},
{
'bidderCode': 'brightcom',
+ 'mediaType': 'banner',
'width': 300,
'height': 250,
'statusMessage': 'Bid available',
@@ -483,6 +523,7 @@ export function getBidResponses() {
},
{
'bidderCode': 'brealtime',
+ 'mediaType': 'banner',
'width': 300,
'height': 250,
'statusMessage': 'Bid available',
@@ -515,6 +556,7 @@ export function getBidResponses() {
},
{
'bidderCode': 'pubmatic',
+ 'mediaType': 'banner',
'width': '300',
'height': '250',
'statusMessage': 'Bid available',
@@ -548,6 +590,7 @@ export function getBidResponses() {
},
{
'bidderCode': 'rubicon',
+ 'mediaType': 'banner',
'width': 300,
'height': 600,
'statusMessage': 'Bid available',
@@ -616,138 +659,54 @@ export function getAdUnits() {
return [
{
'code': '/19968336/header-bid-tag1',
- 'sizes': [
- [
- 728,
- 90
- ],
- [
- 970,
- 90
- ]
- ],
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [[728, 90], [970, 90]]
+ },
+ },
'bids': [
{
'bidder': 'adequant',
'params': {
'publisher_id': '1234567',
'bidfloor': 0.01
- },
- 'adUnitCode': '/19968336/header-bid-tag1',
- 'sizes': [
- [
- 728,
- 90
- ],
- [
- 970,
- 90
- ]
- ],
- 'bidId': '3692954f816efc',
- 'bidderRequestId': '2b1a75d5e826c4',
- 'auctionId': '1ff753bd4ae5cb'
+ }
},
{
'bidder': 'appnexus',
'params': {
'placementId': '543221',
'test': 'me'
- },
- 'adUnitCode': '/19968336/header-bid-tag1',
- 'sizes': [
- [
- 728,
- 90
- ],
- [
- 970,
- 90
- ]
- ],
- 'bidId': '68136e1c47023d',
- 'bidderRequestId': '55e24a66bed717',
- 'auctionId': '1ff753bd4ae5cb',
- 'startTime': 1463510220995,
- 'status': 1
+ }
}
]
},
{
'code': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [[300, 250], [300, 600]]
+ }
+ },
'bids': [
{
'bidder': 'appnexus',
'params': {
'placementId': '5324321'
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '7e5d6af25ed188',
- 'bidderRequestId': '55e24a66bed717',
- 'auctionId': '1ff753bd4ae5cb',
- 'startTime': 1463510220996
+ }
},
{
'bidder': 'adequant',
'params': {
'publisher_id': '12353433',
'bidfloor': 0.01
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '4448d80ac1374e',
- 'bidderRequestId': '2b1a75d5e826c4',
- 'auctionId': '1ff753bd4ae5cb'
+ }
},
{
'bidder': 'triplelift',
'params': {
'inventoryCode': 'inv_code_here'
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '9514d586c52abf',
- 'bidderRequestId': '8c4f03b838d7ee',
- 'auctionId': '1ff753bd4ae5cb',
- 'startTime': 1463510220997
+ }
},
{
'bidder': 'springserve',
@@ -755,21 +714,7 @@ export function getAdUnits() {
'impId': 1234,
'supplyPartnerId': 1,
'test': true
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '113079fed03f58c',
- 'bidderRequestId': '1048e0df882e965',
- 'auctionId': '1ff753bd4ae5cb'
+ }
},
{
'bidder': 'rubicon',
@@ -795,105 +740,33 @@ export function getAdUnits() {
15,
10
]
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '13c2c2a79d155ea',
- 'bidderRequestId': '129e383ac549e5d',
- 'auctionId': '1ff753bd4ae5cb'
+ }
},
{
'bidder': 'openx',
'params': {
'jstag_url': 'http://servedbyopenx.com/w/1.0/jstag?nc=account_key',
'unit': 2345677
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '154f9cbf82df565',
- 'bidderRequestId': '1448569c2453b84',
- 'auctionId': '1ff753bd4ae5cb'
+ }
},
{
'bidder': 'pubmatic',
'params': {
'publisherId': 1234567,
'adSlot': '1234567@300x250'
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '17f8c3a8fb13308',
- 'bidderRequestId': '16095445eeb05e4',
- 'auctionId': '1ff753bd4ae5cb'
+ }
},
{
'bidder': 'pagescience',
'params': {
'placementId': '1234567'
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '2074d5757675542',
- 'bidderRequestId': '19883380ef5453a',
- 'auctionId': '1ff753bd4ae5cb',
- 'startTime': 1463510221014
+ }
},
{
'bidder': 'brealtime',
'params': {
'placementId': '1234567'
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '222b6ad5a9b835d',
- 'bidderRequestId': '2163409fdf6f333',
- 'auctionId': '1ff753bd4ae5cb',
- 'startTime': 1463510221015
+ }
},
{
'bidder': 'indexExchange',
@@ -901,21 +774,7 @@ export function getAdUnits() {
'id': '1',
'siteID': 123456,
'timeout': 10000
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '2499961ab3f937a',
- 'bidderRequestId': '23b57a2de4ae50b',
- 'auctionId': '1ff753bd4ae5cb'
+ }
},
{
'bidder': 'adform',
@@ -923,82 +782,26 @@ export function getAdUnits() {
'adxDomain': 'adx.adform.net',
'mid': 123456,
'test': 1
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '26605265bf5e9c5',
- 'bidderRequestId': '25a0902299c17d3',
- 'auctionId': '1ff753bd4ae5cb'
+ }
},
{
'bidder': 'amazon',
'params': {
'aId': 3080
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '2935d8f6764fe45',
- 'bidderRequestId': '28afa21ca9246c1',
- 'auctionId': '1ff753bd4ae5cb'
+ }
},
{
'bidder': 'aol',
'params': {
'network': '112345.45',
'placement': 12345
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '31d1489681dc539',
- 'bidderRequestId': '30bf32da9080fdd',
- 'auctionId': '1ff753bd4ae5cb'
+ }
},
{
'bidder': 'sovrn',
'params': {
'tagid': '123556'
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '33c1a8028d91563',
- 'bidderRequestId': '324bcb47cfcf034',
- 'auctionId': '1ff753bd4ae5cb'
+ }
},
{
'bidder': 'pulsepoint',
@@ -1006,41 +809,13 @@ export function getAdUnits() {
'cf': '300X250',
'cp': 1233456,
'ct': 12357
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '379219f0506a26f',
- 'bidderRequestId': '360ec66bbb0719c',
- 'auctionId': '1ff753bd4ae5cb'
+ }
},
{
'bidder': 'brightcom',
'params': {
'tagId': 75423
- },
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '395cfcf496e7d6d',
- 'bidderRequestId': '38a776c7f001ea',
- 'auctionId': '1ff753bd4ae5cb'
+ }
}
]
}
@@ -1055,6 +830,7 @@ export function getBidResponsesFromAPI() {
'bidderCode': 'brightcom',
'width': 300,
'height': 250,
+ 'mediaType': 'banner',
'statusMessage': 'Bid available',
'adId': '26e0795ab963896',
'cpm': 0.17,
@@ -1086,6 +862,7 @@ export function getBidResponsesFromAPI() {
'bidderCode': 'brealtime',
'width': 300,
'height': 250,
+ 'mediaType': 'banner',
'statusMessage': 'Bid available',
'adId': '275bd666f5a5a5d',
'creative_id': 29681110,
@@ -1118,6 +895,7 @@ export function getBidResponsesFromAPI() {
'bidderCode': 'pubmatic',
'width': '300',
'height': '250',
+ 'mediaType': 'banner',
'statusMessage': 'Bid available',
'adId': '28f4039c636b6a7',
'adSlot': '39620189@300x250',
@@ -1151,6 +929,7 @@ export function getBidResponsesFromAPI() {
'bidderCode': 'rubicon',
'width': 300,
'height': 600,
+ 'mediaType': 'banner',
'statusMessage': 'Bid available',
'adId': '29019e2ab586a5a',
'cpm': 2.74,
diff --git a/test/spec/config_spec.js b/test/spec/config_spec.js
index 196e167420a..c0f4f6bab89 100644
--- a/test/spec/config_spec.js
+++ b/test/spec/config_spec.js
@@ -77,7 +77,8 @@ describe('config API', function () {
syncEnabled: true,
pixelEnabled: true,
syncsPerBidder: 5,
- syncDelay: 3000
+ syncDelay: 3000,
+ auctionDelay: 0
};
setDefaults({'userSync': DEFAULT_USERSYNC});
expect(getConfig('userSync')).to.eql(DEFAULT_USERSYNC);
diff --git a/test/spec/modules/adkernelBidAdapter_spec.js b/test/spec/modules/adkernelBidAdapter_spec.js
index 621b9971304..1f221cd956e 100644
--- a/test/spec/modules/adkernelBidAdapter_spec.js
+++ b/test/spec/modules/adkernelBidAdapter_spec.js
@@ -379,8 +379,8 @@ describe('Adkernel adapter', function () {
describe('adapter configuration', () => {
it('should have aliases', () => {
- expect(spec.aliases).to.have.lengthOf(3);
- expect(spec.aliases).to.be.eql(['headbidding', 'adsolut', 'oftmediahb']);
+ expect(spec.aliases).to.have.lengthOf(4);
+ expect(spec.aliases).to.be.eql(['headbidding', 'adsolut', 'oftmediahb', 'audiencemedia']);
});
});
});
diff --git a/test/spec/modules/appnexusBidAdapter_spec.js b/test/spec/modules/appnexusBidAdapter_spec.js
index ef3f3eef6b3..e35560ac1d0 100644
--- a/test/spec/modules/appnexusBidAdapter_spec.js
+++ b/test/spec/modules/appnexusBidAdapter_spec.js
@@ -675,6 +675,36 @@ describe('AppNexusAdapter', function () {
const payload = JSON.parse(request.data);
expect(payload.tpuids).to.deep.equal([{provider: 'criteo', user_id: 'sample-userid'}]);
});
+
+ it('should populate schain if available', function () {
+ const bidRequest = Object.assign({}, bidRequests[0], {
+ schain: {
+ ver: '1.0',
+ complete: 1,
+ nodes: [
+ {
+ 'asi': 'blob.com',
+ 'sid': '001',
+ 'hp': 1
+ }
+ ]
+ }
+ });
+
+ const request = spec.buildRequests([bidRequest]);
+ const payload = JSON.parse(request.data);
+ expect(payload.schain).to.deep.equal({
+ ver: '1.0',
+ complete: 1,
+ nodes: [
+ {
+ 'asi': 'blob.com',
+ 'sid': '001',
+ 'hp': 1
+ }
+ ]
+ });
+ });
})
describe('interpretResponse', function () {
diff --git a/test/spec/modules/conversantBidAdapter_spec.js b/test/spec/modules/conversantBidAdapter_spec.js
deleted file mode 100644
index bfe3c6e8fa1..00000000000
--- a/test/spec/modules/conversantBidAdapter_spec.js
+++ /dev/null
@@ -1,417 +0,0 @@
-import {expect} from 'chai';
-import {spec} from 'modules/conversantBidAdapter';
-import * as utils from 'src/utils';
-
-var Adapter = require('modules/conversantBidAdapter');
-
-describe('Conversant adapter tests', function() {
- const siteId = '108060';
-
- const bidRequests = [
- // banner with single size
- {
- bidder: 'conversant',
- params: {
- site_id: siteId,
- position: 1,
- tag_id: 'tagid-1',
- secure: false,
- bidfloor: 0.5
- },
- placementCode: 'pcode000',
- transactionId: 'tx000',
- sizes: [[300, 250]],
- bidId: 'bid000',
- bidderRequestId: '117d765b87bed38',
- auctionId: 'req000'
- },
- // banner with sizes in mediaTypes.banner.sizes
- {
- bidder: 'conversant',
- params: {
- site_id: siteId,
- secure: false
- },
- mediaTypes: {
- banner: {
- sizes: [[728, 90], [468, 60]]
- }
- },
- placementCode: 'pcode001',
- transactionId: 'tx001',
- bidId: 'bid001',
- bidderRequestId: '117d765b87bed38',
- auctionId: 'req000'
- },
- // banner with tag id and position
- {
- bidder: 'conversant',
- params: {
- site_id: siteId,
- position: 2,
- tag_id: '',
- secure: false
- },
- placementCode: 'pcode002',
- transactionId: 'tx002',
- sizes: [[300, 600], [160, 600]],
- bidId: 'bid002',
- bidderRequestId: '117d765b87bed38',
- auctionId: 'req000'
- },
- // video with single size
- {
- bidder: 'conversant',
- params: {
- site_id: siteId,
- api: [2],
- protocols: [1, 2],
- mimes: ['video/mp4', 'video/x-flv'],
- maxduration: 30
- },
- mediaTypes: {
- video: {
- context: 'instream',
- playerSize: [632, 499],
- }
- },
- placementCode: 'pcode003',
- transactionId: 'tx003',
- sizes: [640, 480],
- bidId: 'bid003',
- bidderRequestId: '117d765b87bed38',
- auctionId: 'req000'
- },
- // video with playerSize
- {
- bidder: 'conversant',
- params: {
- site_id: siteId,
- maxduration: 30,
- api: [2, 3]
- },
- mediaTypes: {
- video: {
- context: 'instream',
- playerSize: [1024, 768],
- api: [1, 2],
- protocols: [1, 2, 3],
- mimes: ['video/mp4', 'video/x-flv']
- }
- },
- placementCode: 'pcode004',
- transactionId: 'tx004',
- bidId: 'bid004',
- bidderRequestId: '117d765b87bed38',
- auctionId: 'req000'
- },
- // video without sizes
- {
- bidder: 'conversant',
- params: {
- site_id: siteId
- },
- mediaTypes: {
- video: {
- context: 'instream',
- mimes: ['video/mp4', 'video/x-flv']
- }
- },
- placementCode: 'pcode005',
- transactionId: 'tx005',
- bidId: 'bid005',
- bidderRequestId: '117d765b87bed38',
- auctionId: 'req000'
- }];
-
- const bidResponses = {
- body: {
- id: 'req000',
- seatbid: [{
- bid: [{
- nurl: 'notify000',
- adm: 'markup000',
- crid: '1000',
- impid: 'bid000',
- price: 0.99,
- w: 300,
- h: 250,
- adomain: ['https://example.com'],
- id: 'bid000'
- }, {
- impid: 'bid001',
- price: 0.00000,
- id: 'bid001'
- }, {
- nurl: 'notify002',
- adm: 'markup002',
- crid: '1002',
- impid: 'bid002',
- price: 2.99,
- w: 300,
- h: 600,
- adomain: ['https://example.com'],
- id: 'bid002'
- }, {
- nurl: 'notify003',
- adm: 'markup003',
- crid: '1003',
- impid: 'bid003',
- price: 3.99,
- adomain: ['https://example.com'],
- id: 'bid003'
- }]
- }]
- },
- headers: {}};
-
- it('Verify basic properties', function() {
- expect(spec.code).to.equal('conversant');
- expect(spec.aliases).to.be.an('array').with.lengthOf(1);
- expect(spec.aliases[0]).to.equal('cnvr');
- expect(spec.supportedMediaTypes).to.be.an('array').with.lengthOf(2);
- expect(spec.supportedMediaTypes[1]).to.equal('video');
- });
-
- it('Verify isBidRequestValid', function() {
- expect(spec.isBidRequestValid({})).to.be.false;
- expect(spec.isBidRequestValid({params: {}})).to.be.false;
- expect(spec.isBidRequestValid({params: {site_id: '123'}})).to.be.true;
- expect(spec.isBidRequestValid(bidRequests[0])).to.be.true;
- expect(spec.isBidRequestValid(bidRequests[1])).to.be.true;
- expect(spec.isBidRequestValid(bidRequests[2])).to.be.true;
- expect(spec.isBidRequestValid(bidRequests[3])).to.be.true;
- expect(spec.isBidRequestValid(bidRequests[4])).to.be.true;
- expect(spec.isBidRequestValid(bidRequests[5])).to.be.true;
-
- const simpleVideo = JSON.parse(JSON.stringify(bidRequests[3]));
- simpleVideo.params.site_id = 123;
- expect(spec.isBidRequestValid(simpleVideo)).to.be.false;
- simpleVideo.params.site_id = siteId;
- simpleVideo.params.mimes = [1, 2, 3];
- expect(spec.isBidRequestValid(simpleVideo)).to.be.false;
- simpleVideo.params.mimes = 'bad type';
- expect(spec.isBidRequestValid(simpleVideo)).to.be.false;
- delete simpleVideo.params.mimes;
- expect(spec.isBidRequestValid(simpleVideo)).to.be.true;
- });
-
- it('Verify buildRequest', function() {
- const request = spec.buildRequests(bidRequests);
- expect(request.method).to.equal('POST');
- expect(request.url).to.equal('//web.hb.ad.cpe.dotomi.com/s2s/header/24');
- const payload = request.data;
-
- expect(payload).to.have.property('id', 'req000');
- expect(payload).to.have.property('at', 1);
- expect(payload).to.have.property('imp');
- expect(payload.imp).to.be.an('array').with.lengthOf(6);
-
- expect(payload.imp[0]).to.have.property('id', 'bid000');
- expect(payload.imp[0]).to.have.property('secure', 0);
- expect(payload.imp[0]).to.have.property('bidfloor', 0.5);
- expect(payload.imp[0]).to.have.property('displaymanager', 'Prebid.js');
- expect(payload.imp[0]).to.have.property('displaymanagerver').that.matches(/^\d+\.\d+\.\d+$/);
- expect(payload.imp[0]).to.have.property('tagid', 'tagid-1');
- expect(payload.imp[0]).to.have.property('banner');
- expect(payload.imp[0].banner).to.have.property('pos', 1);
- expect(payload.imp[0].banner).to.have.property('format');
- expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}]);
- expect(payload.imp[0]).to.not.have.property('video');
-
- expect(payload.imp[1]).to.have.property('id', 'bid001');
- expect(payload.imp[1]).to.have.property('secure', 0);
- expect(payload.imp[1]).to.have.property('bidfloor', 0);
- expect(payload.imp[1]).to.have.property('displaymanager', 'Prebid.js');
- expect(payload.imp[1]).to.have.property('displaymanagerver').that.matches(/^\d+\.\d+\.\d+$/);
- expect(payload.imp[1]).to.not.have.property('tagid');
- expect(payload.imp[1]).to.have.property('banner');
- expect(payload.imp[1].banner).to.not.have.property('pos');
- expect(payload.imp[1].banner).to.have.property('format');
- expect(payload.imp[1].banner.format).to.deep.equal([{w: 728, h: 90}, {w: 468, h: 60}]);
-
- expect(payload.imp[2]).to.have.property('id', 'bid002');
- expect(payload.imp[2]).to.have.property('secure', 0);
- expect(payload.imp[2]).to.have.property('bidfloor', 0);
- expect(payload.imp[2]).to.have.property('displaymanager', 'Prebid.js');
- expect(payload.imp[2]).to.have.property('displaymanagerver').that.matches(/^\d+\.\d+\.\d+$/);
- expect(payload.imp[2]).to.have.property('banner');
- expect(payload.imp[2].banner).to.have.property('pos', 2);
- expect(payload.imp[2].banner).to.have.property('format');
- expect(payload.imp[2].banner.format).to.deep.equal([{w: 300, h: 600}, {w: 160, h: 600}]);
-
- expect(payload.imp[3]).to.have.property('id', 'bid003');
- expect(payload.imp[3]).to.have.property('secure', 0);
- expect(payload.imp[3]).to.have.property('bidfloor', 0);
- expect(payload.imp[3]).to.have.property('displaymanager', 'Prebid.js');
- expect(payload.imp[3]).to.have.property('displaymanagerver').that.matches(/^\d+\.\d+\.\d+$/);
- expect(payload.imp[3]).to.not.have.property('tagid');
- expect(payload.imp[3]).to.have.property('video');
- expect(payload.imp[3].video).to.not.have.property('pos');
- expect(payload.imp[3].video).to.have.property('w', 632);
- expect(payload.imp[3].video).to.have.property('h', 499);
- expect(payload.imp[3].video).to.have.property('mimes');
- expect(payload.imp[3].video.mimes).to.deep.equal(['video/mp4', 'video/x-flv']);
- expect(payload.imp[3].video).to.have.property('protocols');
- expect(payload.imp[3].video.protocols).to.deep.equal([1, 2]);
- expect(payload.imp[3].video).to.have.property('api');
- expect(payload.imp[3].video.api).to.deep.equal([2]);
- expect(payload.imp[3].video).to.have.property('maxduration', 30);
- expect(payload.imp[3]).to.not.have.property('banner');
-
- expect(payload.imp[4]).to.have.property('id', 'bid004');
- expect(payload.imp[4]).to.have.property('secure', 0);
- expect(payload.imp[4]).to.have.property('bidfloor', 0);
- expect(payload.imp[4]).to.have.property('displaymanager', 'Prebid.js');
- expect(payload.imp[4]).to.have.property('displaymanagerver').that.matches(/^\d+\.\d+\.\d+$/);
- expect(payload.imp[4]).to.not.have.property('tagid');
- expect(payload.imp[4]).to.have.property('video');
- expect(payload.imp[4].video).to.not.have.property('pos');
- expect(payload.imp[4].video).to.have.property('w', 1024);
- expect(payload.imp[4].video).to.have.property('h', 768);
- expect(payload.imp[4].video).to.have.property('mimes');
- expect(payload.imp[4].video.mimes).to.deep.equal(['video/mp4', 'video/x-flv']);
- expect(payload.imp[4].video).to.have.property('protocols');
- expect(payload.imp[4].video.protocols).to.deep.equal([1, 2, 3]);
- expect(payload.imp[4].video).to.have.property('api');
- expect(payload.imp[4].video.api).to.deep.equal([2, 3]);
- expect(payload.imp[4].video).to.have.property('maxduration', 30);
- expect(payload.imp[4]).to.not.have.property('banner');
-
- expect(payload.imp[5]).to.have.property('id', 'bid005');
- expect(payload.imp[5]).to.have.property('secure', 0);
- expect(payload.imp[5]).to.have.property('bidfloor', 0);
- expect(payload.imp[5]).to.have.property('displaymanager', 'Prebid.js');
- expect(payload.imp[5]).to.have.property('displaymanagerver').that.matches(/^\d+\.\d+\.\d+$/);
- expect(payload.imp[5]).to.not.have.property('tagid');
- expect(payload.imp[5]).to.have.property('video');
- expect(payload.imp[5].video).to.not.have.property('pos');
- expect(payload.imp[5].video).to.not.have.property('w');
- expect(payload.imp[5].video).to.not.have.property('h');
- expect(payload.imp[5].video).to.have.property('mimes');
- expect(payload.imp[5].video.mimes).to.deep.equal(['video/mp4', 'video/x-flv']);
- expect(payload.imp[5].video).to.not.have.property('protocols');
- expect(payload.imp[5].video).to.not.have.property('api');
- expect(payload.imp[5].video).to.not.have.property('maxduration');
- expect(payload.imp[5]).to.not.have.property('banner');
-
- expect(payload).to.have.property('site');
- expect(payload.site).to.have.property('id', siteId);
- expect(payload.site).to.have.property('mobile').that.is.oneOf([0, 1]);
- const loc = utils.getTopWindowLocation();
- const page = loc.href;
- expect(payload.site).to.have.property('page', page);
-
- expect(payload).to.have.property('device');
- expect(payload.device).to.have.property('w', screen.width);
- expect(payload.device).to.have.property('h', screen.height);
- expect(payload.device).to.have.property('dnt').that.is.oneOf([0, 1]);
- expect(payload.device).to.have.property('ua', navigator.userAgent);
-
- expect(payload).to.not.have.property('user'); // there should be no user by default
- });
-
- it('Verify interpretResponse', function() {
- const request = spec.buildRequests(bidRequests);
- const response = spec.interpretResponse(bidResponses, request);
- expect(response).to.be.an('array').with.lengthOf(3);
-
- let bid = response[0];
- expect(bid).to.have.property('requestId', 'bid000');
- expect(bid).to.have.property('currency', 'USD');
- expect(bid).to.have.property('cpm', 0.99);
- expect(bid).to.have.property('creativeId', '1000');
- expect(bid).to.have.property('width', 300);
- expect(bid).to.have.property('height', 250);
- expect(bid).to.have.property('ad', 'markup000');
- expect(bid).to.have.property('ttl', 300);
- expect(bid).to.have.property('netRevenue', true);
-
- // There is no bid001 because cpm is $0
-
- bid = response[1];
- expect(bid).to.have.property('requestId', 'bid002');
- expect(bid).to.have.property('currency', 'USD');
- expect(bid).to.have.property('cpm', 2.99);
- expect(bid).to.have.property('creativeId', '1002');
- expect(bid).to.have.property('width', 300);
- expect(bid).to.have.property('height', 600);
- expect(bid).to.have.property('ad', 'markup002');
- expect(bid).to.have.property('ttl', 300);
- expect(bid).to.have.property('netRevenue', true);
-
- bid = response[2];
- expect(bid).to.have.property('requestId', 'bid003');
- expect(bid).to.have.property('currency', 'USD');
- expect(bid).to.have.property('cpm', 3.99);
- expect(bid).to.have.property('creativeId', '1003');
- expect(bid).to.have.property('width', 632);
- expect(bid).to.have.property('height', 499);
- expect(bid).to.have.property('vastUrl', 'markup003');
- expect(bid).to.have.property('mediaType', 'video');
- expect(bid).to.have.property('ttl', 300);
- expect(bid).to.have.property('netRevenue', true);
- });
-
- it('Verify handling of bad responses', function() {
- let response = spec.interpretResponse({}, {});
- expect(response).to.be.an('array').with.lengthOf(0);
- response = spec.interpretResponse({id: '123'}, {});
- expect(response).to.be.an('array').with.lengthOf(0);
- response = spec.interpretResponse({id: '123', seatbid: []}, {});
- expect(response).to.be.an('array').with.lengthOf(0);
- });
-
- it('Verify publisher commond id support', function() {
- // clone bidRequests
- let requests = utils.deepClone(bidRequests)
-
- // add pubcid to every entry
- requests.forEach((unit) => {
- Object.assign(unit, {crumbs: {pubcid: 12345}});
- });
- // construct http post payload
- const payload = spec.buildRequests(requests).data;
- expect(payload).to.have.deep.nested.property('user.ext.fpc', 12345);
- });
-
- it('Verify User ID publisher commond id support', function() {
- // clone bidRequests
- let requests = utils.deepClone(bidRequests)
-
- // add pubcid to every entry
- requests.forEach((unit) => {
- Object.assign(unit, {userId: {pubcid: 67890}});
- });
- // construct http post payload
- const payload = spec.buildRequests(requests).data;
- expect(payload).to.have.deep.nested.property('user.ext.fpc', 67890);
- });
-
- it('Verify GDPR bid request', function() {
- // add gdpr info
- const bidRequest = {
- gdprConsent: {
- consentString: 'BOJObISOJObISAABAAENAA4AAAAAoAAA',
- gdprApplies: true
- }
- };
-
- const payload = spec.buildRequests(bidRequests, bidRequest).data;
- expect(payload).to.have.deep.nested.property('user.ext.consent', 'BOJObISOJObISAABAAENAA4AAAAAoAAA');
- expect(payload).to.have.deep.nested.property('regs.ext.gdpr', 1);
- });
-
- it('Verify GDPR bid request without gdprApplies', function() {
- // add gdpr info
- const bidRequest = {
- gdprConsent: {
- consentString: ''
- }
- };
-
- const payload = spec.buildRequests(bidRequests, bidRequest).data;
- expect(payload).to.have.deep.nested.property('user.ext.consent', '');
- expect(payload).to.not.have.deep.nested.property('regs.ext.gdpr');
- });
-})
diff --git a/test/spec/modules/criteoBidAdapter_spec.js b/test/spec/modules/criteoBidAdapter_spec.js
deleted file mode 100755
index f85e5957950..00000000000
--- a/test/spec/modules/criteoBidAdapter_spec.js
+++ /dev/null
@@ -1,997 +0,0 @@
-import { expect } from 'chai';
-import { tryGetCriteoFastBid, spec, PROFILE_ID_PUBLISHERTAG, ADAPTER_VERSION, PUBLISHER_TAG_URL } from 'modules/criteoBidAdapter';
-import { createBid } from 'src/bidfactory';
-import CONSTANTS from 'src/constants.json';
-import * as utils from 'src/utils';
-import { config } from '../../../src/config';
-import { VIDEO } from '../../../src/mediaTypes';
-
-describe('The Criteo bidding adapter', function () {
- let utilsMock;
-
- beforeEach(function () {
- // Remove FastBid to avoid side effects
- localStorage.removeItem('criteo_fast_bid');
- utilsMock = sinon.mock(utils);
- });
-
- afterEach(function() {
- global.Criteo = undefined;
- utilsMock.restore();
- });
-
- describe('isBidRequestValid', function () {
- it('should return false when given an invalid bid', function () {
- const bid = {
- bidder: 'criteo',
- };
- const isValid = spec.isBidRequestValid(bid);
- expect(isValid).to.equal(false);
- });
-
- it('should return true when given a zoneId bid', function () {
- const bid = {
- bidder: 'criteo',
- params: {
- zoneId: 123,
- },
- };
- const isValid = spec.isBidRequestValid(bid);
- expect(isValid).to.equal(true);
- });
-
- it('should return true when given a networkId bid', function () {
- const bid = {
- bidder: 'criteo',
- params: {
- networkId: 456,
- },
- };
- const isValid = spec.isBidRequestValid(bid);
- expect(isValid).to.equal(true);
- });
-
- it('should return true when given a mixed bid with both a zoneId and a networkId', function () {
- const bid = {
- bidder: 'criteo',
- params: {
- zoneId: 123,
- networkId: 456,
- },
- };
- const isValid = spec.isBidRequestValid(bid);
- expect(isValid).to.equal(true);
- });
-
- it('should return true when given a valid video bid request', function () {
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'instream',
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 1,
- playbackmethod: 1
- }
- },
- })).to.equal(true);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'outstream',
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 2,
- playbackmethod: 1
- }
- },
- })).to.equal(true);
- });
-
- it('should return false when given an invalid video bid request', function () {
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 1,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'instream',
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 2,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'outstream',
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 1,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'adpod',
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 1,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'instream',
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 1,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'instream',
- mimes: ['video/mpeg'],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 1,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'instream',
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 1,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'instream',
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 1,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'instream',
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 1,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'instream',
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- placement: 1,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'instream',
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'instream',
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 1
- }
- },
- })).to.equal(false);
- });
- });
-
- describe('buildRequests', function () {
- const bidderRequest = {
- timeout: 3000,
- gdprConsent: {
- gdprApplies: 1,
- consentString: 'concentDataString',
- vendorData: {
- vendorConsents: {
- '91': 1
- },
- },
- },
- };
-
- afterEach(function () {
- config.resetConfig();
- });
-
- it('should properly build a zoneId request', function () {
- const publisherUrl = 'https://criteo.com?pbt_debug=1&pbt_nolog=1';
- utilsMock.expects('getTopWindowUrl').withExactArgs().once().returns(publisherUrl);
-
- const bidRequests = [
- {
- bidder: 'criteo',
- adUnitCode: 'bid-123',
- transactionId: 'transaction-123',
- sizes: [[728, 90]],
- params: {
- zoneId: 123,
- publisherSubId: '123',
- nativeCallback: function() {},
- integrationMode: 'amp'
- },
- },
- ];
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request.url).to.match(/^\/\/bidder\.criteo\.com\/cdb\?profileId=207&av=\d+&wv=[^&]+&cb=\d+&im=1&debug=1&nolog=1/);
- expect(request.method).to.equal('POST');
- const ortbRequest = request.data;
- expect(ortbRequest.publisher.url).to.equal(publisherUrl);
- expect(ortbRequest.slots).to.have.lengthOf(1);
- expect(ortbRequest.slots[0].impid).to.equal('bid-123');
- expect(ortbRequest.slots[0].transactionid).to.equal('transaction-123');
- expect(ortbRequest.slots[0].sizes).to.have.lengthOf(1);
- expect(ortbRequest.slots[0].sizes[0]).to.equal('728x90');
- expect(ortbRequest.slots[0].zoneid).to.equal(123);
- expect(ortbRequest.gdprConsent.consentData).to.equal('concentDataString');
- expect(ortbRequest.gdprConsent.gdprApplies).to.equal(true);
- expect(ortbRequest.gdprConsent.consentGiven).to.equal(true);
- });
-
- it('should properly build a networkId request', function () {
- const bidderRequest = {
- timeout: 3000,
- gdprConsent: {
- gdprApplies: 0,
- consentString: undefined,
- vendorData: {
- vendorConsents: {
- '1': 0
- },
- },
- },
- };
- const bidRequests = [
- {
- bidder: 'criteo',
- adUnitCode: 'bid-123',
- transactionId: 'transaction-123',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [728, 90]]
- }
- },
- params: {
- networkId: 456,
- },
- },
- ];
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request.url).to.match(/^\/\/bidder\.criteo\.com\/cdb\?profileId=207&av=\d+&wv=[^&]+&cb=\d/);
- expect(request.method).to.equal('POST');
- const ortbRequest = request.data;
- expect(ortbRequest.publisher.url).to.equal(utils.getTopWindowUrl());
- expect(ortbRequest.publisher.networkid).to.equal(456);
- expect(ortbRequest.slots).to.have.lengthOf(1);
- expect(ortbRequest.slots[0].impid).to.equal('bid-123');
- expect(ortbRequest.slots[0].transactionid).to.equal('transaction-123');
- expect(ortbRequest.slots[0].sizes).to.have.lengthOf(2);
- expect(ortbRequest.slots[0].sizes[0]).to.equal('300x250');
- expect(ortbRequest.slots[0].sizes[1]).to.equal('728x90');
- expect(ortbRequest.gdprConsent.consentData).to.equal(undefined);
- expect(ortbRequest.gdprConsent.gdprApplies).to.equal(false);
- expect(ortbRequest.gdprConsent.consentGiven).to.equal(undefined);
- });
-
- it('should properly build a mixed request', function () {
- const bidderRequest = { timeout: 3000 };
- const bidRequests = [
- {
- bidder: 'criteo',
- adUnitCode: 'bid-123',
- transactionId: 'transaction-123',
- sizes: [[728, 90]],
- params: {
- zoneId: 123,
- },
- },
- {
- bidder: 'criteo',
- adUnitCode: 'bid-234',
- transactionId: 'transaction-234',
- sizes: [[300, 250], [728, 90]],
- params: {
- networkId: 456,
- },
- },
- ];
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request.url).to.match(/^\/\/bidder\.criteo\.com\/cdb\?profileId=207&av=\d+&wv=[^&]+&cb=\d/);
- expect(request.method).to.equal('POST');
- const ortbRequest = request.data;
- expect(ortbRequest.publisher.url).to.equal(utils.getTopWindowUrl());
- expect(ortbRequest.publisher.networkid).to.equal(456);
- expect(ortbRequest.slots).to.have.lengthOf(2);
- expect(ortbRequest.slots[0].impid).to.equal('bid-123');
- expect(ortbRequest.slots[0].transactionid).to.equal('transaction-123');
- expect(ortbRequest.slots[0].sizes).to.have.lengthOf(1);
- expect(ortbRequest.slots[0].sizes[0]).to.equal('728x90');
- expect(ortbRequest.slots[1].impid).to.equal('bid-234');
- expect(ortbRequest.slots[1].transactionid).to.equal('transaction-234');
- expect(ortbRequest.slots[1].sizes).to.have.lengthOf(2);
- expect(ortbRequest.slots[1].sizes[0]).to.equal('300x250');
- expect(ortbRequest.slots[1].sizes[1]).to.equal('728x90');
- expect(ortbRequest.gdprConsent).to.equal(undefined);
- });
-
- it('should properly build request with undefined gdpr consent fields when they are not provided', function () {
- const bidRequests = [
- {
- bidder: 'criteo',
- adUnitCode: 'bid-123',
- transactionId: 'transaction-123',
- sizes: [[728, 90]],
- params: {
- zoneId: 123,
- },
- },
- ];
- const bidderRequest = { timeout: 3000,
- gdprConsent: {
- },
- };
-
- const ortbRequest = spec.buildRequests(bidRequests, bidderRequest).data;
- expect(ortbRequest.gdprConsent.consentData).to.equal(undefined);
- expect(ortbRequest.gdprConsent.gdprApplies).to.equal(undefined);
- expect(ortbRequest.gdprConsent.consentGiven).to.equal(undefined);
- });
-
- it('should properly build a video request', function () {
- const bidRequests = [
- {
- bidder: 'criteo',
- adUnitCode: 'bid-123',
- transactionId: 'transaction-123',
- sizes: [[728, 90]],
- mediaTypes: {
- video: {
- playerSize: [640, 480],
- mimes: ['video/mp4', 'video/x-flv'],
- maxduration: 30,
- api: [1, 2],
- protocols: [2, 3]
- }
- },
- params: {
- zoneId: 123,
- video: {
- skip: 1,
- minduration: 5,
- startdelay: 5,
- playbackmethod: [1, 3],
- placement: 2
- }
- },
- },
- ];
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request.url).to.match(/^\/\/bidder\.criteo\.com\/cdb\?profileId=207&av=\d+&wv=[^&]+&cb=\d/);
- expect(request.method).to.equal('POST');
- const ortbRequest = request.data;
- expect(ortbRequest.slots[0].video.mimes).to.deep.equal(['video/mp4', 'video/x-flv']);
- expect(ortbRequest.slots[0].video.playersizes).to.deep.equal(['640x480']);
- expect(ortbRequest.slots[0].video.maxduration).to.equal(30);
- expect(ortbRequest.slots[0].video.api).to.deep.equal([1, 2]);
- expect(ortbRequest.slots[0].video.protocols).to.deep.equal([2, 3]);
- expect(ortbRequest.slots[0].video.skip).to.equal(1);
- expect(ortbRequest.slots[0].video.minduration).to.equal(5);
- expect(ortbRequest.slots[0].video.startdelay).to.equal(5);
- expect(ortbRequest.slots[0].video.playbackmethod).to.deep.equal([1, 3]);
- expect(ortbRequest.slots[0].video.placement).to.equal(2);
- });
-
- it('should properly build a video request with more than one player size', function () {
- const bidRequests = [
- {
- bidder: 'criteo',
- adUnitCode: 'bid-123',
- transactionId: 'transaction-123',
- sizes: [[728, 90]],
- mediaTypes: {
- video: {
- playerSize: [[640, 480], [800, 600]],
- mimes: ['video/mp4', 'video/x-flv'],
- maxduration: 30,
- api: [1, 2],
- protocols: [2, 3]
- }
- },
- params: {
- zoneId: 123,
- video: {
- skip: 1,
- minduration: 5,
- startdelay: 5,
- playbackmethod: [1, 3],
- placement: 2
- }
- },
- },
- ];
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request.url).to.match(/^\/\/bidder\.criteo\.com\/cdb\?profileId=207&av=\d+&wv=[^&]+&cb=\d/);
- expect(request.method).to.equal('POST');
- const ortbRequest = request.data;
- expect(ortbRequest.slots[0].video.mimes).to.deep.equal(['video/mp4', 'video/x-flv']);
- expect(ortbRequest.slots[0].video.playersizes).to.deep.equal(['640x480', '800x600']);
- expect(ortbRequest.slots[0].video.maxduration).to.equal(30);
- expect(ortbRequest.slots[0].video.api).to.deep.equal([1, 2]);
- expect(ortbRequest.slots[0].video.protocols).to.deep.equal([2, 3]);
- expect(ortbRequest.slots[0].video.skip).to.equal(1);
- expect(ortbRequest.slots[0].video.minduration).to.equal(5);
- expect(ortbRequest.slots[0].video.startdelay).to.equal(5);
- expect(ortbRequest.slots[0].video.playbackmethod).to.deep.equal([1, 3]);
- expect(ortbRequest.slots[0].video.placement).to.equal(2);
- });
-
- it('should properly build a request with ceh', function () {
- const bidRequests = [
- {
- bidder: 'criteo',
- adUnitCode: 'bid-123',
- transactionId: 'transaction-123',
- sizes: [[728, 90]],
- params: {
- zoneId: 123,
- },
- },
- ];
- config.setConfig({
- criteo: {
- ceh: 'hashedemail'
- }
- });
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request.data.user).to.not.be.null;
- expect(request.data.user.ceh).to.equal('hashedemail');
- });
- });
-
- describe('interpretResponse', function () {
- it('should return an empty array when parsing a no bid response', function () {
- const response = {};
- const request = { bidRequests: [] };
- const bids = spec.interpretResponse(response, request);
- expect(bids).to.have.lengthOf(0);
- });
-
- it('should properly parse a bid response with a networkId', function () {
- const response = {
- body: {
- slots: [{
- impid: 'test-requestId',
- cpm: 1.23,
- creative: 'test-ad',
- width: 728,
- height: 90,
- dealCode: 'myDealCode',
- }],
- },
- };
- const request = {
- bidRequests: [{
- adUnitCode: 'test-requestId',
- bidId: 'test-bidId',
- params: {
- networkId: 456,
- }
- }]
- };
- const bids = spec.interpretResponse(response, request);
- expect(bids).to.have.lengthOf(1);
- expect(bids[0].requestId).to.equal('test-bidId');
- expect(bids[0].cpm).to.equal(1.23);
- expect(bids[0].ad).to.equal('test-ad');
- expect(bids[0].width).to.equal(728);
- expect(bids[0].height).to.equal(90);
- expect(bids[0].dealId).to.equal('myDealCode');
- });
-
- it('should properly parse a bid responsewith with a zoneId', function () {
- const response = {
- body: {
- slots: [{
- impid: 'test-requestId',
- bidId: 'abc123',
- cpm: 1.23,
- creative: 'test-ad',
- width: 728,
- height: 90,
- zoneid: 123,
- }],
- },
- };
- const request = {
- bidRequests: [{
- adUnitCode: 'test-requestId',
- bidId: 'test-bidId',
- params: {
- zoneId: 123,
- },
- }]
- };
- const bids = spec.interpretResponse(response, request);
- expect(bids).to.have.lengthOf(1);
- expect(bids[0].requestId).to.equal('test-bidId');
- expect(bids[0].adId).to.equal('abc123');
- expect(bids[0].cpm).to.equal(1.23);
- expect(bids[0].ad).to.equal('test-ad');
- expect(bids[0].width).to.equal(728);
- expect(bids[0].height).to.equal(90);
- });
-
- it('should properly parse a bid responsewith with a video', function () {
- const response = {
- body: {
- slots: [{
- impid: 'test-requestId',
- bidId: 'abc123',
- cpm: 1.23,
- displayurl: 'http://test-ad',
- width: 728,
- height: 90,
- zoneid: 123,
- video: true
- }],
- },
- };
- const request = {
- bidRequests: [{
- adUnitCode: 'test-requestId',
- bidId: 'test-bidId',
- params: {
- zoneId: 123,
- },
- }]
- };
- const bids = spec.interpretResponse(response, request);
- expect(bids).to.have.lengthOf(1);
- expect(bids[0].requestId).to.equal('test-bidId');
- expect(bids[0].adId).to.equal('abc123');
- expect(bids[0].cpm).to.equal(1.23);
- expect(bids[0].vastUrl).to.equal('http://test-ad');
- expect(bids[0].mediaType).to.equal(VIDEO);
- });
-
- it('should properly parse a bid responsewith with a zoneId passed as a string', function () {
- const response = {
- body: {
- slots: [{
- impid: 'test-requestId',
- cpm: 1.23,
- creative: 'test-ad',
- width: 728,
- height: 90,
- zoneid: 123,
- }],
- },
- };
- const request = {
- bidRequests: [{
- adUnitCode: 'test-requestId',
- bidId: 'test-bidId',
- params: {
- zoneId: '123',
- },
- }]
- };
- const bids = spec.interpretResponse(response, request);
- expect(bids).to.have.lengthOf(1);
- expect(bids[0].requestId).to.equal('test-bidId');
- expect(bids[0].cpm).to.equal(1.23);
- expect(bids[0].ad).to.equal('test-ad');
- expect(bids[0].width).to.equal(728);
- expect(bids[0].height).to.equal(90);
- });
-
- it('should generate unique adIds if none are returned by the endpoint', function () {
- const response = {
- body: {
- slots: [{
- impid: 'test-requestId',
- cpm: 1.23,
- creative: 'test-ad',
- width: 300,
- height: 250,
- }, {
- impid: 'test-requestId',
- cpm: 4.56,
- creative: 'test-ad',
- width: 728,
- height: 90,
- }],
- },
- };
- const request = {
- bidRequests: [{
- adUnitCode: 'test-requestId',
- bidId: 'test-bidId',
- sizes: [[300, 250], [728, 90]],
- params: {
- networkId: 456,
- }
- }]
- };
- const bids = spec.interpretResponse(response, request);
- expect(bids).to.have.lengthOf(2);
- const prebidBids = bids.map(bid => Object.assign(createBid(CONSTANTS.STATUS.GOOD, request.bidRequests[0]), bid));
- expect(prebidBids[0].adId).to.not.equal(prebidBids[1].adId);
- });
- });
-
- describe('tryGetCriteoFastBid', function () {
- const VALID_HASH = 'vBeD8Q7GU6lypFbzB07W8hLGj7NL+p7dI9ro2tCxkrmyv0F6stNuoNd75Us33iNKfEoW+cFWypelr6OJPXxki2MXWatRhJuUJZMcK4VBFnxi3Ro+3a0xEfxE4jJm4eGe98iC898M+/YFHfp+fEPEnS6pEyw124ONIFZFrcejpHU=';
- const INVALID_HASH = 'invalid';
- const VALID_PUBLISHER_TAG = 'test';
- const INVALID_PUBLISHER_TAG = 'test invalid';
-
- const FASTBID_LOCAL_STORAGE_KEY = 'criteo_fast_bid';
-
- it('should verify valid hash with valid publisher tag', function () {
- localStorage.setItem(FASTBID_LOCAL_STORAGE_KEY, '// Hash: ' + VALID_HASH + '\n' + VALID_PUBLISHER_TAG);
-
- utilsMock.expects('logInfo').withExactArgs('Using Criteo FastBid').once();
- utilsMock.expects('logWarn').withExactArgs('No hash found in FastBid').never();
- utilsMock.expects('logWarn').withExactArgs('Invalid Criteo FastBid found').never();
-
- tryGetCriteoFastBid();
-
- expect(localStorage.getItem(FASTBID_LOCAL_STORAGE_KEY)).to.equals('// Hash: ' + VALID_HASH + '\n' + VALID_PUBLISHER_TAG);
- utilsMock.verify();
- });
-
- it('should verify valid hash with invalid publisher tag', function () {
- localStorage.setItem(FASTBID_LOCAL_STORAGE_KEY, '// Hash: ' + VALID_HASH + '\n' + INVALID_PUBLISHER_TAG);
-
- utilsMock.expects('logInfo').withExactArgs('Using Criteo FastBid').never();
- utilsMock.expects('logWarn').withExactArgs('No hash found in FastBid').never();
- utilsMock.expects('logWarn').withExactArgs('Invalid Criteo FastBid found').once();
-
- tryGetCriteoFastBid();
-
- expect(localStorage.getItem(FASTBID_LOCAL_STORAGE_KEY)).to.be.null;
- utilsMock.verify();
- });
-
- it('should verify invalid hash with valid publisher tag', function () {
- localStorage.setItem(FASTBID_LOCAL_STORAGE_KEY, '// Hash: ' + INVALID_HASH + '\n' + VALID_PUBLISHER_TAG);
-
- utilsMock.expects('logInfo').withExactArgs('Using Criteo FastBid').never();
- utilsMock.expects('logWarn').withExactArgs('No hash found in FastBid').never();
- utilsMock.expects('logWarn').withExactArgs('Invalid Criteo FastBid found').once();
-
- tryGetCriteoFastBid();
-
- expect(localStorage.getItem(FASTBID_LOCAL_STORAGE_KEY)).to.be.null;
- utilsMock.verify();
- });
-
- it('should verify missing hash', function () {
- localStorage.setItem(FASTBID_LOCAL_STORAGE_KEY, VALID_PUBLISHER_TAG);
-
- utilsMock.expects('logInfo').withExactArgs('Using Criteo FastBid').never();
- utilsMock.expects('logWarn').withExactArgs('No hash found in FastBid').once();
- utilsMock.expects('logWarn').withExactArgs('Invalid Criteo FastBid found').never();
-
- tryGetCriteoFastBid();
-
- expect(localStorage.getItem(FASTBID_LOCAL_STORAGE_KEY)).to.be.null;
- utilsMock.verify();
- });
- });
-
- describe('when pubtag prebid adapter is available', function () {
- it('should forward response to pubtag when calling interpretResponse', () => {
- const response = {};
- const request = {};
-
- const adapter = { interpretResponse: function() {} };
- const adapterMock = sinon.mock(adapter);
- adapterMock.expects('interpretResponse').withExactArgs(response, request).once().returns('ok');
- const prebidAdapter = { GetAdapter: function() {} };
- const prebidAdapterMock = sinon.mock(prebidAdapter);
- prebidAdapterMock.expects('GetAdapter').withExactArgs(request).once().returns(adapter);
-
- global.Criteo = {
- PubTag: {
- Adapters: {
- Prebid: prebidAdapter
- }
- }
- };
-
- expect(spec.interpretResponse(response, request)).equal('ok');
- adapterMock.verify();
- prebidAdapterMock.verify();
- });
-
- it('should forward bid to pubtag when calling onBidWon', () => {
- const bid = { auctionId: 123 };
-
- const adapter = { handleBidWon: function() {} };
- const adapterMock = sinon.mock(adapter);
- adapterMock.expects('handleBidWon').withExactArgs(bid).once();
- const prebidAdapter = { GetAdapter: function() {} };
- const prebidAdapterMock = sinon.mock(prebidAdapter);
- prebidAdapterMock.expects('GetAdapter').withExactArgs(bid.auctionId).once().returns(adapter);
-
- global.Criteo = {
- PubTag: {
- Adapters: {
- Prebid: prebidAdapter
- }
- }
- };
-
- spec.onBidWon(bid);
- adapterMock.verify();
- prebidAdapterMock.verify();
- });
-
- it('should forward bid to pubtag when calling onSetTargeting', () => {
- const bid = { auctionId: 123 };
-
- const adapter = { handleSetTargeting: function() {} };
- const adapterMock = sinon.mock(adapter);
- adapterMock.expects('handleSetTargeting').withExactArgs(bid).once();
- const prebidAdapter = { GetAdapter: function() {} };
- const prebidAdapterMock = sinon.mock(prebidAdapter);
- prebidAdapterMock.expects('GetAdapter').withExactArgs(bid.auctionId).once().returns(adapter);
-
- global.Criteo = {
- PubTag: {
- Adapters: {
- Prebid: prebidAdapter
- }
- }
- };
-
- spec.onSetTargeting(bid);
- adapterMock.verify();
- prebidAdapterMock.verify();
- });
-
- it('should forward bid to pubtag when calling onTimeout', () => {
- const timeoutData = { auctionId: 123 };
-
- const adapter = { handleBidTimeout: function() {} };
- const adapterMock = sinon.mock(adapter);
- adapterMock.expects('handleBidTimeout').once();
- const prebidAdapter = { GetAdapter: function() {} };
- const prebidAdapterMock = sinon.mock(prebidAdapter);
- prebidAdapterMock.expects('GetAdapter').withExactArgs(timeoutData.auctionId).once().returns(adapter);
-
- global.Criteo = {
- PubTag: {
- Adapters: {
- Prebid: prebidAdapter
- }
- }
- };
-
- spec.onTimeout(timeoutData);
- adapterMock.verify();
- prebidAdapterMock.verify();
- });
-
- it('should return a POST method with url & data from pubtag', () => {
- const bidRequests = { };
- const bidderRequest = { };
-
- const prebidAdapter = { buildCdbUrl: function() {}, buildCdbRequest: function() {} };
- const prebidAdapterMock = sinon.mock(prebidAdapter);
- prebidAdapterMock.expects('buildCdbUrl').once().returns('cdbUrl');
- prebidAdapterMock.expects('buildCdbRequest').once().returns('cdbRequest');
-
- const adapters = { Prebid: function() {} };
- const adaptersMock = sinon.mock(adapters);
- adaptersMock.expects('Prebid').withExactArgs(PROFILE_ID_PUBLISHERTAG, ADAPTER_VERSION, bidRequests, bidderRequest, '$prebid.version$').once().returns(prebidAdapter);
-
- global.Criteo = {
- PubTag: {
- Adapters: adapters
- }
- };
-
- const buildRequestsResult = spec.buildRequests(bidRequests, bidderRequest);
- expect(buildRequestsResult.method).equal('POST');
- expect(buildRequestsResult.url).equal('cdbUrl');
- expect(buildRequestsResult.data).equal('cdbRequest');
-
- adaptersMock.verify();
- prebidAdapterMock.verify();
- });
- });
-});
diff --git a/test/spec/modules/criteortusIdSystem_spec.js b/test/spec/modules/criteortusIdSystem_spec.js
index 578f14d066d..217a2f86ba7 100644
--- a/test/spec/modules/criteortusIdSystem_spec.js
+++ b/test/spec/modules/criteortusIdSystem_spec.js
@@ -36,7 +36,8 @@ describe('Criteo RTUS', function() {
let response = { 'status': 'ok', 'userid': 'sample-userid' }
let callBackSpy = sinon.spy();
- let submoduleCallback = criteortusIdSubmodule.getId(configParams);
+ const idResp = criteortusIdSubmodule.getId(configParams);
+ const submoduleCallback = idResp.callback;
submoduleCallback(callBackSpy);
requests[0].respond(
200,
@@ -70,7 +71,8 @@ describe('Criteo RTUS', function() {
let response = { 'status': 'ok', 'userid': 'sample-userid' }
let callBackSpy = sinon.spy();
- let submoduleCallback = criteortusIdSubmodule.getId(configParams);
+ const idResp = criteortusIdSubmodule.getId(configParams);
+ const submoduleCallback = idResp.callback;
submoduleCallback(callBackSpy);
requests[0].respond(
200,
diff --git a/test/spec/modules/datablocksBidAdapter_spec.js b/test/spec/modules/datablocksBidAdapter_spec.js
index 07989b86535..d39116ccb71 100644
--- a/test/spec/modules/datablocksBidAdapter_spec.js
+++ b/test/spec/modules/datablocksBidAdapter_spec.js
@@ -84,12 +84,35 @@ let nativeBid = {
transactionId: '0a4e9788-4def-4b94-bc25-564d7cac99f6'
}
+let videoBid = {
+ adUnitCode: '/19968336/header-bid-tag-0',
+ auctionId: '160c78a4-f808-410f-b682-d8728f3a79e1',
+ bidId: '332045ee374b99',
+ bidder: 'datablocks',
+ bidderRequestId: '15d9012765e36d',
+ mediaTypes: {
+ video: {
+ context: 'instream',
+ playerSize: [501, 400],
+ durationRangeSec: [15, 60]
+ }
+ },
+ params: {
+ sourceId: 7560,
+ host: 'v5demo.datablocks.net',
+ video: {
+ minduration: 14
+ }
+ },
+ transactionId: '0a4e9788-4def-4b94-bc25-564d7cac99f7'
+}
+
const bidderRequest = {
auctionId: '8bfef1be-d3ac-4d18-8859-754c7b4cf017',
auctionStart: Date.now(),
biddeCode: 'datablocks',
bidderRequestId: '10c47a5fc3c41',
- bids: [bid, bid2, nativeBid],
+ bids: [bid, bid2, nativeBid, videoBid],
refererInfo: {
numIframes: 0,
reachedTop: true,
@@ -140,6 +163,18 @@ let resObject = {
crid: '177432',
cat: [],
api: []
+ }, {
+ id: '1090738575',
+ impid: '15d9012765e36f',
+ price: 25.000000,
+ cid: '12345',
+ adid: '12345',
+ crid: '123456',
+ nurl: 'http://click.v5demo.datablocks.net/m//?fcid=435235435432',
+ cat: [],
+ api: [],
+ w: 500,
+ h: 400
}]
}],
cur: 'USD',
@@ -175,6 +210,11 @@ let bidRequest = {
native: {request: '{"native":{"assets":[{"id":"1","required":true,"title":{"len":140}},{"id":"2","required":true,"data":{"type":2}},{"id":"3","img":{"w":728,"h":90,"type":3}}]}}'},
secure: false,
tagid: '/19968336/header-bid-tag-0'
+ }, {
+ id: '15d9012765e36f',
+ video: {w: 500, h: 400, minduration: 15, maxduration: 60},
+ secure: false,
+ tagid: '/19968336/header-bid-tag-0'
}],
site: {
domain: '',
@@ -198,7 +238,7 @@ describe('DatablocksAdapter', function() {
});
describe('buildRequests', function() {
- let requests = spec.buildRequests([bid, bid2, nativeBid], bidderRequest);
+ let requests = spec.buildRequests([bid, bid2, nativeBid, videoBid], bidderRequest);
it('Creates an array of request objects', function() {
expect(requests).to.be.an('array').that.is.not.empty;
});
@@ -232,6 +272,9 @@ describe('DatablocksAdapter', function() {
expect(imp.native.request).to.be.a('string');
let native = JSON.parse(imp.native.request);
expect(native).to.be.a('object');
+ } else if (imp.video) {
+ expect(imp).to.have.all.keys('video', 'id', 'secure', 'tagid');
+ expect(imp.video).to.have.all.keys('w', 'h', 'minduration', 'maxduration')
} else {
expect(true).to.equal(false);
}
@@ -276,6 +319,10 @@ describe('DatablocksAdapter', function() {
expect(dataItem.native.title).to.be.a('string');
expect(dataItem.native.body).to.be.a('string');
expect(dataItem.native.clickUrl).to.be.a('string');
+ } else if (dataItem.mediaType == 'video') {
+ expect(dataItem.vastUrl).to.be.a('string');
+ expect(dataItem.width).to.be.a('number');
+ expect(dataItem.height).to.be.a('number');
}
}
it('Returns an empty array if invalid response is passed', function() {
diff --git a/test/spec/modules/dfpAdServerVideo_spec.js b/test/spec/modules/dfpAdServerVideo_spec.js
index bd417189aef..6271c9b38f4 100644
--- a/test/spec/modules/dfpAdServerVideo_spec.js
+++ b/test/spec/modules/dfpAdServerVideo_spec.js
@@ -30,7 +30,7 @@ describe('The DFP video support module', function () {
}));
expect(url.protocol).to.equal('https:');
- expect(url.host).to.equal('pubads.g.doubleclick.net');
+ expect(url.host).to.equal('securepubads.g.doubleclick.net');
const queryParams = parseQS(url.query);
expect(queryParams).to.have.property('correlator');
@@ -374,7 +374,7 @@ describe('The DFP video support module', function () {
url = parse(masterTag);
expect(url.protocol).to.equal('https:');
- expect(url.host).to.equal('pubads.g.doubleclick.net');
+ expect(url.host).to.equal('securepubads.g.doubleclick.net');
const queryParams = parseQS(url.query);
expect(queryParams).to.have.property('correlator');
@@ -428,7 +428,7 @@ describe('The DFP video support module', function () {
}
url = parse(masterTag);
expect(url.protocol).to.equal('https:');
- expect(url.host).to.equal('pubads.g.doubleclick.net');
+ expect(url.host).to.equal('securepubads.g.doubleclick.net');
const queryParams = parseQS(url.query);
expect(queryParams).to.have.property('correlator');
diff --git a/test/spec/modules/djaxBidAdapter_spec.js b/test/spec/modules/djaxBidAdapter_spec.js
new file mode 100644
index 00000000000..82955ba43bc
--- /dev/null
+++ b/test/spec/modules/djaxBidAdapter_spec.js
@@ -0,0 +1,159 @@
+import { expect } from 'chai';
+import { spec } from 'modules/djaxBidAdapter';
+
+const ENDPOINT = 'https://demo.reviveadservermod.com/headerbidding_adminshare/www/admin/plugins/Prebid/getAd.php';
+
+describe('The Djax bidding adapter', function () {
+ describe('isBidRequestValid', function () {
+ it('should return false when given an invalid bid', function () {
+ const bid = {
+ bidder: 'djax',
+ };
+ const isValid = spec.isBidRequestValid(bid);
+ expect(isValid).to.equal(false);
+ });
+
+ it('should return true when given a publisherId in bid', function () {
+ const bid = {
+ bidder: 'djax',
+ params: {
+ publisherId: 2
+ },
+ };
+ const isValid = spec.isBidRequestValid(bid);
+ expect(isValid).to.equal(true);
+ });
+ });
+
+ describe('buildRequests', function () {
+ const bidRequests = [{
+ 'bidder': 'djax',
+ 'params': {
+ 'publisherId': 2
+ },
+ 'adUnitCode': 'adunit-code',
+ 'sizes': [
+ [300, 250],
+ [300, 600]
+ ]
+ }];
+
+ const request = spec.buildRequests(bidRequests);
+
+ it('sends bid request to our endpoint via POST', function () {
+ expect(request.method).to.equal('POST');
+ });
+
+ it('check endpoint url', function () {
+ expect(request.url).to.equal(ENDPOINT)
+ });
+
+ it('sets the proper banner object', function () {
+ expect(bidRequests[0].params.publisherId).to.equal(2);
+ })
+ });
+ const response = {
+ body: [
+ {
+ 'requestId': '2ee937f15015c6',
+ 'cpm': '0.2000',
+ 'width': 300,
+ 'height': 600,
+ 'creativeId': '4',
+ 'currency': 'USD',
+ 'netRevenue': true,
+ 'ad': 'ads.html',
+ 'mediaType': 'banner'
+ },
+ {
+ 'requestId': '3e1af92622bdc',
+ 'cpm': '0.2000',
+ 'creativeId': '4',
+ 'context': 'outstream',
+ 'currency': 'USD',
+ 'netRevenue': true,
+ 'vastUrl': 'tezt.xml',
+ 'width': 640,
+ 'height': 480,
+ 'mediaType': 'video'
+ }]
+ };
+
+ const request = [
+ {
+ 'bidder': 'djax',
+ 'params': {
+ 'publisherId': 2
+ },
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [
+ [300, 600]
+ ]
+ }
+ },
+ 'bidId': '2ee937f15015c6',
+ 'src': 'client',
+ },
+ {
+ 'bidder': 'djax',
+ 'params': {
+ 'publisherId': 2
+ },
+ 'mediaTypes': {
+ 'video': {
+ 'context': 'outstream',
+ 'playerSize': [
+ [640, 480]
+ ]
+ }
+ },
+ 'bidId': '3e1af92622bdc',
+ 'src': 'client',
+ }
+ ];
+
+ describe('interpretResponse', function () {
+ it('return empty array when no ad found', function () {
+ const response = {};
+ const request = { bidRequests: [] };
+ const bids = spec.interpretResponse(response, request);
+ expect(bids).to.have.lengthOf(0);
+ });
+
+ it('check response for banner and video', function () {
+ const bids = spec.interpretResponse(response, request);
+ expect(bids).to.have.lengthOf(2);
+ expect(bids[0].requestId).to.equal('2ee937f15015c6');
+ expect(bids[0].cpm).to.equal('0.2000');
+ expect(bids[1].cpm).to.equal('0.2000');
+ expect(bids[0].width).to.equal(300);
+ expect(bids[0].height).to.equal(600);
+ expect(bids[1].vastUrl).to.not.equal('');
+ expect(bids[0].ad).to.not.equal('');
+ expect(bids[1].adResponse).to.not.equal('');
+ expect(bids[1].renderer).not.to.be.an('undefined');
+ });
+ });
+
+ describe('On winning bid', function () {
+ const bids = spec.interpretResponse(response, request);
+ spec.onBidWon(bids);
+ });
+
+ describe('On bid Time out', function () {
+ const bids = spec.interpretResponse(response, request);
+ spec.onTimeout(bids);
+ });
+
+ describe('user sync', function () {
+ it('to check the user sync iframe', function () {
+ let syncs = spec.getUserSyncs({
+ iframeEnabled: true
+ });
+ expect(syncs).to.not.be.an('undefined');
+ expect(syncs).to.have.lengthOf(1);
+ expect(syncs[0].type).to.equal('iframe');
+ });
+ });
+});
diff --git a/test/spec/modules/emoteevBidAdapter_spec.js b/test/spec/modules/emoteevBidAdapter_spec.js
index aa97b58ec38..b6a62c16963 100644
--- a/test/spec/modules/emoteevBidAdapter_spec.js
+++ b/test/spec/modules/emoteevBidAdapter_spec.js
@@ -773,7 +773,9 @@ describe('emoteevBidAdapter', function () {
sinon.assert.notCalled(config.getConfig);
sinon.assert.notCalled(utils.getParameterByName);
});
- it('has intended side-effects', function () {
+ });
+ describe('isBidRequestValid empty request', function() {
+ it('has intended side-effects empty request', function () {
const invalidBidRequest = {};
spec.isBidRequestValid(invalidBidRequest);
sinon.assert.notCalled(utils.triggerPixel);
diff --git a/test/spec/modules/microadBidAdapter_spec.js b/test/spec/modules/microadBidAdapter_spec.js
index a6d1aa1d266..32bf15d53b9 100644
--- a/test/spec/modules/microadBidAdapter_spec.js
+++ b/test/spec/modules/microadBidAdapter_spec.js
@@ -258,6 +258,13 @@ describe('microadBidAdapter', () => {
);
});
});
+
+ it('should always use the HTTPS endpoint https://s-rtb-pb.send.microad.jp/prebid even if it is served via HTTP', () => {
+ const requests = spec.buildRequests([bidRequestTemplate], bidderRequest);
+ requests.forEach(request => {
+ expect(request.url.lastIndexOf('https', 0) === 0).to.be.true;
+ });
+ });
});
describe('interpretResponse', () => {
diff --git a/test/spec/modules/openxBidAdapter_spec.js b/test/spec/modules/openxBidAdapter_spec.js
deleted file mode 100644
index 7476d06cf9a..00000000000
--- a/test/spec/modules/openxBidAdapter_spec.js
+++ /dev/null
@@ -1,1806 +0,0 @@
-import {expect} from 'chai';
-import {spec, resetBoPixel} from 'modules/openxBidAdapter';
-import {newBidder} from 'src/adapters/bidderFactory';
-import {userSync} from 'src/userSync';
-import {config} from 'src/config';
-import * as utils from 'src/utils';
-
-const URLBASE = '/w/1.0/arj';
-const URLBASEVIDEO = '/v/1.0/avjp';
-
-describe('OpenxAdapter', function () {
- const adapter = newBidder(spec);
-
- /**
- * Type Definitions
- */
-
- /**
- * @typedef {{
- * impression: string,
- * inview: string,
- * click: string
- * }}
- */
- let OxArjTracking;
- /**
- * @typedef {{
- * ads: {
- * version: number,
- * count: number,
- * pixels: string,
- * ad: Array
- * }
- * }}
- */
- let OxArjResponse;
- /**
- * @typedef {{
- * adunitid: number,
- * adid:number,
- * type: string,
- * htmlz: string,
- * framed: number,
- * is_fallback: number,
- * ts: string,
- * cpipc: number,
- * pub_rev: string,
- * tbd: ?string,
- * adv_id: string,
- * deal_id: string,
- * auct_win_is_deal: number,
- * brand_id: string,
- * currency: string,
- * idx: string,
- * creative: Array
- * }}
- */
- let OxArjAdUnit;
- /**
- * @typedef {{
- * id: string,
- * width: string,
- * height: string,
- * target: string,
- * mime: string,
- * media: string,
- * tracking: OxArjTracking
- * }}
- */
- let OxArjCreative;
-
- // HELPER METHODS
- /**
- * @type {OxArjCreative}
- */
- const DEFAULT_TEST_ARJ_CREATIVE = {
- id: '0',
- width: 'test-width',
- height: 'test-height',
- target: 'test-target',
- mime: 'test-mime',
- media: 'test-media',
- tracking: {
- impression: 'test-impression',
- inview: 'test-inview',
- click: 'test-click'
- }
- };
-
- /**
- * @type {OxArjAdUnit}
- */
- const DEFAULT_TEST_ARJ_AD_UNIT = {
- adunitid: 0,
- type: 'test-type',
- html: 'test-html',
- framed: 0,
- is_fallback: 0,
- ts: 'test-ts',
- tbd: 'NaN',
- deal_id: undefined,
- auct_win_is_deal: undefined,
- cpipc: 0,
- pub_rev: 'test-pub_rev',
- adv_id: 'test-adv_id',
- brand_id: 'test-brand_id',
- currency: 'test-currency',
- idx: '0',
- creative: [DEFAULT_TEST_ARJ_CREATIVE]
- };
-
- /**
- * @type {OxArjResponse}
- */
- const DEFAULT_ARJ_RESPONSE = {
- ads: {
- version: 0,
- count: 1,
- pixels: 'http://testpixels.net',
- ad: [DEFAULT_TEST_ARJ_AD_UNIT]
- }
- };
-
- describe('inherited functions', function () {
- it('exists and is a function', function () {
- expect(adapter.callBids).to.exist.and.to.be.a('function');
- });
- });
-
- describe('isBidRequestValid', function () {
- describe('when request is for a banner ad', function () {
- let bannerBid;
- beforeEach(function () {
- bannerBid = {
- bidder: 'openx',
- params: {},
- adUnitCode: 'adunit-code',
- mediaTypes: {banner: {}},
- sizes: [[300, 250], [300, 600]],
- bidId: '30b31c1838de1e',
- bidderRequestId: '22edbae2733bf6',
- auctionId: '1d1a030790a475'
- };
- });
-
- it('should return false when there is no delivery domain', function () {
- bannerBid.params = {'unit': '12345678'};
- expect(spec.isBidRequestValid(bannerBid)).to.equal(false);
- });
-
- describe('when there is a delivery domain', function () {
- beforeEach(function () {
- bannerBid.params = {delDomain: 'test-delivery-domain'}
- });
-
- it('should return false when there is no ad unit id and size', function () {
- expect(spec.isBidRequestValid(bannerBid)).to.equal(false);
- });
-
- it('should return true if there is an adunit id ', function () {
- bannerBid.params.unit = '12345678';
- expect(spec.isBidRequestValid(bannerBid)).to.equal(true);
- });
-
- it('should return true if there is no adunit id and sizes are defined', function () {
- bannerBid.mediaTypes.banner.sizes = [720, 90];
- expect(spec.isBidRequestValid(bannerBid)).to.equal(true);
- });
-
- it('should return false if no sizes are defined ', function () {
- expect(spec.isBidRequestValid(bannerBid)).to.equal(false);
- });
-
- it('should return false if sizes empty ', function () {
- bannerBid.mediaTypes.banner.sizes = [];
- expect(spec.isBidRequestValid(bannerBid)).to.equal(false);
- });
- });
- });
-
- describe('when request is for a multiformat ad', function () {
- describe('and request config uses mediaTypes video and banner', () => {
- const multiformatBid = {
- bidder: 'openx',
- params: {
- unit: '12345678',
- delDomain: 'test-del-domain'
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[300, 250]]
- },
- video: {
- playerSize: [300, 250]
- }
- },
- bidId: '30b31c1838de1e',
- bidderRequestId: '22edbae2733bf6',
- auctionId: '1d1a030790a475',
- transactionId: '4008d88a-8137-410b-aa35-fbfdabcb478e'
- };
- it('should return true multisize when required params found', function () {
- expect(spec.isBidRequestValid(multiformatBid)).to.equal(true);
- });
-
- it('should send bid request to openx url via GET, with mediaType specified as banner', function () {
- const request = spec.buildRequests([multiformatBid]);
- expect(request[0].url).to.equal(`//${multiformatBid.params.delDomain}${URLBASE}`);
- expect(request[0].data.ph).to.be.undefined;
- expect(request[0].method).to.equal('GET');
- });
- });
- });
-
- describe('when request is for a video ad', function () {
- describe('and request config uses mediaTypes', () => {
- const videoBidWithMediaTypes = {
- bidder: 'openx',
- params: {
- unit: '12345678',
- delDomain: 'test-del-domain'
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- video: {
- playerSize: [640, 480]
- }
- },
- bidId: '30b31c1838de1e',
- bidderRequestId: '22edbae2733bf6',
- auctionId: '1d1a030790a475',
- transactionId: '4008d88a-8137-410b-aa35-fbfdabcb478e'
- };
- it('should return true when required params found', function () {
- expect(spec.isBidRequestValid(videoBidWithMediaTypes)).to.equal(true);
- });
-
- it('should return false when required params are not passed', function () {
- let videoBidWithMediaTypes = Object.assign({}, videoBidWithMediaTypes);
- videoBidWithMediaTypes.params = {};
- expect(spec.isBidRequestValid(videoBidWithMediaTypes)).to.equal(false);
- });
- it('should send bid request to openx url via GET, with mediaType specified as video', function () {
- const request = spec.buildRequests([videoBidWithMediaTypes]);
- expect(request[0].url).to.equal(`//${videoBidWithMediaTypes.params.delDomain}${URLBASEVIDEO}`);
- expect(request[0].data.ph).to.be.undefined;
- expect(request[0].method).to.equal('GET');
- });
- });
- describe('and request config uses both delDomain and platform', () => {
- const videoBidWithDelDomainAndPlatform = {
- bidder: 'openx',
- params: {
- unit: '12345678',
- delDomain: 'test-del-domain',
- platform: '1cabba9e-cafe-3665-beef-f00f00f00f00',
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- video: {
- playerSize: [640, 480]
- }
- },
- bidId: '30b31c1838de1e',
- bidderRequestId: '22edbae2733bf6',
- auctionId: '1d1a030790a475',
- transactionId: '4008d88a-8137-410b-aa35-fbfdabcb478e'
- };
- it('should return true when required params found', function () {
- expect(spec.isBidRequestValid(videoBidWithDelDomainAndPlatform)).to.equal(true);
- });
-
- it('should return false when required params are not passed', function () {
- let videoBidWithMediaTypes = Object.assign({}, videoBidWithDelDomainAndPlatform);
- videoBidWithMediaTypes.params = {};
- expect(spec.isBidRequestValid(videoBidWithMediaTypes)).to.equal(false);
- });
- it('should send bid request to openx url via GET, with mediaType specified as video', function () {
- const request = spec.buildRequests([videoBidWithDelDomainAndPlatform]);
- expect(request[0].url).to.equal(`//u.openx.net${URLBASEVIDEO}`);
- expect(request[0].data.ph).to.equal(videoBidWithDelDomainAndPlatform.params.platform);
- expect(request[0].method).to.equal('GET');
- });
- });
- describe('and request config uses mediaType', () => {
- const videoBidWithMediaType = {
- 'bidder': 'openx',
- 'params': {
- 'unit': '12345678',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- 'mediaType': 'video',
- 'sizes': [640, 480],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475',
- 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e'
- };
- it('should return true when required params found', function () {
- expect(spec.isBidRequestValid(videoBidWithMediaType)).to.equal(true);
- });
-
- it('should return false when required params are not passed', function () {
- let videoBidWithMediaType = Object.assign({}, videoBidWithMediaType);
- delete videoBidWithMediaType.params;
- videoBidWithMediaType.params = {};
- expect(spec.isBidRequestValid(videoBidWithMediaType)).to.equal(false);
- });
- it('should send bid request to openx url via GET, with mediaType specified as video', function () {
- const request = spec.buildRequests([videoBidWithMediaType]);
- expect(request[0].url).to.equal(`//${videoBidWithMediaType.params.delDomain}${URLBASEVIDEO}`);
- expect(request[0].data.ph).to.be.undefined;
- expect(request[0].method).to.equal('GET');
- });
- });
- });
- });
-
- describe('buildRequests for banner ads', function () {
- const bidRequestsWithMediaType = [{
- 'bidder': 'openx',
- 'params': {
- 'unit': '12345678',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- 'mediaType': 'banner',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475'
- }];
- const bidRequestsWithMediaTypes = [{
- 'bidder': 'openx',
- 'params': {
- 'unit': '11',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': '/adunit-code/test-path',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- 'bidId': 'test-bid-id-1',
- 'bidderRequestId': 'test-bid-request-1',
- 'auctionId': 'test-auction-1'
- }, {
- 'bidder': 'openx',
- 'params': {
- 'unit': '22',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[728, 90]]
- }
- },
- 'bidId': 'test-bid-id-2',
- 'bidderRequestId': 'test-bid-request-2',
- 'auctionId': 'test-auction-2'
- }];
- const bidRequestsWithPlatform = [{
- 'bidder': 'openx',
- 'params': {
- 'unit': '11',
- 'platform': '1cabba9e-cafe-3665-beef-f00f00f00f00',
- },
- 'adUnitCode': '/adunit-code/test-path',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- 'bidId': 'test-bid-id-1',
- 'bidderRequestId': 'test-bid-request-1',
- 'auctionId': 'test-auction-1'
- }, {
- 'bidder': 'openx',
- 'params': {
- 'unit': '11',
- 'platform': '1cabba9e-cafe-3665-beef-f00f00f00f00',
- },
- 'adUnitCode': '/adunit-code/test-path',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- 'bidId': 'test-bid-id-1',
- 'bidderRequestId': 'test-bid-request-1',
- 'auctionId': 'test-auction-1'
- }];
-
- it('should send bid request to openx url via GET, with mediaType specified as banner', function () {
- const request = spec.buildRequests(bidRequestsWithMediaType);
- expect(request[0].url).to.equal('//' + bidRequestsWithMediaType[0].params.delDomain + URLBASE);
- expect(request[0].data.ph).to.be.undefined;
- expect(request[0].method).to.equal('GET');
- });
-
- it('should send bid request to openx url via GET, with mediaTypes specified with banner type', function () {
- const request = spec.buildRequests(bidRequestsWithMediaTypes);
- expect(request[0].url).to.equal('//' + bidRequestsWithMediaTypes[0].params.delDomain + URLBASE);
- expect(request[0].data.ph).to.be.undefined;
- expect(request[0].method).to.equal('GET');
- });
-
- it('should send bid request to openx platform url via GET, if platform is present', function () {
- const request = spec.buildRequests(bidRequestsWithPlatform);
- expect(request[0].url).to.equal(`//u.openx.net${URLBASE}`);
- expect(request[0].data.ph).to.equal(bidRequestsWithPlatform[0].params.platform);
- expect(request[0].method).to.equal('GET');
- });
-
- it('should send bid request to openx platform url via GET, if both params present', function () {
- const bidRequestsWithPlatformAndDelDomain = [{
- 'bidder': 'openx',
- 'params': {
- 'unit': '11',
- 'delDomain': 'test-del-domain',
- 'platform': '1cabba9e-cafe-3665-beef-f00f00f00f00',
- },
- 'adUnitCode': '/adunit-code/test-path',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- 'bidId': 'test-bid-id-1',
- 'bidderRequestId': 'test-bid-request-1',
- 'auctionId': 'test-auction-1'
- }, {
- 'bidder': 'openx',
- 'params': {
- 'unit': '11',
- 'delDomain': 'test-del-domain',
- 'platform': '1cabba9e-cafe-3665-beef-f00f00f00f00',
- },
- 'adUnitCode': '/adunit-code/test-path',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- 'bidId': 'test-bid-id-1',
- 'bidderRequestId': 'test-bid-request-1',
- 'auctionId': 'test-auction-1'
- }];
-
- const request = spec.buildRequests(bidRequestsWithPlatformAndDelDomain);
- expect(request[0].url).to.equal(`//u.openx.net${URLBASE}`);
- expect(request[0].data.ph).to.equal(bidRequestsWithPlatform[0].params.platform);
- expect(request[0].method).to.equal('GET');
- });
-
- it('should send the adunit codes', function () {
- const request = spec.buildRequests(bidRequestsWithMediaTypes);
- expect(request[0].data.divIds).to.equal(`${encodeURIComponent(bidRequestsWithMediaTypes[0].adUnitCode)},${encodeURIComponent(bidRequestsWithMediaTypes[1].adUnitCode)}`);
- });
-
- it('should send ad unit ids when any are defined', function () {
- const bidRequestsWithUnitIds = [{
- 'bidder': 'openx',
- 'params': {
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- 'bidId': 'test-bid-id-1',
- 'bidderRequestId': 'test-bid-request-1',
- 'auctionId': 'test-auction-1'
- }, {
- 'bidder': 'openx',
- 'params': {
- 'unit': '22',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[728, 90]]
- }
- },
- 'bidId': 'test-bid-id-2',
- 'bidderRequestId': 'test-bid-request-2',
- 'auctionId': 'test-auction-2'
- }];
- const request = spec.buildRequests(bidRequestsWithUnitIds);
- expect(request[0].data.auid).to.equal(`,${bidRequestsWithUnitIds[1].params.unit}`);
- });
-
- it('should not send any ad unit ids when none are defined', function () {
- const bidRequestsWithoutUnitIds = [{
- 'bidder': 'openx',
- 'params': {
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- 'bidId': 'test-bid-id-1',
- 'bidderRequestId': 'test-bid-request-1',
- 'auctionId': 'test-auction-1'
- }, {
- 'bidder': 'openx',
- 'params': {
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[728, 90]]
- }
- },
- 'bidId': 'test-bid-id-2',
- 'bidderRequestId': 'test-bid-request-2',
- 'auctionId': 'test-auction-2'
- }];
- const request = spec.buildRequests(bidRequestsWithoutUnitIds);
- expect(request[0].data).to.not.have.any.keys('auid');
- });
-
- describe('when there is a legacy request with no media type', function () {
- const deprecatedBidRequestsFormatWithNoMediaType = [{
- 'bidder': 'openx',
- 'params': {
- 'unit': '12345678',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475'
- }];
-
- let requestData;
-
- beforeEach(function () {
- requestData = spec.buildRequests(deprecatedBidRequestsFormatWithNoMediaType)[0].data;
- });
-
- it('should have an ad unit id', function () {
- expect(requestData.auid).to.equal('12345678');
- });
-
- it('should have ad sizes', function () {
- expect(requestData.aus).to.equal('300x250,300x600');
- });
- });
-
- it('should send out custom params on bids that have customParams specified', function () {
- const bidRequest = Object.assign({},
- bidRequestsWithMediaTypes[0],
- {
- params: {
- 'unit': '12345678',
- 'delDomain': 'test-del-domain',
- 'customParams': {'Test1': 'testval1+', 'test2': ['testval2/', 'testval3']}
- }
- }
- );
-
- const request = spec.buildRequests([bidRequest]);
- const dataParams = request[0].data;
-
- expect(dataParams.tps).to.exist;
- expect(dataParams.tps).to.equal(btoa('test1=testval1.&test2=testval2_,testval3'));
- });
-
- it('should send out custom floors on bids that have customFloors specified', function () {
- const bidRequest = Object.assign({},
- bidRequestsWithMediaTypes[0],
- {
- params: {
- 'unit': '12345678',
- 'delDomain': 'test-del-domain',
- 'customFloor': 1.500001
- }
- }
- );
-
- const request = spec.buildRequests([bidRequest]);
- const dataParams = request[0].data;
-
- expect(dataParams.aumfs).to.exist;
- expect(dataParams.aumfs).to.equal('1500');
- });
-
- it('should send out custom bc parameter, if override is present', function () {
- const bidRequest = Object.assign({},
- bidRequestsWithMediaTypes[0],
- {
- params: {
- 'unit': '12345678',
- 'delDomain': 'test-del-domain',
- 'bc': 'hb_override'
- }
- }
- );
-
- const request = spec.buildRequests([bidRequest]);
- const dataParams = request[0].data;
-
- expect(dataParams.bc).to.exist;
- expect(dataParams.bc).to.equal('hb_override');
- });
-
- it('should not send any consent management properties', function () {
- const request = spec.buildRequests(bidRequestsWithMediaTypes);
- expect(request[0].data.gdpr).to.equal(undefined);
- expect(request[0].data.gdpr_consent).to.equal(undefined);
- expect(request[0].data.x_gdpr_f).to.equal(undefined);
- });
-
- describe('when there is a consent management framework', function () {
- let bidRequests;
- let mockConfig;
- let bidderRequest;
- const IAB_CONSENT_FRAMEWORK_CODE = 1;
-
- beforeEach(function () {
- bidRequests = [{
- bidder: 'openx',
- params: {
- unit: '12345678-banner',
- delDomain: 'test-del-domain'
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- bidId: 'test-bid-id',
- bidderRequestId: 'test-bidder-request-id',
- auctionId: 'test-auction-id'
- }, {
- 'bidder': 'openx',
- 'mediaTypes': {
- video: {
- playerSize: [640, 480]
- }
- },
- 'params': {
- 'unit': '12345678-video',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
-
- bidId: 'test-bid-id',
- bidderRequestId: 'test-bidder-request-id',
- auctionId: 'test-auction-id',
- transactionId: '4008d88a-8137-410b-aa35-fbfdabcb478e'
- }];
- });
-
- afterEach(function () {
- config.getConfig.restore();
- });
-
- describe('when GDPR applies', function () {
- beforeEach(function () {
- bidderRequest = {
- gdprConsent: {
- consentString: 'test-gdpr-consent-string',
- gdprApplies: true
- }
- };
-
- mockConfig = {
- consentManagement: {
- cmpApi: 'iab',
- timeout: 1111,
- allowAuctionWithoutConsent: 'cancel'
- }
- };
-
- sinon.stub(config, 'getConfig').callsFake((key) => {
- return utils.deepAccess(mockConfig, key);
- });
- });
-
- it('should send a signal to specify that GDPR applies to this request', function () {
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request[0].data.gdpr).to.equal(1);
- expect(request[1].data.gdpr).to.equal(1);
- });
-
- it('should send the consent string', function () {
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request[0].data.gdpr_consent).to.equal(bidderRequest.gdprConsent.consentString);
- expect(request[1].data.gdpr_consent).to.equal(bidderRequest.gdprConsent.consentString);
- });
-
- it('should send the consent management framework code', function () {
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request[0].data.x_gdpr_f).to.equal(IAB_CONSENT_FRAMEWORK_CODE);
- expect(request[1].data.x_gdpr_f).to.equal(IAB_CONSENT_FRAMEWORK_CODE);
- });
- });
-
- describe('when GDPR does not apply', function () {
- beforeEach(function () {
- bidderRequest = {
- gdprConsent: {
- consentString: 'test-gdpr-consent-string',
- gdprApplies: false
- }
- };
-
- mockConfig = {
- consentManagement: {
- cmpApi: 'iab',
- timeout: 1111,
- allowAuctionWithoutConsent: 'cancel'
- }
- };
-
- sinon.stub(config, 'getConfig').callsFake((key) => {
- return utils.deepAccess(mockConfig, key);
- });
- });
-
- it('should not send a signal to specify that GDPR does not apply to this request', function () {
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request[0].data.gdpr).to.equal(0);
- expect(request[1].data.gdpr).to.equal(0);
- });
-
- it('should send the consent string', function () {
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request[0].data.gdpr_consent).to.equal(bidderRequest.gdprConsent.consentString);
- expect(request[1].data.gdpr_consent).to.equal(bidderRequest.gdprConsent.consentString);
- });
-
- it('should send the consent management framework code', function () {
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request[0].data.x_gdpr_f).to.equal(IAB_CONSENT_FRAMEWORK_CODE);
- expect(request[1].data.x_gdpr_f).to.equal(IAB_CONSENT_FRAMEWORK_CODE);
- });
- });
-
- describe('when GDPR consent has undefined data', function () {
- beforeEach(function () {
- bidderRequest = {
- gdprConsent: {
- consentString: 'test-gdpr-consent-string',
- gdprApplies: true
- }
- };
-
- mockConfig = {
- consentManagement: {
- cmpApi: 'iab',
- timeout: 1111,
- allowAuctionWithoutConsent: 'cancel'
- }
- };
-
- sinon.stub(config, 'getConfig').callsFake((key) => {
- return utils.deepAccess(mockConfig, key);
- });
- });
-
- it('should not send a signal to specify whether GDPR applies to this request, when GDPR application is undefined', function () {
- delete bidderRequest.gdprConsent.gdprApplies;
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request[0].data).to.not.have.property('gdpr');
- expect(request[1].data).to.not.have.property('gdpr');
- });
-
- it('should not send the consent string, when consent string is undefined', function () {
- delete bidderRequest.gdprConsent.consentString;
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request[0].data).to.not.have.property('gdpr_consent');
- expect(request[1].data).to.not.have.property('gdpr_consent');
- });
-
- it('should not send the consent management framework code, when format is undefined', function () {
- delete mockConfig.consentManagement.cmpApi;
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request[0].data).to.not.have.property('x_gdpr_f');
- expect(request[1].data).to.not.have.property('x_gdpr_f');
- });
- });
- });
-
- it('should not send a coppa query param when there are no coppa param settings in the bid requests', function () {
- const bidRequestsWithoutCoppa = [{
- bidder: 'openx',
- params: {
- unit: '11',
- delDomain: 'test-del-domain',
- coppa: false
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- bidId: 'test-bid-id-1',
- bidderRequestId: 'test-bid-request-1',
- auctionId: 'test-auction-1'
- }, {
- bidder: 'openx',
- params: {
- unit: '22',
- delDomain: 'test-del-domain'
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[728, 90]]
- }
- },
- bidId: 'test-bid-id-2',
- bidderRequestId: 'test-bid-request-2',
- auctionId: 'test-auction-2'
- }];
- const request = spec.buildRequests(bidRequestsWithoutCoppa);
- expect(request[0].data).to.not.have.any.keys('tfcd');
- });
-
- it('should send a coppa flag there is when there is coppa param settings in the bid requests', function () {
- const bidRequestsWithCoppa = [{
- bidder: 'openx',
- params: {
- unit: '11',
- delDomain: 'test-del-domain',
- coppa: false
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- bidId: 'test-bid-id-1',
- bidderRequestId: 'test-bid-request-1',
- auctionId: 'test-auction-1'
- }, {
- bidder: 'openx',
- params: {
- unit: '22',
- delDomain: 'test-del-domain',
- coppa: true
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[728, 90]]
- }
- },
- bidId: 'test-bid-id-2',
- bidderRequestId: 'test-bid-request-2',
- auctionId: 'test-auction-2'
- }];
- const request = spec.buildRequests(bidRequestsWithCoppa);
- expect(request[0].data.tfcd).to.equal(1);
- });
-
- it('should not send a "no segmentation" flag there no DoNotTrack setting that is set to true', function () {
- const bidRequestsWithoutDnt = [{
- bidder: 'openx',
- params: {
- unit: '11',
- delDomain: 'test-del-domain',
- doNotTrack: false
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- bidId: 'test-bid-id-1',
- bidderRequestId: 'test-bid-request-1',
- auctionId: 'test-auction-1'
- }, {
- bidder: 'openx',
- params: {
- unit: '22',
- delDomain: 'test-del-domain'
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[728, 90]]
- }
- },
- bidId: 'test-bid-id-2',
- bidderRequestId: 'test-bid-request-2',
- auctionId: 'test-auction-2'
- }];
- const request = spec.buildRequests(bidRequestsWithoutDnt);
- expect(request[0].data).to.not.have.any.keys('ns');
- });
-
- it('should send a "no segmentation" flag there is any DoNotTrack setting that is set to true', function () {
- const bidRequestsWithDnt = [{
- bidder: 'openx',
- params: {
- unit: '11',
- delDomain: 'test-del-domain',
- doNotTrack: false
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- bidId: 'test-bid-id-1',
- bidderRequestId: 'test-bid-request-1',
- auctionId: 'test-auction-1'
- }, {
- bidder: 'openx',
- params: {
- unit: '22',
- delDomain: 'test-del-domain',
- doNotTrack: true
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[728, 90]]
- }
- },
- bidId: 'test-bid-id-2',
- bidderRequestId: 'test-bid-request-2',
- auctionId: 'test-auction-2'
- }];
- const request = spec.buildRequests(bidRequestsWithDnt);
- expect(request[0].data.ns).to.equal(1);
- });
-
- describe('publisher common id query param', function() {
- it('should not send a pubcid query param when there is no crumbs.pubcid defined in the bid requests', function () {
- const request = spec.buildRequests(bidRequestsWithMediaType);
- expect(request[0].data).to.not.have.any.keys('pubcid');
- });
-
- it('should send a pubcid query param when crumbs.pubcid is defined in the bid requests', function () {
- const bidRequestsWithPubcid = [{
- bidder: 'openx',
- params: {
- unit: '11',
- delDomain: 'test-del-domain'
- },
- crumbs: {
- pubcid: 'c4a4c843-2368-4b5e-b3b1-6ee4702b9ad6'
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- bidId: 'test-bid-id-1',
- bidderRequestId: 'test-bid-request-1',
- auctionId: 'test-auction-1'
- }];
- const request = spec.buildRequests(bidRequestsWithPubcid);
- expect(request[0].data.pubcid).to.equal('c4a4c843-2368-4b5e-b3b1-6ee4702b9ad6');
- });
-
- it('should send a pubcid query param when userId.pubcid is defined in the bid requests', function () {
- const bidRequestsWithPubcid = [{
- bidder: 'openx',
- params: {
- unit: '11',
- delDomain: 'test-del-domain'
- },
- userId: {
- pubcid: 'c1a4c843-2368-4b5e-b3b1-6ee4702b9ad6'
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- bidId: 'test-bid-id-1',
- bidderRequestId: 'test-bid-request-1',
- auctionId: 'test-auction-1'
- }];
- const request = spec.buildRequests(bidRequestsWithPubcid);
- expect(request[0].data.pubcid).to.equal('c1a4c843-2368-4b5e-b3b1-6ee4702b9ad6');
- });
- })
-
- describe('when schain is provided', function () {
- let bidRequests;
- let schainConfig;
- const supplyChainNodePropertyOrder = ['asi', 'sid', 'hp', 'rid', 'name', 'domain'];
-
- beforeEach(function () {
- schainConfig = {
- 'ver': '1.0',
- 'complete': 1,
- 'nodes': [
- {
- 'asi': 'exchange1.com',
- 'sid': '1234',
- 'hp': 1,
- 'rid': 'bid-request-1',
- 'name': 'publisher',
- 'domain': 'publisher.com'
- // omitted ext
- },
- {
- 'asi': 'exchange2.com',
- 'sid': 'abcd',
- 'hp': 1,
- 'rid': 'bid-request-2',
- // name field missing
- 'domain': 'intermediary.com'
- },
- {
- 'asi': 'exchange3.com',
- 'sid': '4321',
- 'hp': 1,
- // request id
- // name field missing
- 'domain': 'intermediary-2.com'
- }
- ]
- };
-
- bidRequests = [{
- 'bidder': 'openx',
- 'params': {
- 'unit': '11',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': '/adunit-code/test-path',
- mediaTypes: {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- 'bidId': 'test-bid-id-1',
- 'bidderRequestId': 'test-bid-request-1',
- 'auctionId': 'test-auction-1',
- 'schain': schainConfig
- }];
- });
-
- it('should send a schain parameter with the proper delimiter symbols', function () {
- const request = spec.buildRequests(bidRequests);
- const dataParams = request[0].data;
- const numNodes = schainConfig.nodes.length;
-
- // each node will have a ! to denote beginning of a new node
- expect(dataParams.schain.match(/!/g).length).to.equal(numNodes);
-
- // 1 comma in the front for version
- // 5 commas per node
- expect(dataParams.schain.match(/,/g).length).to.equal(numNodes * 5 + 1);
- });
-
- it('should send a schain with the right version', function () {
- const request = spec.buildRequests(bidRequests);
- const dataParams = request[0].data;
- let serializedSupplyChain = dataParams.schain.split('!');
- let version = serializedSupplyChain.shift().split(',')[0];
-
- expect(version).to.equal(bidRequests[0].schain.ver);
- });
-
- it('should send a schain with the right complete value', function () {
- const request = spec.buildRequests(bidRequests);
- const dataParams = request[0].data;
- let serializedSupplyChain = dataParams.schain.split('!');
- let isComplete = serializedSupplyChain.shift().split(',')[1];
-
- expect(isComplete).to.equal(String(bidRequests[0].schain.complete));
- });
-
- it('should send all available params in the right order', function () {
- const request = spec.buildRequests(bidRequests);
- const dataParams = request[0].data;
- let serializedSupplyChain = dataParams.schain.split('!');
- serializedSupplyChain.shift();
-
- serializedSupplyChain.forEach((serializedNode, nodeIndex) => {
- let nodeProperties = serializedNode.split(',');
-
- nodeProperties.forEach((nodeProperty, propertyIndex) => {
- let node = schainConfig.nodes[nodeIndex];
- let key = supplyChainNodePropertyOrder[propertyIndex];
-
- expect(nodeProperty).to.equal(node[key] ? String(node[key]) : '',
- `expected node '${nodeIndex}' property '${nodeProperty}' to key '${key}' to be the same value`)
- });
- });
- });
- });
- });
-
- describe('buildRequests for video', function () {
- const bidRequestsWithMediaTypes = [{
- 'bidder': 'openx',
- 'mediaTypes': {
- video: {
- playerSize: [640, 480]
- }
- },
- 'params': {
- 'unit': '12345678',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
-
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475',
- 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e'
- }];
-
- const bidRequestsWithMediaType = [{
- 'bidder': 'openx',
- 'mediaType': 'video',
- 'params': {
- 'unit': '12345678',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- 'sizes': [640, 480],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475',
- 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e'
- }];
-
- it('should send bid request to openx url via GET, with mediaType as video', function () {
- const request = spec.buildRequests(bidRequestsWithMediaType);
- expect(request[0].url).to.equal('//' + bidRequestsWithMediaType[0].params.delDomain + URLBASEVIDEO);
- expect(request[0].method).to.equal('GET');
- });
-
- it('should send bid request to openx url via GET, with mediaTypes having video parameter', function () {
- const request = spec.buildRequests(bidRequestsWithMediaTypes);
- expect(request[0].url).to.equal('//' + bidRequestsWithMediaTypes[0].params.delDomain + URLBASEVIDEO);
- expect(request[0].method).to.equal('GET');
- });
-
- it('should have the correct parameters', function () {
- const request = spec.buildRequests(bidRequestsWithMediaTypes);
- const dataParams = request[0].data;
-
- expect(dataParams.auid).to.equal('12345678');
- expect(dataParams.vht).to.equal(480);
- expect(dataParams.vwd).to.equal(640);
- });
-
- it('should send a bc parameter', function () {
- const request = spec.buildRequests(bidRequestsWithMediaTypes);
- const dataParams = request[0].data;
-
- expect(dataParams.bc).to.have.string('hb_pb');
- });
-
- describe('when using the video param', function () {
- let videoBidRequest;
-
- beforeEach(function () {
- videoBidRequest = {
- 'bidder': 'openx',
- 'mediaTypes': {
- video: {
- context: 'instream',
- playerSize: [640, 480]
- }
- },
- 'params': {
- 'unit': '12345678',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475',
- 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e'
- }
- });
-
- it('should not allow you to set a url', function () {
- videoBidRequest.params.video = {
- url: 'test-url'
- };
- const request = spec.buildRequests([videoBidRequest]);
-
- expect(request[0].data.url).to.be.undefined;
- });
-
- it('should not allow you to override the javascript url', function () {
- let myUrl = 'my-url';
- videoBidRequest.params.video = {
- ju: myUrl
- };
- const request = spec.buildRequests([videoBidRequest]);
-
- expect(request[0].data.ju).to.not.equal(myUrl);
- });
-
- describe('when using the openRtb param', function () {
- it('should covert the param to a JSON string', function () {
- let myOpenRTBObject = {};
- videoBidRequest.params.video = {
- openrtb: myOpenRTBObject
- };
- const request = spec.buildRequests([videoBidRequest]);
-
- expect(request[0].data.openrtb).to.equal(JSON.stringify(myOpenRTBObject));
- });
-
- it("should use the bidRequest's playerSize when it is available", function () {
- const width = 200;
- const height = 100;
- const myOpenRTBObject = {v: height, w: width};
- videoBidRequest.params.video = {
- openrtb: myOpenRTBObject
- };
- const request = spec.buildRequests([videoBidRequest]);
- const openRtbRequestParams = JSON.parse(request[0].data.openrtb);
-
- expect(openRtbRequestParams.w).to.not.equal(width);
- expect(openRtbRequestParams.v).to.not.equal(height);
- });
-
- it('should use the the openRTB\'s sizing when the bidRequest\'s playerSize is not available', function () {
- const width = 200;
- const height = 100;
- const myOpenRTBObject = {v: height, w: width};
- videoBidRequest.params.video = {
- openrtb: myOpenRTBObject
- };
- videoBidRequest.mediaTypes.video.playerSize = undefined;
-
- const request = spec.buildRequests([videoBidRequest]);
- const openRtbRequestParams = JSON.parse(request[0].data.openrtb);
-
- expect(openRtbRequestParams.w).to.equal(width);
- expect(openRtbRequestParams.v).to.equal(height);
- });
- });
- });
- });
-
- describe('interpretResponse for banner ads', function () {
- beforeEach(function () {
- sinon.spy(userSync, 'registerSync');
- });
-
- afterEach(function () {
- userSync.registerSync.restore();
- });
-
- describe('when there is a standard response', function () {
- const creativeOverride = {
- id: 234,
- width: '300',
- height: '250',
- tracking: {
- impression: 'http://openx-d.openx.net/v/1.0/ri?ts=ts'
- }
- };
-
- const adUnitOverride = {
- ts: 'test-1234567890-ts',
- idx: '0',
- currency: 'USD',
- pub_rev: '10000',
- html: 'OpenX Ad
'
- };
- let adUnit;
- let bidResponse;
-
- let bid;
- let bidRequest;
- let bidRequestConfigs;
-
- beforeEach(function () {
- bidRequestConfigs = [{
- 'bidder': 'openx',
- 'params': {
- 'unit': '12345678',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- 'mediaType': 'banner',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475'
- }];
-
- bidRequest = {
- method: 'GET',
- url: '//openx-d.openx.net/v/1.0/arj',
- data: {},
- payload: {'bids': bidRequestConfigs, 'startTime': new Date()}
- };
-
- adUnit = mockAdUnit(adUnitOverride, creativeOverride);
- bidResponse = mockArjResponse(undefined, [adUnit]);
- bid = spec.interpretResponse({body: bidResponse}, bidRequest)[0];
- });
-
- it('should return a price', function () {
- expect(bid.cpm).to.equal(parseInt(adUnitOverride.pub_rev, 10) / 1000);
- });
-
- it('should return a request id', function () {
- expect(bid.requestId).to.equal(bidRequest.payload.bids[0].bidId);
- });
-
- it('should return width and height for the creative', function () {
- expect(bid.width).to.equal(creativeOverride.width);
- expect(bid.height).to.equal(creativeOverride.height);
- });
-
- it('should return a creativeId', function () {
- expect(bid.creativeId).to.equal(creativeOverride.id);
- });
-
- it('should return an ad', function () {
- expect(bid.ad).to.equal(adUnitOverride.html);
- });
-
- it('should have a time-to-live of 5 minutes', function () {
- expect(bid.ttl).to.equal(300);
- });
-
- it('should always return net revenue', function () {
- expect(bid.netRevenue).to.equal(true);
- });
-
- it('should return a currency', function () {
- expect(bid.currency).to.equal(adUnitOverride.currency);
- });
-
- it('should return a transaction state', function () {
- expect(bid.ts).to.equal(adUnitOverride.ts);
- });
-
- it('should return a brand ID', function () {
- expect(bid.meta.brandId).to.equal(DEFAULT_TEST_ARJ_AD_UNIT.brand_id);
- });
-
- it('should return a brand ID', function () {
- expect(bid.meta.dspid).to.equal(DEFAULT_TEST_ARJ_AD_UNIT.adv_id);
- });
-
- it('should register a beacon', function () {
- resetBoPixel();
- spec.interpretResponse({body: bidResponse}, bidRequest);
- sinon.assert.calledWith(userSync.registerSync, 'image', 'openx', sinon.match(new RegExp(`\/\/openx-d\.openx\.net.*\/bo\?.*ts=${adUnitOverride.ts}`)));
- });
- });
-
- describe('when there is a deal', function () {
- const adUnitOverride = {
- deal_id: 'ox-1000'
- };
- let adUnit;
- let bidResponse;
-
- let bid;
- let bidRequestConfigs;
- let bidRequest;
-
- beforeEach(function () {
- bidRequestConfigs = [{
- 'bidder': 'openx',
- 'params': {
- 'unit': '12345678',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- 'mediaType': 'banner',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475'
- }];
-
- bidRequest = {
- method: 'GET',
- url: '//openx-d.openx.net/v/1.0/arj',
- data: {},
- payload: {'bids': bidRequestConfigs, 'startTime': new Date()}
- };
- adUnit = mockAdUnit(adUnitOverride);
- bidResponse = mockArjResponse(null, [adUnit]);
- bid = spec.interpretResponse({body: bidResponse}, bidRequest)[0];
- mockArjResponse();
- });
-
- it('should return a deal id', function () {
- expect(bid.dealId).to.equal(adUnitOverride.deal_id);
- });
- });
-
- describe('when there is no bids in the response', function () {
- let bidRequest;
- let bidRequestConfigs;
-
- beforeEach(function () {
- bidRequestConfigs = [{
- 'bidder': 'openx',
- 'params': {
- 'unit': '12345678',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- 'mediaType': 'banner',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475'
- }];
-
- bidRequest = {
- method: 'GET',
- url: '//openx-d.openx.net/v/1.0/arj',
- data: {},
- payload: {'bids': bidRequestConfigs, 'startTime': new Date()}
- };
- });
-
- it('handles nobid responses', function () {
- const bidResponse = {
- 'ads':
- {
- 'version': 1,
- 'count': 1,
- 'pixels': 'http://testpixels.net',
- 'ad': []
- }
- };
-
- const result = spec.interpretResponse({body: bidResponse}, bidRequest);
- expect(result.length).to.equal(0);
- });
- });
-
- describe('when adunits return out of order', function () {
- const bidRequests = [{
- bidder: 'openx',
- params: {
- unit: '12345678',
- delDomain: 'test-del-domain'
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[100, 111]]
- }
- },
- bidId: 'test-bid-request-id-1',
- bidderRequestId: 'test-request-1',
- auctionId: 'test-auction-id-1'
- }, {
- bidder: 'openx',
- params: {
- unit: '12345678',
- delDomain: 'test-del-domain'
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[200, 222]]
- }
- },
- bidId: 'test-bid-request-id-2',
- bidderRequestId: 'test-request-1',
- auctionId: 'test-auction-id-1'
- }, {
- bidder: 'openx',
- params: {
- unit: '12345678',
- delDomain: 'test-del-domain'
- },
- adUnitCode: 'adunit-code',
- mediaTypes: {
- banner: {
- sizes: [[300, 333]]
- }
- },
- 'bidId': 'test-bid-request-id-3',
- 'bidderRequestId': 'test-request-1',
- 'auctionId': 'test-auction-id-1'
- }];
- const bidRequest = {
- method: 'GET',
- url: '//openx-d.openx.net/v/1.0/arj',
- data: {},
- payload: {'bids': bidRequests, 'startTime': new Date()}
- };
-
- let outOfOrderAdunits = [
- mockAdUnit({
- idx: '1'
- }, {
- width: bidRequests[1].mediaTypes.banner.sizes[0][0],
- height: bidRequests[1].mediaTypes.banner.sizes[0][1]
- }),
- mockAdUnit({
- idx: '2'
- }, {
- width: bidRequests[2].mediaTypes.banner.sizes[0][0],
- height: bidRequests[2].mediaTypes.banner.sizes[0][1]
- }),
- mockAdUnit({
- idx: '0'
- }, {
- width: bidRequests[0].mediaTypes.banner.sizes[0][0],
- height: bidRequests[0].mediaTypes.banner.sizes[0][1]
- })
- ];
-
- let bidResponse = mockArjResponse(undefined, outOfOrderAdunits);
-
- it('should return map adunits back to the proper request', function () {
- const bids = spec.interpretResponse({body: bidResponse}, bidRequest);
- expect(bids[0].requestId).to.equal(bidRequests[1].bidId);
- expect(bids[0].width).to.equal(bidRequests[1].mediaTypes.banner.sizes[0][0]);
- expect(bids[0].height).to.equal(bidRequests[1].mediaTypes.banner.sizes[0][1]);
- expect(bids[1].requestId).to.equal(bidRequests[2].bidId);
- expect(bids[1].width).to.equal(bidRequests[2].mediaTypes.banner.sizes[0][0]);
- expect(bids[1].height).to.equal(bidRequests[2].mediaTypes.banner.sizes[0][1]);
- expect(bids[2].requestId).to.equal(bidRequests[0].bidId);
- expect(bids[2].width).to.equal(bidRequests[0].mediaTypes.banner.sizes[0][0]);
- expect(bids[2].height).to.equal(bidRequests[0].mediaTypes.banner.sizes[0][1]);
- });
- });
- });
-
- describe('interpretResponse for video ads', function () {
- beforeEach(function () {
- sinon.spy(userSync, 'registerSync');
- });
-
- afterEach(function () {
- userSync.registerSync.restore();
- });
-
- const bidsWithMediaTypes = [{
- 'bidder': 'openx',
- 'mediaTypes': {video: {}},
- 'params': {
- 'unit': '12345678',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- 'sizes': [640, 480],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475',
- 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e'
- }];
- const bidsWithMediaType = [{
- 'bidder': 'openx',
- 'mediaType': 'video',
- 'params': {
- 'unit': '12345678',
- 'delDomain': 'test-del-domain'
- },
- 'adUnitCode': 'adunit-code',
- 'sizes': [640, 480],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475',
- 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e'
- }];
- const bidRequestsWithMediaTypes = {
- method: 'GET',
- url: '//openx-d.openx.net/v/1.0/avjp',
- data: {},
- payload: {'bid': bidsWithMediaTypes[0], 'startTime': new Date()}
- };
- const bidRequestsWithMediaType = {
- method: 'GET',
- url: '//openx-d.openx.net/v/1.0/avjp',
- data: {},
- payload: {'bid': bidsWithMediaType[0], 'startTime': new Date()}
- };
- const bidResponse = {
- 'pub_rev': '1',
- 'width': '640',
- 'height': '480',
- 'adid': '5678',
- 'vastUrl': 'http://testvast.com/vastpath?colo=http://test-colo.com&ph=test-ph&ts=test-ts',
- 'pixels': 'http://testpixels.net'
- };
-
- it('should return correct bid response with MediaTypes', function () {
- const expectedResponse = [
- {
- 'requestId': '30b31c1838de1e',
- 'cpm': 1,
- 'width': '640',
- 'height': '480',
- 'mediaType': 'video',
- 'creativeId': '5678',
- 'vastUrl': 'http://testvast.com',
- 'ttl': 300,
- 'netRevenue': true,
- 'currency': 'USD'
- }
- ];
-
- const result = spec.interpretResponse({body: bidResponse}, bidRequestsWithMediaTypes);
- expect(JSON.stringify(Object.keys(result[0]).sort())).to.eql(JSON.stringify(Object.keys(expectedResponse[0]).sort()));
- });
-
- it('should return correct bid response with MediaType', function () {
- const expectedResponse = [
- {
- 'requestId': '30b31c1838de1e',
- 'cpm': 1,
- 'width': '640',
- 'height': '480',
- 'mediaType': 'video',
- 'creativeId': '5678',
- 'vastUrl': 'http://testvast.com',
- 'ttl': 300,
- 'netRevenue': true,
- 'currency': 'USD'
- }
- ];
-
- const result = spec.interpretResponse({body: bidResponse}, bidRequestsWithMediaType);
- expect(JSON.stringify(Object.keys(result[0]).sort())).to.eql(JSON.stringify(Object.keys(expectedResponse[0]).sort()));
- });
-
- it('should handle nobid responses for bidRequests with MediaTypes', function () {
- const bidResponse = {'vastUrl': '', 'pub_rev': '', 'width': '', 'height': '', 'adid': '', 'pixels': ''};
- const result = spec.interpretResponse({body: bidResponse}, bidRequestsWithMediaTypes);
- expect(result.length).to.equal(0);
- });
-
- it('should handle nobid responses for bidRequests with MediaType', function () {
- const bidResponse = {'vastUrl': '', 'pub_rev': '', 'width': '', 'height': '', 'adid': '', 'pixels': ''};
- const result = spec.interpretResponse({body: bidResponse}, bidRequestsWithMediaType);
- expect(result.length).to.equal(0);
- });
-
- it('should register a beacon', function () {
- resetBoPixel();
- spec.interpretResponse({body: bidResponse}, bidRequestsWithMediaTypes);
- sinon.assert.calledWith(userSync.registerSync, 'image', 'openx', sinon.match(/^\/\/test-colo\.com/))
- sinon.assert.calledWith(userSync.registerSync, 'image', 'openx', sinon.match(/ph=test-ph/));
- sinon.assert.calledWith(userSync.registerSync, 'image', 'openx', sinon.match(/ts=test-ts/));
- });
- });
-
- describe('user sync', function () {
- const syncUrl = 'http://testpixels.net';
-
- describe('iframe sync', function () {
- it('should register the pixel iframe from banner ad response', function () {
- let syncs = spec.getUserSyncs(
- {iframeEnabled: true},
- [{body: {ads: {pixels: syncUrl}}}]
- );
- expect(syncs).to.deep.equal([{type: 'iframe', url: syncUrl}]);
- });
-
- it('should register the pixel iframe from video ad response', function () {
- let syncs = spec.getUserSyncs(
- {iframeEnabled: true},
- [{body: {pixels: syncUrl}}]
- );
- expect(syncs).to.deep.equal([{type: 'iframe', url: syncUrl}]);
- });
-
- it('should register the default iframe if no pixels available', function () {
- let syncs = spec.getUserSyncs(
- {iframeEnabled: true},
- []
- );
- expect(syncs).to.deep.equal([{type: 'iframe', url: '//u.openx.net/w/1.0/pd'}]);
- });
- });
-
- describe('pixel sync', function () {
- it('should register the image pixel from banner ad response', function () {
- let syncs = spec.getUserSyncs(
- {pixelEnabled: true},
- [{body: {ads: {pixels: syncUrl}}}]
- );
- expect(syncs).to.deep.equal([{type: 'image', url: syncUrl}]);
- });
-
- it('should register the image pixel from video ad response', function () {
- let syncs = spec.getUserSyncs(
- {pixelEnabled: true},
- [{body: {pixels: syncUrl}}]
- );
- expect(syncs).to.deep.equal([{type: 'image', url: syncUrl}]);
- });
-
- it('should register the default image pixel if no pixels available', function () {
- let syncs = spec.getUserSyncs(
- {pixelEnabled: true},
- []
- );
- expect(syncs).to.deep.equal([{type: 'image', url: '//u.openx.net/w/1.0/pd'}]);
- });
- });
-
- it('should prioritize iframe over image for user sync', function () {
- let syncs = spec.getUserSyncs(
- {iframeEnabled: true, pixelEnabled: true},
- [{body: {ads: {pixels: syncUrl}}}]
- );
- expect(syncs).to.deep.equal([{type: 'iframe', url: syncUrl}]);
- });
- });
-
- /**
- * Makes sure the override object does not introduce
- * new fields against the contract
- *
- * This does a shallow check in order to make key checking simple
- * with respect to what a helper handles. For helpers that have
- * nested fields, either check your design on maybe breaking it up
- * to smaller, manageable pieces
- *
- * OR just call this on your nth level field if necessary.
- *
- * @param {Object} override Object with keys that overrides the default
- * @param {Object} contract Original object contains the default fields
- * @param {string} typeName Name of the type we're checking for error messages
- * @throws {AssertionError}
- */
- function overrideKeyCheck(override, contract, typeName) {
- expect(contract).to.include.all.keys(Object.keys(override));
- }
-
- /**
- * Creates a mock ArjResponse
- * @param {OxArjResponse=} response
- * @param {Array=} adUnits
- * @throws {AssertionError}
- * @return {OxArjResponse}
- */
- function mockArjResponse(response, adUnits = []) {
- let mockedArjResponse = utils.deepClone(DEFAULT_ARJ_RESPONSE);
-
- if (response) {
- overrideKeyCheck(response, DEFAULT_ARJ_RESPONSE, 'OxArjResponse');
- overrideKeyCheck(response.ads, DEFAULT_ARJ_RESPONSE.ads, 'OxArjResponse');
- Object.assign(mockedArjResponse, response);
- }
-
- if (adUnits.length) {
- mockedArjResponse.ads.count = adUnits.length;
- mockedArjResponse.ads.ad = adUnits.map((adUnit, index) => {
- overrideKeyCheck(adUnit, DEFAULT_TEST_ARJ_AD_UNIT, 'OxArjAdUnit');
- return Object.assign(utils.deepClone(DEFAULT_TEST_ARJ_AD_UNIT), adUnit);
- });
- }
-
- return mockedArjResponse;
- }
-
- /**
- * Creates a mock ArjAdUnit
- * @param {OxArjAdUnit=} adUnit
- * @param {OxArjCreative=} creative
- * @throws {AssertionError}
- * @return {OxArjAdUnit}
- */
- function mockAdUnit(adUnit, creative) {
- overrideKeyCheck(adUnit, DEFAULT_TEST_ARJ_AD_UNIT, 'OxArjAdUnit');
-
- let mockedAdUnit = Object.assign(utils.deepClone(DEFAULT_TEST_ARJ_AD_UNIT), adUnit);
-
- if (creative) {
- overrideKeyCheck(creative, DEFAULT_TEST_ARJ_CREATIVE);
- if (creative.tracking) {
- overrideKeyCheck(creative.tracking, DEFAULT_TEST_ARJ_CREATIVE.tracking, 'OxArjCreative');
- }
- Object.assign(mockedAdUnit.creative[0], creative);
- }
-
- return mockedAdUnit;
- }
-});
diff --git a/test/spec/modules/pubCommonId_spec.js b/test/spec/modules/pubCommonId_spec.js
index fb4a58377c3..fd2bff5bac6 100644
--- a/test/spec/modules/pubCommonId_spec.js
+++ b/test/spec/modules/pubCommonId_spec.js
@@ -15,6 +15,9 @@ import * as auctionModule from 'src/auction';
import { registerBidder } from 'src/adapters/bidderFactory';
import * as utils from 'src/utils';
+let events = require('src/events');
+let constants = require('src/constants.json');
+
var assert = require('chai').assert;
var expect = require('chai').expect;
@@ -231,13 +234,13 @@ describe('Publisher Common ID', function () {
});
});
- it('read only', function() {
+ it('disable auto create', function() {
setConfig({
- readOnly: true
+ create: false
});
const config = getPubcidConfig();
- expect(config.readOnly).to.be.true;
+ expect(config.create).to.be.false;
expect(config.typeEnabled).to.equal('html5');
let adUnits = getAdUnits();
@@ -335,4 +338,33 @@ describe('Publisher Common ID', function () {
expect(localStorage.getItem(key)).to.be.null;
});
});
+
+ describe('event callback', () => {
+ beforeEach(() => {
+ setConfig();
+ cleanUp();
+ sinon.stub(events, 'getEvents').returns([]);
+ sinon.stub(utils, 'triggerPixel');
+ });
+ afterEach(() => {
+ setConfig();
+ cleanUp();
+ events.getEvents.restore();
+ utils.triggerPixel.restore();
+ });
+ it('auction end trigger', () => {
+ setConfig({
+ pixelUrl: '/any/url'
+ });
+
+ let adUnits = getAdUnits();
+ let innerAdUnits;
+ requestBidHook((config) => { innerAdUnits = config.adUnits }, {adUnits});
+
+ expect(utils.triggerPixel.called).to.be.false;
+ events.emit(constants.EVENTS.AUCTION_END, {});
+ expect(utils.triggerPixel.called).to.be.true;
+ expect(utils.triggerPixel.getCall(0).args[0]).to.include('/any/url');
+ });
+ });
});
diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js
deleted file mode 100644
index 3de83c56213..00000000000
--- a/test/spec/modules/pubmaticBidAdapter_spec.js
+++ /dev/null
@@ -1,2118 +0,0 @@
-import {expect} from 'chai';
-import {spec} from 'modules/pubmaticBidAdapter';
-import * as utils from 'src/utils';
-import {config} from 'src/config';
-const constants = require('src/constants.json');
-
-describe('PubMatic adapter', function () {
- let bidRequests;
- let videoBidRequests;
- let multipleMediaRequests;
- let bidResponses;
- let nativeBidRequests;
- let nativeBidRequestsWithAllParams;
- let nativeBidRequestsWithoutAsset;
- let nativeBidRequestsWithRequiredParam;
- let nativeBidResponse;
- let validnativeBidImpression;
- let validnativeBidImpressionWithRequiredParam;
- let nativeBidImpressionWithoutRequiredParams;
- let validnativeBidImpressionWithAllParams;
- let bannerAndVideoBidRequests;
- let bannerAndNativeBidRequests;
- let videoAndNativeBidRequests;
- let bannerVideoAndNativeBidRequests;
- let bannerBidResponse;
- let videoBidResponse;
- let schainConfig;
-
- beforeEach(function () {
- schainConfig = {
- 'ver': '1.0',
- 'complete': 1,
- 'nodes': [
- {
- 'asi': 'indirectseller.com',
- 'sid': '00001',
- 'hp': 1
- },
-
- {
- 'asi': 'indirectseller-2.com',
- 'sid': '00002',
- 'hp': 2
- }
- ]
- };
-
- bidRequests = [
- {
- bidder: 'pubmatic',
- mediaTypes: {
- banner: {
- sizes: [[728, 90], [160, 600]]
- }
- },
- params: {
- publisherId: '301',
- adSlot: '/15671365/DMDemo@300x250:0',
- kadfloor: '1.2',
- pmzoneid: 'aabc, ddef',
- kadpageurl: 'www.publisher.com',
- yob: '1986',
- gender: 'M',
- lat: '12.3',
- lon: '23.7',
- wiid: '1234567890',
- profId: '100',
- verId: '200',
- currency: 'AUD',
- dctr: 'key1:val1,val2|key2:val1'
- },
- placementCode: '/19968336/header-bid-tag-1',
- sizes: [[300, 250], [300, 600]],
- bidId: '23acc48ad47af5',
- requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
- bidderRequestId: '1c56ad30b9b8ca8',
- transactionId: '92489f71-1bf2-49a0-adf9-000cea934729',
- schain: schainConfig
- }
- ];
-
- videoBidRequests =
- [
- {
- code: 'video1',
- mediaTypes: {
- video: {
- playerSize: [640, 480],
- context: 'instream'
- }
- },
- bidder: 'pubmatic',
- bidId: '22bddb28db77d',
- params: {
- publisherId: '5890',
- adSlot: 'Div1@0x0', // ad_id or tagid
- video: {
- mimes: ['video/mp4', 'video/x-flv'],
- skippable: true,
- minduration: 5,
- maxduration: 30,
- startdelay: 5,
- playbackmethod: [1, 3],
- api: [1, 2],
- protocols: [2, 3],
- battr: [13, 14],
- linearity: 1,
- placement: 2,
- minbitrate: 10,
- maxbitrate: 10
- }
- }
- }
- ];
-
- multipleMediaRequests = [
- {
- bidder: 'pubmatic',
- params: {
- publisherId: '301',
- adSlot: '/15671365/DMDemo@300x250:0',
- kadfloor: '1.2',
- pmzoneid: 'aabc, ddef',
- kadpageurl: 'www.publisher.com',
- yob: '1986',
- gender: 'M',
- lat: '12.3',
- lon: '23.7',
- wiid: '1234567890',
- profId: '100',
- verId: '200'
- }
- },
- {
- code: 'div-instream',
- mediaTypes: {
- video: {
- context: 'instream',
- playerSize: [300, 250]
- },
- },
- bidder: 'pubmatic',
- params: {
- publisherId: '5890',
- adSlot: 'Div1@640x480', // ad_id or tagid
- video: {
- mimes: ['video/mp4', 'video/x-flv'],
- skippable: true,
- minduration: 5,
- maxduration: 30,
- startdelay: 15,
- playbackmethod: [1, 3],
- api: [1, 2],
- protocols: [2, 3],
- w: 640,
- h: 480,
- battr: [13, 14],
- linearity: 1,
- placement: 2,
- minbitrate: 100,
- maxbitrate: 4096
- }
- }
- }
- ];
-
- nativeBidRequests = [{
- code: '/19968336/prebid_native_example_1',
- sizes: [
- [300, 250]
- ],
- mediaTypes: {
- native: {
- title: {
- required: true,
- length: 80
- },
- image: {
- required: true,
- sizes: [300, 250]
- },
- sponsoredBy: {
- required: true
- }
- }
- },
- nativeParams: {
- title: { required: true, length: 80 },
- image: { required: true, sizes: [300, 250] },
- sponsoredBy: { required: true }
- },
- bidder: 'pubmatic',
- params: {
- publisherId: '5670',
- adSlot: '/43743431/NativeAutomationPrebid@1x1',
- },
- bidId: '2a5571261281d4',
- requestId: 'B68287E1-DC39-4B38-9790-FE4F179739D6',
- bidderRequestId: '1c56ad30b9b8ca8',
- }];
-
- nativeBidRequestsWithAllParams = [{
- code: '/19968336/prebid_native_example_1',
- sizes: [
- [300, 250]
- ],
- mediaTypes: {
- native: {
- title: {required: true, len: 80, ext: {'title1': 'title2'}},
- icon: {required: true, sizes: [50, 50], ext: {'icon1': 'icon2'}},
- image: {required: true, sizes: [728, 90], ext: {'image1': 'image2'}, 'mimes': ['image/png', 'image/gif']},
- sponsoredBy: {required: true, len: 10, ext: {'sponsor1': 'sponsor2'}},
- body: {required: true, len: 10, ext: {'body1': 'body2'}},
- rating: {required: true, len: 10, ext: {'rating1': 'rating2'}},
- likes: {required: true, len: 10, ext: {'likes1': 'likes2'}},
- downloads: {required: true, len: 10, ext: {'downloads1': 'downloads2'}},
- price: {required: true, len: 10, ext: {'price1': 'price2'}},
- saleprice: {required: true, len: 10, ext: {'saleprice1': 'saleprice2'}},
- phone: {required: true, len: 10, ext: {'phone1': 'phone2'}},
- address: {required: true, len: 10, ext: {'address1': 'address2'}},
- desc2: {required: true, len: 10, ext: {'desc21': 'desc22'}},
- displayurl: {required: true, len: 10, ext: {'displayurl1': 'displayurl2'}}
- }
- },
- nativeParams: {
- title: {required: true, len: 80, ext: {'title1': 'title2'}},
- icon: {required: true, sizes: [50, 50], ext: {'icon1': 'icon2'}},
- image: {required: true, sizes: [728, 90], ext: {'image1': 'image2'}, 'mimes': ['image/png', 'image/gif']},
- sponsoredBy: {required: true, len: 10, ext: {'sponsor1': 'sponsor2'}},
- body: {required: true, len: 10, ext: {'body1': 'body2'}},
- rating: {required: true, len: 10, ext: {'rating1': 'rating2'}},
- likes: {required: true, len: 10, ext: {'likes1': 'likes2'}},
- downloads: {required: true, len: 10, ext: {'downloads1': 'downloads2'}},
- price: {required: true, len: 10, ext: {'price1': 'price2'}},
- saleprice: {required: true, len: 10, ext: {'saleprice1': 'saleprice2'}},
- phone: {required: true, len: 10, ext: {'phone1': 'phone2'}},
- address: {required: true, len: 10, ext: {'address1': 'address2'}},
- desc2: {required: true, len: 10, ext: {'desc21': 'desc22'}},
- displayurl: {required: true, len: 10, ext: {'displayurl1': 'displayurl2'}}
- },
- bidder: 'pubmatic',
- params: {
- publisherId: '5670',
- adSlot: '/43743431/NativeAutomationPrebid@1x1',
- },
- bidId: '2a5571261281d4',
- requestId: 'B68287E1-DC39-4B38-9790-FE4F179739D6',
- bidderRequestId: '1c56ad30b9b8ca8',
- }];
-
- nativeBidRequestsWithoutAsset = [{
- code: '/19968336/prebid_native_example_1',
- sizes: [
- [300, 250]
- ],
- mediaTypes: {
- native: {
- type: 'image'
- }
- },
- nativeParams: {
- title: { required: true },
- image: { required: true },
- sponsoredBy: { required: true },
- clickUrl: { required: true }
- },
- bidder: 'pubmatic',
- params: {
- publisherId: '5670',
- adSlot: '/43743431/NativeAutomationPrebid@1x1',
- }
- }];
-
- nativeBidRequestsWithRequiredParam = [{
- code: '/19968336/prebid_native_example_1',
- sizes: [
- [300, 250]
- ],
- mediaTypes: {
- native: {
- title: {
- required: false,
- length: 80
- },
- image: {
- required: false,
- sizes: [300, 250]
- },
- sponsoredBy: {
- required: true
- }
- }
- },
- nativeParams: {
- title: { required: false, length: 80 },
- image: { required: false, sizes: [300, 250] },
- sponsoredBy: { required: true }
- },
- bidder: 'pubmatic',
- params: {
- publisherId: '5670',
- adSlot: '/43743431/NativeAutomationPrebid@1x1',
- }
- }];
-
- bannerAndVideoBidRequests = [
- {
- code: 'div-banner-video',
- mediaTypes: {
- video: {
- playerSize: [640, 480],
- context: 'instream'
- },
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- bidder: 'pubmatic',
- params: {
- publisherId: '301',
- adSlot: '/15671365/DMDemo@300x250:0',
- kadfloor: '1.2',
- pmzoneid: 'aabc, ddef',
- kadpageurl: 'www.publisher.com',
- yob: '1986',
- gender: 'M',
- lat: '12.3',
- lon: '23.7',
- wiid: '1234567890',
- profId: '100',
- verId: '200',
- currency: 'AUD',
- dctr: 'key1:val1,val2|key2:val1',
- video: {
- mimes: ['video/mp4', 'video/x-flv'],
- skippable: true,
- minduration: 5,
- maxduration: 30,
- startdelay: 15,
- playbackmethod: [1, 3],
- api: [1, 2],
- protocols: [2, 3],
- w: 640,
- h: 480,
- battr: [13, 14],
- linearity: 1,
- placement: 2,
- minbitrate: 100,
- maxbitrate: 4096
- }
- },
- placementCode: '/19968336/header-bid-tag-1',
- sizes: [[728, 90]],
- bidId: '23acc48ad47af5',
- requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
- bidderRequestId: '1c56ad30b9b8ca8',
- transactionId: '92489f71-1bf2-49a0-adf9-000cea934729'
- }
- ];
-
- bannerAndNativeBidRequests = [
- {
- code: 'div-banner-native',
- mediaTypes: {
- native: {
- title: {
- required: true,
- length: 80
- },
- image: {
- required: true,
- sizes: [300, 250]
- },
- sponsoredBy: {
- required: true
- }
- },
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- nativeParams: {
- title: { required: true, length: 80 },
- image: { required: true, sizes: [300, 250] },
- sponsoredBy: { required: true }
- },
- bidder: 'pubmatic',
- params: {
- publisherId: '301',
- adSlot: '/15671365/DMDemo@300x250:0',
- kadfloor: '1.2',
- pmzoneid: 'aabc, ddef',
- kadpageurl: 'www.publisher.com',
- yob: '1986',
- gender: 'M',
- lat: '12.3',
- lon: '23.7',
- wiid: '1234567890',
- profId: '100',
- verId: '200',
- currency: 'AUD',
- dctr: 'key1:val1,val2|key2:val1'
- },
- placementCode: '/19968336/header-bid-tag-1',
- sizes: [[728, 90]],
- bidId: '23acc48ad47af5',
- requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
- bidderRequestId: '1c56ad30b9b8ca8',
- transactionId: '92489f71-1bf2-49a0-adf9-000cea934729'
- }
- ];
-
- videoAndNativeBidRequests = [
- {
- code: 'div-video-native',
- mediaTypes: {
- native: {
- title: {
- required: true,
- length: 80
- },
- image: {
- required: true,
- sizes: [300, 250]
- },
- sponsoredBy: {
- required: true
- }
- },
- video: {
- playerSize: [640, 480],
- context: 'instream'
- }
- },
- nativeParams: {
- title: { required: true, length: 80 },
- image: { required: true, sizes: [300, 250] },
- sponsoredBy: { required: true }
- },
- bidder: 'pubmatic',
- params: {
- publisherId: '301',
- adSlot: '/15671365/DMDemo@300x250:0',
- video: {
- mimes: ['video/mp4', 'video/x-flv'],
- skippable: true,
- minduration: 5,
- maxduration: 30,
- startdelay: 15,
- playbackmethod: [1, 3],
- api: [1, 2],
- protocols: [2, 3],
- w: 640,
- h: 480,
- battr: [13, 14],
- linearity: 1,
- placement: 2,
- minbitrate: 100,
- maxbitrate: 4096
- }
- },
- placementCode: '/19968336/header-bid-tag-1',
- sizes: [[728, 90]],
- bidId: '23acc48ad47af5',
- requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
- bidderRequestId: '1c56ad30b9b8ca8',
- transactionId: '92489f71-1bf2-49a0-adf9-000cea934729'
- }
- ];
-
- bannerVideoAndNativeBidRequests = [
- {
- code: 'div-video-native',
- mediaTypes: {
- native: {
- title: {
- required: true,
- length: 80
- },
- image: {
- required: true,
- sizes: [300, 250]
- },
- sponsoredBy: {
- required: true
- }
- },
- video: {
- playerSize: [640, 480],
- context: 'instream'
- },
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- },
- nativeParams: {
- title: { required: true, length: 80 },
- image: { required: true, sizes: [300, 250] },
- sponsoredBy: { required: true }
- },
- bidder: 'pubmatic',
- params: {
- publisherId: '301',
- adSlot: '/15671365/DMDemo@300x250:0',
- video: {
- mimes: ['video/mp4', 'video/x-flv'],
- skippable: true,
- minduration: 5,
- maxduration: 30,
- startdelay: 15,
- playbackmethod: [1, 3],
- api: [1, 2],
- protocols: [2, 3],
- w: 640,
- h: 480,
- battr: [13, 14],
- linearity: 1,
- placement: 2,
- minbitrate: 100,
- maxbitrate: 4096
- }
- },
- placementCode: '/19968336/header-bid-tag-1',
- sizes: [[728, 90]],
- bidId: '23acc48ad47af5',
- requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
- bidderRequestId: '1c56ad30b9b8ca8',
- transactionId: '92489f71-1bf2-49a0-adf9-000cea934729'
- }
- ];
-
- bidResponses = {
- 'body': {
- 'id': '93D3BAD6-E2E2-49FB-9D89-920B1761C865',
- 'seatbid': [{
- 'bid': [{
- 'id': '74858439-49D7-4169-BA5D-44A046315B2F',
- 'impid': '22bddb28db77d',
- 'price': 1.3,
- 'adm': 'image3.pubmatic.com Layer based creative',
- 'adomain': ['blackrock.com'],
- 'h': 250,
- 'w': 300,
- 'ext': {
- 'deal_channel': 6,
- 'advid': 976,
- 'dspid': 123
- }
- }]
- }, {
- 'bid': [{
- 'id': '74858439-49D7-4169-BA5D-44A046315BEF',
- 'impid': '22bddb28db77e',
- 'price': 1.7,
- 'adm': 'image3.pubmatic.com Layer based creative',
- 'adomain': ['hivehome.com'],
- 'h': 250,
- 'w': 300,
- 'ext': {
- 'deal_channel': 5,
- 'advid': 832,
- 'dspid': 422
- }
- }]
- }]
- }
- };
-
- nativeBidResponse = {
- 'body': {
- 'id': '1544691825939',
- 'seatbid': [{
- 'bid': [{
- 'id': 'B68287E1-DC39-4B38-9790-FE4F179739D6',
- 'impid': '2a5571261281d4',
- 'price': 0.01,
- 'adm': "{\"native\":{\"assets\":[{\"id\":1,\"title\":{\"text\":\"Native Test Title\"}},{\"id\":2,\"img\":{\"h\":627,\"url\":\"http://stagingpub.net/native_ads/PM-Native-Ad-1200x627.png\",\"w\":1200}},{\"data\":{\"value\":\"Sponsored By PubMatic\"},\"id\":4}],\"imptrackers\":[\"http://imptracker.com/main/9bde02d0-6017-11e4-9df7-005056967c35\",\"http://172.16.4.213/AdServer/AdDisplayTrackerServlet?operId=1&pubId=5890&siteId=5892&adId=6016&adType=12&adServerId=243&kefact=0.010000&kaxefact=0.010000&kadNetFrequecy=0&kadwidth=0&kadheight=0&kadsizeid=7&kltstamp=1544692761&indirectAdId=0&adServerOptimizerId=2&ranreq=0.1&kpbmtpfact=1.000000&dcId=1&tldId=0&passback=0&svr=MADS1107&ekefact=GSQSXOLKDgBAvRnoiNj0LxtpAnNEO30u1ZI5sITloOsP7gzh&ekaxefact=GSQSXAXLDgD0fOZLCjgbnVJiyS3D65dqDkxfs2ArpC3iugXw&ekpbmtpfact=GSQSXCDLDgB5mcooOvXtCKmx7TnNDJDY2YuHFOL3o9ceoU4H&crID=campaign111&lpu=advertiserdomain.com&ucrid=273354366805642829&campaignId=16981&creativeId=0&pctr=0.000000&wDSPByrId=511&wDspId=6&wbId=0&wrId=0&wAdvID=1&isRTB=1&rtbId=C09BB577-B8C1-4C3E-A0FF-73F6F631C80A&imprId=B68287E1-DC39-4B38-9790-FE4F179739D6&oid=B68287E1-DC39-4B38-9790-FE4F179739D6&pageURL=http%3A%2F%2Ftest.com%2FTestPages%2Fnativead.html\"],\"jstracker\":\" ',
- 'h': 250,
- 'w': 300,
- 'ext': {
- 'deal_channel': 6
- }
- }]
- }]
- }
- };
-
- videoBidResponse = {
- 'body': {
- 'id': '93D3BAD6-E2E2-49FB-9D89-920B1761C865',
- 'seatbid': [{
- 'bid': [{
- 'id': '74858439-49D7-4169-BA5D-44A046315B2F',
- 'impid': '22bddb28db77d',
- 'price': 1.3,
- 'adm': 'Acudeo CompatibleVAST 2.0 Instream Test 1VAST 2.0 Instream Test 1https://dsptracker.com/{PSPM}00:00:04https://www.pubmatic.com',
- 'h': 250,
- 'w': 300,
- 'ext': {
- 'deal_channel': 6
- }
- }]
- }]
- }
- }
- });
-
- describe('implementation', function () {
- describe('Bid validations', function () {
- it('valid bid case', function () {
- let validBid = {
- bidder: 'pubmatic',
- params: {
- publisherId: '301',
- adSlot: '/15671365/DMDemo@300x250:0'
- }
- },
- isValid = spec.isBidRequestValid(validBid);
- expect(isValid).to.equal(true);
- });
-
- it('invalid bid case: publisherId not passed', function () {
- let validBid = {
- bidder: 'pubmatic',
- params: {
- adSlot: '/15671365/DMDemo@300x250:0'
- }
- },
- isValid = spec.isBidRequestValid(validBid);
- expect(isValid).to.equal(false);
- });
-
- it('invalid bid case: publisherId is not string', function () {
- let validBid = {
- bidder: 'pubmatic',
- params: {
- publisherId: 301,
- adSlot: '/15671365/DMDemo@300x250:0'
- }
- },
- isValid = spec.isBidRequestValid(validBid);
- expect(isValid).to.equal(false);
- });
-
- it('valid bid case: adSlot is not passed', function () {
- let validBid = {
- bidder: 'pubmatic',
- params: {
- publisherId: '301'
- }
- },
- isValid = spec.isBidRequestValid(validBid);
- expect(isValid).to.equal(true);
- });
- });
-
- describe('Request formation', function () {
- it('buildRequests function should not modify original bidRequests object', function () {
- let originalBidRequests = utils.deepClone(bidRequests);
- let request = spec.buildRequests(bidRequests);
- expect(bidRequests).to.deep.equal(originalBidRequests);
- });
-
- it('buildRequests function should not modify original nativebidRequests object', function () {
- let originalBidRequests = utils.deepClone(nativeBidRequests);
- let request = spec.buildRequests(nativeBidRequests);
- expect(nativeBidRequests).to.deep.equal(originalBidRequests);
- });
-
- it('Endpoint checking', function () {
- let request = spec.buildRequests(bidRequests);
- expect(request.url).to.equal('https://hbopenbid.pubmatic.com/translator?source=prebid-client');
- expect(request.method).to.equal('POST');
- });
-
- it('Request params check', function () {
- let request = spec.buildRequests(bidRequests);
- let data = JSON.parse(request.data);
- 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(bidRequests[0].params.kadpageurl); // forced pageURL
- expect(data.site.publisher.id).to.equal(bidRequests[0].params.publisherId); // publisher Id
- expect(data.site.ext).to.exist.and.to.be.an('object'); // dctr parameter
- expect(data.site.ext.key_val).to.exist.and.to.equal(bidRequests[0].params.dctr);
- expect(data.user.yob).to.equal(parseInt(bidRequests[0].params.yob)); // YOB
- expect(data.user.gender).to.equal(bidRequests[0].params.gender); // Gender
- expect(data.device.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude
- expect(data.device.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude
- expect(data.user.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude
- expect(data.user.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude
- expect(data.ext.wrapper.wv).to.equal($$REPO_AND_VERSION$$); // Wrapper Version
- expect(data.ext.wrapper.transactionId).to.equal(bidRequests[0].transactionId); // Prebid TransactionId
- expect(data.ext.wrapper.wiid).to.equal(bidRequests[0].params.wiid); // OpenWrap: Wrapper Impression ID
- expect(data.ext.wrapper.profile).to.equal(parseInt(bidRequests[0].params.profId)); // OpenWrap: Wrapper Profile ID
- expect(data.ext.wrapper.version).to.equal(parseInt(bidRequests[0].params.verId)); // OpenWrap: Wrapper Profile Version ID
-
- expect(data.imp[0].id).to.equal(bidRequests[0].bidId); // Prebid bid id is passed as id
- expect(data.imp[0].bidfloor).to.equal(parseFloat(bidRequests[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(bidRequests[0].params.pmzoneid.split(',').slice(0, 50).map(id => id.trim()).join()); // pmzoneid
- expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency);
- expect(data.source.ext.schain).to.deep.equal(bidRequests[0].schain);
- });
-
- it('Request params check: without adSlot', function () {
- delete bidRequests[0].params.adSlot;
- let request = spec.buildRequests(bidRequests);
- let data = JSON.parse(request.data);
- 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(bidRequests[0].params.kadpageurl); // forced pageURL
- expect(data.site.publisher.id).to.equal(bidRequests[0].params.publisherId); // publisher Id
- expect(data.site.ext).to.exist.and.to.be.an('object'); // dctr parameter
- expect(data.site.ext.key_val).to.exist.and.to.equal(bidRequests[0].params.dctr);
- expect(data.user.yob).to.equal(parseInt(bidRequests[0].params.yob)); // YOB
- expect(data.user.gender).to.equal(bidRequests[0].params.gender); // Gender
- expect(data.device.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude
- expect(data.device.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude
- expect(data.user.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude
- expect(data.user.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude
- expect(data.ext.wrapper.wv).to.equal($$REPO_AND_VERSION$$); // Wrapper Version
- expect(data.ext.wrapper.transactionId).to.equal(bidRequests[0].transactionId); // Prebid TransactionId
- expect(data.ext.wrapper.wiid).to.equal(bidRequests[0].params.wiid); // OpenWrap: Wrapper Impression ID
- expect(data.ext.wrapper.profile).to.equal(parseInt(bidRequests[0].params.profId)); // OpenWrap: Wrapper Profile ID
- expect(data.ext.wrapper.version).to.equal(parseInt(bidRequests[0].params.verId)); // OpenWrap: Wrapper Profile Version ID
-
- expect(data.imp[0].id).to.equal(bidRequests[0].bidId); // Prebid bid id is passed as id
- expect(data.imp[0].bidfloor).to.equal(parseFloat(bidRequests[0].params.kadfloor)); // kadfloor
- expect(data.imp[0].tagid).to.deep.equal(undefined); // tagid
- expect(data.imp[0].banner.w).to.equal(728); // width
- expect(data.imp[0].banner.h).to.equal(90); // height
- expect(data.imp[0].banner.format).to.deep.equal([{w: 160, h: 600}]);
- expect(data.imp[0].ext.pmZoneId).to.equal(bidRequests[0].params.pmzoneid.split(',').slice(0, 50).map(id => id.trim()).join()); // pmzoneid
- expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency);
- });
-
- it('Request params multi size format object check', function () {
- let bidRequests = [
- {
- bidder: 'pubmatic',
- params: {
- publisherId: '301',
- adSlot: '/15671365/DMDemo@300x250:0',
- kadfloor: '1.2',
- pmzoneid: 'aabc, ddef',
- kadpageurl: 'www.publisher.com',
- yob: '1986',
- gender: 'M',
- lat: '12.3',
- lon: '23.7',
- wiid: '1234567890',
- profId: '100',
- verId: '200',
- currency: 'AUD'
- },
- placementCode: '/19968336/header-bid-tag-1',
- bidId: '23acc48ad47af5',
- requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
- bidderRequestId: '1c56ad30b9b8ca8',
- transactionId: '92489f71-1bf2-49a0-adf9-000cea934729'
- }
- ];
- /* case 1 - size passed in adslot */
- let request = spec.buildRequests(bidRequests);
- let data = JSON.parse(request.data);
-
- expect(data.imp[0].banner.w).to.equal(300); // width
- expect(data.imp[0].banner.h).to.equal(250); // height
-
- /* case 2 - size passed in adslot as well as in sizes array */
- bidRequests[0].sizes = [[300, 600], [300, 250]];
- bidRequests[0].mediaTypes = {
- banner: {
- sizes: [[300, 600], [300, 250]]
- }
- };
- request = spec.buildRequests(bidRequests);
- data = JSON.parse(request.data);
-
- expect(data.imp[0].banner.w).to.equal(300); // width
- expect(data.imp[0].banner.h).to.equal(250); // height
-
- /* case 3 - size passed in sizes but not in adslot */
- bidRequests[0].params.adSlot = '/15671365/DMDemo';
- bidRequests[0].sizes = [[300, 250], [300, 600]];
- bidRequests[0].mediaTypes = {
- banner: {
- sizes: [[300, 250], [300, 600]]
- }
- };
- request = spec.buildRequests(bidRequests);
- data = JSON.parse(request.data);
-
- expect(data.imp[0].banner.w).to.equal(300); // width
- expect(data.imp[0].banner.h).to.equal(250); // height
- expect(data.imp[0].banner.format).exist.and.to.be.an('array');
- expect(data.imp[0].banner.format[0]).exist.and.to.be.an('object');
- expect(data.imp[0].banner.format[0].w).to.equal(300); // width
- expect(data.imp[0].banner.format[0].h).to.equal(600); // height
- });
-
- it('Request params currency check', function () {
- let multipleBidRequests = [
- {
- bidder: 'pubmatic',
- params: {
- publisherId: '301',
- adSlot: '/15671365/DMDemo@300x250:0',
- kadfloor: '1.2',
- pmzoneid: 'aabc, ddef',
- kadpageurl: 'www.publisher.com',
- yob: '1986',
- gender: 'M',
- lat: '12.3',
- lon: '23.7',
- wiid: '1234567890',
- profId: '100',
- verId: '200',
- currency: 'AUD'
- },
- placementCode: '/19968336/header-bid-tag-1',
- sizes: [[300, 250], [300, 600]],
- bidId: '23acc48ad47af5',
- requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
- bidderRequestId: '1c56ad30b9b8ca8',
- transactionId: '92489f71-1bf2-49a0-adf9-000cea934729'
- },
- {
- bidder: 'pubmatic',
- params: {
- publisherId: '301',
- adSlot: '/15671365/DMDemo@300x250:0',
- kadfloor: '1.2',
- pmzoneid: 'aabc, ddef',
- kadpageurl: 'www.publisher.com',
- yob: '1986',
- gender: 'M',
- lat: '12.3',
- lon: '23.7',
- wiid: '1234567890',
- profId: '100',
- verId: '200',
- currency: 'GBP'
- },
- placementCode: '/19968336/header-bid-tag-1',
- sizes: [[300, 250], [300, 600]],
- bidId: '23acc48ad47af5',
- requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
- bidderRequestId: '1c56ad30b9b8ca8',
- transactionId: '92489f71-1bf2-49a0-adf9-000cea934729'
- }
- ];
-
- /* case 1 -
- currency specified in both adunits
- output: imp[0] and imp[1] both use currency specified in bidRequests[0].params.currency
-
- */
- let request = spec.buildRequests(multipleBidRequests);
- let data = JSON.parse(request.data);
-
- expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency);
- expect(data.imp[1].bidfloorcur).to.equal(bidRequests[0].params.currency);
-
- /* case 2 -
- currency specified in only 1st adunit
- output: imp[0] and imp[1] both use currency specified in bidRequests[0].params.currency
-
- */
- delete multipleBidRequests[1].params.currency;
- request = spec.buildRequests(multipleBidRequests);
- data = JSON.parse(request.data);
- expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency);
- expect(data.imp[1].bidfloorcur).to.equal(bidRequests[0].params.currency);
-
- /* case 3 -
- currency specified in only 1st adunit
- output: imp[0] and imp[1] both use default currency - USD
-
- */
- delete multipleBidRequests[0].params.currency;
- request = spec.buildRequests(multipleBidRequests);
- data = JSON.parse(request.data);
- expect(data.imp[0].bidfloorcur).to.equal('USD');
- expect(data.imp[1].bidfloorcur).to.equal('USD');
-
- /* case 4 -
- currency not specified in 1st adunit but specified in 2nd adunit
- output: imp[0] and imp[1] both use default currency - USD
-
- */
- multipleBidRequests[1].params.currency = 'AUD';
- request = spec.buildRequests(multipleBidRequests);
- data = JSON.parse(request.data);
- expect(data.imp[0].bidfloorcur).to.equal('USD');
- expect(data.imp[1].bidfloorcur).to.equal('USD');
- });
-
- it('Request params check with GDPR Consent', function () {
- let bidRequest = {
- gdprConsent: {
- consentString: 'kjfdniwjnifwenrif3',
- gdprApplies: true
- }
- };
- let request = spec.buildRequests(bidRequests, bidRequest);
- let data = JSON.parse(request.data);
- expect(data.user.ext.consent).to.equal('kjfdniwjnifwenrif3');
- expect(data.regs.ext.gdpr).to.equal(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(bidRequests[0].params.kadpageurl); // forced pageURL
- expect(data.site.publisher.id).to.equal(bidRequests[0].params.publisherId); // publisher Id
- expect(data.user.yob).to.equal(parseInt(bidRequests[0].params.yob)); // YOB
- expect(data.user.gender).to.equal(bidRequests[0].params.gender); // Gender
- expect(data.device.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude
- expect(data.device.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude
- expect(data.user.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude
- expect(data.user.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude
- expect(data.ext.wrapper.wv).to.equal($$REPO_AND_VERSION$$); // Wrapper Version
- expect(data.ext.wrapper.transactionId).to.equal(bidRequests[0].transactionId); // Prebid TransactionId
- expect(data.ext.wrapper.wiid).to.equal(bidRequests[0].params.wiid); // OpenWrap: Wrapper Impression ID
- expect(data.ext.wrapper.profile).to.equal(parseInt(bidRequests[0].params.profId)); // OpenWrap: Wrapper Profile ID
- expect(data.ext.wrapper.version).to.equal(parseInt(bidRequests[0].params.verId)); // OpenWrap: Wrapper Profile Version ID
-
- expect(data.imp[0].id).to.equal(bidRequests[0].bidId); // Prebid bid id is passed as id
- expect(data.imp[0].bidfloor).to.equal(parseFloat(bidRequests[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(bidRequests[0].params.pmzoneid.split(',').slice(0, 50).map(id => id.trim()).join()); // pmzoneid
- });
-
- it('Request should have digitrust params', function() {
- window.DigiTrust = {
- getUser: function () {
- }
- };
- var bidRequest = {};
- let sandbox = sinon.sandbox.create();
- sandbox.stub(window.DigiTrust, 'getUser').callsFake(() =>
- ({
- success: true,
- identity: {
- privacy: {optout: false},
- id: 'testId',
- keyv: 4
- }
- })
- );
-
- let request = spec.buildRequests(bidRequests, bidRequest);
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal([{
- 'source': 'digitru.st',
- 'uids': [{
- 'id': 'testId',
- 'atype': 1,
- 'ext': {
- 'keyv': 4
- }
- }]
- }]);
- sandbox.restore();
- delete window.DigiTrust;
- });
-
- it('Request should not have digitrust params when DigiTrust not loaded', function() {
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal(undefined);
- });
-
- it('Request should not have digitrust params due to optout', function() {
- window.DigiTrust = {
- getUser: function () {
- }
- };
- let sandbox = sinon.sandbox.create();
- sandbox.stub(window.DigiTrust, 'getUser').callsFake(() =>
- ({
- success: true,
- identity: {
- privacy: {optout: true},
- id: 'testId',
- keyv: 4
- }
- })
- );
-
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal(undefined);
- sandbox.restore();
- delete window.DigiTrust;
- });
-
- it('Request should not have digitrust params due to failure', function() {
- window.DigiTrust = {
- getUser: function () {
- }
- };
- let sandbox = sinon.sandbox.create();
- sandbox.stub(window.DigiTrust, 'getUser').callsFake(() =>
- ({
- success: false,
- identity: {
- privacy: {optout: false},
- id: 'testId',
- keyv: 4
- }
- })
- );
-
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal(undefined);
- sandbox.restore();
- delete window.DigiTrust;
- });
-
- describe('DigiTrustId from config', function() {
- var origGetConfig;
- let sandbox;
- beforeEach(() => {
- sandbox = sinon.sandbox.create();
- window.DigiTrust = {
- getUser: sandbox.spy()
- };
- });
-
- afterEach(() => {
- sandbox.restore();
- delete window.DigiTrust;
- });
-
- it('Request should have digiTrustId config params', function() {
- sandbox.stub(config, 'getConfig').callsFake((key) => {
- var config = {
- digiTrustId: {
- success: true,
- identity: {
- privacy: {optout: false},
- id: 'testId',
- keyv: 4
- }
- }
- };
- return config[key];
- });
-
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal([{
- 'source': 'digitru.st',
- 'uids': [{
- 'id': 'testId',
- 'atype': 1,
- 'ext': {
- 'keyv': 4
- }
- }]
- }]);
- // should not have called DigiTrust.getUser()
- expect(window.DigiTrust.getUser.notCalled).to.equal(true);
- });
-
- it('Request should not have digiTrustId config params due to optout', function() {
- sandbox.stub(config, 'getConfig').callsFake((key) => {
- var config = {
- digiTrustId: {
- success: true,
- identity: {
- privacy: {optout: true},
- id: 'testId',
- keyv: 4
- }
- }
- }
- return config[key];
- });
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal(undefined);
- // should not have called DigiTrust.getUser()
- expect(window.DigiTrust.getUser.notCalled).to.equal(true);
- });
-
- it('Request should not have digiTrustId config params due to failure', function() {
- sandbox.stub(config, 'getConfig').callsFake((key) => {
- var config = {
- digiTrustId: {
- success: false,
- identity: {
- privacy: {optout: false},
- id: 'testId',
- keyv: 4
- }
- }
- }
- return config[key];
- });
-
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal(undefined);
- // should not have called DigiTrust.getUser()
- expect(window.DigiTrust.getUser.notCalled).to.equal(true);
- });
-
- it('Request should not have digiTrustId config params if they do not exist', function() {
- sandbox.stub(config, 'getConfig').callsFake((key) => {
- var config = {};
- return config[key];
- });
-
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal(undefined);
- // should have called DigiTrust.getUser() once
- expect(window.DigiTrust.getUser.calledOnce).to.equal(true);
- });
- });
-
- describe('AdsrvrOrgId from config', function() {
- let sandbox;
- beforeEach(() => {
- sandbox = sinon.sandbox.create();
- });
-
- afterEach(() => {
- sandbox.restore();
- });
-
- it('Request should have adsrvrOrgId config params', function() {
- sandbox.stub(config, 'getConfig').callsFake((key) => {
- var config = {
- adsrvrOrgId: {
- 'TDID': '5e740345-c25e-436d-b466-5f2f9fa95c17',
- 'TDID_LOOKUP': 'TRUE',
- 'TDID_CREATED_AT': '2018-10-01T07:05:40'
- }
- };
- return config[key];
- });
-
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal([{
- 'source': 'adserver.org',
- 'uids': [{
- 'id': '5e740345-c25e-436d-b466-5f2f9fa95c17',
- 'atype': 1,
- 'ext': {
- 'rtiPartner': 'TDID'
- }
- }]
- }]);
- });
-
- it('Request should NOT have adsrvrOrgId config params if id in adsrvrOrgId is NOT string', function() {
- sandbox.stub(config, 'getConfig').callsFake((key) => {
- var config = {
- adsrvrOrgId: {
- 'TDID': 1,
- 'TDID_LOOKUP': 'TRUE',
- 'TDID_CREATED_AT': '2018-10-01T07:05:40'
- }
- };
- return config[key];
- });
-
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal(undefined);
- });
-
- it('Request should NOT have adsrvrOrgId config params if adsrvrOrgId is NOT object', function() {
- sandbox.stub(config, 'getConfig').callsFake((key) => {
- var config = {
- adsrvrOrgId: null
- };
- return config[key];
- });
-
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal(undefined);
- });
-
- it('Request should NOT have adsrvrOrgId config params if id in adsrvrOrgId is NOT set', function() {
- sandbox.stub(config, 'getConfig').callsFake((key) => {
- var config = {
- adsrvrOrgId: {
- 'TDID_LOOKUP': 'TRUE',
- 'TDID_CREATED_AT': '2018-10-01T07:05:40'
- }
- };
- return config[key];
- });
-
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal(undefined);
- });
- });
-
- describe('AdsrvrOrgId from userId module', function() {
- let sandbox;
- beforeEach(() => {
- sandbox = sinon.sandbox.create();
- });
-
- afterEach(() => {
- sandbox.restore();
- });
-
- it('Request should have AdsrvrOrgId config params', function() {
- bidRequests[0].userId = {};
- bidRequests[0].userId.tdid = 'TTD_ID_FROM_USER_ID_MODULE';
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal([{
- 'source': 'adserver.org',
- 'uids': [{
- 'id': 'TTD_ID_FROM_USER_ID_MODULE',
- 'atype': 1,
- 'ext': {
- 'rtiPartner': 'TDID'
- }
- }]
- }]);
- });
-
- it('Request should have adsrvrOrgId from UserId Module if config and userId module both have TTD ID', function() {
- sandbox.stub(config, 'getConfig').callsFake((key) => {
- var config = {
- adsrvrOrgId: {
- 'TDID': 'TTD_ID_FROM_CONFIG',
- 'TDID_LOOKUP': 'TRUE',
- 'TDID_CREATED_AT': '2018-10-01T07:05:40'
- }
- };
- return config[key];
- });
- bidRequests[0].userId = {};
- bidRequests[0].userId.tdid = 'TTD_ID_FROM_USER_ID_MODULE';
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal([{
- 'source': 'adserver.org',
- 'uids': [{
- 'id': 'TTD_ID_FROM_USER_ID_MODULE',
- 'atype': 1,
- 'ext': {
- 'rtiPartner': 'TDID'
- }
- }]
- }]);
- });
-
- it('Request should NOT have adsrvrOrgId params if userId is NOT object', function() {
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal(undefined);
- });
-
- it('Request should NOT have adsrvrOrgId params if userId.tdid is NOT string', function() {
- bidRequests[0].userId = {
- tdid: 1234
- };
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal(undefined);
- });
- });
-
- describe('AdsrvrOrgId and Digitrust', function() {
- // here we are considering cases only of accepting DigiTrustId from config
- let sandbox;
- beforeEach(() => {
- sandbox = sinon.sandbox.create();
- window.DigiTrust = {
- getUser: sandbox.spy()
- };
- });
-
- afterEach(() => {
- sandbox.restore();
- delete window.DigiTrust;
- });
-
- it('Request should have id of both AdsrvrOrgId and Digitrust if both have returned valid ids', function() {
- sandbox.stub(config, 'getConfig').callsFake((key) => {
- var config = {
- adsrvrOrgId: {
- 'TDID': '5e740345-c25e-436d-b466-5f2f9fa95c17',
- 'TDID_LOOKUP': 'TRUE',
- 'TDID_CREATED_AT': '2018-10-01T07:05:40'
- },
- digiTrustId: {
- success: true,
- identity: {
- privacy: {optout: false},
- id: 'testId',
- keyv: 4
- }
- }
- };
- return config[key];
- });
-
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal([{
- 'source': 'digitru.st',
- 'uids': [{
- 'id': 'testId',
- 'atype': 1,
- 'ext': {
- 'keyv': 4
- }
- }]
- }, {
- 'source': 'adserver.org',
- 'uids': [{
- 'id': '5e740345-c25e-436d-b466-5f2f9fa95c17',
- 'atype': 1,
- 'ext': {
- 'rtiPartner': 'TDID'
- }
- }]
- }]);
- });
-
- it('Request should have id of only AdsrvrOrgId and NOT Digitrust if only AdsrvrOrgId have returned valid id', function() {
- sandbox.stub(config, 'getConfig').callsFake((key) => {
- var config = {
- adsrvrOrgId: {
- 'TDID': '5e740345-c25e-436d-b466-5f2f9fa95c17',
- 'TDID_LOOKUP': 'TRUE',
- 'TDID_CREATED_AT': '2018-10-01T07:05:40'
- },
- digiTrustId: {
- success: true,
- identity: {
- privacy: {optout: true},
- id: 'testId',
- keyv: 4
- }
- }
- };
- return config[key];
- });
-
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal([{
- 'source': 'adserver.org',
- 'uids': [{
- 'id': '5e740345-c25e-436d-b466-5f2f9fa95c17',
- 'atype': 1,
- 'ext': {
- 'rtiPartner': 'TDID'
- }
- }]
- }]);
- });
-
- it('Request should have id of only Digitrust and NOT AdsrvrOrgId if only Digitrust have returned valid id', function() {
- sandbox.stub(config, 'getConfig').callsFake((key) => {
- var config = {
- adsrvrOrgId: {
- 'TDID_LOOKUP': 'TRUE',
- 'TDID_CREATED_AT': '2018-10-01T07:05:40'
- },
- digiTrustId: {
- success: true,
- identity: {
- privacy: {optout: false},
- id: 'testId',
- keyv: 4
- }
- }
- };
- return config[key];
- });
-
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal([{
- 'source': 'digitru.st',
- 'uids': [{
- 'id': 'testId',
- 'atype': 1,
- 'ext': {
- 'keyv': 4
- }
- }]
- }]);
- });
-
- it('Request should NOT have id of Digitrust and NOT AdsrvrOrgId if only both have NOT returned valid ids', function() {
- sandbox.stub(config, 'getConfig').callsFake((key) => {
- var config = {
- adsrvrOrgId: {
- 'TDID_LOOKUP': 'TRUE',
- 'TDID_CREATED_AT': '2018-10-01T07:05:40'
- },
- digiTrustId: {
- success: true,
- identity: {
- privacy: {optout: true},
- id: 'testId',
- keyv: 4
- }
- }
- };
- return config[key];
- });
-
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal(undefined);
- });
- });
-
- it('Request params check for video ad', function () {
- let request = spec.buildRequests(videoBidRequests);
- 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.ext['video_skippable']).to.equal(videoBidRequests[0].params.video.skippable ? 1 : 0);
- 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);
- 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.ext['video_skippable']).to.equal(multipleMediaRequests[1].params.video.skippable ? 1 : 0);
- 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('Request params should have valid native bid request for all valid params', function () {
- let request = spec.buildRequests(nativeBidRequests);
- let data = JSON.parse(request.data);
- expect(data.imp[0].native).to.exist;
- expect(data.imp[0].native['request']).to.exist;
- expect(data.imp[0].tagid).to.equal('/43743431/NativeAutomationPrebid');
- expect(data.imp[0]['native']['request']).to.exist.and.to.be.an('string');
- expect(data.imp[0]['native']['request']).to.exist.and.to.equal(validnativeBidImpression.native.request);
- });
-
- it('Request params should not have valid native bid request for non native request', function () {
- let request = spec.buildRequests(bidRequests);
- let data = JSON.parse(request.data);
- expect(data.imp[0].native).to.not.exist;
- });
-
- it('Request params should have valid native bid request with valid required param values for all valid params', function () {
- let request = spec.buildRequests(nativeBidRequestsWithRequiredParam);
- let data = JSON.parse(request.data);
- expect(data.imp[0].native).to.exist;
- expect(data.imp[0].native['request']).to.exist;
- expect(data.imp[0].tagid).to.equal('/43743431/NativeAutomationPrebid');
- expect(data.imp[0]['native']['request']).to.exist.and.to.be.an('string');
- expect(data.imp[0]['native']['request']).to.exist.and.to.equal(validnativeBidImpressionWithRequiredParam.native.request);
- });
-
- it('should not have valid native request if assets are not defined with minimum required params and only native is the slot', function () {
- let request = spec.buildRequests(nativeBidRequestsWithoutAsset);
- expect(request).to.deep.equal(undefined);
- });
-
- it('Request params should have valid native bid request for all native params', function () {
- let request = spec.buildRequests(nativeBidRequestsWithAllParams);
- let data = JSON.parse(request.data);
- expect(data.imp[0].native).to.exist;
- expect(data.imp[0].native['request']).to.exist;
- expect(data.imp[0].tagid).to.equal('/43743431/NativeAutomationPrebid');
- expect(data.imp[0]['native']['request']).to.exist.and.to.be.an('string');
- 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);
- 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);
- 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);
- 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);
- 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);
- 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);
- 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);
- 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);
- 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.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);
- 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);
- 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);
- 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 not have native object incase of invalid config present', function() {
- bannerAndNativeBidRequests[0].mediaTypes.native = {
- title: { required: true },
- image: { required: true },
- sponsoredBy: { required: true },
- clickUrl: { required: true }
- };
- bannerAndNativeBidRequests[0].nativeParams = {
- title: { required: true },
- image: { required: true },
- sponsoredBy: { required: true },
- clickUrl: { required: true }
- }
- let request = spec.buildRequests(bannerAndNativeBidRequests);
- let data = JSON.parse(request.data);
- data = data.imp[0];
-
- expect(data.banner).to.exist;
- expect(data.native).to.not.exist;
- });
-
- it('Request params - video and native multiformat request - should not 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);
- let data = JSON.parse(request.data);
- data = data.imp[0];
-
- expect(data.video).to.exist;
- expect(data.native).to.not.exist;
- });
- });
-
- it('Request params dctr check', function () {
- let multipleBidRequests = [
- {
- bidder: 'pubmatic',
- params: {
- publisherId: '301',
- adSlot: '/15671365/DMDemo@300x250:0',
- kadfloor: '1.2',
- pmzoneid: 'aabc, ddef',
- kadpageurl: 'www.publisher.com',
- yob: '1986',
- gender: 'M',
- lat: '12.3',
- lon: '23.7',
- wiid: '1234567890',
- profId: '100',
- verId: '200',
- currency: 'AUD',
- dctr: 'key1=val1|key2=val2,!val3'
- },
- placementCode: '/19968336/header-bid-tag-1',
- sizes: [[300, 250], [300, 600]],
- bidId: '23acc48ad47af5',
- requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
- bidderRequestId: '1c56ad30b9b8ca8',
- transactionId: '92489f71-1bf2-49a0-adf9-000cea934729'
- },
- {
- bidder: 'pubmatic',
- params: {
- publisherId: '301',
- adSlot: '/15671365/DMDemo@300x250:0',
- kadfloor: '1.2',
- pmzoneid: 'aabc, ddef',
- kadpageurl: 'www.publisher.com',
- yob: '1986',
- gender: 'M',
- lat: '12.3',
- lon: '23.7',
- wiid: '1234567890',
- profId: '100',
- verId: '200',
- currency: 'GBP',
- dctr: 'key1=val3|key2=val1,!val3|key3=val123'
- },
- placementCode: '/19968336/header-bid-tag-1',
- sizes: [[300, 250], [300, 600]],
- bidId: '23acc48ad47af5',
- requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
- bidderRequestId: '1c56ad30b9b8ca8',
- transactionId: '92489f71-1bf2-49a0-adf9-000cea934729'
- }
- ];
-
- let request = spec.buildRequests(multipleBidRequests);
- let data = JSON.parse(request.data);
-
- /* case 1 -
- dctr is found in adunit[0]
- */
-
- expect(data.site.ext).to.exist.and.to.be.an('object'); // dctr parameter
- expect(data.site.ext.key_val).to.exist.and.to.equal(multipleBidRequests[0].params.dctr);
-
- /* case 2 -
- dctr not present in adunit[0]
- */
- delete multipleBidRequests[0].params.dctr;
- request = spec.buildRequests(multipleBidRequests);
- data = JSON.parse(request.data);
-
- expect(data.site.ext).to.not.exist;
-
- /* case 3 -
- dctr is present in adunit[0], but is not a string value
- */
- multipleBidRequests[0].params.dctr = 123;
- request = spec.buildRequests(multipleBidRequests);
- data = JSON.parse(request.data);
-
- expect(data.site.ext).to.not.exist;
- });
-
- describe('Request param bcat checking', function() {
- let multipleBidRequests = [
- {
- bidder: 'pubmatic',
- params: {
- publisherId: '301',
- adSlot: '/15671365/DMDemo@300x250:0',
- kadfloor: '1.2',
- pmzoneid: 'aabc, ddef',
- kadpageurl: 'www.publisher.com',
- yob: '1986',
- gender: 'M',
- lat: '12.3',
- lon: '23.7',
- wiid: '1234567890',
- profId: '100',
- verId: '200',
- currency: 'AUD',
- dctr: 'key1=val1|key2=val2,!val3'
- },
- placementCode: '/19968336/header-bid-tag-1',
- sizes: [[300, 250], [300, 600]],
- bidId: '23acc48ad47af5',
- requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
- bidderRequestId: '1c56ad30b9b8ca8',
- transactionId: '92489f71-1bf2-49a0-adf9-000cea934729'
- },
- {
- bidder: 'pubmatic',
- params: {
- publisherId: '301',
- adSlot: '/15671365/DMDemo@300x250:0',
- kadfloor: '1.2',
- pmzoneid: 'aabc, ddef',
- kadpageurl: 'www.publisher.com',
- yob: '1986',
- gender: 'M',
- lat: '12.3',
- lon: '23.7',
- wiid: '1234567890',
- profId: '100',
- verId: '200',
- currency: 'GBP',
- dctr: 'key1=val3|key2=val1,!val3|key3=val123'
- },
- placementCode: '/19968336/header-bid-tag-1',
- sizes: [[300, 250], [300, 600]],
- bidId: '23acc48ad47af5',
- requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
- bidderRequestId: '1c56ad30b9b8ca8',
- transactionId: '92489f71-1bf2-49a0-adf9-000cea934729'
- }
- ];
-
- it('bcat: pass only strings', function() {
- multipleBidRequests[0].params.bcat = [1, 2, 3, 'IAB1', 'IAB2'];
- let request = spec.buildRequests(multipleBidRequests);
- let data = JSON.parse(request.data);
- expect(data.bcat).to.exist.and.to.deep.equal(['IAB1', 'IAB2']);
- });
-
- it('bcat: pass strings with length greater than 3', function() {
- multipleBidRequests[0].params.bcat = ['AB', 'CD', 'IAB1', 'IAB2'];
- let request = spec.buildRequests(multipleBidRequests);
- let data = JSON.parse(request.data);
- expect(data.bcat).to.exist.and.to.deep.equal(['IAB1', 'IAB2']);
- });
-
- it('bcat: trim the strings', function() {
- multipleBidRequests[0].params.bcat = [' IAB1 ', ' IAB2 '];
- let request = spec.buildRequests(multipleBidRequests);
- let data = JSON.parse(request.data);
- expect(data.bcat).to.exist.and.to.deep.equal(['IAB1', 'IAB2']);
- });
-
- it('bcat: pass only unique strings', function() {
- // multi slot
- multipleBidRequests[0].params.bcat = ['IAB1', 'IAB2', 'IAB1', 'IAB2', 'IAB1', 'IAB2'];
- multipleBidRequests[1].params.bcat = ['IAB1', 'IAB2', 'IAB1', 'IAB2', 'IAB1', 'IAB3'];
- let request = spec.buildRequests(multipleBidRequests);
- let data = JSON.parse(request.data);
- expect(data.bcat).to.exist.and.to.deep.equal(['IAB1', 'IAB2', 'IAB3']);
- });
-
- it('bcat: do not pass bcat if all entries are invalid', function() {
- // multi slot
- multipleBidRequests[0].params.bcat = ['', 'IAB', 'IAB'];
- multipleBidRequests[1].params.bcat = [' ', 22, 99999, 'IA'];
- let request = spec.buildRequests(multipleBidRequests);
- let data = JSON.parse(request.data);
- expect(data.bcat).to.deep.equal(undefined);
- });
- });
-
- describe('Response checking', function () {
- it('should check for valid response values', function () {
- let request = spec.buildRequests(bidRequests);
- let data = JSON.parse(request.data);
- let response = spec.interpretResponse(bidResponses, request);
- expect(response).to.be.an('array').with.length.above(0);
- expect(response[0].requestId).to.equal(bidResponses.body.seatbid[0].bid[0].impid);
- expect(response[0].cpm).to.equal((bidResponses.body.seatbid[0].bid[0].price).toFixed(2));
- expect(response[0].width).to.equal(bidResponses.body.seatbid[0].bid[0].w);
- expect(response[0].height).to.equal(bidResponses.body.seatbid[0].bid[0].h);
- if (bidResponses.body.seatbid[0].bid[0].crid) {
- expect(response[0].creativeId).to.equal(bidResponses.body.seatbid[0].bid[0].crid);
- } else {
- expect(response[0].creativeId).to.equal(bidResponses.body.seatbid[0].bid[0].id);
- }
- expect(response[0].dealId).to.equal(bidResponses.body.seatbid[0].bid[0].dealid);
- expect(response[0].currency).to.equal('USD');
- expect(response[0].netRevenue).to.equal(false);
- expect(response[0].ttl).to.equal(300);
- expect(response[0].meta.networkId).to.equal(123);
- expect(response[0].meta.buyerId).to.equal(976);
- expect(response[0].meta.clickUrl).to.equal('blackrock.com');
- expect(response[0].referrer).to.include(data.site.ref);
- expect(response[0].ad).to.equal(bidResponses.body.seatbid[0].bid[0].adm);
-
- expect(response[1].requestId).to.equal(bidResponses.body.seatbid[1].bid[0].impid);
- expect(response[1].cpm).to.equal((bidResponses.body.seatbid[1].bid[0].price).toFixed(2));
- expect(response[1].width).to.equal(bidResponses.body.seatbid[1].bid[0].w);
- expect(response[1].height).to.equal(bidResponses.body.seatbid[1].bid[0].h);
- if (bidResponses.body.seatbid[1].bid[0].crid) {
- expect(response[1].creativeId).to.equal(bidResponses.body.seatbid[1].bid[0].crid);
- } else {
- expect(response[1].creativeId).to.equal(bidResponses.body.seatbid[1].bid[0].id);
- }
- expect(response[1].dealId).to.equal(bidResponses.body.seatbid[1].bid[0].dealid);
- expect(response[1].currency).to.equal('USD');
- expect(response[1].netRevenue).to.equal(false);
- expect(response[1].ttl).to.equal(300);
- expect(response[1].meta.networkId).to.equal(422);
- expect(response[1].meta.buyerId).to.equal(832);
- expect(response[1].meta.clickUrl).to.equal('hivehome.com');
- expect(response[1].referrer).to.include(data.site.ref);
- expect(response[1].ad).to.equal(bidResponses.body.seatbid[1].bid[0].adm);
- });
-
- it('should check for dealChannel value selection', function () {
- let request = spec.buildRequests(bidRequests);
- let response = spec.interpretResponse(bidResponses, request);
- expect(response).to.be.an('array').with.length.above(0);
- expect(response[0].dealChannel).to.equal('PMPG');
- expect(response[1].dealChannel).to.equal('PREF');
- });
-
- it('should check for unexpected dealChannel value selection', function () {
- let request = spec.buildRequests(bidRequests);
- let updateBiResponse = bidResponses;
- updateBiResponse.body.seatbid[0].bid[0].ext.deal_channel = 11;
-
- let response = spec.interpretResponse(updateBiResponse, request);
-
- expect(response).to.be.an('array').with.length.above(0);
- expect(response[0].dealChannel).to.equal(null);
- });
-
- it('should have a valid native bid response', function() {
- let request = spec.buildRequests(nativeBidRequests);
- let data = JSON.parse(request.data);
- data.imp[0].id = '2a5571261281d4';
- request.data = JSON.stringify(data);
- let response = spec.interpretResponse(nativeBidResponse, request);
- expect(response).to.be.an('array').with.length.above(0);
- expect(response[0].native).to.exist.and.to.be.an('object');
- expect(response[0].mediaType).to.exist.and.to.equal('native');
- expect(response[0].native.title).to.exist.and.to.be.an('string');
- expect(response[0].native.image).to.exist.and.to.be.an('object');
- expect(response[0].native.image.url).to.exist.and.to.be.an('string');
- expect(response[0].native.image.height).to.exist;
- expect(response[0].native.image.width).to.exist;
- expect(response[0].native.sponsoredBy).to.exist.and.to.be.an('string');
- expect(response[0].native.clickUrl).to.exist.and.to.be.an('string');
- });
-
- it('should check for valid banner mediaType in case of multiformat request', function() {
- let request = spec.buildRequests(bidRequests);
- let response = spec.interpretResponse(bannerBidResponse, request);
-
- 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);
- 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);
- let response = spec.interpretResponse(nativeBidResponse, request);
-
- expect(response[0].mediaType).to.equal('native');
- });
- });
- });
-});
diff --git a/test/spec/modules/radsBidAdapter_spec.js b/test/spec/modules/radsBidAdapter_spec.js
new file mode 100644
index 00000000000..6981955f261
--- /dev/null
+++ b/test/spec/modules/radsBidAdapter_spec.js
@@ -0,0 +1,206 @@
+import { expect } from 'chai';
+import { spec } from 'modules/radsBidAdapter';
+import { newBidder } from 'src/adapters/bidderFactory';
+
+const RADS_ENDPOINT_URL = 'https://rads.recognified.net/md.request.php';
+
+describe('radsAdapter', function () {
+ const adapter = newBidder(spec);
+
+ describe('isBidRequestValid', function () {
+ let bid = {
+ 'bidder': 'rads',
+ 'params': {
+ 'placement': '6682',
+ 'pfilter': {
+ 'floorprice': 1000000
+ },
+ 'bcat': 'IAB2,IAB4',
+ 'dvt': 'desktop',
+ 'ip': '1.1.1.1'
+ },
+ 'sizes': [
+ [300, 250]
+ ],
+ '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 () {
+ let bid = Object.assign({}, bid);
+ delete bid.params;
+ bid.params = {
+ 'someIncorrectParam': 0
+ };
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
+ });
+ });
+
+ describe('buildRequests', function () {
+ let bidRequests = [{
+ 'bidder': 'rads',
+ 'params': {
+ 'placement': '6682',
+ 'pfilter': {
+ 'floorprice': 1000000,
+ 'geo': {
+ 'country': 'DE'
+ }
+ },
+ 'bcat': 'IAB2,IAB4',
+ 'dvt': 'desktop',
+ 'ip': '1.1.1.1'
+ },
+ 'sizes': [
+ [300, 250]
+ ],
+ 'bidId': '30b31c1838de1e',
+ 'bidderRequestId': '22edbae2733bf6',
+ 'auctionId': '1d1a030790a475'
+ }, {
+ 'bidder': 'rads',
+ 'params': {
+ 'placement': '6682',
+ 'pfilter': {
+ 'floorprice': 1000000,
+ 'geo': {
+ 'country': 'DE',
+ 'region': 'DE-BE'
+ },
+ },
+ 'bcat': 'IAB2,IAB4',
+ 'dvt': 'desktop'
+ },
+ 'mediaTypes': {
+ 'video': {
+ 'playerSize': [640, 480],
+ 'context': 'instream'
+ }
+ },
+ 'bidId': '30b31c1838de1e',
+ 'bidderRequestId': '22edbae2733bf6',
+ 'auctionId': '1d1a030790a475'
+ }];
+
+ let bidderRequest = {
+ refererInfo: {
+ referer: 'some_referrer.net'
+ }
+ }
+
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ it('sends bid request to our endpoint via GET', function () {
+ expect(request[0].method).to.equal('GET');
+ let data = request[0].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid');
+ expect(data).to.equal('rt=bid-response&_f=prebid_js&_ps=6682&srw=300&srh=250&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&bcat=IAB2%2CIAB4&dvt=desktop&i=1.1.1.1');
+ });
+
+ it('sends bid video request to our rads endpoint via GET', function () {
+ expect(request[1].method).to.equal('GET');
+ let data = request[1].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid');
+ expect(data).to.equal('rt=vast2&_f=prebid_js&_ps=6682&srw=640&srh=480&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgeo%5D%5Bregion%5D=DE-BE&bcat=IAB2%2CIAB4&dvt=desktop');
+ });
+ });
+
+ describe('interpretResponse', function () {
+ let serverBannerResponse = {
+ 'body': {
+ 'cpm': 5000000,
+ 'crid': 100500,
+ 'width': '300',
+ 'height': '250',
+ 'adTag': '',
+ 'requestId': '220ed41385952a',
+ 'currency': 'EUR',
+ 'ttl': 60,
+ 'netRevenue': true,
+ 'zone': '6682'
+ }
+ };
+ let serverVideoResponse = {
+ 'body': {
+ 'cpm': 5000000,
+ 'crid': 100500,
+ 'width': '300',
+ 'height': '250',
+ 'vastXml': '{"reason":7001,"status":"accepted"}',
+ 'requestId': '220ed41385952a',
+ 'currency': 'EUR',
+ 'ttl': 60,
+ 'netRevenue': true,
+ 'zone': '6682'
+ }
+ };
+
+ let expectedResponse = [{
+ requestId: '23beaa6af6cdde',
+ cpm: 0.5,
+ width: 0,
+ height: 0,
+ creativeId: 100500,
+ dealId: '',
+ currency: 'EUR',
+ netRevenue: true,
+ ttl: 300,
+ ad: ''
+ }, {
+ requestId: '23beaa6af6cdde',
+ cpm: 0.5,
+ width: 0,
+ height: 0,
+ creativeId: 100500,
+ dealId: '',
+ currency: 'EUR',
+ netRevenue: true,
+ ttl: 300,
+ vastXml: '{"reason":7001,"status":"accepted"}',
+ mediaType: 'video'
+ }];
+
+ it('should get the correct bid response by display ad', function () {
+ let bidRequest = [{
+ 'method': 'GET',
+ 'url': RADS_ENDPOINT_URL,
+ 'refererInfo': {
+ 'referer': ''
+ },
+ 'data': {
+ 'bid_id': '30b31c1838de1e'
+ }
+ }];
+ let result = spec.interpretResponse(serverBannerResponse, bidRequest[0]);
+ expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0]));
+ });
+
+ it('should get the correct rads video bid response by display ad', function () {
+ let bidRequest = [{
+ 'method': 'GET',
+ 'url': RADS_ENDPOINT_URL,
+ 'mediaTypes': {
+ 'video': {
+ 'playerSize': [640, 480],
+ 'context': 'instream'
+ }
+ },
+ 'data': {
+ 'bid_id': '30b31c1838de1e'
+ }
+ }];
+ let result = spec.interpretResponse(serverVideoResponse, bidRequest[0]);
+ expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[1]));
+ });
+
+ it('handles empty bid response', function () {
+ let response = {
+ body: {}
+ };
+ let result = spec.interpretResponse(response);
+ expect(result.length).to.equal(0);
+ });
+ });
+});
diff --git a/test/spec/modules/rubiconAnalyticsAdapter_spec.js b/test/spec/modules/rubiconAnalyticsAdapter_spec.js
deleted file mode 100644
index 9c005c3394f..00000000000
--- a/test/spec/modules/rubiconAnalyticsAdapter_spec.js
+++ /dev/null
@@ -1,762 +0,0 @@
-import rubiconAnalyticsAdapter, { SEND_TIMEOUT, parseBidResponse } from 'modules/rubiconAnalyticsAdapter';
-import CONSTANTS from 'src/constants.json';
-import { config } from 'src/config';
-
-import {
- setConfig,
- addBidResponseHook,
-} from 'modules/currency';
-
-let Ajv = require('ajv');
-let schema = require('./rubiconAnalyticsSchema.json');
-let ajv = new Ajv({
- allErrors: true
-});
-
-let validator = ajv.compile(schema);
-
-function validate(message) {
- validator(message);
- expect(validator.errors).to.deep.equal(null);
-}
-
-// using es6 "import * as events from 'src/events'" causes the events.getEvents stub not to work...
-let events = require('src/events');
-let ajax = require('src/ajax');
-let utils = require('src/utils');
-
-const {
- EVENTS: {
- AUCTION_INIT,
- AUCTION_END,
- BID_REQUESTED,
- BID_RESPONSE,
- BIDDER_DONE,
- BID_WON,
- BID_TIMEOUT,
- SET_TARGETING
- }
-} = CONSTANTS;
-
-const BID = {
- 'bidder': 'rubicon',
- 'width': 640,
- 'height': 480,
- 'mediaType': 'video',
- 'statusMessage': 'Bid available',
- 'bidId': '2ecff0db240757',
- 'adId': 'fake_ad_id',
- 'source': 'client',
- 'requestId': '2ecff0db240757',
- 'currency': 'USD',
- 'creativeId': '3571560',
- 'cpm': 1.22752,
- 'ttl': 300,
- 'netRevenue': false,
- 'ad': '',
- 'rubiconTargeting': {
- 'rpfl_elemid': '/19968336/header-bid-tag-0',
- 'rpfl_14062': '2_tier0100'
- },
- 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa',
- 'responseTimestamp': 1519149629415,
- 'requestTimestamp': 1519149628471,
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'timeToRespond': 944,
- 'pbLg': '1.00',
- 'pbMg': '1.20',
- 'pbHg': '1.22',
- 'pbAg': '1.20',
- 'pbDg': '1.22',
- 'pbCg': '',
- 'size': '640x480',
- 'adserverTargeting': {
- 'hb_bidder': 'rubicon',
- 'hb_adid': '2ecff0db240757',
- 'hb_pb': 1.20,
- 'hb_size': '640x480',
- 'hb_source': 'client'
- },
- getStatusCode() {
- return 1;
- }
-};
-
-const BID2 = Object.assign({}, BID, {
- adUnitCode: '/19968336/header-bid-tag1',
- bidId: '3bd4ebb1c900e2',
- adId: 'fake_ad_id',
- requestId: '3bd4ebb1c900e2',
- width: 728,
- height: 90,
- mediaType: 'banner',
- cpm: 1.52,
- source: 'server',
- rubiconTargeting: {
- 'rpfl_elemid': '/19968336/header-bid-tag1',
- 'rpfl_14062': '2_tier0100'
- },
- adserverTargeting: {
- 'hb_bidder': 'rubicon',
- 'hb_adid': '3bd4ebb1c900e2',
- 'hb_pb': '1.500',
- 'hb_size': '728x90',
- 'hb_source': 'server'
- }
-});
-
-const MOCK = {
- SET_TARGETING: {
- [BID.adUnitCode]: BID.adserverTargeting,
- [BID2.adUnitCode]: BID2.adserverTargeting
- },
- AUCTION_INIT: {
- 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa',
- 'timestamp': 1519767010567,
- 'auctionStatus': 'inProgress',
- 'adUnits': [ {
- 'code': '/19968336/header-bid-tag1',
- 'sizes': [[640, 480]],
- 'bids': [ {
- 'bidder': 'rubicon',
- 'params': {
- 'accountId': 1001, 'siteId': 113932, 'zoneId': 535512
- }
- } ],
- 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014'
- }
- ],
- 'adUnitCodes': ['/19968336/header-bid-tag1'],
- 'bidderRequests': [ {
- 'bidderCode': 'rubicon',
- 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa',
- 'bidderRequestId': '1be65d7958826a',
- 'bids': [ {
- 'bidder': 'rubicon',
- 'params': {
- 'accountId': 1001, 'siteId': 113932, 'zoneId': 535512
- },
- 'mediaTypes': {
- 'banner': {
- 'sizes': [[640, 480]]
- }
- },
- 'adUnitCode': '/19968336/header-bid-tag1',
- 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014',
- 'sizes': [[640, 480]],
- 'bidId': '2ecff0db240757',
- 'bidderRequestId': '1be65d7958826a',
- 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa',
- 'src': 'client',
- 'bidRequestsCount': 1
- }
- ],
- 'timeout': 3000,
- 'refererInfo': {
- 'referer': 'http://www.test.com/page.html', 'reachedTop': true, 'numIframes': 0, 'stack': ['http://www.test.com/page.html']
- }
- }
- ],
- 'bidsReceived': [],
- 'winningBids': [],
- 'timeout': 3000,
- 'config': {
- 'accountId': 1001, 'endpoint': '//localhost:9999/event'
- }
- },
- BID_REQUESTED: {
- 'bidder': 'rubicon',
- 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa',
- 'bidderRequestId': '1be65d7958826a',
- 'bids': [
- {
- 'bidder': 'rubicon',
- 'params': {
- 'accountId': '1001',
- 'siteId': '70608',
- 'zoneId': '335918',
- 'userId': '12346',
- 'keywords': ['a', 'b', 'c'],
- 'inventory': 'test',
- 'visitor': {'ucat': 'new', 'lastsearch': 'iphone'},
- 'position': 'btf',
- 'video': {
- 'language': 'en',
- 'playerHeight': 480,
- 'playerWidth': 640,
- 'size_id': 203,
- 'skip': 1,
- 'skipdelay': 15,
- 'aeParams': {
- 'p_aso.video.ext.skip': '1',
- 'p_aso.video.ext.skipdelay': '15'
- }
- }
- },
- 'mediaType': 'video',
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014',
- 'sizes': [[640, 480]],
- 'bidId': '2ecff0db240757',
- 'bidderRequestId': '1be65d7958826a',
- 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa'
- },
- {
- 'bidder': 'rubicon',
- 'params': {
- 'accountId': '14062',
- 'siteId': '70608',
- 'zoneId': '335918',
- 'userId': '12346',
- 'keywords': ['a', 'b', 'c'],
- 'inventory': {'rating': '4-star', 'prodtype': 'tech'},
- 'visitor': {'ucat': 'new', 'lastsearch': 'iphone'},
- 'position': 'atf'
- },
- 'mediaTypes': {
- 'banner': {
- 'sizes': [[1000, 300], [970, 250], [728, 90]]
- }
- },
- 'adUnitCode': '/19968336/header-bid-tag1',
- 'transactionId': 'c116413c-9e3f-401a-bee1-d56aec29a1d4',
- 'sizes': [[1000, 300], [970, 250], [728, 90]],
- 'bidId': '3bd4ebb1c900e2',
- 'bidderRequestId': '1be65d7958826a',
- 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa'
- }
- ],
- 'auctionStart': 1519149536560,
- 'timeout': 5000,
- 'start': 1519149562216
- },
- BID_RESPONSE: [
- BID,
- BID2
- ],
- AUCTION_END: {
- 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa'
- },
- BID_WON: [
- Object.assign({}, BID, {
- 'status': 'rendered'
- }),
- Object.assign({}, BID2, {
- 'status': 'rendered'
- })
- ],
- BIDDER_DONE: {
- 'bidderCode': 'rubicon',
- 'bids': [
- BID,
- Object.assign({}, BID2, {
- 'serverResponseTimeMs': 42,
- })
- ]
- },
- BID_TIMEOUT: [
- {
- 'bidId': '2ecff0db240757',
- 'bidder': 'rubicon',
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa'
- }
- ]
-};
-
-const ANALYTICS_MESSAGE = {
- 'eventTimeMillis': 1519767013781,
- 'integration': 'pbjs',
- 'version': '$prebid.version$',
- 'referrerUri': 'http://www.test.com/page.html',
- 'auctions': [
- {
- 'clientTimeoutMillis': 3000,
- 'serverTimeoutMillis': 1000,
- 'accountId': 1001,
- 'samplingFactor': 1,
- 'adUnits': [
- {
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014',
- 'videoAdFormat': 'outstream',
- 'mediaTypes': [
- 'video'
- ],
- 'dimensions': [
- {
- 'width': 640,
- 'height': 480
- }
- ],
- 'status': 'success',
- 'accountId': 1001,
- 'siteId': 70608,
- 'zoneId': 335918,
- 'adserverTargeting': {
- 'hb_bidder': 'rubicon',
- 'hb_adid': '2ecff0db240757',
- 'hb_pb': '1.200',
- 'hb_size': '640x480',
- 'hb_source': 'client'
- },
- 'bids': [
- {
- 'bidder': 'rubicon',
- 'bidId': '2ecff0db240757',
- 'status': 'success',
- 'source': 'client',
- 'clientLatencyMillis': 3214,
- 'params': {
- 'accountId': '1001',
- 'siteId': '70608',
- 'zoneId': '335918'
- },
- 'bidResponse': {
- 'bidPriceUSD': 1.22752,
- 'dimensions': {
- 'width': 640,
- 'height': 480
- },
- 'mediaType': 'video'
- }
- }
- ]
- },
- {
- 'adUnitCode': '/19968336/header-bid-tag1',
- 'transactionId': 'c116413c-9e3f-401a-bee1-d56aec29a1d4',
- 'mediaTypes': [
- 'banner'
- ],
- 'dimensions': [
- {
- 'width': 1000,
- 'height': 300
- },
- {
- 'width': 970,
- 'height': 250
- },
- {
- 'width': 728,
- 'height': 90
- }
- ],
- 'status': 'success',
- 'adserverTargeting': {
- 'hb_bidder': 'rubicon',
- 'hb_adid': '3bd4ebb1c900e2',
- 'hb_pb': '1.500',
- 'hb_size': '728x90',
- 'hb_source': 'server'
- },
- 'bids': [
- {
- 'bidder': 'rubicon',
- 'bidId': '3bd4ebb1c900e2',
- 'status': 'success',
- 'source': 'server',
- 'clientLatencyMillis': 3214,
- 'serverLatencyMillis': 42,
- 'params': {
- 'accountId': '14062',
- 'siteId': '70608',
- 'zoneId': '335918'
- },
- 'bidResponse': {
- 'bidPriceUSD': 1.52,
- 'dimensions': {
- 'width': 728,
- 'height': 90
- },
- 'mediaType': 'banner'
- }
- }
- ]
- }
- ]
- }
- ],
- 'bidsWon': [
- {
- 'bidder': 'rubicon',
- 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014',
- 'adUnitCode': '/19968336/header-bid-tag-0',
- 'bidId': '2ecff0db240757',
- 'status': 'success',
- 'source': 'client',
- 'clientLatencyMillis': 3214,
- 'samplingFactor': 1,
- 'accountId': 1001,
- 'siteId': 70608,
- 'zoneId': 335918,
- 'params': {
- 'accountId': '1001',
- 'siteId': '70608',
- 'zoneId': '335918'
- },
- 'videoAdFormat': 'outstream',
- 'mediaTypes': [
- 'video'
- ],
- 'adserverTargeting': {
- 'hb_bidder': 'rubicon',
- 'hb_adid': '2ecff0db240757',
- 'hb_pb': '1.200',
- 'hb_size': '640x480',
- 'hb_source': 'client'
- },
- 'bidResponse': {
- 'bidPriceUSD': 1.22752,
- 'dimensions': {
- 'width': 640,
- 'height': 480
- },
- 'mediaType': 'video'
- },
- 'bidwonStatus': 'success'
- },
- {
- 'bidder': 'rubicon',
- 'transactionId': 'c116413c-9e3f-401a-bee1-d56aec29a1d4',
- 'adUnitCode': '/19968336/header-bid-tag1',
- 'bidId': '3bd4ebb1c900e2',
- 'status': 'success',
- 'source': 'server',
- 'clientLatencyMillis': 3214,
- 'serverLatencyMillis': 42,
- 'samplingFactor': 1,
- 'accountId': 1001,
- 'params': {
- 'accountId': '14062',
- 'siteId': '70608',
- 'zoneId': '335918'
- },
- 'mediaTypes': [
- 'banner'
- ],
- 'adserverTargeting': {
- 'hb_bidder': 'rubicon',
- 'hb_adid': '3bd4ebb1c900e2',
- 'hb_pb': '1.500',
- 'hb_size': '728x90',
- 'hb_source': 'server'
- },
- 'bidResponse': {
- 'bidPriceUSD': 1.52,
- 'dimensions': {
- 'width': 728,
- 'height': 90
- },
- 'mediaType': 'banner'
- },
- 'bidwonStatus': 'success'
- }
- ],
- 'wrapperName': '10000_fakewrapper_test'
-};
-
-function performStandardAuction() {
- events.emit(AUCTION_INIT, MOCK.AUCTION_INIT);
- events.emit(BID_REQUESTED, MOCK.BID_REQUESTED);
- events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]);
- events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]);
- events.emit(BIDDER_DONE, MOCK.BIDDER_DONE);
- events.emit(AUCTION_END, MOCK.AUCTION_END);
- events.emit(SET_TARGETING, MOCK.SET_TARGETING);
- events.emit(BID_WON, MOCK.BID_WON[0]);
- events.emit(BID_WON, MOCK.BID_WON[1]);
-}
-
-describe('rubicon analytics adapter', function () {
- let sandbox;
- let xhr;
- let requests;
- let oldScreen;
- let clock;
-
- beforeEach(function () {
- sandbox = sinon.sandbox.create();
-
- xhr = sandbox.useFakeXMLHttpRequest();
- requests = [];
- xhr.onCreate = request => requests.push(request);
-
- sandbox.stub(events, 'getEvents').returns([]);
-
- sandbox.stub(utils, 'getTopWindowUrl').returns('http://www.test.com/page.html');
-
- clock = sandbox.useFakeTimers(1519767013781);
-
- config.setConfig({
- s2sConfig: {
- timeout: 1000,
- accountId: 10000,
- },
- rubicon: {
- wrapperName: '10000_fakewrapper_test'
- }
- })
- });
-
- afterEach(function () {
- sandbox.restore();
- config.resetConfig();
- });
-
- it('should require accountId', function () {
- sandbox.stub(utils, 'logError');
-
- rubiconAnalyticsAdapter.enableAnalytics({
- options: {
- endpoint: '//localhost:9999/event'
- }
- });
-
- expect(utils.logError.called).to.equal(true);
- });
-
- it('should require endpoint', function () {
- sandbox.stub(utils, 'logError');
-
- rubiconAnalyticsAdapter.enableAnalytics({
- options: {
- accountId: 1001
- }
- });
-
- expect(utils.logError.called).to.equal(true);
- });
-
- describe('sampling', function () {
- beforeEach(function () {
- sandbox.stub(Math, 'random').returns(0.08);
- sandbox.stub(utils, 'logError');
- });
-
- afterEach(function () {
- rubiconAnalyticsAdapter.disableAnalytics();
- });
-
- describe('with options.samplingFactor', function () {
- it('should sample', function () {
- rubiconAnalyticsAdapter.enableAnalytics({
- options: {
- endpoint: '//localhost:9999/event',
- accountId: 1001,
- samplingFactor: 10
- }
- });
-
- performStandardAuction();
-
- expect(requests.length).to.equal(1);
- });
-
- it('should unsample', function () {
- rubiconAnalyticsAdapter.enableAnalytics({
- options: {
- endpoint: '//localhost:9999/event',
- accountId: 1001,
- samplingFactor: 20
- }
- });
-
- performStandardAuction();
-
- expect(requests.length).to.equal(0);
- });
-
- it('should throw errors for invalid samplingFactor', function () {
- rubiconAnalyticsAdapter.enableAnalytics({
- options: {
- endpoint: '//localhost:9999/event',
- accountId: 1001,
- samplingFactor: 30
- }
- });
-
- performStandardAuction();
-
- expect(requests.length).to.equal(0);
- expect(utils.logError.called).to.equal(true);
- });
- });
- describe('with options.sampling', function () {
- it('should sample', function () {
- rubiconAnalyticsAdapter.enableAnalytics({
- options: {
- endpoint: '//localhost:9999/event',
- accountId: 1001,
- sampling: 0.1
- }
- });
-
- performStandardAuction();
-
- expect(requests.length).to.equal(1);
- });
-
- it('should unsample', function () {
- rubiconAnalyticsAdapter.enableAnalytics({
- options: {
- endpoint: '//localhost:9999/event',
- accountId: 1001,
- sampling: 0.05
- }
- });
-
- performStandardAuction();
-
- expect(requests.length).to.equal(0);
- });
-
- it('should throw errors for invalid samplingFactor', function () {
- rubiconAnalyticsAdapter.enableAnalytics({
- options: {
- endpoint: '//localhost:9999/event',
- accountId: 1001,
- sampling: 1 / 30
- }
- });
-
- performStandardAuction();
-
- expect(requests.length).to.equal(0);
- expect(utils.logError.called).to.equal(true);
- });
- });
- });
-
- describe('when handling events', function () {
- beforeEach(function () {
- rubiconAnalyticsAdapter.enableAnalytics({
- options: {
- endpoint: '//localhost:9999/event',
- accountId: 1001
- }
- });
- });
-
- afterEach(function () {
- rubiconAnalyticsAdapter.disableAnalytics();
- });
-
- it('should build a batched message from prebid events', function () {
- performStandardAuction();
-
- expect(requests.length).to.equal(1);
- let request = requests[0];
-
- expect(request.url).to.equal('//localhost:9999/event');
-
- let message = JSON.parse(request.requestBody);
- validate(message);
-
- expect(message).to.deep.equal(ANALYTICS_MESSAGE);
- });
-
- it('should send batched message without BID_WON if necessary and further BID_WON events individually', function () {
- events.emit(AUCTION_INIT, MOCK.AUCTION_INIT);
- events.emit(BID_REQUESTED, MOCK.BID_REQUESTED);
- events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]);
- events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]);
- events.emit(BIDDER_DONE, MOCK.BIDDER_DONE);
- events.emit(AUCTION_END, MOCK.AUCTION_END);
- events.emit(SET_TARGETING, MOCK.SET_TARGETING);
- events.emit(BID_WON, MOCK.BID_WON[0]);
-
- clock.tick(SEND_TIMEOUT + 1000);
-
- events.emit(BID_WON, MOCK.BID_WON[1]);
-
- expect(requests.length).to.equal(2);
-
- let message = JSON.parse(requests[0].requestBody);
- validate(message);
- expect(message.bidsWon.length).to.equal(1);
- expect(message.auctions).to.deep.equal(ANALYTICS_MESSAGE.auctions);
- expect(message.bidsWon[0]).to.deep.equal(ANALYTICS_MESSAGE.bidsWon[0]);
-
- message = JSON.parse(requests[1].requestBody);
- validate(message);
- expect(message.bidsWon.length).to.equal(1);
- expect(message).to.not.have.property('auctions');
- expect(message.bidsWon[0]).to.deep.equal(ANALYTICS_MESSAGE.bidsWon[1]);
- });
-
- it('should properly mark bids as timed out', function () {
- events.emit(AUCTION_INIT, MOCK.AUCTION_INIT);
- events.emit(BID_REQUESTED, MOCK.BID_REQUESTED);
- events.emit(BID_TIMEOUT, MOCK.BID_TIMEOUT);
- events.emit(AUCTION_END, MOCK.AUCTION_END);
-
- clock.tick(SEND_TIMEOUT + 1000);
-
- expect(requests.length).to.equal(1);
-
- let message = JSON.parse(requests[0].requestBody);
- validate(message);
- let timedOutBid = message.auctions[0].adUnits[0].bids[0];
- expect(timedOutBid.status).to.equal('error');
- expect(timedOutBid.error.code).to.equal('timeout-error');
- expect(timedOutBid).to.not.have.property('bidResponse');
- });
-
- it('should successfully convert bid price to USD in parseBidResponse', function () {
- // Set the rates
- setConfig({
- adServerCurrency: 'JPY',
- rates: {
- USD: {
- JPY: 100
- }
- }
- });
-
- // set our bid response to JPY
- const bidCopy = utils.deepClone(BID2);
- bidCopy.currency = 'JPY';
- bidCopy.cpm = 100;
-
- // Now add the bidResponse hook which hooks on the currenct conversion function onto the bid response
- let innerBid;
- addBidResponseHook(function(adCodeId, bid) {
- innerBid = bid;
- }, 'elementId', bidCopy);
-
- // Use the rubi analytics parseBidResponse Function to get the resulting cpm from the bid response!
- const bidResponseObj = parseBidResponse(innerBid);
- expect(bidResponseObj).to.have.property('bidPriceUSD');
- expect(bidResponseObj.bidPriceUSD).to.equal(1.0);
- });
- });
-
- describe('config with integration type', () => {
- it('should use the integration type provided in the config instead of the default', () => {
- sandbox.stub(config, 'getConfig').callsFake(function (key) {
- const config = {
- 'rubicon.int_type': 'testType'
- };
- return config[key];
- });
-
- rubiconAnalyticsAdapter.enableAnalytics({
- options: {
- endpoint: '//localhost:9999/event',
- accountId: 1001
- }
- });
-
- performStandardAuction();
-
- expect(requests.length).to.equal(1);
- const request = requests[0];
- const message = JSON.parse(request.requestBody);
- expect(message.integration).to.equal('testType');
-
- rubiconAnalyticsAdapter.disableAnalytics();
- });
- });
-});
diff --git a/test/spec/modules/tripleliftBidAdapter_spec.js b/test/spec/modules/tripleliftBidAdapter_spec.js
index 52a7be3020c..190f463f7a5 100644
--- a/test/spec/modules/tripleliftBidAdapter_spec.js
+++ b/test/spec/modules/tripleliftBidAdapter_spec.js
@@ -54,46 +54,49 @@ describe('triplelift adapter', function () {
});
describe('buildRequests', function () {
- let bidRequests = [
- {
- bidder: 'triplelift',
- params: {
- inventoryCode: '12345',
- floor: 1.0,
- },
- adUnitCode: 'adunit-code',
- sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']],
- bidId: '30b31c1838de1e',
- bidderRequestId: '22edbae2733bf6',
- auctionId: '1d1a030790a475',
- }
- ];
+ let bidRequests;
+ let bidderRequest;
- let bidderRequest = {
- bidderCode: 'triplelift',
- auctionId: 'a7ebcd1d-66ff-4b5c-a82c-6a21a6ee5a18',
- bidderRequestId: '5c55612f99bc11',
- bids: [
+ this.beforeEach(() => {
+ bidRequests = [
{
- imp_id: 0,
- cpm: 1.062,
- width: 300,
- height: 250,
- ad: 'ad-markup',
- iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg'
+ bidder: 'triplelift',
+ params: {
+ inventoryCode: '12345',
+ floor: 1.0,
+ },
+ adUnitCode: 'adunit-code',
+ sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']],
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ userId: {},
}
- ],
- refererInfo: {
- referer: 'http://examplereferer.com'
- },
- gdprConsent: {
- consentString: 'BOONm0NOONm0NABABAENAa-AAAARh7______b9_3__7_9uz_Kv_K7Vf7nnG072lPVA9LTOQ6gEaY',
- gdprApplies: true
- },
- userId: {
- tdid: '6bca7f6b-a98a-46c0-be05-6020f7604598'
- }
- };
+ ];
+
+ bidderRequest = {
+ bidderCode: 'triplelift',
+ auctionId: 'a7ebcd1d-66ff-4b5c-a82c-6a21a6ee5a18',
+ bidderRequestId: '5c55612f99bc11',
+ bids: [
+ {
+ imp_id: 0,
+ cpm: 1.062,
+ width: 300,
+ height: 250,
+ ad: 'ad-markup',
+ iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg'
+ }
+ ],
+ refererInfo: {
+ referer: 'http://examplereferer.com'
+ },
+ gdprConsent: {
+ consentString: 'BOONm0NOONm0NABABAENAa-AAAARh7______b9_3__7_9uz_Kv_K7Vf7nnG072lPVA9LTOQ6gEaY',
+ gdprApplies: true
+ },
+ };
+ });
it('exists and is an object', function () {
const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
@@ -116,10 +119,95 @@ describe('triplelift adapter', function () {
});
it('should add tdid to the payload if included', function () {
+ const id = '6bca7f6b-a98a-46c0-be05-6020f7604598';
+ bidRequests[0].userId.tdid = id;
+ const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
+ const payload = request.data;
+ expect(payload).to.exist;
+ expect(payload.user).to.deep.equal({ext: {eids: [{source: 'adserver.org', uids: [{id, ext: {rtiPartner: 'TDID'}}]}]}});
+ });
+
+ it('should add idl_env to the payload if included', function () {
+ const id = 'XY6104gr0njcH9UDIR7ysFFJcm2XNpqeJTYslleJ_cMlsFOfZI';
+ bidRequests[0].userId.idl_env = id;
+ const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
+ const payload = request.data;
+ expect(payload).to.exist;
+ expect(payload.user).to.deep.equal({ext: {eids: [{source: 'liveramp.com', uids: [{id, ext: {rtiPartner: 'idl'}}]}]}});
+ });
+
+ it('should add both tdid and idl_env to the payload if both are included', function () {
+ const tdidId = '6bca7f6b-a98a-46c0-be05-6020f7604598';
+ const idlEnvId = 'XY6104gr0njcH9UDIR7ysFFJcm2XNpqeJTYslleJ_cMlsFOfZI';
+ bidRequests[0].userId.tdid = tdidId;
+ bidRequests[0].userId.idl_env = idlEnvId;
+
const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
const payload = request.data;
+
expect(payload).to.exist;
- expect(payload.user).to.deep.equal({ext: {eids: [{source: 'adserver.org', uids: [{id: '6bca7f6b-a98a-46c0-be05-6020f7604598', ext: {rtiPartner: 'TDID'}}]}]}});
+ expect(payload.user).to.deep.equal({
+ ext: {
+ eids: [
+ {
+ source: 'adserver.org',
+ uids: [
+ {
+ id: tdidId,
+ ext: { rtiPartner: 'TDID' }
+ }
+ ],
+ },
+ {
+ source: 'liveramp.com',
+ uids: [
+ {
+ id: idlEnvId,
+ ext: { rtiPartner: 'idl' }
+ }
+ ]
+ }
+ ]
+ }
+ });
+ });
+
+ it('should add user ids from multiple bid requests', function () {
+ const tdidId = '6bca7f6b-a98a-46c0-be05-6020f7604598';
+ const idlEnvId = 'XY6104gr0njcH9UDIR7ysFFJcm2XNpqeJTYslleJ_cMlsFOfZI';
+
+ const bidRequestsMultiple = [
+ { ...bidRequests[0], userId: { tdid: tdidId } },
+ { ...bidRequests[0], userId: { idl_env: idlEnvId } },
+ ];
+
+ const request = tripleliftAdapterSpec.buildRequests(bidRequestsMultiple, bidderRequest);
+ const payload = request.data;
+
+ expect(payload.user).to.deep.equal({
+ ext: {
+ eids: [
+ {
+ source: 'adserver.org',
+ uids: [
+ {
+ id: tdidId,
+ ext: { rtiPartner: 'TDID' }
+ }
+ ],
+ },
+ {
+ source: 'liveramp.com',
+ uids: [
+ {
+ id: idlEnvId,
+ ext: { rtiPartner: 'idl' }
+ }
+ ]
+ }
+ ]
+ }
+ });
});
it('should return a query string for TL call', function () {
diff --git a/test/spec/modules/turktelekomBidAdapter_spec.js b/test/spec/modules/turktelekomBidAdapter_spec.js
new file mode 100644
index 00000000000..066d2724a97
--- /dev/null
+++ b/test/spec/modules/turktelekomBidAdapter_spec.js
@@ -0,0 +1,749 @@
+import { expect } from 'chai';
+import { spec } from 'modules/turktelekomBidAdapter';
+import { newBidder } from 'src/adapters/bidderFactory';
+
+describe('TurkTelekomAdapter', 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': 'turktelekom',
+ 'params': {
+ 'uid': '17'
+ },
+ '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 () {
+ let bid = Object.assign({}, bid);
+ delete bid.params;
+ bid.params = {
+ 'uid': 0
+ };
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
+ });
+ });
+
+ describe('buildRequests', function () {
+ function parseRequest(url) {
+ const res = {};
+ url.split('&').forEach((it) => {
+ const couple = it.split('=');
+ res[couple[0]] = decodeURIComponent(couple[1]);
+ });
+ return res;
+ }
+
+ const bidderRequest = {
+ refererInfo: {
+ referer: 'http://example.com'
+ }
+ };
+ const referrer = bidderRequest.refererInfo.referer;
+
+ let bidRequests = [
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '18'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '30b31c1838de1e',
+ 'bidderRequestId': '22edbae2733bf6',
+ 'auctionId': '1d1a030790a475',
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '18'
+ },
+ 'adUnitCode': 'adunit-code-2',
+ 'sizes': [[728, 90], [300, 250]],
+ 'bidId': '3150ccb55da321',
+ 'bidderRequestId': '22edbae2733bf6',
+ 'auctionId': '1d1a030790a475',
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '20'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '42dbe3a7168a6a',
+ 'bidderRequestId': '22edbae2733bf6',
+ 'auctionId': '1d1a030790a475',
+ }
+ ];
+
+ it('should attach valid params to the tag', function () {
+ const request = spec.buildRequests([bidRequests[0]], bidderRequest);
+ expect(request.data).to.be.an('string');
+ const payload = parseRequest(request.data);
+ expect(payload).to.have.property('u', referrer);
+ expect(payload).to.have.property('pt', 'net');
+ expect(payload).to.have.property('auids', '18');
+ expect(payload).to.have.property('sizes', '300x250,300x600');
+ expect(payload).to.have.property('r', '22edbae2733bf6');
+ expect(payload).to.have.property('wrapperType', 'Prebid_js');
+ expect(payload).to.have.property('wrapperVersion', '$prebid.version$');
+ });
+
+ it('sizes must not be duplicated', function () {
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data).to.be.an('string');
+ const payload = parseRequest(request.data);
+ expect(payload).to.have.property('u', referrer);
+ expect(payload).to.have.property('pt', 'net');
+ expect(payload).to.have.property('auids', '18,18,20');
+ expect(payload).to.have.property('sizes', '300x250,300x600,728x90');
+ expect(payload).to.have.property('r', '22edbae2733bf6');
+ });
+
+ it('pt parameter must be "gross" if params.priceType === "gross"', function () {
+ bidRequests[1].params.priceType = 'gross';
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data).to.be.an('string');
+ const payload = parseRequest(request.data);
+ expect(payload).to.have.property('u', referrer);
+ expect(payload).to.have.property('pt', 'gross');
+ expect(payload).to.have.property('auids', '18,18,20');
+ expect(payload).to.have.property('sizes', '300x250,300x600,728x90');
+ expect(payload).to.have.property('r', '22edbae2733bf6');
+ delete bidRequests[1].params.priceType;
+ });
+
+ it('pt parameter must be "net" or "gross"', function () {
+ bidRequests[1].params.priceType = 'some';
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data).to.be.an('string');
+ const payload = parseRequest(request.data);
+ expect(payload).to.have.property('u', referrer);
+ expect(payload).to.have.property('pt', 'net');
+ expect(payload).to.have.property('auids', '18,18,20');
+ expect(payload).to.have.property('sizes', '300x250,300x600,728x90');
+ expect(payload).to.have.property('r', '22edbae2733bf6');
+ delete bidRequests[1].params.priceType;
+ });
+
+ it('if gdprConsent is present payload must have gdpr params', function () {
+ const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA', gdprApplies: true}}, bidderRequest);
+ const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR);
+ expect(request.data).to.be.an('string');
+ const payload = parseRequest(request.data);
+ expect(payload).to.have.property('gdpr_consent', 'AAA');
+ expect(payload).to.have.property('gdpr_applies', '1');
+ });
+
+ it('if gdprApplies is false gdpr_applies must be 0', function () {
+ const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA', gdprApplies: false}}, bidderRequest);
+ const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR);
+ expect(request.data).to.be.an('string');
+ const payload = parseRequest(request.data);
+ expect(payload).to.have.property('gdpr_consent', 'AAA');
+ expect(payload).to.have.property('gdpr_applies', '0');
+ });
+
+ it('if gdprApplies is undefined gdpr_applies must be 1', function () {
+ const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA'}}, bidderRequest);
+ const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR);
+ expect(request.data).to.be.an('string');
+ const payload = parseRequest(request.data);
+ expect(payload).to.have.property('gdpr_consent', 'AAA');
+ expect(payload).to.have.property('gdpr_applies', '1');
+ });
+ });
+
+ describe('interpretResponse', function () {
+ const responses = [
+ {'bid': [{'price': 1.15, 'adm': 'test content 1
', 'auid': 17, 'h': 250, 'w': 300}], 'seat': '1'},
+ {'bid': [{'price': 0.5, 'adm': 'test content 2
', 'auid': 18, 'h': 600, 'w': 300}], 'seat': '1'},
+ {'bid': [{'price': 0.15, 'adm': 'test content 3
', 'auid': 17, 'h': 90, 'w': 728}], 'seat': '1'},
+ {'bid': [{'price': 0, 'auid': 19, 'h': 250, 'w': 300}], 'seat': '1'},
+ {'bid': [{'price': 0, 'adm': 'test content 5
', 'h': 250, 'w': 300}], 'seat': '1'},
+ undefined,
+ {'bid': [], 'seat': '1'},
+ {'seat': '1'},
+ ];
+
+ it('should get correct bid response', function () {
+ const bidRequests = [
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '17'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '659423fff799cb',
+ 'bidderRequestId': '5f2009617a7c0a',
+ 'auctionId': '1cbd2feafe5e8b',
+ }
+ ];
+ const request = spec.buildRequests(bidRequests);
+ const expectedResponse = [
+ {
+ 'requestId': '659423fff799cb',
+ 'cpm': 1.15,
+ 'creativeId': 17,
+ 'dealId': undefined,
+ 'width': 300,
+ 'height': 250,
+ 'ad': 'test content 1
',
+ 'bidderCode': 'turktelekom',
+ 'currency': 'TRY',
+ 'mediaType': 'banner',
+ 'netRevenue': true,
+ 'ttl': 360,
+ }
+ ];
+
+ const result = spec.interpretResponse({'body': {'seatbid': [responses[0]]}}, request);
+ expect(result).to.deep.equal(expectedResponse);
+ });
+
+ it('should get correct multi bid response', function () {
+ const bidRequests = [
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '17'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '300bfeb0d71a5b',
+ 'bidderRequestId': '2c2bb1972df9a',
+ 'auctionId': '1fa09aee5c8c99',
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '18'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '4dff80cc4ee346',
+ 'bidderRequestId': '2c2bb1972df9a',
+ 'auctionId': '1fa09aee5c8c99',
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '17'
+ },
+ 'adUnitCode': 'adunit-code-2',
+ 'sizes': [[728, 90]],
+ 'bidId': '5703af74d0472a',
+ 'bidderRequestId': '2c2bb1972df9a',
+ 'auctionId': '1fa09aee5c8c99',
+ }
+ ];
+ const request = spec.buildRequests(bidRequests);
+ const expectedResponse = [
+ {
+ 'requestId': '300bfeb0d71a5b',
+ 'cpm': 1.15,
+ 'creativeId': 17,
+ 'dealId': undefined,
+ 'width': 300,
+ 'height': 250,
+ 'ad': 'test content 1
',
+ 'bidderCode': 'turktelekom',
+ 'currency': 'TRY',
+ 'mediaType': 'banner',
+ 'netRevenue': true,
+ 'ttl': 360,
+ },
+ {
+ 'requestId': '4dff80cc4ee346',
+ 'cpm': 0.5,
+ 'creativeId': 18,
+ 'dealId': undefined,
+ 'width': 300,
+ 'height': 600,
+ 'ad': 'test content 2
',
+ 'bidderCode': 'turktelekom',
+ 'currency': 'TRY',
+ 'mediaType': 'banner',
+ 'netRevenue': true,
+ 'ttl': 360,
+ },
+ {
+ 'requestId': '5703af74d0472a',
+ 'cpm': 0.15,
+ 'creativeId': 17,
+ 'dealId': undefined,
+ 'width': 728,
+ 'height': 90,
+ 'ad': 'test content 3
',
+ 'bidderCode': 'turktelekom',
+ 'currency': 'TRY',
+ 'mediaType': 'banner',
+ 'netRevenue': true,
+ 'ttl': 360,
+ }
+ ];
+
+ const result = spec.interpretResponse({'body': {'seatbid': responses.slice(0, 3)}}, request);
+ expect(result).to.deep.equal(expectedResponse);
+ });
+
+ it('handles wrong and nobid responses', function () {
+ const bidRequests = [
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '19'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '300bfeb0d7190gf',
+ 'bidderRequestId': '2c2bb1972d23af',
+ 'auctionId': '1fa09aee5c84d34',
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '20'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '300bfeb0d71321',
+ 'bidderRequestId': '2c2bb1972d23af',
+ 'auctionId': '1fa09aee5c84d34',
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '25'
+ },
+ 'adUnitCode': 'adunit-code-2',
+ 'sizes': [[728, 90]],
+ 'bidId': '300bfeb0d7183bb',
+ 'bidderRequestId': '2c2bb1972d23af',
+ 'auctionId': '1fa09aee5c84d34',
+ }
+ ];
+ const request = spec.buildRequests(bidRequests);
+ const result = spec.interpretResponse({'body': {'seatbid': responses.slice(3)}}, request);
+ expect(result.length).to.equal(0);
+ });
+
+ it('complicated case', function () {
+ const fullResponse = [
+ {'bid': [{'price': 1.15, 'adm': 'test content 1
', 'auid': 17, 'h': 250, 'w': 300}], 'seat': '1'},
+ {'bid': [{'price': 0.5, 'adm': 'test content 2
', 'auid': 18, 'h': 600, 'w': 300}], 'seat': '1'},
+ {'bid': [{'price': 0.15, 'adm': 'test content 3
', 'auid': 17, 'h': 90, 'w': 728}], 'seat': '1'},
+ {'bid': [{'price': 0.15, 'adm': 'test content 4
', 'auid': 17, 'h': 600, 'w': 300}], 'seat': '1'},
+ {'bid': [{'price': 0.5, 'adm': 'test content 5
', 'auid': 18, 'h': 600, 'w': 350}], 'seat': '1'},
+ ];
+ const bidRequests = [
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '17'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '2164be6358b9',
+ 'bidderRequestId': '106efe3247',
+ 'auctionId': '32a1f276cb87cb8',
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '17'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '326bde7fbf69',
+ 'bidderRequestId': '106efe3247',
+ 'auctionId': '32a1f276cb87cb8',
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '18'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '4e111f1b66e4',
+ 'bidderRequestId': '106efe3247',
+ 'auctionId': '32a1f276cb87cb8',
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '17'
+ },
+ 'adUnitCode': 'adunit-code-2',
+ 'sizes': [[728, 90]],
+ 'bidId': '26d6f897b516',
+ 'bidderRequestId': '106efe3247',
+ 'auctionId': '32a1f276cb87cb8',
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '44'
+ },
+ 'adUnitCode': 'adunit-code-2',
+ 'sizes': [[728, 90]],
+ 'bidId': '1751cd90161',
+ 'bidderRequestId': '106efe3247',
+ 'auctionId': '32a1f276cb87cb8',
+ }
+ ];
+ const request = spec.buildRequests(bidRequests);
+ const expectedResponse = [
+ {
+ 'requestId': '2164be6358b9',
+ 'cpm': 1.15,
+ 'creativeId': 17,
+ 'dealId': undefined,
+ 'width': 300,
+ 'height': 250,
+ 'ad': 'test content 1
',
+ 'bidderCode': 'turktelekom',
+ 'currency': 'TRY',
+ 'mediaType': 'banner',
+ 'netRevenue': true,
+ 'ttl': 360,
+ },
+ {
+ 'requestId': '4e111f1b66e4',
+ 'cpm': 0.5,
+ 'creativeId': 18,
+ 'dealId': undefined,
+ 'width': 300,
+ 'height': 600,
+ 'ad': 'test content 2
',
+ 'bidderCode': 'turktelekom',
+ 'currency': 'TRY',
+ 'mediaType': 'banner',
+ 'netRevenue': true,
+ 'ttl': 360,
+ },
+ {
+ 'requestId': '26d6f897b516',
+ 'cpm': 0.15,
+ 'creativeId': 17,
+ 'dealId': undefined,
+ 'width': 728,
+ 'height': 90,
+ 'ad': 'test content 3
',
+ 'bidderCode': 'turktelekom',
+ 'currency': 'TRY',
+ 'mediaType': 'banner',
+ 'netRevenue': true,
+ 'ttl': 360,
+ },
+ {
+ 'requestId': '326bde7fbf69',
+ 'cpm': 0.15,
+ 'creativeId': 17,
+ 'dealId': undefined,
+ 'width': 300,
+ 'height': 600,
+ 'ad': 'test content 4
',
+ 'bidderCode': 'turktelekom',
+ 'currency': 'TRY',
+ 'mediaType': 'banner',
+ 'netRevenue': true,
+ 'ttl': 360,
+ }
+ ];
+
+ const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request);
+ expect(result).to.deep.equal(expectedResponse);
+ });
+
+ it('dublicate uids and sizes in one slot', function () {
+ const fullResponse = [
+ {'bid': [{'price': 1.15, 'adm': 'test content 1
', 'auid': 17, 'h': 250, 'w': 300}], 'seat': '1'},
+ {'bid': [{'price': 0.5, 'adm': 'test content 2
', 'auid': 17, 'h': 250, 'w': 300}], 'seat': '1'},
+ ];
+ const bidRequests = [
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '17'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '5126e301f4be',
+ 'bidderRequestId': '171c5405a390',
+ 'auctionId': '35bcbc0f7e79c',
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '17'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '57b2ebe70e16',
+ 'bidderRequestId': '171c5405a390',
+ 'auctionId': '35bcbc0f7e79c',
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '17'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '225fcd44b18c',
+ 'bidderRequestId': '171c5405a390',
+ 'auctionId': '35bcbc0f7e79c',
+ }
+ ];
+ const request = spec.buildRequests(bidRequests);
+ const expectedResponse = [
+ {
+ 'requestId': '5126e301f4be',
+ 'cpm': 1.15,
+ 'creativeId': 17,
+ 'dealId': undefined,
+ 'width': 300,
+ 'height': 250,
+ 'ad': 'test content 1
',
+ 'bidderCode': 'turktelekom',
+ 'currency': 'TRY',
+ 'mediaType': 'banner',
+ 'netRevenue': true,
+ 'ttl': 360,
+ },
+ {
+ 'requestId': '57b2ebe70e16',
+ 'cpm': 0.5,
+ 'creativeId': 17,
+ 'dealId': undefined,
+ 'width': 300,
+ 'height': 250,
+ 'ad': 'test content 2
',
+ 'bidderCode': 'turktelekom',
+ 'currency': 'TRY',
+ 'mediaType': 'banner',
+ 'netRevenue': true,
+ 'ttl': 360,
+ }
+ ];
+
+ const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request);
+ expect(result).to.deep.equal(expectedResponse);
+ });
+ });
+
+ it('should get correct video bid response', function () {
+ const bidRequests = [
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '25'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '57dfefb80eca',
+ 'bidderRequestId': '20394420a762a2',
+ 'auctionId': '140132d07b031',
+ 'mediaTypes': {
+ 'video': {
+ 'context': 'instream'
+ }
+ }
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '26'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': 'e893c787c22dd',
+ 'bidderRequestId': '20394420a762a2',
+ 'auctionId': '140132d07b031',
+ 'mediaTypes': {
+ 'video': {
+ 'context': 'instream'
+ }
+ }
+ }
+ ];
+ const response = [
+ {'bid': [{'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 25, content_type: 'video', w: 300, h: 600}], 'seat': '2'},
+ {'bid': [{'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 26, content_type: 'video'}], 'seat': '2'}
+ ];
+ const request = spec.buildRequests(bidRequests);
+ const expectedResponse = [
+ {
+ 'requestId': '57dfefb80eca',
+ 'cpm': 1.15,
+ 'creativeId': 25,
+ 'dealId': undefined,
+ 'width': 300,
+ 'height': 600,
+ 'bidderCode': 'turktelekom',
+ 'currency': 'TRY',
+ 'mediaType': 'video',
+ 'netRevenue': true,
+ 'ttl': 360,
+ 'vastXml': '\n<\/Ad>\n<\/VAST>',
+ 'adResponse': {
+ 'content': '\n<\/Ad>\n<\/VAST>'
+ }
+ }
+ ];
+
+ const result = spec.interpretResponse({'body': {'seatbid': response}}, request);
+ expect(result).to.deep.equal(expectedResponse);
+ });
+
+ it('should have right renderer in the bid response', function () {
+ const spySetRenderer = sinon.spy();
+ const stubRenderer = {
+ setRender: spySetRenderer
+ };
+ const spyRendererInstall = sinon.spy(function() { return stubRenderer; });
+ const stubRendererConst = {
+ install: spyRendererInstall
+ };
+ const bidRequests = [
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '25'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': 'e6e65553fc8',
+ 'bidderRequestId': '1380f393215dc7',
+ 'auctionId': '10b8d2f3c697e3',
+ 'mediaTypes': {
+ 'video': {
+ 'context': 'outstream'
+ }
+ }
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '26'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': 'c8fdcb3f269f',
+ 'bidderRequestId': '1380f393215dc7',
+ 'auctionId': '10b8d2f3c697e3'
+ },
+ {
+ 'bidder': 'turktelekom',
+ 'params': {
+ 'uid': '27'
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '1de036c37685',
+ 'bidderRequestId': '1380f393215dc7',
+ 'auctionId': '10b8d2f3c697e3',
+ 'renderer': {}
+ }
+ ];
+ const response = [
+ {'bid': [{'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 25, content_type: 'video', w: 300, h: 600}], 'seat': '2'},
+ {'bid': [{'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 26, content_type: 'video', w: 300, h: 250}], 'seat': '2'},
+ {'bid': [{'price': 1.20, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 27, content_type: 'video', w: 300, h: 250}], 'seat': '2'}
+ ];
+ const request = spec.buildRequests(bidRequests);
+ const expectedResponse = [
+ {
+ 'requestId': 'e6e65553fc8',
+ 'cpm': 1.15,
+ 'creativeId': 25,
+ 'dealId': undefined,
+ 'width': 300,
+ 'height': 600,
+ 'bidderCode': 'turktelekom',
+ 'currency': 'TRY',
+ 'mediaType': 'video',
+ 'netRevenue': true,
+ 'ttl': 360,
+ 'vastXml': '\n<\/Ad>\n<\/VAST>',
+ 'adResponse': {
+ 'content': '\n<\/Ad>\n<\/VAST>'
+ },
+ 'renderer': stubRenderer
+ },
+ {
+ 'requestId': 'c8fdcb3f269f',
+ 'cpm': 1.00,
+ 'creativeId': 26,
+ 'dealId': undefined,
+ 'width': 300,
+ 'height': 250,
+ 'bidderCode': 'turktelekom',
+ 'currency': 'TRY',
+ 'mediaType': 'video',
+ 'netRevenue': true,
+ 'ttl': 360,
+ 'vastXml': '\n<\/Ad>\n<\/VAST>',
+ 'adResponse': {
+ 'content': '\n<\/Ad>\n<\/VAST>'
+ },
+ 'renderer': stubRenderer
+ },
+ {
+ 'requestId': '1de036c37685',
+ 'cpm': 1.20,
+ 'creativeId': 27,
+ 'dealId': undefined,
+ 'width': 300,
+ 'height': 250,
+ 'bidderCode': 'turktelekom',
+ 'currency': 'TRY',
+ 'mediaType': 'video',
+ 'netRevenue': true,
+ 'ttl': 360,
+ 'vastXml': '\n<\/Ad>\n<\/VAST>',
+ 'adResponse': {
+ 'content': '\n<\/Ad>\n<\/VAST>'
+ }
+ }
+ ];
+
+ const result = spec.interpretResponse({'body': {'seatbid': response}}, request, stubRendererConst);
+
+ expect(spySetRenderer.calledTwice).to.equal(true);
+ expect(spySetRenderer.getCall(0).args[0]).to.be.a('function');
+ expect(spySetRenderer.getCall(1).args[0]).to.be.a('function');
+
+ expect(spyRendererInstall.calledTwice).to.equal(true);
+ expect(spyRendererInstall.getCall(0).args[0]).to.deep.equal({
+ id: 'e6e65553fc8',
+ url: '//acdn.adnxs.com/video/outstream/ANOutstreamVideo.js',
+ loaded: false
+ });
+ expect(spyRendererInstall.getCall(1).args[0]).to.deep.equal({
+ id: 'c8fdcb3f269f',
+ url: '//acdn.adnxs.com/video/outstream/ANOutstreamVideo.js',
+ loaded: false
+ });
+
+ expect(result).to.deep.equal(expectedResponse);
+ });
+});
diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js
index 04aaec5baa7..e1740dede85 100644
--- a/test/spec/modules/userId_spec.js
+++ b/test/spec/modules/userId_spec.js
@@ -1,6 +1,15 @@
-import {attachIdSystem, init, requestBidsHook, setSubmoduleRegistry, syncDelay} from 'modules/userId/index.js';
+import {
+ attachIdSystem,
+ auctionDelay,
+ init,
+ requestBidsHook,
+ setSubmoduleRegistry,
+ syncDelay
+} from 'modules/userId/index.js';
import {config} from 'src/config';
import * as utils from 'src/utils';
+import events from 'src/events';
+import CONSTANTS from 'src/constants.json';
import {unifiedIdSubmodule} from 'modules/userId/unifiedIdSystem';
import {pubCommonIdSubmodule} from 'modules/userId/pubCommonIdSystem';
import {id5IdSubmodule} from 'modules/id5IdSystem';
@@ -41,6 +50,16 @@ describe('User ID', function() {
};
}
+ function addConfig(cfg, name, value) {
+ if (cfg && cfg.userSync && cfg.userSync.userIds) {
+ cfg.userSync.userIds.forEach(element => {
+ if (element[name] !== undefined) { element[name] = Object.assign(element[name], value); } else { element[name] = value; }
+ });
+ }
+
+ return cfg;
+ }
+
before(function() {
utils.setCookie('_pubcid_optout', '', EXPIRED_COOKIE_DATE);
localStorage.removeItem('_pbjs_id_optout');
@@ -51,11 +70,13 @@ describe('User ID', function() {
beforeEach(function() {
utils.setCookie('pubcid', '', EXPIRED_COOKIE_DATE);
utils.setCookie('pubcid_alt', 'altpubcid200000', (new Date(Date.now() + 5000).toUTCString()));
+ sinon.spy(utils, 'setCookie');
});
afterEach(function () {
$$PREBID_GLOBAL$$.requestBids.removeAll();
config.resetConfig();
+ utils.setCookie.restore();
});
after(function() {
@@ -129,7 +150,7 @@ describe('User ID', function() {
expect(pubcid1).to.not.equal(pubcid2);
});
- it('Check new cookie', function () {
+ it('Use existing cookie', function () {
let adUnits = [getAdUnitMock()];
let innerAdUnits;
@@ -143,6 +164,46 @@ describe('User ID', function() {
expect(bid.userId.pubcid).to.equal('altpubcid200000');
});
});
+ // Because the cookie exists already, there should be no setCookie call by default
+ expect(utils.setCookie.callCount).to.equal(0);
+ });
+
+ it('Extend cookie', function () {
+ let adUnits = [getAdUnitMock()];
+ let innerAdUnits;
+ let customConfig = getConfigMock(['pubCommonId', 'pubcid_alt', 'cookie']);
+ customConfig = addConfig(customConfig, 'params', {extend: true});
+
+ setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]);
+ init(config);
+ config.setConfig(customConfig);
+ requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits});
+ innerAdUnits.forEach((unit) => {
+ unit.bids.forEach((bid) => {
+ expect(bid).to.have.deep.nested.property('userId.pubcid');
+ expect(bid.userId.pubcid).to.equal('altpubcid200000');
+ });
+ });
+ // Because extend is true, the cookie will be updated even if it exists already
+ expect(utils.setCookie.callCount).to.equal(1);
+ });
+
+ it('Disable auto create', function () {
+ let adUnits = [getAdUnitMock()];
+ let innerAdUnits;
+ let customConfig = getConfigMock(['pubCommonId', 'pubcid', 'cookie']);
+ customConfig = addConfig(customConfig, 'params', {create: false});
+
+ setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]);
+ init(config);
+ config.setConfig(customConfig);
+ requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits});
+ innerAdUnits.forEach((unit) => {
+ unit.bids.forEach((bid) => {
+ expect(bid).to.not.have.deep.nested.property('userId.pubcid');
+ });
+ });
+ expect(utils.setCookie.callCount).to.equal(0);
});
});
@@ -281,6 +342,247 @@ describe('User ID', function() {
});
expect(syncDelay).to.equal(99);
});
+
+ it('config auctionDelay updates module correctly', function () {
+ setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule]);
+ init(config);
+ config.setConfig({
+ usersync: {
+ auctionDelay: 100,
+ userIds: [{
+ name: 'unifiedId',
+ storage: { name: 'unifiedid', type: 'cookie' }
+ }]
+ }
+ });
+ expect(auctionDelay).to.equal(100);
+ });
+
+ it('config auctionDelay defaults to 0 if not a number', function () {
+ setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule]);
+ init(config);
+ config.setConfig({
+ usersync: {
+ auctionDelay: '',
+ userIds: [{
+ name: 'unifiedId',
+ storage: { name: 'unifiedid', type: 'cookie' }
+ }]
+ }
+ });
+ expect(auctionDelay).to.equal(0);
+ });
+ });
+
+ describe('auction and user sync delays', function() {
+ let sandbox;
+ let adUnits;
+ let mockIdCallback;
+ let auctionSpy;
+
+ before(function() {
+ sandbox = sinon.createSandbox();
+ sandbox.stub(global, 'setTimeout');
+ sandbox.stub(events, 'on');
+ });
+
+ beforeEach(function() {
+ // remove cookie
+ utils.setCookie('MOCKID', '', EXPIRED_COOKIE_DATE);
+
+ adUnits = [getAdUnitMock()];
+
+ auctionSpy = sandbox.spy();
+ mockIdCallback = sandbox.stub();
+ const mockIdSystem = {
+ name: 'mockId',
+ decode: function(value) {
+ return {
+ 'mid': value['MOCKID']
+ };
+ },
+ getId: function() {
+ const storedId = utils.getCookie('MOCKID');
+ if (storedId) {
+ return {id: {'MOCKID': storedId}};
+ }
+ return {callback: mockIdCallback};
+ }
+ };
+
+ init(config);
+
+ attachIdSystem(mockIdSystem, true);
+ });
+
+ afterEach(function () {
+ $$PREBID_GLOBAL$$.requestBids.removeAll();
+ config.resetConfig();
+ sandbox.resetHistory();
+ });
+
+ after(function() {
+ sandbox.restore();
+ });
+
+ it('delays auction if auctionDelay is set, timing out at auction delay', function() {
+ config.setConfig({
+ usersync: {
+ auctionDelay: 33,
+ syncDelay: 77,
+ userIds: [{
+ name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' }
+ }]
+ }
+ });
+
+ requestBidsHook(auctionSpy, {adUnits});
+
+ // check auction was delayed
+ global.setTimeout.calledOnce.should.equal(true);
+ global.setTimeout.calledWith(sinon.match.func, 33);
+ auctionSpy.calledOnce.should.equal(false);
+
+ // check ids were fetched
+ mockIdCallback.calledOnce.should.equal(true);
+
+ // callback to continue auction if timed out
+ global.setTimeout.callArg(0);
+ auctionSpy.calledOnce.should.equal(true);
+
+ // does not call auction again once ids are synced
+ mockIdCallback.callArgWith(0, {'MOCKID': '1234'});
+ auctionSpy.calledOnce.should.equal(true);
+
+ // no sync after auction ends
+ events.on.called.should.equal(false);
+ });
+
+ it('delays auction if auctionDelay is set, continuing auction if ids are fetched before timing out', function(done) {
+ config.setConfig({
+ usersync: {
+ auctionDelay: 33,
+ syncDelay: 77,
+ userIds: [{
+ name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' }
+ }]
+ }
+ });
+
+ requestBidsHook(auctionSpy, {adUnits});
+
+ // check auction was delayed
+ global.setTimeout.calledOnce.should.equal(true);
+ global.setTimeout.calledWith(sinon.match.func, 33);
+ auctionSpy.calledOnce.should.equal(false);
+
+ // check ids were fetched
+ mockIdCallback.calledOnce.should.equal(true);
+
+ // if ids returned, should continue auction
+ mockIdCallback.callArgWith(0, {'MOCKID': '1234'});
+ auctionSpy.calledOnce.should.equal(true);
+
+ // check ids were copied to bids
+ adUnits.forEach(unit => {
+ unit.bids.forEach(bid => {
+ expect(bid).to.have.deep.nested.property('userId.mid');
+ expect(bid.userId.mid).to.equal('1234');
+ });
+ done();
+ });
+
+ // no sync after auction ends
+ events.on.called.should.equal(false);
+ });
+
+ it('does not delay auction if not set, delays id fetch after auction ends with syncDelay', function() {
+ config.setConfig({
+ usersync: {
+ syncDelay: 77,
+ userIds: [{
+ name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' }
+ }]
+ }
+ });
+
+ // check config has been set correctly
+ expect(auctionDelay).to.equal(0);
+ expect(syncDelay).to.equal(77);
+
+ requestBidsHook(auctionSpy, {adUnits});
+
+ // should not delay auction
+ global.setTimeout.calledOnce.should.equal(false);
+ auctionSpy.calledOnce.should.equal(true);
+
+ // check user sync is delayed after auction is ended
+ mockIdCallback.calledOnce.should.equal(false);
+ events.on.calledOnce.should.equal(true);
+ events.on.calledWith(CONSTANTS.EVENTS.AUCTION_END, sinon.match.func);
+
+ // once auction is ended, sync user ids after delay
+ events.on.callArg(1);
+ global.setTimeout.calledOnce.should.equal(true);
+ global.setTimeout.calledWith(sinon.match.func, 77);
+ mockIdCallback.calledOnce.should.equal(false);
+
+ // once sync delay is over, ids should be fetched
+ global.setTimeout.callArg(0);
+ mockIdCallback.calledOnce.should.equal(true);
+ });
+
+ it('does not delay user id sync after auction ends if set to 0', function() {
+ config.setConfig({
+ usersync: {
+ syncDelay: 0,
+ userIds: [{
+ name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' }
+ }]
+ }
+ });
+
+ expect(syncDelay).to.equal(0);
+
+ requestBidsHook(auctionSpy, {adUnits});
+
+ // auction should not be delayed
+ global.setTimeout.calledOnce.should.equal(false);
+ auctionSpy.calledOnce.should.equal(true);
+
+ // sync delay after auction is ended
+ mockIdCallback.calledOnce.should.equal(false);
+ events.on.calledOnce.should.equal(true);
+ events.on.calledWith(CONSTANTS.EVENTS.AUCTION_END, sinon.match.func);
+
+ // once auction is ended, if no sync delay, fetch ids
+ events.on.callArg(1);
+ global.setTimeout.calledOnce.should.equal(false);
+ mockIdCallback.calledOnce.should.equal(true);
+ });
+
+ it('does not delay auction if there are no ids to fetch', function() {
+ utils.setCookie('MOCKID', JSON.stringify({'MOCKID': '123456778'}), new Date(Date.now() + 5000).toUTCString());
+
+ config.setConfig({
+ usersync: {
+ auctionDelay: 33,
+ syncDelay: 77,
+ userIds: [{
+ name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' }
+ }]
+ }
+ });
+
+ requestBidsHook(auctionSpy, {adUnits});
+
+ global.setTimeout.calledOnce.should.equal(false);
+ auctionSpy.calledOnce.should.equal(true);
+ mockIdCallback.calledOnce.should.equal(false);
+
+ // no sync after auction ends
+ events.on.called.should.equal(false);
+ });
});
describe('Request bids hook appends userId to bid objs in adapters', function() {
@@ -549,8 +851,9 @@ describe('User ID', function() {
'mid': value['MOCKID']
};
},
- getId: function() {
- return {'MOCKID': '1234'}
+ getId: function(params, storedId) {
+ if (storedId) return {};
+ return {id: {'MOCKID': '1234'}};
}
});
@@ -582,5 +885,76 @@ describe('User ID', function() {
done();
}, {adUnits});
});
- })
+ });
+
+ describe('callbacks at the end of auction', function() {
+ let xhr;
+ let requests;
+
+ beforeEach(function() {
+ requests = [];
+ xhr = sinon.useFakeXMLHttpRequest();
+ xhr.onCreate = request => requests.push(request);
+ sinon.stub(events, 'getEvents').returns([]);
+ sinon.stub(utils, 'triggerPixel');
+ utils.setCookie('pubcid', '', EXPIRED_COOKIE_DATE);
+ utils.setCookie('unifiedid', '', EXPIRED_COOKIE_DATE);
+ });
+
+ afterEach(function() {
+ xhr.restore();
+ events.getEvents.restore();
+ utils.triggerPixel.restore();
+ utils.setCookie('pubcid', '', EXPIRED_COOKIE_DATE);
+ utils.setCookie('unifiedid', '', EXPIRED_COOKIE_DATE);
+ });
+
+ it('pubcid callback with url', function () {
+ let adUnits = [getAdUnitMock()];
+ let innerAdUnits;
+ let customCfg = getConfigMock(['pubCommonId', 'pubcid_alt', 'cookie']);
+ customCfg = addConfig(customCfg, 'params', {pixelUrl: '/any/pubcid/url'});
+
+ setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]);
+ init(config);
+ config.setConfig(customCfg);
+ requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits});
+
+ expect(utils.triggerPixel.called).to.be.false;
+ events.emit(CONSTANTS.EVENTS.AUCTION_END, {});
+ expect(utils.triggerPixel.getCall(0).args[0]).to.include('/any/pubcid/url');
+ });
+
+ it('unifiedid callback with url', function () {
+ let adUnits = [getAdUnitMock()];
+ let innerAdUnits;
+ let customCfg = getConfigMock(['unifiedId', 'unifiedid', 'cookie']);
+ addConfig(customCfg, 'params', {url: '/any/unifiedid/url'});
+
+ setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]);
+ init(config);
+ config.setConfig(customCfg);
+ requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits});
+
+ expect(requests).to.be.empty;
+ events.emit(CONSTANTS.EVENTS.AUCTION_END, {});
+ expect(requests[0].url).to.equal('/any/unifiedid/url');
+ });
+
+ it('unifiedid callback with partner', function () {
+ let adUnits = [getAdUnitMock()];
+ let innerAdUnits;
+ let customCfg = getConfigMock(['unifiedId', 'unifiedid', 'cookie']);
+ addConfig(customCfg, 'params', {partner: 'rubicon'});
+
+ setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]);
+ init(config);
+ config.setConfig(customCfg);
+ requestBidsHook((config) => { innerAdUnits = config.adUnits }, {adUnits});
+
+ expect(requests).to.be.empty;
+ events.emit(CONSTANTS.EVENTS.AUCTION_END, {});
+ expect(requests[0].url).to.equal('//match.adsrvr.org/track/rid?ttd_pid=rubicon&fmt=json');
+ });
+ });
});
diff --git a/test/spec/modules/videoNowBidAdapter_spec.js b/test/spec/modules/videoNowBidAdapter_spec.js
new file mode 100644
index 00000000000..337960c6edd
--- /dev/null
+++ b/test/spec/modules/videoNowBidAdapter_spec.js
@@ -0,0 +1,566 @@
+import { expect } from 'chai'
+import { spec } from 'modules/videoNowBidAdapter'
+import { replaceAuctionPrice } from '../../../src/utils'
+
+const placementId = 'div-gpt-ad-1438287399331-1'
+const LS_ITEM_NAME = 'videonow-config'
+
+const getValidServerResponse = () => {
+ const serverResponse = {
+ body: {
+ id: '111-111',
+ bidid: '2955a162-699e-4811-ce88-5c3ac973e73c',
+ cur: 'RUB',
+ seatbid: [
+ {
+ bid: [
+ {
+ id: 'e3bf2b82e3e9485113fad6c9b27f8768.1',
+ impid: '1',
+ price: 10.97,
+ nurl: 'http://localhost:8086/event/nurl',
+ netRevenue: false,
+ ttl: 800,
+ adm: '',
+ crid: 'e3bf2b82e3e9485113fad6c9b27f8768.1',
+ h: 640,
+ w: 480,
+ ext: {
+ init: 'http://localhost:8086/vn_init.js',
+ module: {
+ min: 'http://localhost:8086/vn_module.js',
+ log: 'http://localhost:8086/vn_module.js?log=1'
+ },
+ format: {
+ name: 'flyRoll',
+ },
+ },
+
+ },
+ ],
+ group: 0,
+ },
+ ],
+ price: 10,
+ ext: {
+ placementId,
+ pixels: [
+ 'http://localhost:8086/event/pxlcookiematching?uiid=1',
+ 'http://localhost:8086/event/pxlcookiematching?uiid=2',
+ ],
+ iframes: [
+ 'http://localhost:8086/event/ifrcookiematching?uiid=1',
+ 'http://localhost:8086/event/ifrcookiematching?uiid=2',
+ ],
+ },
+ },
+ headers: {},
+ }
+
+ return JSON.parse(JSON.stringify(serverResponse))
+}
+
+describe('videonowAdapterTests', function() {
+ describe('bidRequestValidity', function() {
+ it('bidRequest with pId', function() {
+ expect(spec.isBidRequestValid({
+ bidder: 'videonow',
+ params: {
+ pId: '86858',
+ },
+ })).to.equal(true)
+ })
+
+ it('bidRequest without pId', function() {
+ expect(spec.isBidRequestValid({
+ bidder: 'videonow',
+ params: {
+ nomater: 86858,
+ },
+ })).to.equal(false)
+
+ it('bidRequest is empty', function() {
+ expect(spec.isBidRequestValid({})).to.equal(false)
+ })
+
+ it('bidRequest is undefned', function() {
+ expect(spec.isBidRequestValid(undefined)).to.equal(false)
+ })
+ })
+
+ describe('bidRequest', function() {
+ const validBidRequests = [
+ {
+ bidder: 'videonow',
+ params: {
+ pId: '1',
+ placementId,
+ url: 'http://localhost:8086/bid?p=exists',
+ bidFloor: 10,
+ cur: 'RUB'
+ },
+ crumbs: {
+ pubcid: 'feded041-35dd-4b54-979a-6d7805abfa75',
+ },
+ mediaTypes: {
+ banner: {
+ sizes: [[640, 480], [320, 200]]
+ },
+ },
+ adUnitCode: 'test-ad',
+ transactionId: '676403c7-09c9-4b56-be82-e7cae81f40b9',
+ sizes: [[640, 480], [320, 200]],
+ bidId: '268c309f46390d',
+ bidderRequestId: '1dfdd514c36ef6',
+ auctionId: '4d523546-889a-4029-9a79-13d3c69f9922',
+ src: 'client',
+ bidRequestsCount: 1,
+ },
+ ]
+
+ const bidderRequest = {
+ bidderCode: 'videonow',
+ auctionId: '4d523546-889a-4029-9a79-13d3c69f9922',
+ bidderRequestId: '1dfdd514c36ef6',
+ bids: [
+ {
+ bidder: 'videonow',
+ params: {
+ pId: '1',
+ placementId,
+ url: 'http://localhost:8086/bid',
+ bidFloor: 10,
+ cur: 'RUB',
+ },
+ crumbs: {
+ pubcid: 'feded041-35dd-4b54-979a-6d7805abfa75',
+ },
+ mediaTypes: {
+ banner: {
+ sizes: [[640, 480], [320, 200]],
+ },
+ },
+ adUnitCode: 'test-ad',
+ transactionId: '676403c7-09c9-4b56-be82-e7cae81f40b9',
+ sizes: [[640, 480], [320, 200]],
+ bidId: '268c309f46390d',
+ bidderRequestId: '1dfdd514c36ef6',
+ auctionId: '4d523546-889a-4029-9a79-13d3c69f9922',
+ src: 'client',
+ bidRequestsCount: 1,
+ },
+ ],
+ auctionStart: 1565794308584,
+ timeout: 3000,
+ refererInfo: {
+ referer: 'http://localhost:8086/page',
+ reachedTop: true,
+ numIframes: 0,
+ stack: [
+ 'http://localhost:8086/page',
+ ],
+ },
+ start: 1565794308589,
+ }
+
+ const requests = spec.buildRequests(validBidRequests, bidderRequest)
+ const request = (requests && requests.length && requests[0]) || {}
+
+ it('bidRequest count', function() {
+ expect(requests.length).to.equal(1)
+ })
+
+ it('bidRequest method', function() {
+ expect(request.method).to.equal('POST')
+ })
+
+ it('bidRequest url', function() {
+ expect(request.url).to.equal('http://localhost:8086/bid?p=exists&profile_id=1')
+ })
+
+ it('bidRequest data', function() {
+ const data = request.data
+ expect(data.aid).to.be.eql(validBidRequests[0].params.aid)
+ expect(data.id).to.be.eql(validBidRequests[0].bidId)
+ expect(data.sizes).to.be.eql(validBidRequests[0].sizes)
+ })
+
+ describe('bidRequest advanced', function() {
+ const bidderRequestEmptyParamsAndExtParams = {
+ bidder: 'videonow',
+ params: {
+ pId: '1',
+ },
+ ext: {
+ p1: 'ext1',
+ p2: 'ext2',
+ },
+ }
+
+ it('bidRequest count', function() {
+ const requests = spec.buildRequests([bidderRequestEmptyParamsAndExtParams], bidderRequest)
+ expect(requests.length).to.equal(1)
+ })
+
+ it('bidRequest default url', function() {
+ const requests = spec.buildRequests([bidderRequestEmptyParamsAndExtParams], bidderRequest)
+ const request = (requests && requests.length && requests[0]) || {}
+ expect(request.url).to.equal('https://bidder.videonow.ru/prebid?profile_id=1')
+ })
+
+ it('bidRequest default currency', function() {
+ const requests = spec.buildRequests([bidderRequestEmptyParamsAndExtParams], bidderRequest)
+ const request = (requests && requests.length && requests[0]) || {}
+ const data = (request && request.data) || {}
+ expect(data.cur).to.equal('RUB')
+ })
+
+ it('bidRequest ext parameters ', function() {
+ const requests = spec.buildRequests([bidderRequestEmptyParamsAndExtParams], bidderRequest)
+ const request = (requests && requests.length && requests[0]) || {}
+ const data = (request && request.data) || {}
+ expect(data['ext_p1']).to.equal('ext1')
+ expect(data['ext_p2']).to.equal('ext2')
+ })
+
+ it('bidRequest without params', function() {
+ const bidderReq = {
+ bidder: 'videonow',
+ }
+ const requests = spec.buildRequests([bidderReq], bidderRequest)
+ expect(requests.length).to.equal(1)
+ })
+ })
+ })
+
+ describe('onBidWon', function() {
+ const cpm = 10
+ const nurl = 'http://fakedomain.nld?price=${AUCTION_PRICE}'
+ const imgSrc = replaceAuctionPrice(nurl, cpm)
+ const foundPixels = () => window.document.body.querySelectorAll(`img[src="${imgSrc}"]`)
+
+ it('Should not create nurl pixel if bid is undefined', function() {
+ spec.onBidWon()
+ expect(foundPixels().length).to.equal(0)
+ })
+
+ it('Should not create nurl pixel if bid does not contains nurl', function() {
+ spec.onBidWon({})
+ expect(foundPixels().length).to.equal(0)
+ })
+
+ it('Should create nurl pixel if bid nurl', function() {
+ spec.onBidWon({ nurl, cpm })
+ expect(foundPixels().length).to.equal(1)
+ })
+ })
+
+ describe('getUserSyncs', function() {
+ it('Should return an empty array if not get serverResponses', function() {
+ expect(spec.getUserSyncs({}).length).to.equal(0)
+ })
+
+ it('Should return an empty array if get serverResponses as empty array', function() {
+ expect(spec.getUserSyncs({}, []).length).to.equal(0)
+ })
+
+ it('Should return an empty array if serverResponses has no body', function() {
+ const serverResp = getValidServerResponse()
+ delete serverResp.body
+ const syncs = spec.getUserSyncs({}, [serverResp])
+ expect(syncs.length).to.equal(0)
+ })
+
+ it('Should return an empty array if serverResponses has no ext', function() {
+ const serverResp = getValidServerResponse()
+ delete serverResp.body.ext
+ const syncs = spec.getUserSyncs({}, [serverResp])
+ expect(syncs.length).to.equal(0)
+ })
+
+ it('Should return an array', function() {
+ const serverResp = getValidServerResponse()
+ const syncs = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [serverResp])
+ expect(syncs.length).to.equal(4)
+ })
+
+ it('Should return pixels', function() {
+ const serverResp = getValidServerResponse()
+ const syncs = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [serverResp])
+ expect(syncs.length).to.equal(2)
+ expect(syncs[0].type).to.equal('image')
+ expect(syncs[1].type).to.equal('image')
+ })
+
+ it('Should return iframes', function() {
+ const serverResp = getValidServerResponse()
+ const syncs = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [serverResp])
+ expect(syncs.length).to.equal(2)
+ expect(syncs[0].type).to.equal('iframe')
+ expect(syncs[1].type).to.equal('iframe')
+ })
+ })
+
+ describe('interpretResponse', function() {
+ const bidRequest = {
+ method: 'POST',
+ url: 'http://localhost:8086/bid?profile_id=1',
+ data: {
+ id: '217b8ab59a18e8',
+ cpm: 10,
+ sizes: [[640, 480], [320, 200]],
+ cur: 'RUB',
+ placementId,
+ ref: 'http://localhost:8086/page',
+ },
+ }
+
+ it('Should have only one bid', function() {
+ const serverResponse = getValidServerResponse()
+ const result = spec.interpretResponse(serverResponse, bidRequest)
+ expect(result.length).to.equal(1)
+ })
+
+ it('Should have required keys', function() {
+ const serverResponse = getValidServerResponse()
+ const result = spec.interpretResponse(serverResponse, bidRequest)
+ const bid = serverResponse.body.seatbid[0].bid[0]
+ const res = result[0]
+ expect(res.requestId).to.be.eql(bidRequest.data.id)
+ expect(res.cpm).to.be.eql(bid.price)
+ expect(res.creativeId).to.be.eql(bid.crid)
+ expect(res.netRevenue).to.be.a('boolean')
+ expect(res.ttl).to.be.eql(bid.ttl)
+ expect(res.renderer).to.be.a('Object')
+ expect(res.renderer.render).to.be.a('function')
+ })
+
+ it('Should return an empty array if empty or no bids in response', function() {
+ expect(spec.interpretResponse({ body: '' }, {}).length).to.equal(0)
+ })
+
+ it('Should return an empty array if bidRequest\'s data is absent', function() {
+ const serverResponse = getValidServerResponse()
+ expect(spec.interpretResponse(serverResponse, undefined).length).to.equal(0)
+ })
+
+ it('Should return an empty array if bidRequest\'s data is not contains bidId ', function() {
+ const serverResponse = getValidServerResponse()
+ expect(spec.interpretResponse(serverResponse, { data: {} }).length).to.equal(0)
+ })
+
+ it('Should return an empty array if bidRequest\'s data bidId is undefined', function() {
+ const serverResponse = getValidServerResponse()
+ expect(spec.interpretResponse(serverResponse, { data: { id: null } }).length).to.equal(0)
+ })
+
+ it('Should return an empty array if serverResponse do not contains seatbid', function() {
+ expect(spec.interpretResponse({ body: {} }, bidRequest).length).to.equal(0)
+ })
+
+ it('Should return an empty array if serverResponse\'s seatbid is empty', function() {
+ expect(spec.interpretResponse({ body: { seatbid: [] } }, bidRequest).length).to.equal(0)
+ })
+
+ it('Should return an empty array if serverResponse\'s placementId is undefined', function() {
+ expect(spec.interpretResponse({ body: { seatbid: [1, 2] } }, bidRequest).length).to.equal(0)
+ })
+
+ it('Should return an empty array if serverResponse\'s id in the bid is undefined', function() {
+ const serverResp = getValidServerResponse()
+ delete serverResp.body.seatbid[0].bid[0].id
+ let res = spec.interpretResponse(serverResp, bidRequest)
+ expect(res.length).to.equal(0)
+ })
+
+ it('Should return an empty array if serverResponse\'s price in the bid is undefined', function() {
+ const serverResp = getValidServerResponse()
+ delete serverResp.body.seatbid[0].bid[0].price
+ const res = spec.interpretResponse(serverResp, bidRequest)
+ expect(res.length).to.equal(0)
+ })
+
+ it('Should return an empty array if serverResponse\'s price in the bid is 0', function() {
+ const serverResp = getValidServerResponse()
+ serverResp.body.seatbid[0].bid[0].price = 0
+ const res = spec.interpretResponse(serverResp, bidRequest)
+
+ expect(res.length).to.equal(0)
+ })
+
+ it('Should return an empty array if serverResponse\'s init in the bid\'s ext is undefined', function() {
+ const serverResp = getValidServerResponse()
+ delete serverResp.body.seatbid[0].bid[0].ext.init
+ const res = spec.interpretResponse(serverResp, bidRequest)
+
+ expect(res.length).to.equal(0)
+ })
+
+ it('Should return an empty array if serverResponse\'s module in the bid\'s ext is undefined', function() {
+ const serverResp = getValidServerResponse()
+ delete serverResp.body.seatbid[0].bid[0].ext.module
+ const res = spec.interpretResponse(serverResp, bidRequest)
+
+ expect(res.length).to.equal(0)
+ })
+
+ it('Should return an empty array if serverResponse\'s adm in the bid is undefined', function() {
+ const serverResp = getValidServerResponse()
+ delete serverResp.body.seatbid[0].bid[0].adm
+ const res = spec.interpretResponse(serverResp, bidRequest)
+
+ expect(res.length).to.equal(0)
+ })
+
+ it('Should return an empty array if serverResponse\'s the bid\'s ext is undefined', function() {
+ const serverResp = getValidServerResponse()
+ delete serverResp.body.seatbid[0].bid[0].ext
+ const res = spec.interpretResponse(serverResp, bidRequest)
+
+ expect(res.length).to.equal(0)
+ })
+
+ it('Default ttl is 300', function() {
+ const serverResp = getValidServerResponse()
+ delete serverResp.body.seatbid[0].bid[0].ttl
+ const res = spec.interpretResponse(serverResp, bidRequest)
+ expect(res.length).to.equal(1)
+ expect(res[0].ttl).to.equal(300)
+ })
+
+ it('Default netRevenue is true', function() {
+ const serverResp = getValidServerResponse()
+ delete serverResp.body.seatbid[0].bid[0].netRevenue
+ const res = spec.interpretResponse(serverResp, bidRequest)
+ expect(res.length).to.equal(1)
+ expect(res[0].netRevenue).to.be.true;
+ })
+
+ it('Default currency is RUB', function() {
+ const serverResp = getValidServerResponse()
+ delete serverResp.body.cur
+ const res = spec.interpretResponse(serverResp, bidRequest)
+ expect(res.length).to.equal(1)
+ expect(res[0].currency).to.equal('RUB')
+ })
+
+ describe('different module paths', function() {
+ beforeEach(function() {
+ window.localStorage && localStorage.setItem(LS_ITEM_NAME, '{}')
+ })
+
+ afterEach(function() {
+ const serverResp = getValidServerResponse()
+ const { module: { log, min }, init } = serverResp.body.seatbid[0].bid[0].ext
+ remove(init)
+ remove(log)
+ remove(min)
+
+ function remove(src) {
+ if (!src) return
+ const d = document.querySelectorAll(`script[src^="${src}"]`)
+ d && d.length && Array.from(d).forEach(el => el && el.remove())
+ }
+ })
+
+ it('should use prod module by default', function() {
+ const serverResp = getValidServerResponse()
+ const res = spec.interpretResponse(serverResp, bidRequest)
+ expect(res.length).to.equal(1)
+
+ const renderer = res[0].renderer
+ expect(renderer).to.be.an('object')
+ expect(renderer.url).to.equal(serverResp.body.seatbid[0].bid[0].ext.module.min)
+ })
+
+ it('should use "log" module if "prod" is not exists', function() {
+ const serverResp = getValidServerResponse()
+ delete serverResp.body.seatbid[0].bid[0].ext.module.min
+ const res = spec.interpretResponse(serverResp, bidRequest)
+ expect(res.length).to.equal(1)
+
+ const renderer = res[0].renderer
+ expect(renderer).to.be.an('object')
+ expect(renderer.url).to.equal(serverResp.body.seatbid[0].bid[0].ext.module.log)
+ })
+
+ it('should correct combine src for init', function() {
+ const serverResp = getValidServerResponse()
+
+ const src = `${serverResp.body.seatbid[0].bid[0].ext.init}?profileId=1`
+ const placementElement = document.createElement('div')
+ placementElement.setAttribute('id', placementId)
+
+ const resp = spec.interpretResponse(serverResp, bidRequest)
+ expect(resp.length).to.equal(1)
+
+ const renderer = resp[0].renderer
+ expect(renderer).to.be.an('object')
+
+ document.body.appendChild(placementElement)
+
+ renderer.render()
+
+ const res = document.querySelectorAll(`script[src="${src}"]`)
+ expect(res.length).to.equal(1)
+ })
+
+ it('should correct combine src for init if init url contains "?"', function() {
+ const serverResp = getValidServerResponse()
+
+ serverResp.body.seatbid[0].bid[0].ext.init += '?div=1'
+ const src = `${serverResp.body.seatbid[0].bid[0].ext.init}&profileId=1`
+
+ const placementElement = document.createElement('div')
+ placementElement.setAttribute('id', placementId)
+
+ const resp = spec.interpretResponse(serverResp, bidRequest)
+ expect(resp.length).to.equal(1)
+
+ const renderer = resp[0].renderer
+ expect(renderer).to.be.an('object')
+
+ document.body.appendChild(placementElement)
+
+ renderer.render()
+
+ const res = document.querySelectorAll(`script[src="${src}"]`)
+ expect(res.length).to.equal(1)
+ })
+ })
+
+ describe('renderer object', function() {
+ it('execute renderer.render() should create window.videonow object', function() {
+ const serverResp = getValidServerResponse()
+ const res = spec.interpretResponse(serverResp, bidRequest)
+ expect(res.length).to.equal(1)
+
+ const renderer = res[0].renderer
+ expect(renderer).to.be.an('object')
+ expect(renderer.render).to.a('function')
+
+ const doc = window.document
+ const placementElement = doc.createElement('div')
+ placementElement.setAttribute('id', placementId)
+ doc.body.appendChild(placementElement)
+
+ renderer.render()
+ expect(window.videonow).to.an('object')
+ })
+ })
+
+ it('execute renderer.render() should not create window.videonow object if placement element not found', function() {
+ const serverResp = getValidServerResponse()
+ const res = spec.interpretResponse(serverResp, bidRequest)
+ expect(res.length).to.equal(1)
+
+ const renderer = res[0].renderer
+ expect(renderer).to.be.an('object')
+ expect(renderer.render).to.a('function')
+
+ renderer.render()
+ expect(window.videonow).to.be.undefined
+ })
+ })
+ })
+})
diff --git a/test/spec/modules/widespaceBidAdapter_spec.js b/test/spec/modules/widespaceBidAdapter_spec.js
index 55afbead72c..b3884a90b84 100644
--- a/test/spec/modules/widespaceBidAdapter_spec.js
+++ b/test/spec/modules/widespaceBidAdapter_spec.js
@@ -144,6 +144,35 @@ describe('+widespaceAdatperTest', function () {
const request = spec.buildRequests(bidRequest, bidderRequest);
const UrlRegExp = /^((ftp|http|https):)?\/\/[^ "]+$/;
+ let fakeLocalStorage = {};
+ let lsSetStub;
+ let lsGetStub;
+ let lsRemoveStub;
+
+ beforeEach(function() {
+ lsSetStub = sinon.stub(window.localStorage, 'setItem').callsFake(function (name, value) {
+ fakeLocalStorage[name] = value;
+ });
+
+ lsGetStub = sinon.stub(window.localStorage, 'getItem').callsFake(function (key) {
+ return fakeLocalStorage[key] || null;
+ });
+
+ lsRemoveStub = sinon.stub(window.localStorage, 'removeItem').callsFake(function (key) {
+ if (key && (fakeLocalStorage[key] !== null || fakeLocalStorage[key] !== undefined)) {
+ delete fakeLocalStorage[key];
+ }
+ return true;
+ });
+ });
+
+ afterEach(function() {
+ lsSetStub.restore();
+ lsGetStub.restore();
+ lsRemoveStub.restore();
+ fakeLocalStorage = {};
+ });
+
it('-bidRequest method is POST', function () {
expect(request[0].method).to.equal('POST');
});
diff --git a/test/spec/unit/core/adapterManager_spec.js b/test/spec/unit/core/adapterManager_spec.js
index 8eb1e21b229..1933e4a736d 100644
--- a/test/spec/unit/core/adapterManager_spec.js
+++ b/test/spec/unit/core/adapterManager_spec.js
@@ -927,12 +927,12 @@ describe('adapterManager tests', function () {
expect(bidRequests.length).to.equal(2);
let rubiconBidRequests = find(bidRequests, bidRequest => bidRequest.bidderCode === 'rubicon');
expect(rubiconBidRequests.bids.length).to.equal(1);
- expect(rubiconBidRequests.bids[0].sizes).to.deep.equal(find(adUnits, adUnit => adUnit.code === rubiconBidRequests.bids[0].adUnitCode).sizes);
+ expect(rubiconBidRequests.bids[0].mediaTypes).to.deep.equal(find(adUnits, adUnit => adUnit.code === rubiconBidRequests.bids[0].adUnitCode).mediaTypes);
let appnexusBidRequests = find(bidRequests, bidRequest => bidRequest.bidderCode === 'appnexus');
expect(appnexusBidRequests.bids.length).to.equal(2);
- expect(appnexusBidRequests.bids[0].sizes).to.deep.equal(find(adUnits, adUnit => adUnit.code === appnexusBidRequests.bids[0].adUnitCode).sizes);
- expect(appnexusBidRequests.bids[1].sizes).to.deep.equal(find(adUnits, adUnit => adUnit.code === appnexusBidRequests.bids[1].adUnitCode).sizes);
+ expect(appnexusBidRequests.bids[0].mediaTypes).to.deep.equal(find(adUnits, adUnit => adUnit.code === appnexusBidRequests.bids[0].adUnitCode).mediaTypes);
+ expect(appnexusBidRequests.bids[1].mediaTypes).to.deep.equal(find(adUnits, adUnit => adUnit.code === appnexusBidRequests.bids[1].adUnitCode).mediaTypes);
});
it('should not filter video bids', function () {
@@ -1109,8 +1109,6 @@ describe('adapterManager tests', function () {
expect(bidRequests[0].adUnitsS2SCopy.length).to.equal(1);
expect(bidRequests[0].adUnitsS2SCopy[0].bids.length).to.equal(1);
expect(bidRequests[0].adUnitsS2SCopy[0].bids[0].bidder).to.equal('rubicon');
- expect(bidRequests[0].adUnitsS2SCopy[0].bids[0].adUnitCode).to.equal(adUnits[1].code);
- expect(bidRequests[0].adUnitsS2SCopy[0].bids[0].bid_id).to.equal(bidRequests[0].bids[0].bid_id);
expect(bidRequests[0].adUnitsS2SCopy[0].labelAny).to.deep.equal(['visitor-uk', 'desktop']);
});
});