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

Kubient video #7056

Closed
wants to merge 12 commits into from
Closed
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
70 changes: 51 additions & 19 deletions modules/kubientBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,75 @@
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER} from '../src/mediaTypes.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import * as utils from '../src/utils.js';

const BIDDER_CODE = 'kubient';
const END_POINT = 'https://kssp.kbntx.ch/pbjs';
const VERSION = '1.0';
const END_POINT = 'https://kssp.kbntx.ch/kubprebidjs';
const VERSION = '1.1';
const VENDOR_ID = 794;
export const spec = {
code: BIDDER_CODE,
gvlid: VENDOR_ID,
supportedMediaTypes: [BANNER],
supportedMediaTypes: [ BANNER, VIDEO ],
isBidRequestValid: function (bid) {
return !!(bid && bid.params);
},
buildRequests: function (validBidRequests, bidderRequest) {
if (!validBidRequests || !bidderRequest) {
return;
}
const result = validBidRequests.map(function (bid) {
return validBidRequests.map(function (bid) {
let floor = 0.0;
if (typeof bid.getFloor === 'function') {
const mediaType = (Object.keys(bid.mediaTypes).length == 1) ? Object.keys(bid.mediaTypes)[0] : '*';
const sizes = bid.sizes || '*';
const floorInfo = bid.getFloor({currency: 'USD', mediaType: mediaType, size: sizes});
if (typeof floorInfo === 'object' && floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) {
floor = parseFloat(floorInfo.floor);
}
}

let adSlot = {
bidId: bid.bidId,
zoneId: bid.params.zoneid || '',
floor: floor || 0.0
};

if (bid.mediaTypes.banner) {
adSlot.banner = bid.mediaTypes.banner;
}

if (bid.mediaTypes.video) {
adSlot.video = bid.mediaTypes.video;
}

if (bid.schain) {
adSlot.schain = bid.schain;
}

let data = {
v: VERSION,
requestId: bid.bidderRequestId,
adSlots: [{
bidId: bid.bidId,
zoneId: bid.params.zoneid || '',
floor: bid.params.floor || 0.0,
sizes: bid.sizes || [],
schain: bid.schain || {},
mediaTypes: bid.mediaTypes
}],
referer: (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) ? bidderRequest.refererInfo.referer : null,
adSlots: [adSlot],
tmax: bidderRequest.timeout,
gdpr: (bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) ? 1 : 0,
consent: (bidderRequest.gdprConsent && bidderRequest.gdprConsent.consentString) ? bidderRequest.gdprConsent.consentString : null,
consentGiven: kubientGetConsentGiven(bidderRequest.gdprConsent),
uspConsent: bidderRequest.uspConsent
};

if (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) {
data.referer = bidderRequest.refererInfo.referer
}

if (bidderRequest.gdprConsent && bidderRequest.gdprConsent.consentString) {
data.consent = bidderRequest.gdprConsent.consentString
}

return {
method: 'POST',
url: END_POINT,
data: JSON.stringify(data)
};
});
return result;
},
interpretResponse: function interpretResponse(serverResponse, request) {
if (!serverResponse || !serverResponse.body || !serverResponse.body.seatbid) {
Expand All @@ -52,7 +79,7 @@ export const spec = {
serverResponse.body.seatbid.forEach(seatbid => {
let bids = seatbid.bid || [];
bids.forEach(bid => {
bidResponses.push({
const bidResponse = {
requestId: bid.bidId,
cpm: bid.price,
currency: bid.cur,
Expand All @@ -61,8 +88,13 @@ export const spec = {
creativeId: bid.creativeId,
netRevenue: bid.netRevenue,
ttl: bid.ttl,
ad: bid.adm
});
ad: bid.adm,
meta: {}
};
if (bid.meta && bid.meta.adomain && utils.isArray(bid.meta.adomain)) {
bidResponse.meta.advertiserDomains = bid.meta.adomain;
}
bidResponses.push(bidResponse);
});
});
return bidResponses;
Expand Down
123 changes: 105 additions & 18 deletions test/spec/modules/kubientBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ import { expect, assert } from 'chai';
import { spec } from 'modules/kubientBidAdapter.js';

describe('KubientAdapter', function () {
let bid = {
let bidBanner = {
bidId: '2dd581a2b6281d',
bidder: 'kubient',
bidderRequestId: '145e1d6a7837c9',
params: {
zoneid: '5678',
floor: 0.05,
zoneid: '5678'
},
getFloor: function(params) {
return {
floor: 0.05,
currency: 'USD'
};
},
auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2',
mediaTypes: {
Expand All @@ -18,7 +23,43 @@ describe('KubientAdapter', function () {
},
transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62',
schain: {
ver: '1.0',
ver: '1.1',
complete: 1,
nodes: [
{
asi: 'example.com',
sid: '0',
hp: 1,
rid: 'bidrequestid',
domain: 'example.com'
}
]
}
};
let bidVideo = {
bidId: '1dd581a2b6281d',
bidder: 'kubient',
bidderRequestId: '245e1d6a7837c9',
params: {
zoneid: '5676'
},
getFloor: function(params) {
return {
floor: 1.0,
currency: 'USD'
};
},
auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d1',
mediaTypes: {
video: {
context: 'instream',
playerSize: [640, 480],
mimes: ['video/mp4']
}
},
transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e61',
schain: {
ver: '1.1',
complete: 1,
nodes: [
{
Expand Down Expand Up @@ -48,11 +89,51 @@ describe('KubientAdapter', function () {
consentString: consentString,
gdprApplies: true
},
uspConsent: uspConsentData,
bids: [bid]
uspConsent: uspConsentData
};
describe('buildRequests', function () {
let serverRequests = spec.buildRequests([bid], bidderRequest);
describe('buildRequestBanner', function () {
let serverRequests = spec.buildRequests([bidBanner], Object.assign({}, bidderRequest, {bids: [bidBanner]}));
it('Creates a ServerRequest object with method, URL and data', function () {
expect(serverRequests).to.be.an('array');
});
for (let i = 0; i < serverRequests.length; i++) {
let serverRequest = serverRequests[i];
it('Creates a ServerRequest object with method, URL and data', function () {
expect(serverRequest.method).to.be.a('string');
expect(serverRequest.url).to.be.a('string');
expect(serverRequest.data).to.be.a('string');
});
it('Returns POST method', function () {
expect(serverRequest.method).to.equal('POST');
});
it('Returns valid URL', function () {
expect(serverRequest.url).to.equal('https://kssp.kbntx.ch/kubprebidjs');
});
it('Returns valid data if array of bids is valid', function () {
let data = JSON.parse(serverRequest.data);
expect(data).to.be.an('object');
expect(data).to.have.all.keys('v', 'requestId', 'adSlots', 'gdpr', 'referer', 'tmax', 'consent', 'consentGiven', 'uspConsent');
expect(data.v).to.exist.and.to.be.a('string');
expect(data.requestId).to.exist.and.to.be.a('string');
expect(data.referer).to.be.a('string');
expect(data.tmax).to.exist.and.to.be.a('number');
expect(data.gdpr).to.exist.and.to.be.within(0, 1);
expect(data.consent).to.equal(consentString);
expect(data.uspConsent).to.exist.and.to.equal(uspConsentData);
for (let j = 0; j < data['adSlots'].length; j++) {
let adSlot = data['adSlots'][i];
expect(adSlot).to.have.all.keys('bidId', 'zoneId', 'floor', 'banner', 'schain');
expect(adSlot.bidId).to.be.a('string');
expect(adSlot.zoneId).to.be.a('string');
expect(adSlot.floor).to.be.a('number');
expect(adSlot.schain).to.be.an('object');
expect(adSlot.banner).to.be.an('object');
}
});
}
});
describe('buildRequestVideo', function () {
let serverRequests = spec.buildRequests([bidVideo], Object.assign({}, bidderRequest, {bids: [bidVideo]}));
it('Creates a ServerRequest object with method, URL and data', function () {
expect(serverRequests).to.be.an('array');
});
Expand All @@ -67,7 +148,7 @@ describe('KubientAdapter', function () {
expect(serverRequest.method).to.equal('POST');
});
it('Returns valid URL', function () {
expect(serverRequest.url).to.equal('https://kssp.kbntx.ch/pbjs');
expect(serverRequest.url).to.equal('https://kssp.kbntx.ch/kubprebidjs');
});
it('Returns valid data if array of bids is valid', function () {
let data = JSON.parse(serverRequest.data);
Expand All @@ -82,28 +163,31 @@ describe('KubientAdapter', function () {
expect(data.uspConsent).to.exist.and.to.equal(uspConsentData);
for (let j = 0; j < data['adSlots'].length; j++) {
let adSlot = data['adSlots'][i];
expect(adSlot).to.have.all.keys('bidId', 'zoneId', 'floor', 'sizes', 'schain', 'mediaTypes');
expect(adSlot).to.have.all.keys('bidId', 'zoneId', 'floor', 'video', 'schain');
expect(adSlot.bidId).to.be.a('string');
expect(adSlot.zoneId).to.be.a('string');
expect(adSlot.floor).to.be.a('number');
expect(adSlot.sizes).to.be.an('array');
expect(adSlot.schain).to.be.an('object');
expect(adSlot.mediaTypes).to.be.an('object');
expect(adSlot.video).to.be.an('object');
}
});
}
});

describe('isBidRequestValid', function () {
it('Should return true when required params are found', function () {
expect(spec.isBidRequestValid(bid)).to.be.true;
expect(spec.isBidRequestValid(bidBanner)).to.be.true;
expect(spec.isBidRequestValid(bidVideo)).to.be.true;
});
it('Should return false when required params are not found', function () {
expect(spec.isBidRequestValid(bid)).to.be.true;
expect(spec.isBidRequestValid(bidBanner)).to.be.true;
expect(spec.isBidRequestValid(bidVideo)).to.be.true;
});
it('Should return false when params are not found', function () {
delete bid.params;
expect(spec.isBidRequestValid(bid)).to.be.false;
delete bidBanner.params;
expect(spec.isBidRequestValid(bidBanner)).to.be.false;
delete bidVideo.params;
expect(spec.isBidRequestValid(bidVideo)).to.be.false;
});
});

Expand All @@ -124,7 +208,8 @@ describe('KubientAdapter', function () {
h: 250,
cur: 'USD',
netRevenue: false,
ttl: 360
ttl: 360,
meta: {adomain: ['google.com', 'yahoo.com']}
}
]
}
Expand All @@ -134,7 +219,7 @@ describe('KubientAdapter', function () {
let bannerResponses = spec.interpretResponse(serverResponse);
expect(bannerResponses).to.be.an('array').that.is.not.empty;
let dataItem = bannerResponses[0];
expect(dataItem).to.have.all.keys('requestId', 'cpm', 'ad', 'creativeId', 'width', 'height', 'currency', 'netRevenue', 'ttl');
expect(dataItem).to.have.all.keys('requestId', 'cpm', 'ad', 'creativeId', 'width', 'height', 'currency', 'netRevenue', 'ttl', 'meta');
expect(dataItem.requestId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].bidId);
expect(dataItem.cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price);
expect(dataItem.ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].adm);
Expand All @@ -144,6 +229,8 @@ describe('KubientAdapter', function () {
expect(dataItem.currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].cur);
expect(dataItem.netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(serverResponse.body.seatbid[0].bid[0].netRevenue);
expect(dataItem.ttl).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].ttl);
expect(dataItem.meta).to.exist.and.to.be.a('object');
expect(dataItem.meta.advertiserDomains).to.exist.and.to.be.a('array').and.to.equal(serverResponse.body.seatbid[0].bid[0].meta.adomain);
});

it('Should return no ad when not given a server response', function () {
Expand Down