diff --git a/modules/ablidaBidAdapter.js b/modules/ablidaBidAdapter.js new file mode 100644 index 00000000000..33642a1ac9e --- /dev/null +++ b/modules/ablidaBidAdapter.js @@ -0,0 +1,93 @@ +import * as utils from '../src/utils'; +import {config} from '../src/config'; +import {registerBidder} from '../src/adapters/bidderFactory'; + +const BIDDER_CODE = 'ablida'; +const ENDPOINT_URL = 'https://bidder.ablida.net/prebid'; + +export const spec = { + code: BIDDER_CODE, + + /** + * 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) { + return !!(bid.params.placementId); + }, + + /** + * Make a server request from the list of BidRequests. + * + * @return Array Info describing the request to the server. + * @param validBidRequests + * @param bidderRequest + */ + buildRequests: function (validBidRequests, bidderRequest) { + if (validBidRequests.length === 0) { + return []; + } + return validBidRequests.map(bidRequest => { + const sizes = utils.parseSizesInput(bidRequest.sizes)[0]; + const size = sizes.split('x'); + const jaySupported = 'atob' in window && 'currentScript' in document; + const device = getDevice(); + const payload = { + placementId: bidRequest.params.placementId, + width: size[0], + height: size[1], + bidId: bidRequest.bidId, + categories: bidRequest.params.categories, + referer: bidderRequest.refererInfo.referer, + jaySupported: jaySupported, + device: device + }; + return { + method: 'POST', + url: ENDPOINT_URL, + data: payload + }; + }); + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {ServerResponse} serverResponse A successful response from the server. + * @param bidRequest + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function (serverResponse, bidRequest) { + const bidResponses = []; + const response = serverResponse.body; + + response.forEach(function(bid) { + bid.ttl = config.getConfig('_bidderTimeout'); + bidResponses.push(bid); + }); + return bidResponses; + }, +}; + +function getDevice() { + const ua = navigator.userAgent; + const topWindow = window.top; + if ((/(ipad|xoom|sch-i800|playbook|silk|tablet|kindle)|(android(?!.*mobi))/i).test(ua)) { + return 'tablet'; + } + if ((/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(ua)) { + return 'connectedtv'; + } + if ((/Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Windows\sCE|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/i).test(ua)) { + return 'smartphone'; + } + const width = topWindow.innerWidth || topWindow.document.documentElement.clientWidth || topWindow.document.body.clientWidth; + if (width > 320) { + return 'desktop'; + } + return 'other'; +} + +registerBidder(spec); diff --git a/modules/ablidaBidAdapter.md b/modules/ablidaBidAdapter.md new file mode 100644 index 00000000000..70e6576cd30 --- /dev/null +++ b/modules/ablidaBidAdapter.md @@ -0,0 +1,32 @@ +# Overview + +**Module Name**: Ablida Bidder Adapter +**Module Type**: Bidder Adapter +**Maintainer**: d.kuster@ablida.de + +# Description + +Module that connects to Ablida's bidder for bids. + +# Test Parameters +``` + var adUnits = [ + { + code: 'ad-div', + mediaTypes: { + banner: { + sizes: [[300, 250]], + } + }, + bids: [ + { + bidder: 'ablida', + params: { + placementId: 'mediumrectangle-demo', + categories: ['automotive', 'news-and-politics'] // optional: categories of page + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/ablidaBidAdapter_spec.js b/test/spec/modules/ablidaBidAdapter_spec.js new file mode 100644 index 00000000000..8e0424aee23 --- /dev/null +++ b/test/spec/modules/ablidaBidAdapter_spec.js @@ -0,0 +1,102 @@ +import {assert, expect} from 'chai'; +import {spec} from 'modules/ablidaBidAdapter'; +import {newBidder} from 'src/adapters/bidderFactory'; + +const ENDPOINT_URL = 'https://bidder.ablida.net/prebid'; + +describe('ablidaBidAdapter', function () { + const adapter = newBidder(spec); + describe('isBidRequestValid', function () { + let bid = { + bidder: 'ablida', + params: { + placementId: 123 + }, + adUnitCode: 'adunit-code', + sizes: [ + [300, 250] + ], + bidId: '1234asdf1234', + bidderRequestId: '1234asdf1234asdf', + auctionId: '69e8fef8-5105-4a99-b011-d5669f3bc7f0' + }; + it('should return true where required params found', function () { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + }); + describe('buildRequests', function () { + let bidRequests = [ + { + bidder: 'ablida', + params: { + placementId: 123 + }, + sizes: [ + [300, 250] + ], + adUnitCode: 'adunit-code', + bidId: '23beaa6af6cdde', + bidderRequestId: '14d2939272a26a', + auctionId: '69e8fef8-5105-4a99-b011-d5669f3bc7f0', + } + ]; + + let bidderRequests = { + refererInfo: { + numIframes: 0, + reachedTop: true, + referer: 'http://example.com', + stack: ['http://example.com'] + } + }; + + const request = spec.buildRequests(bidRequests, bidderRequests); + it('sends bid request via POST', function () { + expect(request[0].method).to.equal('POST'); + }); + }); + + describe('interpretResponse', function () { + let bidRequest = { + method: 'POST', + url: ENDPOINT_URL, + data: { + placementId: 'testPlacementId', + width: 300, + height: 200, + bidId: '2b8c4de0116e54', + jaySupported: true, + device: 'desktop', + referer: 'www.example.com' + } + }; + let serverResponse = { + body: [{ + requestId: '2b8c4de0116e54', + cpm: 1.00, + width: 300, + height: 250, + creativeId: '2b8c4de0116e54', + currency: 'EUR', + netRevenue: true, + ttl: 3000, + ad: '' + }] + }; + it('should get the correct bid response', function () { + let expectedResponse = [{ + requestId: '2b8c4de0116e54', + cpm: 1.00, + width: 300, + height: 250, + creativeId: '2b8c4de0116e54', + currency: 'EUR', + netRevenue: true, + ttl: 3000, + ad: '' + }]; + let result = spec.interpretResponse(serverResponse, bidRequest[0]); + expect(Object.keys(result)).to.deep.equal(Object.keys(expectedResponse)); + }); + }); +});