diff --git a/modules/adxcgAnalyticsAdapter.js b/modules/adxcgAnalyticsAdapter.js new file mode 100644 index 00000000000..5d2040c8e08 --- /dev/null +++ b/modules/adxcgAnalyticsAdapter.js @@ -0,0 +1,94 @@ +import {ajax} from 'src/ajax'; +import adapter from 'src/AnalyticsAdapter'; +import adaptermanager from 'src/adaptermanager'; +import * as url from 'src/url'; +import * as utils from 'src/utils'; + +const emptyUrl = ''; +const analyticsType = 'endpoint'; +const adxcgAnalyticsVersion = 'v1.04'; + +let initOptions; +let auctionTimestamp; +let events = { + bidRequests: [], + bidResponses: [] +}; + +var adxcgAnalyticsAdapter = Object.assign(adapter( + { + emptyUrl, + analyticsType + }), { + track({eventType, args}) { + if (typeof args !== 'undefined') { + if (eventType === 'bidTimeout') { + events.bidTimeout = args; + } else if (eventType === 'auctionInit') { + events.auctionInit = args; + auctionTimestamp = args.timestamp; + } else if (eventType === 'bidRequested') { + events.bidRequests.push(args); + } else if (eventType === 'bidResponse') { + events.bidResponses.push(mapBidResponse(args)); + } else if (eventType === 'bidWon') { + send({ + bidWon: mapBidResponse(args) + }); + } + } + + if (eventType === 'auctionEnd') { + send(events); + } + } +}); + +function mapBidResponse(bidResponse) { + return { + adUnitCode: bidResponse.adUnitCode, + statusMessage: bidResponse.statusMessage, + bidderCode: bidResponse.bidderCode, + adId: bidResponse.adId, + mediaType: bidResponse.mediaType, + creative_id: bidResponse.creative_id, + width: bidResponse.width, + height: bidResponse.height, + cpm: bidResponse.cpm, + timeToRespond: bidResponse.timeToRespond + }; +} + +function send(data) { + data.initOptions = initOptions; + data.auctionTimestamp = auctionTimestamp; + + let location = utils.getTopWindowLocation(); + let secure = location.protocol == 'https:'; + + let adxcgAnalyticsRequestUrl = url.format({ + protocol: secure ? 'https' : 'http', + hostname: secure ? 'hbarxs.adxcg.net' : 'hbarx.adxcg.net', + pathname: '/pbrx', + search: { + auctionTimestamp: auctionTimestamp, + adxcgAnalyticsVersion: adxcgAnalyticsVersion, + prebidVersion: $$PREBID_GLOBAL$$.version + } + }); + + ajax(adxcgAnalyticsRequestUrl, undefined, JSON.stringify(data), {method: 'POST'}); +} + +adxcgAnalyticsAdapter.originEnableAnalytics = adxcgAnalyticsAdapter.enableAnalytics; +adxcgAnalyticsAdapter.enableAnalytics = function (config) { + initOptions = config.options; + adxcgAnalyticsAdapter.originEnableAnalytics(config); +}; + +adaptermanager.registerAnalyticsAdapter({ + adapter: adxcgAnalyticsAdapter, + code: 'adxcg' +}); + +export default adxcgAnalyticsAdapter; diff --git a/test/spec/modules/adxcgAnalyticsAdapter_spec.js b/test/spec/modules/adxcgAnalyticsAdapter_spec.js new file mode 100644 index 00000000000..790a39789b2 --- /dev/null +++ b/test/spec/modules/adxcgAnalyticsAdapter_spec.js @@ -0,0 +1,81 @@ +import adxcgAnalyticsAdapter from 'modules/adxcgAnalyticsAdapter'; +import { expect } from 'chai'; +let adaptermanager = require('src/adaptermanager'); +let events = require('src/events'); +let constants = require('src/constants.json'); + +describe('adxcg analytics adapter', () => { + let xhr; + let requests; + + beforeEach(() => { + xhr = sinon.useFakeXMLHttpRequest(); + requests = []; + xhr.onCreate = request => requests.push(request); + }); + + afterEach(() => { + xhr.restore(); + }); + + describe('track', () => { + it('builds and sends auction data', () => { + let auctionTimestamp = 42; + let initOptions = { + publisherId: '42' + }; + let bidRequest = { + requestId: 'requestIdData' + }; + let bidResponse = { + adId: 'adIdData', + ad: 'adContent' + }; + + adaptermanager.registerAnalyticsAdapter({ + code: 'adxcg', + adapter: adxcgAnalyticsAdapter + }); + + adaptermanager.enableAnalytics({ + provider: 'adxcg', + options: initOptions + }); + + events.emit(constants.EVENTS.AUCTION_INIT, { + timestamp: auctionTimestamp + }); + events.emit(constants.EVENTS.BID_REQUESTED, bidRequest); + events.emit(constants.EVENTS.BID_RESPONSE, bidResponse); + events.emit(constants.EVENTS.AUCTION_END, {}); + + expect(requests.length).to.equal(1); + + let auctionEventData = JSON.parse(requests[0].requestBody); + + expect(auctionEventData.bidRequests.length).to.equal(1); + expect(auctionEventData.bidRequests[0]).to.deep.equal(bidRequest); + + expect(auctionEventData.bidResponses.length).to.equal(1); + expect(auctionEventData.bidResponses[0].adId).to.equal(bidResponse.adId); + expect(auctionEventData.bidResponses[0]).to.not.have.property('ad'); + + expect(auctionEventData.initOptions).to.deep.equal(initOptions); + expect(auctionEventData.auctionTimestamp).to.equal(auctionTimestamp); + + events.emit(constants.EVENTS.BID_WON, { + adId: 'adIdData', + ad: 'adContent' + }); + + expect(requests.length).to.equal(2); + + let winEventData = JSON.parse(requests[1].requestBody); + + expect(winEventData.bidWon.adId).to.equal(bidResponse.adId); + expect(winEventData.bidWon).to.not.have.property('ad'); + expect(winEventData.initOptions).to.deep.equal(initOptions); + expect(winEventData.auctionTimestamp).to.equal(auctionTimestamp); + }); + }); +});