From 09a09c486a4760a010a1ca2b4db7291c2649b83f Mon Sep 17 00:00:00 2001 From: kpis-msa <50609476+kpis-msa@users.noreply.github.com> Date: Tue, 5 Nov 2019 22:33:26 +0900 Subject: [PATCH] 2019/10/18 Create Mobsmart bidder adapter (#4339) --- modules/mobsmartBidAdapter.js | 94 ++++++++ modules/mobsmartBidAdapter.md | 50 +++++ test/spec/modules/mobsmartBidAdapter_spec.js | 214 +++++++++++++++++++ 3 files changed, 358 insertions(+) create mode 100644 modules/mobsmartBidAdapter.js create mode 100644 modules/mobsmartBidAdapter.md create mode 100644 test/spec/modules/mobsmartBidAdapter_spec.js diff --git a/modules/mobsmartBidAdapter.js b/modules/mobsmartBidAdapter.js new file mode 100644 index 00000000000..ba02aef38ef --- /dev/null +++ b/modules/mobsmartBidAdapter.js @@ -0,0 +1,94 @@ +import { registerBidder } from '../src/adapters/bidderFactory'; +import { config } from '../src/config'; + +const BIDDER_CODE = 'mobsmart'; +const ENDPOINT = 'https://prebid.mobsmart.net/prebid/endpoint'; + +export const spec = { + code: BIDDER_CODE, + isBidRequestValid: function(bid) { + if (bid.bidder !== BIDDER_CODE) { + return false; + } + + return true; + }, + buildRequests: function(validBidRequests, bidderRequest) { + const timeout = config.getConfig('bidderTimeout'); + const referrer = encodeURIComponent(bidderRequest.refererInfo.referer); + + return validBidRequests.map(bidRequest => { + const adUnit = { + code: bidRequest.adUnitCode, + bids: { + bidder: bidRequest.bidder, + params: bidRequest.params + }, + mediaTypes: bidRequest.mediaTypes + }; + + if (bidRequest.hasOwnProperty('sizes') && bidRequest.sizes.length > 0) { + adUnit.sizes = bidRequest.sizes; + } + + const request = { + auctionId: bidRequest.auctionId, + requestId: bidRequest.bidId, + bidRequestsCount: bidRequest.bidRequestsCount, + bidderRequestId: bidRequest.bidderRequestId, + transactionId: bidRequest.transactionId, + referrer: referrer, + timeout: timeout, + adUnit: adUnit + }; + + if (bidRequest.userId && bidRequest.userId.pubcid) { + request.userId = {pubcid: bidRequest.userId.pubcid}; + } + + return { + method: 'POST', + url: ENDPOINT, + data: JSON.stringify(request) + } + }); + }, + interpretResponse: function(serverResponse) { + const bidResponses = []; + + if (serverResponse.body) { + const response = serverResponse.body; + const bidResponse = { + requestId: response.requestId, + cpm: response.cpm, + width: response.width, + height: response.height, + creativeId: response.creativeId, + currency: response.currency, + netRevenue: response.netRevenue, + ttl: response.ttl, + ad: response.ad, + }; + bidResponses.push(bidResponse); + } + + return bidResponses; + }, + getUserSyncs: function(syncOptions, serverResponses) { + let syncs = []; + if (syncOptions.iframeEnabled) { + syncs.push({ + type: 'iframe', + url: 'https://tags.mobsmart.net/tags/iframe' + }); + } else if (syncOptions.pixelEnabled) { + syncs.push({ + type: 'image', + url: 'https://tags.mobsmart.net/tags/image' + }); + } + + return syncs; + } +} +registerBidder(spec); diff --git a/modules/mobsmartBidAdapter.md b/modules/mobsmartBidAdapter.md new file mode 100644 index 00000000000..1240d6db494 --- /dev/null +++ b/modules/mobsmartBidAdapter.md @@ -0,0 +1,50 @@ +# Overview + +``` +Module Name: Mobsmart Bidder Adapter +Module Type: Bidder Adapter +Maintainer: adx@kpis.jp +``` + +# Description + +Module that connects to Mobsmart demand sources to fetch bids. + +# Test Parameters +``` + var adUnits = [ + { + code: 'test-div', + mediaTypes: { + banner: { + sizes: [[300, 250]], // a display size + } + }, + bids: [ + { + bidder: "mobsmart", + params: { + floorPrice: 100, + currency: 'JPY' + } + } + ] + },{ + code: 'test-div', + mediaTypes: { + banner: { + sizes: [[320, 50]], // a mobile size + } + }, + bids: [ + { + bidder: "mobsmart", + params: { + floorPrice: 90, + currency: 'JPY' + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/mobsmartBidAdapter_spec.js b/test/spec/modules/mobsmartBidAdapter_spec.js new file mode 100644 index 00000000000..7c1128276ab --- /dev/null +++ b/test/spec/modules/mobsmartBidAdapter_spec.js @@ -0,0 +1,214 @@ +import { expect } from 'chai'; +import { spec } from 'modules/mobsmartBidAdapter'; + +describe('mobsmartBidAdapter', function () { + describe('isBidRequestValid', function () { + let bid; + beforeEach(function() { + bid = { + bidder: 'mobsmart', + params: { + floorPrice: 100, + currency: 'JPY' + }, + mediaTypes: { + banner: { + size: [[300, 250]] + } + } + }; + }); + + it('should return true when valid bid request is set', function() { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + + it('should return false when bidder is not set to "mobsmart"', function() { + bid.bidder = 'bidder'; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return true when params are not set', function() { + delete bid.params.floorPrice; + delete bid.params.currency; + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + }); + + describe('buildRequests', function () { + let bidRequests; + beforeEach(function() { + bidRequests = [ + { + bidder: 'mobsmart', + adUnitCode: 'mobsmart-ad-code', + auctionId: 'auctionid-123', + bidId: 'bidid123', + bidRequestsCount: 1, + bidderRequestId: 'bidderrequestid123', + transactionId: 'transaction-id-123', + sizes: [[300, 250]], + requestId: 'requestid123', + params: { + floorPrice: 100, + currency: 'JPY' + }, + mediaTypes: { + banner: { + size: [[300, 250]] + } + }, + userId: { + pubcid: 'pubc-id-123' + } + }, { + bidder: 'mobsmart', + adUnitCode: 'mobsmart-ad-code2', + auctionId: 'auctionid-456', + bidId: 'bidid456', + bidRequestsCount: 1, + bidderRequestId: 'bidderrequestid456', + transactionId: 'transaction-id-456', + sizes: [[320, 50]], + requestId: 'requestid456', + params: { + floorPrice: 100, + currency: 'JPY' + }, + mediaTypes: { + banner: { + size: [[320, 50]] + } + }, + userId: { + pubcid: 'pubc-id-456' + } + } + ]; + }); + + let bidderRequest = { + refererInfo: { + referer: 'https://example.com' + } + }; + + it('should not contain a sizes when sizes is not set', function() { + delete bidRequests[0].sizes; + delete bidRequests[1].sizes; + let requests = spec.buildRequests(bidRequests, bidderRequest); + expect(requests[0].data.sizes).to.be.an('undefined'); + expect(requests[1].data.sizes).to.be.an('undefined'); + }); + + it('should not contain a userId when userId is not set', function() { + delete bidRequests[0].userId; + delete bidRequests[1].userId; + let requests = spec.buildRequests(bidRequests, bidderRequest); + expect(requests[0].data.userId).to.be.an('undefined'); + expect(requests[1].data.userId).to.be.an('undefined'); + }); + + it('should have a post method', function() { + let requests = spec.buildRequests(bidRequests, bidderRequest); + expect(requests[0].method).to.equal('POST'); + expect(requests[1].method).to.equal('POST'); + }); + + it('should contain a request id equals to the bid id', function() { + let requests = spec.buildRequests(bidRequests, bidderRequest); + expect(JSON.parse(requests[0].data).requestId).to.equal(bidRequests[0].bidId); + expect(JSON.parse(requests[1].data).requestId).to.equal(bidRequests[1].bidId); + }); + + it('should have an url that match the default endpoint', function() { + let requests = spec.buildRequests(bidRequests, bidderRequest); + expect(requests[0].url).to.equal('https://prebid.mobsmart.net/prebid/endpoint'); + expect(requests[1].url).to.equal('https://prebid.mobsmart.net/prebid/endpoint'); + }); + }); + + describe('interpretResponse', function () { + let serverResponse; + beforeEach(function() { + serverResponse = { + body: { + 'requestId': 'request-id', + 'cpm': 100, + 'width': 300, + 'height': 250, + 'ad': '