Skip to content

Commit

Permalink
PulsePoint Lite adapter (prebid#1016)
Browse files Browse the repository at this point in the history
* 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 prebid#509

* ET-1765: Adding support for additional params in PulsePoint adapter (#2)

* ET-1850: Fixing prebid#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
  • Loading branch information
anand-venkatraman authored and Mat Brown committed Mar 20, 2017
1 parent 3939535 commit a6f9a55
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 2 deletions.
1 change: 1 addition & 0 deletions adapters.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"piximedia",
"pubmatic",
"pulsepoint",
"pulsepointLite",
"rhythmone",
"rubicon",
"smartyads",
Expand Down
2 changes: 1 addition & 1 deletion src/adapters/pulsepoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
90 changes: 90 additions & 0 deletions src/adapters/pulsepointLite.js
Original file line number Diff line number Diff line change
@@ -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;
108 changes: 108 additions & 0 deletions test/spec/adapters/pulsepointLite_spec.js
Original file line number Diff line number Diff line change
@@ -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');
});

});
2 changes: 1 addition & 1 deletion test/spec/adapters/pulsepoint_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});

Expand Down

0 comments on commit a6f9a55

Please sign in to comment.