diff --git a/modules/brightMountainMediaBidAdapter.js b/modules/brightMountainMediaBidAdapter.js index b57e696148f..5539004bdcd 100644 --- a/modules/brightMountainMediaBidAdapter.js +++ b/modules/brightMountainMediaBidAdapter.js @@ -1,14 +1,27 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; import * as utils from '../src/utils.js'; const BIDDER_CODE = 'bmtm'; const AD_URL = 'https://one.elitebidder.com/api/hb'; +const SYNC_URL = 'https://console.brightmountainmedia.com:8443/cookieSync'; + +const videoExt = [ + 'video/x-ms-wmv', + 'video/x-flv', + 'video/mp4', + 'video/3gpp', + 'application/x-mpegURL', + 'video/quicktime', + 'video/x-msvideo', + 'application/x-shockwave-flash', + 'application/javascript' +]; export const spec = { code: BIDDER_CODE, aliases: ['brightmountainmedia'], - supportedMediaTypes: [BANNER, VIDEO, NATIVE], + supportedMediaTypes: [BANNER, VIDEO], isBidRequestValid: (bid) => { return Boolean(bid.bidId && bid.params && bid.params.placement_id); @@ -42,13 +55,38 @@ export const spec = { } for (let i = 0; i < validBidRequests.length; i++) { let bid = validBidRequests[i]; - let traff = bid.params.traffic || BANNER let placement = { placementId: bid.params.placement_id, bidId: bid.bidId, - sizes: bid.mediaTypes[traff].sizes, - traffic: traff }; + + if (bid.mediaTypes.hasOwnProperty(BANNER)) { + placement['traffic'] = BANNER; + if (bid.mediaTypes.banner.sizes) { + placement['sizes'] = bid.mediaTypes.banner.sizes; + } + } + + if (bid.mediaTypes.hasOwnProperty(VIDEO)) { + placement['traffic'] = VIDEO; + if (bid.mediaTypes.video.context) { + placement['context'] = bid.mediaTypes.video.context; + } + if (bid.mediaTypes.video.playerSize) { + placement['sizes'] = bid.mediaTypes.video.playerSize; + } + if (bid.mediaTypes.video.mimes && Array.isArray(bid.mediaTypes.video.mimes)) { + placement['mimes'] = bid.mediaTypes.video.mimes; + } else { + placement['mimes'] = videoExt; + } + if (bid.mediaTypes.video.skip != undefined) { + placement['skip'] = bid.mediaTypes.video.skip; + } + if (bid.mediaTypes.video.playbackmethod && Array.isArray(bid.mediaTypes.video.playbackmethod)) { + placement['playbackmethod'] = bid.mediaTypes.video.playbackmethod; + } + } if (bid.schain) { placement.schain = bid.schain; } @@ -62,25 +100,26 @@ export const spec = { }, interpretResponse: (serverResponse) => { - let response = []; - try { - serverResponse = serverResponse.body; - for (let i = 0; i < serverResponse.length; i++) { - let resItem = serverResponse[i]; - - response.push(resItem); + let bidResponse = []; + const response = serverResponse.body; + if (response && Array.isArray(response) && response.length > 0) { + for (let i = 0; i < response.length; i++) { + if (response[i].cpm > 0) { + if (response[i].mediaType && response[i].mediaType === 'video') { + response[i].vastXml = response[i].ad; + } + bidResponse.push(response[i]); + } } - } catch (e) { - utils.logMessage(e); - }; - return response; + } + return bidResponse; }, getUserSyncs: (syncOptions) => { if (syncOptions.iframeEnabled) { return [{ type: 'iframe', - url: 'https://console.brightmountainmedia.com:8443/cookieSync' + url: SYNC_URL }]; } }, diff --git a/modules/brightMountainMediaBidAdapter.md b/modules/brightMountainMediaBidAdapter.md index 8dba3a4e6e5..97cebe5b633 100644 --- a/modules/brightMountainMediaBidAdapter.md +++ b/modules/brightMountainMediaBidAdapter.md @@ -10,25 +10,102 @@ Maintainer: dev@brightmountainmedia.com Connects to Bright Mountain Media exchange for bids. -Bright Mountain Media bid adapter currently supports Banner. +Bright Mountain Media bid adapter currently supports Banner and Video. + +# Sample Ad Unit: For Publishers + +## Sample Banner only Ad Unit -# Test Parameters ``` - var adUnits = [ - code: 'placementid_0', - mediaTypes: { +var adUnits = [ + { + code: 'postbid_iframe', + mediaTypes: { banner: { - sizes: [[300, 250]] + sizes: [[300, 250]] } - }, - bids: [ + }, + bids: [ { - bidder: 'bmtm', - params: { - placement_id: '5f21784949be82079d08c', - traffic: 'banner' - } + "bidder": "bmtm", + "params": { + "placement_id": 1 + } } - ] + ] + } ]; -``` \ No newline at end of file +``` + +## Sample Video only Ad Unit: Outstream + +``` +var adUnits = [ + { + code: 'postbid_iframe_video', + mediaTypes: { + video: { + playerSize: [[640, 480]], + context: 'outstream' + ... // Additional ORTB video params + } + }, + bids: [ + { + bidder: "bmtm", + params: { + placement_id: 1 + } + } + ], + renderer: { + url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', + render: function (bid) { + adResponse = { + ad: { + video: { + content: bid.vastXml, + player_height: bid.height, + player_width: bid.width + } + } + } + // push to render queue because ANOutstreamVideo may not be loaded yet. + bid.renderer.push(() => { + ANOutstreamVideo.renderAd({ + targetId: bid.adUnitCode, + adResponse: adResponse + }); + }); + } + } + } +]; + +``` + +## Sample Video only Ad Unit: Instream + +``` +var adUnits = [ + { + code: 'postbid_iframe_video', + mediaTypes: { + video: { + playerSize: [[640, 480]], + context: 'instream' + ... // Additional ORTB video params + }, + }, + bids: [ + { + bidder: "bmtm", + params: { + placement_id: 1 + } + } + ] + } +]; + +``` diff --git a/test/spec/modules/brightMountainMediaBidAdapter_spec.js b/test/spec/modules/brightMountainMediaBidAdapter_spec.js index bc7f69f0baf..6c7ef816f4f 100644 --- a/test/spec/modules/brightMountainMediaBidAdapter_spec.js +++ b/test/spec/modules/brightMountainMediaBidAdapter_spec.js @@ -1,13 +1,18 @@ import { expect } from 'chai'; import { spec } from '../../../modules/brightMountainMediaBidAdapter.js'; +const BIDDER_CODE = 'bmtm'; +const ENDPOINT_URL = 'https://one.elitebidder.com/api/hb'; +const ENDPOINT_URL_SYNC = 'https://console.brightmountainmedia.com:8443/cookieSync'; +const PLACEMENT_ID = 329; + describe('brightMountainMediaBidAdapter_spec', function () { - let bid = { + let bidBanner = { bidId: '2dd581a2b6281d', - bidder: 'bmtm', + bidder: BIDDER_CODE, bidderRequestId: '145e1d6a7837c9', params: { - placement_id: '123qwerty' + placement_id: PLACEMENT_ID }, placementCode: 'placementid_0', auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', @@ -18,8 +23,30 @@ describe('brightMountainMediaBidAdapter_spec', function () { }, transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62', }; + + let bidVideo = { + bidId: '2dd581a2b6281d', + bidder: BIDDER_CODE, + bidderRequestId: '145e1d6a7837c9', + params: { + placement_id: PLACEMENT_ID + }, + placementCode: 'placementid_0', + auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', + mediaTypes: { + video: { + playerSizes: [[300, 250]], + context: 'outstream', + skip: 0, + playbackmethod: [1, 2], + mimes: ['video/mp4'] + } + }, + transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62', + }; + let bidderRequest = { - bidderCode: 'bmtm', + bidderCode: BIDDER_CODE, auctionId: 'fffffff-ffff-ffff-ffff-ffffffffffff', bidderRequestId: 'ffffffffffffff', start: 1472239426002, @@ -29,22 +56,20 @@ describe('brightMountainMediaBidAdapter_spec', function () { refererInfo: { referer: 'http://www.example.com', reachedTop: true, - }, - bids: [bid] - } + } + }; describe('isBidRequestValid', function () { it('Should return true when when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; + expect(spec.isBidRequestValid(bidBanner)).to.be.true; }); it('Should return false when required params are not passed', function () { - bid.params = {} - expect(spec.isBidRequestValid(bid)).to.be.false; + bidBanner.params = {} + expect(spec.isBidRequestValid(bidBanner)).to.be.false; }); }); - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid], bidderRequest); + function testServerRequestBody(serverRequest) { it('Creates a ServerRequest object with method, URL and data', function () { expect(serverRequest).to.exist; expect(serverRequest.method).to.exist; @@ -55,7 +80,7 @@ describe('brightMountainMediaBidAdapter_spec', function () { expect(serverRequest.method).to.equal('POST'); }); it('Returns valid URL', function () { - expect(serverRequest.url).to.equal('https://one.elitebidder.com/api/hb'); + expect(serverRequest.url).to.equal(ENDPOINT_URL); }); it('Returns valid data if array of bids is valid', function () { @@ -69,43 +94,31 @@ describe('brightMountainMediaBidAdapter_spec', function () { expect(data.host).to.be.a('string'); expect(data.page).to.be.a('string'); let placements = data['placements']; - for (let i = 0; i < placements.length; i++) { - let placement = placements[i]; - expect(placement).to.have.all.keys('placementId', 'bidId', 'traffic', 'sizes'); - expect(placement.placementId).to.be.a('string'); - expect(placement.bidId).to.be.a('string'); - expect(placement.traffic).to.be.a('string'); - expect(placement.sizes).to.be.an('array'); - } + expect(placements).to.be.an('array'); }); + } + + describe('buildRequests', function () { + bidderRequest['bids'] = [bidBanner]; + let serverRequest = spec.buildRequests([bidBanner], bidderRequest); + testServerRequestBody(serverRequest); + + bidderRequest['bids'] = [bidVideo]; + serverRequest = spec.buildRequests([bidVideo], bidderRequest); + testServerRequestBody(serverRequest); + it('Returns empty data if no valid requests are passed', function () { serverRequest = spec.buildRequests([]); let data = serverRequest.data; expect(data.placements).to.be.an('array').that.is.empty; }); }); - describe('interpretResponse', function () { - let resObject = { - body: [{ - requestId: '123', - mediaType: 'banner', - cpm: 0.3, - width: 320, - height: 50, - ad: '