From 23c9009108310d60cc0762be2c910a9a3fe3ba42 Mon Sep 17 00:00:00 2001 From: devcollectcent <45760266+devcollectcent@users.noreply.github.com> Date: Mon, 10 Dec 2018 14:51:03 +0200 Subject: [PATCH 1/7] Create collectcentBidAdapter.js New bider adapter for collectcent --- modules/collectcentBidAdapter.js | 94 ++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 modules/collectcentBidAdapter.js diff --git a/modules/collectcentBidAdapter.js b/modules/collectcentBidAdapter.js new file mode 100644 index 00000000000..caded725285 --- /dev/null +++ b/modules/collectcentBidAdapter.js @@ -0,0 +1,94 @@ +import { registerBidder } from 'src/adapters/bidderFactory'; +import { BANNER, NATIVE, VIDEO } from 'src/mediaTypes'; +import * as utils from 'src/utils'; + +const BIDDER_CODE = 'collectcent'; +const URL = '//publishers.motionspots.com/?c=o&m=multi'; +const URL_SYNC = '//publishers.motionspots.com/?c=o&m=cookie'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + + /** + * Determines whether or not the given bid request is valid. + * + * @param {object} bid The bid to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: (bid) => { + return Boolean(bid.bidId && + bid.params && + !isNaN(bid.params.placementId) && + spec.supportedMediaTypes.indexOf(bid.params.traffic) !== -1 + ); + }, + + /** + * Make a server request from the list of BidRequests. + * + * @param {BidRequest[]} validBidRequests A non-empty list of valid bid requests that should be sent to the Server. + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: (validBidRequests, bidderRequest) => { + let winTop; + try { + winTop = window.top; + winTop.location.toString(); + } catch (e) { + utils.logMessage(e); + winTop = window; + }; + + const location = winTop.location; + const placements = []; + const request = { + 'secure': (location.protocol === 'https:') ? 1 : 0, + 'deviceWidth': winTop.screen.width, + 'deviceHeight': winTop.screen.height, + 'host': location.host, + 'page': location.pathname, + 'placements': placements + }; + + for (let i = 0; i < validBidRequests.length; i++) { + const bid = validBidRequests[i]; + const params = bid.params; + placements.push({ + placementId: params.placementId, + bidId: bid.bidId, + sizes: bid.sizes, + traffic: params.traffic + }); + } + return { + method: 'POST', + url: URL, + data: request + }; + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {*} serverResponse A successful response from the server. + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: (serverResponse) => { + try { + serverResponse = serverResponse.body; + } catch (e) { + utils.logMessage(e); + }; + return serverResponse; + }, + + getUserSyncs: () => { + return [{ + type: 'image', + url: URL_SYNC + }]; + } +}; + +registerBidder(spec); From a97bc2e9653533a7a3f280ca4bbeecf797b00edb Mon Sep 17 00:00:00 2001 From: devcollectcent <45760266+devcollectcent@users.noreply.github.com> Date: Mon, 10 Dec 2018 14:56:56 +0200 Subject: [PATCH 2/7] Create collectcentBidAdapter.md Description and integration example --- modules/collectcentBidAdapter.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 modules/collectcentBidAdapter.md diff --git a/modules/collectcentBidAdapter.md b/modules/collectcentBidAdapter.md new file mode 100644 index 00000000000..938bdc420cd --- /dev/null +++ b/modules/collectcentBidAdapter.md @@ -0,0 +1,27 @@ +# Overview + +``` +Module Name: Collectcent SSP Bidder Adapter +Module Type: Bidder Adapter +Maintainer: dev.collectcent@gmail.com +``` + +# Description + +Module that connects to Collectcent SSP demand sources + +# Test Parameters +``` + var adUnits = [{ + code: 'placementCode', + sizes: [[300, 250]], + bids: [{ + bidder: 'collectcent', + params: { + placementId: 0, + traffic: 'banner' + } + }] + } + ]; +``` From a2fe05b20e3feb70416a36d3f667b70e20bd3b51 Mon Sep 17 00:00:00 2001 From: devcollectcent <45760266+devcollectcent@users.noreply.github.com> Date: Mon, 10 Dec 2018 15:13:42 +0200 Subject: [PATCH 3/7] Create collectcentBidAdapter_spec.js Collectcent bidder adapter tests added --- .../modules/collectcentBidAdapter_spec.js | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 test/spec/modules/collectcentBidAdapter_spec.js diff --git a/test/spec/modules/collectcentBidAdapter_spec.js b/test/spec/modules/collectcentBidAdapter_spec.js new file mode 100644 index 00000000000..dc36fe7ffaa --- /dev/null +++ b/test/spec/modules/collectcentBidAdapter_spec.js @@ -0,0 +1,118 @@ +import {expect} from 'chai'; +import {spec} from '../../../modules/collectcenBidAdapter'; + +describe('Collectcent', function () { + let bid = { + bidId: '2dd581a2b6281d', + bidder: 'collectcent', + bidderRequestId: '145e1d6a7837c9', + params: { + placementId: 123, + traffic: 'banner' + }, + placementCode: 'placement_0', + auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', + sizes: [[300, 250]], + transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62' + }; + + describe('isBidRequestValid', function () { + it('Should return true when placementId can be cast to a number', function () { + expect(spec.isBidRequestValid(bid)).to.be.true; + }); + it('Should return false when placementId is not a number', function () { + bid.params.placementId = 'aaa'; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + }); + + describe('buildRequests', function () { + let serverRequest = spec.buildRequests([bid]); + it('Creates a ServerRequest object with method, URL and data', function () { + expect(serverRequest).to.exist; + expect(serverRequest.method).to.exist; + expect(serverRequest.url).to.exist; + expect(serverRequest.data).to.exist; + }); + it('Returns POST method', function () { + expect(serverRequest.method).to.equal('POST'); + }); + it('Returns valid URL', function () { + expect(serverRequest.url).to.equal('//publishers.motionspots.com/?c=o&m=multi'); + }); + it('Returns valid data if array of bids is valid', function () { + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'secure', 'host', 'page', 'placements'); + expect(data.deviceWidth).to.be.a('number'); + expect(data.deviceHeight).to.be.a('number'); + expect(data.secure).to.be.within(0, 1); + expect(data.host).to.be.a('string'); + expect(data.page).to.be.a('string'); + let placements = data['placements']; + for (let i = 0; i < placements.length; i++) { + let placement = placements[i]; + expect(placement).to.have.all.keys('placementId', 'bidId', 'traffic', 'sizes'); + expect(placement.placementId).to.be.a('number'); + expect(placement.bidId).to.be.a('string'); + expect(placement.traffic).to.be.a('string'); + expect(placement.sizes).to.be.an('array'); + } + }); + it('Returns empty data if no valid requests are passed', function () { + serverRequest = spec.buildRequests([]); + let data = serverRequest.data; + expect(data.placements).to.be.an('array').that.is.empty; + }); + }); + describe('interpretResponse', function () { + let resObject = { + body: [ { + requestId: '123', + mediaType: 'banner', + cpm: 0.3, + width: 320, + height: 50, + ad: '

Hello ad

', + ttl: 1000, + creativeId: '123asd', + netRevenue: true, + currency: 'USD' + } ] + }; + let serverResponses = spec.interpretResponse(resObject); + it('Returns an array of valid server responses if response object is valid', function () { + expect(serverResponses).to.be.an('array').that.is.not.empty; + for (let i = 0; i < serverResponses.length; i++) { + let dataItem = serverResponses[i]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'mediaType'); + expect(dataItem.requestId).to.be.a('string'); + expect(dataItem.cpm).to.be.a('number'); + expect(dataItem.width).to.be.a('number'); + expect(dataItem.height).to.be.a('number'); + expect(dataItem.ad).to.be.a('string'); + expect(dataItem.ttl).to.be.a('number'); + expect(dataItem.creativeId).to.be.a('string'); + expect(dataItem.netRevenue).to.be.a('boolean'); + expect(dataItem.currency).to.be.a('string'); + expect(dataItem.mediaType).to.be.a('string'); + } + it('Returns an empty array if invalid response is passed', function () { + serverResponses = spec.interpretResponse('invalid_response'); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + }); + }); + + describe('getUserSyncs', function () { + let userSync = spec.getUserSyncs(); + it('Returns valid URL and `', function () { + expect(userSync).to.be.an('array').with.lengthOf(1); + expect(userSync[0].type).to.exist; + expect(userSync[0].url).to.exist; + expect(userSync[0].type).to.be.equal('image'); + expect(userSync[0].url).to.be.equal('//publishers.motionspots.com/?c=o&m=cookie'); + }); + }); +}); From fbda035fd123660312dbfacd084ece3986f532fb Mon Sep 17 00:00:00 2001 From: devcollectcent <45760266+devcollectcent@users.noreply.github.com> Date: Mon, 10 Dec 2018 15:21:13 +0200 Subject: [PATCH 4/7] Update collectcentBidAdapter_spec.js edit --- test/spec/modules/collectcentBidAdapter_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spec/modules/collectcentBidAdapter_spec.js b/test/spec/modules/collectcentBidAdapter_spec.js index dc36fe7ffaa..04c819992cd 100644 --- a/test/spec/modules/collectcentBidAdapter_spec.js +++ b/test/spec/modules/collectcentBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {spec} from '../../../modules/collectcenBidAdapter'; +import {spec} from '../../../modules/collectcentBidAdapter'; describe('Collectcent', function () { let bid = { From 04c3ceb5e0e69da3a4193ec92bbb05f982cd8af3 Mon Sep 17 00:00:00 2001 From: devcollectcent <45760266+devcollectcent@users.noreply.github.com> Date: Tue, 11 Dec 2018 10:43:59 +0200 Subject: [PATCH 5/7] Update collectcentBidAdapter.js Used bidderRequest.refererInfo.referer instead of window.location --- modules/collectcentBidAdapter.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/collectcentBidAdapter.js b/modules/collectcentBidAdapter.js index caded725285..1a285a4c16d 100644 --- a/modules/collectcentBidAdapter.js +++ b/modules/collectcentBidAdapter.js @@ -34,14 +34,13 @@ export const spec = { let winTop; try { winTop = window.top; - winTop.location.toString(); } catch (e) { utils.logMessage(e); winTop = window; }; - const location = winTop.location; const placements = []; + const location = new URL(bidderRequest.refererInfo.referer); const request = { 'secure': (location.protocol === 'https:') ? 1 : 0, 'deviceWidth': winTop.screen.width, From 76ddb86fa6b3c8de41bbf2b97c93de41123f6fe4 Mon Sep 17 00:00:00 2001 From: devcollectcent <45760266+devcollectcent@users.noreply.github.com> Date: Tue, 11 Dec 2018 15:12:46 +0200 Subject: [PATCH 6/7] Update collectcentBidAdapter.js --- modules/collectcentBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/collectcentBidAdapter.js b/modules/collectcentBidAdapter.js index 1a285a4c16d..ab7df12d190 100644 --- a/modules/collectcentBidAdapter.js +++ b/modules/collectcentBidAdapter.js @@ -40,7 +40,7 @@ export const spec = { }; const placements = []; - const location = new URL(bidderRequest.refererInfo.referer); + const location = bidderRequest ? new URL(bidderRequest.refererInfo.referer) : winTop.location; const request = { 'secure': (location.protocol === 'https:') ? 1 : 0, 'deviceWidth': winTop.screen.width, From 3e6688ee977208f814c6c780cc53ab9000e8d6b0 Mon Sep 17 00:00:00 2001 From: devcollectcent <45760266+devcollectcent@users.noreply.github.com> Date: Tue, 11 Dec 2018 17:53:29 +0200 Subject: [PATCH 7/7] Update collectcentBidAdapter.js Rename URL to URL_MULTI --- modules/collectcentBidAdapter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/collectcentBidAdapter.js b/modules/collectcentBidAdapter.js index ab7df12d190..df64da1f7f0 100644 --- a/modules/collectcentBidAdapter.js +++ b/modules/collectcentBidAdapter.js @@ -3,7 +3,7 @@ import { BANNER, NATIVE, VIDEO } from 'src/mediaTypes'; import * as utils from 'src/utils'; const BIDDER_CODE = 'collectcent'; -const URL = '//publishers.motionspots.com/?c=o&m=multi'; +const URL_MULTI = '//publishers.motionspots.com/?c=o&m=multi'; const URL_SYNC = '//publishers.motionspots.com/?c=o&m=cookie'; export const spec = { @@ -62,7 +62,7 @@ export const spec = { } return { method: 'POST', - url: URL, + url: URL_MULTI, data: request }; },