Skip to content

Commit

Permalink
Add Pollux Adapter (#1431)
Browse files Browse the repository at this point in the history
* Added PolluxNetwork Bid Adapter

Added module, test spec and integration example for Pollux Network Bid Adapter

* Update Pollux domain

Update Pollux default domain on prebid adapter

* Export getParameterByName method

On Utils.js make getParameterByName method public

* Executed changes requested by @jaiminpanchal27 on 2017-08-01

Moved zone_728x90.html to integrationExamples/gpt/pollux_zone_728x90.html;
Added bidRequest as second parameter to bidfactory.createBid() on Pollux Bid Adapter;
Added more test cases to increase test coverage (at least 85%);

Review Ref:
 - #1431 (review)

* Fixed Eslint errors on commit f745fe1

* Executed changes requested on PR#1431 review #54993573

- Removed $$PREBID_GLOBAL$$ public vars in unit test;
- Moved stubs creation and its restoration to beforeEach and afterEach hooks in unit test;
- Exposed polluxHandler method on polluxBidAdapter.

* Remove redundant export

This line was added in #1409, removing this then I'll merge
  • Loading branch information
polluxnetwork authored and matthewlane committed Aug 15, 2017
1 parent 02b40a0 commit 302560f
Show file tree
Hide file tree
Showing 3 changed files with 373 additions and 0 deletions.
104 changes: 104 additions & 0 deletions integrationExamples/gpt/pollux_zone_728x90.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<!DOCTYPE html>
<html>
<head>
<!-- Prebid Config Section START -->
<!-- Make sure this is inserted before your GPT tag -->
<script>
var PREBID_TIMEOUT = 3000;

var adUnits = [{
code: 'div-gpt-ad-1460505661639-0',
sizes: [[728, 90]],
bids: [
{
bidder: 'pollux',
params: {
zone: '276'
}
},
{
bidder: 'pollux',
params: {
zone: '1806'
}
}
]
}];

var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];
</script>
<!-- Prebid Config Section END -->

<!-- Prebid Boilerplate Section START. No Need to Edit. -->
<script type="text/javascript" src="//cdn-assetsx.plxnt.com/assets/public/js/prebid.js" async></script>
<script>
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
googletag.cmd.push(function() {
googletag.pubads().disableInitialLoad();
});

pbjs.que.push(function() {
pbjs.addAdUnits(adUnits);
pbjs.requestBids({
bidsBackHandler: sendAdserverRequest
});
});

function sendAdserverRequest() {
if (pbjs.adserverRequestSent) return;
pbjs.adserverRequestSent = true;
googletag.cmd.push(function() {
pbjs.que.push(function() {
pbjs.setTargetingForGPTAsync();
googletag.pubads().refresh();
});
});
};

setTimeout(function() {
sendAdserverRequest();
}, PREBID_TIMEOUT);

</script>
<!-- Prebid Boilerplate Section END -->

<script>
(function () {
var gads = document.createElement('script');
gads.async = true;
gads.type = 'text/javascript';
var useSSL = 'https:' == document.location.protocol;
gads.src = (useSSL ? 'https:' : 'http:') +
'//www.googletagservices.com/tag/js/gpt.js';
var node = document.getElementsByTagName('script')[0];
node.parentNode.insertBefore(gads, node);
})();
</script>

<script>
googletag.cmd.push(function () {
googletag.defineSlot('/19968336/header-bid-tag1', [[728, 90]], 'div-gpt-ad-1460505661639-0').addService(googletag.pubads());
googletag.pubads().enableSingleRequest();
googletag.enableServices();
});
</script>

<style>
body {
margin: 0;
padding: 0;
}
</style>
<title>test</title>
</head>

<body>
<div id='div-gpt-ad-1460505661639-0'>
<script type='text/javascript'>
googletag.cmd.push(function() { googletag.display('div-gpt-ad-1460505661639-0'); });
</script>
</div>
</body>
</html>
97 changes: 97 additions & 0 deletions modules/polluxBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import bidfactory from 'src/bidfactory';
import bidmanager from 'src/bidmanager';
import * as utils from 'src/utils';
import adloader from 'src/adloader';
import adaptermanager from 'src/adaptermanager';
import { STATUS } from 'src/constants';

