From 30c0763f512bd0dabfb458b1d0fc569f062bf7cf Mon Sep 17 00:00:00 2001 From: Anand Venkatraman Date: Wed, 15 Mar 2017 14:02:59 -0400 Subject: [PATCH] PulsePoint Lite adapter (#1016) * ET-1691: Pulsepoint Analytics adapter for Prebid. (#1) * ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter * ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter * ET-1691: cleanup * ET-1691: minor * ET-1691: revert package.json change * Adding bidRequest to bidFactory.createBid method as per https://github.com/prebid/Prebid.js/issues/509 * ET-1765: Adding support for additional params in PulsePoint adapter (#2) * ET-1850: Fixing https://github.com/prebid/Prebid.js/issues/866 * ET-1850: Adding a "lite" adapter. * Minor fix * Fix for response parsing * Minor changes * Minor changes * Updating JS lib endpoint * Updating JS lib endpoint * addressing review comments * fixing jshint error --- adapters.json | 1 + src/adapters/pulsepoint.js | 2 +- src/adapters/pulsepointLite.js | 90 ++++++++++++++++++ test/spec/adapters/pulsepointLite_spec.js | 108 ++++++++++++++++++++++ test/spec/adapters/pulsepoint_spec.js | 2 +- 5 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 src/adapters/pulsepointLite.js create mode 100644 test/spec/adapters/pulsepointLite_spec.js diff --git a/adapters.json b/adapters.json index 218582d4092b..ce2cd6bf3c24 100644 --- a/adapters.json +++ b/adapters.json @@ -27,6 +27,7 @@ "piximedia", "pubmatic", "pulsepoint", + "pulsepointLite", "rhythmone", "rubicon", "smartyads", diff --git a/src/adapters/pulsepoint.js b/src/adapters/pulsepoint.js index aaad60ee3110..e206c32550a1 100644 --- a/src/adapters/pulsepoint.js +++ b/src/adapters/pulsepoint.js @@ -5,7 +5,7 @@ var utils = require('../utils.js'); var PulsePointAdapter = function PulsePointAdapter() { - var getJsStaticUrl = window.location.protocol + '//tag.contextweb.com/getjs.static.js'; + var getJsStaticUrl = window.location.protocol + '//tag-st.contextweb.com/getjs.static.js'; var bidUrl = window.location.protocol + '//bid.contextweb.com/header/tag'; function _callBids(params) { diff --git a/src/adapters/pulsepointLite.js b/src/adapters/pulsepointLite.js new file mode 100644 index 000000000000..49900bc2c08a --- /dev/null +++ b/src/adapters/pulsepointLite.js @@ -0,0 +1,90 @@ +import {createBid} from 'src/bidfactory'; +import {addBidResponse} from 'src/bidmanager'; +import {logError,getTopWindowLocation} from 'src/utils'; +import {ajax} from 'src/ajax'; +import {STATUS} from 'src/constants'; + +function PulsePointLiteAdapter() { + + const bidUrl = window.location.protocol + '//bid.contextweb.com/header/tag?'; + const ajaxOptions = { + method: 'GET', + withCredentials: true, + contentType: 'text/plain' + }; + + function _callBids(bidderRequest) { + bidderRequest.bids.forEach(bidRequest => { + try { + var params = Object.assign({}, environment(), bidRequest.params); + var url = bidUrl + Object.keys(params).map(k => k + '=' + encodeURIComponent(params[k])).join('&'); + ajax(url, (bidResponse) => { + bidResponseAvailable(bidRequest, bidResponse); + }, null, ajaxOptions); + } catch(e) { + //register passback on any exceptions while attempting to fetch response. + logError('pulsepoint.requestBid', 'ERROR', e); + bidResponseAvailable(bidRequest); + } + }); + } + + function environment() { + return { + cn: 1, + ca: 'BID', + tl: 1, + 'if': 0, + cwu: getTopWindowLocation().href, + cwr: referrer(), + dw: document.documentElement.clientWidth, + cxy: document.documentElement.clientWidth + ',' + document.documentElement.clientHeight, + tz: new Date().getTimezoneOffset(), + ln: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage) + }; + } + + function referrer() { + try { + return window.top.document.referrer; + } catch (e) { + return document.referrer; + } + } + + function bidResponseAvailable(bidRequest, rawResponse) { + if (rawResponse) { + var bidResponse = parse(rawResponse); + if(bidResponse) { + var adSize = bidRequest.params.cf.toUpperCase().split('X'); + var bid = createBid(STATUS.GOOD, bidRequest); + bid.bidderCode = bidRequest.bidder; + bid.cpm = bidResponse.bidCpm; + bid.ad = bidResponse.html; + bid.width = adSize[0]; + bid.height = adSize[1]; + addBidResponse(bidRequest.placementCode, bid); + return; + } + } + var passback = createBid(STATUS.NO_BID, bidRequest); + passback.bidderCode = bidRequest.bidder; + addBidResponse(bidRequest.placementCode, passback); + } + + function parse(rawResponse) { + try { + return JSON.parse(rawResponse); + } catch (ex) { + logError('pulsepoint.safeParse', 'ERROR', ex); + return null; + } + } + + return { + callBids: _callBids + }; + +} + +module.exports = PulsePointLiteAdapter; diff --git a/test/spec/adapters/pulsepointLite_spec.js b/test/spec/adapters/pulsepointLite_spec.js new file mode 100644 index 000000000000..c52ef5568805 --- /dev/null +++ b/test/spec/adapters/pulsepointLite_spec.js @@ -0,0 +1,108 @@ +import {expect} from 'chai'; +import PulsePointAdapter from 'src/adapters/pulsepointLite'; +import bidManager from 'src/bidmanager'; +import * as ajax from "src/ajax"; +import {parse as parseURL} from 'src/url'; + +describe("PulsePoint Lite Adapter Tests", () => { + + let pulsepointAdapter = new PulsePointAdapter(); + let slotConfigs; + let ajaxStub; + + beforeEach(() => { + sinon.stub(bidManager, 'addBidResponse'); + ajaxStub = sinon.stub(ajax, 'ajax'); + + slotConfigs = { + bids: [ + { + placementCode: "/DfpAccount1/slot1", + bidder: "pulsepoint", + bidId: 'bid12345', + params: { + cp: "p10000", + ct: "t10000", + cf: "300x250" + } + },{ + placementCode: "/DfpAccount2/slot2", + bidder: "pulsepoint", + bidId: 'bid23456', + params: { + cp: "p20000", + ct: "t20000", + cf: "728x90" + } + } + ] + }; + }); + + afterEach(() => { + bidManager.addBidResponse.restore(); + ajaxStub.restore(); + }); + + it('Verify requests sent to PulsePoint', () => { + pulsepointAdapter.callBids(slotConfigs); + var call = parseURL(ajaxStub.firstCall.args[0]).search; + //slot 1 + expect(call.cp).to.equal('p10000'); + expect(call.ct).to.equal('t10000'); + expect(call.cf).to.equal('300x250'); + expect(call.ca).to.equal('BID'); + expect(call.cn).to.equal('1'); + //slot 2 + call = parseURL(ajaxStub.secondCall.args[0]).search; + expect(call.cp).to.equal('p20000'); + expect(call.ct).to.equal('t20000'); + expect(call.cf).to.equal('728x90'); + expect(call.ca).to.equal('BID'); + expect(call.cn).to.equal('1'); + }); + + it('Verify bid', () => { + pulsepointAdapter.callBids(slotConfigs); + //trigger a mock ajax callback with bid. + ajaxStub.firstCall.args[1](JSON.stringify({ + html: 'This is an Ad', + bidCpm: 1.25 + })); + let placement = bidManager.addBidResponse.firstCall.args[0]; + let bid = bidManager.addBidResponse.firstCall.args[1]; + expect(placement).to.equal('/DfpAccount1/slot1'); + expect(bid.bidderCode).to.equal('pulsepoint'); + expect(bid.cpm).to.equal(1.25); + expect(bid.ad).to.equal('This is an Ad'); + expect(bid.width).to.equal('300'); + expect(bid.height).to.equal('250'); + expect(bid.adId).to.equal('bid12345'); + }); + + it('Verify passback', () => { + pulsepointAdapter.callBids(slotConfigs); + //trigger a mock ajax callback with no bid. + ajaxStub.firstCall.args[1](null); + let placement = bidManager.addBidResponse.firstCall.args[0]; + let bid = bidManager.addBidResponse.firstCall.args[1]; + expect(placement).to.equal('/DfpAccount1/slot1'); + expect(bid.bidderCode).to.equal('pulsepoint'); + expect(bid).to.not.have.property('ad'); + expect(bid).to.not.have.property('cpm'); + expect(bid.adId).to.equal('bid12345'); + }); + + it('Verify passback when ajax call fails', () => { + ajaxStub.throws(); + pulsepointAdapter.callBids(slotConfigs); + let placement = bidManager.addBidResponse.firstCall.args[0]; + let bid = bidManager.addBidResponse.firstCall.args[1]; + expect(placement).to.equal('/DfpAccount1/slot1'); + expect(bid.bidderCode).to.equal('pulsepoint'); + expect(bid).to.not.have.property('ad'); + expect(bid).to.not.have.property('cpm'); + expect(bid.adId).to.equal('bid12345'); + }); + +}); diff --git a/test/spec/adapters/pulsepoint_spec.js b/test/spec/adapters/pulsepoint_spec.js index 0e9fb97fa4cd..b3c24d388903 100644 --- a/test/spec/adapters/pulsepoint_spec.js +++ b/test/spec/adapters/pulsepoint_spec.js @@ -127,7 +127,7 @@ describe("PulsePoint Adapter Tests", () => { pulsepointAdapter.callBids(slotConfigs); let libraryLoadCall = adLoader.loadScript.firstCall.args[0]; let callback = adLoader.loadScript.firstCall.args[1]; - expect(libraryLoadCall).to.equal('http://tag.contextweb.com/getjs.static.js'); + expect(libraryLoadCall).to.equal('http://tag-st.contextweb.com/getjs.static.js'); expect(callback).to.be.a('function'); });