Skip to content

Commit be43c55

Browse files
agon-qurdinaMatt Kendall
authored and
Matt Kendall
committed
Gjirafa Bidder Adapter (#1944)
* Added Gjirafa adapter * Add gjirafa adapter unit test * adapter update * New line * Requested changes * change hello_world.html to one bid * change hello_world.html to one bid * Dropping changes in gitignore and hello_world example * hello_world changes * Drop hello_world and gitignore
1 parent 8e3047b commit be43c55

File tree

3 files changed

+283
-0
lines changed

3 files changed

+283
-0
lines changed

modules/gjirafaBidAdapter.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import * as utils from 'src/utils';
2+
import {registerBidder} from 'src/adapters/bidderFactory';
3+
4+
const BIDDER_CODE = 'gjirafa';
5+
const ENDPOINT_URL = 'https://gjc.gjirafa.com/Home/GetBid';
6+
const DIMENSION_SEPARATOR = 'x';
7+
const SIZE_SEPARATOR = ';';
8+
9+
export const spec = {
10+
code: BIDDER_CODE,
11+
/**
12+
* Determines whether or not the given bid request is valid.
13+
*
14+
* @param {BidRequest} bid The bid params to validate.
15+
* @return boolean True if this is a valid bid, and false otherwise.
16+
*/
17+
isBidRequestValid: function(bid) {
18+
return bid.params && (!!bid.params.placementId || (!!bid.params.minCPM && !!bid.params.minCPC));
19+
},
20+
/**
21+
* Make a server request from the list of BidRequests.
22+
*
23+
* @param {validBidRequests[]} - an array of bids
24+
* @return ServerRequest Info describing the request to the server.
25+
*/
26+
buildRequests: function(validBidRequests, bidderRequest) {
27+
return validBidRequests.map(bidRequest => {
28+
let gjid = Math.floor(Math.random() * 99999999);
29+
let sizes = generateSizeParam(bidRequest.sizes);
30+
let configId = bidRequest.params.placementId || '';
31+
let minCPM = bidRequest.params.minCPM || 0.0;
32+
let minCPC = bidRequest.params.minCPC || 0.0;
33+
let allowExplicit = bidRequest.params.explicit || 0;
34+
const body = {
35+
gjid: gjid,
36+
sizes: sizes,
37+
configId: configId,
38+
minCPM: minCPM,
39+
minCPC: minCPC,
40+
allowExplicit: allowExplicit,
41+
referrer: utils.getTopWindowUrl(),
42+
requestid: bidRequest.bidderRequestId,
43+
bidid: bidRequest.bidId
44+
};
45+
if (document.referrer) {
46+
body.referrer = document.referrer;
47+
}
48+
return {
49+
method: 'GET',
50+
url: ENDPOINT_URL,
51+
data: body
52+
};
53+
});
54+
},
55+
/**
56+
* Unpack the response from the server into a list of bids.
57+
*
58+
* @param {ServerResponse} serverResponse A successful response from the server.
59+
* @return {Bid[]} An array of bids which were nested inside the server.
60+
*/
61+
interpretResponse: function(serverResponse, bidRequest) {
62+
const serverBody = serverResponse.body;
63+
const bidResponses = [];
64+
const bidResponse = {
65+
requestId: bidRequest.data.bidid,
66+
cpm: serverBody.CPM,
67+
width: serverBody.Width,
68+
height: serverBody.Height,
69+
creativeId: serverBody.CreativeId,
70+
currency: serverBody.Currency,
71+
netRevenue: serverBody.NetRevenue,
72+
ttl: serverBody.TTL,
73+
referrer: serverBody.Referrer,
74+
ad: serverBody.Ad
75+
};
76+
bidResponses.push(bidResponse);
77+
return bidResponses;
78+
}
79+
}
80+
81+
/**
82+
* Generate size param for bid request using sizes array
83+
*
84+
* @param {Array} sizes Possible sizes for the ad unit.
85+
* @return {string} Processed sizes param to be used for the bid request.
86+
*/
87+
function generateSizeParam(sizes) {
88+
return sizes.map(size => size.join(DIMENSION_SEPARATOR)).join(SIZE_SEPARATOR);
89+
}
90+
91+
registerBidder(spec);

modules/gjirafaBidAdapter.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Overview
2+
Module Name: Gjirafa Bidder Adapter Module
3+
Type: Bidder Adapter
4+
Maintainer: [email protected]
5+
6+
# Description
7+
Gjirafa Bidder Adapter for Prebid.js.
8+
9+
# Test Parameters
10+
var adUnits = [
11+
{
12+
code: 'test-div',
13+
sizes: [[728, 90]], // leaderboard
14+
bids: [
15+
{
16+
bidder: 'gjirafa',
17+
params: {
18+
placementId: '71-3'
19+
}
20+
}
21+
]
22+
},{
23+
code: 'test-div',
24+
sizes: [[300, 250]], // mobile rectangle
25+
bids: [
26+
{
27+
bidder: 'gjirafa',
28+
params: {
29+
minCPM: 0.0001,
30+
minCPC: 0.001,
31+
explicit: true
32+
}
33+
}
34+
]
35+
}
36+
];
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import { expect } from 'chai';
2+
import { spec } from 'modules/gjirafaBidAdapter';
3+
4+
describe('gjirafaAdapterTest', () => {
5+
describe('bidRequestValidity', () => {
6+
it('bidRequest with placementId, minCPM and minCPC params', () => {
7+
expect(spec.isBidRequestValid({
8+
bidder: 'gjirafa',
9+
params: {
10+
placementId: 'test-div',
11+
minCPM: 0.0001,
12+
minCPC: 0.001
13+
}
14+
})).to.equal(true);
15+
});
16+
17+
it('bidRequest with only placementId param', () => {
18+
expect(spec.isBidRequestValid({
19+
bidder: 'gjirafa',
20+
params: {
21+
placementId: 'test-div'
22+
}
23+
})).to.equal(true);
24+
});
25+
26+
it('bidRequest with minCPM and minCPC params', () => {
27+
expect(spec.isBidRequestValid({
28+
bidder: 'gjirafa',
29+
params: {
30+
minCPM: 0.0001,
31+
minCPC: 0.001
32+
}
33+
})).to.equal(true);
34+
});
35+
36+
it('bidRequest with no placementId, minCPM or minCPC params', () => {
37+
expect(spec.isBidRequestValid({
38+
bidder: 'gjirafa',
39+
params: {
40+
}
41+
})).to.equal(false);
42+
});
43+
});
44+
45+
describe('bidRequest', () => {
46+
const bidRequests = [{
47+
'bidder': 'gjirafa',
48+
'params': {
49+
'placementId': '71-3'
50+
},
51+
'adUnitCode': 'hb-leaderboard',
52+
'transactionId': 'b6b889bb-776c-48fd-bc7b-d11a1cf0425e',
53+
'sizes': [[728, 90], [980, 200], [980, 150], [970, 90], [970, 250]],
54+
'bidId': '10bdc36fe0b48c8',
55+
'bidderRequestId': '70deaff71c281d',
56+
'auctionId': 'f9012acc-b6b7-4748-9098-97252914f9dc'
57+
},
58+
{
59+
'bidder': 'gjirafa',
60+
'params': {
61+
'minCPM': 0.0001,
62+
'minCPC': 0.001,
63+
'explicit': true
64+
},
65+
'adUnitCode': 'hb-inarticle',
66+
'transactionId': '8757194d-ea7e-4c06-abc0-cfe92bfc5295',
67+
'sizes': [[300, 250]],
68+
'bidId': '81a6dcb65e2bd9',
69+
'bidderRequestId': '70deaff71c281d',
70+
'auctionId': 'f9012acc-b6b7-4748-9098-97252914f9dc'
71+
}];
72+
73+
it('bidRequest HTTP method', () => {
74+
const requests = spec.buildRequests(bidRequests);
75+
requests.forEach(function(requestItem) {
76+
expect(requestItem.method).to.equal('GET');
77+
});
78+
});
79+
80+
it('bidRequest url', () => {
81+
const endpointUrl = 'https://gjc.gjirafa.com/Home/GetBid';
82+
const requests = spec.buildRequests(bidRequests);
83+
requests.forEach(function(requestItem) {
84+
expect(requestItem.url).to.match(new RegExp(`${endpointUrl}`));
85+
});
86+
});
87+
88+
it('bidRequest data', () => {
89+
const requests = spec.buildRequests(bidRequests);
90+
requests.forEach(function(requestItem) {
91+
expect(requestItem.data).to.exists;
92+
});
93+
});
94+
95+
it('bidRequest sizes', () => {
96+
const requests = spec.buildRequests(bidRequests);
97+
expect(requests[0].data.sizes).to.equal('728x90;980x200;980x150;970x90;970x250');
98+
expect(requests[1].data.sizes).to.equal('300x250');
99+
});
100+
});
101+
102+
describe('interpretResponse', () => {
103+
const bidRequest = {
104+
'method': 'GET',
105+
'url': 'https://gjc.gjirafa.com/Home/GetBid',
106+
'data': {
107+
'gjid': 2323007,
108+
'sizes': '728x90;980x200;980x150;970x90;970x250',
109+
'configId': '71-3',
110+
'minCPM': 0,
111+
'minCPC': 0,
112+
'allowExplicit': 0,
113+
'referrer': 'http://localhost:9999/integrationExamples/gpt/hello_world.html?pbjs_debug=true',
114+
'requestid': '26ee8fe87940da7',
115+
'bidid': '2962dbedc4768bf'
116+
}
117+
};
118+
119+
const bidResponse = {
120+
body: [{
121+
'CPM': 1,
122+
'Width': 728,
123+
'Height': 90,
124+
'Referrer': 'https://example.com/',
125+
'Ad': 'test ad',
126+
'CreativeId': '123abc',
127+
'NetRevenue': false,
128+
'Currency': 'EUR',
129+
'TTL': 360
130+
}],
131+
headers: {}
132+
};
133+
134+
it('all keys present', () => {
135+
const result = spec.interpretResponse(bidResponse, bidRequest);
136+
137+
let keys = [
138+
'requestId',
139+
'cpm',
140+
'width',
141+
'height',
142+
'creativeId',
143+
'currency',
144+
'netRevenue',
145+
'ttl',
146+
'referrer',
147+
'ad'
148+
];
149+
150+
let resultKeys = Object.keys(result[0]);
151+
resultKeys.forEach(function(key) {
152+
expect(keys.indexOf(key) !== -1).to.equal(true);
153+
});
154+
})
155+
});
156+
});

0 commit comments

Comments
 (0)