diff --git a/modules/sekindoUMBidAdapter.js b/modules/sekindoUMBidAdapter.js index ee36dd3c88a..6e866c6547e 100644 --- a/modules/sekindoUMBidAdapter.js +++ b/modules/sekindoUMBidAdapter.js @@ -1,91 +1,115 @@ -import { getBidRequest } from 'src/utils.js'; -import { config } from 'src/config'; - -var CONSTANTS = require('src/constants.json'); -var utils = require('src/utils.js'); -var bidfactory = require('src/bidfactory.js'); -var bidmanager = require('src/bidmanager.js'); -var adloader = require('src/adloader.js'); -var adaptermanager = require('src/adaptermanager'); - -function SekindoUMAdapter() { - function _callBids(params) { - var bids = params.bids; - var bidsCount = bids.length; - - var pubUrl = null; - if (parent !== window) { pubUrl = document.referrer; } else { pubUrl = window.location.href; } - - for (var i = 0; i < bidsCount; i++) { - var bidReqeust = bids[i]; - var callbackId = bidReqeust.bidId; - _requestBids(bidReqeust, callbackId, pubUrl); - // store a reference to the bidRequest from the callback id - // bidmanager.pbCallbackMap[callbackId] = bidReqeust; - } - } - - $$PREBID_GLOBAL$$.sekindoCB = function(callbackId, response) { - var bidObj = getBidRequest(callbackId); - if (typeof (response) !== 'undefined' && typeof (response.cpm) !== 'undefined') { - var bid = []; - if (bidObj) { - var bidCode = bidObj.bidder; - var placementCode = bidObj.placementCode; - - if (response.cpm !== undefined && response.cpm > 0) { - bid = bidfactory.createBid(CONSTANTS.STATUS.GOOD); - bid.callback_uid = callbackId; - bid.bidderCode = bidCode; - bid.creative_id = response.adId; - bid.cpm = parseFloat(response.cpm); - bid.ad = response.ad; - bid.width = response.width; - bid.height = response.height; - - bidmanager.addBidResponse(placementCode, bid); - } else { - bid = bidfactory.createBid(CONSTANTS.STATUS.NO_BID); - bid.callback_uid = callbackId; - bid.bidderCode = bidCode; - bidmanager.addBidResponse(placementCode, bid); - } - } - } else { - if (bidObj) { - utils.logMessage('No prebid response for placement ' + bidObj.placementCode); - } else { - utils.logMessage('sekindoUM callback general error'); - } - } - }; - - function _requestBids(bid, callbackId, pubUrl) { - // determine tag params - var spaceId = utils.getBidIdParameter('spaceId', bid.params); - var subId = utils.getBidIdParameter('subId', bid.params); - var bidfloor = utils.getBidIdParameter('bidfloor', bid.params); - var protocol = (document.location.protocol === 'https:' ? 's' : ''); - var scriptSrc = 'http' + protocol + '://hb.sekindo.com/live/liveView.php?'; - - scriptSrc = utils.tryAppendQueryString(scriptSrc, 's', spaceId); - scriptSrc = utils.tryAppendQueryString(scriptSrc, 'subId', subId); - scriptSrc = utils.tryAppendQueryString(scriptSrc, 'pubUrl', pubUrl); - scriptSrc = utils.tryAppendQueryString(scriptSrc, 'hbcb', callbackId); - scriptSrc = utils.tryAppendQueryString(scriptSrc, 'hbver', '3'); - scriptSrc = utils.tryAppendQueryString(scriptSrc, 'hbobj', '$$PREBID_GLOBAL$$'); - scriptSrc = utils.tryAppendQueryString(scriptSrc, 'dcpmflr', bidfloor); - scriptSrc = utils.tryAppendQueryString(scriptSrc, 'hbto', config.getConfig('bidderTimeout')); - scriptSrc = utils.tryAppendQueryString(scriptSrc, 'protocol', protocol); - - adloader.loadScript(scriptSrc); - } - - return { - callBids: _callBids - }; -} - -adaptermanager.registerBidAdapter(new SekindoUMAdapter(), 'sekindoUM'); - -module.exports = SekindoUMAdapter; +import * as utils from 'src/utils'; +import {registerBidder} from 'src/adapters/bidderFactory'; +export const spec = { + code: 'sekindoUM', + supportedMediaTypes: ['video'], + /** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function(bid) { + if (bid.mediaType == 'video' || (typeof bid.mediaTypes == 'object' && typeof bid.mediaTypes.video == 'object')) { + if (typeof bid.params.video != 'object' || typeof bid.params.video.playerWidth == 'undefined' || typeof bid.params.video.playerHeight == 'undefined') { + return false; + } + } + return !!(bid.params.spaceId); + }, + /** + * Make a server request from the list of BidRequests. + * + * @param {validBidRequests[]} - an array of bids + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: function(validBidRequests, bidderRequest) { + var pubUrl = null; + if (parent !== window) { + pubUrl = document.referrer; + } else { + pubUrl = window.location.href; + } + + return validBidRequests.map(bidRequest => { + var subId = utils.getBidIdParameter('subId', bidRequest.params); + var spaceId = utils.getBidIdParameter('spaceId', bidRequest.params); + var bidfloor = utils.getBidIdParameter('bidfloor', bidRequest.params); + var protocol = (document.location.protocol === 'https:' ? 's' : ''); + var queryString = ''; + + queryString = utils.tryAppendQueryString(queryString, 's', spaceId); + queryString = utils.tryAppendQueryString(queryString, 'subId', subId); + queryString = utils.tryAppendQueryString(queryString, 'pubUrl', pubUrl); + queryString = utils.tryAppendQueryString(queryString, 'hbTId', bidRequest.transactionId); + queryString = utils.tryAppendQueryString(queryString, 'hbBidId', bidRequest.bidId); + queryString = utils.tryAppendQueryString(queryString, 'hbver', '4'); + queryString = utils.tryAppendQueryString(queryString, 'hbcb', '1');/// legasy + queryString = utils.tryAppendQueryString(queryString, 'dcpmflr', bidfloor); + queryString = utils.tryAppendQueryString(queryString, 'protocol', protocol); + if (bidRequest.mediaType === 'video' || (typeof bidRequest.mediaTypes == 'object' && typeof bidRequest.mediaTypes.video == 'object')) { + queryString = utils.tryAppendQueryString(queryString, 'x', bidRequest.params.playerWidth); + queryString = utils.tryAppendQueryString(queryString, 'y', bidRequest.params.playerHeight); + if (typeof vid_vastType != 'undefined') { + queryString = utils.tryAppendQueryString(queryString, 'vid_vastType', bidRequest.params.vid_vastType); + } + if (typeof bidRequest.mediaTypes == 'object' && typeof bidRequest.mediaTypes.video == 'object' && typeof bidRequest.mediaTypes.video.context == 'string') { + queryString = utils.tryAppendQueryString(queryString, 'vid_context', bidRequest.mediaTypes.video.context); + } + } + + var endpointUrl = 'http' + protocol + '://hb.sekindo.com/live/liveView.php'; + + return { + method: 'GET', + url: endpointUrl, + data: queryString, + }; + }); + }, + /** + * Unpack the response from the server into a list of bids. + * + * @param {*} serverResponse A successful response from the server. + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function(serverResponse, bidRequest) { + if (typeof serverResponse !== 'object') { + return []; + } + + let bidResponses = []; + var bidResponse = { + requestId: serverResponse.body.id, + bidderCode: spec.code, + cpm: serverResponse.body.cpm, + width: serverResponse.body.width, + height: serverResponse.body.height, + creativeId: serverResponse.body.creativeId, + currency: serverResponse.body.currency, + netRevenue: serverResponse.body.netRevenue, + ttl: serverResponse.body.ttl + }; + if (bidRequest.mediaType == 'video') { + if (typeof serverResponse.body.vastUrl != 'undefined') { + bidResponse.vastUrl = serverResponse.body.vastUrl; + } else { + bidResponse.vastXml = serverResponse.body.vastXml; + } + } else { + bidResponse.ad = serverResponse.body.ad; + } + + bidResponses.push(bidResponse); + return bidResponses; + }, + getUserSyncs: function(syncOptions) { + if (syncOptions.iframeEnabled) { + return [{ + type: 'iframe', + url: 'ADAPTER_SYNC_URL' + }]; + } + } +} +registerBidder(spec); diff --git a/modules/sekindoUMBidAdapter.md b/modules/sekindoUMBidAdapter.md new file mode 100755 index 00000000000..9f44e7a855e --- /dev/null +++ b/modules/sekindoUMBidAdapter.md @@ -0,0 +1,41 @@ +# Overview + +**Module Name**: sekindoUM Bidder Adapter +**Module Type**: Bidder Adapter +**Maintainer**: nissime@sekindo.com + +# Description + +Connects to Sekindo (part of UM) demand source to fetch bids. +Banner, Outstream and Native formats are supported. + + +# Test Parameters +``` + var adUnits = [{ + code: 'banner-ad-div', + sizes: [[300, 250]], + bids: [{ + bidder: 'sekindoUM', + params: { + spaceId: 14071 + } + }] + }, + { + code: 'video-ad-div', + sizes: [[640, 480]], + bids: [{ + bidder: 'sekindoUM', + params: { + spaceId: 87812, + video:{ + playerWidth:640, + playerHeight:480, + vid_vastType: 5 //optional + } + } + }] + } + ]; +``` diff --git a/test/spec/modules/sekindoUMBidAdapter_spec.js b/test/spec/modules/sekindoUMBidAdapter_spec.js index 073c09b0f4f..a5731da0789 100644 --- a/test/spec/modules/sekindoUMBidAdapter_spec.js +++ b/test/spec/modules/sekindoUMBidAdapter_spec.js @@ -1,78 +1,160 @@ -import {expect} from 'chai'; -import SekindoUMAdapter from '../../../modules/sekindoUMBidAdapter'; -var bidManager = require('src/bidmanager'); +import { expect } from 'chai'; +import { spec } from 'modules/sekindoUMBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory'; -describe('sekindoUM Adapter Tests', () => { - let _sekindoUMAdapter; - var addBidResponseSpy; +describe('sekindoUMAdapter', () => { + const adapter = newBidder(spec); - const bidderRequest = { - bidderCode: 'sekindoUM', - bids: [{ - bidder: 'sekindoUM', - bidId: 'sekindo_bidId', - bidderRequestId: 'sekindo_bidderRequestId', - requestId: 'sekindo_requestId', - placementCode: 'foo', - params: { - spaceId: 14071 - } - }] + const bannerParams = { + 'spaceId': '14071' }; - beforeEach(() => { - _sekindoUMAdapter = new SekindoUMAdapter(); + const videoParams = { + 'spaceId': '14071', + 'video': { + playerWidth: 300, + playerHeight: 250, + vid_vastType: 2 // optional + } + }; + + var bidRequests = { + 'bidder': 'sekindoUM', + 'params': bannerParams, + 'adUnitCode': 'adunit-code', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + 'mediaType': 'banner' + }; + + describe('inherited functions', () => { + it('exists and is a function', () => { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); }); - describe('sekindoUM callBids', () => { - beforeEach(() => { - _sekindoUMAdapter.callBids(bidderRequest); + describe('isBidRequestValid', () => { + it('should return true when required params found', () => { + bidRequests.mediaType = 'banner'; + bidRequests.params = bannerParams; + expect(spec.isBidRequestValid(bidRequests)).to.equal(true); }); - it('Verify sekindo script tag was created', () => { - var scriptTags = document.getElementsByTagName('script'); - var sekindoTagExists = 0; - for (var i = 0; i < scriptTags.length; i++) { - if (scriptTags[i].src.match('hb.sekindo.com') != null) { - sekindoTagExists = 1; - break; - } - } - expect(sekindoTagExists).to.equal(1); + it('should return false when required video params are missing', () => { + bidRequests.mediaType = 'video'; + bidRequests.params = bannerParams; + expect(spec.isBidRequestValid(bidRequests)).to.equal(false); + }); + + it('should return true when required Video params found', () => { + bidRequests.mediaType = 'video'; + bidRequests.params = videoParams; + expect(spec.isBidRequestValid(bidRequests)).to.equal(true); }); }); - describe('Should submit bid responses correctly', function () { - beforeEach(function () { - addBidResponseSpy = sinon.stub(bidManager, 'addBidResponse'); - $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); - _sekindoUMAdapter = new SekindoUMAdapter(); + describe('buildRequests', () => { + it('banner data should be a query string and method = GET', () => { + bidRequests.mediaType = 'banner'; + bidRequests.params = bannerParams; + const request = spec.buildRequests([bidRequests]); + expect(request[0].data).to.be.a('string'); + expect(request[0].method).to.equal('GET'); }); - afterEach(function () { - addBidResponseSpy.restore(); + it('video data should be a query string and method = GET', () => { + bidRequests.mediaType = 'video'; + bidRequests.params = videoParams; + const request = spec.buildRequests([bidRequests]); + expect(request[0].data).to.be.a('string'); + expect(request[0].method).to.equal('GET'); }); + }); - it('Should correctly submit valid bid to the bid manager', function () { - var HB_bid = { - adId: 'sekindoUM_bidId', - cpm: 0.23, - width: 300, - height: 250, - ad: '