Skip to content

Commit

Permalink
add Vertamedia video adpater (#959)
Browse files Browse the repository at this point in the history
* Vertamedia prebid.js adapter initial

* sync

* remove https

* add http

* remove let

* fix typo

* fix spaces

* add descriptionUrl; remove log
  • Loading branch information
Gorokhov authored and jaiminpanchal27 committed Feb 6, 2017
1 parent 8dc5a88 commit 1b4eaf0
Show file tree
Hide file tree
Showing 3 changed files with 253 additions and 0 deletions.
5 changes: 5 additions & 0 deletions adapters.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"adform",
"adkernel",
"admedia",
"vertamedia",
"aol",
"appnexus",
"appnexusAst",
Expand Down Expand Up @@ -66,6 +67,10 @@
"appnexusAst": {
"supportedMediaTypes": ["video"]
}
}, {
"vertamedia": {
"supportedMediaTypes": ["video"]
}
},
{
"rubicon": {
Expand Down
101 changes: 101 additions & 0 deletions src/adapters/vertamedia.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import Adapter from 'src/adapters/adapter';
import bidfactory from 'src/bidfactory';
import bidmanager from 'src/bidmanager';
import * as utils from 'src/utils';
import { ajax } from 'src/ajax';
import { STATUS } from 'src/constants';

const ENDPOINT = '//rtb.vertamedia.com/hb/';

function VertamediaAdapter() {
var baseAdapter = Adapter.createNew('vertamedia'),
bidRequest;

baseAdapter.callBids = function (bidRequests) {
if (!bidRequests || !bidRequests.bids || bidRequests.bids.length === 0) {
return;
}

var RTBDataParams = prepareAndSaveRTBRequestParams(bidRequests.bids[0]);

if (!RTBDataParams) {
return;
}

ajax(ENDPOINT, handleResponse, RTBDataParams, {
contentType: 'text/plain',
withCredentials: true,
method: 'GET'
});
};

function prepareAndSaveRTBRequestParams(bid) {
if (!bid || !bid.params || !bid.params.aid || !bid.placementCode) {
return;
}

bidRequest = bid;
bidRequest.width = parseInt(bid.sizes[0], 10) || undefined;
bidRequest.height = parseInt(bid.sizes[1], 10) || undefined;

return {
aid: bid.params.aid,
w: parseInt(bid.sizes[0], 10) || undefined,
h: parseInt(bid.sizes[1], 10) || undefined,
domain: document.location.hostname
};
}

/* Notify Prebid of bid responses so bids can get in the auction */
function handleResponse(response) {
var parsed;

try {
parsed = JSON.parse(response);
} catch (error) {
utils.logError(error);
}

if (!parsed || parsed.error || !parsed.bids || !parsed.bids.length) {
bidmanager.addBidResponse(bidRequest.placementCode, createBid(STATUS.NO_BID));

return;
}

bidmanager.addBidResponse(bidRequest.placementCode, createBid(STATUS.GOOD, parsed.bids[0]));
}

function createBid(status, tag) {
var bid = bidfactory.createBid(status, tag);

bid.code = baseAdapter.getBidderCode();
bid.bidderCode = bidRequest.bidder;

if (!tag || status !== STATUS.GOOD) {
return bid;
}

bid.mediaType = 'video';
bid.cpm = tag.cpm;
bid.creative_id = tag.cmpId;
bid.width = bidRequest.width;
bid.height = bidRequest.height;
bid.descriptionUrl = tag.url;
bid.vastUrl = tag.url;

return bid;
}

return {
createNew: VertamediaAdapter.createNew,
callBids: baseAdapter.callBids,
setBidderCode: baseAdapter.setBidderCode
};

}

VertamediaAdapter.createNew = function () {
return new VertamediaAdapter();
};

module.exports = VertamediaAdapter;
147 changes: 147 additions & 0 deletions test/spec/adapters/vertamedia_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import { expect } from 'chai';
import Adapter from 'src/adapters/vertamedia';
import bidmanager from 'src/bidmanager';

const ENDPOINT = 'http://rtb.vertamedia.com/hb/?aid=22489&w=640&h=480&domain=localhost';

const REQUEST = {
"bidderCode": "vertamedia",
"requestId": "d3e07445-ab06-44c8-a9dd-5ef9af06d2a6",
"bidderRequestId": "7101db09af0db2",
"bids": [
{
"bidder": "vertamedia",
"params": {
aid: 22489,
placementId: '123456'
},
"placementCode": "/19968336/header-bid-tag1",
"sizes": [640, 480],
"bidId": "84ab500420319d",
"bidderRequestId": "7101db09af0db2",
"requestId": "d3e07445-ab06-44c8-a9dd-5ef9af06d2a6"
}
],
"start": 1469479810130
};
var RESPONSE = {
"source": {
"aid": 22489,
"pubId": 18016,
"sid": "0"
},
"bids": [
{
"cmpId": 9541,
"cpm": 4.5,
"url": "http://rtb.vertamedia.com/vast?adid=BFDB9CC0038AD918",
"cur": "USD"
}
]
};


describe('VertamediaAdater', () => {

let adapter;

beforeEach(() => adapter = Adapter.createNew());

describe('request function', () => {

let xhr;
let requests;

beforeEach(() => {
xhr = sinon.useFakeXMLHttpRequest();
requests = [];
xhr.onCreate = request => requests.push(request);
});

afterEach(() => xhr.restore());

it('exists and is a function', () => {
expect(adapter.callBids).to.exist.and.to.be.a('function');
});

it('requires paramters to make request', () => {
adapter.callBids({});
expect(requests).to.be.empty;
});

it('requires member && invCode', () => {
let backup = REQUEST.bids[0].params;
REQUEST.bids[0].params = {member: 1234};
adapter.callBids(REQUEST);
expect(requests).to.be.empty;
REQUEST.bids[0].params = backup;
});


it('sends bid request to ENDPOINT via POST', () => {
adapter.callBids(REQUEST);
expect(requests[0].url).to.equal(ENDPOINT);
expect(requests[0].method).to.equal('GET');
});

});

describe('response handler', () => {

let server;

beforeEach(() => {
server = sinon.fakeServer.create();
sinon.stub(bidmanager, 'addBidResponse');
});

afterEach(() => {
server.restore();
bidmanager.addBidResponse.restore();
});

it('registers bids', () => {
server.respondWith(JSON.stringify(RESPONSE));

adapter.callBids(REQUEST);
server.respond();
sinon.assert.calledOnce(bidmanager.addBidResponse);

const response = bidmanager.addBidResponse.firstCall.args[1];
expect(response).to.have.property('statusMessage', 'Bid available');
expect(response).to.have.property('cpm', 4.5);
});

it('handles nobid responses', () => {
server.respondWith(JSON.stringify({
aid: 356465468,
w: 640,
h: 480,
domain: 'localhost'
}));

adapter.callBids(REQUEST);
server.respond();
sinon.assert.calledOnce(bidmanager.addBidResponse);

const response = bidmanager.addBidResponse.firstCall.args[1];
expect(response).to.have.property(
'statusMessage',
'Bid returned empty or error response'
);
});

it('handles JSON.parse errors', () => {
server.respondWith('');

adapter.callBids(REQUEST);
server.respond();
sinon.assert.calledOnce(bidmanager.addBidResponse);

expect(bidmanager.addBidResponse.firstCall.args[1]).to.have.property(
'statusMessage',
'Bid returned empty or error response'
);
});
});
});

0 comments on commit 1b4eaf0

Please sign in to comment.