Skip to content

Commit

Permalink
Adding Video Support for Conversant Adapter
Browse files Browse the repository at this point in the history
* Added support for video
* Added tag_id parameter
* Added position parameter
* Changed API endpoint
* Added support for multiple sizes per ad unit
  • Loading branch information
trex-conversant committed Jun 6, 2017
1 parent ece853a commit 66f21a0
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 46 deletions.
5 changes: 5 additions & 0 deletions adapters.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@
},
{
"admixer": {
"supportedMediaTypes": ["video"]
}
},
{
"conversant": {
"supportedMediaTypes": ["video"]
}
}
Expand Down
125 changes: 90 additions & 35 deletions src/adapters/conversant.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
'use strict';
var VERSION = '2.0.1',
CONSTANTS = require('../constants.json'),
utils = require('../utils.js'),
bidfactory = require('../bidfactory.js'),
bidmanager = require('../bidmanager.js'),
adloader = require('../adloader'),
ajax = require('../ajax').ajax;
var VERSION = '2.1.0';
var CONSTANTS = require('../constants.json');
var utils = require('../utils.js');
var bidfactory = require('../bidfactory.js');
var bidmanager = require('../bidmanager.js');
var adloader = require('../adloader');
var ajax = require('../ajax').ajax;

/**
* Adapter for requesting bids from Conversant
*/
var ConversantAdapter = function () {
var w = window,
n = navigator;
var w = window;
var n = navigator;

// production endpoint
var conversantUrl = '//media.msg.dotomi.com/s2s/header?callback=$$PREBID_GLOBAL$$.conversantResponse';
var conversantUrl = '//media.msg.dotomi.com/s2s/header/24?callback=$$PREBID_GLOBAL$$.conversantResponse';

// SSAPI returns JSONP with window.pbjs.conversantResponse as the cb
var appendScript = function (code) {
Expand Down Expand Up @@ -55,21 +55,26 @@ var ConversantAdapter = function () {

var requestBids = function (bidReqs) {
// build bid request object
var page = location.pathname + location.search + location.hash,
siteId = '',
conversantImps = [],
conversantBidReqs,
secure = 0;
var page = location.pathname + location.search + location.hash;
var siteId = '';
var conversantImps = [];
var conversantBidReqs;
var secure = 0;

// build impression array for conversant
utils._each(bidReqs, function (bid) {
var bidfloor = utils.getBidIdParameter('bidfloor', bid.params),
adW = 0,
adH = 0,
imp;
var bidfloor = utils.getBidIdParameter('bidfloor', bid.params);
var adW = 0;
var adH = 0;
var format;
var tagId;
var pos;
var imp;

secure = utils.getBidIdParameter('secure', bid.params) ? 1 : secure;
siteId = utils.getBidIdParameter('site_id', bid.params) + '';
tagId = utils.getBidIdParameter('tag_id', bid.params);
pos = utils.getBidIdParameter('position', bid.params);

// Allow sizes to be overridden per placement
var bidSizes = Array.isArray(bid.params.sizes) ? bid.params.sizes : bid.sizes;
Expand All @@ -78,22 +83,69 @@ var ConversantAdapter = function () {
adW = bidSizes[0];
adH = bidSizes[1];
} else {
adW = bidSizes[0][0];
adH = bidSizes[0][1];
format = [];
utils._each(bidSizes, function (bidSize) {
format.push({
w: bidSize[0],
h: bidSize[1]
});
});
}

imp = {
id: bid.bidId,
banner: {
w: adW,
h: adH
},
secure: secure,
bidfloor: bidfloor || 0,
displaymanager: 'Prebid.js',
displaymanagerver: VERSION
};

if (tagId !== '') {
imp.tagid = tagId;
}

if (bid.mediaType === 'video') {
var mimes = [];
var maxduration = 0;
var protocols = [];
var api = [];

var video = Array.isArray(format) ? {format: format} : {w: adW, h: adH};

mimes = utils.getBidIdParameter('mimes', bid.params);
if (mimes !== '') {
video.mimes = mimes;
}

maxduration = utils.getBidIdParameter('maxduration', bid.params);
if (maxduration !== '') {
video.maxduration = maxduration;
}

protocols = utils.getBidIdParameter('protocols', bid.params);
if (protocols !== '') {
video.protocols = protocols;
}

api = utils.getBidIdParameter('api', bid.params);
if (api !== '') {
video.api = api;
}

if (pos !== '') {
video.pos = pos;
}

imp.video = video;
} else {
var banner = Array.isArray(format) ? {format: format} : {w: adW, h: adH};

if (pos !== '') {
banner.pos = pos;
}
imp.banner = banner;
}

conversantImps.push(imp);
});

Expand Down Expand Up @@ -135,13 +187,13 @@ var ConversantAdapter = function () {
var parseSeatbid = function (bidResponse) {
var placementsWithBidsBack = [];
utils._each(bidResponse.bid, function (conversantBid) {
var responseCPM,
placementCode = '',
id = conversantBid.impid,
bid = {},
responseAd,
responseNurl,
sizeArrayLength;
var responseCPM;
var placementCode = '';
var id = conversantBid.impid;
var bid = {};
var responseAd;
var responseNurl;
var sizeArrayLength;

// Bid request we sent Conversant
var bidRequested = $$PREBID_GLOBAL$$._bidsRequested.find(bidSet => bidSet.bidderCode === 'conversant').bids.find(bid => bid.bidId === id);
Expand All @@ -162,11 +214,14 @@ var ConversantAdapter = function () {
bid = bidfactory.createBid(1, bidRequested);
bid.creative_id = conversantBid.id || '';
bid.bidderCode = 'conversant';

bid.cpm = responseCPM;

// Track impression image onto returned html
bid.ad = responseAd + '<img src=\"' + responseNurl + '\" />';
if (bidRequested.mediaType === 'video') {
bid.vastUrl = responseAd;
} else {
// Track impression image onto returned html
bid.ad = responseAd + '<img src="' + responseNurl + '" />';
}

sizeArrayLength = bidRequested.sizes.length;
if (sizeArrayLength === 2 && typeof bidRequested.sizes[0] === 'number' && typeof bidRequested.sizes[1] === 'number') {
Expand Down
142 changes: 131 additions & 11 deletions test/spec/adapters/conversant_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ describe('Conversant adapter tests', function () {
sizes: [[300, 600]],
params: {
site_id: '87293',
position: 1,
tag_id: 'tagid-1',
secure: false
}
},
{
}, {
bidId: 'bidId2',
bidder: 'conversant',
placementCode: 'div2',
Expand All @@ -28,14 +29,27 @@ describe('Conversant adapter tests', function () {
site_id: '87293',
secure: false
}
},
{
}, {
bidId: 'bidId3',
bidder: 'conversant',
placementCode: 'div3',
sizes: [[300, 600], [160, 600]],
params: {
site_id: '87293',
position: 1,
tag_id: '',
secure: false
}
}, {
bidId: 'bidId4',
bidder: 'conversant',
placementCode: 'div4',
mediaType: 'video',
sizes: [[480, 480]],
params: {
site_id: '89192',
pos: 1,
tagid: 'tagid-4',
secure: false
}
}
Expand Down Expand Up @@ -101,7 +115,7 @@ describe('Conversant adapter tests', function () {
expect(thirdBid.bidderCode).to.equal('conversant');
expect(placementCode3).to.equal('div3');

expect(addBidResponseSpy.getCalls().length).to.equal(3);
expect(addBidResponseSpy.getCalls().length).to.equal(4);
});

it('Should submit bids with statuses of 2 to the bid manager for empty bid responses', function () {
Expand All @@ -126,7 +140,7 @@ describe('Conversant adapter tests', function () {
expect(thirdBid.getStatusCode()).to.equal(2);
expect(thirdBid.bidderCode).to.equal('conversant');

expect(addBidResponseSpy.getCalls().length).to.equal(3);
expect(addBidResponseSpy.getCalls().length).to.equal(4);
});

it('Should submit valid bids to the bid manager', function () {
Expand All @@ -150,8 +164,7 @@ describe('Conversant adapter tests', function () {
adm: 'adm2',
h: 300,
w: 600
},
{
}, {
id: 33333,
impid: 'bidId3',
price: 0.33,
Expand Down Expand Up @@ -190,8 +203,34 @@ describe('Conversant adapter tests', function () {
expect(thirdBid.ad).to.equal('adm3' + '<img src="" />');
expect(placementCode3).to.equal('div3');

expect(addBidResponseSpy.getCalls().length).to.equal(3);
expect(addBidResponseSpy.getCalls().length).to.equal(4);
});

it('Should submit video bid responses correctly.', function () {
var bidResponse = {
id: 123,
seatbid: [{
bid: [{
id: 1111111,
impid: 'bidId4',
price: 0.11,
nurl: 'imp_tracker',
adm: 'vasturl'
}]
}]
};

$$PREBID_GLOBAL$$.conversantResponse(bidResponse);

var videoBid = addBidResponseSpy.getCall(0).args[1];
var placementCode = addBidResponseSpy.getCall(0).args[0];

expect(videoBid.getStatusCode()).to.equal(1);
expect(videoBid.bidderCode).to.equal('conversant');
expect(videoBid.cpm).to.equal(0.11);
expect(videoBid.vastUrl).to.equal('vasturl');
expect(placementCode).to.equal('div4');
})
});

describe('Should submit the correct headers in the xhr', function () {
Expand All @@ -218,8 +257,7 @@ describe('Conversant adapter tests', function () {
adm: 'adm2',
h: 300,
w: 600
},
{
}, {
id: 3333,
impid: 'bidId3',
price: 0.33,
Expand Down Expand Up @@ -253,4 +291,86 @@ describe('Conversant adapter tests', function () {
expect(request.requestBody).to.not.be.empty;
});
});
describe('Should create valid bid requests.', function () {
var server,
adapter;

var bidResponse = {
id: 123,
seatbid: [{
bid: [{
id: 1111,
impid: 'bidId1',
price: 0.11,
nurl: '',
adm: 'adm',
h: 250,
w: 300,
ext: {}
}, {
id: 2222,
impid: 'bidId2',
price: 0.22,
nurl: '',
adm: 'adm2',
h: 300,
w: 600
}, {
id: 3333,
impid: 'bidId3',
price: 0.33,
nurl: '',
adm: 'adm3',
h: 160,
w: 600
}]
}]
};

beforeEach(function () {
server = sinon.fakeServer.create();
adapter = new Adapter();
});

afterEach(function () {
server.restore();
});

beforeEach(function () {
var resp = [200, {'Content-type': 'text/javascript'}, '$$PREBID_GLOBAL$$.conversantResponse(\'' + JSON.stringify(bidResponse) + '\')'];
server.respondWith('POST', new RegExp('media.msg.dotomi.com/s2s/header'), resp);
});

it('Should create valid bid requests.', function () {
adapter.callBids(bidderRequest);
server.respond();
var request = JSON.parse(server.requests[0].requestBody);
expect(request.imp[0].banner.format[0].w).to.equal(300);
expect(request.imp[0].banner.format[0].h).to.equal(600);
expect(request.imp[0].tagid).to.equal('tagid-1');
expect(request.imp[0].banner.pos).to.equal(1);
expect(request.imp[0].secure).to.equal(0);
expect(request.site.id).to.equal('89192');
});

it('Should not pass empty or missing optional parameters on requests.', function () {
adapter.callBids(bidderRequest);
server.respond();

var request = JSON.parse(server.requests[0].requestBody);
expect(request.imp[1].tagid).to.equal(undefined);
expect(request.imp[2].tagid).to.equal(undefined);
expect(request.imp[1].pos).to.equal(undefined);
});

it('Should create the format objects correctly.', function () {
adapter.callBids(bidderRequest);
server.respond();

var request = JSON.parse(server.requests[0].requestBody);
expect(request.imp[2].banner.format.length).to.equal(2);
expect(request.imp[2].banner.format[0].w).to.equal(300);
expect(request.imp[2].banner.format[1].w).to.equal(160);
});
});
});

0 comments on commit 66f21a0

Please sign in to comment.