Skip to content

Commit

Permalink
ShowHeroes adapter v2 (#5085)
Browse files Browse the repository at this point in the history
* 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 (#4222)

* ShowHeroes adapter - banner and outstream fixes (#4222)

* ShowHeroes adapter - description and outstream changes (#4222)

* ShowHeroes adapter - increase test coverage and small fix

* ShowHeroes Adapter - naming convention issue

* Mixed AdUnits declaration support

Co-authored-by: veranevera <vera.yukhina@showheroes.com>
  • Loading branch information
vadim-mazzherin and veranevera authored Apr 14, 2020
1 parent bcfca15 commit bddf7e9
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 68 deletions.
111 changes: 64 additions & 47 deletions modules/showheroes-bsBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const spec = {
return !!bid.params.playerId;
},
buildRequests: function(validBidRequests, bidderRequest) {
let adUnits = [];
const pageURL = validBidRequests[0].params.contentPageUrl || bidderRequest.refererInfo.referer;
const isStage = !!validBidRequests[0].params.stage;
const isOutstream = utils.deepAccess(validBidRequests[0], 'mediaTypes.video.context') === 'outstream';
Expand All @@ -38,53 +39,53 @@ export const spec = {
const outstreamOptions = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions');
const isBanner = !!validBidRequests[0].mediaTypes.banner || (isOutstream && !(isCustomRender || isNativeRender || isNodeRender));

let adUnits = validBidRequests.map((bid) => {
validBidRequests.forEach((bid) => {
const videoSizes = getVideoSizes(bid);
const bannerSizes = getBannerSizes(bid);
const vpaidMode = utils.getBidIdParameter('vpaidMode', bid.params);

let sizes = bid.sizes.length === 1 ? bid.sizes[0] : bid.sizes;
if (sizes && !sizes.length) {
let mediaSize;
let mediaVideoSize = utils.deepAccess(bid, 'mediaTypes.video.playerSize');
if (utils.isArray(mediaVideoSize)) {
mediaSize = mediaVideoSize;
const makeBids = (type, size) => {
let context = '';
let streamType = 2;

if (type === BANNER) {
streamType = 5;
} else {
mediaSize = bid.mediaTypes.banner.sizes;
}
if (utils.isArray(mediaSize[0])) {
sizes = mediaSize[0];
} else if (utils.isNumber(mediaSize[0])) {
sizes = mediaSize;
context = utils.deepAccess(bid, 'mediaTypes.video.context');
if (vpaidMode && context === 'instream') {
streamType = 1;
}
if (context === 'outstream') {
streamType = 5;
}
}
}

const context = utils.deepAccess(bid, 'mediaTypes.video.context');

let streamType = 2;
return {
type: streamType,
bidId: bid.bidId,
mediaType: type,
context: context,
playerId: utils.getBidIdParameter('playerId', bid.params),
auctionId: bidderRequest.auctionId,
bidderCode: BIDDER_CODE,
gdprConsent: bidderRequest.gdprConsent,
start: +new Date(),
timeout: 3000,
size: {
width: size[0],
height: size[1]
},
params: bid.params,
};
};

if (vpaidMode && context === 'instream') {
streamType = 1;
}
if (isBanner || context === 'outstream') {
streamType = 5;
}
videoSizes.forEach((size) => {
adUnits.push(makeBids(VIDEO, size));
});

return {
type: streamType,
bidId: bid.bidId,
mediaType: isBanner ? BANNER : VIDEO,
context: context,
playerId: utils.getBidIdParameter('playerId', bid.params),
auctionId: bidderRequest.auctionId,
bidderCode: BIDDER_CODE,
gdprConsent: bidderRequest.gdprConsent,
start: +new Date(),
timeout: 3000,
video: {
width: sizes[0],
height: sizes[1]
},
params: bid.params,
};
bannerSizes.forEach((size) => {
adUnits.push(makeBids(BANNER, size));
});
});

return {
Expand All @@ -94,6 +95,7 @@ export const spec = {
data: {
'user': [],
'meta': {
'adapterVersion': 2,
'pageURL': encodeURIComponent(pageURL),
'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner && !outstreamOptions) || false,
'isDesktop': utils.getWindowTop().document.documentElement.clientWidth > 700,
Expand Down Expand Up @@ -156,12 +158,12 @@ function createBids(bidRes, reqData) {
bidUnit.cpm = bid.cpm;
bidUnit.requestId = bid.bidId;
bidUnit.currency = bid.currency;
bidUnit.mediaType = reqBid.mediaType || VIDEO;
bidUnit.mediaType = bid.mediaType || VIDEO;
bidUnit.ttl = TTL;
bidUnit.creativeId = 'c_' + bid.bidId;
bidUnit.netRevenue = true;
bidUnit.width = bid.video.width;
bidUnit.height = bid.video.height;
bidUnit.width = bid.size.width;
bidUnit.height = bid.size.height;
if (bid.vastXml) {
bidUnit.vastXml = bid.vastXml;
bidUnit.adResponse = {
Expand All @@ -171,16 +173,16 @@ function createBids(bidRes, reqData) {
if (bid.vastTag) {
bidUnit.vastUrl = bid.vastTag;
}
if (reqBid.mediaType === BANNER) {
if (bid.mediaType === BANNER) {
bidUnit.ad = getBannerHtml(bid, reqBid, reqData);
} else if (reqBid.context === 'outstream') {
} else if (bid.context === 'outstream') {
const renderer = Renderer.install({
id: bid.bidId,
url: '//',
config: {
playerId: reqBid.playerId,
width: bid.video.width,
height: bid.video.height,
width: bid.size.width,
height: bid.size.height,
vastUrl: bid.vastTag,
vastXml: bid.vastXml,
debug: reqData.debug,
Expand Down Expand Up @@ -267,4 +269,19 @@ function getBannerHtml (bid, reqBid, reqData) {
</html>`;
}

function getVideoSizes(bidRequest) {
return formatSizes(utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize') || []);
}

function getBannerSizes(bidRequest) {
return formatSizes(utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes || []);
}

function formatSizes(sizes) {
if (!sizes || !sizes.length) {
return []
}
return Array.isArray(sizes[0]) ? sizes : [sizes];
}

registerBidder(spec);
110 changes: 89 additions & 21 deletions test/spec/modules/showheroes-bsBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,22 @@ const bidRequestBanner = {
}
}

const bidRequestBannerMultiSizes = {
...bidRequestCommonParams,
...{
'mediaTypes': {
'banner': {
'sizes': [[640, 360], [480, 320]]
}
}
}
}

const bidRequestVideoAndBanner = {
...bidRequestBanner,
...bidRequestVideo
}

describe('shBidAdapter', function () {
const adapter = newBidder(spec)

Expand Down Expand Up @@ -120,8 +136,8 @@ describe('shBidAdapter', function () {
}], bidderRequest)
const payload = request.data.requests[0];
expect(payload).to.be.an('object');
expect(payload.video).to.have.property('width', 640);
expect(payload.video).to.have.property('height', 480);
expect(payload.size).to.have.property('width', 640);
expect(payload.size).to.have.property('height', 480);

const request2 = spec.buildRequests([{
'params': {},
Expand All @@ -130,8 +146,8 @@ describe('shBidAdapter', function () {
}], bidderRequest)
const payload2 = request2.data.requests[0];
expect(payload).to.be.an('object');
expect(payload2.video).to.have.property('width', 320);
expect(payload2.video).to.have.property('height', 240);
expect(payload2.size).to.have.property('width', 320);
expect(payload2.size).to.have.property('height', 240);
})

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

const request2 = spec.buildRequests([{
'params': {},
Expand All @@ -160,8 +176,8 @@ describe('shBidAdapter', function () {
}], bidderRequest)
const payload2 = request2.data.requests[0];
expect(payload).to.be.an('object');
expect(payload2.video).to.have.property('width', 320);
expect(payload2.video).to.have.property('height', 240);
expect(payload2.size).to.have.property('width', 320);
expect(payload2.size).to.have.property('height', 240);
})

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

it('should attach valid params to the payload when type is banner (multi sizes)', function () {
const request = spec.buildRequests([bidRequestBannerMultiSizes], bidderRequest)
const payload = request.data.requests[0];
expect(payload).to.be.an('object');
expect(payload).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd');
expect(payload).to.have.property('mediaType', BANNER);
expect(payload).to.have.property('type', 5);
expect(payload).to.have.nested.property('size.width', 640);
expect(payload).to.have.nested.property('size.height', 360);
const payload2 = request.data.requests[1];
expect(payload2).to.be.an('object');
expect(payload2).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd');
expect(payload2).to.have.property('mediaType', BANNER);
expect(payload2).to.have.property('type', 5);
expect(payload2).to.have.nested.property('size.width', 480);
expect(payload2).to.have.nested.property('size.height', 320);
})

it('should attach valid params to the payload when type is banner and video', function () {
const request = spec.buildRequests([bidRequestVideoAndBanner], bidderRequest)
const payload = request.data.requests[0];
expect(payload).to.be.an('object');
expect(payload).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd');
expect(payload).to.have.property('mediaType', VIDEO);
expect(payload).to.have.property('type', 2);
const payload2 = request.data.requests[1];
expect(payload2).to.be.an('object');
expect(payload2).to.have.property('playerId', '47427aa0-f11a-4d24-abca-1295a46a46cd');
expect(payload2).to.have.property('mediaType', BANNER);
expect(payload2).to.have.property('type', 5);
})

it('passes gdpr if present', function () {
const request = spec.buildRequests([bidRequestVideo], {...bidderRequest, ...gdpr})
const payload = request.data.requests[0];
Expand All @@ -208,16 +256,36 @@ describe('shBidAdapter', function () {
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'
const vastXml = '<?xml version="1.0" encoding="utf-8"?><VAST version="3.0"><Error><![CDATA[https://static.showheroes.com/shim.gif]]></Error></VAST>'

const response = {
const basicResponse = {
'cpm': 5,
'currency': 'EUR',
'mediaType': VIDEO,
'context': 'instream',
'bidId': '38b373e1e31c18',
'size': {'width': 640, 'height': 480},
'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',
'vastXml': vastXml,
};

const responseVideo = {
'bids': [{
'cpm': 5,
'currency': 'EUR',
'bidId': '38b373e1e31c18',
'video': {'width': 640, 'height': 480},
'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',
'vastXml': vastXml,
...basicResponse,
}],
}
};

const responseVideoOutstream = {
'bids': [{
...basicResponse,
'context': 'outstream',
}],
};

const responseBanner = {
'bids': [{
...basicResponse,
'mediaType': BANNER,
}],
};

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

const result = spec.interpretResponse({'body': response}, request)
const result = spec.interpretResponse({'body': responseVideo}, request)
expect(result).to.deep.equal(expectedResponse)
})

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

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

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

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

Expand Down Expand Up @@ -297,7 +365,7 @@ describe('shBidAdapter', function () {

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

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

Expand Down Expand Up @@ -332,7 +400,7 @@ describe('shBidAdapter', function () {

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

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

Expand Down

0 comments on commit bddf7e9

Please sign in to comment.