forked from prebid/Prebid.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added LoopMe Adapter * Replace Object.entries with entries
- Loading branch information
1 parent
d36d458
commit 5112950
Showing
3 changed files
with
229 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import * as utils from 'src/utils'; | ||
import { registerBidder } from 'src/adapters/bidderFactory'; | ||
import { BANNER } from 'src/mediaTypes'; | ||
|
||
const LOOPME_ENDPOINT = 'https://loopme.me/api/hb'; | ||
|
||
const entries = (obj) => { | ||
let output = []; | ||
for (let key in obj) { | ||
if (obj.hasOwnProperty(key)) { | ||
output.push([key, obj[key]]) | ||
} | ||
} | ||
return output; | ||
} | ||
|
||
export const spec = { | ||
code: 'loopme', | ||
supportedMediaTypes: [BANNER], | ||
/** | ||
* @param {object} bid | ||
* @return boolean | ||
*/ | ||
isBidRequestValid: function(bid) { | ||
if (typeof bid.params !== 'object') { | ||
return false; | ||
} | ||
|
||
return !!bid.params.ak; | ||
}, | ||
/** | ||
* @param {BidRequest[]} bidRequests | ||
* @param bidderRequest | ||
* @return ServerRequest[] | ||
*/ | ||
buildRequests: function(bidRequests, bidderRequest) { | ||
return bidRequests.map(bidRequest => { | ||
bidRequest.startTime = new Date().getTime(); | ||
let payload = bidRequest.params; | ||
|
||
if (bidderRequest && bidderRequest.gdprConsent) { | ||
payload.user_consent = bidderRequest.gdprConsent.consentString; | ||
} | ||
|
||
let queryString = entries(payload) | ||
.map(item => `${item[0]}=${encodeURI(item[1])}`) | ||
.join('&'); | ||
|
||
const sizes = | ||
'&sizes=' + | ||
utils | ||
.getAdUnitSizes(bidRequest) | ||
.map(size => `${size[0]}x${size[1]}`) | ||
.join('&sizes='); | ||
|
||
queryString = `${queryString}${sizes}`; | ||
|
||
return { | ||
method: 'GET', | ||
url: `${LOOPME_ENDPOINT}`, | ||
options: { withCredentials: false }, | ||
bidId: bidRequest.bidId, | ||
data: queryString | ||
}; | ||
}); | ||
}, | ||
/** | ||
* @param {*} responseObj | ||
* @param {BidRequest} bidRequest | ||
* @return {Bid[]} An array of bids which | ||
*/ | ||
interpretResponse: function(response = {}, bidRequest) { | ||
const responseObj = response.body; | ||
|
||
if ( | ||
responseObj == null || | ||
typeof responseObj !== 'object' || | ||
!responseObj.hasOwnProperty('ad') | ||
) { | ||
return []; | ||
} | ||
|
||
return [ | ||
{ | ||
requestId: bidRequest.bidId, | ||
cpm: responseObj.cpm, | ||
width: responseObj.width, | ||
height: responseObj.height, | ||
ad: responseObj.ad, | ||
ttl: responseObj.ttl, | ||
currency: responseObj.currency, | ||
creativeId: responseObj.creativeId, | ||
dealId: responseObj.dealId, | ||
netRevenue: responseObj.netRevenue | ||
} | ||
]; | ||
} | ||
}; | ||
registerBidder(spec); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Overview | ||
|
||
``` | ||
Module Name: LoopMe Bid Adapter | ||
Module Type: Bidder Adapter | ||
Maintainer: support@loopme.com | ||
``` | ||
|
||
# Description | ||
|
||
Connect to LoopMe's exchange for bids. | ||
|
||
# Test Parameters | ||
``` | ||
var adUnits = [{ | ||
code: 'test-div', | ||
mediaTypes: { | ||
banner: { | ||
sizes: [[300, 250], [300,600]], | ||
} | ||
}, | ||
bids: [{ | ||
bidder: 'loopme', | ||
params: { | ||
ak: 'cc885e3acc' | ||
} | ||
}] | ||
}]; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import { expect } from 'chai'; | ||
import { spec } from '../../../modules/loopmeBidAdapter'; | ||
import * as utils from 'src/utils'; | ||
|
||
describe('LoopMeAdapter', function () { | ||
const bidRequests = [{ | ||
bidder: 'loopme', | ||
params: { | ||
ak: 'b510d5bcda' | ||
}, | ||
mediaTypes: { | ||
banner: { | ||
sizes: [[300, 250]] | ||
} | ||
}, | ||
adUnitCode: 'ad-1', | ||
bidId: '2652ca954bce9' | ||
}]; | ||
|
||
describe('isBidRequestValid', function () { | ||
it('should return true if the ak parameter is present', function () { | ||
expect(spec.isBidRequestValid(bidRequests[0])).to.be.true; | ||
}); | ||
|
||
it('should return false if the ak parameter is not present', function () { | ||
let bidRequest = utils.deepClone(bidRequests[0]); | ||
delete bidRequest.params.ak; | ||
expect(spec.isBidRequestValid(bidRequest)).to.be.false; | ||
}); | ||
|
||
it('should return false if the params object is not present', function () { | ||
let bidRequest = utils.deepClone(bidRequests); | ||
delete bidRequest[0].params; | ||
expect(spec.isBidRequestValid(bidRequest)).to.be.false; | ||
}); | ||
}); | ||
|
||
describe('buildRequests', function () { | ||
it('should generate a valid single GET request for multiple bid requests', function () { | ||
const request = spec.buildRequests(bidRequests)[0]; | ||
expect(request.method).to.equal('GET'); | ||
expect(request.url).to.equal('https://loopme.me/api/hb'); | ||
expect(request.bidId).to.equal('2652ca954bce9'); | ||
expect(request.data).to.exist; | ||
|
||
const requestData = request.data; | ||
expect(requestData).to.contain('ak=b510d5bcda'); | ||
expect(requestData).to.contain('sizes=300x250'); | ||
}); | ||
|
||
it('should add GDPR data to request if available', function () { | ||
const bidderRequest = { | ||
gdprConsent: { | ||
consentString: 'AAABBB' | ||
} | ||
}; | ||
const request = spec.buildRequests(bidRequests, bidderRequest)[0]; | ||
const requestData = request.data; | ||
|
||
expect(requestData).to.contain('user_consent=AAABBB'); | ||
}); | ||
}); | ||
|
||
describe('interpretResponse', function () { | ||
it('should return an empty array if an invalid response is passed', function () { | ||
const interpretedResponse = spec.interpretResponse({}); | ||
expect(interpretedResponse).to.be.an('array').that.is.empty; | ||
}); | ||
|
||
it('should return valid response when passed valid server response', function () { | ||
const serverResponse = { | ||
body: { | ||
'requestId': '2652ca954bce9', | ||
'cpm': 1, | ||
'width': 480, | ||
'height': 320, | ||
'creativeId': '20154', | ||
'currency': 'USD', | ||
'netRevenue': false, | ||
'ttl': 360, | ||
'ad': `<div>Hello</div>` | ||
} | ||
}; | ||
|
||
const request = spec.buildRequests(bidRequests)[0]; | ||
const interpretedResponse = spec.interpretResponse(serverResponse, request); | ||
|
||
expect(interpretedResponse).to.have.lengthOf(1); | ||
|
||
expect(interpretedResponse[0].requestId).to.equal(serverResponse.body.requestId); | ||
expect(interpretedResponse[0].cpm).to.equal(serverResponse.body.cpm); | ||
expect(interpretedResponse[0].width).to.equal(serverResponse.body.width); | ||
expect(interpretedResponse[0].height).to.equal(serverResponse.body.height); | ||
expect(interpretedResponse[0].creativeId).to.equal(serverResponse.body.creativeId); | ||
expect(interpretedResponse[0].currency).to.equal(serverResponse.body.currency); | ||
expect(interpretedResponse[0].netRevenue).to.equal(serverResponse.body.netRevenue); | ||
expect(interpretedResponse[0].ad).to.equal(serverResponse.body.ad); | ||
expect(interpretedResponse[0].ttl).to.equal(serverResponse.body.ttl); | ||
}); | ||
}); | ||
}); |