Skip to content

Commit

Permalink
Colossus SSP header bidding adapter 1.0.0 (prebid#2029)
Browse files Browse the repository at this point in the history
* create adapter colossusssp

* Trigger for current build rerun on Travis CI
  • Loading branch information
Bill Newman authored and jaiminpanchal27 committed Jan 23, 2018
1 parent 8907cae commit 6cfaa5c
Show file tree
Hide file tree
Showing 3 changed files with 277 additions and 0 deletions.
132 changes: 132 additions & 0 deletions modules/colossussspBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { registerBidder } from 'src/adapters/bidderFactory';
import * as utils from 'src/utils';

const BIDDER_CODE = 'colossusssp';
const URL = '//colossusssp.com/?c=o&m=multi';
const URL_SYNC = '//colossusssp.com/?c=o&m=cookie';

let sizeObj = {
'468x60': 1,
'728x90': 2,
'300x600': 10,
'300x250': 15,
'300x100': 19,
'320x50': 43,
'300x50': 44,
'300x300': 48,
'300x1050': 54,
'970x90': 55,
'970x250': 57,
'1000x90': 58,
'320x80': 59,
'640x480': 65,
'320x480': 67,
'320x320': 72,
'320x160': 73,
'480x300': 83,
'970x310': 94,
'970x210': 96,
'480x320': 101,
'768x1024': 102,
'1000x300': 113,
'320x100': 117,
'800x250': 118,
'200x600': 119
};

utils._each(sizeObj, (item, key) => sizeObj[item] = key);

export const spec = {
code: BIDDER_CODE,

/**
* 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 (!isNaN(bid.params.placement_id) &&
((bid.params.sizes !== undefined && bid.params.sizes.length > 0 && bid.params.sizes.some((sizeIndex) => sizeObj[sizeIndex] !== undefined)) ||
(bid.sizes !== undefined && bid.sizes.length > 0 && bid.sizes.map((size) => `${size[0]}x${size[1]}`).some((size) => sizeObj[size] !== undefined))));
},

/**
* 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) => {
let winTop = window;
try {
window.top.location.toString();
winTop = window.top;
} catch (e) {
utils.logMessage(e);
};
let location = utils.getTopWindowLocation();
let placements = [];
let request = {
'deviceWidth': winTop.screen.width,
'deviceHeight': winTop.screen.height,
'language': (navigator && navigator.language) ? navigator.language : '',
'secure': location.protocol === 'https:' ? 1 : 0,
'host': location.host,
'page': location.pathname,
'placements': placements
};
for (let i = 0; i < validBidRequests.length; i++) {
let bid = validBidRequests[i];
let placement = {};
placement['placementId'] = bid.params.placement_id;
placement['bidId'] = bid.bidId;
placement['sizes'] = bid.sizes;
placements.push(placement);
}
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) => {
let response = [];
try {
serverResponse = serverResponse.body;
for (let i = 0; i < serverResponse.length; i++) {
let resItem = serverResponse[i];
if (resItem.width && !isNaN(resItem.width) &&
resItem.height && !isNaN(resItem.height) &&
resItem.requestId && typeof resItem.requestId === 'string' &&
resItem.cpm && !isNaN(resItem.cpm) &&
resItem.ad && typeof resItem.ad === 'string' &&
resItem.ttl && !isNaN(resItem.ttl) &&
resItem.creativeId && typeof resItem.creativeId === 'string' &&
resItem.netRevenue && typeof resItem.netRevenue === 'boolean' &&
resItem.currency && typeof resItem.currency === 'string') {
response.push(resItem);
}
}
} catch (e) {
utils.logMessage(e);
};
return response;
},

getUserSyncs: () => {
return [{
type: 'image',
url: URL_SYNC
}];
}
};

registerBidder(spec);
26 changes: 26 additions & 0 deletions modules/colossussspBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Overview

```
Module Name: Colossus SSP Bidder Adapter
Module Type: Bidder Adapter
Maintainer: [email protected]
```

# Description

Module that connects to Colossus SSP demand sources

# Test Parameters
```
var adUnits = [{
code: 'placementid_0',
sizes: [[300, 250]],
bids: [{
bidder: 'colossusssp',
params: {
placement_id: 0
}
}]
}
];
```
119 changes: 119 additions & 0 deletions test/spec/modules/colossussspBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import {expect} from 'chai';
import {spec} from '../../../modules/colossussspBidAdapter';

describe('ColossussspAdapter', () => {
let bid = {
bidId: '2dd581a2b6281d',
bidder: 'colossusssp',
bidderRequestId: '145e1d6a7837c9',
params: {
placement_id: 0
},
placementCode: 'placementid_0',
auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2',
sizes: [[300, 250]],
transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62'
};

describe('isBidRequestValid', () => {
it('Should return true when placement_id can be cast to a number, and when at least one of the sizes passed is allowed', () => {
expect(spec.isBidRequestValid(bid)).to.be.true;
});
it('Should return false when placement_id is not a number', () => {
bid.params.placement_id = 'aaa';
expect(spec.isBidRequestValid(bid)).to.be.false;
});
it('Should return false when the sizes are not allowed', () => {
bid.sizes = [[1, 1]];
expect(spec.isBidRequestValid(bid)).to.be.false;
});
});

describe('buildRequests', () => {
let serverRequest = spec.buildRequests([bid]);
it('Creates a ServerRequest object with method, URL and data', () => {
expect(serverRequest).to.exist;
expect(serverRequest.method).to.exist;
expect(serverRequest.url).to.exist;
expect(serverRequest.data).to.exist;
});
it('Returns POST method', () => {
expect(serverRequest.method).to.equal('POST');
});
it('Returns valid URL', () => {
expect(serverRequest.url).to.equal('//colossusssp.com/?c=o&m=multi');
});
it('Returns valid data if array of bids is valid', () => {
let data = serverRequest.data;
expect(data).to.be.an('object');
expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements');
expect(data.deviceWidth).to.be.a('number');
expect(data.deviceHeight).to.be.a('number');
expect(data.language).to.be.a('string');
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', 'sizes');
expect(placement.placementId).to.be.a('number');
expect(placement.bidId).to.be.a('string');
expect(placement.sizes).to.be.an('array');
}
});
it('Returns empty data if no valid requests are passed', () => {
serverRequest = spec.buildRequests([]);
let data = serverRequest.data;
expect(data.placements).to.be.an('array').that.is.empty;
});
});
describe('interpretResponse', () => {
let resObject = {
body: [ {
requestId: '123',
cpm: 0.3,
width: 320,
height: 50,
ad: '<h1>Hello ad</h1>',
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', () => {
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');
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');
}
it('Returns an empty array if invalid response is passed', () => {
serverResponses = spec.interpretResponse('invalid_response');
expect(serverResponses).to.be.an('array').that.is.empty;
});
});
});

describe('getUserSyncs', () => {
let userSync = spec.getUserSyncs();
it('Returns valid URL and type', () => {
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('//colossusssp.com/?c=o&m=cookie');
});
});
});

0 comments on commit 6cfaa5c

Please sign in to comment.