diff --git a/integrationExamples/gpt/hello_world_emoteev.html b/integrationExamples/gpt/hello_world_emoteev.html
index 5e4d0716d2b..5a33e2d9701 100644
--- a/integrationExamples/gpt/hello_world_emoteev.html
+++ b/integrationExamples/gpt/hello_world_emoteev.html
@@ -5,74 +5,69 @@
+ setTimeout(function () {
+ initAdserver();
+ }, FAILSAFE_TIMEOUT);
+ googletag.cmd.push(function () {
+ googletag.defineSlot('/19968336/header-bid-tag-1', sizes, 'div-1')
+ .addService(googletag.pubads());
+ googletag.pubads().enableSingleRequest();
+ googletag.enableServices();
+ });
+
@@ -80,9 +75,9 @@ Basic Prebid.js Example
Div-1
diff --git a/modules/emoteevBidAdapter.js b/modules/emoteevBidAdapter.js
index 9b03b357818..4436d39bb70 100644
--- a/modules/emoteevBidAdapter.js
+++ b/modules/emoteevBidAdapter.js
@@ -1,76 +1,322 @@
+/**
+ * This file contains Emoteev bid adpater.
+ *
+ * It is organised as follows:
+ * - Constants values;
+ * - Spec API functions, which should be pristine pure;
+ * - Ancillary functions, which should be as pure as possible;
+ * - Adapter API, where unpure side-effects happen.
+ *
+ * The code style is « functional core, imperative shell ».
+ *
+ * @link https://www.emoteev.io
+ * @file This files defines the spec of EmoteevBidAdapter.
+ * @author Emoteev Engineering .
+ */
+
import {registerBidder} from '../src/adapters/bidderFactory';
import {BANNER} from '../src/mediaTypes';
-import * as utils from '../src/utils';
+import {
+ triggerPixel,
+ getUniqueIdentifierStr,
+ contains,
+ deepAccess,
+ isArray,
+ getParameterByName
+} from '../src/utils';
import {config} from '../src/config';
+import * as url from '../src/url';
+import {getCookie} from './pubCommonId';
export const BIDDER_CODE = 'emoteev';
-export const AK_PBJS_VERSION = '1.35.0';
-export const EMOTEEV_BASE_URL = 'https://prebid.emoteev.io';
-export const EMOTEEV_BASE_URL_STAGING = 'https://prebid-staging.emoteev.io';
-export const EMOTEEV_BASE_URL_DEVELOPMENT = 'http://localhost:3000';
+/**
+ * Version number of the adapter API.
+ */
+export const ADAPTER_VERSION = '1.35.0';
+
+export const DOMAIN = 'prebid.emoteev.io';
+export const DOMAIN_STAGING = 'prebid-staging.emoteev.io';
+export const DOMAIN_DEVELOPMENT = 'localhost:3000';
-export const ENDPOINT_PATH = '/api/prebid/bid';
-export const USER_SYNC_IFRAME_URL_PATH = '/api/prebid/sync-iframe';
-export const USER_SYNC_IMAGE_URL_PATH = '/api/prebid/sync-image';
+/**
+ * Path of Emoteev endpoint for events.
+ */
+export const EVENTS_PATH = '/api/ad_event.json';
+
+/**
+ * Path of Emoteev bidder.
+ */
+export const BIDDER_PATH = '/api/prebid/bid';
+export const USER_SYNC_IFRAME_PATH = '/api/prebid/sync-iframe';
+export const USER_SYNC_IMAGE_PATH = '/api/prebid/sync-image';
export const PRODUCTION = 'production';
export const STAGING = 'staging';
export const DEVELOPMENT = 'development';
export const DEFAULT_ENV = PRODUCTION;
-export const conformBidRequest = bidRequest => {
+export const ON_ADAPTER_CALLED = 'on_adapter_called';
+export const ON_BID_WON = 'on_bid_won';
+export const ON_BIDDER_TIMEOUT = 'on_bidder_timeout';
+
+/**
+ * Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#valid-build-requests-array for detailed semantic.
+ *
+ * @param {AdUnit.bidRequest} bidRequest
+ * @returns {boolean} Is this bidRequest valid?
+ */
+export const isBidRequestValid = (bidRequest) => {
+ return !!(
+ bidRequest &&
+ bidRequest.params &&
+ deepAccess(bidRequest, 'params.adSpaceId') &&
+ bidRequest.bidder === BIDDER_CODE &&
+ validateSizes(deepAccess(bidRequest, 'mediaTypes.banner.sizes')));
+};
+
+/**
+ * Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#serverrequest-objects for detailed semantic.
+ *
+ * @param {string} env Emoteev environment parameter
+ * @param {boolean} debug Pbjs debug parameter.
+ * @param {string} currency See http://prebid.org/dev-docs/modules/currency.html for detailed semantic.
+ * @param {Array} validBidRequests Takes an array of bid requests, which are guaranteed to have passed the isBidRequestValid() test.
+ * @param bidderRequest General context for a bidder request being constructed
+ * @returns {ServerRequest}
+ */
+export const buildRequests = (env, debug, currency, validBidRequests, bidderRequest) => {
return {
- params: bidRequest.params,
- crumbs: bidRequest.crumbs,
- sizes: bidRequest.sizes,
- bidId: bidRequest.bidId,
- bidderRequestId: bidRequest.bidderRequestId,
+ method: 'POST',
+ url: bidderUrl(env),
+ data: JSON.stringify(requestsPayload(debug, currency, validBidRequests, bidderRequest))
};
};
-export const emoteevDebug = (parameterDebug, configDebug) => {
- if (parameterDebug && parameterDebug.length && parameterDebug.length > 0) return JSON.parse(parameterDebug);
- else if (configDebug) return configDebug;
- else return false;
-};
+/**
+ * Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#interpreting-the-response for detailed semantic.
+ *
+ * @param {Array} serverResponse.body The body of the server response is an array of bid objects.
+ * @returns {Array}
+ */
+export const interpretResponse = (serverResponse) => serverResponse.body;
-export const emoteevEnv = (parameteremoteevEnv, configemoteevEnv) => {
- if (utils.contains([PRODUCTION, STAGING, DEVELOPMENT], parameteremoteevEnv)) return parameteremoteevEnv;
- else if (utils.contains([PRODUCTION, STAGING, DEVELOPMENT], configemoteevEnv)) return configemoteevEnv;
- else return DEFAULT_ENV;
+/**
+ * Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#registering-on-set-targeting for detailed semantic.
+ *
+ * @param {string} env Emoteev environment parameter.
+ * @param {BidRequest} bidRequest
+ * @returns {UrlObject}
+ */
+export function onAdapterCalled(env, bidRequest) {
+ return {
+ protocol: 'https',
+ hostname: domain(env),
+ pathname: EVENTS_PATH,
+ search: {
+ eventName: ON_ADAPTER_CALLED,
+ pubcId: deepAccess(bidRequest, 'crumbs.pubcid'),
+ bidId: bidRequest.bidId,
+ adSpaceId: deepAccess(bidRequest, 'params.adSpaceId'),
+ cache_buster: getUniqueIdentifierStr()
+ }
+ };
+}
+
+/**
+ * Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#registering-on-bid-won for detailed semantic.
+ *
+ * @param {string} env Emoteev environment parameter.
+ * @param {string} pubcId Publisher common id. See http://prebid.org/dev-docs/modules/pubCommonId.html for detailed semantic.
+ * @param bidObject
+ * @returns {UrlObject}
+ */
+export const onBidWon = (env, pubcId, bidObject) => {
+ const bidId = bidObject.requestId;
+ return {
+ protocol: 'https',
+ hostname: domain(env),
+ pathname: EVENTS_PATH,
+ search: {
+ eventName: ON_BID_WON,
+ pubcId,
+ bidId,
+ cache_buster: getUniqueIdentifierStr()
+ }
+ };
};
-export const emoteevOverrides = (parameteremoteevOverrides, configemoteevOverrides) => {
- if (parameteremoteevOverrides && parameteremoteevOverrides.length !== 0) {
- let parsedParams = null;
- try {
- parsedParams = JSON.parse(parameteremoteevOverrides);
- } catch (error) {
- parsedParams = null;
+/**
+ * Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#registering-on-timeout for detailed semantic.
+ *
+ * @param {string} env Emoteev environment parameter.
+ * @param {BidRequest} bidRequest
+ * @returns {UrlObject}
+ */
+export const onTimeout = (env, bidRequest) => {
+ return {
+ protocol: 'https',
+ hostname: domain(env),
+ pathname: EVENTS_PATH,
+ search: {
+ eventName: ON_BIDDER_TIMEOUT,
+ pubcId: deepAccess(bidRequest, 'crumbs.pubcid'),
+ bidId: bidRequest.bidId,
+ adSpaceId: deepAccess(bidRequest, 'params.adSpaceId'),
+ timeout: bidRequest.timeout,
+ cache_buster: getUniqueIdentifierStr()
}
- if (parsedParams) return parsedParams;
}
- if (configemoteevOverrides && Object.keys(configemoteevOverrides).length !== 0) return configemoteevOverrides;
- else return {};
};
-export const akUrl = (environment) => {
- switch (environment) {
+/**
+ * Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#registering-user-syncs for detailed semantic.
+ *
+ * @param {string} env Emoteev environment parameter
+ * @param {SyncOptions} syncOptions
+ * @returns userSyncs
+ */
+export const getUserSyncs = (env, syncOptions) => {
+ let syncs = [];
+ if (syncOptions.pixelEnabled) {
+ syncs.push({
+ type: 'image',
+ url: userSyncImageUrl(env),
+ });
+ }
+ if (syncOptions.iframeEnabled) {
+ syncs.push({
+ type: 'iframe',
+ url: userSyncIframeUrl(env),
+ });
+ }
+ return syncs;
+};
+
+/**
+ * Pure function.
+ *
+ * @param {string} env Emoteev environment parameter
+ * @returns {string} The domain for network calls to Emoteev.
+ */
+export const domain = (env) => {
+ switch (env) {
case DEVELOPMENT:
- return EMOTEEV_BASE_URL_DEVELOPMENT;
+ return DOMAIN_DEVELOPMENT;
case STAGING:
- return EMOTEEV_BASE_URL_STAGING;
+ return DOMAIN_STAGING;
default:
- return EMOTEEV_BASE_URL;
+ return DOMAIN;
}
};
-export const endpointUrl = (parameteremoteevEnv, configemoteevEnv) => akUrl(emoteevEnv(parameteremoteevEnv, configemoteevEnv)).concat(ENDPOINT_PATH);
-export const userSyncIframeUrl = (parameteremoteevEnv, configemoteevEnv) => akUrl(emoteevEnv(parameteremoteevEnv, configemoteevEnv)).concat(USER_SYNC_IFRAME_URL_PATH);
-export const userSyncImageUrl = (parameteremoteevEnv, configemoteevEnv) => akUrl(emoteevEnv(parameteremoteevEnv, configemoteevEnv)).concat(USER_SYNC_IMAGE_URL_PATH);
+/**
+ * Pure function.
+ *
+ * @param {string} env Emoteev environment parameter
+ * @returns {string} The full URL which events is sent to.
+ */
+export const eventsUrl = env => url.format({
+ protocol: (env === DEVELOPMENT) ? 'http' : 'https',
+ hostname: domain(env),
+ pathname: EVENTS_PATH
+});
-export const getViewDimensions = () => {
+/**
+ * Pure function.
+ *
+ * @param {string} env Emoteev environment parameter
+ * @returns {string} The full URL which bidderRequest is sent to.
+ */
+export const bidderUrl = env => url.format({
+ protocol: (env === DEVELOPMENT) ? 'http' : 'https',
+ hostname: domain(env),
+ pathname: BIDDER_PATH
+});
+
+/**
+ * Pure function.
+ *
+ * @param {string} env Emoteev environment parameter
+ * @returns {string} The full URL called for iframe-based user sync
+ */
+export const userSyncIframeUrl = env => url.format({
+ protocol: (env === DEVELOPMENT) ? 'http' : 'https',
+ hostname: domain(env),
+ pathname: USER_SYNC_IFRAME_PATH
+});
+
+/**
+ * Pure function.
+ *
+ * @param {string} env Emoteev environment parameter
+ * @returns {string} The full URL called for image-based user sync
+ */
+export const userSyncImageUrl = env => url.format({
+ protocol: (env === DEVELOPMENT) ? 'http' : 'https',
+ hostname: domain(env),
+ pathname: USER_SYNC_IMAGE_PATH
+});
+
+/**
+ * Pure function.
+ *
+ * @param {Array>} sizes
+ * @returns {boolean} are sizes valid?
+ */
+const validateSizes = sizes => isArray(sizes) && sizes.some(size => isArray(size) && size.length === 2);
+
+/**
+ * Pure function.
+ *
+ * @param {BidRequest} bidRequest
+ * @returns {object} An object which represents a BidRequest for Emoteev server side.
+ */
+export const conformBidRequest = bidRequest => {
+ return {
+ params: bidRequest.params,
+ crumbs: bidRequest.crumbs,
+ sizes: bidRequest.sizes,
+ bidId: bidRequest.bidId,
+ bidderRequestId: bidRequest.bidderRequestId,
+ };
+};
+
+/**
+ * Pure function.
+ *
+ * @param {boolean} debug Pbjs debug parameter
+ * @param {string} currency See http://prebid.org/dev-docs/modules/currency.html for detailed information
+ * @param {BidRequest} validBidRequests
+ * @param {object} bidderRequest
+ * @returns
+ */
+export const requestsPayload = (debug, currency, validBidRequests, bidderRequest) => {
+ return {
+ akPbjsVersion: ADAPTER_VERSION,
+ bidRequests: validBidRequests.map(conformBidRequest),
+ currency: currency,
+ debug: debug,
+ language: navigator.language,
+ refererInfo: bidderRequest.refererInfo,
+ deviceInfo: getDeviceInfo(
+ getDeviceDimensions(window),
+ getViewDimensions(window, document),
+ getDocumentDimensions(document),
+ isWebGLEnabled(document)),
+ userAgent: navigator.userAgent,
+ gdprApplies: deepAccess(bidderRequest, 'gdprConsent.gdprApplies'),
+ gdprConsent: deepAccess(bidderRequest, 'gdprConsent.consentString'),
+ };
+};
+
+/**
+ * Pure function
+ * @param {Window} window
+ * @param {Document} document
+ * @returns {{width: number, height: number}} View dimensions
+ */
+export const getViewDimensions = (window, document) => {
let w = window;
let prefix = 'inner';
@@ -85,14 +331,24 @@ export const getViewDimensions = () => {
};
};
-export const getDeviceDimensions = () => {
+/**
+ * Pure function
+ * @param {Window} window
+ * @returns {{width: number, height: number}} Device dimensions
+ */
+export const getDeviceDimensions = (window) => {
return {
width: window.screen ? window.screen.width : '',
height: window.screen ? window.screen.height : '',
};
};
-export const getDocumentDimensions = () => {
+/**
+ * Pure function
+ * @param {Document} document
+ * @returns {{width: number, height: number}} Document dimensions
+ */
+export const getDocumentDimensions = (document) => {
const de = document.documentElement;
const be = document.body;
@@ -112,7 +368,12 @@ export const getDocumentDimensions = () => {
};
};
-export const isWebGLEnabled = () => {
+/**
+ * Unpure function
+ * @param {Document} document
+ * @returns {boolean} Is WebGL enabled?
+ */
+export const isWebGLEnabled = (document) => {
// Create test canvas
let canvas = document.createElement('canvas');
@@ -141,6 +402,14 @@ export const isWebGLEnabled = () => {
return !!gl;
};
+/**
+ * Pure function
+ * @param {{width: number, height: number}} deviceDimensions
+ * @param {{width: number, height: number}} viewDimensions
+ * @param {{width: number, height: number}} documentDimensions
+ * @param {boolean} webGL
+ * @returns {object} Device information
+ */
export const getDeviceInfo = (deviceDimensions, viewDimensions, documentDimensions, webGL) => {
return {
browserWidth: viewDimensions.width,
@@ -153,62 +422,62 @@ export const getDeviceInfo = (deviceDimensions, viewDimensions, documentDimensio
};
};
-const validateSizes = sizes => utils.isArray(sizes) && sizes.some(size => utils.isArray(size) && size.length === 2);
+/**
+ * Pure function
+ * @param {object} config pbjs config value
+ * @param {string} parameter Environment override from URL query param.
+ * @returns One of [PRODUCTION, STAGING, DEVELOPMENT].
+ */
+export const resolveEnv = (config, parameter) => {
+ const configEnv = deepAccess(config, 'emoteev.env');
+
+ if (contains([PRODUCTION, STAGING, DEVELOPMENT], parameter)) return parameter;
+ else if (contains([PRODUCTION, STAGING, DEVELOPMENT], configEnv)) return configEnv;
+ else return DEFAULT_ENV;
+};
+
+/**
+ * Pure function
+ * @param {object} config pbjs config value
+ * @param {string} parameter Debug override from URL query param.
+ * @returns {boolean}
+ */
+export const resolveDebug = (config, parameter) => {
+ if (parameter && parameter.length && parameter.length > 0) return JSON.parse(parameter);
+ else if (config.debug) return config.debug;
+ else return false;
+};
+/**
+ * EmoteevBidAdapter spec
+ * @access public
+ * @type {BidderSpec}
+ */
export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [BANNER],
-
- isBidRequestValid: (bid) => {
- return !!(
- bid &&
- bid.params &&
- bid.params.adSpaceId &&
- bid.bidder === BIDDER_CODE &&
- validateSizes(bid.mediaTypes.banner.sizes)
- );
- },
-
- buildRequests: (validBidRequests, bidderRequest) => {
- const payload = Object.assign({},
- {
- akPbjsVersion: AK_PBJS_VERSION,
- bidRequests: validBidRequests.map(conformBidRequest),
- currency: config.getConfig('currency'),
- debug: emoteevDebug(utils.getParameterByName('emoteevDebug'), config.getConfig('emoteev.debug')),
- language: navigator.language,
- refererInfo: bidderRequest.refererInfo,
- deviceInfo: getDeviceInfo(getDeviceDimensions(), getViewDimensions(), getDocumentDimensions(), isWebGLEnabled()),
- userAgent: navigator.userAgent,
- },
- emoteevOverrides(utils.getParameterByName('emoteevOverrides'), config.getConfig('emoteev.overrides')));
-
- return {
- method: 'POST',
- url: endpointUrl(utils.getParameterByName('emoteevEnv'), config.getConfig('emoteev.env')),
- data: JSON.stringify(payload),
- };
- },
-
- interpretResponse: (serverResponse) => serverResponse.body,
-
- getUserSyncs: (syncOptions, serverResponses) => {
- const parameteremoteevEnv = utils.getParameterByName('emoteev.env');
- const configemoteevEnv = config.getConfig('emoteev.env');
- const syncs = [];
- if (syncOptions.iframeEnabled) {
- syncs.push({
- type: 'iframe',
- url: userSyncIframeUrl(parameteremoteevEnv, configemoteevEnv),
- });
- }
- if (syncOptions.pixelEnabled && serverResponses.length > 0) {
- syncs.push({
- type: 'image',
- url: userSyncImageUrl(parameteremoteevEnv, configemoteevEnv),
- });
- }
- return syncs;
- },
+ isBidRequestValid: isBidRequestValid,
+ buildRequests: (validBidRequests, bidderRequest) =>
+ buildRequests(
+ resolveEnv(config.getConfig(), getParameterByName('emoteevEnv')),
+ resolveDebug(config.getConfig(), getParameterByName('debug')),
+ config.getConfig('currency'),
+ validBidRequests,
+ bidderRequest),
+ interpretResponse: interpretResponse,
+ onBidWon: (bidObject) =>
+ triggerPixel(url.format(onBidWon(
+ resolveEnv(config.getConfig(), getParameterByName('emoteevEnv')),
+ getCookie('_pubcid'),
+ bidObject))),
+ onTimeout: (bidRequest) =>
+ triggerPixel(url.format(onTimeout(
+ resolveEnv(config.getConfig(), getParameterByName('emoteevEnv')),
+ bidRequest))),
+ getUserSyncs: (syncOptions) =>
+ getUserSyncs(
+ resolveEnv(config.getConfig(), getParameterByName('emoteevEnv')),
+ syncOptions),
};
+
registerBidder(spec);
diff --git a/modules/emokteevBidAdapter.md b/modules/emoteevBidAdapter.md
similarity index 100%
rename from modules/emokteevBidAdapter.md
rename to modules/emoteevBidAdapter.md
diff --git a/test/spec/modules/emoteevBidAdapter_spec.js b/test/spec/modules/emoteevBidAdapter_spec.js
index a5f5c439e6f..a5460ab939d 100644
--- a/test/spec/modules/emoteevBidAdapter_spec.js
+++ b/test/spec/modules/emoteevBidAdapter_spec.js
@@ -1,26 +1,49 @@
-import {expect} from 'chai';
import {
- AK_PBJS_VERSION,
- EMOTEEV_BASE_URL,
- EMOTEEV_BASE_URL_STAGING,
- emoteevDebug,
- emoteevEnv,
- emoteevOverrides,
- akUrl,
+ assert, expect
+} from 'chai';
+import {
+ ADAPTER_VERSION,
+ DOMAIN,
+ DOMAIN_DEVELOPMENT,
+ DOMAIN_STAGING,
+ domain,
+ BIDDER_PATH,
+ bidderUrl,
+ buildRequests,
conformBidRequest,
DEFAULT_ENV,
- ENDPOINT_PATH,
- endpointUrl,
+ DEVELOPMENT,
+ EVENTS_PATH,
+ eventsUrl,
+ getDeviceDimensions,
+ getDeviceInfo,
+ getDocumentDimensions,
+ getUserSyncs,
+ getViewDimensions,
+ interpretResponse,
+ isBidRequestValid,
+ isWebGLEnabled,
+ ON_ADAPTER_CALLED,
+ ON_BID_WON,
+ ON_BIDDER_TIMEOUT,
+ onBidWon,
+ onAdapterCalled,
+ onTimeout,
PRODUCTION,
+ requestsPayload,
+ resolveDebug,
+ resolveEnv,
spec,
STAGING,
- USER_SYNC_IFRAME_URL_PATH,
- USER_SYNC_IMAGE_URL_PATH,
+ USER_SYNC_IFRAME_PATH,
+ USER_SYNC_IMAGE_PATH,
userSyncIframeUrl,
userSyncImageUrl,
} from 'modules/emoteevBidAdapter';
-import {newBidder} from 'src/adapters/bidderFactory';
-import {config} from 'src/config';
+import * as url from '../../../src/url';
+import * as utils from '../../../src/utils';
+import * as pubCommonId from '../../../modules/pubCommonId';
+import {config} from '../../../src/config';
const cannedValidBidRequests = [{
adUnitCode: '/19968336/header-bid-tag-1',
@@ -48,7 +71,11 @@ const cannedBidderRequest = {
stack: ['http://localhost:9999/integrationExamples/gpt/hello_world_emoteev.html']
},
start: 1544200012839,
- timeout: 3000
+ timeout: 3000,
+ gdprConsent: {
+ gdprApplies: true,
+ consentString: 'my consentString'
+ }
};
const serverResponse =
{
@@ -68,106 +95,11 @@ const serverResponse =
};
describe('emoteevBidAdapter', function () {
- const adapter = newBidder(spec);
-
- describe('inherited functions', function () {
- it('exists and is a function', function () {
- expect(adapter.callBids).to.exist.and.to.be.a('function');
- });
- });
-
- describe('conformBidRequest', function () {
- it('returns a bid-request', function () {
- expect(conformBidRequest(cannedValidBidRequests[0])).to.deep.equal({
- params: cannedValidBidRequests[0].params,
- crumbs: cannedValidBidRequests[0].crumbs,
- sizes: cannedValidBidRequests[0].sizes,
- bidId: cannedValidBidRequests[0].bidId,
- bidderRequestId: cannedValidBidRequests[0].bidderRequestId,
- });
- })
- });
-
- describe('emoteevDebug', function () {
- expect(emoteevDebug(null, null)).to.deep.equal(false)
- });
- describe('emoteevDebug', function () {
- expect(emoteevDebug(null, true)).to.deep.equal(true)
- });
- describe('emoteevDebug', function () {
- expect(emoteevDebug(JSON.stringify(true), null)).to.deep.equal(true)
- });
-
- describe('emoteevEnv', function () {
- expect(emoteevEnv(null, null)).to.deep.equal(DEFAULT_ENV)
- });
- describe('emoteevEnv', function () {
- expect(emoteevEnv(null, STAGING)).to.deep.equal(STAGING)
- });
- describe('emoteevEnv', function () {
- expect(emoteevEnv(STAGING, null)).to.deep.equal(STAGING)
- });
-
- describe('emoteevOverrides', function () {
- expect(emoteevOverrides(null, null)).to.deep.equal({})
- });
- describe('emoteevOverrides', function () {
- expect(emoteevOverrides(JSON.stringify({a: 1}), null)).to.deep.equal({a: 1})
- });
- describe('emoteevOverrides', function () {
- expect(emoteevOverrides('incorrect', null)).to.deep.equal({})
- }); // expect no exception
- describe('emoteevOverrides', function () {
- expect(emoteevOverrides(null, {a: 1})).to.deep.equal({a: 1})
- });
-
- describe('akUrl', function () {
- expect(akUrl(null)).to.deep.equal(EMOTEEV_BASE_URL)
- });
- describe('akUrl', function () {
- expect(akUrl('anything')).to.deep.equal(EMOTEEV_BASE_URL)
- });
- describe('akUrl', function () {
- expect(akUrl(STAGING)).to.deep.equal(EMOTEEV_BASE_URL_STAGING)
- });
- describe('akUrl', function () {
- expect(akUrl('production')).to.deep.equal(EMOTEEV_BASE_URL)
- });
-
- describe('endpointUrl', function () {
- expect(endpointUrl(null, null)).to.deep.equal(EMOTEEV_BASE_URL.concat(ENDPOINT_PATH))
- });
- describe('endpointUrl', function () {
- expect(endpointUrl(null, STAGING)).to.deep.equal(EMOTEEV_BASE_URL_STAGING.concat(ENDPOINT_PATH))
- });
- describe('endpointUrl', function () {
- expect(endpointUrl(STAGING, null)).to.deep.equal(EMOTEEV_BASE_URL_STAGING.concat(ENDPOINT_PATH))
- });
-
- describe('userSyncIframeUrl', function () {
- expect(userSyncIframeUrl(null, null)).to.deep.equal(EMOTEEV_BASE_URL.concat(USER_SYNC_IFRAME_URL_PATH))
- });
- describe('userSyncIframeUrl', function () {
- expect(userSyncIframeUrl(null, STAGING)).to.deep.equal(EMOTEEV_BASE_URL_STAGING.concat(USER_SYNC_IFRAME_URL_PATH))
- });
- describe('userSyncIframeUrl', function () {
- expect(userSyncIframeUrl(STAGING, null)).to.deep.equal(EMOTEEV_BASE_URL_STAGING.concat(USER_SYNC_IFRAME_URL_PATH))
- });
-
- describe('userSyncImageUrl', function () {
- expect(userSyncImageUrl(null, null)).to.deep.equal(EMOTEEV_BASE_URL.concat(USER_SYNC_IMAGE_URL_PATH))
- });
- describe('userSyncImageUrl', function () {
- expect(userSyncImageUrl(null, STAGING)).to.deep.equal(EMOTEEV_BASE_URL_STAGING.concat(USER_SYNC_IMAGE_URL_PATH))
- });
- describe('userSyncImageUrl', function () {
- expect(userSyncImageUrl(STAGING, null)).to.deep.equal(EMOTEEV_BASE_URL_STAGING.concat(USER_SYNC_IMAGE_URL_PATH))
- });
-
describe('isBidRequestValid', function () {
- it('should return true when required params found', function () {
+ it('should return true when valid', function () {
const validBid = {
bidder: 'emoteev',
+ bidId: '23a45b4e3',
params: {
adSpaceId: 12345,
},
@@ -177,11 +109,14 @@ describe('emoteevBidAdapter', function () {
}
},
};
- expect(spec.isBidRequestValid(validBid)).to.equal(true);
+ expect(isBidRequestValid(validBid)).to.equal(true);
+
+ expect(spec.isBidRequestValid(validBid)).to.exist.and.to.be.a('boolean');
+ expect(spec.isBidRequestValid({})).to.exist.and.to.be.a('boolean');
});
it('should return false when required params are invalid', function () {
- expect(spec.isBidRequestValid({
+ expect(isBidRequestValid({
bidder: '', // invalid bidder
params: {
adSpaceId: 12345,
@@ -192,7 +127,7 @@ describe('emoteevBidAdapter', function () {
}
},
})).to.equal(false);
- expect(spec.isBidRequestValid({
+ expect(isBidRequestValid({
bidder: 'emoteev',
params: {
adSpaceId: '', // invalid adSpaceId
@@ -203,7 +138,7 @@ describe('emoteevBidAdapter', function () {
}
},
})).to.equal(false);
- expect(spec.isBidRequestValid({
+ expect(isBidRequestValid({
bidder: 'emoteev',
params: {
adSpaceId: 12345,
@@ -219,131 +154,602 @@ describe('emoteevBidAdapter', function () {
describe('buildRequests', function () {
const
+ env = DEFAULT_ENV,
+ debug = true,
currency = 'EUR',
- emoteevEnv = STAGING,
- emoteevDebug = true,
- emoteevOverrides = {
- iAmOverride: 'iAmOverride'
- };
- config.setConfig({ // asynchronous
- currency,
- emoteev: {
- env: STAGING,
- debug: emoteevDebug,
- overrides: emoteevOverrides
- }
- });
+ request = buildRequests(env, debug, currency, cannedValidBidRequests, cannedBidderRequest);
- config.getConfig('emoteev', function () {
- const request = spec.buildRequests(cannedValidBidRequests, cannedBidderRequest);
-
- it('creates a request object with correct method, url and data', function () {
- expect(request).to.exist.and.have.all.keys(
- 'method',
- 'url',
- 'data',
- );
- expect(request.method).to.equal('POST');
- expect(request.url).to.equal(endpointUrl(emoteevEnv, emoteevEnv));
-
- let requestData = JSON.parse(request.data);
- expect(requestData).to.exist.and.have.all.keys(
- 'akPbjsVersion',
- 'bidRequests',
- 'currency',
- 'debug',
- 'iAmOverride',
- 'language',
- 'refererInfo',
- 'deviceInfo',
- 'userAgent',
- );
-
- expect(requestData.bidRequests[0]).to.exist.and.have.all.keys(
- 'params',
- 'crumbs',
- 'sizes',
- 'bidId',
- 'bidderRequestId',
- );
-
- expect(requestData.akPbjsVersion).to.deep.equal(AK_PBJS_VERSION);
- expect(requestData.bidRequests[0].params).to.deep.equal(cannedValidBidRequests[0].params);
- expect(requestData.bidRequests[0].crumbs).to.deep.equal(cannedValidBidRequests[0].crumbs);
- expect(requestData.bidRequests[0].mediaTypes).to.deep.equal(cannedValidBidRequests[0].mediaTypes);
- expect(requestData.bidRequests[0].bidId).to.deep.equal(cannedValidBidRequests[0].bidId);
- expect(requestData.bidRequests[0].bidderRequestId).to.deep.equal(cannedValidBidRequests[0].bidderRequestId);
- expect(requestData.currency).to.deep.equal(currency);
- expect(requestData.debug).to.deep.equal(emoteevDebug);
- expect(requestData.iAmOverride).to.deep.equal('iAmOverride');
- expect(requestData.language).to.deep.equal(navigator.language);
- expect(requestData.deviceInfo).to.exist.and.have.all.keys(
- 'browserWidth',
- 'browserHeight',
- 'deviceWidth',
- 'deviceHeight',
- 'documentWidth',
- 'documentHeight',
- 'webGL',
- );
- expect(requestData.userAgent).to.deep.equal(navigator.userAgent);
- });
- });
+ expect(request).to.exist.and.have.all.keys(
+ 'method',
+ 'url',
+ 'data',
+ );
+
+ expect(request.method).to.equal('POST');
+ expect(request.url).to.equal(bidderUrl(env));
+
+ expect(spec.buildRequests(cannedValidBidRequests, cannedBidderRequest)).to.exist.and.to.be.an('object');
});
describe('interpretResponse', function () {
it('bid objects from response', function () {
- const bidResponses = spec.interpretResponse(serverResponse);
- expect(bidResponses).to.be.an('array').that.is.not.empty; // yes, syntax is correct
- expect(bidResponses[0]).to.have.all.keys(
- 'requestId',
- 'cpm',
- 'width',
- 'height',
- 'ad',
- 'ttl',
- 'creativeId',
- 'netRevenue',
- 'currency',
- );
-
- expect(bidResponses[0].requestId).to.equal(cannedValidBidRequests[0].bidId);
- expect(bidResponses[0].cpm).to.equal(serverResponse.body[0].cpm);
- expect(bidResponses[0].width).to.equal(serverResponse.body[0].width);
- expect(bidResponses[0].height).to.equal(serverResponse.body[0].height);
- expect(bidResponses[0].ad).to.equal(serverResponse.body[0].ad);
- expect(bidResponses[0].ttl).to.equal(serverResponse.body[0].ttl);
- expect(bidResponses[0].creativeId).to.equal(serverResponse.body[0].creativeId);
- expect(bidResponses[0].netRevenue).to.equal(serverResponse.body[0].netRevenue);
- expect(bidResponses[0].currency).to.equal(serverResponse.body[0].currency);
+ const bidResponses = interpretResponse(serverResponse);
+ expect(bidResponses).to.be.an('array').that.is.not.empty;
+ expect(bidResponses[0]).to.have.property('requestId', cannedValidBidRequests[0].bidId);
+ expect(bidResponses[0]).to.have.property('cpm', serverResponse.body[0].cpm);
+ expect(bidResponses[0]).to.have.property('width', serverResponse.body[0].width);
+ expect(bidResponses[0]).to.have.property('height', serverResponse.body[0].height);
+ expect(bidResponses[0]).to.have.property('ad', serverResponse.body[0].ad);
+ expect(bidResponses[0]).to.have.property('ttl', serverResponse.body[0].ttl);
+ expect(bidResponses[0]).to.have.property('creativeId', serverResponse.body[0].creativeId);
+ expect(bidResponses[0]).to.have.property('netRevenue', serverResponse.body[0].netRevenue);
+ expect(bidResponses[0]).to.have.property('currency', serverResponse.body[0].currency);
});
});
- describe('getUserSyncs', function () {
- config.setConfig({emoteevEnv: PRODUCTION});
- expect(spec.getUserSyncs({
- iframeEnabled: true
- }, [{}])).to.deep.equal([{
- type: 'iframe',
- url: EMOTEEV_BASE_URL.concat(USER_SYNC_IFRAME_URL_PATH)
- }]);
+ describe('onAdapterCalled', function () {
+ const
+ bidRequest = cannedValidBidRequests[0],
+ url = onAdapterCalled(DEFAULT_ENV, bidRequest);
+
+ expect(url).to.have.property('protocol');
+ expect(url).to.have.property('hostname');
+ expect(url).to.have.property('pathname', EVENTS_PATH);
+ expect(url).to.have.nested.property('search.eventName', ON_ADAPTER_CALLED);
+ expect(url).to.have.nested.property('search.pubcId', bidRequest.crumbs.pubcid);
+ expect(url).to.have.nested.property('search.bidId', bidRequest.bidId);
+ expect(url).to.have.nested.property('search.adSpaceId', bidRequest.params.adSpaceId);
+ expect(url).to.have.nested.property('search.cache_buster');
+ });
+
+ describe('onBidWon', function () {
+ const
+ pubcId = cannedValidBidRequests[0].crumbs.pubcid,
+ bidObject = serverResponse.body[0],
+ url = onBidWon(DEFAULT_ENV, pubcId, bidObject);
+
+ expect(url).to.have.property('protocol');
+ expect(url).to.have.property('hostname');
+ expect(url).to.have.property('pathname', EVENTS_PATH);
+ expect(url).to.have.nested.property('search.eventName', ON_BID_WON);
+ expect(url).to.have.nested.property('search.pubcId', pubcId);
+ expect(url).to.have.nested.property('search.bidId', bidObject.requestId);
+ expect(url).to.have.nested.property('search.cache_buster');
+ });
+
+ describe('onTimeout', function () {
+ const
+ data = {
+ ...cannedValidBidRequests[0],
+ timeout: 123,
+ },
+ url = onTimeout(DEFAULT_ENV, data);
- expect(spec.getUserSyncs({
- pixelEnabled: true
- }, [{}])).to.deep.equal([{
+ expect(url).to.have.property('protocol');
+ expect(url).to.have.property('hostname');
+ expect(url).to.have.property('pathname', EVENTS_PATH);
+ expect(url).to.have.nested.property('search.eventName', ON_BIDDER_TIMEOUT);
+ expect(url).to.have.nested.property('search.bidId', data.bidId);
+ expect(url).to.have.nested.property('search.pubcId', data.crumbs.pubcid);
+ expect(url).to.have.nested.property('search.adSpaceId', data.params.adSpaceId);
+ expect(url).to.have.nested.property('search.timeout', data.timeout);
+ expect(url).to.have.nested.property('search.cache_buster');
+ });
+
+ describe('getUserSyncs', function () {
+ expect(getUserSyncs(
+ DEFAULT_ENV,
+ {
+ iframeEnabled: false,
+ pixelEnabled: false
+ })).to.deep.equal([]);
+ expect(getUserSyncs(
+ PRODUCTION,
+ {
+ iframeEnabled: false,
+ pixelEnabled: true
+ })).to.deep.equal([{
type: 'image',
- url: EMOTEEV_BASE_URL.concat(USER_SYNC_IMAGE_URL_PATH)
+ url: userSyncImageUrl(PRODUCTION)
}]);
-
- expect(spec.getUserSyncs({
- iframeEnabled: true,
- pixelEnabled: true
- }, [{}])).to.deep.equal([{
+ expect(getUserSyncs(
+ STAGING,
+ {
+ iframeEnabled: true,
+ pixelEnabled: false
+ })).to.deep.equal([{
type: 'iframe',
- url: EMOTEEV_BASE_URL.concat(USER_SYNC_IFRAME_URL_PATH)
- }, {
+ url: userSyncIframeUrl(STAGING)
+ }]);
+ expect(getUserSyncs(
+ DEVELOPMENT,
+ {
+ iframeEnabled: true,
+ pixelEnabled: true
+ })).to.deep.equal([{
type: 'image',
- url: EMOTEEV_BASE_URL.concat(USER_SYNC_IMAGE_URL_PATH)
+ url: userSyncImageUrl(DEVELOPMENT)
+ }, {
+ type: 'iframe',
+ url: userSyncIframeUrl(DEVELOPMENT)
}]);
});
+
+ describe('domain', function () {
+ expect(domain(null)).to.deep.equal(DOMAIN);
+ expect(domain('anything')).to.deep.equal(DOMAIN);
+ expect(domain(PRODUCTION)).to.deep.equal(DOMAIN);
+ expect(domain(STAGING)).to.deep.equal(DOMAIN_STAGING);
+ expect(domain(DEVELOPMENT)).to.deep.equal(DOMAIN_DEVELOPMENT);
+ });
+
+ describe('eventsUrl', function () {
+ expect(eventsUrl(null)).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(DEFAULT_ENV),
+ pathname: EVENTS_PATH
+ }));
+ expect(eventsUrl('anything')).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(DEFAULT_ENV),
+ pathname: EVENTS_PATH
+ }));
+ expect(eventsUrl(PRODUCTION)).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(PRODUCTION),
+ pathname: EVENTS_PATH
+ }));
+ expect(eventsUrl(STAGING)).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(STAGING),
+ pathname: EVENTS_PATH
+ }));
+ expect(eventsUrl(DEVELOPMENT)).to.deep.equal(url.format({
+ hostname: domain(DEVELOPMENT),
+ pathname: EVENTS_PATH
+ }));
+ });
+
+ describe('bidderUrl', function () {
+ expect(bidderUrl(null)).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(DEFAULT_ENV),
+ pathname: BIDDER_PATH
+ }));
+ expect(bidderUrl('anything')).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(DEFAULT_ENV),
+ pathname: BIDDER_PATH
+ }));
+ expect(bidderUrl(PRODUCTION)).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(PRODUCTION),
+ pathname: BIDDER_PATH
+ }));
+ expect(bidderUrl(STAGING)).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(STAGING),
+ pathname: BIDDER_PATH
+ }));
+ expect(bidderUrl(DEVELOPMENT)).to.deep.equal(url.format({
+ hostname: domain(DEVELOPMENT),
+ pathname: BIDDER_PATH
+ }));
+ });
+
+ describe('userSyncIframeUrl', function () {
+ expect(userSyncIframeUrl(null)).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(DEFAULT_ENV),
+ pathname: USER_SYNC_IFRAME_PATH
+ }));
+ expect(userSyncIframeUrl('anything')).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(DEFAULT_ENV),
+ pathname: USER_SYNC_IFRAME_PATH
+ }));
+ expect(userSyncIframeUrl(PRODUCTION)).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(PRODUCTION),
+ pathname: USER_SYNC_IFRAME_PATH
+ }));
+ expect(userSyncIframeUrl(STAGING)).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(STAGING),
+ pathname: USER_SYNC_IFRAME_PATH
+ }));
+ expect(userSyncIframeUrl(DEVELOPMENT)).to.deep.equal(url.format({
+ hostname: domain(DEVELOPMENT),
+ pathname: USER_SYNC_IFRAME_PATH
+ }));
+ });
+
+ describe('userSyncImageUrl', function () {
+ expect(userSyncImageUrl(null)).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(DEFAULT_ENV),
+ pathname: USER_SYNC_IMAGE_PATH
+ }));
+ expect(userSyncImageUrl('anything')).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(DEFAULT_ENV),
+ pathname: USER_SYNC_IMAGE_PATH
+ }));
+ expect(userSyncImageUrl(PRODUCTION)).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(PRODUCTION),
+ pathname: USER_SYNC_IMAGE_PATH
+ }));
+ expect(userSyncImageUrl(STAGING)).to.deep.equal(url.format({
+ protocol: 'https',
+ hostname: domain(STAGING),
+ pathname: USER_SYNC_IMAGE_PATH
+ }));
+ expect(userSyncImageUrl(DEVELOPMENT)).to.deep.equal(url.format({
+ hostname: domain(DEVELOPMENT),
+ pathname: USER_SYNC_IMAGE_PATH
+ }));
+ });
+
+ describe('conformBidRequest', function () {
+ expect(conformBidRequest(cannedValidBidRequests[0])).to.deep.equal({
+ params: cannedValidBidRequests[0].params,
+ crumbs: cannedValidBidRequests[0].crumbs,
+ sizes: cannedValidBidRequests[0].sizes,
+ bidId: cannedValidBidRequests[0].bidId,
+ bidderRequestId: cannedValidBidRequests[0].bidderRequestId,
+ });
+ });
+
+ describe('requestsPayload', function () {
+ const
+ currency = 'EUR',
+ debug = true;
+
+ const payload = requestsPayload(debug, currency, cannedValidBidRequests, cannedBidderRequest);
+
+ expect(payload).to.exist.and.have.all.keys(
+ 'akPbjsVersion',
+ 'bidRequests',
+ 'currency',
+ 'debug',
+ 'language',
+ 'refererInfo',
+ 'deviceInfo',
+ 'userAgent',
+ 'gdprApplies',
+ 'gdprConsent'
+ );
+
+ expect(payload.bidRequests[0]).to.exist.and.have.all.keys(
+ 'params',
+ 'crumbs',
+ 'sizes',
+ 'bidId',
+ 'bidderRequestId',
+ );
+
+ expect(payload.akPbjsVersion).to.deep.equal(ADAPTER_VERSION);
+ expect(payload.bidRequests[0].params).to.deep.equal(cannedValidBidRequests[0].params);
+ expect(payload.bidRequests[0].crumbs).to.deep.equal(cannedValidBidRequests[0].crumbs);
+ expect(payload.bidRequests[0].mediaTypes).to.deep.equal(cannedValidBidRequests[0].mediaTypes);
+ expect(payload.bidRequests[0].bidId).to.deep.equal(cannedValidBidRequests[0].bidId);
+ expect(payload.bidRequests[0].bidderRequestId).to.deep.equal(cannedValidBidRequests[0].bidderRequestId);
+ expect(payload.currency).to.deep.equal(currency);
+ expect(payload.debug).to.deep.equal(debug);
+ expect(payload.language).to.deep.equal(navigator.language);
+ expect(payload.deviceInfo).to.exist.and.have.all.keys(
+ 'browserWidth',
+ 'browserHeight',
+ 'deviceWidth',
+ 'deviceHeight',
+ 'documentWidth',
+ 'documentHeight',
+ 'webGL',
+ );
+ expect(payload.userAgent).to.deep.equal(navigator.userAgent);
+ expect(payload.gdprApplies).to.deep.equal(cannedBidderRequest.gdprConsent.gdprApplies);
+ expect(payload.gdprConsent).to.deep.equal(cannedBidderRequest.gdprConsent.consentString);
+ });
+
+ describe('getViewDimensions', function () {
+ const window = {
+ innerWidth: 1024,
+ innerHeight: 768
+ };
+ const documentWithElement = {
+ documentElement:
+ {
+ clientWidth: 512,
+ clientHeight: 384
+ }
+ };
+ const documentWithBody = {
+ body:
+ {
+ clientWidth: 512,
+ clientHeight: 384
+ }
+ };
+ expect(getViewDimensions(window, documentWithElement)).to.deep.equal({
+ width: 1024,
+ height: 768
+ });
+ expect(getViewDimensions(window, documentWithBody)).to.deep.equal({width: 1024, height: 768});
+ expect(getViewDimensions(window, documentWithElement)).to.deep.equal({
+ width: 1024,
+ height: 768
+ });
+ expect(getViewDimensions(window, documentWithBody)).to.deep.equal({width: 1024, height: 768});
+ expect(getViewDimensions({}, documentWithElement)).to.deep.equal({width: 512, height: 384});
+ expect(getViewDimensions({}, documentWithBody)).to.deep.equal({width: 512, height: 384});
+ });
+
+ describe('getDeviceDimensions', function () {
+ const window = {screen: {width: 1024, height: 768}};
+ expect(getDeviceDimensions(window)).to.deep.equal({width: 1024, height: 768});
+ expect(getDeviceDimensions({})).to.deep.equal({width: '', height: ''});
+ });
+
+ describe('getDocumentDimensions', function () {
+ expect(getDocumentDimensions({
+ documentElement: {
+ clientWidth: 1,
+ clientHeight: 1,
+ offsetWidth: 0,
+ offsetHeight: 0,
+ scrollWidth: 0,
+ scrollHeight: 0,
+ },
+ })).to.deep.equal({width: 1, height: 1});
+
+ expect(getDocumentDimensions({
+ documentElement: {
+ clientWidth: 1,
+ clientHeight: 1,
+ offsetWidth: 0,
+ offsetHeight: 0,
+ scrollWidth: 0,
+ scrollHeight: 0,
+ },
+ body: {
+ scrollHeight: 0,
+ offsetHeight: 0,
+ }
+ })).to.deep.equal({width: 1, height: 1});
+
+ expect(getDocumentDimensions({
+ documentElement: {
+ clientWidth: 0,
+ clientHeight: 0,
+ offsetWidth: 1,
+ offsetHeight: 1,
+ scrollWidth: 0,
+ scrollHeight: 0,
+ },
+ body: {
+ scrollHeight: 0,
+ offsetHeight: 0,
+ }
+ })).to.deep.equal({width: 1, height: 1});
+
+ expect(getDocumentDimensions({
+ documentElement: {
+ clientWidth: 0,
+ clientHeight: 0,
+ offsetWidth: 0,
+ offsetHeight: 0,
+ scrollWidth: 1,
+ scrollHeight: 1,
+ },
+ body: {
+ scrollHeight: 0,
+ offsetHeight: 0,
+ }
+ })).to.deep.equal({width: 1, height: 1});
+
+ expect(getDocumentDimensions({
+ documentElement: {
+ clientWidth: undefined,
+ clientHeight: undefined,
+ offsetWidth: undefined,
+ offsetHeight: undefined,
+ scrollWidth: undefined,
+ scrollHeight: undefined,
+ },
+ body: {
+ scrollHeight: undefined,
+ offsetHeight: undefined,
+ }
+ })).to.deep.equal({width: '', height: ''});
+ });
+
+ // describe('isWebGLEnabled', function () {
+ // it('handles no webgl', function () {
+ // const
+ // document = new Document(),
+ // canvas = sinon.createStubInstance(HTMLCanvasElement);
+ // sinon.stub(document, 'createElement').withArgs('canvas').returns(canvas);
+ // canvas.getContext.withArgs('webgl').returns(undefined);
+ // canvas.getContext.withArgs('experimental-webgl').returns(undefined);
+ // expect(isWebGLEnabled(document)).to.equal(false);
+ // });
+ //
+ // it('handles webgl exception', function () {
+ // const
+ // document = new Document(),
+ // canvas = sinon.createStubInstance(HTMLCanvasElement);
+ // sinon.stub(document, 'createElement').withArgs('canvas').returns(canvas);
+ // canvas.getContext.withArgs('webgl').throws(DOMException);
+ // expect(isWebGLEnabled(document)).to.equal(false);
+ // });
+ //
+ // it('handles experimental webgl', function () {
+ // const
+ // document = new Document(),
+ // canvas = sinon.createStubInstance(HTMLCanvasElement);
+ // sinon.stub(document, 'createElement').withArgs('canvas').returns(canvas);
+ // canvas.getContext.withArgs('webgl').returns(undefined);
+ // canvas.getContext.withArgs('experimental-webgl').returns(true);
+ // expect(isWebGLEnabled(document)).to.equal(true);
+ // });
+ //
+ // it('handles experimental webgl exception', function () {
+ // const
+ // document = new Document(),
+ // canvas = sinon.createStubInstance(HTMLCanvasElement);
+ // sinon.stub(document, 'createElement').withArgs('canvas').returns(canvas);
+ // canvas.getContext.withArgs('webgl').returns(undefined);
+ // canvas.getContext.withArgs('experimental-webgl').throws(DOMException);
+ // expect(isWebGLEnabled(document)).to.equal(false);
+ // });
+ //
+ // it('handles webgl', function () {
+ // const
+ // document = new Document(),
+ // canvas = sinon.createStubInstance(HTMLCanvasElement);
+ // sinon.stub(document, 'createElement').withArgs('canvas').returns(canvas);
+ // canvas.getContext.withArgs('webgl').returns(true);
+ // expect(isWebGLEnabled(document)).to.equal(true);
+ // });
+ // });
+
+ describe('getDeviceInfo', function () {
+ expect(getDeviceInfo(
+ {width: 1, height: 2},
+ {width: 3, height: 4},
+ {width: 5, height: 6},
+ true
+ )).to.deep.equal({
+ deviceWidth: 1,
+ deviceHeight: 2,
+ browserWidth: 3,
+ browserHeight: 4,
+ documentWidth: 5,
+ documentHeight: 6,
+ webGL: true
+ });
+ });
+
+ describe('resolveEnv', function () {
+ it('defaults to production', function () {
+ expect(resolveEnv({}, null)).to.deep.equal(DEFAULT_ENV);
+ });
+ expect(resolveEnv({}, PRODUCTION)).to.deep.equal(PRODUCTION);
+ expect(resolveEnv({}, STAGING)).to.deep.equal(STAGING);
+ expect(resolveEnv({}, DEVELOPMENT)).to.deep.equal(DEVELOPMENT);
+ expect(resolveEnv({emoteev: {env: PRODUCTION}}, null)).to.deep.equal(PRODUCTION);
+ expect(resolveEnv({emoteev: {env: STAGING}}, null)).to.deep.equal(STAGING);
+ expect(resolveEnv({emoteev: {env: DEVELOPMENT}}, null)).to.deep.equal(DEVELOPMENT);
+ it('prioritizes parameter over configuration', function () {
+ expect(resolveEnv({emoteev: {env: STAGING}}, DEVELOPMENT)).to.deep.equal(DEVELOPMENT);
+ });
+ });
+
+ describe('resolveDebug', function () {
+ it('defaults to production', function () {
+ expect(resolveDebug({}, null)).to.deep.equal(false);
+ });
+ expect(resolveDebug({}, 'false')).to.deep.equal(false);
+ expect(resolveDebug({}, 'true')).to.deep.equal(true);
+ expect(resolveDebug({debug: true}, null)).to.deep.equal(true);
+ it('prioritizes parameter over configuration', function () {
+ expect(resolveDebug({debug: true}, 'false')).to.deep.equal(false);
+ });
+ });
+
+ describe('side effects', function () {
+ let triggerPixelSpy;
+ let getCookieSpy;
+ let getConfigSpy;
+ let getParameterByNameSpy;
+ beforeEach(function () {
+ triggerPixelSpy = sinon.spy(utils, 'triggerPixel');
+ getCookieSpy = sinon.spy(pubCommonId, 'getCookie');
+ getConfigSpy = sinon.spy(config, 'getConfig');
+ getParameterByNameSpy = sinon.spy(utils, 'getParameterByName');
+ });
+ afterEach(function () {
+ triggerPixelSpy.restore();
+ getCookieSpy.restore();
+ getConfigSpy.restore();
+ getParameterByNameSpy.restore();
+ });
+
+ describe('isBidRequestValid', function () {
+ it('has intended side-effects', function () {
+ const validBidRequest = {
+ bidder: 'emoteev',
+ bidId: '23a45b4e3',
+ params: {
+ adSpaceId: 12345,
+ },
+ mediaTypes: {
+ banner: {
+ sizes: [[750, 200]]
+ }
+ },
+ };
+ spec.isBidRequestValid(validBidRequest);
+ sinon.assert.notCalled(utils.triggerPixel);
+ sinon.assert.notCalled(pubCommonId.getCookie);
+ sinon.assert.notCalled(config.getConfig);
+ sinon.assert.notCalled(utils.getParameterByName);
+ });
+ it('has intended side-effects', function () {
+ const invalidBidRequest = {};
+ spec.isBidRequestValid(invalidBidRequest);
+ sinon.assert.notCalled(utils.triggerPixel);
+ sinon.assert.notCalled(pubCommonId.getCookie);
+ sinon.assert.notCalled(config.getConfig);
+ sinon.assert.notCalled(utils.getParameterByName);
+ });
+ });
+ describe('buildRequests', function () {
+ it('has intended side-effects', function () {
+ spec.buildRequests(cannedValidBidRequests, cannedBidderRequest);
+ sinon.assert.notCalled(utils.triggerPixel);
+ sinon.assert.notCalled(pubCommonId.getCookie);
+ sinon.assert.callCount(config.getConfig, 3);
+ sinon.assert.callCount(utils.getParameterByName, 2);
+ });
+ });
+ describe('interpretResponse', function () {
+ it('has intended side-effects', function () {
+ spec.interpretResponse(serverResponse);
+ sinon.assert.notCalled(utils.triggerPixel);
+ sinon.assert.notCalled(pubCommonId.getCookie);
+ sinon.assert.notCalled(config.getConfig);
+ sinon.assert.notCalled(utils.getParameterByName);
+ });
+ });
+ describe('onBidWon', function () {
+ it('has intended side-effects', function () {
+ const bidObject = serverResponse.body[0];
+ spec.onBidWon(bidObject);
+ sinon.assert.calledOnce(utils.triggerPixel);
+ sinon.assert.calledOnce(pubCommonId.getCookie);
+ sinon.assert.calledOnce(config.getConfig);
+ sinon.assert.calledOnce(utils.getParameterByName);
+ });
+ });
+ describe('onTimeout', function () {
+ it('has intended side-effects', function () {
+ spec.onTimeout(cannedValidBidRequests[0]);
+ sinon.assert.calledOnce(utils.triggerPixel);
+ sinon.assert.notCalled(pubCommonId.getCookie);
+ sinon.assert.calledOnce(config.getConfig);
+ sinon.assert.calledOnce(utils.getParameterByName);
+ });
+ });
+ describe('getUserSyncs', function () {
+ it('has intended side-effects', function () {
+ spec.getUserSyncs({});
+ sinon.assert.notCalled(utils.triggerPixel);
+ sinon.assert.notCalled(pubCommonId.getCookie);
+ sinon.assert.calledOnce(config.getConfig);
+ sinon.assert.calledOnce(utils.getParameterByName);
+ });
+ });
+ });
});