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.
* Adding AdButler Adapter * Prevent AdButler TypeError Only attempt to build a bid response if we have the information of which bid to respond to. * Refactor AdButler Testing Now stubbing adLoader instead of spying. Additional changes to ensure all tests still passed. * Prevent AdButler TypeErrors Prevent AdButler TypeErrors and pass bid request object into the bid response. * Add optional domain parameter. Add optional domain parameter to AdButler adapter. * Update AdButler adapter to 3.0 spec
- Loading branch information
1 parent
4c9bf6f
commit bb7ecad
Showing
3 changed files
with
352 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,131 @@ | ||
'use strict'; | ||
|
||
import * as utils from '../src/utils'; | ||
import {config} from '../src/config'; | ||
import {registerBidder} from '../src/adapters/bidderFactory'; | ||
|
||
const BIDDER_CODE = 'adbutler'; | ||
|
||
export const spec = { | ||
code: BIDDER_CODE, | ||
pageID: Math.floor(Math.random() * 10e6), | ||
aliases: ['divreach'], | ||
|
||
isBidRequestValid: function (bid) { | ||
return !!(bid.params.accountID && bid.params.zoneID); | ||
}, | ||
|
||
buildRequests: function (validBidRequests) { | ||
let i; | ||
let zoneID; | ||
let bidRequest; | ||
let accountID; | ||
let keyword; | ||
let domain; | ||
let requestURI; | ||
let serverRequests = []; | ||
let zoneCounters = {}; | ||
|
||
for (i = 0; i < validBidRequests.length; i++) { | ||
bidRequest = validBidRequests[i]; | ||
zoneID = utils.getBidIdParameter('zoneID', bidRequest.params); | ||
accountID = utils.getBidIdParameter('accountID', bidRequest.params); | ||
keyword = utils.getBidIdParameter('keyword', bidRequest.params); | ||
domain = utils.getBidIdParameter('domain', bidRequest.params); | ||
|
||
if (!(zoneID in zoneCounters)) { | ||
zoneCounters[zoneID] = 0; | ||
} | ||
|
||
if (typeof domain === 'undefined' || domain.length === 0) { | ||
domain = 'servedbyadbutler.com'; | ||
} | ||
|
||
requestURI = 'https://' + domain + '/adserve/;type=hbr;'; | ||
requestURI += 'ID=' + encodeURIComponent(accountID) + ';'; | ||
requestURI += 'setID=' + encodeURIComponent(zoneID) + ';'; | ||
requestURI += 'pid=' + encodeURIComponent(spec.pageID) + ';'; | ||
requestURI += 'place=' + encodeURIComponent(zoneCounters[zoneID]) + ';'; | ||
|
||
// append the keyword for targeting if one was passed in | ||
if (keyword !== '') { | ||
requestURI += 'kw=' + encodeURIComponent(keyword) + ';'; | ||
} | ||
|
||
zoneCounters[zoneID]++; | ||
serverRequests.push({ | ||
method: 'GET', | ||
url: requestURI, | ||
data: {}, | ||
bidRequest: bidRequest | ||
}); | ||
} | ||
return serverRequests; | ||
}, | ||
|
||
interpretResponse: function (serverResponse, bidRequest) { | ||
const bidObj = bidRequest.bidRequest; | ||
let bidResponses = []; | ||
let bidResponse = {}; | ||
let isCorrectSize = false; | ||
let isCorrectCPM = true; | ||
let CPM; | ||
let minCPM; | ||
let maxCPM; | ||
let width; | ||
let height; | ||
|
||
serverResponse = serverResponse.body; | ||
if (serverResponse && serverResponse.status === 'SUCCESS' && bidObj) { | ||
CPM = serverResponse.cpm; | ||
minCPM = utils.getBidIdParameter('minCPM', bidObj.params); | ||
maxCPM = utils.getBidIdParameter('maxCPM', bidObj.params); | ||
width = parseInt(serverResponse.width); | ||
height = parseInt(serverResponse.height); | ||
|
||
// Ensure response CPM is within the given bounds | ||
if (minCPM !== '' && CPM < parseFloat(minCPM)) { | ||
isCorrectCPM = false; | ||
} | ||
if (maxCPM !== '' && CPM > parseFloat(maxCPM)) { | ||
isCorrectCPM = false; | ||
} | ||
|
||
// Ensure that response ad matches one of the placement sizes. | ||
utils._each(utils.deepAccess(bidObj, 'mediaTypes.banner.sizes', []), function (size) { | ||
if (width === size[0] && height === size[1]) { | ||
isCorrectSize = true; | ||
} | ||
}); | ||
if (isCorrectCPM && isCorrectSize) { | ||
bidResponse.requestId = bidObj.bidId; | ||
bidResponse.bidderCode = bidObj.bidder; | ||
bidResponse.creativeId = serverResponse.placement_id; | ||
bidResponse.cpm = CPM; | ||
bidResponse.width = width; | ||
bidResponse.height = height; | ||
bidResponse.ad = serverResponse.ad_code; | ||
bidResponse.ad += spec.addTrackingPixels(serverResponse.tracking_pixels); | ||
bidResponse.currency = 'USD'; | ||
bidResponse.netRevenue = true; | ||
bidResponse.ttl = config.getConfig('_bidderTimeout'); | ||
bidResponse.referrer = utils.deepAccess(bidObj, 'refererInfo.referer'); | ||
bidResponses.push(bidResponse); | ||
} | ||
} | ||
return bidResponses; | ||
}, | ||
|
||
addTrackingPixels: function (trackingPixels) { | ||
let trackingPixelMarkup = ''; | ||
utils._each(trackingPixels, function (pixelURL) { | ||
let trackingPixel = '<img height="0" width="0" border="0" style="display:none;" src="'; | ||
trackingPixel += pixelURL; | ||
trackingPixel += '">'; | ||
|
||
trackingPixelMarkup += trackingPixel; | ||
}); | ||
return trackingPixelMarkup; | ||
} | ||
}; | ||
registerBidder(spec); |
Empty file.
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,221 @@ | ||
import {expect} from 'chai'; | ||
import {spec} from 'modules/adbutlerBidAdapter'; | ||
|
||
describe('AdButler adapter', function () { | ||
let bidRequests; | ||
|
||
beforeEach(function () { | ||
bidRequests = [ | ||
{ | ||
bidder: 'adbutler', | ||
params: { | ||
accountID: '167283', | ||
zoneID: '210093', | ||
keyword: 'red', | ||
minCPM: '1.00', | ||
maxCPM: '5.00' | ||
}, | ||
placementCode: '/19968336/header-bid-tag-1', | ||
mediaTypes: { | ||
banner: { | ||
sizes: [[300, 250], [300, 600]], | ||
}, | ||
}, | ||
bidId: '23acc48ad47af5', | ||
auctionId: '0fb4905b-9456-4152-86be-c6f6d259ba99', | ||
bidderRequestId: '1c56ad30b9b8ca8', | ||
transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' | ||
} | ||
]; | ||
}); | ||
|
||
describe('implementation', function () { | ||
describe('for requests', function () { | ||
it('should accept valid bid', function () { | ||
let validBid = { | ||
bidder: 'adbutler', | ||
params: { | ||
accountID: '167283', | ||
zoneID: '210093' | ||
} | ||
}, | ||
isValid = spec.isBidRequestValid(validBid); | ||
|
||
expect(isValid).to.equal(true); | ||
}); | ||
|
||
it('should reject invalid bid', function () { | ||
let invalidBid = { | ||
bidder: 'adbutler', | ||
params: { | ||
accountID: '167283', | ||
} | ||
}, | ||
isValid = spec.isBidRequestValid(invalidBid); | ||
|
||
expect(isValid).to.equal(false); | ||
}); | ||
|
||
it('should use custom domain string', function () { | ||
let bidRequests = [ | ||
{ | ||
bidId: '3c9408cdbf2f68', | ||
sizes: [[300, 250]], | ||
bidder: 'adbutler', | ||
params: { | ||
accountID: '107878', | ||
zoneID: '86133', | ||
domain: 'servedbyadbutler.com.dan.test' | ||
}, | ||
auctionId: '10b327aa396609', | ||
placementCode: '/123456/header-bid-tag-1' | ||
} | ||
], | ||
requests = spec.buildRequests(bidRequests), | ||
requestURL = requests[0].url; | ||
|
||
expect(requestURL).to.have.string('.dan.test'); | ||
}); | ||
|
||
it('should set default domain', function () { | ||
let requests = spec.buildRequests(bidRequests), | ||
request = requests[0]; | ||
|
||
let [domain] = request.url.split('/adserve/'); | ||
|
||
expect(domain).to.equal('https://servedbyadbutler.com'); | ||
}); | ||
|
||
it('should set the keyword parameter', function () { | ||
let requests = spec.buildRequests(bidRequests), | ||
requestURL = requests[0].url; | ||
|
||
expect(requestURL).to.have.string(';kw=red;'); | ||
}); | ||
|
||
it('should increment the count for the same zone', function () { | ||
let bidRequests = [ | ||
{ | ||
sizes: [[300, 250]], | ||
bidder: 'adbutler', | ||
params: { | ||
accountID: '107878', | ||
zoneID: '86133', | ||
} | ||
}, { | ||
sizes: [[300, 250]], | ||
bidder: 'adbutler', | ||
params: { | ||
accountID: '107878', | ||
zoneID: '86133', | ||
} | ||
}, | ||
], | ||
requests = spec.buildRequests(bidRequests), | ||
firstRequest = requests[0].url, | ||
secondRequest = requests[1].url; | ||
|
||
expect(firstRequest).to.have.string(';place=0;'); | ||
expect(secondRequest).to.have.string(';place=1;'); | ||
}); | ||
}); | ||
|
||
describe('bid responses', function () { | ||
it('should return complete bid response', function () { | ||
let serverResponse = { | ||
body: { | ||
status: 'SUCCESS', | ||
account_id: 167283, | ||
zone_id: 210093, | ||
cpm: 1.5, | ||
width: 300, | ||
height: 250, | ||
place: 0, | ||
ad_code: '<img src="http://image.source.com/img" alt="" title="" border="0" width="300" height="250">', | ||
tracking_pixels: [ | ||
'http://tracking.pixel.com/params=info' | ||
] | ||
} | ||
}, | ||
bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); | ||
|
||
expect(bids).to.be.lengthOf(1); | ||
|
||
expect(bids[0].bidderCode).to.equal('adbutler'); | ||
expect(bids[0].cpm).to.equal(1.5); | ||
expect(bids[0].width).to.equal(300); | ||
expect(bids[0].height).to.equal(250); | ||
expect(bids[0].currency).to.equal('USD'); | ||
expect(bids[0].netRevenue).to.equal(true); | ||
expect(bids[0].ad).to.have.length.above(1); | ||
expect(bids[0].ad).to.have.string('http://tracking.pixel.com/params=info'); | ||
}); | ||
|
||
it('should return empty bid response', function () { | ||
let serverResponse = { | ||
body: { | ||
status: 'NO_ELIGIBLE_ADS', | ||
zone_id: 210083, | ||
width: 300, | ||
height: 250, | ||
place: 0 | ||
} | ||
}, | ||
bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); | ||
|
||
expect(bids).to.be.lengthOf(0); | ||
}); | ||
|
||
it('should return empty bid response on incorrect size', function () { | ||
let serverResponse = { | ||
body: { | ||
status: 'SUCCESS', | ||
account_id: 167283, | ||
zone_id: 210083, | ||
cpm: 1.5, | ||
width: 728, | ||
height: 90, | ||
place: 0 | ||
} | ||
}, | ||
bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); | ||
|
||
expect(bids).to.be.lengthOf(0); | ||
}); | ||
|
||
it('should return empty bid response with CPM too low', function () { | ||
let serverResponse = { | ||
body: { | ||
status: 'SUCCESS', | ||
account_id: 167283, | ||
zone_id: 210093, | ||
cpm: 0.75, | ||
width: 300, | ||
height: 250, | ||
place: 0 | ||
} | ||
}, | ||
bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); | ||
|
||
expect(bids).to.be.lengthOf(0); | ||
}); | ||
|
||
it('should return empty bid response with CPM too high', function () { | ||
let serverResponse = { | ||
body: { | ||
status: 'SUCCESS', | ||
account_id: 167283, | ||
zone_id: 210093, | ||
cpm: 7, | ||
width: 300, | ||
height: 250, | ||
place: 0 | ||
} | ||
}, | ||
bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); | ||
|
||
expect(bids).to.be.lengthOf(0); | ||
}); | ||
}); | ||
}); | ||
}); |