diff --git a/modules/aolBidAdapter.js b/modules/aolBidAdapter.js
index 5adba83e9df..c76bd1ccfd6 100644
--- a/modules/aolBidAdapter.js
+++ b/modules/aolBidAdapter.js
@@ -1,341 +1,349 @@
-const utils = require('src/utils.js');
-const ajax = require('src/ajax.js').ajax;
-const bidfactory = require('src/bidfactory.js');
-const bidmanager = require('src/bidmanager.js');
-const constants = require('src/constants.json');
-const adaptermanager = require('src/adaptermanager');
-const BaseAdapter = require('src/adapter').default;
+import * as utils from 'src/utils';
+import { registerBidder } from 'src/adapters/bidderFactory';
+import { config } from 'src/config';
+import constants from 'src/constants.json';
const AOL_BIDDERS_CODES = {
- aol: 'aol',
- onemobile: 'onemobile',
- onedisplay: 'onedisplay'
+ AOL: 'aol',
+ ONEMOBILE: 'onemobile',
+ ONEDISPLAY: 'onedisplay'
};
+const AOL_ENDPOINTS = {
+ DISPLAY: {
+ GET: 'display-get'
+ },
+ MOBILE: {
+ GET: 'mobile-get',
+ POST: 'mobile-post'
+ }
+};
+
+const SYNC_TYPES = {
+ IFRAME: {
+ TAG: 'iframe',
+ TYPE: 'iframe'
+ },
+ IMAGE: {
+ TAG: 'img',
+ TYPE: 'image'
+ }
+};
+
+const pubapiTemplate = template`//${'host'}/pubapi/3.0/${'network'}/${'placement'}/${'pageid'}/${'sizeid'}/ADTECH;v=2;cmd=bid;cors=yes;alias=${'alias'}${'bidfloor'}${'keyValues'};misc=${'misc'}`;
+const nexageBaseApiTemplate = template`//${'host'}/bidRequest?`;
+const nexageGetApiTemplate = template`dcn=${'dcn'}&pos=${'pos'}&cmd=bid${'ext'}`;
+const MP_SERVER_MAP = {
+ us: 'adserver-us.adtech.advertising.com',
+ eu: 'adserver-eu.adtech.advertising.com',
+ as: 'adserver-as.adtech.advertising.com'
+};
+const NEXAGE_SERVER = 'hb.nexage.com';
+const BID_RESPONSE_TTL = 300;
+
$$PREBID_GLOBAL$$.aolGlobals = {
pixelsDropped: false
};
-const AolAdapter = function AolAdapter() {
- let showCpmAdjustmentWarning = true;
- const pubapiTemplate = template`${'protocol'}://${'host'}/pubapi/3.0/${'network'}/${'placement'}/${'pageid'}/${'sizeid'}/ADTECH;v=2;cmd=bid;cors=yes;alias=${'alias'}${'bidfloor'};misc=${'misc'}`;
- const nexageBaseApiTemplate = template`${'protocol'}://${'host'}/bidRequest?`;
- const nexageGetApiTemplate = template`dcn=${'dcn'}&pos=${'pos'}&cmd=bid${'ext'}`;
- const MP_SERVER_MAP = {
- us: 'adserver-us.adtech.advertising.com',
- eu: 'adserver-eu.adtech.advertising.com',
- as: 'adserver-as.adtech.advertising.com'
+let showCpmAdjustmentWarning = (function () {
+ let showCpmWarning = true;
+
+ return function () {
+ let bidderSettings = $$PREBID_GLOBAL$$.bidderSettings;
+ if (showCpmWarning && bidderSettings && bidderSettings.aol &&
+ typeof bidderSettings.aol.bidCpmAdjustment === 'function') {
+ utils.logWarn(
+ 'bidCpmAdjustment is active for the AOL adapter. ' +
+ 'As of Prebid 0.14, AOL can bid in net – please contact your accounts team to enable.'
+ );
+ showCpmWarning = false; // warning is shown at most once
+ }
};
- const NEXAGE_SERVER = 'hb.nexage.com';
- const SYNC_TYPES = {
- iframe: 'IFRAME',
- img: 'IMG'
+})();
+
+function template(strings, ...keys) {
+ return function(...values) {
+ let dict = values[values.length - 1] || {};
+ let result = [strings[0]];
+ keys.forEach(function(key, i) {
+ let value = Number.isInteger(key) ? values[key] : dict[key];
+ result.push(value, strings[i + 1]);
+ });
+ return result.join('');
};
-
- let domReady = (() => {
- let readyEventFired = false;
- return fn => {
- let idempotentFn = () => {
- if (readyEventFired) {
- return;
+}
+
+function isSecureProtocol() {
+ return document.location.protocol === 'https:';
+}
+
+function parsePixelItems(pixels) {
+ let itemsRegExp = /(img|iframe)[\s\S]*?src\s*=\s*("|')(.*?)\2/gi;
+ let tagNameRegExp = /\w*(?=\s)/;
+ let srcRegExp = /src=("|')(.*?)\1/;
+ let pixelsItems = [];
+
+ if (pixels) {
+ let matchedItems = pixels.match(itemsRegExp);
+ if (matchedItems) {
+ matchedItems.forEach(item => {
+ let tagName = item.match(tagNameRegExp)[0];
+ let url = item.match(srcRegExp)[2];
+
+ if (tagName && tagName) {
+ pixelsItems.push({
+ type: tagName === SYNC_TYPES.IMAGE.TAG ? SYNC_TYPES.IMAGE.TYPE : SYNC_TYPES.IFRAME.TYPE,
+ url: url
+ });
}
- readyEventFired = true;
- return fn();
- };
-
- if (document.readyState === 'complete') {
- return idempotentFn();
- }
-
- document.addEventListener('DOMContentLoaded', idempotentFn, false);
- window.addEventListener('load', idempotentFn, false);
- };
- })();
-
- function dropSyncCookies(pixels) {
- if (!$$PREBID_GLOBAL$$.aolGlobals.pixelsDropped) {
- let pixelElements = parsePixelItems(pixels);
- renderPixelElements(pixelElements);
- $$PREBID_GLOBAL$$.aolGlobals.pixelsDropped = true;
+ });
}
}
- function parsePixelItems(pixels) {
- let itemsRegExp = /(img|iframe)[\s\S]*?src\s*=\s*("|')(.*?)\2/gi;
- let tagNameRegExp = /\w*(?=\s)/;
- let srcRegExp = /src=("|')(.*?)\1/;
- let pixelsItems = [];
-
- if (pixels) {
- let matchedItems = pixels.match(itemsRegExp);
- if (matchedItems) {
- matchedItems.forEach(item => {
- let tagNameMatches = item.match(tagNameRegExp);
- let sourcesPathMatches = item.match(srcRegExp);
- if (tagNameMatches && sourcesPathMatches) {
- pixelsItems.push({
- tagName: tagNameMatches[0].toUpperCase(),
- src: sourcesPathMatches[2]
- });
- }
- });
- }
- }
+ return pixelsItems;
+}
- return pixelsItems;
- }
+function _buildMarketplaceUrl(bid) {
+ const params = bid.params;
+ const serverParam = params.server;
+ let regionParam = params.region || 'us';
+ let server;
- function renderPixelElements(pixelsElements) {
- pixelsElements.forEach((element) => {
- switch (element.tagName) {
- case SYNC_TYPES.img:
- return renderPixelImage(element);
- case SYNC_TYPES.iframe:
- return renderPixelIframe(element);
- }
- });
+ if (!MP_SERVER_MAP.hasOwnProperty(regionParam)) {
+ utils.logWarn(`Unknown region '${regionParam}' for AOL bidder.`);
+ regionParam = 'us'; // Default region.
}
- function renderPixelImage(pixelsItem) {
- let image = new Image();
- image.src = pixelsItem.src;
+ if (serverParam) {
+ server = serverParam;
+ } else {
+ server = MP_SERVER_MAP[regionParam];
}
- function renderPixelIframe(pixelsItem) {
- let iframe = document.createElement('iframe');
- iframe.width = 1;
- iframe.height = 1;
- iframe.style.display = 'none';
- iframe.src = pixelsItem.src;
- if (document.readyState === 'interactive' ||
- document.readyState === 'complete') {
- document.body.appendChild(iframe);
- } else {
- domReady(() => {
- document.body.appendChild(iframe);
- });
- }
- }
+ // Set region param, used by AOL analytics.
+ params.region = regionParam;
+
+ return pubapiTemplate({
+ host: server,
+ network: params.network,
+ placement: parseInt(params.placement),
+ pageid: params.pageId || 0,
+ sizeid: params.sizeId || 0,
+ alias: params.alias || utils.getUniqueIdentifierStr(),
+ bidfloor: formatMarketplaceBidFloor(params.bidFloor),
+ keyValues: formatMarketplaceKeyValues(params.keyValues),
+ misc: new Date().getTime() // cache busting
+ });
+}
- function template(strings, ...keys) {
- return function(...values) {
- let dict = values[values.length - 1] || {};
- let result = [strings[0]];
- keys.forEach(function(key, i) {
- let value = Number.isInteger(key) ? values[key] : dict[key];
- result.push(value, strings[i + 1]);
- });
- return result.join('');
- };
- }
+function formatMarketplaceBidFloor(bidFloor) {
+ return (typeof bidFloor !== 'undefined') ? `;bidfloor=${bidFloor.toString()}` : '';
+}
- function _buildMarketplaceUrl(bid) {
- const params = bid.params;
- const serverParam = params.server;
- let regionParam = params.region || 'us';
- let server;
+function formatMarketplaceKeyValues(keyValues) {
+ let formattedKeyValues = '';
- if (!MP_SERVER_MAP.hasOwnProperty(regionParam)) {
- utils.logWarn(`Unknown region '${regionParam}' for AOL bidder.`);
- regionParam = 'us'; // Default region.
- }
+ utils._each(keyValues, (value, key) => {
+ formattedKeyValues += `;kv${key}=${encodeURIComponent(value)}`;
+ });
- if (serverParam) {
- server = serverParam;
- } else {
- server = MP_SERVER_MAP[regionParam];
- }
+ return formattedKeyValues;
+}
- // Set region param, used by AOL analytics.
- params.region = regionParam;
-
- return pubapiTemplate({
- protocol: (document.location.protocol === 'https:') ? 'https' : 'http',
- host: server,
- network: params.network,
- placement: parseInt(params.placement),
- pageid: params.pageId || 0,
- sizeid: params.sizeId || 0,
- alias: params.alias || utils.getUniqueIdentifierStr(),
- bidfloor: (typeof params.bidFloor !== 'undefined')
- ? `;bidfloor=${params.bidFloor.toString()}` : '',
- misc: new Date().getTime() // cache busting
+function _buildOneMobileBaseUrl(bid) {
+ return nexageBaseApiTemplate({
+ host: bid.params.host || NEXAGE_SERVER
+ });
+}
+
+function _buildOneMobileGetUrl(bid) {
+ let {dcn, pos} = bid.params;
+ let nexageApi = _buildOneMobileBaseUrl(bid);
+ if (dcn && pos) {
+ let ext = '';
+ if (isSecureProtocol()) {
+ bid.params.ext = bid.params.ext || {};
+ bid.params.ext.secure = 1;
+ }
+ utils._each(bid.params.ext, (value, key) => {
+ ext += `&${key}=${encodeURIComponent(value)}`;
});
+ nexageApi += nexageGetApiTemplate({dcn, pos, ext});
}
+ return nexageApi;
+}
- function _buildNexageApiUrl(bid) {
- let {dcn, pos} = bid.params;
- let isSecure = (document.location.protocol === 'https:');
- let nexageApi = nexageBaseApiTemplate({
- protocol: isSecure ? 'https' : 'http',
- host: bid.params.host || NEXAGE_SERVER
- });
- if (dcn && pos) {
- let ext = '';
- if (isSecure) {
- bid.params.ext = bid.params.ext || {};
- bid.params.ext.secure = 1;
- }
- utils._each(bid.params.ext, (value, key) => {
- ext += `&${key}=${encodeURIComponent(value)}`;
- });
- nexageApi += nexageGetApiTemplate({dcn, pos, ext});
- }
- return nexageApi;
- }
+function _parseBidResponse(response, bidRequest) {
+ let bidData;
- function _addErrorBidResponse(bid, response = {}) {
- const bidResponse = bidfactory.createBid(2, bid);
- bidResponse.bidderCode = bid.bidder;
- bidResponse.reason = response.nbr;
- bidResponse.raw = response;
- bidmanager.addBidResponse(bid.placementCode, bidResponse);
+ try {
+ bidData = response.seatbid[0].bid[0];
+ } catch (e) {
+ return;
}
- function _addBidResponse(bid, response) {
- let bidData;
+ let cpm;
- try {
- bidData = response.seatbid[0].bid[0];
- } catch (e) {
- _addErrorBidResponse(bid, response);
- return;
- }
-
- let cpm;
+ if (bidData.ext && bidData.ext.encp) {
+ cpm = bidData.ext.encp;
+ } else {
+ cpm = bidData.price;
- if (bidData.ext && bidData.ext.encp) {
- cpm = bidData.ext.encp;
- } else {
- cpm = bidData.price;
-
- if (cpm === null || isNaN(cpm)) {
- utils.logError('Invalid price in bid response', AOL_BIDDERS_CODES.aol, bid);
- _addErrorBidResponse(bid, response);
- return;
- }
+ if (cpm === null || isNaN(cpm)) {
+ utils.logError('Invalid price in bid response', AOL_BIDDERS_CODES.AOL, bid);
+ return;
}
+ }
- let ad = bidData.adm;
- if (response.ext && response.ext.pixels) {
- if (bid.params.userSyncOn === constants.EVENTS.BID_RESPONSE) {
- dropSyncCookies(response.ext.pixels);
- } else {
- let formattedPixels = response.ext.pixels.replace(/<\/?script( type=('|")text\/javascript('|")|)?>/g, '');
-
- ad += '';
- }
- }
+ let ad = bidData.adm;
+ if (response.ext && response.ext.pixels) {
+ if (config.getConfig('aol.userSyncOn') !== constants.EVENTS.BID_RESPONSE) {
+ let formattedPixels = response.ext.pixels.replace(/<\/?script( type=('|")text\/javascript('|")|)?>/g, '');
- const bidResponse = bidfactory.createBid(1, bid);
- bidResponse.bidderCode = bid.bidder;
- bidResponse.ad = ad;
- bidResponse.cpm = cpm;
- bidResponse.width = bidData.w;
- bidResponse.height = bidData.h;
- bidResponse.creativeId = bidData.crid;
- bidResponse.pubapiId = response.id;
- bidResponse.currencyCode = response.cur;
- if (bidData.dealid) {
- bidResponse.dealId = bidData.dealid;
+ ad += '';
}
-
- bidmanager.addBidResponse(bid.placementCode, bidResponse);
}
- function _isMarketplaceBidder(bidder) {
- return bidder === AOL_BIDDERS_CODES.aol || bidder === AOL_BIDDERS_CODES.onedisplay;
- }
+ return {
+ bidderCode: bidRequest.bidderCode,
+ requestId: bidRequest.bidId,
+ ad: ad,
+ cpm: cpm,
+ width: bidData.w,
+ height: bidData.h,
+ creativeId: bidData.crid,
+ pubapiId: response.id,
+ currency: response.cur,
+ dealId: bidData.dealid,
+ netRevenue: true,
+ ttl: BID_RESPONSE_TTL
+ };
+}
- function _isNexageBidder(bidder) {
- return bidder === AOL_BIDDERS_CODES.aol || bidder === AOL_BIDDERS_CODES.onemobile;
- }
+function _isMarketplaceBidder(bidder) {
+ return bidder === AOL_BIDDERS_CODES.AOL || bidder === AOL_BIDDERS_CODES.ONEDISPLAY;
+}
+
+function _isNexageBidder(bidder) {
+ return bidder === AOL_BIDDERS_CODES.AOL || bidder === AOL_BIDDERS_CODES.ONEMOBILE;
+}
- function _isNexageRequestPost(bid) {
- if (_isNexageBidder(bid.bidder) && bid.params.id && bid.params.imp && bid.params.imp[0]) {
- let imp = bid.params.imp[0];
- return imp.id && imp.tagid &&
- ((imp.banner && imp.banner.w && imp.banner.h) ||
+function _isNexageRequestPost(bid) {
+ if (_isNexageBidder(bid.bidder) && bid.params.id && bid.params.imp && bid.params.imp[0]) {
+ let imp = bid.params.imp[0];
+ return imp.id && imp.tagid &&
+ ((imp.banner && imp.banner.w && imp.banner.h) ||
(imp.video && imp.video.mimes && imp.video.minduration && imp.video.maxduration));
- }
}
-
- function _isNexageRequestGet(bid) {
- return _isNexageBidder(bid.bidder) && bid.params.dcn && bid.params.pos;
+}
+
+function _isNexageRequestGet(bid) {
+ return _isNexageBidder(bid.bidder) && bid.params.dcn && bid.params.pos;
+}
+
+function isMarketplaceBid(bid) {
+ return _isMarketplaceBidder(bid.bidder) && bid.params.placement && bid.params.network;
+}
+
+function isMobileBid(bid) {
+ return _isNexageRequestGet(bid) || _isNexageRequestPost(bid);
+}
+
+function resolveEndpointCode(bid) {
+ if (_isNexageRequestGet(bid)) {
+ return AOL_ENDPOINTS.MOBILE.GET;
+ } else if (_isNexageRequestPost(bid)) {
+ return AOL_ENDPOINTS.MOBILE.POST;
+ } else if (isMarketplaceBid(bid)) {
+ return AOL_ENDPOINTS.DISPLAY.GET;
}
+}
- function _isMarketplaceRequest(bid) {
- return _isMarketplaceBidder(bid.bidder) && bid.params.placement && bid.params.network;
- }
+function formatBidRequest(endpointCode, bid) {
+ let bidRequest;
+
+ switch (endpointCode) {
+ case AOL_ENDPOINTS.DISPLAY.GET:
+ bidRequest = {
+ url: _buildMarketplaceUrl(bid),
+ method: 'GET'
+ };
+ break;
- function _callBids(params) {
- utils._each(params.bids, bid => {
- let apiUrl;
- let data = null;
- let options = {
- withCredentials: true
+ case AOL_ENDPOINTS.MOBILE.GET:
+ bidRequest = {
+ url: _buildOneMobileGetUrl(bid),
+ method: 'GET'
};
- let isNexageRequestPost = _isNexageRequestPost(bid);
- let isNexageRequestGet = _isNexageRequestGet(bid);
- let isMarketplaceRequest = _isMarketplaceRequest(bid);
-
- if (isNexageRequestGet || isNexageRequestPost) {
- apiUrl = _buildNexageApiUrl(bid);
- if (isNexageRequestPost) {
- data = bid.params;
- options.customHeaders = {
+ break;
+
+ case AOL_ENDPOINTS.MOBILE.POST:
+ bidRequest = {
+ url: _buildOneMobileBaseUrl(bid),
+ method: 'POST',
+ data: bid.params,
+ options: {
+ contentType: 'application/json',
+ customHeaders: {
'x-openrtb-version': '2.2'
- };
- options.method = 'POST';
- options.contentType = 'application/json';
+ }
}
- } else if (isMarketplaceRequest) {
- apiUrl = _buildMarketplaceUrl(bid);
- }
+ };
+ break;
+ }
- if (apiUrl) {
- ajax(apiUrl, response => {
- // Needs to be here in case bidderSettings are defined after requestBids() is called
- if (showCpmAdjustmentWarning &&
- $$PREBID_GLOBAL$$.bidderSettings && $$PREBID_GLOBAL$$.bidderSettings.aol &&
- typeof $$PREBID_GLOBAL$$.bidderSettings.aol.bidCpmAdjustment === 'function'
- ) {
- utils.logWarn(
- 'bidCpmAdjustment is active for the AOL adapter. ' +
- 'As of Prebid 0.14, AOL can bid in net – please contact your accounts team to enable.'
- );
- }
- showCpmAdjustmentWarning = false; // warning is shown at most once
+ bidRequest.bidderCode = bid.bidder;
+ bidRequest.bidId = bid.bidId;
+ bidRequest.userSyncOn = bid.params.userSyncOn;
- if (!response && response.length <= 0) {
- utils.logError('Empty bid response', AOL_BIDDERS_CODES.aol, bid);
- _addErrorBidResponse(bid, response);
- return;
- }
+ return bidRequest;
+}
- try {
- response = JSON.parse(response);
- } catch (e) {
- utils.logError('Invalid JSON in bid response', AOL_BIDDERS_CODES.aol, bid);
- _addErrorBidResponse(bid, response);
- return;
- }
+function interpretResponse({body}, bidRequest) {
+ showCpmAdjustmentWarning();
- _addBidResponse(bid, response);
- }, data, options);
+ if (!body) {
+ utils.logError('Empty bid response', bidRequest.bidderCode, body);
+ } else {
+ let bid = _parseBidResponse(body, bidRequest);
+
+ if (bid) {
+ return bid;
+ }
+ }
+}
+
+export const spec = {
+ code: AOL_BIDDERS_CODES.AOL,
+ aliases: [AOL_BIDDERS_CODES.ONEMOBILE, AOL_BIDDERS_CODES.ONEDISPLAY],
+ isBidRequestValid: function(bid) {
+ return isMarketplaceBid(bid) || isMobileBid(bid);
+ },
+ buildRequests: function (bids) {
+ return bids.map(bid => {
+ const endpointCode = resolveEndpointCode(bid);
+
+ if (endpointCode) {
+ return formatBidRequest(endpointCode, bid);
}
});
- }
+ },
+ interpretResponse: interpretResponse,
+ getUserSyncs: function(options, bidResponses) {
+ let bidResponse = bidResponses[0];
- return Object.assign(this, new BaseAdapter(AOL_BIDDERS_CODES.aol), {
- callBids: _callBids
- });
-};
+ if (config.getConfig('aol.userSyncOn') === constants.EVENTS.BID_RESPONSE) {
+ if (!$$PREBID_GLOBAL$$.aolGlobals.pixelsDropped && bidResponse.ext && bidResponse.ext.pixels) {
+ $$PREBID_GLOBAL$$.aolGlobals.pixelsDropped = true;
-adaptermanager.registerBidAdapter(new AolAdapter(), AOL_BIDDERS_CODES.aol);
-adaptermanager.aliasBidAdapter(AOL_BIDDERS_CODES.aol, AOL_BIDDERS_CODES.onedisplay);
-adaptermanager.aliasBidAdapter(AOL_BIDDERS_CODES.aol, AOL_BIDDERS_CODES.onemobile);
+ return parsePixelItems(bidResponse.ext.pixels);
+ }
+ }
+
+ return [];
+ }
+};
-module.exports = AolAdapter;
+registerBidder(spec);
diff --git a/modules/aolBidAdapter.md b/modules/aolBidAdapter.md
new file mode 100644
index 00000000000..a92e933bd36
--- /dev/null
+++ b/modules/aolBidAdapter.md
@@ -0,0 +1,47 @@
+# Overview
+
+Module Name: AOL Bid Adapter
+
+Module Type: AOL Adapter
+
+Maintainer: hb-fe-tech@oath.com
+
+# Description
+
+Module that connects to AOL's demand sources
+
+# Test Parameters
+```javascript
+ var adUnits = [
+ {
+ code: 'test-ad',
+ sizes: [[300, 250]],
+ bids: [
+ {
+ bidder: 'onedisplay',
+ params: {
+ placement: '3611253',
+ network: '9599.1',
+ bidFloor: '0.80',
+ keyValues: {
+ test: 'key'
+ }
+ }
+ }
+ ]
+ },
+ {
+ code: 'test-mobile-ad',
+ sizes: [[300, 250]],
+ bids: [
+ {
+ bidder: 'onemobile',
+ params: {
+ dcn: '2c9d2b50015a5aa95b70a9b0b5b10012',
+ pos: 'header'
+ }
+ }
+ ]
+ }
+ ];
+```
diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js
index 0b4b0d7cd0c..7535d6ad613 100644
--- a/src/adapters/bidderFactory.js
+++ b/src/adapters/bidderFactory.js
@@ -228,11 +228,19 @@ export function newBidder(spec) {
const onResponse = delayExecution(afterAllResponses, requests.length)
requests.forEach(processRequest);
+ function formatGetParameters(data) {
+ if (data) {
+ return `?${typeof data === 'object' ? parseQueryStringParameters(data) : data}`;
+ }
+
+ return '';
+ }
+
function processRequest(request) {
switch (request.method) {
case 'GET':
ajax(
- `${request.url}?${typeof request.data === 'object' ? parseQueryStringParameters(request.data) : request.data}`,
+ `${request.url}${formatGetParameters(request.data)}`,
{
success: onSuccess,
error: onFailure
diff --git a/test/spec/modules/aolBidAdapter_spec.js b/test/spec/modules/aolBidAdapter_spec.js
index 188c5375b89..efa595ecc64 100644
--- a/test/spec/modules/aolBidAdapter_spec.js
+++ b/test/spec/modules/aolBidAdapter_spec.js
@@ -1,7 +1,7 @@
import {expect} from 'chai';
import * as utils from 'src/utils';
-import AolAdapter from 'modules/aolBidAdapter';
-import bidmanager from 'src/bidmanager';
+import {spec} from 'modules/aolBidAdapter';
+import {config} from 'src/config';
let getDefaultBidResponse = () => {
return {
@@ -13,9 +13,10 @@ let getDefaultBidResponse = () => {
impid: '245730051428950632',
price: 0.09,
adm: '',
- crid: '0',
+ crid: 'creative-id',
h: 90,
w: 728,
+ dealid: 'deal-id',
ext: {sizeid: 225}
}]
}]
@@ -67,15 +68,16 @@ let getDefaultBidRequest = () => {
};
};
+let getPixels = () => {
+ return '';
+};
+
describe('AolAdapter', () => {
const MARKETPLACE_URL = 'adserver-us.adtech.advertising.com/pubapi/3.0/';
const NEXAGE_URL = 'hb.nexage.com/bidRequest?';
- let adapter;
-
- beforeEach(() => adapter = new AolAdapter());
-
- function createBidderRequest({bids, params} = {}) {
+ function createCustomBidRequest({bids, params} = {}) {
var bidderRequest = getDefaultBidRequest();
if (bids && Array.isArray(bids)) {
bidderRequest.bids = bids;
@@ -86,620 +88,437 @@ describe('AolAdapter', () => {
return bidderRequest;
}
- describe('callBids()', () => {
- it('exists and is a function', () => {
- expect(adapter.callBids).to.exist.and.to.be.a('function');
+ describe('interpretResponse()', () => {
+ let bidderSettingsBackup;
+ let bidResponse;
+ let bidRequest;
+ let logWarnSpy;
+
+ beforeEach(() => {
+ bidderSettingsBackup = $$PREBID_GLOBAL$$.bidderSettings;
+ bidRequest = {
+ bidderCode: 'test-bidder-code',
+ bidId: 'bid-id'
+ };
+ bidResponse = {
+ body: getDefaultBidResponse()
+ };
+ logWarnSpy = sinon.spy(utils, 'logWarn');
});
- describe('bid request', () => {
- describe('Marketplace api', () => {
- let xhr;
- let requests;
-
- beforeEach(() => {
- xhr = sinon.useFakeXMLHttpRequest();
- requests = [];
- xhr.onCreate = request => requests.push(request);
- });
-
- afterEach(() => xhr.restore());
-
- it('requires parameters to be made', () => {
- adapter.callBids({});
- expect(requests).to.be.empty;
- });
-
- it('should hit the Marketplace api endpoint with the Marketplace config', () => {
- adapter.callBids(getDefaultBidRequest());
- expect(requests[0].url).to.contain(MARKETPLACE_URL);
- });
-
- it('should hit the Marketplace via onedisplay bidder code', () => {
- let bidRequest = createBidderRequest({
- bids: [{
- bidder: 'onedisplay'
- }],
- params: getMarketplaceBidParams()
- });
-
- adapter.callBids(bidRequest);
- expect(requests[0].url).to.contain(MARKETPLACE_URL);
- });
-
- it('should hit the Marketplace via onedisplay bidder code when Marketplace and Nexage params are present', () => {
- let bidParams = Object.assign(getMarketplaceBidParams(), getNexageGetBidParams());
- let bidRequest = createBidderRequest({
- bids: [{
- bidder: 'onedisplay'
- }],
- params: bidParams
- });
-
- adapter.callBids(bidRequest);
- expect(requests[0].url).to.contain(MARKETPLACE_URL);
- });
-
- it('should hit the Marketplace via onedisplay bidder code when Nexage params are present', () => {
- let bidParams = Object.assign(getMarketplaceBidParams(), getNexageGetBidParams(), getNexagePostBidParams());
- let bidRequest = createBidderRequest({
- bids: [{
- bidder: 'onedisplay'
- }],
- params: bidParams
- });
-
- adapter.callBids(bidRequest);
- expect(requests[0].url).to.contain(MARKETPLACE_URL);
- });
-
- it('should not resolve endpoint for onedisplay bidder code when only Nexage params are present', () => {
- let bidParams = Object.assign(getNexageGetBidParams(), getNexagePostBidParams());
-
- adapter.callBids(createBidderRequest({
- bids: [{
- bidder: 'onedisplay'
- }],
- params: bidParams
- }));
- expect(requests.length).to.equal(0);
- });
-
- it('should hit endpoint based on the region config option', () => {
- adapter.callBids(createBidderRequest({
- params: {
- placement: 1234567,
- network: '9599.1',
- region: 'eu'
- }
- }));
- expect(requests[0].url).to.contain('adserver-eu.adtech.advertising.com/pubapi/3.0/');
- });
-
- it('should hit the default endpoint in case of unknown region config option', () => {
- adapter.callBids(createBidderRequest({
- params: {
- placement: 1234567,
- network: '9599.1',
- region: 'an'
- }
- }));
- expect(requests[0].url).to.contain(MARKETPLACE_URL);
- });
-
- it('should hit endpoint based on the server config option', () => {
- adapter.callBids(createBidderRequest({
- params: {
- placement: 1234567,
- network: '9599.1',
- server: 'adserver-eu.adtech.advertising.com'
- }
- }));
- expect(requests[0].url).to.contain('adserver-eu.adtech.advertising.com/pubapi/3.0/');
- });
-
- it('should be the pubapi bid request', () => {
- adapter.callBids(getDefaultBidRequest());
- expect(requests[0].url).to.contain('cmd=bid;');
- });
-
- it('should be the version 2 of pubapi', () => {
- adapter.callBids(getDefaultBidRequest());
- expect(requests[0].url).to.contain('v=2;');
- });
-
- it('should contain cache busting', () => {
- adapter.callBids(getDefaultBidRequest());
- expect(requests[0].url).to.match(/misc=\d+/);
- });
-
- it('should contain required params - placement & network', () => {
- adapter.callBids(createBidderRequest({
- params: {
- placement: 1234567,
- network: '9599.1'
- }
- }));
- expect(requests[0].url).to.contain('/pubapi/3.0/9599.1/1234567/');
- });
-
- it('should contain pageId and sizeId of 0 if params are missing', () => {
- adapter.callBids(createBidderRequest({
- params: {
- placement: 1234567,
- network: '9599.1'
- }
- }));
- expect(requests[0].url).to.contain('/pubapi/3.0/9599.1/1234567/0/0/ADTECH;');
- });
-
- it('should contain pageId optional param', () => {
- adapter.callBids(createBidderRequest({
- params: {
- placement: 1234567,
- network: '9599.1',
- pageId: 12345
- }
- }));
- expect(requests[0].url).to.contain('/pubapi/3.0/9599.1/1234567/12345/');
- });
-
- it('should contain sizeId optional param', () => {
- adapter.callBids(createBidderRequest({
- params: {
- placement: 1234567,
- network: '9599.1',
- sizeId: 12345
- }
- }));
- expect(requests[0].url).to.contain('/12345/ADTECH;');
- });
-
- it('should contain generated alias if alias param is missing', () => {
- adapter.callBids(createBidderRequest({
- params: {
- placement: 1234567,
- network: '9599.1'
- }
- }));
- expect(requests[0].url).to.match(/alias=\w+?;/);
- });
-
- it('should contain alias optional param', () => {
- adapter.callBids(createBidderRequest({
- params: {
- placement: 1234567,
- network: '9599.1',
- alias: 'desktop_articlepage_something_box_300_250'
- }
- }));
- expect(requests[0].url).to.contain('alias=desktop_articlepage_something_box_300_250');
- });
-
- it('should not contain bidfloor if bidFloor param is missing', () => {
- adapter.callBids(createBidderRequest({
- params: {
- placement: 1234567,
- network: '9599.1'
- }
- }));
- expect(requests[0].url).not.to.contain('bidfloor=');
- });
+ afterEach(() => {
+ $$PREBID_GLOBAL$$.bidderSettings = bidderSettingsBackup;
+ logWarnSpy.restore();
+ });
- it('should contain bidFloor optional param', () => {
- adapter.callBids(createBidderRequest({
- params: {
- placement: 1234567,
- network: '9599.1',
- bidFloor: 0.80
- }
- }));
- expect(requests[0].url).to.contain('bidfloor=0.8');
- });
+ it('should return formatted bid response with required properties', () => {
+ let formattedBidResponse = spec.interpretResponse(bidResponse, bidRequest);
+ expect(formattedBidResponse).to.deep.equal({
+ bidderCode: bidRequest.bidderCode,
+ requestId: 'bid-id',
+ ad: '',
+ cpm: 0.09,
+ width: 728,
+ height: 90,
+ creativeId: 'creative-id',
+ pubapiId: '245730051428950632',
+ currency: 'USD',
+ dealId: 'deal-id',
+ netRevenue: true,
+ ttl: 300
});
+ });
- describe('Nexage api', () => {
- let xhr;
- let requests;
+ it('should return formatted bid response including pixels', () => {
+ bidResponse.body.ext = {
+ pixels: ''
+ };
- beforeEach(() => {
- xhr = sinon.useFakeXMLHttpRequest();
- requests = [];
- xhr.onCreate = request => requests.push(request);
- });
+ let formattedBidResponse = spec.interpretResponse(bidResponse, bidRequest);
- afterEach(() => xhr.restore());
+ expect(formattedBidResponse.ad).to.equal(
+ '' +
+ ''
+ );
+ });
- it('requires parameters to be made', () => {
- adapter.callBids({});
- expect(requests).to.be.empty;
- });
+ it('should show warning in the console', function() {
+ $$PREBID_GLOBAL$$.bidderSettings = {
+ aol: {
+ bidCpmAdjustment: function() {}
+ }
+ };
+ spec.interpretResponse(bidResponse, bidRequest);
+ expect(utils.logWarn.calledOnce).to.be.true;
+ });
+ });
- it('should hit the nexage api endpoint with the nexage config', () => {
- adapter.callBids(createBidderRequest({
- params: getNexageGetBidParams()
- }));
+ describe('buildRequests()', () => {
+ it('method exists and is a function', () => {
+ expect(spec.buildRequests).to.exist.and.to.be.a('function');
+ });
- expect(requests[0].url).to.contain(NEXAGE_URL);
- });
+ describe('Marketplace', () => {
+ it('should not return request when no bids are present', () => {
+ let [request] = spec.buildRequests([]);
+ expect(request).to.be.empty;
+ });
- it('should hit the nexage api custom endpoint if specified in the nexage config', () => {
- let bidParams = Object.assign({
- host: 'qa-hb.nexage.com'
- }, getNexageGetBidParams());
+ it('should return request for Marketplace endpoint', () => {
+ let bidRequest = getDefaultBidRequest();
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain(MARKETPLACE_URL);
+ });
- adapter.callBids(createBidderRequest({
- params: bidParams
- }));
- expect(requests[0].url).to.contain('qa-hb.nexage.com/bidRequest?');
+ it('should return request for Marketplace via onedisplay bidder code', () => {
+ let bidRequest = createCustomBidRequest({
+ bids: [{
+ bidder: 'onedisplay'
+ }],
+ params: getMarketplaceBidParams()
});
- it('should hit nexage api when nexage and marketplace params are present', () => {
- let bidParams = Object.assign(getNexageGetBidParams(), getMarketplaceBidParams());
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain(MARKETPLACE_URL);
+ });
- adapter.callBids(createBidderRequest({
- params: bidParams
- }));
- expect(requests[0].url).to.contain(NEXAGE_URL);
+ it('should return Marketplace request via onedisplay bidder code when' +
+ 'Marketplace and One Mobile GET params are present', () => {
+ let bidParams = Object.assign(getMarketplaceBidParams(), getNexageGetBidParams());
+ let bidRequest = createCustomBidRequest({
+ bids: [{
+ bidder: 'onedisplay'
+ }],
+ params: bidParams
});
- it('should hit nexage api via onemobile bidder code when nexage and marketplace params are present', () => {
- let bidParams = Object.assign(getNexageGetBidParams(), getMarketplaceBidParams());
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain(MARKETPLACE_URL);
+ });
- adapter.callBids(createBidderRequest({
- bids: [{
- bidder: 'onemobile'
- }],
- params: bidParams
- }));
- expect(requests[0].url).to.contain(NEXAGE_URL);
+ it('should return Marketplace request via onedisplay bidder code when' +
+ 'Marketplace and One Mobile GET + POST params are present', () => {
+ let bidParams = Object.assign(getMarketplaceBidParams(), getNexageGetBidParams(), getNexagePostBidParams());
+ let bidRequest = createCustomBidRequest({
+ bids: [{
+ bidder: 'onedisplay'
+ }],
+ params: bidParams
});
- it('should not resolve endpoint for onemobile bidder code when only Marketplace params are present', () => {
- adapter.callBids(createBidderRequest({
- bids: [{
- bidder: 'onemobile'
- }],
- params: getMarketplaceBidParams()
- }));
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain(MARKETPLACE_URL);
+ });
- expect(requests.length).to.equal(0);
+ it('should not resolve endpoint for onedisplay bidder code ' +
+ 'when only One Mobile params are present', () => {
+ let bidParams = Object.assign(getNexageGetBidParams(), getNexagePostBidParams());
+ let bidRequest = createCustomBidRequest({
+ bids: [{
+ bidder: 'onedisplay'
+ }],
+ params: bidParams
});
- it('should contain required params - dcn & pos', () => {
- adapter.callBids(createBidderRequest({
- params: getNexageGetBidParams()
- }));
-
- expect(requests[0].url).to.contain(NEXAGE_URL + 'dcn=2c9d2b50015c5ce9db6aeeed8b9500d6&pos=header');
- });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request).to.be.empty;
+ });
- it('should contain cmd=bid by default', () => {
- adapter.callBids(createBidderRequest({
- params: {
- dcn: '54321123',
- pos: 'footer-2324'
- }
- }));
- expect(requests[0].url).to.contain('hb.nexage.com/bidRequest?dcn=54321123&pos=footer-2324&cmd=bid');
+ it('should return Marketplace URL for eu region', () => {
+ let bidRequest = createCustomBidRequest({
+ params: {
+ placement: 1234567,
+ network: '9599.1',
+ region: 'eu'
+ }
});
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain('adserver-eu.adtech.advertising.com/pubapi/3.0/');
+ });
- it('should contain optional parameters if they are set', () => {
- adapter.callBids(createBidderRequest({
- params: {
- dcn: '54321123',
- pos: 'footer-2324',
- ext: {
- param1: 'val1',
- param2: 'val2',
- param3: 'val3',
- param4: 'val4'
- }
- }
- }));
- expect(requests[0].url).to.contain('hb.nexage.com/bidRequest?dcn=54321123&pos=footer-2324&cmd=bid' +
- '¶m1=val1¶m2=val2¶m3=val3¶m4=val4');
+ it('should return Marketplace URL for eu region when server option is present', () => {
+ let bidRequest = createCustomBidRequest({
+ params: {
+ placement: 1234567,
+ network: '9599.1',
+ server: 'adserver-eu.adtech.advertising.com'
+ }
});
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain('adserver-eu.adtech.advertising.com/pubapi/3.0/');
+ });
- it('should hit the nexage api endpoint with post data with the openrtb config', () => {
- let bidConfig = getNexagePostBidParams();
-
- adapter.callBids(createBidderRequest({
- params: bidConfig
- }));
- expect(requests[0].url).to.contain(NEXAGE_URL);
- expect(requests[0].requestBody).to.deep.equal(bidConfig);
- expect(requests[0].requestHeaders).to.have.property('x-openrtb-version');
+ it('should return default Marketplace URL in case of unknown region config option', () => {
+ let bidRequest = createCustomBidRequest({
+ params: {
+ placement: 1234567,
+ network: '9599.1',
+ region: 'an'
+ }
});
-
- it('should not hit the nexage api endpoint with post data with the openrtb config' +
- ' if a required parameter is missing', () => {
- let bidConfig = getNexagePostBidParams();
-
- bidConfig.imp[0].id = null;
- adapter.callBids(createBidderRequest({
- params: bidConfig
- }));
- expect(requests).to.be.empty;
- })
- ;
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain(MARKETPLACE_URL);
});
- });
-
- describe('bid response', () => {
- let server;
- beforeEach(() => {
- server = sinon.fakeServer.create();
- sinon.stub(bidmanager, 'addBidResponse');
+ it('should return url with pubapi bid option', () => {
+ let bidRequest = getDefaultBidRequest();
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain('cmd=bid;');
});
- afterEach(() => {
- server.restore();
- bidmanager.addBidResponse.restore();
+ it('should return url with version 2 of pubapi', () => {
+ let bidRequest = getDefaultBidRequest();
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain('v=2;');
});
- it('should be added to bidmanager if returned from pubapi', () => {
- server.respondWith(JSON.stringify(getDefaultBidResponse()));
- adapter.callBids(getDefaultBidRequest());
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
+ it('should return url with cache busting option', () => {
+ let bidRequest = getDefaultBidRequest();
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.match(/misc=\d+/);
});
- it('should be added to bidmanager if returned from nexage GET bid request', () => {
- server.respondWith(JSON.stringify(getDefaultBidResponse()));
- adapter.callBids(createBidderRequest({
+ it('should return url with default pageId and sizeId', () => {
+ let bidRequest = createCustomBidRequest({
params: {
- dcn: '54321123',
- pos: 'footer-2324'
+ placement: 1234567,
+ network: '9599.1'
}
- }));
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
+ });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain('/pubapi/3.0/9599.1/1234567/0/0/ADTECH;');
});
- it('should be added to bidmanager if returned from nexage POST bid request', () => {
- server.respondWith(JSON.stringify(getDefaultBidResponse()));
- adapter.callBids(createBidderRequest({
+ it('should return url with custom pageId and sizeId when options are present', () => {
+ let bidRequest = createCustomBidRequest({
params: {
- id: 'id-1',
- imp: [{
- id: 'id-2',
- banner: {
- w: '100',
- h: '100'
- },
- tagid: 'header1'
- }]
+ placement: 1234567,
+ network: '9599.1',
+ pageId: 1111,
+ sizeId: 2222
}
- }));
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
- var bidResponse = bidmanager.addBidResponse.firstCall.args[1];
+ });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain('/pubapi/3.0/9599.1/1234567/1111/2222/ADTECH;');
});
- it('should be added to bidmanager with correct bidderCode', () => {
- server.respondWith(JSON.stringify(getDefaultBidResponse()));
- adapter.callBids(getDefaultBidRequest());
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
- expect(bidmanager.addBidResponse.firstCall.args[1]).to.have.property('bidderCode', 'aol');
+ it('should return url with default alias if alias param is missing', () => {
+ let bidRequest = getDefaultBidRequest();
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.match(/alias=\w+?;/);
});
- it('should have adId matching the bidId from related bid request', () => {
- server.respondWith(JSON.stringify(getDefaultBidResponse()));
- adapter.callBids(getDefaultBidRequest());
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
- expect(bidmanager.addBidResponse.firstCall.args[1])
- .to.have.property('adId', '84ab500420319d');
+ it('should return url with custom alias if it is present', () => {
+ let bidRequest = createCustomBidRequest({
+ params: {
+ placement: 1234567,
+ network: '9599.1',
+ alias: 'desktop_articlepage_something_box_300_250'
+ }
+ });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain('alias=desktop_articlepage_something_box_300_250');
});
- it('should be added to bidmanager as invalid in case of empty response', () => {
- server.respondWith('');
- adapter.callBids(getDefaultBidRequest());
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
- expect(bidmanager.addBidResponse.firstCall.args[1].getStatusCode()).to.equal(2);
+ it('should return url without bidfloor option if is is missing', () => {
+ let bidRequest = getDefaultBidRequest();
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).not.to.contain('bidfloor=');
});
- it('should be added to bidmanager as invalid in case of invalid JSON response', () => {
- server.respondWith('{foo:{bar:{baz:');
- adapter.callBids(getDefaultBidRequest());
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
- expect(bidmanager.addBidResponse.firstCall.args[1].getStatusCode()).to.equal(2);
+ it('should return url with bidFloor option if it is present', () => {
+ let bidRequest = createCustomBidRequest({
+ params: {
+ placement: 1234567,
+ network: '9599.1',
+ bidFloor: 0.80
+ }
+ });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain('bidfloor=0.8');
});
- it('should be added to bidmanager as invalid in case of no bid data', () => {
- let bidResponse = getDefaultBidResponse();
- bidResponse.seatbid = [];
- server.respondWith(JSON.stringify(bidResponse));
-
- adapter.callBids(getDefaultBidRequest());
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
- expect(bidmanager.addBidResponse.firstCall.args[1].getStatusCode()).to.equal(2);
+ it('should return url with key values if keyValues param is present', () => {
+ let bidRequest = createCustomBidRequest({
+ params: {
+ placement: 1234567,
+ network: '9599.1',
+ keyValues: {
+ age: 25,
+ height: 3.42,
+ test: 'key'
+ }
+ }
+ });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain('kvage=25;kvheight=3.42;kvtest=key');
});
+ });
- it('should have adId matching the bidId from bid request in case of no bid data', () => {
- let bidResponse = getDefaultBidResponse();
- bidResponse.seatbid = [];
- server.respondWith(JSON.stringify(bidResponse));
-
- adapter.callBids(getDefaultBidRequest());
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
- expect(bidmanager.addBidResponse.firstCall.args[1])
- .to.have.property('adId', '84ab500420319d');
+ describe('One Mobile', () => {
+ it('should return One Mobile url when One Mobile get params are present', () => {
+ let bidRequest = createCustomBidRequest({
+ params: getNexageGetBidParams()
+ });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain(NEXAGE_URL);
});
- it('should be added to bidmanager as invalid in case of empty price', () => {
- let bidResponse = getDefaultBidResponse();
- bidResponse.seatbid[0].bid[0].price = undefined;
-
- server.respondWith(JSON.stringify(bidResponse));
- adapter.callBids(getDefaultBidRequest());
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
- expect(bidmanager.addBidResponse.firstCall.args[1].getStatusCode()).to.equal(2);
+ it('should return One Mobile url with different host when host option is present', () => {
+ let bidParams = Object.assign({
+ host: 'qa-hb.nexage.com'
+ }, getNexageGetBidParams());
+ let bidRequest = createCustomBidRequest({
+ params: bidParams
+ });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain('qa-hb.nexage.com/bidRequest?');
});
- it('should be added to bidmanager with attributes from pubapi response', () => {
- let bidResponse = getDefaultBidResponse();
- bidResponse.seatbid[0].bid[0].crid = '12345';
-
- server.respondWith(JSON.stringify(bidResponse));
- adapter.callBids(getDefaultBidRequest());
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
- let addedBidResponse = bidmanager.addBidResponse.firstCall.args[1];
- expect(addedBidResponse.ad).to.equal('');
- expect(addedBidResponse.cpm).to.equal(0.09);
- expect(addedBidResponse.width).to.equal(728);
- expect(addedBidResponse.height).to.equal(90);
- expect(addedBidResponse.creativeId).to.equal('12345');
- expect(addedBidResponse.pubapiId).to.equal('245730051428950632');
+ it('should return One Mobile url when One Mobile and Marketplace params are present', () => {
+ let bidParams = Object.assign(getNexageGetBidParams(), getMarketplaceBidParams());
+ let bidRequest = createCustomBidRequest({
+ params: bidParams
+ });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain(NEXAGE_URL);
});
- it('should be added to bidmanager including pixels from pubapi response', () => {
- let bidResponse = getDefaultBidResponse();
- bidResponse.ext = {
- pixels: ''
- };
-
- server.respondWith(JSON.stringify(bidResponse));
- adapter.callBids(getDefaultBidRequest());
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
- let addedBidResponse = bidmanager.addBidResponse.firstCall.args[1];
- expect(addedBidResponse.ad).to.equal(
- '' +
- ''
- );
+ it('should return One Mobile url for onemobile bidder code ' +
+ 'when One Mobile GET and Marketplace params are present', () => {
+ let bidParams = Object.assign(getNexageGetBidParams(), getMarketplaceBidParams());
+ let bidRequest = createCustomBidRequest({
+ bids: [{
+ bidder: 'onemobile'
+ }],
+ params: bidParams
+ });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain(NEXAGE_URL);
});
- it('should be added to bidmanager including dealid from pubapi response', () => {
- let bidResponse = getDefaultBidResponse();
- bidResponse.seatbid[0].bid[0].dealid = '12345';
-
- server.respondWith(JSON.stringify(bidResponse));
- adapter.callBids(getDefaultBidRequest());
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
- let addedBidResponse = bidmanager.addBidResponse.firstCall.args[1];
- expect(addedBidResponse.dealId).to.equal('12345');
+ it('should not return any url for onemobile bidder code' +
+ 'when only Marketplace params are present', () => {
+ let bidRequest = createCustomBidRequest({
+ bids: [{
+ bidder: 'onemobile'
+ }],
+ params: getMarketplaceBidParams()
+ });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request).to.be.empty;
});
- it('should be added to bidmanager including encrypted price from pubapi response', () => {
- let bidResponse = getDefaultBidResponse();
- bidResponse.seatbid[0].bid[0].ext.encp = 'a9334987';
- server.respondWith(JSON.stringify(bidResponse));
-
- adapter.callBids(getDefaultBidRequest());
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
- let addedBidResponse = bidmanager.addBidResponse.firstCall.args[1];
- expect(addedBidResponse.cpm).to.equal('a9334987');
+ it('should return One Mobile url with required params - dcn & pos', () => {
+ let bidRequest = createCustomBidRequest({
+ params: getNexageGetBidParams()
+ });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain(NEXAGE_URL + 'dcn=2c9d2b50015c5ce9db6aeeed8b9500d6&pos=header');
});
- it('should not render pixels on pubapi response when no parameter is set', () => {
- let bidResponse = getDefaultBidResponse();
- bidResponse.ext = {
- pixels: ''
- };
- server.respondWith(JSON.stringify(bidResponse));
- adapter.callBids(getDefaultBidRequest());
- server.respond();
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
- expect(document.body.querySelectorAll('iframe[src="pixels.org"]').length).to.equal(0);
+ it('should return One Mobile url with cmd=bid option', () => {
+ let bidRequest = createCustomBidRequest({
+ params: getNexageGetBidParams()
+ });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain('cmd=bid');
});
- it('should render pixels from pubapi response when param userSyncOn is set with \'bidResponse\'', () => {
- let bidResponse = getDefaultBidResponse();
- bidResponse.ext = {
- pixels: ''
- };
+ it('should return One Mobile url with generic params if ext option is present', () => {
+ let bidRequest = createCustomBidRequest({
+ params: {
+ dcn: '54321123',
+ pos: 'footer-2324',
+ ext: {
+ param1: 'val1',
+ param2: 'val2',
+ param3: 'val3',
+ param4: 'val4'
+ }
+ }
+ });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain('hb.nexage.com/bidRequest?dcn=54321123&pos=footer-2324&cmd=bid' +
+ '¶m1=val1¶m2=val2¶m3=val3¶m4=val4');
+ });
- server.respondWith(JSON.stringify(bidResponse));
- let bidRequest = getDefaultBidRequest();
- bidRequest.bids[0].params.userSyncOn = 'bidResponse';
- adapter.callBids(bidRequest);
- server.respond();
+ it('should return request object for One Mobile POST endpoint when POST configuration is present', () => {
+ let bidConfig = getNexagePostBidParams();
+ let bidRequest = createCustomBidRequest({
+ params: bidConfig
+ });
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request.url).to.contain(NEXAGE_URL);
+ expect(request.method).to.equal('POST');
+ expect(request.data).to.deep.equal(bidConfig);
+ expect(request.options).to.deep.equal({
+ contentType: 'application/json',
+ customHeaders: {
+ 'x-openrtb-version': '2.2'
+ }
+ });
+ });
- let assertPixelsItem = (pixelsItemSelector) => {
- let pixelsItem = document.body.querySelectorAll(pixelsItemSelector)[0];
+ it('should not return request object for One Mobile POST endpoint' +
+ 'if required parameterers are missed', () => {
+ let bidRequest = createCustomBidRequest({
+ params: {
+ imp: []
+ }
+ });
+ let [request] = spec.buildRequests(bidRequest.bids);
+ expect(request).to.be.empty;
+ });
+ });
+ });
- expect(pixelsItem.width).to.equal('1');
- expect(pixelsItem.height).to.equal('1');
- expect(pixelsItem.style.display).to.equal('none');
- };
+ describe('getUserSyncs()', () => {
+ let bidResponse;
+ let bidRequest;
- assertPixelsItem('iframe[src="pixels.org"]');
- assertPixelsItem('iframe[src="pixels1.org"]');
- expect($$PREBID_GLOBAL$$.aolGlobals.pixelsDropped).to.be.true;
+ beforeEach(() => {
+ $$PREBID_GLOBAL$$.aolGlobals.pixelsDropped = false;
+ config.setConfig({
+ aol: {
+ userSyncOn: 'bidResponse'
+ },
});
+ bidResponse = getDefaultBidResponse();
+ bidResponse.ext = {
+ pixels: getPixels()
+ };
+ });
- it('should not render pixels if it was rendered before', () => {
- $$PREBID_GLOBAL$$.aolGlobals.pixelsDropped = true;
- let bidResponse = getDefaultBidResponse();
- bidResponse.ext = {
- pixels: ''
- };
- server.respondWith(JSON.stringify(bidResponse));
-
- let bidRequest = getDefaultBidRequest();
- bidRequest.bids[0].params.userSyncOn = 'bidResponse';
- adapter.callBids(bidRequest);
- server.respond();
+ it('should return user syncs only if userSyncOn equals to "bidResponse"', () => {
+ let userSyncs = spec.getUserSyncs({}, [bidResponse], bidRequest);
- expect(bidmanager.addBidResponse.calledOnce).to.be.true;
+ expect($$PREBID_GLOBAL$$.aolGlobals.pixelsDropped).to.be.true;
+ expect(userSyncs).to.deep.equal([
+ {type: 'image', url: 'img.org'},
+ {type: 'iframe', url: 'pixels1.org'}
+ ]);
+ });
- let assertPixelsItem = (pixelsItemSelector) => {
- let pixelsItems = document.body.querySelectorAll(pixelsItemSelector);
+ it('should not return user syncs if it has already been returned', () => {
+ $$PREBID_GLOBAL$$.aolGlobals.pixelsDropped = true;
- expect(pixelsItems.length).to.equal(0);
- };
+ let userSyncs = spec.getUserSyncs({}, [bidResponse], bidRequest);
- assertPixelsItem('iframe[src="test.com"]');
- assertPixelsItem('iframe[src="test2.com"]');
- });
+ expect($$PREBID_GLOBAL$$.aolGlobals.pixelsDropped).to.be.true;
+ expect(userSyncs).to.deep.equal([]);
});
- describe('when bidCpmAdjustment is set', () => {
- let bidderSettingsBackup;
- let server;
+ it('should not return user syncs if pixels are not present', () => {
+ bidResponse.ext.pixels = null;
- beforeEach(() => {
- bidderSettingsBackup = $$PREBID_GLOBAL$$.bidderSettings;
- server = sinon.fakeServer.create();
- });
+ let userSyncs = spec.getUserSyncs({}, [bidResponse], bidRequest);
- afterEach(() => {
- $$PREBID_GLOBAL$$.bidderSettings = bidderSettingsBackup;
- server.restore();
- if (utils.logWarn.restore) {
- utils.logWarn.restore();
- }
- });
-
- it('should show warning in the console', function() {
- sinon.spy(utils, 'logWarn');
- server.respondWith(JSON.stringify(getDefaultBidResponse()));
- $$PREBID_GLOBAL$$.bidderSettings = {
- aol: {
- bidCpmAdjustment: function() {}
- }
- };
- adapter.callBids(getDefaultBidRequest());
- server.respond();
- expect(utils.logWarn.calledOnce).to.be.true;
- });
+ expect($$PREBID_GLOBAL$$.aolGlobals.pixelsDropped).to.be.false;
+ expect(userSyncs).to.deep.equal([]);
});
});
});