Skip to content

Commit a544ab9

Browse files
vadim-mazzherinveranevera
authored andcommitted
ShowHeroes adapter v2 (prebid#5085)
* add ShowHeroes Adapter * ShowHeroes adapter - expanded outstream support * Revert "ShowHeroes adapter - expanded outstream support" This reverts commit bfcdb91. * ShowHeroes adapter - expanded outstream support * ShowHeroes adapter - fixes (prebid#4222) * ShowHeroes adapter - banner and outstream fixes (prebid#4222) * ShowHeroes adapter - description and outstream changes (prebid#4222) * ShowHeroes adapter - increase test coverage and small fix * ShowHeroes Adapter - naming convention issue * Mixed AdUnits declaration support Co-authored-by: veranevera <[email protected]>
1 parent a104aec commit a544ab9

File tree

2 files changed

+153
-68
lines changed

2 files changed

+153
-68
lines changed

modules/showheroes-bsBidAdapter.js

Lines changed: 64 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export const spec = {
2929
return !!bid.params.playerId;
3030
},
3131
buildRequests: function(validBidRequests, bidderRequest) {
32+
let adUnits = [];
3233
const pageURL = validBidRequests[0].params.contentPageUrl || bidderRequest.refererInfo.referer;
3334
const isStage = !!validBidRequests[0].params.stage;
3435
const isOutstream = utils.deepAccess(validBidRequests[0], 'mediaTypes.video.context') === 'outstream';
@@ -38,53 +39,53 @@ export const spec = {
3839
const outstreamOptions = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions');
3940
const isBanner = !!validBidRequests[0].mediaTypes.banner || (isOutstream && !(isCustomRender || isNativeRender || isNodeRender));
4041

41-
let adUnits = validBidRequests.map((bid) => {
42+
validBidRequests.forEach((bid) => {
43+
const videoSizes = getVideoSizes(bid);
44+
const bannerSizes = getBannerSizes(bid);
4245
const vpaidMode = utils.getBidIdParameter('vpaidMode', bid.params);
4346

44-
let sizes = bid.sizes.length === 1 ? bid.sizes[0] : bid.sizes;
45-
if (sizes && !sizes.length) {
46-
let mediaSize;
47-
let mediaVideoSize = utils.deepAccess(bid, 'mediaTypes.video.playerSize');
48-
if (utils.isArray(mediaVideoSize)) {
49-
mediaSize = mediaVideoSize;
47+
const makeBids = (type, size) => {
48+
let context = '';
49+
let streamType = 2;
50+
51+
if (type === BANNER) {
52+
streamType = 5;
5053
} else {
51-
mediaSize = bid.mediaTypes.banner.sizes;
52-
}
53-
if (utils.isArray(mediaSize[0])) {
54-
sizes = mediaSize[0];
55-
} else if (utils.isNumber(mediaSize[0])) {
56-
sizes = mediaSize;
54+
context = utils.deepAccess(bid, 'mediaTypes.video.context');
55+
if (vpaidMode && context === 'instream') {
56+
streamType = 1;
57+
}
58+
if (context === 'outstream') {
59+
streamType = 5;
60+
}
5761
}
58-
}
5962

60-
const context = utils.deepAccess(bid, 'mediaTypes.video.context');
61-
62-
let streamType = 2;
63+
return {
64+
type: streamType,
65+
bidId: bid.bidId,
66+
mediaType: type,
67+
context: context,
68+
playerId: utils.getBidIdParameter('playerId', bid.params),
69+
auctionId: bidderRequest.auctionId,
70+
bidderCode: BIDDER_CODE,
71+
gdprConsent: bidderRequest.gdprConsent,
72+
start: +new Date(),
73+
timeout: 3000,
74+
size: {
75+
width: size[0],
76+
height: size[1]
77+
},
78+
params: bid.params,
79+
};
80+
};
6381

64-
if (vpaidMode && context === 'instream') {
65-
streamType = 1;
66-
}
67-
if (isBanner || context === 'outstream') {
68-
streamType = 5;
69-
}
82+
videoSizes.forEach((size) => {
83+
adUnits.push(makeBids(VIDEO, size));
84+
});
7085

71-
return {
72-
type: streamType,
73-
bidId: bid.bidId,
74-
mediaType: isBanner ? BANNER : VIDEO,
75-
context: context,
76-
playerId: utils.getBidIdParameter('playerId', bid.params),
77-
auctionId: bidderRequest.auctionId,
78-
bidderCode: BIDDER_CODE,
79-
gdprConsent: bidderRequest.gdprConsent,
80-
start: +new Date(),
81-
timeout: 3000,
82-
video: {
83-
width: sizes[0],
84-
height: sizes[1]
85-
},
86-
params: bid.params,
87-
};
86+
bannerSizes.forEach((size) => {
87+
adUnits.push(makeBids(BANNER, size));
88+
});
8889
});
8990

9091
return {
@@ -94,6 +95,7 @@ export const spec = {
9495
data: {
9596
'user': [],
9697
'meta': {
98+
'adapterVersion': 2,
9799
'pageURL': encodeURIComponent(pageURL),
98100
'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner && !outstreamOptions) || false,
99101
'isDesktop': utils.getWindowTop().document.documentElement.clientWidth > 700,
@@ -156,12 +158,12 @@ function createBids(bidRes, reqData) {
156158
bidUnit.cpm = bid.cpm;
157159
bidUnit.requestId = bid.bidId;
158160
bidUnit.currency = bid.currency;
159-
bidUnit.mediaType = reqBid.mediaType || VIDEO;
161+
bidUnit.mediaType = bid.mediaType || VIDEO;
160162
bidUnit.ttl = TTL;
161163
bidUnit.creativeId = 'c_' + bid.bidId;
162164
bidUnit.netRevenue = true;
163-
bidUnit.width = bid.video.width;
164-
bidUnit.height = bid.video.height;
165+
bidUnit.width = bid.size.width;
166+
bidUnit.height = bid.size.height;
165167
if (bid.vastXml) {
166168
bidUnit.vastXml = bid.vastXml;
167169
bidUnit.adResponse = {
@@ -171,16 +173,16 @@ function createBids(bidRes, reqData) {
171173
if (bid.vastTag) {
172174
bidUnit.vastUrl = bid.vastTag;
173175
}
174-
if (reqBid.mediaType === BANNER) {
176+
if (bid.mediaType === BANNER) {
175177
bidUnit.ad = getBannerHtml(bid, reqBid, reqData);
176-
} else if (reqBid.context === 'outstream') {
178+
} else if (bid.context === 'outstream') {
177179
const renderer = Renderer.install({
178180
id: bid.bidId,
179181
url: '//',
180182
config: {
181183
playerId: reqBid.playerId,
182-
width: bid.video.width,
183-
height: bid.video.height,
184+
width: bid.size.width,
185+
height: bid.size.height,
184186
vastUrl: bid.vastTag,
185187
vastXml: bid.vastXml,
186188
debug: reqData.debug,
@@ -267,4 +269,19 @@ function getBannerHtml (bid, reqBid, reqData) {
267269
</html>`;
268270
}
269271

272+
function getVideoSizes(bidRequest) {
273+
return formatSizes(utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize') || []);
274+
}
275+
276+
function getBannerSizes(bidRequest) {
277+
return formatSizes(utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes || []);
278+
}
279+
280+
function formatSizes(sizes) {
281+
if (!sizes || !sizes.length) {
282+
return []
283+
}
284+
return Array.isArray(sizes[0]) ? sizes : [sizes];
285+
}
286+
270287
registerBidder(spec);

test/spec/modules/showheroes-bsBidAdapter_spec.js

Lines changed: 89 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,22 @@ const bidRequestBanner = {
7979
}
8080
}
8181

82+
const bidRequestBannerMultiSizes = {
83+
...bidRequestCommonParams,
84+
...{
85+
'mediaTypes': {
86+
'banner': {
87+
'sizes': [[640, 360], [480, 320]]
88+
}
89+
}
90+
}
91+
}
92+
93+
const bidRequestVideoAndBanner = {
94+
...bidRequestBanner,
95+
...bidRequestVideo
96+
}
97+
8298
describe('shBidAdapter', function () {
8399
const adapter = newBidder(spec)
84100

@@ -120,8 +136,8 @@ describe('shBidAdapter', function () {
120136
}], bidderRequest)
121137
const payload = request.data.requests[0];
122138
expect(payload).to.be.an('object');
123-
expect(payload.video).to.have.property('width', 640);
124-
expect(payload.video).to.have.property('height', 480);
139+
expect(payload.size).to.have.property('width', 640);
140+
expect(payload.size).to.have.property('height', 480);
125141

126142
const request2 = spec.buildRequests([{
127143
'params': {},
@@ -130,8 +146,8 @@ describe('shBidAdapter', function () {
130146
}], bidderRequest)
131147
const payload2 = request2.data.requests[0];
132148
expect(payload).to.be.an('object');
133-
expect(payload2.video).to.have.property('width', 320);
134-
expect(payload2.video).to.have.property('height', 240);
149+
expect(payload2.size).to.have.property('width', 320);
150+
expect(payload2.size).to.have.property('height', 240);
135151
})
136152

137153
it('should get size from mediaTypes when sizes property is empty', function () {
@@ -146,8 +162,8 @@ describe('shBidAdapter', function () {
146162
}], bidderRequest)
147163
const payload = request.data.requests[0];
148164
expect(payload).to.be.an('object');
149-
expect(payload.video).to.have.property('width', 640);
150-
expect(payload.video).to.have.property('height', 480);
165+
expect(payload.size).to.have.property('width', 640);
166+
expect(payload.size).to.have.property('height', 480);
151167

152168
const request2 = spec.buildRequests([{
153169
'params': {},
@@ -160,8 +176,8 @@ describe('shBidAdapter', function () {
160176
}], bidderRequest)
161177
const payload2 = request2.data.requests[0];
162178
expect(payload).to.be.an('object');
163-
expect(payload2.video).to.have.property('width', 320);
164-
expect(payload2.video).to.have.property('height', 240);
179+
expect(payload2.size).to.have.property('width', 320);
180+
expect(payload2.size).to.have.property('height', 240);
165181
})
166182

167183
it('should attach valid params to the payload when type is video', function () {
@@ -191,6 +207,38 @@ describe('shBidAdapter', function () {
191207
expect(payload).to.have.property('type', 5);
192208
})
193209

210+
it('should attach valid params to the payload when type is banner (multi sizes)', function () {
211+
const request = spec.buildRequests([bidRequestBannerMultiSizes], bidderRequest)
212+
const payload = request.data.requests[0];
213+
expect(payload).to.be.an('object');
214+
expect(payload).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd');
215+
expect(payload).to.have.property('mediaType', BANNER);
216+
expect(payload).to.have.property('type', 5);
217+
expect(payload).to.have.nested.property('size.width', 640);
218+
expect(payload).to.have.nested.property('size.height', 360);
219+
const payload2 = request.data.requests[1];
220+
expect(payload2).to.be.an('object');
221+
expect(payload2).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd');
222+
expect(payload2).to.have.property('mediaType', BANNER);
223+
expect(payload2).to.have.property('type', 5);
224+
expect(payload2).to.have.nested.property('size.width', 480);
225+
expect(payload2).to.have.nested.property('size.height', 320);
226+
})
227+
228+
it('should attach valid params to the payload when type is banner and video', function () {
229+
const request = spec.buildRequests([bidRequestVideoAndBanner], bidderRequest)
230+
const payload = request.data.requests[0];
231+
expect(payload).to.be.an('object');
232+
expect(payload).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd');
233+
expect(payload).to.have.property('mediaType', VIDEO);
234+
expect(payload).to.have.property('type', 2);
235+
const payload2 = request.data.requests[1];
236+
expect(payload2).to.be.an('object');
237+
expect(payload2).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd');
238+
expect(payload2).to.have.property('mediaType', BANNER);
239+
expect(payload2).to.have.property('type', 5);
240+
})
241+
194242
it('passes gdpr if present', function () {
195243
const request = spec.buildRequests([bidRequestVideo], {...bidderRequest, ...gdpr})
196244
const payload = request.data.requests[0];
@@ -208,16 +256,36 @@ describe('shBidAdapter', function () {
208256
const vastTag = 'https://video-library.stage.showheroes.com/commercial/wrapper?player_id=47427aa0-f11a-4d24-abca-1295a46a46cd&ad_bidder=showheroes-bs&master_shadt=1&description_url=https%3A%2F%2Fbid-service.stage.showheroes.com%2Fvast%2Fad%2Fcache%2F4840b920-40e1-4e09-9231-60bbf088c8d6'
209257
const vastXml = '<?xml version="1.0" encoding="utf-8"?><VAST version="3.0"><Error><![CDATA[https://static.showheroes.com/shim.gif]]></Error></VAST>'
210258

211-
const response = {
259+
const basicResponse = {
260+
'cpm': 5,
261+
'currency': 'EUR',
262+
'mediaType': VIDEO,
263+
'context': 'instream',
264+
'bidId': '38b373e1e31c18',
265+
'size': {'width': 640, 'height': 480},
266+
'vastTag': 'https:\/\/video-library.stage.showheroes.com\/commercial\/wrapper?player_id=47427aa0-f11a-4d24-abca-1295a46a46cd&ad_bidder=showheroes-bs&master_shadt=1&description_url=https%3A%2F%2Fbid-service.stage.showheroes.com%2Fvast%2Fad%2Fcache%2F4840b920-40e1-4e09-9231-60bbf088c8d6',
267+
'vastXml': vastXml,
268+
};
269+
270+
const responseVideo = {
212271
'bids': [{
213-
'cpm': 5,
214-
'currency': 'EUR',
215-
'bidId': '38b373e1e31c18',
216-
'video': {'width': 640, 'height': 480},
217-
'vastTag': 'https:\/\/video-library.stage.showheroes.com\/commercial\/wrapper?player_id=47427aa0-f11a-4d24-abca-1295a46a46cd&ad_bidder=showheroes-bs&master_shadt=1&description_url=https%3A%2F%2Fbid-service.stage.showheroes.com%2Fvast%2Fad%2Fcache%2F4840b920-40e1-4e09-9231-60bbf088c8d6',
218-
'vastXml': vastXml,
272+
...basicResponse,
219273
}],
220-
}
274+
};
275+
276+
const responseVideoOutstream = {
277+
'bids': [{
278+
...basicResponse,
279+
'context': 'outstream',
280+
}],
281+
};
282+
283+
const responseBanner = {
284+
'bids': [{
285+
...basicResponse,
286+
'mediaType': BANNER,
287+
}],
288+
};
221289

222290
it('should get correct bid response when type is video', function () {
223291
const request = spec.buildRequests([bidRequestVideo], bidderRequest)
@@ -240,14 +308,14 @@ describe('shBidAdapter', function () {
240308
}
241309
]
242310

243-
const result = spec.interpretResponse({'body': response}, request)
311+
const result = spec.interpretResponse({'body': responseVideo}, request)
244312
expect(result).to.deep.equal(expectedResponse)
245313
})
246314

247315
it('should get correct bid response when type is banner', function () {
248316
const request = spec.buildRequests([bidRequestBanner], bidderRequest)
249317

250-
const result = spec.interpretResponse({'body': response}, request)
318+
const result = spec.interpretResponse({'body': responseBanner}, request)
251319
expect(result[0]).to.have.property('mediaType', BANNER);
252320
expect(result[0].ad).to.include('<script async src="https://static.showheroes.com/publishertag.js')
253321
expect(result[0].ad).to.include('<div class="showheroes-spot"')
@@ -266,7 +334,7 @@ describe('shBidAdapter', function () {
266334

267335
const request = spec.buildRequests([bidRequest], bidderRequest)
268336

269-
const result = spec.interpretResponse({'body': response}, request)
337+
const result = spec.interpretResponse({'body': responseVideoOutstream}, request)
270338
const bid = result[0]
271339
expect(bid).to.have.property('mediaType', VIDEO);
272340

@@ -297,7 +365,7 @@ describe('shBidAdapter', function () {
297365

298366
const request = spec.buildRequests([bidRequest], bidderRequest)
299367

300-
const result = spec.interpretResponse({'body': response}, request)
368+
const result = spec.interpretResponse({'body': responseVideoOutstream}, request)
301369
const bid = result[0]
302370
expect(bid).to.have.property('mediaType', VIDEO);
303371

@@ -332,7 +400,7 @@ describe('shBidAdapter', function () {
332400

333401
const request = spec.buildRequests([bidRequest], bidderRequest)
334402

335-
const result = spec.interpretResponse({'body': response}, request)
403+
const result = spec.interpretResponse({'body': responseVideoOutstream}, request)
336404
const bid = result[0]
337405
expect(bid).to.have.property('mediaType', VIDEO);
338406

0 commit comments

Comments
 (0)