Skip to content

Commit

Permalink
New Orbidder Prebid Adapter (#3434)
Browse files Browse the repository at this point in the history
* 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 idettman committed Jan 15, 2019
1 parent 339c93d commit 937ea8a
Show file tree
Hide file tree
Showing 3 changed files with 298 additions and 0 deletions.
77 changes: 77 additions & 0 deletions modules/orbidderBidAdapter.js
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);
26 changes: 26 additions & 0 deletions modules/orbidderBidAdapter.md
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'
}]
}];
```
195 changes: 195 additions & 0 deletions test/spec/modules/orbidderBidAdapter_spec.js
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);
});
});
});

0 comments on commit 937ea8a

Please sign in to comment.