Skip to content

Commit

Permalink
add smms adapter (#4439)
Browse files Browse the repository at this point in the history
* add smms adapter

* re-run ci, why adigo adapter failed??

* review comments fix, remove deprecated functions, fix unit test
  • Loading branch information
songtungmtp authored and jaiminpanchal27 committed Nov 20, 2019
1 parent 58319b8 commit 16aad1f
Show file tree
Hide file tree
Showing 3 changed files with 376 additions and 0 deletions.
155 changes: 155 additions & 0 deletions modules/smmsBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import * as utils from '../src/utils';
import { registerBidder } from '../src/adapters/bidderFactory';

const BIDDER_CODE = 'smms';
const ENDPOINT_BANNER = 'https://bidder.mediams.mb.softbank.jp/api/v1/prebid/banner';
const ENDPOINT_NATIVE = 'https://bidder.mediams.mb.softbank.jp/api/v1/prebid/native';
const COOKIE_SYNC_URL = 'https://bidder.mediams.mb.softbank.jp/api/v1/cookie/gen';
const SUPPORTED_MEDIA_TYPES = ['banner', 'native'];
const SUPPORTED_CURRENCIES = ['USD', 'JPY'];
const DEFAULT_CURRENCY = 'JPY';
const NET_REVENUE = true;

function _encodeURIComponent(a) {
let b = window.encodeURIComponent(a);
b = b.replace(/'/g, '%27');
return b;
}

export function _getUrlVars(url) {
let hash;
const myJson = {};
const hashes = url.slice(url.indexOf('?') + 1).split('&');
for (let i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
myJson[hash[0]] = hash[1];
}
return myJson;
}

export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: SUPPORTED_MEDIA_TYPES,
isBidRequestValid: function(bid) {
let valid = !!(bid.params.placementId);
if (valid && bid.params.hasOwnProperty('currency')) {
if (SUPPORTED_CURRENCIES.indexOf(bid.params.currency) === -1) {
utils.logError('Invalid currency type, we support only JPY and USD!');
valid = false;
}
}

return valid;
},
/**
* 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) {
const serverRequests = [];
let refererInfo;
if (bidderRequest && bidderRequest.refererInfo) {
refererInfo = bidderRequest.refererInfo;
}

const g = (typeof (geparams) !== 'undefined' && typeof (geparams) == 'object' && geparams) ? geparams : {};
validBidRequests.forEach((bid, i) => {
let endpoint = ENDPOINT_BANNER;
let data = {
'placementid': bid.params.placementId,
'cur': bid.params.hasOwnProperty('currency') ? bid.params.currency : DEFAULT_CURRENCY,
'ua': navigator.userAgent,
'adtk': _encodeURIComponent(g.lat ? '0' : '1'),
'loc': (refererInfo && refererInfo.referer) ? refererInfo.referer : '',
'topframe': (window.parent == window.self) ? 1 : 0,
'sw': screen && screen.width,
'sh': screen && screen.height,
'cb': Math.floor(Math.random() * 99999999999),
'tpaf': 1,
'cks': 1,
'requestid': bid.bidId,
'referer': (refererInfo && refererInfo.referer) ? refererInfo.referer : ''
};

if (bid.hasOwnProperty('nativeParams')) {
endpoint = ENDPOINT_NATIVE;
data.tkf = 1; // return url tracker
data.ad_track = '1';
data.apiv = '1.1.0';
}

serverRequests.push({
method: 'GET',
url: endpoint,
data: utils.parseQueryStringParameters(data)
});
});

return serverRequests;
},
interpretResponse: function(serverResponse, request) {
const data = _getUrlVars(request.data)
const successBid = serverResponse.body || {};
let bidResponses = [];
if (successBid.hasOwnProperty(data.placementid)) {
let bid = successBid[data.placementid]
let bidResponse = {
requestId: bid.requestid,
cpm: bid.price,
creativeId: bid.creativeId,
currency: bid.cur,
netRevenue: NET_REVENUE,
ttl: 700
};

if (bid.hasOwnProperty('title')) { // it is native ad response
bidResponse.mediaType = 'native'
bidResponse.native = {
title: bid.title,
body: bid.description,
cta: bid.cta,
sponsoredBy: bid.advertiser,
clickUrl: _encodeURIComponent(bid.landingURL),
impressionTrackers: bid.trackings,
}
if (bid.screenshots) {
bidResponse.native.image = {
url: bid.screenshots.url,
height: bid.screenshots.height,
width: bid.screenshots.width,
}
}
if (bid.icon) {
bidResponse.native.icon = {
url: bid.icon.url,
height: bid.icon.height,
width: bid.icon.width,
}
}
} else {
bidResponse.ad = bid.adm
bidResponse.width = bid.width
bidResponse.height = bid.height
}

bidResponses.push(bidResponse);
}

return bidResponses;
},
getUserSyncs: function(syncOptions, serverResponses) {
let syncs = []
syncs.push({
type: 'image',
url: COOKIE_SYNC_URL
})

return syncs;
},
onTimeout: function(timeoutData) {},
onBidWon: function(bid) {},
onSetTargeting: function(bid) {}
}
registerBidder(spec);
60 changes: 60 additions & 0 deletions modules/smmsBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Overview

Module Name: SMMS Bid Adapter

Maintainer: SBBGRP-SSP-PMP@g.softbank.co.jp

# Description

Module that connects to softbank's demand sources

# Test Parameters

```javascript
var adUnits = [
{
code: 'test',
mediaTypes: {
banner: {
sizes: [[300, 250], [300,600]],
}
},
bids: [
{
bidder: 'smms',
params: {
placementId: 1440837,
currency: 'USD'
}
}
]
},
{
code: 'test',
mediaTypes: {
native: {
title: {
required: true,
len: 80
},
image: {
required: true,
sizes: [150, 50]
},
sponsoredBy: {
required: true
}
}
},
bids: [
{
bidder: 'smms',
params: {
placementId: 1440838,
currency: 'USD'
}
},
],
}
];
```
161 changes: 161 additions & 0 deletions test/spec/modules/smmsBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import {expect} from 'chai';
import {spec, _getUrlVars} from 'modules/smmsBidAdapter';
import * as utils from 'src/utils';

const BASE_URI = 'https://bidder.mediams.mb.softbank.jp/api/v1/prebid/banner'
const NATIVE_BASE_URI = 'https://bidder.mediams.mb.softbank.jp/api/v1/prebid/native'

describe('smms adapter', function() {
let bidRequests;
let nativeBidRequests;

beforeEach(function() {
bidRequests = [
{
bidder: 'smms',
params: {
placementId: 1440837,
currency: 'USD'
}
}
]

nativeBidRequests = [
{
bidder: 'smms',
params: {
placementId: 1440838,
currency: 'USD'
},
nativeParams: {
title: {
required: true,
len: 80
},
image: {
required: true,
sizes: [150, 50]
},
sponsoredBy: {
required: true
}
}
}
]
})

describe('isBidRequestValid', function () {
it('valid bid case: required params found', function () {
let validBid = {
bidder: 'smms',
params: {
placementId: 1440837,
currency: 'USD'
}
}
let isValid = spec.isBidRequestValid(validBid);
expect(isValid).to.equal(true);
});

it('invalid bid case: placementId is not passed', function() {
let validBid = {
bidder: 'smms',
params: {
}
}
let isValid = spec.isBidRequestValid(validBid);
expect(isValid).to.equal(false);
})

it('invalid bid case: currency is not support', function() {
let validBid = {
bidder: 'smms',
params: {
placementId: 1440837,
currency: 'AUD'
}
}
let isValid = spec.isBidRequestValid(validBid);
expect(isValid).to.equal(false);
})
})

describe('buildRequests', function () {
it('sends bid request to ENDPOINT via GET', function () {
const request = spec.buildRequests(bidRequests)[0];
expect(request.url).to.equal(BASE_URI);
expect(request.method).to.equal('GET');
});

it('sends native bid request to ENDPOINT via GET', function () {
const request = spec.buildRequests(nativeBidRequests)[0];
expect(request.url).to.equal(NATIVE_BASE_URI);
expect(request.method).to.equal('GET');
});

it('buildRequests function should not modify original bidRequests object', function () {
let originalBidRequests = utils.deepClone(bidRequests);
spec.buildRequests(bidRequests);
expect(bidRequests).to.deep.equal(originalBidRequests);
});

it('buildRequests function should not modify original nativeBidRequests object', function () {
let originalBidRequests = utils.deepClone(nativeBidRequests);
spec.buildRequests(nativeBidRequests);
expect(nativeBidRequests).to.deep.equal(originalBidRequests);
});

it('Request params check', function() {
let request = spec.buildRequests(bidRequests)[0];
const data = _getUrlVars(request.data)
expect(parseInt(data.placementid)).to.exist.and.to.equal(bidRequests[0].params.placementId);
expect(data.cur).to.exist.and.to.equal(bidRequests[0].params.currency);
})

it('Native request params check', function() {
let request = spec.buildRequests(nativeBidRequests)[0];
const data = _getUrlVars(request.data)
expect(parseInt(data.placementid)).to.exist.and.to.equal(nativeBidRequests[0].params.placementId);
expect(data.cur).to.exist.and.to.equal(nativeBidRequests[0].params.currency);
})
})

describe('interpretResponse', function () {
let response = {
1440837:
{
'creativeId': '<!-- CREATIVE ID -->',
'cur': 'USD',
'price': 0.0920,
'width': 300,
'height': 250,
'requestid': '2e42361a6172bf',
'adm': '<!-- ADS TAG -->'
}
}

it('should get correct bid response', function () {
let expectedResponse = [
{
'requestId': '2e42361a6172bf',
'cpm': 0.0920,
'width': 300,
'height': 250,
'netRevenue': true,
'currency': 'USD',
'creativeId': '<!-- CREATIVE ID -->',
'ttl': 700,
'ad': '<!-- ADS TAG -->'
}
];
let request = spec.buildRequests(bidRequests)[0];
let result = spec.interpretResponse({body: response}, request);
expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0]));
expect(result[0].cpm).to.not.equal(null);
expect(result[0].creativeId).to.not.equal(null);
expect(result[0].ad).to.not.equal(null);
expect(result[0].currency).to.equal('USD');
expect(result[0].netRevenue).to.equal(true);
});
})
})

0 comments on commit 16aad1f

Please sign in to comment.