diff --git a/modules/invisiblyAnalyticsAdapter.js b/modules/invisiblyAnalyticsAdapter.js new file mode 100644 index 00000000000..e3bcb39ec4c --- /dev/null +++ b/modules/invisiblyAnalyticsAdapter.js @@ -0,0 +1,224 @@ +/** + * invisiblyAdapterAdapter.js - analytics adapter for Invisibly + */ +import { ajaxBuilder } from '../src/ajax'; +import adapter from '../src/AnalyticsAdapter'; +import adapterManager from '../src/adapterManager'; + +const DEFAULT_EVENT_URL = 'https://api.pymx5.com/v1/' + 'sites/events'; +const analyticsType = 'endpoint'; +const analyticsName = 'Invisibly Analytics Adapter:'; + +const utils = require('../src/utils'); +const CONSTANTS = require('../src/constants.json'); +const ajax = ajaxBuilder(0); + +// Events needed +const { + EVENTS: { + AUCTION_INIT, + AUCTION_END, + BID_ADJUSTMENT, + BID_TIMEOUT, + BID_REQUESTED, + BID_RESPONSE, + NO_BID, + BID_WON, + BIDDER_DONE, + SET_TARGETING, + REQUEST_BIDS, + ADD_AD_UNITS, + AD_RENDER_FAILED + } +} = CONSTANTS; + +const _VERSION = 1; +const _pageViewId = utils.generateUUID(); +let initOptions = null; +let _startAuction = 0; +let _bidRequestTimeout = 0; +let flushInterval; +let invisiblyAnalyticsEnabled = false; + +const w = window; +const d = document; +let e = d.documentElement; +let g = d.getElementsByTagName('body')[0]; +let x = w.innerWidth || e.clientWidth || g.clientWidth; +let y = w.innerHeight || e.clientHeight || g.clientHeight; + +let _pageView = { + eventType: 'pageView', + userAgent: window.navigator.userAgent, + timestamp: Date.now(), + timezoneOffset: new Date().getTimezoneOffset(), + language: window.navigator.language, + vendor: window.navigator.vendor, + screenWidth: x, + screenHeight: y +}; + +let _eventQueue = [_pageView]; + +let invisiblyAdapter = Object.assign( + adapter({ url: DEFAULT_EVENT_URL, analyticsType }), + { + track({ eventType, args }) { + handleEvent(eventType, args); + }, + sendEvent + } +); + +invisiblyAdapter.originEnableAnalytics = invisiblyAdapter.enableAnalytics; +invisiblyAdapter.enableAnalytics = function(config) { + initOptions = config.options || {}; + initOptions.url = initOptions.url || DEFAULT_EVENT_URL; + if (initOptions.url && initOptions.account) { + invisiblyAnalyticsEnabled = true; + invisiblyAdapter.originEnableAnalytics(config); + } else { + invisiblyAnalyticsEnabled = false; + invisiblyAdapter.originDisableAnalytics(); + } + flushInterval = setInterval(flush, 1000); +}; + +invisiblyAdapter.originDisableAnalytics = invisiblyAdapter.disableAnalytics; +invisiblyAdapter.disableAnalytics = function() { + if (!invisiblyAnalyticsEnabled) { + return; + } + flush(); + clearInterval(flushInterval); + invisiblyAdapter.originDisableAnalytics(); +}; + +function flush() { + if (!invisiblyAnalyticsEnabled) { + return; + } + + if (_eventQueue.length > 0) { + while (_eventQueue.length) { + let eventFromQue = _eventQueue.shift(); + let eventtype = 'PREBID_' + eventFromQue.eventType; + delete eventFromQue.eventType; + + let data = { + pageViewId: _pageViewId, + ver: _VERSION, + bundleId: initOptions.bundleId, + ...eventFromQue + }; + + let payload = { + event_type: eventtype, + event_data: { ...data } + }; + ajax( + initOptions.url, + () => utils.logInfo(`${analyticsName} sent events batch`), + JSON.stringify(payload), + { + contentType: 'application/json', + method: 'POST', + withCredentials: true + } + ); + } + } +} + +function handleEvent(eventType, eventArgs) { + eventArgs = eventArgs ? JSON.parse(JSON.stringify(eventArgs)) : {}; + let invisiblyEvent = {}; + + switch (eventType) { + case AUCTION_INIT: { + invisiblyEvent = eventArgs; + _startAuction = invisiblyEvent.timestamp; + _bidRequestTimeout = invisiblyEvent.timeout; + break; + } + case AUCTION_END: { + invisiblyEvent = eventArgs; + invisiblyEvent.start = _startAuction; + invisiblyEvent.end = Date.now(); + break; + } + case BID_ADJUSTMENT: { + invisiblyEvent.bidders = eventArgs; + break; + } + case BID_TIMEOUT: { + invisiblyEvent.bidders = eventArgs; + invisiblyEvent.duration = _bidRequestTimeout; + break; + } + case BID_REQUESTED: { + invisiblyEvent = eventArgs; + break; + } + case BID_RESPONSE: { + invisiblyEvent = eventArgs; + break; + } + case NO_BID: { + invisiblyEvent.noBid = eventArgs; + break; + } + case BID_WON: { + invisiblyEvent = eventArgs; + break; + } + case BIDDER_DONE: { + invisiblyEvent = eventArgs; + break; + } + case SET_TARGETING: { + invisiblyEvent.targetings = eventArgs; + break; + } + case REQUEST_BIDS: { + invisiblyEvent = eventArgs; + break; + } + case ADD_AD_UNITS: { + invisiblyEvent = eventArgs; + break; + } + case AD_RENDER_FAILED: { + invisiblyEvent = eventArgs; + break; + } + default: + return; + } + invisiblyEvent.eventType = eventType; + invisiblyEvent.timestamp = invisiblyEvent.timestamp || Date.now(); + sendEvent(invisiblyEvent); +} + +function sendEvent(event) { + _eventQueue.push(event); + utils.logInfo(`${analyticsName}Event ${event.eventType}:`, event); + + if (event.eventType === AUCTION_END) { + flush(); + clearInterval(flushInterval); + } +} + +adapterManager.registerAnalyticsAdapter({ + adapter: invisiblyAdapter, + code: 'invisiblyAnalytics' +}); + +invisiblyAdapter.getOptions = function() { + return initOptions; +}; + +invisiblyAdapter.flush = flush; + +export default invisiblyAdapter; diff --git a/modules/invisiblyAnalyticsAdapter.md b/modules/invisiblyAnalyticsAdapter.md new file mode 100644 index 00000000000..1023e6baf96 --- /dev/null +++ b/modules/invisiblyAnalyticsAdapter.md @@ -0,0 +1,24 @@ +# Overview + +``` +Module Name: Invisibly Analytics + +Module Type: Analytics Adapter + +Maintainer: sanjay.rawlani@invisibly.com +``` + +# Description + +Analytics adapter for Invisibly. Please contact: sanjay.rawlani@invisibly.com for any additional information. Official website link to the vendor: https://invisibly.com/ + +# Test Parameters + +``` +{ + provider: 'invisiblyAnalytics', + options : { + account: 'invisibly' //account is a mandatory input to adapter configuration + } +} +``` diff --git a/test/spec/modules/invisiblyAnalyticsAdapter_spec.js b/test/spec/modules/invisiblyAnalyticsAdapter_spec.js new file mode 100644 index 00000000000..6ee989907b5 --- /dev/null +++ b/test/spec/modules/invisiblyAnalyticsAdapter_spec.js @@ -0,0 +1,496 @@ +import invisiblyAdapter from 'modules/invisiblyAnalyticsAdapter'; +import { expect } from 'chai'; +let events = require('src/events'); +let constants = require('src/constants.json'); + +describe('Invisibly Analytics Adapter test suite', function() { + let xhr; + let requests = []; + const BID1 = { + width: 980, + height: 240, + cpm: 1.1, + timeToRespond: 200, + bidId: '2ecff0db240757', + requestId: '2ecff0db240757', + adId: '2ecff0db240757', + auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa', + adUnitCode: '/19968336/header-bid-tag-0', + adserverTargeting: { + hb_bidder: 'testBidder', + hb_adid: '2ecff0db240757', + hb_pb: 1.2, + hb_size: '640x480', + hb_source: 'client' + }, + getStatusCode() { + return CONSTANTS.STATUS.GOOD; + } + }; + + const BID2 = Object.assign({}, BID1, { + width: 300, + height: 250, + cpm: 2.2, + timeToRespond: 300, + bidId: '3ecff0db240757', + requestId: '3ecff0db240757', + adId: '3ecff0db240757' + }); + + const BID3 = { + bidId: '4ecff0db240757', + requestId: '4ecff0db240757', + adId: '4ecff0db240757', + auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa', + adUnitCode: '/19968336/header-bid-tag1', + adserverTargeting: { + hb_bidder: 'testBidder', + hb_adid: '3bd4ebb1c900e2', + hb_pb: '1.500', + hb_size: '728x90', + hb_source: 'server' + }, + getStatusCode() { + return CONSTANTS.STATUS.NO_BID; + } + }; + + const MOCK = { + config: { + provider: 'invisiblyAnalytics', + options: { + bundleId: '', + account: 'invisibly' + } + }, + AUCTION_INIT: { + auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa' + }, + BID_REQUESTED: { + bidder: 'mockBidder', + auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa', + bidderRequestId: '1be65d7958826a', + bids: [ + { + bidder: 'mockBidder', + adUnitCode: 'panorama_d_1', + bidId: '2ecff0db240757' + }, + { + bidder: 'mockBidder', + adUnitCode: 'box_d_1', + bidId: '3ecff0db240757' + }, + { + bidder: 'mockBidder', + adUnitCode: 'box_d_2', + bidId: '4ecff0db240757' + } + ], + start: 1519149562216 + }, + BID_RESPONSE: [BID1, BID2], + AUCTION_END: { + auctionId: 'test_timeout_auction_id', + timestamp: 1234567890, + timeout: 3000, + auctionEnd: 1234567990 + }, + BID_WON: { + bidderCode: 'appnexus', + width: 300, + height: 250, + adId: '1ebb82ec35375e', + mediaType: 'banner', + cpm: 0.5, + requestId: '1582271863760569973', + creative_id: '96846035', + creativeId: '96846035', + ttl: 60, + currency: 'USD', + netRevenue: true, + auctionId: '9c7b70b9-b6ab-4439-9e71-b7b382797c18', + responseTimestamp: 1537521629657, + requestTimestamp: 1537521629331, + bidder: 'appnexus', + adUnitCode: 'div-gpt-ad-1460505748561-0', + timeToRespond: 326, + size: '300x250', + status: 'rendered', + eventType: 'bidWon', + ad: 'some ad', + adUrl: 'ad url' + }, + BIDDER_DONE: { + bidderCode: 'mockBidder', + bids: [BID1, BID2, BID3] + }, + BID_TIMEOUT: [ + { + bidId: '2ecff0db240757', + auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa' + } + ], + BID_ADJUSTMENT: { + ad: 'html', + adId: '298bf14ecbafb', + cpm: 1.01, + creativeId: '2249:92806132', + currency: 'USD', + height: 250, + mediaType: 'banner', + requestId: '298bf14ecbafb', + size: '300x250', + source: 'client', + status: 'rendered', + statusMessage: 'Bid available', + timeToRespond: 421, + ttl: 300, + width: 300 + }, + NO_BID: { + testKey: false + }, + SET_TARGETING: { + [BID1.adUnitCode]: BID1.adserverTargeting, + [BID3.adUnitCode]: BID3.adserverTargeting + }, + REQUEST_BIDS: { + call: 'request' + }, + ADD_AD_UNITS: { call: 'addAdUnits' }, + AD_RENDER_FAILED: { call: 'adRenderFailed' }, + INVALID_EVENT: { + mockKey: 'this event should not emit' + } + }; + + describe('Invisibly Analytic tests specs', function() { + beforeEach(function() { + xhr = sinon.useFakeXMLHttpRequest(); + requests = []; + xhr.onCreate = request => requests.push(request); + sinon.stub(events, 'getEvents').returns([]); + sinon.spy(invisiblyAdapter, 'track'); + }); + + afterEach(function() { + invisiblyAdapter.disableAnalytics(); + events.getEvents.restore(); + invisiblyAdapter.track.restore(); + xhr.restore(); + }); + + // specs to test invisibly account input to enableAnaylitcs + describe('monitor enableAnalytics method', function() { + it('should catch all events triggered with invisibly account config', function() { + invisiblyAdapter.enableAnalytics({ + provider: 'invisiblyAnalytics', + options: { + account: 'invisibly' + } + }); + + events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); + events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); + events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); + events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); + events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); + sinon.assert.callCount(invisiblyAdapter.track, 5); + }); + + it('should not catch events triggered without invisibly account config', function() { + invisiblyAdapter.enableAnalytics({ + provider: 'invisiblyAnalytics', + options: {} + }); + + events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); + events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); + events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); + events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); + events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); + invisiblyAdapter.flush(); + sinon.assert.callCount(invisiblyAdapter.track, 0); + }); + // spec to test custom api endpoint + it('support custom endpoint', function() { + let custom_url = 'custom url'; + invisiblyAdapter.enableAnalytics({ + provider: 'invisiblyAnalytics', + options: { + url: custom_url, + bundleId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', + account: 'invisibly' + } + }); + expect(invisiblyAdapter.getOptions().url).to.equal(custom_url); + }); + }); + + // spec for auction init event + it('auction init event', function() { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse(requests[1].requestBody.substring(0)); + // pageView is default event initially hence expecting 2 requests + expect(requests.length).to.equal(2); + expect(requests[1].url).to.equal('https://api.pymx5.com/v1/sites/events'); + expect(invisiblyEvents.event_data.auctionId).to.equal( + MOCK.AUCTION_INIT.auctionId + ); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_type).to.equal('PREBID_auctionInit'); + expect(invisiblyEvents.event_data.ver).to.equal(1); + }); + + // spec for bid adjustment event + it('bid adjustment event', function() { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.BID_ADJUSTMENT, MOCK.BID_ADJUSTMENT); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse(requests[0].requestBody.substring(0)); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_bidAdjustment'); + expect(invisiblyEvents.event_data.bidders.cpm).to.equal( + MOCK.BID_ADJUSTMENT.cpm + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for bid timeout event + it('bid timeout event', function() { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.BID_TIMEOUT, MOCK.BID_TIMEOUT); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse(requests[0].requestBody.substring(0)); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_bidTimeout'); + expect(invisiblyEvents.event_data.bidders.bidId).to.equal( + MOCK.BID_TIMEOUT.bidId + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for bid requested event + it('bid requested event', function() { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse(requests[0].requestBody.substring(0)); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_bidRequested'); + expect(invisiblyEvents.event_data.auctionId).to.equal( + MOCK.BID_REQUESTED.auctionId + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for bid response event + it('bid response event', function() { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse(requests[0].requestBody.substring(0)); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_bidResponse'); + expect(invisiblyEvents.event_data.cpm).to.equal(MOCK.BID_REQUESTED.cpm); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for no bid event + it('no bid event', function() { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.NO_BID, MOCK.NO_BID); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse(requests[0].requestBody.substring(0)); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_noBid'); + expect(invisiblyEvents.event_data.noBid.testKey).to.equal( + MOCK.NO_BID.testKey + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for bid won event + it('bid won event', function() { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse(requests[0].requestBody.substring(0)); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_bidWon'); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for bidder done event + it('bidder done event', function() { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.BIDDER_DONE, MOCK.BIDDER_DONE); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse(requests[0].requestBody.substring(0)); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_bidderDone'); + expect(invisiblyEvents.event_data.bidderCode).to.equal( + MOCK.BIDDER_DONE.bidderCode + ); + expect(invisiblyEvents.event_data.bids.length).to.equal( + MOCK.BIDDER_DONE.bids.length + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for set targeting event + it('set targeting event', function() { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.SET_TARGETING, MOCK.SET_TARGETING); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse(requests[0].requestBody.substring(0)); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_setTargeting'); + expect( + invisiblyEvents.event_data.targetings[BID1.adUnitCode] + ).to.deep.equal(BID1.adserverTargeting); + expect( + invisiblyEvents.event_data.targetings[BID3.adUnitCode] + ).to.deep.equal(BID3.adserverTargeting); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for request bids event + it('request bids event', function() { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.REQUEST_BIDS, MOCK.REQUEST_BIDS); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse(requests[0].requestBody.substring(0)); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_requestBids'); + expect(invisiblyEvents.event_data.call).to.equal(MOCK.REQUEST_BIDS.call); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for add ad units event + it('add ad units event', function() { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.ADD_AD_UNITS, MOCK.ADD_AD_UNITS); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse(requests[0].requestBody.substring(0)); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_addAdUnits'); + expect(invisiblyEvents.event_data.call).to.equal(MOCK.ADD_AD_UNITS.call); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for ad render failed event + it('ad render failed event', function() { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.AD_RENDER_FAILED, MOCK.AD_RENDER_FAILED); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse(requests[0].requestBody.substring(0)); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_adRenderFailed'); + expect(invisiblyEvents.event_data.call).to.equal( + MOCK.AD_RENDER_FAILED.call + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // spec for auction end event + it('auction end event', function() { + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); + invisiblyAdapter.flush(); + + const invisiblyEvents = JSON.parse(requests[0].requestBody.substring(0)); + expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal('https://api.pymx5.com/v1/sites/events'); + expect(invisiblyEvents.event_data.pageViewId).to.exist; + expect(invisiblyEvents.event_data.ver).to.equal(1); + expect(invisiblyEvents.event_type).to.equal('PREBID_auctionEnd'); + expect(invisiblyEvents.event_data.auctionId).to.equal( + MOCK.AUCTION_END.auctionId + ); + sinon.assert.callCount(invisiblyAdapter.track, 1); + }); + + // should not call sendEvent for events not supported by the adapter + it('it should not call sendEvent for this event emit', function() { + sinon.spy(invisiblyAdapter, 'sendEvent'); + invisiblyAdapter.enableAnalytics(MOCK.config); + events.emit(constants.EVENTS.INVALID_EVENT, MOCK.INVALID_EVENT); + invisiblyAdapter.flush(); + + expect(requests.length).to.equal(0); + sinon.assert.callCount(invisiblyAdapter.track, 0); + sinon.assert.callCount(invisiblyAdapter.sendEvent, 0); + }); + + // spec to emit all events + it('track all event without errors', function() { + invisiblyAdapter.enableAnalytics(MOCK.config); + + events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); + events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); + events.emit(constants.EVENTS.BID_ADJUSTMENT, MOCK.BID_ADJUSTMENT); + events.emit(constants.EVENTS.BID_TIMEOUT, MOCK.BID_TIMEOUT); + events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); + events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); + events.emit(constants.EVENTS.NO_BID, MOCK.NO_BID); + events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); + events.emit(constants.EVENTS.BIDDER_DONE, MOCK.BIDDER_DONE); + events.emit(constants.EVENTS.SET_TARGETING, MOCK.SET_TARGETING); + events.emit(constants.EVENTS.REQUEST_BIDS, MOCK.REQUEST_BIDS); + events.emit(constants.EVENTS.ADD_AD_UNITS, MOCK.ADD_AD_UNITS); + events.emit(constants.EVENTS.AD_RENDER_FAILED, MOCK.AD_RENDER_FAILED); + + sinon.assert.callCount(invisiblyAdapter.track, 13); + }); + }); +});