// Prebid adapter for Pollux header bidding client
function PolluxBidAdapter() {
function _callBids(params) {
var bidderUrl = (window.location.protocol) + '//adn.plxnt.com/prebid';
var bids = params.bids || [];
for (var i = 0; i < bids.length; i++) {
var request_obj = {};
var bid = bids[i];
// check params
if (bid.params.zone) {
var domain = utils.getParameterByName('domain');
var tracker2 = utils.getParameterByName('tracker2');
if (domain) {
request_obj.domain = domain;
} else {
request_obj.domain = window.location.host;
}
if (tracker2) {
request_obj.tracker2 = tracker2;
}
request_obj.zone = bid.params.zone;
} else {
utils.logError('required param "zone" is missing', 'polluxHandler');
continue;
}
var parsedSizes = utils.parseSizesInput(bid.sizes);
var parsedSizesLength = parsedSizes.length;
if (parsedSizesLength > 0) {
// first value should be "size"
request_obj.size = parsedSizes[0];
if (parsedSizesLength > 1) {
// any subsequent values should be "promo_sizes"
var promo_sizes = [];
for (var j = 1; j < parsedSizesLength; j++) {
promo_sizes.push(parsedSizes[j]);
}
request_obj.promo_sizes = promo_sizes.join(',');
}
}
// detect urls
request_obj.callback_id = bid.bidId;
// set a different url bidder
if (bid.bidderUrl) {
bidderUrl = bid.bidderUrl;
}
var prebidUrl = bidderUrl + '?' + utils.parseQueryStringParameters(request_obj);
utils.logMessage('Pollux request built: ' + prebidUrl);
adloader.loadScript(prebidUrl, null, true);
}
}

// expose the callback to global object
function _polluxHandler (response) {
// pollux handler
var bidObject = {};
var callback_id = response.callback_id;
var placementCode = '';
var bidObj = utils.getBidRequest(callback_id);
if (bidObj) {
placementCode = bidObj.placementCode;
}
if (bidObj && response.cpm > 0 && !!response.ad) {
bidObject = bidfactory.createBid(STATUS.GOOD, bidObj);
bidObject.bidderCode = bidObj.bidder;
bidObject.mediaType = response.mediaType;
bidObject.cpm = parseFloat(response.cpm);
if (response.ad_type === 'url') {
bidObject.adUrl = response.ad;
} else {
bidObject.ad = response.ad;
}
bidObject.width = response.width;
bidObject.height = response.height;
} else {
bidObject = bidfactory.createBid(STATUS.NO_BID, bidObj);
bidObject.bidderCode = 'pollux';
utils.logMessage('No prebid response from polluxHandler for placement code ' + placementCode);
}
bidmanager.addBidResponse(placementCode, bidObject);
};
$$PREBID_GLOBAL$$.polluxHandler = _polluxHandler;
// Export the `callBids` function, so that Prebid.js can execute
// this function when the page asks to send out bid requests.
return {
callBids: _callBids,
polluxHandler: _polluxHandler
};
};
adaptermanager.registerBidAdapter(new PolluxBidAdapter(), 'pollux');
module.exports = PolluxBidAdapter;
172 changes: 172 additions & 0 deletions test/spec/modules/polluxBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
describe('Pollux Bid Adapter tests', function () {
var expect = require('chai').expect;
var urlParse = require('url-parse');
var querystringify = require('querystringify');
var Adapter = require('modules/polluxBidAdapter');
var adLoader = require('src/adloader');
var bidmanager = require('src/bidmanager');
var utils = require('src/utils');

var stubLoadScript;
var stubAddBidResponse;
var polluxAdapter;

// mock golbal _bidsRequested var
var bidsRequested = [];
utils.getBidRequest = function (id) {
return bidsRequested.map(bidSet => bidSet.bids.find(bid => bid.bidId === id)).find(bid => bid);
};

beforeEach(function () {
polluxAdapter = new Adapter();
bidsRequested = [];
stubLoadScript = sinon.stub(adLoader, 'loadScript');
stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse');
});

afterEach(function () {
stubLoadScript.restore();
stubAddBidResponse.restore();
});

describe('creation of bid url', function () {
it('bid request for single placement', function () {
var params = {
bidderCode: 'pollux',
bids: [{
placementCode: 'div-gpt-ad-1460505661639-0',
bidId: '21fe992ca48d55',
bidder: 'pollux',
sizes: [[300, 250]],
params: { zone: '1806' }
}]
};

polluxAdapter.callBids(params);

var bidUrl = stubLoadScript.getCall(0).args[0];

sinon.assert.calledOnce(stubLoadScript);

var parsedBidUrl = urlParse(bidUrl);
var parsedBidUrlQueryString = querystringify.parse(parsedBidUrl.query);

expect(parsedBidUrlQueryString).to.have.property('zone').and.to.equal('1806');
expect(parsedBidUrlQueryString).to.have.property('domain').and.to.have.length.above(1);
});
});

describe('handling bid response', function () {
it('should return complete bid response adUrl', function() {
var params = {
bidderCode: 'pollux',
bids: [{
placementCode: 'div-gpt-ad-1460505661639-0',
sizes: [[300, 250]],
bidId: '21fe992ca48d55',
bidder: 'pollux',
params: { zone: '1806' }
}]
};

var response = {
cpm: 0.5,
width: 300,
height: 250,
callback_id: '21fe992ca48d55',
ad: 'some.ad.url',
ad_type: 'url',
zone: 1806
};

polluxAdapter.callBids(params);
bidsRequested.push(params);
polluxAdapter.polluxHandler(response);

sinon.assert.calledOnce(stubAddBidResponse);

var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0];
var bidObject1 = stubAddBidResponse.getCall(0).args[1];

expect(bidPlacementCode1).to.equal('div-gpt-ad-1460505661639-0');
expect(bidObject1.bidderCode).to.equal('pollux');
expect(bidObject1.cpm).to.equal(0.5);
expect(bidObject1.width).to.equal(300);
expect(bidObject1.height).to.equal(250);
expect(bidObject1.adUrl).to.have.length.above(1);
});

it('should return complete bid response ad (html)', function() {
var params = {
bidderCode: 'pollux',
bids: [{
placementCode: 'div-gpt-ad-1460505661639-0',
sizes: [[300, 250]],
bidId: '21fe992ca48d55',
bidder: 'pollux',
params: { zone: '1806' }
}]
};

var response = {
cpm: 0.5,
width: 300,
height: 250,
callback_id: '21fe992ca48d55',
ad: '<script src="some.ad.url"></script>',
ad_type: 'html',
zone: 1806
};

polluxAdapter.callBids(params);
bidsRequested.push(params);
polluxAdapter.polluxHandler(response);

sinon.assert.calledOnce(stubAddBidResponse);

var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0];
var bidObject1 = stubAddBidResponse.getCall(0).args[1];

expect(bidPlacementCode1).to.equal('div-gpt-ad-1460505661639-0');
expect(bidObject1.bidderCode).to.equal('pollux');
expect(bidObject1.cpm).to.equal(0.5);
expect(bidObject1.width).to.equal(300);
expect(bidObject1.height).to.equal(250);
expect(bidObject1.ad).to.have.length.above(1);
});

it('should return no bid response', function() {
var params = {
bidderCode: 'pollux',
bids: [{
placementCode: 'div-gpt-ad-1460505661639-0',
sizes: [[300, 250]],
bidId: '21fe992ca48d55',
bidder: 'pollux',
params: { zone: '276' }
}]
};

var response = {
cpm: null,
width: null,
height: null,
callback_id: null,
ad: null,
zone: null
};

polluxAdapter.callBids(params);
bidsRequested.push(params);
polluxAdapter.polluxHandler(response);

sinon.assert.calledOnce(stubAddBidResponse);

var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0];
var bidObject1 = stubAddBidResponse.getCall(0).args[1];

expect(bidPlacementCode1).to.equal('');
expect(bidObject1.bidderCode).to.equal('pollux');
});
});
});

0 comments on commit 302560f

Please sign in to comment.