diff --git a/modules/pulsepointBidAdapter.js b/modules/pulsepointBidAdapter.js
index 015e80d5692..7297c931326 100644
--- a/modules/pulsepointBidAdapter.js
+++ b/modules/pulsepointBidAdapter.js
@@ -1,21 +1,9 @@
-import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
-/* eslint dot-notation:0, quote-props:0 */
-import {convertTypes, deepAccess, isArray, isFn, logError} from '../src/utils.js';
+import { ortbConverter } from '../libraries/ortbConverter/converter.js';
+import {convertTypes, isArray} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
-import {Renderer} from '../src/Renderer.js';
-const NATIVE_DEFAULTS = {
- TITLE_LEN: 100,
- DESCR_LEN: 200,
- SPONSORED_BY_LEN: 50,
- IMG_MIN: 150,
- ICON_MIN: 50,
-};
-
-const DEFAULT_BID_TTL = 20;
const DEFAULT_CURRENCY = 'USD';
-const DEFAULT_NET_REVENUE = true;
-const KNOWN_PARAMS = ['cp', 'ct', 'cf', 'video', 'battr', 'bcat', 'badv', 'bidfloor'];
+const KNOWN_PARAMS = ['cp', 'ct', 'cf', 'battr', 'deals'];
const DEFAULT_TMAX = 500;
/**
@@ -41,33 +29,21 @@ export const spec = {
),
buildRequests: (bidRequests, bidderRequest) => {
- // convert Native ORTB definition to old-style prebid native definition
- bidRequests = convertOrtbRequestToProprietaryNative(bidRequests);
-
- const request = {
- id: bidRequests[0].bidderRequestId,
- imp: bidRequests.map(slot => impression(slot)),
- site: site(bidRequests, bidderRequest),
- app: app(bidRequests),
- device: device(),
- bcat: deepAccess(bidderRequest.ortb2Imp, 'bcat') || bidRequests[0].params.bcat,
- badv: bidRequests[0].params.badv,
- user: user(bidRequests[0], bidderRequest),
- regs: regs(bidderRequest),
- source: source(bidRequests[0].schain),
- tmax: bidderRequest.timeout || DEFAULT_TMAX,
- };
+ const data = converter.toORTB({bidRequests, bidderRequest});
return {
method: 'POST',
url: 'https://bid.contextweb.com/header/ortb?src=prebid',
- data: request,
+ data,
bidderRequest
};
},
- interpretResponse: (response, request) => (
- bidResponseAvailable(request, response)
- ),
+ interpretResponse: (response, request) => {
+ if (response.body) {
+ return converter.fromORTB({response: response.body, request: request.data}).bids;
+ }
+ return [];
+ },
getUserSyncs: syncOptions => {
if (syncOptions.iframeEnabled) {
@@ -82,7 +58,7 @@ export const spec = {
}];
}
},
- transformBidParams: function(params, isOpenRtb) {
+ transformBidParams: function(params) {
return convertTypes({
'cf': 'string',
'cp': 'number',
@@ -91,124 +67,61 @@ export const spec = {
}
};
-/**
- * Callback for bids, after the call to PulsePoint completes.
- */
-function bidResponseAvailable(request, response) {
- const idToImpMap = {};
- const idToBidMap = {};
- const idToSlotConfig = {};
- const bidResponse = response.body;
- // extract the request bids and the response bids, keyed by impr-id
- const ortbRequest = request.data;
- ortbRequest.imp.forEach(imp => {
- idToImpMap[imp.id] = imp;
- });
- if (bidResponse) {
- bidResponse.seatbid.forEach(seatBid => seatBid.bid.forEach(bid => {
- idToBidMap[bid.impid] = bid;
- }));
- }
- if (request.bidderRequest && request.bidderRequest.bids) {
- request.bidderRequest.bids.forEach(bid => {
- idToSlotConfig[bid.bidId] = bid;
- });
- }
- const bids = [];
- Object.keys(idToImpMap).forEach(id => {
- if (idToBidMap[id]) {
- const bid = {
- requestId: id,
- cpm: idToBidMap[id].price,
- creative_id: idToBidMap[id].crid,
- creativeId: idToBidMap[id].crid,
- adId: id,
- ttl: idToBidMap[id].exp || DEFAULT_BID_TTL,
- netRevenue: DEFAULT_NET_REVENUE,
- currency: bidResponse.cur || DEFAULT_CURRENCY,
- meta: { advertiserDomains: idToBidMap[id].adomain || [] }
- };
- if (idToImpMap[id].video) {
- // for outstream, a renderer is specified
- if (idToSlotConfig[id] && deepAccess(idToSlotConfig[id], 'mediaTypes.video.context') === 'outstream') {
- bid.renderer = outstreamRenderer(deepAccess(idToSlotConfig[id], 'renderer.options'), deepAccess(idToBidMap[id], 'ext.outstream'));
+const converter = ortbConverter({
+ context: {
+ netRevenue: true,
+ ttl: 300,
+ currency: 'USD'
+ },
+
+ imp(buildImp, bidRequest, context) {
+ const imp = buildImp(bidRequest, context);
+ // tagid
+ imp.tagid = bidRequest.params.ct.toString();
+ // unknown params
+ const unknownParams = slotUnknownParams(bidRequest);
+ if (imp.ext || unknownParams) {
+ imp.ext = Object.assign({}, imp.ext, unknownParams);
+ }
+ // battr
+ if (bidRequest.params.battr) {
+ ['banner', 'video', 'audio', 'native'].forEach(k => {
+ if (imp[k]) {
+ imp[k].battr = bidRequest.params.battr;
}
- bid.vastXml = idToBidMap[id].adm;
- bid.mediaType = 'video';
- bid.width = idToBidMap[id].w;
- bid.height = idToBidMap[id].h;
- } else if (idToImpMap[id].banner) {
- bid.ad = idToBidMap[id].adm;
- bid.width = idToBidMap[id].w || idToImpMap[id].banner.w;
- bid.height = idToBidMap[id].h || idToImpMap[id].banner.h;
- } else if (idToImpMap[id]['native']) {
- bid['native'] = nativeResponse(idToImpMap[id], idToBidMap[id]);
- bid.mediaType = 'native';
- }
- bids.push(bid);
+ });
}
- });
- return bids;
-}
-
-/**
- * Produces an OpenRTBImpression from a slot config.
- */
-function impression(slot) {
- var firstPartyData = slot.ortb2Imp?.ext || {};
- var ext = Object.assign({}, firstPartyData, slotUnknownParams(slot));
- return {
- id: slot.bidId,
- banner: banner(slot),
- 'native': nativeImpression(slot),
- tagid: slot.params.ct.toString(),
- video: video(slot),
- bidfloor: bidFloor(slot),
- ext: Object.keys(ext).length > 0 ? ext : null,
- };
-}
-
-/**
- * Produces an OpenRTB Banner object for the slot given.
- */
-function banner(slot) {
- const sizes = parseSizes(slot);
- const size = adSize(slot, sizes);
- return (slot.mediaTypes && slot.mediaTypes.banner) ? {
- w: size[0],
- h: size[1],
- battr: slot.params.battr,
- format: sizes
- } : null;
-}
+ // deals
+ if (bidRequest.params.deals && isArray(bidRequest.params.deals)) {
+ imp.pmp = {
+ private_auction: 0,
+ deals: bidRequest.params.deals
+ };
+ }
+ return imp;
+ },
-/**
- * Produce openrtb format objects based on the sizes configured for the slot.
- */
-function parseSizes(slot) {
- const sizes = deepAccess(slot, 'mediaTypes.banner.sizes');
- if (sizes && isArray(sizes)) {
- return sizes.filter(sz => isArray(sz) && sz.length === 2).map(sz => ({
- w: sz[0],
- h: sz[1]
- }));
- }
- return null;
-}
+ request(buildRequest, imps, bidderRequest, context) {
+ const request = buildRequest(imps, bidderRequest, context);
+ // publisher id
+ const siteOrApp = request.site || request.app;
+ const pubId = context.bidRequests && context.bidRequests.length > 0 ? context.bidRequests[0].params.cp : '0';
+ if (siteOrApp) {
+ siteOrApp.publisher = Object.assign({}, siteOrApp.publisher, {
+ id: pubId.toString()
+ });
+ }
+ // tmax
+ request.tmax = request.tmax || DEFAULT_TMAX;
+ return request;
+ },
-/**
- * Produces an OpenRTB Video object for the slot given
- */
-function video(slot) {
- if (slot.params.video) {
- return Object.assign({},
- slot.params.video, // previously supported as bidder param
- slot.mediaTypes && slot.mediaTypes.video ? slot.mediaTypes.video : {}, // params on mediaTypes.video
- {battr: slot.params.battr}
- );
- }
- return null;
-}
+ bidResponse(buildBidResponse, bid, context) {
+ const bidResponse = buildBidResponse(bid, context);
+ bidResponse.cur = bidResponse.cur || DEFAULT_CURRENCY;
+ return bidResponse;
+ },
+});
/**
* Unknown params are captured and sent on ext
@@ -225,278 +138,4 @@ function slotUnknownParams(slot) {
return Object.keys(ext).length > 0 ? { prebid: ext } : null;
}
-/**
- * Sets up the renderer on the bid, for outstream bid responses.
- */
-function outstreamRenderer(rendererOptions, outstreamExtOptions) {
- const renderer = Renderer.install({
- url: outstreamExtOptions.rendererUrl,
- config: {
- defaultOptions: outstreamExtOptions.config,
- rendererOptions,
- type: outstreamExtOptions.type
- },
- loaded: false,
- });
- renderer.setRender((bid) => {
- bid.renderer.push(() => {
- const config = bid.renderer.getConfig();
- new window.PulsePointOutstreamRenderer().render({
- adUnitCode: bid.adUnitCode,
- vastXml: bid.vastXml,
- type: config.type,
- defaultOptions: config.defaultOptions,
- rendererOptions
- });
- });
- });
- return renderer;
-}
-
-/**
- * Produces an OpenRTB Native object for the slot given.
- */
-function nativeImpression(slot) {
- if (slot.nativeParams) {
- const assets = [];
- addAsset(assets, titleAsset(assets.length + 1, slot.nativeParams.title, NATIVE_DEFAULTS.TITLE_LEN));
- addAsset(assets, dataAsset(assets.length + 1, slot.nativeParams.body, 2, NATIVE_DEFAULTS.DESCR_LEN));
- addAsset(assets, dataAsset(assets.length + 1, slot.nativeParams.sponsoredBy, 1, NATIVE_DEFAULTS.SPONSORED_BY_LEN));
- addAsset(assets, imageAsset(assets.length + 1, slot.nativeParams.icon, 1, NATIVE_DEFAULTS.ICON_MIN, NATIVE_DEFAULTS.ICON_MIN));
- addAsset(assets, imageAsset(assets.length + 1, slot.nativeParams.image, 3, NATIVE_DEFAULTS.IMG_MIN, NATIVE_DEFAULTS.IMG_MIN));
- return {
- request: JSON.stringify({ assets }),
- ver: '1.1',
- battr: slot.params.battr,
- };
- }
- return null;
-}
-
-/**
- * Helper method to add an asset to the assets list.
- */
-function addAsset(assets, asset) {
- if (asset) {
- assets.push(asset);
- }
-}
-
-/**
- * Produces a Native Title asset for the configuration given.
- */
-function titleAsset(id, params, defaultLen) {
- if (params) {
- return {
- id,
- required: params.required ? 1 : 0,
- title: {
- len: params.len || defaultLen,
- },
- };
- }
- return null;
-}
-
-/**
- * Produces a Native Image asset for the configuration given.
- */
-function imageAsset(id, params, type, defaultMinWidth, defaultMinHeight) {
- return params ? {
- id,
- required: params.required ? 1 : 0,
- img: {
- type,
- wmin: params.wmin || defaultMinWidth,
- hmin: params.hmin || defaultMinHeight,
- }
- } : null;
-}
-
-/**
- * Produces a Native Data asset for the configuration given.
- */
-function dataAsset(id, params, type, defaultLen) {
- return params ? {
- id,
- required: params.required ? 1 : 0,
- data: {
- type,
- len: params.len || defaultLen,
- }
- } : null;
-}
-
-/**
- * Produces an OpenRTB site object.
- */
-function site(bidRequests, bidderRequest) {
- const pubId = bidRequests && bidRequests.length > 0 ? bidRequests[0].params.cp : '0';
- const appParams = bidRequests[0].params.app;
- if (!appParams) {
- // use the first party data if available, and override only publisher/ref/page properties
- var firstPartyData = bidderRequest?.ortb2?.site || {};
- return Object.assign({}, firstPartyData, {
- publisher: {
- id: pubId.toString(),
- },
- // TODO: does the fallback make sense here?
- ref: bidderRequest?.refererInfo?.ref || window.document.referrer,
- page: bidderRequest?.refererInfo?.page || ''
- });
- }
- return null;
-}
-
-/**
- * Produces an OpenRTB App object.
- */
-function app(bidderRequest) {
- const pubId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.cp : '0';
- const appParams = bidderRequest[0].params.app;
- if (appParams) {
- return {
- publisher: {
- id: pubId.toString(),
- },
- bundle: appParams.bundle,
- storeurl: appParams.storeUrl,
- domain: appParams.domain,
- }
- }
- return null;
-}
-
-/**
- * Produces an OpenRTB Device object.
- */
-function device() {
- return {
- ua: navigator.userAgent,
- language: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage),
- };
-}
-
-/**
- * Safely parses the input given. Returns null on
- * parsing failure.
- */
-function parse(rawResponse) {
- try {
- if (rawResponse) {
- return JSON.parse(rawResponse);
- }
- } catch (ex) {
- logError('pulsepointLite.safeParse', 'ERROR', ex);
- }
- return null;
-}
-
-/**
- * Determines the AdSize for the slot.
- */
-function adSize(slot, sizes) {
- if (slot.params.cf) {
- const size = slot.params.cf.toUpperCase().split('X');
- const width = parseInt(slot.params.cw || size[0], 10);
- const height = parseInt(slot.params.ch || size[1], 10);
- return [width, height];
- } else if (sizes && sizes.length > 0) {
- return [sizes[0].w, sizes[0].h];
- }
- return [1, 1];
-}
-
-/**
- * Handles the user level attributes and produces
- * an openrtb User object.
- */
-function user(bidRequest, bidderRequest) {
- var user = bidderRequest?.ortb2?.user || { ext: {} };
- var ext = user.ext;
- if (bidderRequest) {
- if (bidderRequest.gdprConsent) {
- ext.consent = bidderRequest.gdprConsent.consentString;
- }
- }
- if (bidRequest) {
- let eids = bidRequest.userIdAsEids;
- if (eids) {
- ext.eids = eids;
- }
- }
- return user;
-}
-
-/**
- * Produces the regulations ortb object
- */
-function regs(bidderRequest) {
- if (bidderRequest.gdprConsent || bidderRequest.uspConsent) {
- var ext = {};
- // GDPR applies attribute (actual consent value is in user object)
- if (bidderRequest.gdprConsent) {
- ext.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0;
- }
- // CCPA
- if (bidderRequest.uspConsent) {
- ext.us_privacy = bidderRequest.uspConsent;
- }
- return { ext };
- }
- return null;
-}
-
-/**
- * Creates source object with supply chain
- */
-function source(schain) {
- if (schain) {
- return {
- ext: { schain }
- };
- }
- return null;
-}
-
-/**
- * Parses the native response from the Bid given.
- */
-function nativeResponse(imp, bid) {
- if (imp['native']) {
- const nativeAd = parse(bid.adm);
- const keys = {};
- if (nativeAd && nativeAd['native'] && nativeAd['native'].assets) {
- nativeAd['native'].assets.forEach(asset => {
- keys.title = asset.title ? asset.title.text : keys.title;
- keys.body = asset.data && asset.data.type === 2 ? asset.data.value : keys.body;
- keys.sponsoredBy = asset.data && asset.data.type === 1 ? asset.data.value : keys.sponsoredBy;
- keys.image = asset.img && asset.img.type === 3 ? asset.img.url : keys.image;
- keys.icon = asset.img && asset.img.type === 1 ? asset.img.url : keys.icon;
- });
- if (nativeAd['native'].link) {
- keys.clickUrl = encodeURIComponent(nativeAd['native'].link.url);
- }
- keys.impressionTrackers = nativeAd['native'].imptrackers;
- return keys;
- }
- }
- return null;
-}
-
-function bidFloor(slot) {
- let floor = slot.params.bidfloor;
- if (isFn(slot.getFloor)) {
- const floorData = slot.getFloor({
- mediaType: slot.mediaTypes.banner ? 'banner' : slot.mediaTypes.video ? 'video' : 'Native',
- size: '*',
- currency: DEFAULT_CURRENCY,
- });
- if (floorData && floorData.floor) {
- floor = floorData.floor;
- }
- }
- return floor;
-}
-
registerBidder(spec);
diff --git a/modules/pulsepointBidAdapter.md b/modules/pulsepointBidAdapter.md
index 7f4b7e6b611..899c277f92f 100644
--- a/modules/pulsepointBidAdapter.md
+++ b/modules/pulsepointBidAdapter.md
@@ -2,7 +2,7 @@
**Module Name**: PulsePoint Bidder Adapter
**Module Type**: Bidder Adapter
-**Maintainer**: ExchangeTeam@pulsepoint.com
+**Maintainer**: ExchangeTeam@pulsepoint.com
# Description
@@ -18,55 +18,49 @@ Please use ```pulsepoint``` as the bidder code.
sizes: [[300, 250]],
bids: [{
bidder: 'pulsepoint',
- params: {
- cf: '300X250',
+ params: {
cp: 512379,
ct: 486653
}
}]
},{
- code: 'native-ad-div',
- sizes: [[1, 1]],
- nativeParams: {
- title: { required: true, len: 75 },
- image: { required: true },
- body: { len: 200 },
- sponsoredBy: { len: 20 }
- },
- bids: [{
- bidder: 'pulsepoint',
- params: {
- cp: 512379,
- ct: 505642
- }
- }]
- },{
- code: 'outstream-div',
- mediaTypes: {
- video: {
- playerSize: [640, 480],
- context: 'outstream',
- h: 300,
- w: 400,
- minduration: 1,
- maxduration: 210,
- linearity: 1,
- mimes: ["video/mp4", "video/ogg", "video/webm"],
- pos: 3
- }
- },
- bids: [{
- bidder: 'pulsepoint',
- params: {
- cp: 512379,
- ct: 505642
- }
- }],
- renderer: {
- options: {
- text: "PulsePoint Outstream"
- }
- }
+ code: 'native-1-slot',
+ mediaTypes: {
+ native: {
+ ortb: {
+ assets: [{
+ id: 1,
+ required: 1,
+ img: {
+ type: 3,
+ w: 150,
+ h: 50,
+ }
+ },
+ {
+ id: 2,
+ required: 1,
+ title: {
+ len: 80
+ }
+ },
+ {
+ id: 3,
+ required: 1,
+ data: {
+ type: 1
+ }
+ }]
+ }
+ }
+ },
+ bids: [{
+ bidder: 'pulsepoint',
+ params: {
+ cp: 512379,
+ ct: 694973
+ }
+ }]
},{
code: 'instream',
mediaTypes: {
diff --git a/test/spec/modules/pulsepointBidAdapter_spec.js b/test/spec/modules/pulsepointBidAdapter_spec.js
index 60dca9e6da0..8db7e909771 100644
--- a/test/spec/modules/pulsepointBidAdapter_spec.js
+++ b/test/spec/modules/pulsepointBidAdapter_spec.js
@@ -1,7 +1,8 @@
/* eslint dot-notation:0, quote-props:0 */
import {expect} from 'chai';
import {spec} from 'modules/pulsepointBidAdapter.js';
-import {deepClone} from 'src/utils.js';
+import {syncAddFPDToBidderRequest} from '../../helpers/fpd.js';
+import {deepClone} from '../../../src/utils';
describe('PulsePoint Adapter Tests', function () {
const slotConfigs = [{
@@ -31,39 +32,52 @@ describe('PulsePoint Adapter Tests', function () {
cf: '728x90'
}
}];
+ const nativeOrtbRequest = {
+ assets: [{
+ id: 1,
+ required: 1,
+ img: {
+ type: 3,
+ w: 150,
+ h: 50,
+ }
+ },
+ {
+ id: 2,
+ required: 1,
+ title: {
+ len: 80
+ }
+ },
+ {
+ id: 3,
+ required: 0,
+ data: {
+ type: 1
+ }
+ }]
+ };
const nativeSlotConfig = [{
placementCode: '/DfpAccount1/slot3',
bidId: 'bid12345',
- nativeParams: {
- title: { required: true, len: 200 },
- image: { wmin: 100 },
- sponsoredBy: { }
+ mediaTypes: {
+ native: {
+ sendTargetingKeys: false,
+ ortb: nativeOrtbRequest
+ }
},
+ nativeOrtbRequest,
params: {
cp: 'p10000',
ct: 't10000'
}
}];
- const appSlotConfig = [{
- placementCode: '/DfpAccount1/slot3',
- bidId: 'bid12345',
- params: {
- cp: 'p10000',
- ct: 't10000',
- app: {
- bundle: 'com.pulsepoint.apps',
- storeUrl: 'https://pulsepoint.com/apps',
- domain: 'pulsepoint.com',
- }
- }
- }];
const videoSlotConfig = [{
placementCode: '/DfpAccount1/slotVideo',
bidId: 'bid12345',
- params: {
- cp: 'p10000',
- ct: 't10000',
+ mediaTypes: {
video: {
+ playerSize: [400, 300],
w: 400,
h: 300,
minduration: 5,
@@ -73,6 +87,10 @@ describe('PulsePoint Adapter Tests', function () {
minbitrate: 200,
protocols: [1, 2, 4]
}
+ },
+ params: {
+ cp: 'p10000',
+ ct: 't10000'
}
}];
const additionalParamsConfig = [{
@@ -97,68 +115,6 @@ describe('PulsePoint Adapter Tests', function () {
}
}];
- const ortbParamsSlotConfig = [{
- placementCode: '/DfpAccount1/slot1',
- mediaTypes: {
- banner: {
- sizes: [[1, 1]]
- }
- },
- bidId: 'bid12345',
- params: {
- cp: 'p10000',
- ct: 't10000',
- cf: '1x1',
- bcat: ['IAB-1', 'IAB-20'],
- battr: [1, 2, 3],
- bidfloor: 1.5,
- badv: ['cocacola.com', 'lays.com']
- }
- }, {
- placementCode: '/DfpAccount1/slotVideo',
- bidId: 'bid12345',
- params: {
- cp: 'p10000',
- ct: 't10000',
- video: {
- w: 400,
- h: 300,
- minduration: 5,
- maxduration: 10,
- },
- battr: [2, 3, 4],
- bidfloor: 2.5,
- }
- }];
-
- const outstreamSlotConfig = [{
- placementCode: '/DfpAccount1/slot1',
- mediaTypes: {
- video: {
- playerSize: [640, 480],
- context: 'outstream'
- }
- },
- bidId: 'bid12345',
- params: {
- cp: 'p10000',
- ct: 't10000',
- cf: '1x1',
- video: {
- h: 300,
- w: 400,
- minduration: 1,
- maxduration: 210,
- linearity: 1,
- }
- },
- renderer: {
- options: {
- text: 'PulsePoint Outstream'
- }
- }
- }];
-
const schainParamsSlotConfig = [{
placementCode: '/DfpAccount1/slot1',
mediaTypes: {
@@ -200,7 +156,7 @@ describe('PulsePoint Adapter Tests', function () {
};
it('Verify build request', function () {
- const request = spec.buildRequests(slotConfigs, bidderRequest);
+ const request = spec.buildRequests(slotConfigs, syncAddFPDToBidderRequest(bidderRequest));
expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
expect(request.method).to.equal('POST');
const ortbRequest = request.data;
@@ -208,7 +164,6 @@ describe('PulsePoint Adapter Tests', function () {
expect(ortbRequest.site).to.not.equal(null);
expect(ortbRequest.site.publisher).to.not.equal(null);
expect(ortbRequest.site.publisher.id).to.equal('p10000');
- expect(ortbRequest.site.ref).to.equal(bidderRequest.refererInfo.ref);
expect(ortbRequest.site.page).to.equal('https://publisher.com/home');
expect(ortbRequest.imp).to.have.lengthOf(2);
// device object
@@ -217,19 +172,15 @@ describe('PulsePoint Adapter Tests', function () {
// slot 1
expect(ortbRequest.imp[0].tagid).to.equal('t10000');
expect(ortbRequest.imp[0].banner).to.not.equal(null);
- expect(ortbRequest.imp[0].banner.w).to.equal(300);
- expect(ortbRequest.imp[0].banner.h).to.equal(250);
+ expect(ortbRequest.imp[0].banner.format).to.deep.eq([{'w': 728, 'h': 90}, {'w': 160, 'h': 600}]);
// slot 2
expect(ortbRequest.imp[1].tagid).to.equal('t20000');
expect(ortbRequest.imp[1].banner).to.not.equal(null);
- expect(ortbRequest.imp[1].banner.w).to.equal(728);
- expect(ortbRequest.imp[1].banner.h).to.equal(90);
- // tmax
- expect(ortbRequest.tmax).to.equal(500);
+ expect(ortbRequest.imp[1].banner.format).to.deep.eq([{'w': 728, 'h': 90}]);
});
it('Verify parse response', function () {
- const request = spec.buildRequests(slotConfigs, bidderRequest);
+ const request = spec.buildRequests(slotConfigs, syncAddFPDToBidderRequest(bidderRequest));
const ortbRequest = request.data;
const ortbResponse = {
seatbid: [{
@@ -237,11 +188,16 @@ describe('PulsePoint Adapter Tests', function () {
impid: ortbRequest.imp[0].id,
price: 1.25,
adm: 'This is an Ad',
- crid: 'Creative#123'
+ crid: 'Creative#123',
+ mtype: 1,
+ w: 300,
+ h: 250,
+ exp: 20,
+ adomain: ['advertiser.com']
}]
}]
};
- const bids = spec.interpretResponse({ body: ortbResponse }, request);
+ const bids = spec.interpretResponse({body: ortbResponse}, request);
expect(bids).to.have.lengthOf(1);
// verify first bid
const bid = bids[0];
@@ -249,140 +205,112 @@ describe('PulsePoint Adapter Tests', function () {
expect(bid.ad).to.equal('This is an Ad');
expect(bid.width).to.equal(300);
expect(bid.height).to.equal(250);
- expect(bid.adId).to.equal('bid12345');
expect(bid.creative_id).to.equal('Creative#123');
expect(bid.creativeId).to.equal('Creative#123');
expect(bid.netRevenue).to.equal(true);
expect(bid.currency).to.equal('USD');
expect(bid.ttl).to.equal(20);
- });
-
- it('Verify ttl/currency/adomain applied to bid', function () {
- const request = spec.buildRequests(slotConfigs, bidderRequest);
- const ortbRequest = request.data;
- const ortbResponse = {
- seatbid: [{
- bid: [{
- impid: ortbRequest.imp[0].id,
- price: 1.25,
- adm: 'This is an Ad#1',
- crid: 'Creative#123',
- exp: 50,
- adomain: ['advertiser.com']
- }, {
- impid: ortbRequest.imp[1].id,
- price: 1.25,
- adm: 'This is an Ad#2',
- crid: 'Creative#123'
- }]
- }],
- cur: 'GBP'
- };
- const bids = spec.interpretResponse({ body: ortbResponse }, request);
- expect(bids).to.have.lengthOf(2);
- // verify first bid
- const bid = bids[0];
- expect(bid.cpm).to.equal(1.25);
- expect(bid.ad).to.equal('This is an Ad#1');
- expect(bid.ttl).to.equal(50);
- expect(bid.currency).to.equal('GBP');
expect(bid.meta).to.not.be.null;
expect(bid.meta.advertiserDomains).to.eql(['advertiser.com']);
- const secondBid = bids[1];
- expect(secondBid.cpm).to.equal(1.25);
- expect(secondBid.ad).to.equal('This is an Ad#2');
- expect(secondBid.ttl).to.equal(20);
- expect(secondBid.currency).to.equal('GBP');
- expect(secondBid.meta).to.not.be.null;
- expect(secondBid.meta.advertiserDomains).to.eql([]);
});
it('Verify full passback', function () {
const request = spec.buildRequests(slotConfigs, bidderRequest);
- const bids = spec.interpretResponse({ body: null }, request)
+ const bids = spec.interpretResponse({body: null}, request)
expect(bids).to.have.lengthOf(0);
});
- it('Verify Native request', function () {
- const request = spec.buildRequests(nativeSlotConfig, bidderRequest);
- expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
- expect(request.method).to.equal('POST');
- const ortbRequest = request.data;
- // native impression
- expect(ortbRequest.imp[0].tagid).to.equal('t10000');
- expect(ortbRequest.imp[0].banner).to.equal(null);
- const nativePart = ortbRequest.imp[0]['native'];
- expect(nativePart).to.not.equal(null);
- expect(nativePart.ver).to.equal('1.1');
- expect(nativePart.request).to.not.equal(null);
- // native request assets
- const nativeRequest = JSON.parse(ortbRequest.imp[0]['native'].request);
- expect(nativeRequest).to.not.equal(null);
- expect(nativeRequest.assets).to.have.lengthOf(3);
- // title asset
- expect(nativeRequest.assets[0].id).to.equal(1);
- expect(nativeRequest.assets[0].required).to.equal(1);
- expect(nativeRequest.assets[0].title).to.not.equal(null);
- expect(nativeRequest.assets[0].title.len).to.equal(200);
- // data asset
- expect(nativeRequest.assets[1].id).to.equal(2);
- expect(nativeRequest.assets[1].required).to.equal(0);
- expect(nativeRequest.assets[1].title).to.be.undefined;
- expect(nativeRequest.assets[1].data).to.not.equal(null);
- expect(nativeRequest.assets[1].data.type).to.equal(1);
- expect(nativeRequest.assets[1].data.len).to.equal(50);
- // image asset
- expect(nativeRequest.assets[2].id).to.equal(3);
- expect(nativeRequest.assets[2].required).to.equal(0);
- expect(nativeRequest.assets[2].title).to.be.undefined;
- expect(nativeRequest.assets[2].img).to.not.equal(null);
- expect(nativeRequest.assets[2].img.wmin).to.equal(100);
- expect(nativeRequest.assets[2].img.hmin).to.equal(150);
- expect(nativeRequest.assets[2].img.type).to.equal(3);
- });
+ if (FEATURES.NATIVE) {
+ it('Verify Native request', function () {
+ const request = spec.buildRequests(nativeSlotConfig, syncAddFPDToBidderRequest(bidderRequest));
+ expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
+ expect(request.method).to.equal('POST');
+ const ortbRequest = request.data;
+ // native impression
+ expect(ortbRequest.imp[0].tagid).to.equal('t10000');
+ expect(ortbRequest.imp[0].banner).to.be.undefined;
+ const nativePart = ortbRequest.imp[0]['native'];
+ expect(nativePart).to.not.equal(null);
+ expect(nativePart.request).to.not.equal(null);
+ // native request assets
+ const nativeRequest = JSON.parse(ortbRequest.imp[0]['native'].request);
+ expect(nativeRequest).to.not.equal(null);
+ expect(nativeRequest.assets).to.have.lengthOf(3);
+ // image asset
+ expect(nativeRequest.assets[0].id).to.equal(1);
+ expect(nativeRequest.assets[0].required).to.equal(1);
+ expect(nativeRequest.assets[0].title).to.be.undefined;
+ expect(nativeRequest.assets[0].img).to.not.equal(null);
+ expect(nativeRequest.assets[0].img.w).to.equal(150);
+ expect(nativeRequest.assets[0].img.h).to.equal(50);
+ expect(nativeRequest.assets[0].img.type).to.equal(3);
+ // title asset
+ expect(nativeRequest.assets[1].id).to.equal(2);
+ expect(nativeRequest.assets[1].required).to.equal(1);
+ expect(nativeRequest.assets[1].title).to.not.equal(null);
+ expect(nativeRequest.assets[1].title.len).to.equal(80);
+ // data asset
+ expect(nativeRequest.assets[2].id).to.equal(3);
+ expect(nativeRequest.assets[2].required).to.equal(0);
+ expect(nativeRequest.assets[2].title).to.be.undefined;
+ expect(nativeRequest.assets[2].data).to.not.equal(null);
+ expect(nativeRequest.assets[2].data.type).to.equal(1);
+ });
- it('Verify Native response', function () {
- const request = spec.buildRequests(nativeSlotConfig, bidderRequest);
- expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
- expect(request.method).to.equal('POST');
- const ortbRequest = request.data;
- const nativeResponse = {
- 'native': {
+ it('Verify Native response', function () {
+ const request = spec.buildRequests(nativeSlotConfig, syncAddFPDToBidderRequest(bidderRequest));
+ expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
+ expect(request.method).to.equal('POST');
+ const ortbRequest = request.data;
+ const nativeResponse = {
assets: [
- { title: { text: 'Ad Title' } },
- { data: { type: 1, value: 'Sponsored By: Brand' } },
- { img: { type: 3, url: 'https://images.cdn.brand.com/123' } }
+ {id: 1, img: {type: 3, url: 'https://images.cdn.brand.com/123'}},
+ {id: 2, title: {text: 'Ad Title'}},
+ {id: 3, data: {type: 1, value: 'Sponsored By: Brand'}}
],
- link: { url: 'https://brand.clickme.com/' },
+ link: {url: 'https://brand.clickme.com/'},
imptrackers: ['https://imp1.trackme.com/', 'https://imp1.contextweb.com/']
- }
- };
- const ortbResponse = {
- seatbid: [{
- bid: [{
- impid: ortbRequest.imp[0].id,
- price: 1.25,
- adm: JSON.stringify(nativeResponse)
+
+ };
+ const ortbResponse = {
+ seatbid: [{
+ bid: [{
+ impid: ortbRequest.imp[0].id,
+ price: 1.25,
+ adm: JSON.stringify(nativeResponse),
+ mtype: 4
+ }]
}]
- }]
- };
- const bids = spec.interpretResponse({ body: ortbResponse }, request);
- // verify bid
- const bid = bids[0];
- expect(bid.cpm).to.equal(1.25);
- expect(bid.adId).to.equal('bid12345');
- expect(bid.ad).to.be.undefined;
- expect(bid.mediaType).to.equal('native');
- const nativeBid = bid['native'];
- expect(nativeBid).to.not.equal(null);
- expect(nativeBid.title).to.equal('Ad Title');
- expect(nativeBid.sponsoredBy).to.equal('Sponsored By: Brand');
- expect(nativeBid.image).to.equal('https://images.cdn.brand.com/123');
- expect(nativeBid.clickUrl).to.equal(encodeURIComponent('https://brand.clickme.com/'));
- expect(nativeBid.impressionTrackers).to.have.lengthOf(2);
- expect(nativeBid.impressionTrackers[0]).to.equal('https://imp1.trackme.com/');
- expect(nativeBid.impressionTrackers[1]).to.equal('https://imp1.contextweb.com/');
- });
+ };
+ const bids = spec.interpretResponse({body: ortbResponse}, request);
+ // verify bid
+ const bid = bids[0];
+ expect(bid.cpm).to.equal(1.25);
+ expect(bid.requestId).to.equal('bid12345');
+ expect(bid.ad).to.be.undefined;
+ expect(bid.mediaType).to.equal('native');
+ expect(bid['native']).to.not.be.null;
+ expect(bid['native'].ortb).to.not.be.null;
+ const nativeBid = bid['native'].ortb;
+ expect(nativeBid.assets).to.have.lengthOf(3);
+ expect(nativeBid.assets[0].id).to.equal(1);
+ expect(nativeBid.assets[0].img).to.not.be.null;
+ expect(nativeBid.assets[0].img.type).to.equal(3);
+ expect(nativeBid.assets[0].img.url).to.equal('https://images.cdn.brand.com/123');
+ expect(nativeBid.assets[1].id).to.equal(2);
+ expect(nativeBid.assets[1].title).to.not.be.null;
+ expect(nativeBid.assets[1].title.text).to.equal('Ad Title');
+ expect(nativeBid.assets[2].id).to.equal(3);
+ expect(nativeBid.assets[2].data).to.not.be.null;
+ expect(nativeBid.assets[2].data.type).to.equal(1);
+ expect(nativeBid.assets[2].data.value).to.equal('Sponsored By: Brand');
+ expect(nativeBid.link).to.not.be.null;
+ expect(nativeBid.link.url).to.equal('https://brand.clickme.com/');
+ expect(nativeBid.imptrackers).to.have.lengthOf(2);
+ expect(nativeBid.imptrackers[0]).to.equal('https://imp1.trackme.com/');
+ expect(nativeBid.imptrackers[1]).to.equal('https://imp1.contextweb.com/');
+ });
+ }
it('Verifies bidder code', function () {
expect(spec.code).to.equal('pulsepoint');
@@ -430,19 +358,6 @@ describe('PulsePoint Adapter Tests', function () {
expect(options[0].url).to.equal('https://bh.contextweb.com/visitormatch/prebid');
});
- it('Verify app requests', function () {
- const request = spec.buildRequests(appSlotConfig, bidderRequest);
- const ortbRequest = request.data;
- // site object
- expect(ortbRequest.site).to.equal(null);
- expect(ortbRequest.app).to.not.be.null;
- expect(ortbRequest.app.publisher).to.not.equal(null);
- expect(ortbRequest.app.publisher.id).to.equal('p10000');
- expect(ortbRequest.app.bundle).to.equal('com.pulsepoint.apps');
- expect(ortbRequest.app.storeurl).to.equal('https://pulsepoint.com/apps');
- expect(ortbRequest.app.domain).to.equal('pulsepoint.com');
- });
-
it('Verify GDPR', function () {
const bidderRequestGdpr = {
gdprConsent: {
@@ -450,7 +365,7 @@ describe('PulsePoint Adapter Tests', function () {
consentString: 'serialized_gpdr_data'
}
};
- const request = spec.buildRequests(slotConfigs, Object.assign({}, bidderRequest, bidderRequestGdpr));
+ const request = spec.buildRequests(slotConfigs, syncAddFPDToBidderRequest(Object.assign({}, bidderRequest, bidderRequestGdpr)));
expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
expect(request.method).to.equal('POST');
const ortbRequest = request.data;
@@ -468,7 +383,8 @@ describe('PulsePoint Adapter Tests', function () {
const bidderRequestUSPrivacy = {
uspConsent: '1YYY'
};
- const request = spec.buildRequests(slotConfigs, Object.assign({}, bidderRequest, bidderRequestUSPrivacy));
+ const request = spec.buildRequests(slotConfigs,
+ syncAddFPDToBidderRequest(Object.assign({}, bidderRequest, bidderRequestUSPrivacy)));
expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
expect(request.method).to.equal('POST');
const ortbRequest = request.data;
@@ -478,52 +394,54 @@ describe('PulsePoint Adapter Tests', function () {
expect(ortbRequest.regs.ext.us_privacy).to.equal('1YYY');
});
- it('Verify Video request', function () {
- const request = spec.buildRequests(videoSlotConfig, bidderRequest);
- expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
- expect(request.method).to.equal('POST');
- const ortbRequest = request.data;
- expect(ortbRequest).to.not.equal(null);
- expect(ortbRequest.imp).to.have.lengthOf(1);
- expect(ortbRequest.imp[0].video).to.not.be.null;
- expect(ortbRequest.imp[0].native).to.be.null;
- expect(ortbRequest.imp[0].banner).to.be.null;
- expect(ortbRequest.imp[0].video.w).to.equal(400);
- expect(ortbRequest.imp[0].video.h).to.equal(300);
- expect(ortbRequest.imp[0].video.minduration).to.equal(5);
- expect(ortbRequest.imp[0].video.maxduration).to.equal(10);
- expect(ortbRequest.imp[0].video.startdelay).to.equal(0);
- expect(ortbRequest.imp[0].video.skip).to.equal(1);
- expect(ortbRequest.imp[0].video.minbitrate).to.equal(200);
- expect(ortbRequest.imp[0].video.protocols).to.eql([1, 2, 4]);
- });
+ if (FEATURES.VIDEO) {
+ it('Verify Video request', function () {
+ const request = spec.buildRequests(videoSlotConfig, syncAddFPDToBidderRequest(bidderRequest));
+ expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
+ expect(request.method).to.equal('POST');
+ const ortbRequest = request.data;
+ expect(ortbRequest).to.not.equal(null);
+ expect(ortbRequest.imp).to.have.lengthOf(1);
+ expect(ortbRequest.imp[0].video).to.not.be.null;
+ expect(ortbRequest.imp[0].native).to.be.undefined;
+ expect(ortbRequest.imp[0].banner).to.be.undefined;
+ expect(ortbRequest.imp[0].video.w).to.equal(400);
+ expect(ortbRequest.imp[0].video.h).to.equal(300);
+ expect(ortbRequest.imp[0].video.minduration).to.equal(5);
+ expect(ortbRequest.imp[0].video.maxduration).to.equal(10);
+ expect(ortbRequest.imp[0].video.startdelay).to.equal(0);
+ expect(ortbRequest.imp[0].video.skip).to.equal(1);
+ expect(ortbRequest.imp[0].video.minbitrate).to.equal(200);
+ expect(ortbRequest.imp[0].video.protocols).to.eql([1, 2, 4]);
+ });
- it('Verify Video response', function () {
- const request = spec.buildRequests(videoSlotConfig, bidderRequest);
- expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
- expect(request.method).to.equal('POST');
- const ortbRequest = request.data;
- const ortbResponse = {
- seatbid: [{
- bid: [{
- impid: ortbRequest.imp[0].id,
- price: 1.25,
- adm: 'https//pulsepoint.video.mp4'
+ it('Verify Video response', function () {
+ const request = spec.buildRequests(videoSlotConfig, bidderRequest);
+ expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
+ expect(request.method).to.equal('POST');
+ const ortbRequest = request.data;
+ const ortbResponse = {
+ seatbid: [{
+ bid: [{
+ impid: ortbRequest.imp[0].id,
+ price: 1.25,
+ adm: 'https//pulsepoint.video.mp4',
+ mtype: 2
+ }]
}]
- }]
- };
- const bids = spec.interpretResponse({ body: ortbResponse }, request);
- const bid = bids[0];
- expect(bid.cpm).to.equal(1.25);
- expect(bid.adId).to.equal('bid12345');
- expect(bid.ad).to.be.undefined;
- expect(bid['native']).to.be.undefined;
- expect(bid.mediaType).to.equal('video');
- expect(bid.vastXml).to.equal(ortbResponse.seatbid[0].bid[0].adm);
- });
+ };
+ const bids = spec.interpretResponse({ body: ortbResponse }, request);
+ const bid = bids[0];
+ expect(bid.cpm).to.equal(1.25);
+ expect(bid.ad).to.be.undefined;
+ expect(bid['native']).to.be.undefined;
+ expect(bid.mediaType).to.equal('video');
+ expect(bid.vastXml).to.equal(ortbResponse.seatbid[0].bid[0].adm);
+ });
+ }
it('Verify extra parameters', function () {
- let request = spec.buildRequests(additionalParamsConfig, bidderRequest);
+ let request = spec.buildRequests(additionalParamsConfig, syncAddFPDToBidderRequest(bidderRequest));
let ortbRequest = request.data;
expect(ortbRequest).to.not.equal(null);
expect(ortbRequest.imp).to.have.lengthOf(1);
@@ -538,31 +456,15 @@ describe('PulsePoint Adapter Tests', function () {
expect(ortbRequest.imp[0].ext.prebid.extra_key4).to.eql([1, 2, 3]);
expect(Object.keys(ortbRequest.imp[0].ext.prebid)).to.eql(['extra_key1', 'extra_key2', 'extra_key3', 'extra_key4']);
// attempting with a configuration with no unknown params.
- request = spec.buildRequests(outstreamSlotConfig, bidderRequest);
+ request = spec.buildRequests(videoSlotConfig, bidderRequest);
ortbRequest = request.data;
expect(ortbRequest).to.not.equal(null);
expect(ortbRequest.imp).to.have.lengthOf(1);
- expect(ortbRequest.imp[0].ext).to.equal(null);
- });
-
- it('Verify ortb parameters', function () {
- const request = spec.buildRequests(ortbParamsSlotConfig, bidderRequest);
- const ortbRequest = request.data;
- expect(ortbRequest).to.not.equal(null);
- expect(ortbRequest.bcat).to.eql(['IAB-1', 'IAB-20']);
- expect(ortbRequest.badv).to.eql(['cocacola.com', 'lays.com']);
- expect(ortbRequest.imp).to.have.lengthOf(2);
- expect(ortbRequest.imp[0].bidfloor).to.equal(1.5);
- expect(ortbRequest.imp[0].banner.battr).to.eql([1, 2, 3]);
- expect(ortbRequest.imp[0].ext).to.be.null;
- // slot 2
- expect(ortbRequest.imp[1].bidfloor).to.equal(2.5);
- expect(ortbRequest.imp[1].video.battr).to.eql([2, 3, 4]);
- expect(ortbRequest.imp[1].ext).to.be.null;
+ expect(ortbRequest.imp[0].ext).to.be.undefined;
});
it('Verify schain parameters', function () {
- const request = spec.buildRequests(schainParamsSlotConfig, bidderRequest);
+ const request = spec.buildRequests(schainParamsSlotConfig, syncAddFPDToBidderRequest(bidderRequest));
const ortbRequest = request.data;
expect(ortbRequest).to.not.equal(null);
expect(ortbRequest.source).to.not.equal(null);
@@ -580,42 +482,6 @@ describe('PulsePoint Adapter Tests', function () {
expect(ortbRequest.source.ext.schain.nodes[0].domain).to.equal('publisher.com');
});
- it('Verify outstream renderer', function () {
- const bidderRequestOutstream = Object.assign({}, bidderRequest, {bids: [outstreamSlotConfig[0]]});
- const request = spec.buildRequests(outstreamSlotConfig, bidderRequestOutstream);
- const ortbRequest = request.data;
- expect(ortbRequest).to.not.be.null;
- expect(ortbRequest.imp[0]).to.not.be.null;
- expect(ortbRequest.imp[0].video).to.not.be.null;
- const ortbResponse = {
- seatbid: [{
- bid: [{
- impid: ortbRequest.imp[0].id,
- price: 1.25,
- adm: 'https//pulsepoint.video.mp4',
- ext: {
- outstream: {
- type: 'Inline',
- config: {
- text: 'ADVERTISEMENT',
- skipaftersec: 5
- },
- rendererUrl: 'https://tag.contextweb.com/hb-outstr-renderer.js'
- }
- }
- }]
- }]
- };
- const bids = spec.interpretResponse({ body: ortbResponse }, request);
- const bid = bids[0];
- expect(bid.cpm).to.equal(1.25);
- expect(bid.renderer).to.not.be.null;
- expect(bid.renderer.url).to.equal('https://tag.contextweb.com/hb-outstr-renderer.js');
- expect(bid.renderer.getConfig()).to.not.be.null;
- expect(bid.renderer.getConfig().defaultOptions).to.eql(ortbResponse.seatbid[0].bid[0].ext.outstream.config);
- expect(bid.renderer.getConfig().rendererOptions).to.eql(outstreamSlotConfig[0].renderer.options);
- expect(bid.renderer.getConfig().type).to.equal('Inline');
- });
it('Verify common id parameters', function () {
const bidRequests = deepClone(slotConfigs);
bidRequests[0].userIdAsEids = [{
@@ -633,169 +499,17 @@ describe('PulsePoint Adapter Tests', function () {
}]
}
];
- const request = spec.buildRequests(bidRequests, bidderRequest);
+ const request = spec.buildRequests(bidRequests, syncAddFPDToBidderRequest(bidderRequest));
expect(request).to.be.not.null;
- const ortbRequest = request.data;
expect(request.data).to.be.not.null;
+ const ortbRequest = request.data;
// user object
expect(ortbRequest.user).to.not.be.undefined;
expect(ortbRequest.user.ext).to.not.be.undefined;
expect(ortbRequest.user.ext.eids).to.not.be.undefined;
expect(ortbRequest.user.ext.eids).to.deep.equal(bidRequests[0].userIdAsEids);
});
- it('Verify multiple adsizes', function () {
- const bidRequests = deepClone(slotConfigs);
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request).to.be.not.null;
- expect(request.data).to.be.not.null;
- const ortbRequest = request.data;
- expect(ortbRequest.imp).to.have.lengthOf(2);
- // first impression has multi sizes
- expect(ortbRequest.imp[0].banner).to.not.be.null;
- expect(ortbRequest.imp[0].banner.w).to.equal(300);
- expect(ortbRequest.imp[0].banner.h).to.equal(250);
- expect(ortbRequest.imp[0].banner.format).to.not.be.null;
- expect(ortbRequest.imp[0].banner.format).to.have.lengthOf(2);
- expect(ortbRequest.imp[0].banner.format[0].w).to.equal(728);
- expect(ortbRequest.imp[0].banner.format[0].h).to.equal(90);
- expect(ortbRequest.imp[0].banner.format[1].w).to.equal(160);
- expect(ortbRequest.imp[0].banner.format[1].h).to.equal(600);
- // slot 2
- expect(ortbRequest.imp[1].banner).to.not.be.null;
- expect(ortbRequest.imp[1].banner.w).to.equal(728);
- expect(ortbRequest.imp[1].banner.h).to.equal(90);
- expect(ortbRequest.imp[1].banner.format).to.not.be.null;
- expect(ortbRequest.imp[1].banner.format).to.have.lengthOf(1);
- expect(ortbRequest.imp[1].banner.format[0].w).to.equal(728);
- expect(ortbRequest.imp[1].banner.format[0].h).to.equal(90);
- // adsize on response
- const ortbResponse = {
- seatbid: [{
- bid: [{
- impid: ortbRequest.imp[0].id,
- price: 1.25,
- adm: 'This is an Ad',
- crid: 'Creative#123',
- w: 728,
- h: 90
- }]
- }]
- };
- const bids = spec.interpretResponse({ body: ortbResponse }, request);
- expect(bids).to.have.lengthOf(1);
- const bid = bids[0];
- expect(bid.width).to.equal(728);
- expect(bid.height).to.equal(90);
- });
- it('Verify multi-format response', function () {
- const bidRequests = deepClone(slotConfigs);
- bidRequests[0].mediaTypes['native'] = {
- title: {
- required: true
- },
- image: {
- required: true
- },
- sponsoredBy: {
- required: true
- }
- };
- bidRequests[1].params.video = {
- w: 400,
- h: 300,
- minduration: 5,
- maxduration: 10,
- };
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request).to.be.not.null;
- expect(request.data).to.be.not.null;
- const ortbRequest = request.data;
- expect(ortbRequest.imp).to.have.lengthOf(2);
- // adsize on response
- const ortbResponse = {
- seatbid: [{
- bid: [{
- impid: ortbRequest.imp[0].id,
- price: 1.25,
- adm: 'This is an Ad',
- crid: 'Creative#123',
- w: 728,
- h: 90
- }, {
- impid: ortbRequest.imp[1].id,
- price: 2.5,
- adm: '',
- crid: 'Creative#234',
- w: 728,
- h: 90
- }]
- }]
- };
- // request has both types - banner and native, response is parsed as banner.
- // for impression#2, response is parsed as video
- const bids = spec.interpretResponse({ body: ortbResponse }, request);
- expect(bids).to.have.lengthOf(2);
- const bid = bids[0];
- expect(bid.width).to.equal(728);
- expect(bid.height).to.equal(90);
- const secondBid = bids[1];
- expect(secondBid.vastXml).to.equal('');
- });
- it('Verify bid floor', function () {
- const bidRequests = deepClone(slotConfigs);
- bidRequests[0].params.bidfloor = 1.05;
- let request = spec.buildRequests(bidRequests, bidderRequest);
- let ortbRequest = request.data;
- expect(ortbRequest).to.not.equal(null);
- expect(ortbRequest.imp[0].bidfloor).to.equal(1.05);
- expect(ortbRequest.imp[1].bidfloor).to.be.undefined;
- let floorArg = null;
- // publisher uses the floor module
- bidRequests[0].getFloor = (arg) => {
- floorArg = arg;
- return { floor: 1.25 };
- };
- bidRequests[1].getFloor = () => {
- return { floor: 2.05 };
- };
- request = spec.buildRequests(bidRequests, bidderRequest);
- ortbRequest = request.data;
- expect(ortbRequest).to.not.equal(null);
- expect(ortbRequest.imp[0].bidfloor).to.equal(1.25);
- expect(ortbRequest.imp[1].bidfloor).to.equal(2.05);
- expect(floorArg).to.not.be.null;
- expect(floorArg.mediaType).to.equal('banner');
- expect(floorArg.currency).to.equal('USD');
- expect(floorArg.size).to.equal('*');
- });
- it('Verify Video params on mediaTypes.video', function () {
- const bidRequests = deepClone(videoSlotConfig);
- bidRequests[0].mediaTypes = {
- video: {
- w: 600,
- h: 400,
- minduration: 15,
- maxduration: 20,
- startdelay: 10,
- skip: 0,
- }
- };
- const request = spec.buildRequests(bidRequests, bidderRequest);
- const ortbRequest = request.data;
- expect(ortbRequest).to.not.equal(null);
- expect(ortbRequest.imp).to.have.lengthOf(1);
- expect(ortbRequest.imp[0].video).to.not.be.null;
- expect(ortbRequest.imp[0].native).to.be.null;
- expect(ortbRequest.imp[0].banner).to.be.null;
- expect(ortbRequest.imp[0].video.w).to.equal(600);
- expect(ortbRequest.imp[0].video.h).to.equal(400);
- expect(ortbRequest.imp[0].video.minduration).to.equal(15);
- expect(ortbRequest.imp[0].video.maxduration).to.equal(20);
- expect(ortbRequest.imp[0].video.startdelay).to.equal(10);
- expect(ortbRequest.imp[0].video.skip).to.equal(0);
- expect(ortbRequest.imp[0].video.minbitrate).to.equal(200);
- expect(ortbRequest.imp[0].video.protocols).to.eql([1, 2, 4]);
- });
+
it('Verify user level first party data', function () {
const bidderRequest = {
refererInfo: {
@@ -819,7 +533,7 @@ describe('PulsePoint Adapter Tests', function () {
}
}
};
- let request = spec.buildRequests(slotConfigs, bidderRequest);
+ let request = spec.buildRequests(slotConfigs, syncAddFPDToBidderRequest(bidderRequest));
let ortbRequest = request.data;
expect(ortbRequest).to.not.equal(null);
expect(ortbRequest.user).to.not.equal(null);
@@ -835,12 +549,9 @@ describe('PulsePoint Adapter Tests', function () {
}
});
});
+
it('Verify site level first party data', function () {
const bidderRequest = {
- refererInfo: {
- page: 'https://publisher.com/home',
- ref: 'https://referrer'
- },
ortb2: {
site: {
content: {
@@ -853,11 +564,14 @@ describe('PulsePoint Adapter Tests', function () {
}]
},
page: 'http://pub.com/news',
- ref: 'http://google.com'
+ ref: 'http://google.com',
+ publisher: {
+ domain: 'pub.com'
+ }
}
}
};
- let request = spec.buildRequests(slotConfigs, bidderRequest);
+ let request = spec.buildRequests(slotConfigs, syncAddFPDToBidderRequest(bidderRequest));
let ortbRequest = request.data;
expect(ortbRequest).to.not.equal(null);
expect(ortbRequest.site).to.not.equal(null);
@@ -871,13 +585,15 @@ describe('PulsePoint Adapter Tests', function () {
}
}]
},
- page: 'https://publisher.com/home',
- ref: 'https://referrer',
+ page: 'http://pub.com/news',
+ ref: 'http://google.com',
publisher: {
- id: 'p10000'
+ id: 'p10000',
+ domain: 'pub.com'
}
});
});
+
it('Verify impression/slot level first party data', function () {
const bidderRequests = [{
placementCode: '/DfpAccount1/slot1',
@@ -928,4 +644,27 @@ describe('PulsePoint Adapter Tests', function () {
// assert bidderRequest value is used when available
expect(mkRequest(Object.assign({}, { timeout: 6000 }, bidderRequest)).tmax).to.equal(6000)
});
+
+ it('Verify deals', function () {
+ const bidRequests = deepClone(slotConfigs);
+ const deals = [{
+ id: 'DEAL_ONE',
+ bidfloor: 1.1
+ }, {
+ id: 'DEAL_TWO',
+ bidfloor: 2.2
+ }];
+ bidRequests[0].params.deals = deals;
+ const request = spec.buildRequests(bidRequests, syncAddFPDToBidderRequest(bidderRequest));
+ expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid');
+ expect(request.method).to.equal('POST');
+ const ortbRequest = request.data;
+ // slot 1
+ expect(ortbRequest.imp[0].tagid).to.equal('t10000');
+ expect(ortbRequest.imp[0].pmp).to.not.be.undefined;
+ expect(ortbRequest.imp[0].pmp).to.deep.equal({
+ private_auction: 0,
+ deals
+ });
+ })
});