Skip to content

Commit

Permalink
New Bid adapter: Performax (#5480)
Browse files Browse the repository at this point in the history
* Performax adapater

* Repair md

* Remove unused functions, change to singlequoutes

Co-authored-by: VasekProchazka <[email protected]>
  • Loading branch information
VasekProchazka and VasekProchazka authored Jul 17, 2020
1 parent bab94f0 commit b25e57d
Show file tree
Hide file tree
Showing 3 changed files with 366 additions and 0 deletions.
56 changes: 56 additions & 0 deletions modules/performaxBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {logWarn} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';

const CLIENT = 'hellboy:v0.0.1'
const BIDDER_CODE = 'performax';
const BIDDER_SHORT_CODE = 'px';
const ENDPOINT = 'https://dale.performax.cz/hb';

export const spec = {
code: BIDDER_CODE,
aliases: [BIDDER_SHORT_CODE],

isBidRequestValid: function (bid) {
return !!bid.params.slotId;
},

buildUrl: function (validBidRequests, bidderRequest) {
const slotIds = validBidRequests.map(request => request.params.slotId);
let url = [`${ENDPOINT}?slotId[]=${slotIds.join()}`];
url.push('client=' + CLIENT);
url.push('auctionId=' + bidderRequest.auctionId);
return url.join('&');
},

buildRequests: function (validBidRequests, bidderRequest) {
return {
method: 'POST',
url: this.buildUrl(validBidRequests, bidderRequest),
data: {'validBidRequests': validBidRequests, 'bidderRequest': bidderRequest},
options: {contentType: 'application/json'},
}
},

buildHtml: function (ad) {
const keys = Object.keys(ad.data || {});
return ad.code.replace(
new RegExp('\\$(' + keys.join('|') + ')\\$', 'g'),
(matched, key) => ad.data[key] || matched
);
},

interpretResponse: function (serverResponse, request) {
let bidResponses = [];
for (let i = 0; i < serverResponse.body.length; i++) {
const ad = serverResponse.body[i].ad;
if (ad.type === 'empty') {
logWarn(`One of ads is empty (reason=${ad.reason})`);
continue;
}
serverResponse.body[i].ad = this.buildHtml(ad);
bidResponses.push(serverResponse.body[i]);
}
return bidResponses;
}
}
registerBidder(spec);
36 changes: 36 additions & 0 deletions modules/performaxBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Overview

```
Module Name: Performax Bid Adapter
Module Type: Bidder Adapter
Maintainer: [email protected]
```

# Description

Connects to Performax exchange for bids.

Performax bid adapter supports Banner.


# Sample Banner Ad Unit: For Publishers

```javascript
var adUnits = [
{
code: 'performax-div',
sizes: [[300, 300]],
bids: [
{
bidder: "performax",
params: {
slotId: 28 // required
}
}
]
}
];
```

Where:
* slotId - id of slot in PX system
274 changes: 274 additions & 0 deletions test/spec/modules/performaxBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
import * as utils from 'src/utils.js';
import { expect } from 'chai';
import { spec } from 'modules/performaxBidAdapter';

describe('PerformaxAdapter', function () {
let bidRequests, bidderRequest;
let serverResponse, serverRequest;

const URL =
'https://dale.performax.cz/hb?slotId[]=3,2&client=hellboy:v0.0.1&auctionId=144b5079-8cbf-49a5-aca7-a68b3296cd6c';

bidRequests = [
{
adUnitCode: 'postbid_iframe',
auctionId: '144b5079-8cbf-49a5-aca7-a68b3296cd6c',
bidId: '2a4332f6b2bc74',
bidRequestsCount: 1,
bidder: 'performax',
bidderRequestId: '1c7d8bf204f11e',
bidderRequestsCount: 1,
bidderWinsCount: 0,
mediaTypes: {
banner: {
sizes: [[300, 300]],
},
},
params: {
slotId: 3,
},
sizes: [[300, 300]],
src: 'client',
transactionId: '14969d09-0068-4d5b-a34e-e35091561dee',
},
{
adUnitCode: 'postbid_iframe2',
auctionId: '144b5079-8cbf-49a5-aca7-a68b3296cd6c',
bidId: '300bb0ac6a156a',
bidRequestsCount: 1,
bidder: 'performax',
bidderRequestId: '1c7d8bf204f11e',
bidderRequestsCount: 1,
bidderWinsCount: 0,
mediaTypes: {
banner: {
sizes: [[300, 300]],
},
},
params: {
slotId: 2,
},
sizes: [[300, 300]],
src: 'client',
transactionId: '107cbebd-8c36-4456-b28c-91a19ba80151',
},
];

bidderRequest = {
auctionId: '144b5079-8cbf-49a5-aca7-a68b3296cd6c',
auctionStart: 1594281941845,
bidderCode: 'performax',
bidderRequestId: '1c7d8bf204f11e',
bids: bidRequests,
refererInfo: {
canonicalUrl: '',
numIframes: 0,
reachedTop: true,
referer: '',
},
stack: [''],
start: 1594281941935,
timeout: 3600,
};

serverResponse = {
body: [
{
ad: {
code: '$SYS_ID$ $VAR_NAME$ rest of the code',
data: {
SYS_ID: 1,
VAR_NAME: 'name',
},
format_id: 2,
id: 11,
size: {
width: 300,
height: 300,
},
tag_ids: [],
type: 'creative',
},
cpm: 30,
creativeId: 'creative:11',
currency: 'CZK',
height: 300,
meta: {
agencyId: 1,
mediaType: 'banner',
},
netRevenue: true,
requestId: '2a4332f6b2bc74',
ttl: 60,
width: 300,
},
{
ad: {
code: '<!-- px empty -->',
reason: 'Slot 2 does not allow HB requests',
type: 'empty',
},
cpm: 0,
creativeId: null,
currency: 'CZK',
height: null,
meta: {
agencyId: null,
mediaType: 'banner',
},
netRevenue: true,
requestId: '1c7d8bf204f11e',
ttl: 60,
width: 300,
},
],
};

serverRequest = {
data: {
bidderRequest: bidderRequest,
validBidRequests: bidRequests,
},
method: 'POST',
options: {
contentType: 'application/json',
},
url: URL,
};

describe('Bid validations', function () {
it('Valid bid', function () {
let validBid = {
bidder: 'performax',
params: {
slotId: 2,
},
},
isValid = spec.isBidRequestValid(validBid);
expect(isValid).to.equal(true);
});

it('Invalid bid: required param is missing', function () {
let invalidBid = {
bidder: 'performax',
params: {
invalidParam: 2,
},
},
isValid = spec.isBidRequestValid(invalidBid);
expect(isValid).to.equal(false);
});
});

describe('Build Url', function () {
it('Should return url', function () {
let url = spec.buildUrl(bidRequests, bidderRequest);
expect(url).to.equal(URL);
});
});

describe('Build Request', function () {
it('Should not modify bidRequests and bidder Requests', function () {
let originalBidRequests = utils.deepClone(bidRequests);
let originalBidderRequest = utils.deepClone(bidderRequest);
let request = spec.buildRequests(bidRequests, bidderRequest);

expect(bidRequests).to.deep.equal(originalBidRequests);
expect(bidderRequest).to.deep.equal(originalBidderRequest);
});

it('Endpoint checking', function () {
let request = spec.buildRequests(bidRequests, bidderRequest);
expect(request.url).to.equal(URL);
expect(request.method).to.equal('POST');
expect(request.options).to.deep.equal({
contentType: 'application/json',
});
});

it('Request params checking', function () {
let request = spec.buildRequests(bidRequests, bidderRequest);
expect(request.data.validBidRequests).to.deep.equal(bidRequests);
expect(request.data.bidderRequest).to.deep.equal(bidderRequest);
});
});

describe('Build Html', function () {
it('Ad with data: should return build html', function () {
let validAd = {
code: '$SYS_ID$ $VAR_NAME$ rest of the code',
data: {
SYS_ID: 1,
VAR_NAME: 'name',
},
format_id: 2,
id: 11,
size: {
width: 300,
height: 300,
},
tag_ids: [],
type: 'creative',
};
let html = spec.buildHtml(validAd);
expect(html).to.equal('1 name rest of the code');
});

it('Ad with partial data: should return html without data change', function () {
let adWithPartialData = {
code: '$SYS_ID$ $VAR_NAME$ rest of the code',
data: {
VAR_NAME: 'name',
},
format_id: 2,
id: 11,
size: {
width: 300,
height: 300,
},
tag_ids: [],
type: 'creative',
};
let html = spec.buildHtml(adWithPartialData);
expect(html).to.equal('$SYS_ID$ name rest of the code');
});

it('Ad without data: should return html without data change', function () {
let adWithoutData = {
code: '$SYS_ID$ $VAR_NAME$ rest of the code',
format_id: 2,
id: 11,
size: {
width: 300,
height: 300,
},
tag_ids: [],
type: 'creative',
};
let html = spec.buildHtml(adWithoutData);
expect(html).to.equal('$SYS_ID$ $VAR_NAME$ rest of the code');
});
});

describe('Interpret Response', function () {
it('Ad without data: should return html without data change', function () {
let ads = spec.interpretResponse(serverResponse, serverRequest);
expect(ads).to.have.length(1);
expect(ads[0]).to.deep.equal({
ad: '1 name rest of the code',
cpm: 30,
creativeId: 'creative:11',
currency: 'CZK',
height: 300,
meta: {
agencyId: 1,
mediaType: 'banner',
},
netRevenue: true,
requestId: '2a4332f6b2bc74',
ttl: 60,
width: 300,
});
});
});
});

0 comments on commit b25e57d

Please sign in to comment.