mk9-prebid
Version:
Header Bidding Management Library
491 lines (428 loc) • 16.3 kB
JavaScript
import {expect} from 'chai'
import {spec} from 'modules/showheroes-bsBidAdapter.js'
import {newBidder} from 'src/adapters/bidderFactory.js'
import {VIDEO, BANNER} from 'src/mediaTypes.js'
const bidderRequest = {
refererInfo: {
referer: 'https://example.com'
}
}
const adomain = ['showheroes.com'];
const gdpr = {
'gdprConsent': {
'consentString': 'BOEFEAyOEFEAyAHABDENAI4AAAB9vABAASA',
'gdprApplies': true
}
}
const schain = {
'schain': {
'validation': 'strict',
'config': {
'ver': '1.0',
'complete': 1,
'nodes': [
{
'asi': 'some.com',
'sid': '00001',
'hp': 1
}
]
}
}
}
const bidRequestCommonParams = {
'bidder': 'showheroes-bs',
'params': {
'playerId': '47427aa0-f11a-4d24-abca-1295a46a46cd',
},
'adUnitCode': 'adunit-code-1',
'sizes': [[640, 480]],
'bidId': '38b373e1e31c18',
'bidderRequestId': '12e3ade2543ba6',
'auctionId': '43aa080090a47f',
}
const bidRequestVideo = {
...bidRequestCommonParams,
...{
'mediaTypes': {
'video': {
'playerSize': [640, 480],
'context': 'instream',
}
}
}
}
const bidRequestOutstream = {
...bidRequestCommonParams,
...{
'mediaTypes': {
'video': {
'playerSize': [640, 480],
'context': 'outstream',
}
}
}
}
const bidRequestVideoVpaid = {
...bidRequestCommonParams,
...{
'params': {
'playerId': '47427aa0-f11a-4d24-abca-1295a46a46cd',
'vpaidMode': true,
},
'mediaTypes': {
'video': {
'playerSize': [640, 480],
'context': 'instream',
}
}
}
}
const bidRequestBanner = {
...bidRequestCommonParams,
...{
'mediaTypes': {
'banner': {
'sizes': [[640, 360]]
}
}
}
}
const bidRequestBannerMultiSizes = {
...bidRequestCommonParams,
...{
'mediaTypes': {
'banner': {
'sizes': [[640, 360], [480, 320]]
}
}
}
}
const bidRequestVideoAndBanner = {
...bidRequestCommonParams,
'mediaTypes': {
...bidRequestBanner.mediaTypes,
...bidRequestVideo.mediaTypes
}
}
describe('shBidAdapter', function () {
const adapter = newBidder(spec)
describe('inherited functions', function () {
it('exists and is a function', function () {
expect(adapter.callBids).to.exist.and.to.be.a('function')
})
})
describe('isBidRequestValid', function () {
it('should return true when required params found', function () {
const request = {
'params': {
'playerId': '47427aa0-f11a-4d24-abca-1295a46a46cd',
}
}
expect(spec.isBidRequestValid(request)).to.equal(true)
})
it('should return false when required params are not passed', function () {
const request = {
'params': {}
}
expect(spec.isBidRequestValid(request)).to.equal(false)
})
})
describe('buildRequests', function () {
it('sends bid request to ENDPOINT via POST', function () {
const request = spec.buildRequests([bidRequestVideo], bidderRequest)
expect(request.method).to.equal('POST')
})
it('check sizes formats', function () {
const request = spec.buildRequests([{
'params': {},
'mediaTypes': {
'banner': {
'sizes': [[320, 240]]
}
},
}], bidderRequest)
const payload = request.data.requests[0];
expect(payload).to.be.an('object');
expect(payload.size).to.have.property('width', 320);
expect(payload.size).to.have.property('height', 240);
const request2 = spec.buildRequests([{
'params': {},
'mediaTypes': {
'video': {
'playerSize': [640, 360]
}
},
}], bidderRequest)
const payload2 = request2.data.requests[0];
expect(payload).to.be.an('object');
expect(payload2.size).to.have.property('width', 640);
expect(payload2.size).to.have.property('height', 360);
})
it('should get size from mediaTypes when sizes property is empty', function () {
const request = spec.buildRequests([{
'params': {},
'mediaTypes': {
'video': {
'playerSize': [640, 480]
}
},
'sizes': [],
}], bidderRequest)
const payload = request.data.requests[0];
expect(payload).to.be.an('object');
expect(payload.size).to.have.property('width', 640);
expect(payload.size).to.have.property('height', 480);
const request2 = spec.buildRequests([{
'params': {},
'mediaTypes': {
'banner': {
'sizes': [[320, 240]]
}
},
'sizes': [],
}], bidderRequest)
const payload2 = request2.data.requests[0];
expect(payload).to.be.an('object');
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 () {
const request = spec.buildRequests([bidRequestVideo], 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);
})
it('should attach valid params to the payload when type is video & vpaid mode on', function () {
const request = spec.buildRequests([bidRequestVideoVpaid], 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', 1);
})
it('should attach valid params to the payload when type is banner', function () {
const request = spec.buildRequests([bidRequestBanner], 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);
})
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];
expect(payload).to.be.an('object');
expect(payload.gdprConsent).to.eql(gdpr.gdprConsent)
})
it('passes schain object if present', function() {
const request = spec.buildRequests([{
...bidRequestVideo,
...schain
}], bidderRequest)
const payload = request.data.requests[0];
expect(payload).to.be.an('object');
expect(payload.schain).to.eql(schain.schain);
})
})
describe('interpretResponse', function () {
it('handles nobid responses', function () {
expect(spec.interpretResponse({body: {}}, {data: {meta: {}}}).length).to.equal(0)
expect(spec.interpretResponse({body: []}, {data: {meta: {}}}).length).to.equal(0)
})
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 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,
'adomain': adomain,
};
const responseVideo = {
'bids': [{
...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)
const expectedResponse = [
{
'cpm': 5,
'creativeId': 'c_38b373e1e31c18',
'currency': 'EUR',
'width': 640,
'height': 480,
'mediaType': 'video',
'netRevenue': true,
'vastUrl': vastTag,
'vastXml': vastXml,
'requestId': '38b373e1e31c18',
'ttl': 300,
'adResponse': {
'content': vastXml
},
'meta': {
'advertiserDomains': adomain
}
}
]
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': 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"')
})
it('should get correct bid response when type is outstream (slot)', function () {
const bidRequest = JSON.parse(JSON.stringify(bidRequestOutstream));
const slotId = 'testSlot'
bidRequest.params.outstreamOptions = {
slot: slotId
}
const container = document.createElement('div')
container.setAttribute('id', slotId)
document.body.appendChild(container)
const request = spec.buildRequests([bidRequest], bidderRequest)
const result = spec.interpretResponse({'body': responseVideoOutstream}, request)
const bid = result[0]
expect(bid).to.have.property('mediaType', VIDEO);
const renderer = bid.renderer
expect(renderer).to.be.an('object')
expect(renderer.id).to.equal(bidRequest.bidId)
expect(renderer.config.vastUrl).to.equal(vastTag)
renderer.render(bid)
// TODO: fix these. our tests should not be reliant on third-party scripts. wtf
// const scripts = document.querySelectorAll('script[src="https://static.showheroes.com/publishertag.js"]')
// expect(scripts.length).to.equal(1)
const spots = document.querySelectorAll('.showheroes-spot')
expect(spots.length).to.equal(1)
})
it('should get correct bid response when type is outstream (iframe)', function () {
const bidRequest = JSON.parse(JSON.stringify(bidRequestOutstream));
const slotId = 'testIframe'
bidRequest.params.outstreamOptions = {
iframe: slotId
}
const iframe = document.createElement('iframe')
iframe.setAttribute('id', slotId)
document.body.appendChild(iframe)
const request = spec.buildRequests([bidRequest], bidderRequest)
const result = spec.interpretResponse({'body': responseVideoOutstream}, request)
const bid = result[0]
expect(bid).to.have.property('mediaType', VIDEO);
const renderer = bid.renderer
expect(renderer).to.be.an('object')
expect(renderer.id).to.equal(bidRequest.bidId)
renderer.render(bid)
const iframeDocument = iframe.contentDocument || (iframe.contentWindow && iframe.contentWindow.document)
// const scripts = iframeDocument.querySelectorAll('script[src="https://static.showheroes.com/publishertag.js"]')
// expect(scripts.length).to.equal(1)
const spots = iframeDocument.querySelectorAll('.showheroes-spot')
expect(spots.length).to.equal(1)
})
it('should get correct bid response when type is outstream (customRender)', function (done) {
const bidRequest = JSON.parse(JSON.stringify(bidRequestOutstream));
bidRequest.params.outstreamOptions = {
customRender: function (bid, embedCode) {
const container = document.createElement('div')
container.appendChild(embedCode)
// const scripts = container.querySelectorAll('script[src="https://static.showheroes.com/publishertag.js"]')
// expect(scripts.length).to.equal(1)
const spots = container.querySelectorAll('.showheroes-spot')
expect(spots.length).to.equal(1)
expect(bid.renderer.config.vastUrl).to.equal(vastTag)
expect(bid.renderer.config.vastXml).to.equal(vastXml)
done()
}
}
const request = spec.buildRequests([bidRequest], bidderRequest)
const result = spec.interpretResponse({'body': responseVideoOutstream}, request)
const bid = result[0]
expect(bid).to.have.property('mediaType', VIDEO);
const renderer = bid.renderer
expect(renderer).to.be.an('object')
expect(renderer.id).to.equal(bidRequest.bidId)
renderer.render(bid)
})
})
describe('getUserSyncs', function () {
const response = [{
body: {
userSync: {
iframes: ['https://sync.showheroes.com/iframe'],
pixels: ['https://sync.showheroes.com/pixel']
}
}
}]
it('empty', function () {
let result = spec.getUserSyncs({}, []);
expect(result).to.deep.equal([]);
});
it('iframe', function () {
let result = spec.getUserSyncs({
iframeEnabled: true
}, response);
expect(result[0].type).to.equal('iframe');
expect(result[0].url).to.equal('https://sync.showheroes.com/iframe');
});
it('pixel', function () {
let result = spec.getUserSyncs({
pixelEnabled: true
}, response);
expect(result[0].type).to.equal('image');
expect(result[0].url).to.equal('https://sync.showheroes.com/pixel');
});
});
})