-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add a new bid adapter and test specs for bridgewell * remove getUserSyncs(optional) * change var to let or const * fix a bug in adapter test spec, and add a test for required parameters in bid responses * add semicolons to match styling
- Loading branch information
1 parent
049af72
commit 4ee64ac
Showing
3 changed files
with
325 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,101 @@ | ||
import * as utils from 'src/utils'; | ||
import {registerBidder} from 'src/adapters/bidderFactory'; | ||
|
||
const BIDDER_CODE = 'bridgewell'; | ||
const REQUEST_ENDPOINT = '//rec.scupio.com/recweb/prebid.aspx'; | ||
|
||
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 && bid.params && !!bid.params.ChannelID; | ||
}, | ||
|
||
/** | ||
* Make a server request from the list of BidRequests. | ||
* | ||
* @param {BidRequest[]} validBidRequests - an array of bids | ||
* @return ServerRequest Info describing the request to the server. | ||
*/ | ||
buildRequests: function(validBidRequests) { | ||
const channelIDs = []; | ||
|
||
utils._each(validBidRequests, function(bid) { | ||
channelIDs.push(bid.params.ChannelID); | ||
}); | ||
|
||
return { | ||
method: 'GET', | ||
url: REQUEST_ENDPOINT, | ||
data: { | ||
'ChannelID': channelIDs.join(',') | ||
}, | ||
validBidRequests: validBidRequests | ||
}; | ||
}, | ||
|
||
/** | ||
* Unpack the response from the server into a list of bids. | ||
* | ||
* @param {*} 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 = []; | ||
|
||
// map responses to requests | ||
utils._each(bidRequest.validBidRequests, function(req) { | ||
const bidResponse = {}; | ||
|
||
if (!serverResponse.body) { | ||
return; | ||
} | ||
|
||
let matchedResponse = serverResponse.body.find(function(res) { | ||
return !!res && !res.consumed && req.sizes.find(function(size) { | ||
return res.width === size[0] && res.height === size[1]; | ||
}); | ||
}); | ||
|
||
if (matchedResponse) { | ||
matchedResponse.consumed = true; | ||
|
||
// check required parameters | ||
if (typeof matchedResponse.cpm !== 'number') { | ||
return; | ||
} else if (typeof matchedResponse.width !== 'number' || typeof matchedResponse.height !== 'number') { | ||
return; | ||
} else if (typeof matchedResponse.ad !== 'string') { | ||
return; | ||
} else if (typeof matchedResponse.net_revenue === 'undefined') { | ||
return; | ||
} else if (typeof matchedResponse.currency !== 'string') { | ||
return; | ||
} | ||
|
||
bidResponse.requestId = req.bidId; | ||
bidResponse.cpm = matchedResponse.cpm; | ||
bidResponse.width = matchedResponse.width; | ||
bidResponse.height = matchedResponse.height; | ||
bidResponse.ad = matchedResponse.ad; | ||
bidResponse.ttl = matchedResponse.ttl; | ||
bidResponse.creativeId = matchedResponse.id; | ||
bidResponse.netRevenue = matchedResponse.net_revenue === 'true'; | ||
bidResponse.currency = matchedResponse.currency; | ||
|
||
bidResponses.push(bidResponse); | ||
} | ||
}); | ||
|
||
return bidResponses; | ||
} | ||
}; | ||
|
||
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,38 @@ | ||
# Overview | ||
|
||
Module Name: Bridgewell Bidder Adapter | ||
Module Type: Bidder Adapter | ||
Maintainer: kuchunchou@bridgewell.com | ||
|
||
# Description | ||
|
||
Module that connects to Bridgewell demand source to fetch bids. | ||
|
||
# Test Parameters | ||
``` | ||
var adUnits = [ | ||
{ | ||
code: 'test-div', | ||
sizes: [[300, 250]], | ||
bids: [ | ||
{ | ||
bidder: 'bridgewell', | ||
params: { | ||
ChannelID: 'CgUxMjMzOBIBNiIFcGVubnkqCQisAhD6ARoBOQ', | ||
} | ||
} | ||
] | ||
},{ | ||
code: 'test-div', | ||
sizes: [[728, 90]], | ||
bids: [ | ||
{ | ||
bidder: 'bridgewell', | ||
params: { | ||
ChannelID: 'CgUxMjMzOBIBNiIGcGVubnkzKggI2AUQWhoBOQ', | ||
} | ||
} | ||
] | ||
} | ||
]; | ||
``` |
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,186 @@ | ||
import { expect } from 'chai'; | ||
import { spec } from 'modules/bridgewellBidAdapter'; | ||
import { newBidder } from 'src/adapters/bidderFactory'; | ||
import * as utils from 'src/utils'; | ||
|
||
describe('bridgewellBidAdapter', function () { | ||
let bidRequests = [ | ||
{ | ||
'bidder': 'bridgewell', | ||
'params': { | ||
'ChannelID': 'CLJgEAYYvxUiBXBlbm55KgkIrAIQ-gEaATk' | ||
}, | ||
'adUnitCode': 'adunit-code-1', | ||
'sizes': [[300, 250], [300, 600]], | ||
'bidId': '30b31c1838de1e', | ||
'bidderRequestId': '22edbae2733bf6', | ||
'auctionId': '1d1a030790a475', | ||
}, | ||
{ | ||
'bidder': 'bridgewell', | ||
'params': { | ||
'ChannelID': 'CgUxMjMzOBIBNiIGcGVubnkzKggI2AUQWhoBOQ' | ||
}, | ||
'adUnitCode': 'adunit-code-2', | ||
'sizes': [[728, 90]], | ||
'bidId': '3150ccb55da321', | ||
'bidderRequestId': '22edbae2733bf6', | ||
'auctionId': '1d1a030790a475', | ||
}, | ||
{ | ||
'bidder': 'bridgewell', | ||
'params': { | ||
'ChannelID': 'CgUxMjMzOBIBNiIFcGVubnkqCQisAhD6ARoBOQ' | ||
}, | ||
'adUnitCode': 'adunit-code-1', | ||
'sizes': [[300, 250]], | ||
'bidId': '42dbe3a7168a6a', | ||
'bidderRequestId': '22edbae2733bf6', | ||
'auctionId': '1d1a030790a475', | ||
} | ||
]; | ||
const adapter = newBidder(spec); | ||
|
||
describe('inherited functions', () => { | ||
it('exists and is a function', () => { | ||
expect(adapter.callBids).to.exist.and.to.be.a('function'); | ||
}); | ||
}); | ||
|
||
describe('isBidRequestValid', () => { | ||
let bid = { | ||
'bidder': 'bridgewell', | ||
'params': { | ||
'ChannelID': 'CLJgEAYYvxUiBXBlbm55KgkIrAIQ-gEaATk' | ||
}, | ||
'adUnitCode': 'adunit-code', | ||
'sizes': [[300, 250], [300, 600]], | ||
'bidId': '30b31c1838de1e', | ||
'bidderRequestId': '22edbae2733bf6', | ||
'auctionId': '1d1a030790a475', | ||
}; | ||
|
||
it('should return true when required params found', () => { | ||
expect(spec.isBidRequestValid(bid)).to.equal(true); | ||
}); | ||
|
||
it('should return false when required params are not passed', () => { | ||
let bid = Object.assign({}, bid); | ||
delete bid.params; | ||
bid.params = { | ||
'ChannelID': 0 | ||
}; | ||
expect(spec.isBidRequestValid(bid)).to.equal(false); | ||
}); | ||
}); | ||
|
||
describe('buildRequests', () => { | ||
it('should attach valid params to the tag', () => { | ||
const request = spec.buildRequests([bidRequests[0]]); | ||
const payload = request.data; | ||
expect(payload).to.be.an('object'); | ||
expect(payload).to.have.property('ChannelID').that.is.a('string'); | ||
}); | ||
|
||
it('should attach validBidRequests to the tag', () => { | ||
const request = spec.buildRequests(bidRequests); | ||
const validBidRequests = request.validBidRequests; | ||
expect(validBidRequests).to.deep.equal(bidRequests); | ||
}); | ||
|
||
it('should attach valid params to the tag if multiple ChannelIDs are presented', () => { | ||
const request = spec.buildRequests(bidRequests); | ||
const payload = request.data; | ||
expect(payload).to.be.an('object'); | ||
expect(payload).to.have.property('ChannelID').that.is.a('string'); | ||
expect(payload.ChannelID.split(',')).to.have.lengthOf(bidRequests.length); | ||
}); | ||
}); | ||
|
||
describe('interpretResponse', () => { | ||
const request = spec.buildRequests(bidRequests); | ||
const serverResponses = [{ | ||
'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', | ||
'bidder_code': 'bridgewell', | ||
'cpm': 5.0, | ||
'width': 300, | ||
'height': 250, | ||
'ad': '<div>test 300x250</div>', | ||
'ttl': 360, | ||
'net_revenue': 'true', | ||
'currency': 'NTD' | ||
}, { | ||
'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', | ||
'bidder_code': 'bridgewell', | ||
'cpm': 5.0, | ||
'width': 728, | ||
'height': 90, | ||
'ad': '<div>test 728x90</div>', | ||
'ttl': 360, | ||
'net_revenue': 'true', | ||
'currency': 'NTD' | ||
}, { | ||
'id': '8f12c646-3b87-4326-a837-c2a76999f168', | ||
'bidder_code': 'bridgewell', | ||
'cpm': 5.0, | ||
'width': 300, | ||
'height': 250, | ||
'ad': '<div>test 300x250</div>', | ||
'ttl': 360, | ||
'net_revenue': 'true', | ||
'currency': 'NTD' | ||
}]; | ||
|
||
it('should return all required parameters', () => { | ||
const result = spec.interpretResponse({'body': serverResponses}, request); | ||
result.every(res => expect(res.cpm).to.be.a('number')); | ||
result.every(res => expect(res.width).to.be.a('number')); | ||
result.every(res => expect(res.height).to.be.a('number')); | ||
result.every(res => expect(res.ttl).to.be.a('number')); | ||
result.every(res => expect(res.netRevenue).to.be.a('boolean')); | ||
result.every(res => expect(res.currency).to.be.a('string')); | ||
result.every(res => expect(res.ad).to.be.a('string')); | ||
}); | ||
|
||
it('should give up bid if server response is undefiend', () => { | ||
const result = spec.interpretResponse({'body': undefined}, request); | ||
expect(result).to.deep.equal([]); | ||
}); | ||
|
||
it('should give up bid if cpm is missing', () => { | ||
let target = Object.assign({}, serverResponses[0]); | ||
delete target.cpm; | ||
const result = spec.interpretResponse({'body': [target]}, request); | ||
expect(result).to.deep.equal([]); | ||
}); | ||
|
||
it('should give up bid if width or height is missing', () => { | ||
let target = Object.assign({}, serverResponses[0]); | ||
delete target.height; | ||
delete target.width; | ||
const result = spec.interpretResponse({'body': [target]}, request); | ||
expect(result).to.deep.equal([]); | ||
}); | ||
|
||
it('should give up bid if ad is missing', () => { | ||
let target = Object.assign({}, serverResponses[0]); | ||
delete target.ad; | ||
const result = spec.interpretResponse({'body': [target]}, request); | ||
expect(result).to.deep.equal([]); | ||
}); | ||
|
||
it('should give up bid if revenue mode is missing', () => { | ||
let target = Object.assign({}, serverResponses[0]); | ||
delete target.net_revenue; | ||
const result = spec.interpretResponse({'body': [target]}, request); | ||
expect(result).to.deep.equal([]); | ||
}); | ||
|
||
it('should give up bid if currency is missing', () => { | ||
let target = Object.assign({}, serverResponses[0]); | ||
delete target.currency; | ||
const result = spec.interpretResponse({'body': [target]}, request); | ||
expect(result).to.deep.equal([]); | ||
}); | ||
}); | ||
}); |