Skip to content

Commit

Permalink
Performax Bid Adapter: New bidder adapter (prebid#11325)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukashakl authored and f.caspar committed May 14, 2024
1 parent 179010a commit 8db660c
Show file tree
Hide file tree
Showing 3 changed files with 288 additions and 0 deletions.
77 changes: 77 additions & 0 deletions modules/performaxBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { deepSetValue, deepAccess } from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER } from '../src/mediaTypes.js'
import { ortbConverter } from '../libraries/ortbConverter/converter.js';

const BIDDER_CODE = 'performax';
const BIDDER_SHORT_CODE = 'px';
const GVLID = 732
const ENDPOINT = 'https://dale.performax.cz/ortb'
export const converter = ortbConverter({

imp(buildImp, bidRequest, context) {
const imp = buildImp(bidRequest, context);
deepSetValue(imp, 'tagid', bidRequest.params.tagid);
return imp;
},

bidResponse(buildBidResponse, bid, context) {
context.netRevenue = deepAccess(bid, 'netRevenue');
context.mediaType = deepAccess(bid, 'mediaType');
context.currency = deepAccess(bid, 'currency');

return buildBidResponse(bid, context)
},

context: {
ttl: 360,
}
})

export const spec = {
code: BIDDER_CODE,
aliases: [BIDDER_SHORT_CODE],
gvlid: GVLID,
supportedMediaTypes: [BANNER],

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

buildRequests: function (bidRequests, bidderRequest) {
let data = converter.toORTB({bidderRequest, bidRequests})
return [{
method: 'POST',
url: ENDPOINT,
options: {'contentType': 'application/json'},
data: data
}]
},

interpretResponse: function (bidderResponse, request) {
if (!bidderResponse.body) return [];
const response = bidderResponse.body
const data = {

seatbid: response.seatbid.map(seatbid => ({
seat: seatbid.seat,
bid: seatbid.bid.map(bid => ({
impid: bid.imp_id,
w: bid.w,
h: bid.h,
requestId: request.data.id,
price: bid.price,
currency: response.cur,
adm: bid.adm,
crid: bid.id,
netRevenue: true,
mediaType: BANNER,
}))
}))
};
return converter.fromORTB({ response: data, request: request.data }).bids
},

}

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: development@performax.cz
```

# Description

Connects to Performax exchange for bids.

Performax bid adapter supports Banner.


# Sample Banner Ad Unit: For Publishers

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

175 changes: 175 additions & 0 deletions test/spec/modules/performaxBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import { expect } from 'chai';
import { spec, converter } from 'modules/performaxBidAdapter.js';

describe('Performax adapter', function () {
let bids = [{
bidder: 'performax',
params: {
tagid: 'sample'
},
ortb2Imp: {
ext: {}
},
mediaTypes: {
banner: {
sizes: [
[300, 300],
]}},
adUnitCode: 'postbid_iframe',
transactionId: '84deda92-e9ba-4b0d-a797-43be5e522430',
adUnitId: '4ee4643b-931f-4a17-a571-ccba57886dc8',
sizes: [
[300, 300],
],
bidId: '2bc545c347dbbe',
bidderRequestId: '1534dec005b9a',
auctionId: 'acd97e55-01e1-45ad-813c-67fa27fc5c1b',
src: 'client',
bidRequestsCount: 1,
bidderRequestsCount: 1,
bidderWinsCount: 0,
ortb2: {
source: {},
site: {},
device: {}
},
},

{
bidder: 'performax',
params: {
tagid: '1545'
},
ortb2Imp: {
ext: {}
},
mediaTypes: {
banner: {
sizes: [
[300, 600],
]}},
adUnitCode: 'postbid_halfpage_iframe',
transactionId: '84deda92-e9ba-4b0d-a797-43be5e522430',
adUnitId: '4ee4643b-931f-4a17-a571-ccba57886dc8',
sizes: [
[300, 600],
],
bidId: '3dd53d30c691fe',
bidderRequestId: '1534dec005b9a',
auctionId: 'acd97e55-01e1-45ad-813c-67fa27fc5c1b',
src: 'client',
bidRequestsCount: 1,
bidderRequestsCount: 1,
bidderWinsCount: 0,
ortb2: {
source: {},
site: {},
device: {}
}}];

let bidderRequest = {
bidderCode: 'performax2',
auctionId: 'acd97e55-01e1-45ad-813c-67fa27fc5c1b',
id: 'acd97e55-01e1-45ad-813c-67fa27fc5c1b',
bidderRequestId: '1534dec005b9a',
bids: bids,
ortb2: {
regs: {
ext: {
gdpr: 1
}},
user: {
ext: {
consent: 'consent-string'
}
},
site: {},
device: {}
}};

let serverResponse = {
body: {
cur: 'CZK',
seatbid: [
{
seat: 'performax',
bid: [
{
id: 'sample',
price: 20,
w: 300,
h: 300,
adm: 'My ad'
}
]}]},
}

describe('isBidRequestValid', function () {
let bid = {};
it('should return false when missing "tagid" param', function() {
bid.params = {slotId: 'param'};
expect(spec.isBidRequestValid(bid)).to.equal(false);
bid.params = {};
expect(spec.isBidRequestValid(bid)).to.equal(false);
});

it('should return true when tagid is correct', function() {
bid.params = {tagid: 'sample'};
expect(spec.isBidRequestValid(bid)).to.equal(true);
});
})

describe('buildRequests', function () {
it('should set correct request method and url', function () {
let requests = spec.buildRequests([bids[0]], bidderRequest);
expect(requests).to.be.an('array').that.has.lengthOf(1);
let request = requests[0];
expect(request.method).to.equal('POST');
expect(request.url).to.equal('https://dale.performax.cz/ortb');
expect(request.data).to.be.an('object');
});

it('should pass correct imp', function () {
let requests = spec.buildRequests([bids[0]], bidderRequest);
let {data} = requests[0];
let {imp} = data;
expect(imp).to.be.an('array').that.has.lengthOf(1);
expect(imp[0]).to.be.an('object');
let bid = imp[0];
expect(bid.id).to.equal('2bc545c347dbbe');
expect(bid.banner).to.deep.equal({topframe: 0, format: [{w: 300, h: 300}]});
});

it('should process multiple bids', function () {
let requests = spec.buildRequests(bids, bidderRequest);
expect(requests).to.be.an('array').that.has.lengthOf(1);
let {data} = requests[0];
let {imp} = data;
expect(imp).to.be.an('array').that.has.lengthOf(bids.length);
let bid1 = imp[0];
expect(bid1.banner).to.deep.equal({topframe: 0, format: [{w: 300, h: 300}]});
let bid2 = imp[1];
expect(bid2.banner).to.deep.equal({topframe: 0, format: [{w: 300, h: 600}]});
});
});

describe('interpretResponse', function () {
it('should map params correctly', function () {
let ortbRequest = {data: converter.toORTB({bidderRequest, bids})};
serverResponse.body.id = ortbRequest.data.id;
serverResponse.body.seatbid[0].bid[0].imp_id = ortbRequest.data.imp[0].id;

let result = spec.interpretResponse(serverResponse, ortbRequest);
expect(result).to.be.an('array').that.has.lengthOf(1);
let bid = result[0];

expect(bid.cpm).to.equal(20);
expect(bid.ad).to.equal('My ad');
expect(bid.currency).to.equal('CZK');
expect(bid.mediaType).to.equal('banner');
expect(bid.netRevenue).to.equal(true);
expect(bid.ttl).to.equal(360);
expect(bid.creativeId).to.equal('sample');
});
});
});

0 comments on commit 8db660c

Please sign in to comment.