forked from prebid/Prebid.js
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New Orbidder Prebid Adapter (prebid#3434)
* initial orbidder version in personal github repo * use adUnits from orbidder_example.html * replace obsolete functions * forgot to commit the test * check if bidderRequest object is available * try to fix weird safari/ie issue
- Loading branch information
Hendrik Iseke
authored and
Pedro López Jiménez
committed
Mar 18, 2019
1 parent
eb7b427
commit e8d18b9
Showing
3 changed files
with
298 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,77 @@ | ||
import {detectReferer} from 'src/refererDetection'; | ||
import {ajax} from 'src/ajax'; | ||
import {registerBidder} from 'src/adapters/bidderFactory'; | ||
|
||
export const spec = { | ||
code: 'orbidder', | ||
orbidderHost: (() => { | ||
let ret = 'https://orbidder.otto.de'; | ||
try { | ||
ret = localStorage.getItem('ov_orbidder_host') || ret; | ||
} catch (e) { | ||
} | ||
return ret; | ||
})(), | ||
|
||
isBidRequestValid(bid) { | ||
return !!(bid.sizes && bid.bidId); | ||
}, | ||
|
||
buildRequests(validBidRequests, bidderRequest) { | ||
return validBidRequests.map((bidRequest) => { | ||
let referer = ''; | ||
if (bidderRequest && bidderRequest.refererInfo) { | ||
referer = bidderRequest.refererInfo.referer || ''; | ||
} | ||
const ret = { | ||
url: `${this.orbidderHost}/bid`, | ||
method: 'POST', | ||
data: { | ||
pageUrl: referer, | ||
bidId: bidRequest.bidId, | ||
auctionId: bidRequest.auctionId, | ||
transactionId: bidRequest.transactionId, | ||
adUnitCode: bidRequest.adUnitCode, | ||
sizes: bidRequest.sizes, | ||
params: bidRequest.params | ||
} | ||
}; | ||
if (bidRequest && bidRequest.gdprConsent) { | ||
ret.data.gdprConsent = { | ||
consentString: bidRequest.gdprConsent.consentString, | ||
consentRequired: (typeof bidRequest.gdprConsent.gdprApplies === 'boolean') | ||
? bidRequest.gdprConsent.gdprApplies | ||
: true | ||
}; | ||
} | ||
return ret; | ||
}); | ||
}, | ||
|
||
interpretResponse(serverResponse) { | ||
const bidResponses = []; | ||
serverResponse = serverResponse.body; | ||
if (serverResponse && (serverResponse.length > 0)) { | ||
serverResponse.forEach((bid) => { | ||
const bidResponse = {}; | ||
for (const requiredKey of ['requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', 'netRevenue', 'currency']) { | ||
if (!bid.hasOwnProperty(requiredKey)) { | ||
return []; | ||
} | ||
bidResponse[requiredKey] = bid[requiredKey]; | ||
} | ||
bidResponses.push(bidResponse); | ||
}); | ||
} | ||
return bidResponses; | ||
}, | ||
|
||
onBidWon(winObj) { | ||
const getRefererInfo = detectReferer(window); | ||
const refererInfo = getRefererInfo(); | ||
winObj.pageUrl = refererInfo.referer; | ||
ajax(`${this.orbidderHost}/win`, null, JSON.stringify(winObj)); | ||
} | ||
}; | ||
|
||
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,26 @@ | ||
#Overview | ||
|
||
``` | ||
Module Name: Orbidder Bid Adapter | ||
Module Type: Bidder Adapter | ||
Maintainer: orbidder@otto.de | ||
``` | ||
|
||
# Description | ||
|
||
Module that connects to orbidder demand sources | ||
|
||
# Test Parameters | ||
``` | ||
var adUnits = [{ | ||
code: '/105091519/bidder_test', | ||
mediaTypes: { | ||
banner: { | ||
sizes: [728, 90] | ||
} | ||
}, | ||
bids: [{ | ||
bidder: 'orbidder' | ||
}] | ||
}]; | ||
``` |
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,195 @@ | ||
import {expect} from 'chai'; | ||
import {spec} from 'modules/orbidderBidAdapter'; | ||
import {newBidder} from 'src/adapters/bidderFactory'; | ||
import * as ajax from 'src/ajax'; | ||
|
||
describe('orbidderBidAdapter', () => { | ||
const adapter = newBidder(spec); | ||
const bidRequest = { | ||
bidId: 'd66fa86787e0b0ca900a96eacfd5f0bb', | ||
auctionId: 'ccc4c7cdfe11cfbd74065e6dd28413d8', | ||
transactionId: 'd58851660c0c4461e4aa06344fc9c0c6', | ||
adUnitCode: 'adunit-code', | ||
sizes: [[300, 250], [300, 600]], | ||
params: { | ||
'foo': 'bar' | ||
} | ||
}; | ||
|
||
const buildRequest = function (buildRequest) { | ||
return spec.buildRequests( | ||
[buildRequest], | ||
{ | ||
refererInfo: { | ||
referer: 'http://localhost:9876/' | ||
} | ||
})[0]; | ||
} | ||
|
||
describe('inherited functions', () => { | ||
it('exists and is a function', () => { | ||
expect(adapter.callBids).to.exist.and.to.be.a('function'); | ||
}); | ||
}); | ||
|
||
describe('isBidRequestValid', () => { | ||
it('should return true when required params found', () => { | ||
expect(spec.isBidRequestValid(bidRequest)).to.equal(true); | ||
}); | ||
|
||
it('should return false when required params are not passed', () => { | ||
let bidRequest = Object.assign({}, bidRequest); | ||
delete bidRequest.params; | ||
expect(spec.isBidRequestValid(bidRequest)).to.equal(false); | ||
}); | ||
}); | ||
|
||
describe('buildRequests', () => { | ||
const request = buildRequest(bidRequest); | ||
|
||
it('sends bid request to endpoint via https using post', () => { | ||
expect(request.method).to.equal('POST'); | ||
expect(request.url.indexOf('https://')).to.equal(0); | ||
expect(request.url).to.equal(`${spec.orbidderHost}/bid`); | ||
}); | ||
|
||
it('sends correct bid parameters', () => { | ||
// we add one, because we add referer information from bidderRequest object | ||
expect(Object.keys(request.data).length).to.equal(Object.keys(bidRequest).length + 1); | ||
expect(request.data.pageUrl).to.equal('http://localhost:9876/'); | ||
// expect(request.data.referrer).to.equal(''); | ||
Object.keys(bidRequest).forEach((key) => { | ||
expect(bidRequest[key]).to.equal(request.data[key]); | ||
}); | ||
}); | ||
|
||
it('handles empty gdpr object', () => { | ||
let bidRequest = Object.assign({}, bidRequest); | ||
bidRequest.gdprConsent = {}; | ||
|
||
const request = buildRequest(bidRequest); | ||
expect(request.data.gdprConsent.consentRequired).to.be.equal(true); | ||
}); | ||
|
||
it('handles non-existent gdpr object', () => { | ||
let bidRequest = Object.assign({}, bidRequest); | ||
bidRequest.gdprConsent = null; | ||
|
||
const request = buildRequest(bidRequest); | ||
expect(request.data.gdprConsent).to.be.undefined; | ||
}); | ||
|
||
it('handles properly filled gdpr object where gdpr applies', () => { | ||
const consentString = 'someWeirdString'; | ||
const bidRequest = Object.assign({}, bidRequest); | ||
bidRequest.gdprConsent = { | ||
gdprApplies: true, | ||
consentString: 'someWeirdString' | ||
}; | ||
|
||
const request = buildRequest(bidRequest); | ||
const gdprConsent = request.data.gdprConsent; | ||
expect(gdprConsent.consentRequired).to.be.equal(true); | ||
expect(gdprConsent.consentString).to.be.equal(consentString); | ||
}); | ||
|
||
it('handles properly filled gdpr object where gdpr does not apply', () => { | ||
const consentString = 'someWeirdString'; | ||
const bidRequest = Object.assign({}, bidRequest); | ||
bidRequest.gdprConsent = { | ||
gdprApplies: false, | ||
consentString: 'someWeirdString' | ||
}; | ||
|
||
const request = buildRequest(bidRequest); | ||
const gdprConsent = request.data.gdprConsent; | ||
expect(gdprConsent.consentRequired).to.be.equal(false); | ||
expect(gdprConsent.consentString).to.be.equal(consentString); | ||
}); | ||
}); | ||
|
||
describe('onBidWon', () => { | ||
let ajaxStub; | ||
const winObj = { | ||
test: 1, | ||
pageUrl: 'www.someurl.de', | ||
referrer: 'www.somereferrer.de' | ||
}; | ||
|
||
beforeEach(() => { | ||
ajaxStub = sinon.stub(ajax, 'ajax'); | ||
}); | ||
|
||
afterEach(() => { | ||
ajaxStub.restore(); | ||
}); | ||
|
||
it('calls orbidder\'s win endpoint', () => { | ||
spec.onBidWon(winObj); | ||
expect(ajaxStub.calledOnce).to.equal(true); | ||
expect(ajaxStub.firstCall.args[0].indexOf('https://')).to.equal(0); | ||
expect(ajaxStub.firstCall.args[0]).to.equal(`${spec.orbidderHost}/win`); | ||
expect(ajaxStub.firstCall.args[2]).to.equal(JSON.stringify(winObj)); | ||
}); | ||
}); | ||
|
||
describe('interpretResponse', () => { | ||
it('should get correct bid response', () => { | ||
const serverResponse = [ | ||
{ | ||
'width': 300, | ||
'height': 250, | ||
'creativeId': '29681110', | ||
'ad': '<!-- Creative -->', | ||
'cpm': 0.5, | ||
'requestId': '30b31c1838de1e', | ||
'ttl': 60, | ||
'netRevenue': true, | ||
'currency': 'EUR' | ||
} | ||
]; | ||
|
||
const expectedResponse = [ | ||
{ | ||
'requestId': '30b31c1838de1e', | ||
'cpm': 0.5, | ||
'creativeId': '29681110', | ||
'width': 300, | ||
'height': 250, | ||
'ttl': 60, | ||
'currency': 'EUR', | ||
'ad': '<!-- Creative -->', | ||
'netRevenue': true | ||
} | ||
]; | ||
|
||
const result = spec.interpretResponse({body: serverResponse}); | ||
|
||
expect(result.length).to.equal(expectedResponse.length); | ||
Object.keys(expectedResponse[0]).forEach((key) => { | ||
expect(result[0][key]).to.equal(expectedResponse[0][key]); | ||
}); | ||
}); | ||
|
||
it('handles broken server response', () => { | ||
const serverResponse = [ | ||
{ | ||
'ad': '<!-- Creative -->', | ||
'cpm': 0.5, | ||
'requestId': '30b31c1838de1e', | ||
'ttl': 60 | ||
} | ||
]; | ||
const result = spec.interpretResponse({body: serverResponse}); | ||
|
||
expect(result.length).to.equal(0); | ||
}); | ||
|
||
it('handles nobid responses', () => { | ||
const serverResponse = []; | ||
const result = spec.interpretResponse({body: serverResponse}); | ||
|
||
expect(result.length).to.equal(0); | ||
}); | ||
}); | ||
}); |