diff --git a/modules/kimberliteBidAdapter.js b/modules/kimberliteBidAdapter.js
index 72df921e18f..6ad8b9eda05 100644
--- a/modules/kimberliteBidAdapter.js
+++ b/modules/kimberliteBidAdapter.js
@@ -1,13 +1,14 @@
import { registerBidder } from '../src/adapters/bidderFactory.js';
-import { BANNER } from '../src/mediaTypes.js';
+import { BANNER, VIDEO } from '../src/mediaTypes.js';
import { ortbConverter } from '../libraries/ortbConverter/converter.js'
import { deepSetValue } from '../src/utils.js';
+import {ORTB_MTYPES} from '../libraries/ortbConverter/processors/mediaType.js';
-const VERSION = '1.0.0';
+const VERSION = '1.1.0';
const BIDDER_CODE = 'kimberlite';
const METHOD = 'POST';
-const ENDPOINT_URL = 'https://kimberlite.io/rtb/bid/pbjs';
+export const ENDPOINT_URL = 'https://kimberlite.io/rtb/bid/pbjs';
const VERSION_INFO = {
ver: '$prebid.version$',
@@ -16,7 +17,6 @@ const VERSION_INFO = {
const converter = ortbConverter({
context: {
- mediaType: BANNER,
netRevenue: true,
ttl: 300
},
@@ -35,18 +35,32 @@ const converter = ortbConverter({
const imp = buildImp(bidRequest, context);
imp.tagid = bidRequest.params.placementId;
return imp;
- }
+ },
+
+ bidResponse: function (buildBidResponse, bid, context) {
+ if (!bid.price) return;
+
+ const [type] = Object.keys(context.bidRequest.mediaTypes);
+ if (Object.values(ORTB_MTYPES).includes(type)) {
+ context.mediaType = type;
+ }
+
+ const bidResponse = buildBidResponse(bid, context);
+ return bidResponse;
+ },
});
export const spec = {
code: BIDDER_CODE,
- supportedMediaTypes: [BANNER],
+ supportedMediaTypes: [BANNER, VIDEO],
isBidRequestValid: (bidRequest = {}) => {
const { params, mediaTypes } = bidRequest;
let isValid = Boolean(params && params.placementId);
if (mediaTypes && mediaTypes[BANNER]) {
isValid = isValid && Boolean(mediaTypes[BANNER].sizes);
+ } else if (mediaTypes && mediaTypes[VIDEO]) {
+ isValid = isValid && Boolean(mediaTypes[VIDEO].mimes);
} else {
isValid = false;
}
@@ -58,7 +72,10 @@ export const spec = {
return {
method: METHOD,
url: ENDPOINT_URL,
- data: converter.toORTB({ bidderRequest, bidRequests })
+ data: converter.toORTB({
+ bidRequests,
+ bidderRequest
+ })
}
},
diff --git a/modules/kimberliteBidAdapter.md b/modules/kimberliteBidAdapter.md
index c165f1073aa..06749f2c8e0 100644
--- a/modules/kimberliteBidAdapter.md
+++ b/modules/kimberliteBidAdapter.md
@@ -20,7 +20,7 @@ var adUnits = [
code: 'test-div',
mediaTypes: {
banner: {
- sizes: [[320, 250], [640, 480]],
+ sizes: [[320, 250], [640, 480]], // Required.
}
},
bids: [
@@ -34,3 +34,32 @@ var adUnits = [
}
]
```
+
+## Video AdUnit
+
+```javascript
+var adUnits = [
+ {
+ code: 'test-div',
+ mediaTypes: {
+ video: {
+ // ORTB 2.5 options.
+ mimes: ['video/mp4'], // Required.
+ // Other options are optional.
+ placement: 1,
+ protocols: [3, 6],
+ linearity: 1,
+ startdelay: 0
+ }
+ },
+ bids: [
+ {
+ bidder: "kimberlite",
+ params: {
+ placementId: 'testVideo'
+ }
+ }
+ ]
+ }
+]
+```
diff --git a/test/spec/modules/kimberliteBidAdapter_spec.js b/test/spec/modules/kimberliteBidAdapter_spec.js
index 1480f1cc768..c0394a2090b 100644
--- a/test/spec/modules/kimberliteBidAdapter_spec.js
+++ b/test/spec/modules/kimberliteBidAdapter_spec.js
@@ -1,6 +1,6 @@
-import { spec } from 'modules/kimberliteBidAdapter.js';
+import { spec, ENDPOINT_URL } from 'modules/kimberliteBidAdapter.js';
import { assert } from 'chai';
-import { BANNER } from '../../../src/mediaTypes.js';
+import { BANNER, VIDEO } from '../../../src/mediaTypes.js';
const BIDDER_CODE = 'kimberlite';
@@ -8,74 +8,104 @@ describe('kimberliteBidAdapter', function () {
const sizes = [[640, 480]];
describe('isBidRequestValid', function () {
- let bidRequest;
+ let bidRequests;
beforeEach(function () {
- bidRequest = {
- mediaTypes: {
- [BANNER]: {
- sizes: [[320, 240]]
+ bidRequests = [
+ {
+ mediaTypes: {
+ [BANNER]: {
+ sizes: [[320, 240]]
+ }
+ },
+ params: {
+ placementId: 'test-placement'
}
},
- params: {
- placementId: 'test-placement'
+ {
+ mediaTypes: {
+ [VIDEO]: {
+ mimes: ['video/mp4']
+ }
+ },
+ params: {
+ placementId: 'test-placement'
+ }
}
- };
+ ];
});
- it('pass on valid bidRequest', function () {
- assert.isTrue(spec.isBidRequestValid(bidRequest));
+ it('pass on valid banner bidRequest', function () {
+ assert.isTrue(spec.isBidRequestValid(bidRequests[0]));
});
it('fails on missed placementId', function () {
- delete bidRequest.params.placementId;
- assert.isFalse(spec.isBidRequestValid(bidRequest));
+ delete bidRequests[0].params.placementId;
+ assert.isFalse(spec.isBidRequestValid(bidRequests[0]));
});
it('fails on empty banner', function () {
- delete bidRequest.mediaTypes.banner;
- assert.isFalse(spec.isBidRequestValid(bidRequest));
+ delete bidRequests[0].mediaTypes.banner;
+ assert.isFalse(spec.isBidRequestValid(bidRequests[0]));
});
it('fails on empty banner.sizes', function () {
- delete bidRequest.mediaTypes.banner.sizes;
- assert.isFalse(spec.isBidRequestValid(bidRequest));
+ delete bidRequests[0].mediaTypes.banner.sizes;
+ assert.isFalse(spec.isBidRequestValid(bidRequests[0]));
});
it('fails on empty request', function () {
assert.isFalse(spec.isBidRequestValid());
});
+
+ it('pass on valid video bidRequest', function () {
+ assert.isTrue(spec.isBidRequestValid(bidRequests[1]));
+ });
+
+ it('fails on missed video.mimes', function () {
+ delete bidRequests[1].mediaTypes.video.mimes;
+ assert.isFalse(spec.isBidRequestValid(bidRequests[1]));
+ });
});
describe('buildRequests', function () {
let bidRequests, bidderRequest;
beforeEach(function () {
- bidRequests = [{
- mediaTypes: {
- [BANNER]: {sizes: sizes}
+ bidRequests = [
+ {
+ mediaTypes: {
+ [BANNER]: {sizes: sizes}
+ },
+ params: {
+ placementId: 'test-placement'
+ }
},
- params: {
- placementId: 'test-placement'
+ {
+ mediaTypes: {
+ [VIDEO]: {
+ mimes: ['video/mp4'],
+ }
+ },
+ params: {
+ placementId: 'test-placement'
+ }
}
- }];
+ ];
bidderRequest = {
refererInfo: {
domain: 'example.com',
page: 'https://www.example.com/test.html',
- },
- bids: [{
- mediaTypes: {
- [BANNER]: {sizes: sizes}
- }
- }]
+ }
};
});
it('valid bid request', function () {
const bidRequest = spec.buildRequests(bidRequests, bidderRequest);
+
assert.equal(bidRequest.method, 'POST');
+ assert.equal(bidRequest.url, ENDPOINT_URL);
assert.ok(bidRequest.data);
const requestData = bidRequest.data;
@@ -87,10 +117,10 @@ describe('kimberliteBidAdapter', function () {
expect(requestData.ext).to.be.an('Object').and.have.all.keys('prebid');
expect(requestData.ext.prebid).to.be.an('Object').and.have.all.keys('ver', 'adapterVer');
- const impData = requestData.imp[0];
- expect(impData.banner).is.to.be.an('Object').and.have.all.keys(['format', 'topframe']);
+ const impBannerData = requestData.imp[0];
+ expect(impBannerData.banner).is.to.be.an('Object').and.have.all.keys(['format', 'topframe']);
- const bannerData = impData.banner;
+ const bannerData = impBannerData.banner;
expect(bannerData.format).to.be.an('array').and.is.not.empty;
const formatData = bannerData.format[0];
@@ -98,30 +128,44 @@ describe('kimberliteBidAdapter', function () {
assert.equal(formatData.w, sizes[0][0]);
assert.equal(formatData.h, sizes[0][1]);
+
+ if (FEATURES.VIDEO) {
+ const impVideoData = requestData.imp[1];
+ expect(impVideoData.video).is.to.be.an('Object').and.have.all.keys(['mimes']);
+
+ const videoData = impVideoData.video;
+ expect(videoData.mimes).to.be.an('array').and.is.not.empty;
+ expect(videoData.mimes[0]).to.be.a('string').that.equals('video/mp4');
+ }
});
});
describe('interpretResponse', function () {
- let bidderResponse, bidderRequest, bidRequest, expectedBid;
+ let bidderResponse, bidderRequest, bidRequest, expectedBids;
const requestId = '07fba8b0-8812-4dc6-b91e-4a525d81729c';
- const bidId = '222209853178';
- const impId = 'imp-id';
- const crId = 'creative-id';
- const adm = 'landing';
+ const bannerAdm = 'landing';
+ const videoAdm = 'test vast';
beforeEach(function () {
bidderResponse = {
body: {
id: requestId,
seatbid: [{
- bid: [{
- crid: crId,
- id: bidId,
- impid: impId,
- price: 1,
- adm: adm
- }]
+ bid: [
+ {
+ crid: 1,
+ impid: 1,
+ price: 1,
+ adm: bannerAdm
+ },
+ {
+ crid: 2,
+ impid: 2,
+ price: 1,
+ adm: videoAdm
+ }
+ ]
}]
}
};
@@ -131,36 +175,64 @@ describe('kimberliteBidAdapter', function () {
domain: 'example.com',
page: 'https://www.example.com/test.html',
},
- bids: [{
- bidId: impId,
- mediaTypes: {
- [BANNER]: {sizes: sizes}
+ bids: [
+ {
+ bidId: 1,
+ mediaTypes: {
+ banner: {sizes: sizes}
+ },
+ params: {
+ placementId: 'test-placement'
+ }
},
- params: {
- placementId: 'test-placement'
+ {
+ bidId: 2,
+ mediaTypes: {
+ video: {
+ mimes: ['video/mp4']
+ }
+ },
+ params: {
+ placementId: 'test-placement'
+ }
}
- }]
+ ]
};
- expectedBid = {
- mediaType: 'banner',
- requestId: 'imp-id',
- seatBidId: '222209853178',
- cpm: 1,
- creative_id: 'creative-id',
- creativeId: 'creative-id',
- ttl: 300,
- netRevenue: true,
- ad: adm,
- meta: {}
- };
+ expectedBids = [
+ {
+ mediaType: 'banner',
+ requestId: 1,
+ cpm: 1,
+ creative_id: 1,
+ creativeId: 1,
+ ttl: 300,
+ netRevenue: true,
+ ad: bannerAdm,
+ meta: {}
+ },
+ {
+ mediaType: 'video',
+ requestId: 2,
+ cpm: 1,
+ creative_id: 2,
+ creativeId: 2,
+ ttl: 300,
+ netRevenue: true,
+ vastXml: videoAdm,
+ meta: {}
+ },
+ ];
bidRequest = spec.buildRequests(bidderRequest.bids, bidderRequest);
});
it('pass on valid request', function () {
const bids = spec.interpretResponse(bidderResponse, bidRequest);
- assert.deepEqual(bids[0], expectedBid);
+ assert.deepEqual(bids[0], expectedBids[0]);
+ if (FEATURES.VIDEO) {
+ assert.deepEqual(bids[1], expectedBids[1]);
+ }
});
it('fails on empty response', function () {