Skip to content

Commit bef66ca

Browse files
nduitzChris Pabst
authored and
Chris Pabst
committed
Welect Bid Adapter: update prebid compliance and add adapter back to master (prebid#7776)
* readd welectBidAdapter * readd test * use es6 modules from utils
1 parent abc2881 commit bef66ca

File tree

2 files changed

+317
-0
lines changed

2 files changed

+317
-0
lines changed

modules/welectBidAdapter.js

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { deepAccess } from '../src/utils.js';
2+
import { registerBidder } from '../src/adapters/bidderFactory.js';
3+
4+
const BIDDER_CODE = 'welect';
5+
const DEFAULT_DOMAIN = 'www.welect.de';
6+
7+
export const spec = {
8+
code: BIDDER_CODE,
9+
aliases: ['wlt'],
10+
gvlid: 282,
11+
supportedMediaTypes: ['video'],
12+
13+
// short code
14+
/**
15+
* Determines whether or not the given bid request is valid.
16+
*
17+
* @param {BidRequest} bid The bid params to validate.
18+
* @return boolean True if this is a valid bid, and false otherwise.
19+
*/
20+
isBidRequestValid: function (bid) {
21+
return (
22+
deepAccess(bid, 'mediaTypes.video.context') === 'instream' &&
23+
!!bid.params.placementId
24+
);
25+
},
26+
/**
27+
* Make a server request from the list of BidRequests.
28+
*
29+
* @param {validBidRequests[]} - an array of bids
30+
* @return ServerRequest Info describing the request to the server.
31+
*/
32+
buildRequests: function (validBidRequests) {
33+
return validBidRequests.map((bidRequest) => {
34+
let rawSizes =
35+
deepAccess(bidRequest, 'mediaTypes.video.playerSize') ||
36+
bidRequest.sizes;
37+
let size = rawSizes[0];
38+
39+
let domain = bidRequest.params.domain || DEFAULT_DOMAIN;
40+
41+
let url = `https://${domain}/api/v2/preflight/${bidRequest.params.placementId}`;
42+
43+
let gdprConsent = null;
44+
45+
if (bidRequest && bidRequest.gdprConsent) {
46+
gdprConsent = {
47+
gdpr_consent: {
48+
gdprApplies: bidRequest.gdprConsent.gdprApplies,
49+
tcString: bidRequest.gdprConsent.gdprConsent,
50+
},
51+
};
52+
}
53+
54+
const data = {
55+
width: size[0],
56+
height: size[1],
57+
bid_id: bidRequest.bidId,
58+
...gdprConsent,
59+
};
60+
61+
return {
62+
method: 'POST',
63+
url: url,
64+
data: data,
65+
options: {
66+
contentType: 'application/json',
67+
withCredentials: false,
68+
crossOrigin: true,
69+
},
70+
};
71+
});
72+
},
73+
/**
74+
* Unpack the response from the server into a list of bids.
75+
*
76+
* @param {ServerResponse} serverResponse A successful response from the server.
77+
* @return {Bid[]} An array of bids which were nested inside the server.
78+
*/
79+
interpretResponse: function (serverResponse, bidRequest) {
80+
const responseBody = serverResponse.body;
81+
82+
if (typeof responseBody !== 'object' || responseBody.available !== true) {
83+
return [];
84+
}
85+
86+
const bidResponses = [];
87+
const bidResponse = {
88+
requestId: responseBody.bidResponse.requestId,
89+
cpm: responseBody.bidResponse.cpm,
90+
width: responseBody.bidResponse.width,
91+
height: responseBody.bidResponse.height,
92+
creativeId: responseBody.bidResponse.creativeId,
93+
currency: responseBody.bidResponse.currency,
94+
netRevenue: responseBody.bidResponse.netRevenue,
95+
ttl: responseBody.bidResponse.ttl,
96+
ad: responseBody.bidResponse.ad,
97+
vastUrl: responseBody.bidResponse.vastUrl,
98+
meta: {
99+
advertiserDomains: responseBody.bidResponse.meta.advertiserDomains
100+
}
101+
};
102+
bidResponses.push(bidResponse);
103+
return bidResponses;
104+
},
105+
};
106+
registerBidder(spec);
+211
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
import { expect } from 'chai';
2+
import { spec as adapter } from 'modules/welectBidAdapter.js';
3+
4+
describe('WelectAdapter', function () {
5+
describe('Check methods existance', function () {
6+
it('exists and is a function', function () {
7+
expect(adapter.isBidRequestValid).to.exist.and.to.be.a('function');
8+
});
9+
it('exists and is a function', function () {
10+
expect(adapter.buildRequests).to.exist.and.to.be.a('function');
11+
});
12+
it('exists and is a function', function () {
13+
expect(adapter.interpretResponse).to.exist.and.to.be.a('function');
14+
});
15+
});
16+
17+
describe('Check method isBidRequestValid return', function () {
18+
let bid = {
19+
bidder: 'welect',
20+
params: {
21+
placementId: 'exampleAlias',
22+
domain: 'www.welect.de'
23+
},
24+
sizes: [[640, 360]],
25+
mediaTypes: {
26+
video: {
27+
context: 'instream'
28+
}
29+
},
30+
};
31+
let bid2 = {
32+
bidder: 'welect',
33+
params: {
34+
domain: 'www.welect.de'
35+
},
36+
mediaTypes: {
37+
video: {
38+
context: 'instream',
39+
playerSize: [640, 360]
40+
}
41+
},
42+
};
43+
44+
it('should be true', function () {
45+
expect(adapter.isBidRequestValid(bid)).to.be.true;
46+
});
47+
48+
it('should be false because the placementId is missing', function () {
49+
expect(adapter.isBidRequestValid(bid2)).to.be.false;
50+
});
51+
});
52+
53+
describe('Check buildRequests method', function () {
54+
// Bids to be formatted
55+
let bid1 = {
56+
bidder: 'welect',
57+
params: {
58+
placementId: 'exampleAlias'
59+
},
60+
sizes: [[640, 360]],
61+
mediaTypes: {
62+
video: {
63+
context: 'instream'
64+
}
65+
},
66+
bidId: 'abdc'
67+
};
68+
let bid2 = {
69+
bidder: 'welect',
70+
params: {
71+
placementId: 'exampleAlias',
72+
domain: 'www.welect2.de'
73+
},
74+
sizes: [[640, 360]],
75+
mediaTypes: {
76+
video: {
77+
context: 'instream'
78+
}
79+
},
80+
bidId: 'abdc',
81+
gdprConsent: {
82+
gdprApplies: 1,
83+
gdprConsent: 'some_string'
84+
}
85+
};
86+
87+
let data1 = {
88+
bid_id: 'abdc',
89+
width: 640,
90+
height: 360
91+
}
92+
93+
let data2 = {
94+
bid_id: 'abdc',
95+
width: 640,
96+
height: 360,
97+
gdpr_consent: {
98+
gdprApplies: 1,
99+
tcString: 'some_string'
100+
}
101+
}
102+
103+
// Formatted requets
104+
let request1 = {
105+
method: 'POST',
106+
url: 'https://www.welect.de/api/v2/preflight/exampleAlias',
107+
data: data1,
108+
options: {
109+
contentType: 'application/json',
110+
withCredentials: false,
111+
crossOrigin: true,
112+
}
113+
};
114+
115+
let request2 = {
116+
method: 'POST',
117+
url: 'https://www.welect2.de/api/v2/preflight/exampleAlias',
118+
data: data2,
119+
options: {
120+
contentType: 'application/json',
121+
withCredentials: false,
122+
crossOrigin: true,
123+
}
124+
}
125+
126+
it('defaults to www.welect.de, without gdpr object', function () {
127+
expect(adapter.buildRequests([bid1])).to.deep.equal([request1]);
128+
})
129+
130+
it('must return the right formatted requests, with gdpr object', function () {
131+
expect(adapter.buildRequests([bid2])).to.deep.equal([request2]);
132+
});
133+
});
134+
135+
describe('Check interpretResponse method return', function () {
136+
// invalid server response
137+
let unavailableResponse = {
138+
body: {
139+
available: false
140+
}
141+
};
142+
143+
let availableResponse = {
144+
body: {
145+
available: true,
146+
bidResponse: {
147+
ad: {
148+
video: 'some vast url'
149+
},
150+
meta: {
151+
advertiserDomains: [],
152+
},
153+
cpm: 17,
154+
creativeId: 'svmpreview',
155+
currency: 'EUR',
156+
netRevenue: true,
157+
requestId: 'some bid id',
158+
ttl: 120,
159+
vastUrl: 'some vast url',
160+
height: 640,
161+
width: 320
162+
}
163+
}
164+
}
165+
// bid Request
166+
let bid = {
167+
data: {
168+
bid_id: 'some bid id',
169+
width: 640,
170+
height: 320,
171+
gdpr_consent: {
172+
gdprApplies: 1,
173+
tcString: 'some_string'
174+
}
175+
},
176+
method: 'POST',
177+
url: 'https://www.welect.de/api/v2/preflight/exampleAlias',
178+
options: {
179+
contentType: 'application/json',
180+
withCredentials: false,
181+
crossOrigin: true,
182+
}
183+
};
184+
// Formatted reponse
185+
let result = {
186+
ad: {
187+
video: 'some vast url'
188+
},
189+
meta: {
190+
advertiserDomains: []
191+
},
192+
cpm: 17,
193+
creativeId: 'svmpreview',
194+
currency: 'EUR',
195+
height: 640,
196+
netRevenue: true,
197+
requestId: 'some bid id',
198+
ttl: 120,
199+
vastUrl: 'some vast url',
200+
width: 320
201+
}
202+
203+
it('if response reflects unavailability, should be empty', function () {
204+
expect(adapter.interpretResponse(unavailableResponse, bid)).to.deep.equal([]);
205+
});
206+
207+
it('if response reflects availability, should equal result', function () {
208+
expect(adapter.interpretResponse(availableResponse, bid)).to.deep.equal([result])
209+
})
210+
});
211+
});

0 commit comments

Comments
 (0)