diff --git a/modules/sortableAnalyticsAdapter.js b/modules/sortableAnalyticsAdapter.js deleted file mode 100644 index 4580ce6dbb8..00000000000 --- a/modules/sortableAnalyticsAdapter.js +++ /dev/null @@ -1,535 +0,0 @@ -import { logInfo, getParameterByName, getOldestHighestCpmBid } from '../src/utils.js'; -import adapter from '../src/AnalyticsAdapter.js'; -import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager.js'; -import {ajax} from '../src/ajax.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import { config } from '../src/config.js'; -import {bidderSettings} from '../src/bidderSettings.js'; - -const DEFAULT_PROTOCOL = 'https'; -const DEFAULT_HOST = 'pa.deployads.com'; -const DEFAULT_URL = `${DEFAULT_PROTOCOL}://${DEFAULT_HOST}/pae`; -const ANALYTICS_TYPE = 'endpoint'; -const UTM_STORE_KEY = 'sortable_utm'; - -export const DEFAULT_PBID_TIMEOUT = 1000; -export const TIMEOUT_FOR_REGISTRY = 250; - -const settings = {}; -const { - EVENTS: { - AUCTION_INIT, - AUCTION_END, - BID_REQUESTED, - BID_ADJUSTMENT, - BID_WON, - BID_TIMEOUT, - } -} = CONSTANTS; - -const minsToMillis = mins => mins * 60 * 1000; -const UTM_TTL = minsToMillis(30); - -const SORTABLE_EVENTS = { - BID_WON: 'pbrw', - BID_TIMEOUT: 'pbto', - ERROR: 'pber', - PB_BID: 'pbid' -}; - -const UTM_PARAMS = [ - 'utm_campaign', - 'utm_source', - 'utm_medium', - 'utm_content', - 'utm_term' -]; - -const EVENT_KEYS_SHORT_NAMES = { - 'auctionId': 'ai', - 'adUnitCode': 'ac', - 'adId': 'adi', - 'bidderAlias': 'bs', - 'bidFactor': 'bif', - 'bidId': 'bid', - 'bidRequestCount': 'brc', - 'bidderRequestId': 'brid', - 'bidRequestedSizes': 'rs', - 'bidTopCpm': 'btcp', - 'bidTopCpmCurrency': 'btcc', - 'bidTopIsNetRevenue': 'btin', - 'bidTopFactor': 'btif', - 'bidTopSrc': 'btsrc', - 'cpm': 'c', - 'currency': 'cc', - 'dealId': 'did', - 'isNetRevenue': 'inr', - 'isTop': 'it', - 'isWinner': 'iw', - 'isTimeout': 'ito', - 'mediaType': 'mt', - 'reachedTop': 'rtp', - 'numIframes': 'nif', - 'size': 'siz', - 'start': 'st', - 'tagId': 'tgid', - 'transactionId': 'trid', - 'ttl': 'ttl', - 'ttr': 'ttr', - 'url': 'u', - 'utm_campaign': 'uc', - 'utm_source': 'us', - 'utm_medium': 'um', - 'utm_content': 'un', - 'utm_term': 'ut' -}; - -const auctionCache = {}; - -let bidderFactors = null; - -let timeoutId = null; -let eventsToBeSent = []; - -function getStorage() { - try { - return window['sessionStorage']; - } catch (e) { - return null; - } -} - -function putParams(k, v) { - try { - const storage = getStorage(); - if (!storage) { - return false; - } - if (v === null) { - storage.removeItem(k); - } else { - storage.setItem(k, JSON.stringify(v)); - } - return true; - } catch (e) { - return false; - } -} - -function getParams(k) { - try { - let storage = getStorage(); - if (!storage) { - return null; - } - let value = storage.getItem(k); - return value === null ? null : JSON.parse(value); - } catch (e) { - return null; - } -} - -function storeParams(key, paramsToSave) { - if (!settings.disableSessionTracking) { - for (let property in paramsToSave) { - if (paramsToSave.hasOwnProperty(property)) { - putParams(key, paramsToSave); - break; - } - } - } -} - -function getSiteKey(options) { - const sortableConfig = config.getConfig('sortable') || {}; - const globalSiteId = sortableConfig.siteId; - return globalSiteId || options.siteId; -} - -function generateRandomId() { - let s = (+new Date()).toString(36); - for (let i = 0; i < 6; ++i) { s += (Math.random() * 36 | 0).toString(36); } - return s; -} - -function getSessionParams() { - const stillValid = paramsFromStorage => (paramsFromStorage.created) < (+new Date() + UTM_TTL); - let sessionParams = null; - if (!settings.disableSessionTracking) { - const paramsFromStorage = getParams(UTM_STORE_KEY); - sessionParams = paramsFromStorage && stillValid(paramsFromStorage) ? paramsFromStorage : null; - } - sessionParams = sessionParams || {'created': +new Date(), 'sessionId': generateRandomId()}; - const urlParams = UTM_PARAMS.map(getParameterByName); - if (UTM_PARAMS.every(key => !sessionParams[key])) { - UTM_PARAMS.forEach((v, i) => sessionParams[v] = urlParams[i] || sessionParams[v]); - sessionParams.created = +new Date(); - storeParams(UTM_STORE_KEY, sessionParams); - } - return sessionParams; -} - -function getPrebidVersion() { - return getGlobal().version; -} - -function getFactor(bidder) { - if (bidder && bidder.bidCpmAdjustment) { - return bidder.bidCpmAdjustment(1.0); - } else { - return null; - } -} - -function getBiddersFactors() { - const result = {}; - const settings = bidderSettings.getSettings(); - if (settings) { - Object.keys(settings).forEach(bidderKey => { - const bidder = settings[bidderKey]; - const factor = getFactor(bidder); - if (factor !== null) { - result[bidderKey] = factor; - } - }); - } - return result; -} - -function getBaseEvent(auctionId, adUnitCode, bidderCode) { - const event = {}; - event.s = settings.key; - event.ai = auctionId; - event.ac = adUnitCode; - event.bs = bidderCode; - return event; -} - -function getBidBaseEvent(auctionId, adUnitCode, bidderCode) { - const sessionParams = getSessionParams(); - const prebidVersion = getPrebidVersion(); - const event = getBaseEvent(auctionId, adUnitCode, bidderCode); - event.sid = sessionParams.sessionId; - event.pv = settings.pageviewId; - event.to = auctionCache[auctionId].timeout; - event.pbv = prebidVersion; - UTM_PARAMS.filter(k => sessionParams[k]).forEach(k => event[EVENT_KEYS_SHORT_NAMES[k]] = sessionParams[k]); - return event; -} - -function createPBBidEvent(bid) { - const event = getBidBaseEvent(bid.auctionId, bid.adUnitCode, bid.bidderAlias); - Object.keys(bid).forEach(k => { - const shortName = EVENT_KEYS_SHORT_NAMES[k]; - if (shortName) { - event[shortName] = bid[k]; - } - }); - event._type = SORTABLE_EVENTS.PB_BID; - return event; -} - -function getBidFactor(bidderAlias) { - if (!bidderFactors) { - bidderFactors = getBiddersFactors(); - } - const factor = bidderFactors[bidderAlias]; - return typeof factor !== 'undefined' ? factor : 1.0; -} - -function createPrebidBidWonEvent({auctionId, adUnitCode, bidderAlias, cpm, currency, isNetRevenue}) { - const bidFactor = getBidFactor(bidderAlias); - const event = getBaseEvent(auctionId, adUnitCode, bidderAlias); - event.bif = bidFactor; - bidderFactors = null; - event.c = cpm; - event.cc = currency; - event.inr = isNetRevenue; - event._type = SORTABLE_EVENTS.BID_WON; - return event; -} - -function createPrebidTimeoutEvent({auctionId, adUnitCode, bidderAlias}) { - const event = getBaseEvent(auctionId, adUnitCode, bidderAlias); - event._type = SORTABLE_EVENTS.BID_TIMEOUT; - return event; -} - -function getDistinct(arr) { - return arr.filter((v, i, a) => a.indexOf(v) === i); -} - -function groupBy(list, keyGetterFn) { - const map = {}; - list.forEach(item => { - const key = keyGetterFn(item); - map[key] = map[key] ? map[key].concat(item) : [item]; - }); - return map; -} - -function mergeAndCompressEventsByType(events, type) { - if (!events.length) { - return {}; - } - const allKeys = getDistinct(events.map(ev => Object.keys(ev)).reduce((prev, curr) => prev.concat(curr), [])); - const eventsAsMap = {}; - allKeys.forEach(k => { - events.forEach(ev => eventsAsMap[k] = eventsAsMap[k] ? eventsAsMap[k].concat(ev[k]) : [ev[k]]); - }); - const allSame = arr => arr.every(el => arr[0] === el); - Object.keys(eventsAsMap) - .forEach(k => eventsAsMap[k] = (eventsAsMap[k].length && allSame(eventsAsMap[k])) ? eventsAsMap[k][0] : eventsAsMap[k]); - eventsAsMap._count = events.length; - const result = {}; - result[type] = eventsAsMap; - return result; -} - -function mergeAndCompressEvents(events) { - const types = getDistinct(events.map(e => e._type)); - const groupedEvents = groupBy(events, e => e._type); - const results = types.map(t => groupedEvents[t]) - .map(events => mergeAndCompressEventsByType(events, events[0]._type)); - return results.reduce((prev, eventMap) => { - const key = Object.keys(eventMap)[0]; - prev[key] = eventMap[key]; - return prev; - }, {}); -} - -function registerEvents(events) { - eventsToBeSent = eventsToBeSent.concat(events); - if (!timeoutId) { - timeoutId = setTimeout(() => { - const _eventsToBeSent = eventsToBeSent.slice(); - eventsToBeSent = []; - sendEvents(_eventsToBeSent); - timeoutId = null; - }, TIMEOUT_FOR_REGISTRY); - } -} - -function sendEvents(events) { - const url = settings.url; - const mergedEvents = mergeAndCompressEvents(events); - const options = { - 'contentType': 'text/plain', - 'method': 'POST', - 'withCredentials': true - }; - const onSend = () => logInfo('Sortable Analytics data sent'); - ajax(url, onSend, JSON.stringify(mergedEvents), options); -} - -// converts [[300, 250], [728, 90]] to '300x250,728x90' -function sizesToString(sizes) { - return sizes.map(s => s.join('x')).join(','); -} - -function dimsToSizeString(width, height) { - return `${width}x${height}`; -} - -function handleBidRequested(event) { - const refererInfo = event.refererInfo; - const url = refererInfo.referer; - const reachedTop = refererInfo.reachedTop; - const numIframes = refererInfo.numIframes; - event.bids.forEach(bid => { - const auctionId = bid.auctionId; - const adUnitCode = bid.adUnitCode; - const tagId = bid.bidder === 'sortable' ? bid.params.tagId : ''; - if (!auctionCache[auctionId].adUnits[adUnitCode]) { - auctionCache[auctionId].adUnits[adUnitCode] = {bids: {}}; - } - const adUnit = auctionCache[auctionId].adUnits[adUnitCode]; - const bids = adUnit.bids; - const newBid = { - adUnitCode: bid.adUnitCode, - auctionId: event.auctionId, - bidderAlias: bid.bidder, - bidId: bid.bidId, - bidderRequestId: bid.bidderRequestId, - bidRequestCount: bid.bidRequestsCount, - bidRequestedSizes: sizesToString(bid.sizes), - currency: bid.currency, - cpm: 0.0, - isTimeout: false, - isTop: false, - isWinner: false, - numIframes: numIframes, - start: event.start, - tagId: tagId, - transactionId: bid.transactionId, - reachedTop: reachedTop, - url: encodeURI(url) - }; - bids[newBid.bidderAlias] = newBid; - }); -} - -function handleBidAdjustment(event) { - const auctionId = event.auctionId; - const adUnitCode = event.adUnitCode; - const adUnit = auctionCache[auctionId].adUnits[adUnitCode]; - const bid = adUnit.bids[event.bidderCode]; - const bidFactor = getBidFactor(event.bidderCode); - bid.adId = event.adId; - bid.adUnitCode = event.adUnitCode; - bid.auctionId = event.auctionId; - bid.bidderAlias = event.bidderCode; - bid.bidFactor = bidFactor; - bid.cpm = event.cpm; - bid.currency = event.currency; - bid.dealId = event.dealId; - bid.isNetRevenue = event.netRevenue; - bid.mediaType = event.mediaType; - bid.responseTimestamp = event.responseTimestamp; - bid.size = dimsToSizeString(event.width, event.height); - bid.ttl = event.ttl; - bid.ttr = event.timeToRespond; -} - -function handleBidWon(event) { - const auctionId = event.auctionId; - const auction = auctionCache[auctionId]; - if (auction) { - const adUnitCode = event.adUnitCode; - const adUnit = auction.adUnits[adUnitCode]; - Object.keys(adUnit.bids).forEach(bidderCode => { - const bidFromUnit = adUnit.bids[bidderCode]; - bidFromUnit.isWinner = event.bidderCode === bidderCode; - }); - } else { - const ev = createPrebidBidWonEvent({ - adUnitCode: event.adUnitCode, - auctionId: event.auctionId, - bidderAlias: event.bidderCode, - currency: event.currency, - cpm: event.cpm, - isNetRevenue: event.netRevenue, - }); - registerEvents([ev]); - } -} - -function handleBidTimeout(event) { - event.forEach(timeout => { - const auctionId = timeout.auctionId; - const adUnitCode = timeout.adUnitCode; - const bidderAlias = timeout.bidder; - const auction = auctionCache[auctionId]; - if (auction) { - const adUnit = auction.adUnits[adUnitCode]; - const bid = adUnit.bids[bidderAlias]; - bid.isTimeout = true; - } else { - const prebidTimeoutEvent = createPrebidTimeoutEvent({auctionId, adUnitCode, bidderAlias}); - registerEvents([prebidTimeoutEvent]); - } - }); -} - -function handleAuctionInit(event) { - const auctionId = event.auctionId; - const timeout = event.timeout; - auctionCache[auctionId] = {timeout: timeout, auctionId: auctionId, adUnits: {}}; -} - -function handleAuctionEnd(event) { - const auction = auctionCache[event.auctionId]; - const adUnits = auction.adUnits; - setTimeout(() => { - const events = Object.keys(adUnits).map(adUnitCode => { - const bidderKeys = Object.keys(auction.adUnits[adUnitCode].bids); - const bids = bidderKeys.map(bidderCode => auction.adUnits[adUnitCode].bids[bidderCode]); - const highestBid = bids.length ? bids.reduce(getOldestHighestCpmBid) : null; - return bidderKeys.map(bidderCode => { - const bid = auction.adUnits[adUnitCode].bids[bidderCode]; - if (highestBid && highestBid.cpm) { - bid.isTop = highestBid.bidderAlias === bid.bidderAlias; - bid.bidTopFactor = getBidFactor(highestBid.bidderAlias); - bid.bidTopCpm = highestBid.cpm; - bid.bidTopCpmCurrency = highestBid.currency; - bid.bidTopIsNetRevenue = highestBid.isNetRevenue; - bid.bidTopSrc = highestBid.bidderAlias; - } - return createPBBidEvent(bid); - }); - }).reduce((prev, curr) => prev.concat(curr), []); - bidderFactors = null; - sendEvents(events); - delete auctionCache[event.auctionId]; - }, settings.timeoutForPbid); -} - -function handleError(eventType, event, e) { - const ev = {}; - ev.s = settings.key; - ev.ti = eventType; - ev.args = JSON.stringify(event); - ev.msg = e.message; - ev._type = SORTABLE_EVENTS.ERROR; - registerEvents([ev]); -} - -const sortableAnalyticsAdapter = Object.assign(adapter({url: DEFAULT_URL, ANALYTICS_TYPE}), { - track({eventType, args}) { - try { - switch (eventType) { - case AUCTION_INIT: - handleAuctionInit(args); - break; - case AUCTION_END: - handleAuctionEnd(args); - break; - case BID_REQUESTED: - handleBidRequested(args); - break; - case BID_ADJUSTMENT: - handleBidAdjustment(args); - break; - case BID_WON: - handleBidWon(args); - break; - case BID_TIMEOUT: - handleBidTimeout(args); - break; - } - } catch (e) { - handleError(eventType, args, e); - } - } -}); - -sortableAnalyticsAdapter.originEnableAnalytics = sortableAnalyticsAdapter.enableAnalytics; - -sortableAnalyticsAdapter.enableAnalytics = function (setupConfig) { - if (this.initConfig(setupConfig)) { - logInfo('Sortable Analytics adapter enabled'); - sortableAnalyticsAdapter.originEnableAnalytics(setupConfig); - } -}; - -sortableAnalyticsAdapter.initConfig = function (setupConfig) { - settings.disableSessionTracking = setupConfig.disableSessionTracking === undefined ? false : setupConfig.disableSessionTracking; - settings.key = getSiteKey(setupConfig.options); - settings.protocol = setupConfig.options.protocol || DEFAULT_PROTOCOL; - settings.url = `${settings.protocol}://${setupConfig.options.eventHost || DEFAULT_HOST}/pae/${settings.key}`; - settings.pageviewId = generateRandomId(); - settings.timeoutForPbid = setupConfig.timeoutForPbid ? Math.max(setupConfig.timeoutForPbid, 0) : DEFAULT_PBID_TIMEOUT; - return !!settings.key; -}; - -sortableAnalyticsAdapter.getOptions = function () { - return settings; -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: sortableAnalyticsAdapter, - code: 'sortable' -}); - -export default sortableAnalyticsAdapter; diff --git a/modules/sortableAnalyticsAdapter.md b/modules/sortableAnalyticsAdapter.md deleted file mode 100644 index a4aa8019031..00000000000 --- a/modules/sortableAnalyticsAdapter.md +++ /dev/null @@ -1,9 +0,0 @@ -# Overview - -Module Name: Sortable Analytics Adapter -Module Type: Analytics Adapter -Maintainer: prebid@sortable.com - -# Description - -Analytics adapter for Sortable. Contact prebid@sortable.com for information. diff --git a/test/spec/modules/sortableAnalyticsAdapter_spec.js b/test/spec/modules/sortableAnalyticsAdapter_spec.js deleted file mode 100644 index 9300756eae2..00000000000 --- a/test/spec/modules/sortableAnalyticsAdapter_spec.js +++ /dev/null @@ -1,306 +0,0 @@ -import {expect} from 'chai'; -import sortableAnalyticsAdapter, {TIMEOUT_FOR_REGISTRY, DEFAULT_PBID_TIMEOUT} from 'modules/sortableAnalyticsAdapter.js'; -import * as events from 'src/events.js'; -import CONSTANTS from 'src/constants.json'; -import * as prebidGlobal from 'src/prebidGlobal.js'; -import {server} from 'test/mocks/xhr.js'; - -describe('Sortable Analytics Adapter', function() { - let sandbox; - let clock; - - const initialConfig = { - provider: 'sortable', - options: { - siteId: 'testkey' - } - }; - - const TEST_DATA = { - AUCTION_INIT: { - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - timeout: 3000 - }, - BID_REQUESTED: { - refererInfo: { - referer: 'test.com', - reachedTop: true, - numIframes: 1 - }, - bidderCode: 'sortable', - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - bids: [{ - bidder: 'sortable', - params: { - tagId: 'medrec_1' - }, - adUnitCode: '300x250', - transactionId: 'aa02b498-8a99-418e-bc59-6b6fd45f32de', - sizes: [ - [300, 250] - ], - bidId: '26721042674416', - bidderRequestId: '10141593b1d84a', - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - bidRequestsCount: 1 - }, { - bidder: 'sortable', - params: { - tagId: 'lead_1' - }, - adUnitCode: '728x90', - transactionId: 'b7e9e957-af4f-4c47-8ca7-41f01cb4f105', - sizes: [ - [728, 90] - ], - bidId: '50fa575b41e596', - bidderRequestId: '37a8760be6db23', - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - bidRequestsCount: 1 - }], - start: 1553529405788 - }, - BID_ADJUSTMENT_1: { - bidderCode: 'sortable', - adId: '88221d316425f7', - mediaType: 'banner', - cpm: 0.70, - dealId: null, - currency: 'USD', - netRevenue: true, - ttl: 60, - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - responseTimestamp: 1553534161763, - bidder: 'sortable', - adUnitCode: '300x250', - timeToRespond: 331, - width: '300', - height: '250' - }, - AUCTION_END: { - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e' - }, - BID_ADJUSTMENT_2: { - bidderCode: 'sortable', - adId: '88221d316425f8', - mediaType: 'banner', - cpm: 0.50, - dealId: null, - currency: 'USD', - netRevenue: true, - ttl: 60, - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - responseTimestamp: 1553534161770, - bidder: 'sortable', - adUnitCode: '728x90', - timeToRespond: 338, - width: '728', - height: '90' - }, - BID_WON_1: { - bidderCode: 'sortable', - adId: '88221d316425f7', - mediaType: 'banner', - cpm: 0.70, - dealId: null, - currency: 'USD', - netRevenue: true, - ttl: 60, - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - responseTimestamp: 1553534161763, - bidder: 'sortable', - adUnitCode: '300x250', - timeToRespond: 331 - }, - BID_WON_2: { - bidderCode: 'sortable', - adId: '88221d316425f8', - mediaType: 'banner', - cpm: 0.50, - dealId: null, - currency: 'USD', - netRevenue: true, - ttl: 60, - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - responseTimestamp: 1553534161770, - bidder: 'sortable', - adUnitCode: '728x90', - timeToRespond: 338 - }, - BID_TIMEOUT: [{ - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - adUnitCode: '300x250', - bidder: 'sortable' - }] - }; - - beforeEach(function() { - sandbox = sinon.sandbox.create(); - clock = sandbox.useFakeTimers(); - sandbox.stub(events, 'getEvents').returns([]); - sandbox.stub(prebidGlobal, 'getGlobal').returns({ - version: '1.0', - bidderSettings: { - 'sortable': { - bidCpmAdjustment: function (number) { - return number * 0.95; - } - } - } - }); - sortableAnalyticsAdapter.enableAnalytics(initialConfig); - }); - - afterEach(function() { - sandbox.restore(); - clock.restore(); - sortableAnalyticsAdapter.disableAnalytics(); - }); - - describe('initialize adapter', function() { - const settings = sortableAnalyticsAdapter.getOptions(); - - it('should init settings correctly and apply defaults', function() { - expect(settings).to.include({ - 'disableSessionTracking': false, - 'key': initialConfig.options.siteId, - 'protocol': 'https', - 'url': `https://pa.deployads.com/pae/${initialConfig.options.siteId}`, - 'timeoutForPbid': DEFAULT_PBID_TIMEOUT - }); - }); - it('should assign a pageview ID', function() { - expect(settings).to.have.own.property('pageviewId'); - }); - }); - - describe('events tracking', function() { - beforeEach(function() { - server.requests = []; - }); - it('should send the PBID event', function() { - events.emit(CONSTANTS.EVENTS.AUCTION_INIT, TEST_DATA.AUCTION_INIT); - events.emit(CONSTANTS.EVENTS.BID_REQUESTED, TEST_DATA.BID_REQUESTED); - events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, TEST_DATA.BID_ADJUSTMENT_1); - events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, TEST_DATA.BID_ADJUSTMENT_2); - events.emit(CONSTANTS.EVENTS.AUCTION_END, TEST_DATA.AUCTION_END); - events.emit(CONSTANTS.EVENTS.BID_WON, TEST_DATA.BID_WON_1); - events.emit(CONSTANTS.EVENTS.BID_WON, TEST_DATA.BID_WON_2); - - clock.tick(DEFAULT_PBID_TIMEOUT); - - expect(server.requests.length).to.equal(1); - let result = JSON.parse(server.requests[0].requestBody); - expect(result).to.have.own.property('pbid'); - expect(result.pbid).to.deep.include({ - ai: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - ac: ['300x250', '728x90'], - adi: ['88221d316425f7', '88221d316425f8'], - bs: 'sortable', - bid: ['26721042674416', '50fa575b41e596'], - bif: 0.95, - brc: 1, - brid: ['10141593b1d84a', '37a8760be6db23'], - rs: ['300x250', '728x90'], - btcp: [0.70, 0.50].map(n => n * 0.95), - btcc: 'USD', - btin: true, - btsrc: 'sortable', - c: [0.70, 0.50].map(n => n * 0.95), - cc: 'USD', - did: null, - inr: true, - it: true, - iw: true, - ito: false, - mt: 'banner', - rtp: true, - nif: 1, - pbv: '1.0', - siz: ['300x250', '728x90'], - st: 1553529405788, - tgid: ['medrec_1', 'lead_1'], - to: 3000, - trid: ['aa02b498-8a99-418e-bc59-6b6fd45f32de', 'b7e9e957-af4f-4c47-8ca7-41f01cb4f105'], - ttl: 60, - ttr: [331, 338], - u: 'test.com', - _count: 2 - }); - }); - - it('should track a late bidWon event', function() { - events.emit(CONSTANTS.EVENTS.AUCTION_INIT, TEST_DATA.AUCTION_INIT); - events.emit(CONSTANTS.EVENTS.BID_REQUESTED, TEST_DATA.BID_REQUESTED); - events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, TEST_DATA.BID_ADJUSTMENT_1); - events.emit(CONSTANTS.EVENTS.AUCTION_END, TEST_DATA.AUCTION_END); - - clock.tick(DEFAULT_PBID_TIMEOUT); - - events.emit(CONSTANTS.EVENTS.BID_WON, TEST_DATA.BID_WON_1); - - clock.tick(TIMEOUT_FOR_REGISTRY); - - expect(server.requests.length).to.equal(2); - const pbid_req = JSON.parse(server.requests[0].requestBody); - expect(pbid_req).to.have.own.property('pbid'); - const pbwon_req = JSON.parse(server.requests[1].requestBody); - expect(pbwon_req).to.have.own.property('pbrw'); - expect(pbwon_req.pbrw).to.deep.equal({ - ac: '300x250', - ai: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - bif: 0.95, - bs: 'sortable', - s: initialConfig.options.siteId, - cc: 'USD', - c: 0.70, - inr: true, - _count: 1, - _type: 'pbrw' - }); - }); - - it('should track late bidder timeouts', function() { - events.emit(CONSTANTS.EVENTS.AUCTION_INIT, TEST_DATA.AUCTION_INIT); - events.emit(CONSTANTS.EVENTS.BID_REQUESTED, TEST_DATA.BID_REQUESTED); - events.emit(CONSTANTS.EVENTS.AUCTION_END, TEST_DATA.AUCTION_END); - clock.tick(DEFAULT_PBID_TIMEOUT); - events.emit(CONSTANTS.EVENTS.BID_TIMEOUT, TEST_DATA.BID_TIMEOUT); - - clock.tick(TIMEOUT_FOR_REGISTRY); - - expect(server.requests.length).to.equal(2); - const pbid_req = JSON.parse(server.requests[0].requestBody); - expect(pbid_req).to.have.own.property('pbid'); - const pbto_req = JSON.parse(server.requests[1].requestBody); - expect(pbto_req).to.have.own.property('pbto'); - expect(pbto_req.pbto).to.deep.equal({ - ai: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - s: initialConfig.options.siteId, - ac: '300x250', - bs: 'sortable', - _type: 'pbto', - _count: 1 - }); - }); - - it('should track errors', function() { - events.emit(CONSTANTS.EVENTS.AUCTION_INIT, TEST_DATA.AUCTION_INIT); - events.emit(CONSTANTS.EVENTS.BID_REQUESTED, {}); - - clock.tick(TIMEOUT_FOR_REGISTRY); - - expect(server.requests.length).to.equal(1); - const err_req = JSON.parse(server.requests[0].requestBody); - expect(err_req).to.have.own.property('pber'); - expect(err_req.pber).to.include({ - args: '{}', - s: initialConfig.options.siteId, - _count: 1, - ti: 'bidRequested', - _type: 'pber' - }); - expect(err_req.pber.msg).to.be.a('string'); - }); - }); -});