UNPKG

mk9-prebid

Version:

Header Bidding Management Library

664 lines (574 loc) 21.5 kB
import {expect} from 'chai'; import {config} from 'src/config.js'; import {spec, GOOGLE_CONSENT} from 'modules/spotxBidAdapter.js'; describe('the spotx adapter', function () { function getValidBidObject() { return { bidId: 123, mediaTypes: { video: { playerSize: [['300', '200']] } }, params: { channel_id: 12345, } }; }; describe('isBidRequestValid', function() { var bid; beforeEach(function() { bid = getValidBidObject(); }); it('should fail validation if the bid isn\'t defined or not an object', function() { var result = spec.isBidRequestValid(); expect(result).to.equal(false); result = spec.isBidRequestValid('not an object'); expect(result).to.equal(false); }); it('should succeed validation with all the right parameters', function() { expect(spec.isBidRequestValid(getValidBidObject())).to.equal(true); }); it('should succeed validation with mediaType and outstream_function or outstream_options', function() { bid.mediaType = 'video'; bid.params.outstream_function = 'outstream_func'; expect(spec.isBidRequestValid(bid)).to.equal(true); delete bid.params.outstream_function; bid.params.outstream_options = { slot: 'elemID' }; expect(spec.isBidRequestValid(bid)).to.equal(true); }); it('should succeed with ad_unit outstream and outstream function set', function() { bid.params.ad_unit = 'outstream'; bid.params.outstream_function = function() {}; expect(spec.isBidRequestValid(bid)).to.equal(true); }); it('should succeed with ad_unit outstream, options set for outstream and slot provided', function() { bid.params.ad_unit = 'outstream'; bid.params.outstream_options = {slot: 'ad_container_id'}; expect(spec.isBidRequestValid(bid)).to.equal(true); }); it('should fail without a channel_id', function() { delete bid.params.channel_id; expect(spec.isBidRequestValid(bid)).to.equal(false); }); it('should fail without playerSize', function() { delete bid.mediaTypes.video.playerSize; expect(spec.isBidRequestValid(bid)).to.equal(false); }); it('should fail without video', function() { delete bid.mediaTypes.video; expect(spec.isBidRequestValid(bid)).to.equal(false); }); it('should fail with ad_unit outstream but no options set for outstream', function() { bid.params.ad_unit = 'outstream'; expect(spec.isBidRequestValid(bid)).to.equal(false); }); it('should fail with ad_unit outstream, options set for outstream but no slot provided', function() { bid.params.ad_unit = 'outstream'; bid.params.outstream_options = {}; expect(spec.isBidRequestValid(bid)).to.equal(false); }); }); describe('buildRequests', function() { var bid, bidRequestObj; beforeEach(function() { bid = getValidBidObject(); bidRequestObj = {refererInfo: {referer: 'prebid.js'}}; }); it('should build a very basic request', function() { var request = spec.buildRequests([bid], bidRequestObj)[0]; expect(request.method).to.equal('POST'); expect(request.url).to.equal('https://search.spotxchange.com/openrtb/2.3/dados/12345?src_sys=prebid'); expect(request.bidRequest).to.equal(bidRequestObj); expect(request.data.id).to.equal(12345); expect(request.data.ext.wrap_response).to.equal(1); expect(request.data.imp.id).to.match(/\d+/); expect(request.data.imp.secure).to.equal(0); expect(request.data.imp.video).to.deep.equal({ ext: { sdk_name: 'Prebid 1+', versionOrtb: '2.3' }, h: '200', mimes: [ 'application/javascript', 'video/mp4', 'video/webm' ], w: '300' }); expect(request.data.site).to.deep.equal({ content: 'content', id: '', page: 'prebid.js' }); }); it('should change request parameters based on options sent', function() { var request = spec.buildRequests([bid], bidRequestObj)[0]; expect(request.data.imp.video.ext).to.deep.equal({ sdk_name: 'Prebid 1+', versionOrtb: '2.3' }); bid.params = { channel_id: 54321, ad_mute: 1, hide_skin: 1, ad_volume: 1, ad_unit: 'incontent', outstream_options: {foo: 'bar'}, outstream_function: '987', custom: {bar: 'foo'}, start_delay: true, number_of_ads: 2, spotx_all_google_consent: 1, min_duration: 5, max_duration: 10, placement_type: 1, position: 1 }; bid.userId = { id5id: { uid: 'id5id_1' }, tdid: 'tdid_1' }; bid.crumbs = { pubcid: 'pubcid_1' }; bid.schain = { complete: 1, nodes: [ { asi: 'indirectseller.com', sid: '00001', hp: 1 } ] } request = spec.buildRequests([bid], bidRequestObj)[0]; expect(request.data.id).to.equal(54321); expect(request.data.imp.video).to.contain({ minduration: 5, maxduration: 10 }) expect(request.data.imp.video.ext).to.deep.equal({ ad_volume: 1, hide_skin: 1, ad_unit: 'incontent', outstream_options: {foo: 'bar'}, outstream_function: '987', custom: {bar: 'foo'}, sdk_name: 'Prebid 1+', versionOrtb: '2.3', placement: 1, pos: 1 }); expect(request.data.imp.video.startdelay).to.equal(1); expect(request.data.ext).to.deep.equal({ number_of_ads: 2, wrap_response: 1 }); expect(request.data.user.ext).to.deep.equal({ consented_providers_settings: GOOGLE_CONSENT, eids: [{ source: 'id5-sync.com', uids: [{ id: 'id5id_1', ext: {} }] }, { source: 'adserver.org', uids: [{ id: 'tdid_1', ext: { rtiPartner: 'TDID' } }] }], fpc: 'pubcid_1' }) expect(request.data.source).to.deep.equal({ ext: { schain: { complete: 1, nodes: [ { asi: 'indirectseller.com', sid: '00001', hp: 1 } ] } } }) }); it('should process premarket bids', function() { var request; sinon.stub(Date, 'now').returns(1000); bid.params.pre_market_bids = [{ vast_url: 'prebid.js', deal_id: '123abc', price: 12, currency: 'USD' }]; request = spec.buildRequests([bid], bidRequestObj)[0]; expect(request.data.imp.video.ext.pre_market_bids).to.deep.equal([ { 'cur': 'USD', 'ext': { 'event_log': [ {} ] }, 'id': '123abc', 'seatbid': [ { 'bid': [ { 'adm': '<?xml version="1.0" encoding="utf-8"?><VAST version="2.0"><Ad><Wrapper><VASTAdTagURI>prebid.js</VASTAdTagURI></Wrapper></Ad></VAST>', 'dealid': '123abc', 'impid': 1000, 'price': 12, } ] } ] } ]); Date.now.restore(); }); it('should pass GDPR params', function() { var request; bidRequestObj.gdprConsent = { consentString: 'consent123', gdprApplies: true }; request = spec.buildRequests([bid], bidRequestObj)[0]; expect(request.data.regs.ext.gdpr).to.equal(1); expect(request.data.user.ext.consent).to.equal('consent123'); }); it('should pass CCPA us_privacy string', function() { var request; bidRequestObj.uspConsent = '1YYY' request = spec.buildRequests([bid], bidRequestObj)[0]; expect(request.data.regs.ext.us_privacy).to.equal('1YYY'); }); it('should pass both GDPR params and CCPA us_privacy', function() { var request; bidRequestObj.gdprConsent = { consentString: 'consent123', gdprApplies: true }; bidRequestObj.uspConsent = '1YYY' request = spec.buildRequests([bid], bidRequestObj)[0]; expect(request.data.regs.ext.gdpr).to.equal(1); expect(request.data.user.ext.consent).to.equal('consent123'); expect(request.data.regs.ext.us_privacy).to.equal('1YYY'); }); it('should pass min and max duration params', function() { var request; bid.params.min_duration = 3 bid.params.max_duration = 15 request = spec.buildRequests([bid], bidRequestObj)[0]; expect(request.data.imp.video.minduration).to.equal(3); expect(request.data.imp.video.maxduration).to.equal(15); }); it('should pass placement_type and position params', function() { var request; bid.params.placement_type = 2 bid.params.position = 5 request = spec.buildRequests([bid], bidRequestObj)[0]; expect(request.data.imp.video.ext.placement).to.equal(2); expect(request.data.imp.video.ext.pos).to.equal(5); }); it('should pass page param and override refererInfo.referer', function() { var request; bid.params.page = 'https://example.com'; var origGetConfig = config.getConfig; sinon.stub(config, 'getConfig').callsFake(function (key) { if (key === 'pageUrl') { return 'https://www.spotx.tv'; } return origGetConfig.apply(config, arguments); }); request = spec.buildRequests([bid], bidRequestObj)[0]; expect(request.data.site.page).to.equal('https://example.com'); config.getConfig.restore(); }); it('should use pageUrl from config if page param is not passed', function() { var request; var origGetConfig = config.getConfig; sinon.stub(config, 'getConfig').callsFake(function (key) { if (key === 'pageUrl') { return 'https://www.spotx.tv'; } return origGetConfig.apply(config, arguments); }); request = spec.buildRequests([bid], bidRequestObj)[0]; expect(request.data.site.page).to.equal('https://www.spotx.tv'); config.getConfig.restore(); }); it('should use refererInfo.referer if no page or pageUrl are passed', function() { var request; request = spec.buildRequests([bid], bidRequestObj)[0]; expect(request.data.site.page).to.equal('prebid.js'); }); it('should set ext.wrap_response to 0 when cache url is set and ignoreBidderCacheKey is true', function() { var request; var origGetConfig = config.getConfig; sinon.stub(config, 'getConfig').callsFake(function (key) { if (key === 'cache') { return { url: 'prebidCacheLocation', ignoreBidderCacheKey: true }; } if (key === 'cache.url') { return 'prebidCacheLocation'; } if (key === 'cache.ignoreBidderCacheKey') { return true; } return origGetConfig.apply(config, arguments); }); request = spec.buildRequests([bid], bidRequestObj)[0]; expect(request.data.ext.wrap_response).to.equal(0); config.getConfig.restore(); }); }); describe('interpretResponse', function() { var serverResponse, bidderRequestObj; beforeEach(function() { bidderRequestObj = { bidRequest: { bids: [{ mediaTypes: { video: { playerSize: [['400', '300']] } }, bidId: 123, params: { player_width: 400, player_height: 300, content_page_url: 'prebid.js', ad_mute: 1, outstream_options: {foo: 'bar'}, outstream_function: 'function' } }, { mediaTypes: { video: { playerSize: [['200', '100']] } }, bidId: 124, params: { player_width: 200, player_height: 100, content_page_url: 'prebid.js', ad_mute: 1, outstream_options: {foo: 'bar'}, outstream_function: 'function' } }] } }; serverResponse = { body: { id: 12345, seatbid: [{ bid: [{ impid: 123, cur: 'USD', price: 12, adomain: ['abc.com'], crid: 321, w: 400, h: 300, ext: { cache_key: 'cache123', slot: 'slot123' } }, { impid: 124, cur: 'USD', price: 13, adomain: ['def.com'], w: 200, h: 100, ext: { cache_key: 'cache124', slot: 'slot124' } }] }] } }; }); it('should return an array of bid responses', function() { var responses = spec.interpretResponse(serverResponse, bidderRequestObj); expect(responses).to.be.an('array').with.length(2); expect(responses[0].cache_key).to.equal('cache123'); expect(responses[0].channel_id).to.equal(12345); expect(responses[0].meta.advertiserDomains[0]).to.equal('abc.com'); expect(responses[0].cpm).to.equal(12); expect(responses[0].creativeId).to.equal(321); expect(responses[0].currency).to.equal('USD'); expect(responses[0].height).to.equal(300); expect(responses[0].mediaType).to.equal('video'); expect(responses[0].netRevenue).to.equal(true); expect(responses[0].requestId).to.equal(123); expect(responses[0].ttl).to.equal(360); expect(responses[0].vastUrl).to.equal('https://search.spotxchange.com/ad/vast.html?key=cache123'); expect(responses[0].videoCacheKey).to.equal('cache123'); expect(responses[0].width).to.equal(400); expect(responses[1].cache_key).to.equal('cache124'); expect(responses[1].channel_id).to.equal(12345); expect(responses[1].cpm).to.equal(13); expect(responses[1].meta.advertiserDomains[0]).to.equal('def.com'); expect(responses[1].creativeId).to.equal(''); expect(responses[1].currency).to.equal('USD'); expect(responses[1].height).to.equal(100); expect(responses[1].mediaType).to.equal('video'); expect(responses[1].netRevenue).to.equal(true); expect(responses[1].requestId).to.equal(124); expect(responses[1].ttl).to.equal(360); expect(responses[1].vastUrl).to.equal('https://search.spotxchange.com/ad/vast.html?key=cache124'); expect(responses[1].videoCacheKey).to.equal('cache124'); expect(responses[1].width).to.equal(200); }); }); describe('outstreamRender', function() { var serverResponse, bidderRequestObj; beforeEach(function() { bidderRequestObj = { bidRequest: { bids: [{ mediaTypes: { video: { playerSize: [['400', '300']] } }, bidId: 123, params: { ad_unit: 'outstream', player_width: 400, player_height: 300, content_page_url: 'prebid.js', outstream_options: { ad_mute: 1, foo: 'bar', slot: 'slot123', playersize_auto_adapt: true, custom_override: { digitrust_opt_out: 1, vast_url: 'bad_vast' } }, } }] } }; serverResponse = { body: { id: 12345, seatbid: [{ bid: [{ impid: 123, cur: 'USD', price: 12, crid: 321, w: 400, h: 300, ext: { cache_key: 'cache123', slot: 'slot123' } }] }] } }; }); it('should attempt to insert the EASI script', function() { var scriptTag; sinon.stub(window.document, 'getElementById').returns({ appendChild: sinon.stub().callsFake(function(script) { scriptTag = script; }) }); var responses = spec.interpretResponse(serverResponse, bidderRequestObj); responses[0].renderer.render(responses[0]); expect(scriptTag.getAttribute('type')).to.equal('text/javascript'); expect(scriptTag.getAttribute('src')).to.equal('https://js.spotx.tv/easi/v1/12345.js'); expect(scriptTag.getAttribute('data-spotx_channel_id')).to.equal('12345'); expect(scriptTag.getAttribute('data-spotx_vast_url')).to.equal('https://search.spotxchange.com/ad/vast.html?key=cache123'); expect(scriptTag.getAttribute('data-spotx_ad_unit')).to.equal('incontent'); expect(scriptTag.getAttribute('data-spotx_collapse')).to.equal('0'); expect(scriptTag.getAttribute('data-spotx_autoplay')).to.equal('1'); expect(scriptTag.getAttribute('data-spotx_blocked_autoplay_override_mode')).to.equal('1'); expect(scriptTag.getAttribute('data-spotx_video_slot_can_autoplay')).to.equal('1'); expect(scriptTag.getAttribute('data-spotx_digitrust_opt_out')).to.equal('1'); expect(scriptTag.getAttribute('data-spotx_content_width')).to.equal('400'); expect(scriptTag.getAttribute('data-spotx_content_height')).to.equal('300'); expect(scriptTag.getAttribute('data-spotx_ad_mute')).to.equal('1'); window.document.getElementById.restore(); }); it('should append into an iframe', function() { var scriptTag; sinon.stub(window.document, 'getElementById').returns({ nodeName: 'IFRAME', contentDocument: { body: { appendChild: sinon.stub().callsFake(function(script) { scriptTag = script; }) } } }); bidderRequestObj.bidRequest.bids[0].params.outstream_options.in_iframe = 'iframeId'; var responses = spec.interpretResponse(serverResponse, bidderRequestObj); responses[0].renderer.render(responses[0]); expect(scriptTag.getAttribute('type')).to.equal('text/javascript'); expect(scriptTag.getAttribute('src')).to.equal('https://js.spotx.tv/easi/v1/12345.js'); expect(scriptTag.getAttribute('data-spotx_channel_id')).to.equal('12345'); expect(scriptTag.getAttribute('data-spotx_vast_url')).to.equal('https://search.spotxchange.com/ad/vast.html?key=cache123'); expect(scriptTag.getAttribute('data-spotx_ad_unit')).to.equal('incontent'); expect(scriptTag.getAttribute('data-spotx_collapse')).to.equal('0'); expect(scriptTag.getAttribute('data-spotx_autoplay')).to.equal('1'); expect(scriptTag.getAttribute('data-spotx_blocked_autoplay_override_mode')).to.equal('1'); expect(scriptTag.getAttribute('data-spotx_video_slot_can_autoplay')).to.equal('1'); expect(scriptTag.getAttribute('data-spotx_digitrust_opt_out')).to.equal('1'); expect(scriptTag.getAttribute('data-spotx_content_width')).to.equal('400'); expect(scriptTag.getAttribute('data-spotx_content_height')).to.equal('300'); window.document.getElementById.restore(); }); it('should adjust width and height to match slot clientWidth if playersize_auto_adapt is used', function() { var scriptTag; sinon.stub(window.document, 'getElementById').returns({ clientWidth: 200, appendChild: sinon.stub().callsFake(function(script) { scriptTag = script; }) }); var responses = spec.interpretResponse(serverResponse, bidderRequestObj); responses[0].renderer.render(responses[0]); expect(scriptTag.getAttribute('type')).to.equal('text/javascript'); expect(scriptTag.getAttribute('src')).to.equal('https://js.spotx.tv/easi/v1/12345.js'); expect(scriptTag.getAttribute('data-spotx_content_width')).to.equal('200'); expect(scriptTag.getAttribute('data-spotx_content_height')).to.equal('150'); window.document.getElementById.restore(); }); it('should use a default 4/3 ratio if playersize_auto_adapt is used and response does not contain width or height', function() { delete serverResponse.body.seatbid[0].bid[0].w; delete serverResponse.body.seatbid[0].bid[0].h; var scriptTag; sinon.stub(window.document, 'getElementById').returns({ clientWidth: 200, appendChild: sinon.stub().callsFake(function(script) { scriptTag = script; }) }); var responses = spec.interpretResponse(serverResponse, bidderRequestObj); responses[0].renderer.render(responses[0]); expect(scriptTag.getAttribute('type')).to.equal('text/javascript'); expect(scriptTag.getAttribute('src')).to.equal('https://js.spotx.tv/easi/v1/12345.js'); expect(scriptTag.getAttribute('data-spotx_content_width')).to.equal('200'); expect(scriptTag.getAttribute('data-spotx_content_height')).to.equal('150'); window.document.getElementById.restore(); }); }); });