From 257b8c1121e508288ec0d588fe5a97c2aeae14cf Mon Sep 17 00:00:00 2001
From: Pollux <30473914+polluxnetwork@users.noreply.github.com>
Date: Tue, 15 Aug 2017 18:00:48 +0100
Subject: [PATCH] Add Pollux Adapter (#1431)
* 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:
- https://github.com/prebid/Prebid.js/pull/1431#pullrequestreview-53608436
* 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
---
.../gpt/pollux_zone_728x90.html | 104 +++++++++++
modules/polluxBidAdapter.js | 97 ++++++++++
test/spec/modules/polluxBidAdapter_spec.js | 172 ++++++++++++++++++
3 files changed, 373 insertions(+)
create mode 100644 integrationExamples/gpt/pollux_zone_728x90.html
create mode 100644 modules/polluxBidAdapter.js
create mode 100644 test/spec/modules/polluxBidAdapter_spec.js
diff --git a/integrationExamples/gpt/pollux_zone_728x90.html b/integrationExamples/gpt/pollux_zone_728x90.html
new file mode 100644
index 00000000000..ecede9b5db2
--- /dev/null
+++ b/integrationExamples/gpt/pollux_zone_728x90.html
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ test
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/polluxBidAdapter.js b/modules/polluxBidAdapter.js
new file mode 100644
index 00000000000..54c2122ec36
--- /dev/null
+++ b/modules/polluxBidAdapter.js
@@ -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;
diff --git a/test/spec/modules/polluxBidAdapter_spec.js b/test/spec/modules/polluxBidAdapter_spec.js
new file mode 100644
index 00000000000..1bcfe28124d
--- /dev/null
+++ b/test/spec/modules/polluxBidAdapter_spec.js
@@ -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: '',
+ 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');
+ });
+ });
+});