Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Video Support to Conversant Adapter #1153

Merged
merged 1 commit into from
Jun 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
});
});
});