diff --git a/modules/showheroes-bsBidAdapter.js b/modules/showheroes-bsBidAdapter.js index 026f89c5faa..afac0a88567 100644 --- a/modules/showheroes-bsBidAdapter.js +++ b/modules/showheroes-bsBidAdapter.js @@ -1,200 +1,114 @@ import { deepAccess, - getWindowTop, + deepSetValue, triggerPixel, - logInfo, - logError, getBidIdParameter + isFn, + logInfo } from '../src/utils.js'; -import { config } from '../src/config.js'; import { Renderer } from '../src/Renderer.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { VIDEO, BANNER } from '../src/mediaTypes.js'; -/** - * See https://github.com/prebid/Prebid.js/pull/4222 for details on linting exception - * ShowHeroes only imports after winning a bid - * Also see https://github.com/prebid/Prebid.js/issues/11656 - */ -// eslint-disable-next-line no-restricted-imports -import { loadExternalScript } from '../src/adloader.js'; -import { MODULE_TYPE_BIDDER } from '../src/activities/modules.js'; +import { VIDEO } from '../src/mediaTypes.js'; -const PROD_ENDPOINT = 'https://bs.showheroes.com/api/v1/bid'; -const STAGE_ENDPOINT = 'https://bid-service.stage.showheroes.com/api/v1/bid'; -const VIRALIZE_ENDPOINT = 'https://ads.viralize.tv/prebid-sh/'; -const PROD_PUBLISHER_TAG = 'https://static.showheroes.com/publishertag.js'; -const STAGE_PUBLISHER_TAG = 'https://pubtag.stage.showheroes.com/publishertag.js'; -const PROD_VL = 'https://video-library.showheroes.com'; -const STAGE_VL = 'https://video-library.stage.showheroes.com'; +const ENDPOINT = 'https://ads.viralize.tv/openrtb2/auction/'; const BIDDER_CODE = 'showheroes-bs'; const TTL = 300; -function getEnvURLs(isStage) { - return { - pubTag: isStage ? STAGE_PUBLISHER_TAG : PROD_PUBLISHER_TAG, - vlHost: isStage ? STAGE_VL : PROD_VL - } -} - -const GVLID = 111; - -export const spec = { - code: BIDDER_CODE, - gvlid: GVLID, - aliases: ['showheroesBs'], - supportedMediaTypes: [VIDEO, BANNER], - isBidRequestValid: function(bid) { - return !!bid.params.playerId || !!bid.params.unitId; +const converter = ortbConverter({ + context: { + netRevenue: true, + ttl: TTL, + currency: 'EUR', + mediaType: VIDEO, }, - buildRequests: function(validBidRequests, bidderRequest) { - let adUnits = []; - const pageURL = validBidRequests[0].params.contentPageUrl || - bidderRequest.refererInfo.canonicalUrl || - deepAccess(window, 'location.href'); - const isStage = !!validBidRequests[0].params.stage; - const isViralize = !!validBidRequests[0].params.unitId; - const isOutstream = deepAccess(validBidRequests[0], 'mediaTypes.video.context') === 'outstream'; - const isCustomRender = deepAccess(validBidRequests[0], 'params.outstreamOptions.customRender'); - const isNodeRender = deepAccess(validBidRequests[0], 'params.outstreamOptions.slot') || deepAccess(validBidRequests[0], 'params.outstreamOptions.iframe'); - const isNativeRender = deepAccess(validBidRequests[0], 'renderer'); - const outstreamOptions = deepAccess(validBidRequests[0], 'params.outstreamOptions'); - const isBanner = !!validBidRequests[0].mediaTypes.banner || (isOutstream && !(isCustomRender || isNativeRender || isNodeRender)); - const defaultSchain = validBidRequests[0].schain || {}; - - const consentData = bidderRequest.gdprConsent || {}; - const uspConsent = bidderRequest.uspConsent || ''; - const gdprConsent = { - apiVersion: consentData.apiVersion || 2, - gdprApplies: consentData.gdprApplies || 0, - consentString: consentData.consentString || '', + imp(buildImp, bidRequest, context) { + const imp = buildImp(bidRequest, context); + const videoContext = deepAccess(bidRequest, 'mediaTypes.video.context'); + deepSetValue(imp, 'video.ext.context', videoContext); + imp.ext = imp.ext || {}; + imp.ext.params = bidRequest.params; + imp.ext.adUnitCode = bidRequest.adUnitCode; + + if (!imp.displaymanager) { + imp.displaymanager = 'Prebid.js'; + imp.displaymanagerver = '$prebid.version$'; // prebid version } - validBidRequests.forEach((bid) => { - const videoSizes = getVideoSizes(bid); - const bannerSizes = getBannerSizes(bid); - const vpaidMode = getBidIdParameter('vpaidMode', bid.params); - - const makeBids = (type, size, isViralize) => { - let context = ''; - let streamType = 2; - - if (type === BANNER) { - streamType = 5; - } else { - context = deepAccess(bid, 'mediaTypes.video.context'); - if (vpaidMode && context === 'instream') { - streamType = 1; - } - if (context === 'outstream') { - streamType = 5; - } - } + if (!isFn(bidRequest.getFloor)) { + return imp + } - let rBid = { - type: streamType, - adUnitCode: bid.adUnitCode, - bidId: bid.bidId, - context: context, - // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781 - auctionId: bidderRequest.auctionId, - start: +new Date(), - timeout: 3000, - params: bid.params, - schain: bid.schain || defaultSchain - }; + let floor = bidRequest.getFloor({ + currency: 'EUR', + mediaType: '*', + size: '*', + }); + if (!isNaN(floor?.floor) && floor?.currency === 'EUR') { + imp.bidfloor = floor.floor; + imp.bidfloorcur = 'EUR'; + } + return imp; + }, - if (isViralize) { - rBid.unitId = getBidIdParameter('unitId', bid.params); - rBid.sizes = size; - rBid.mediaTypes = { - [type]: {'context': context} - }; - } else { - rBid.playerId = getBidIdParameter('playerId', bid.params); - rBid.mediaType = type; - rBid.size = { - width: size[0], - height: size[1] - }; - rBid.gdprConsent = gdprConsent; - rBid.uspConsent = uspConsent; - } + bidResponse(buildBidResponse, bid, context) { + const bidResponse = buildBidResponse(bid, context); - return rBid; + if (context.imp?.video?.ext?.context === 'outstream') { + const renderConfig = { + rendererUrl: bid.ext?.rendererConfig?.rendererUrl, + renderFunc: bid.ext?.rendererConfig?.renderFunc, + renderOptions: bid.ext?.rendererConfig?.renderOptions, }; - - if (isViralize) { - if (videoSizes && videoSizes[0]) { - adUnits.push(makeBids(VIDEO, videoSizes, isViralize)); - } - if (bannerSizes && bannerSizes[0]) { - adUnits.push(makeBids(BANNER, bannerSizes, isViralize)); - } - } else { - videoSizes.forEach((size) => { - adUnits.push(makeBids(VIDEO, size)); - }); - - bannerSizes.forEach((size) => { - adUnits.push(makeBids(BANNER, size)); - }); + if (renderConfig.renderFunc && renderConfig.rendererUrl) { + bidResponse.renderer = createRenderer(bidResponse, renderConfig); } - }); - - let endpointUrl; - let data; + } + bidResponse.callbacks = bid.ext?.callbacks; + bidResponse.extra = bid.ext?.extra; + return bidResponse; + }, +}) - const QA = validBidRequests[0].params.qa || {}; +const GVLID = 111; - if (isViralize) { - endpointUrl = VIRALIZE_ENDPOINT; - data = { - 'bidRequests': adUnits, - 'context': { - 'gdprConsent': gdprConsent, - 'uspConsent': uspConsent, - 'schain': defaultSchain, - 'pageURL': QA.pageURL || encodeURIComponent(pageURL) - } - } - } else { - endpointUrl = isStage ? STAGE_ENDPOINT : PROD_ENDPOINT; +export const spec = { + code: BIDDER_CODE, + gvlid: GVLID, + aliases: ['showheroesBs'], + supportedMediaTypes: [VIDEO], + isBidRequestValid: (bid) => { + return !!bid.params.unitId; + }, + buildRequests: (bidRequests, bidderRequest) => { + const QA = bidRequests[0].params.qa; - data = { - 'user': [], - 'meta': { - 'adapterVersion': 2, - 'pageURL': QA.pageURL || encodeURIComponent(pageURL), - 'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner && !outstreamOptions) || false, - 'isDesktop': getWindowTop().document.documentElement.clientWidth > 700, - 'xmlAndTag': !!(isOutstream && isCustomRender) || false, - 'stage': isStage || undefined - }, - 'requests': adUnits, - 'debug': validBidRequests[0].params.debug || false, - } - } + const ortbData = converter.toORTB({ bidRequests, bidderRequest }) return { - url: QA.endpoint || endpointUrl, + url: QA?.endpoint || ENDPOINT, method: 'POST', - options: {contentType: 'application/json', accept: 'application/json'}, - data: data + data: ortbData, }; }, - interpretResponse: function(response, request) { - return createBids(response.body, request.data); + interpretResponse: (response, request) => { + if (!response.body) { + return []; + } + + const bids = converter.fromORTB({response: response.body, request: request.data}).bids; + return bids; }, - getUserSyncs: function(syncOptions, serverResponses) { + getUserSyncs: (syncOptions, serverResponses) => { const syncs = []; - if (!serverResponses.length || !serverResponses[0].body.userSync) { + if (!serverResponses.length || !serverResponses[0].body?.ext?.userSync) { return syncs; } - const userSync = serverResponses[0].body.userSync; + const userSync = serverResponses[0].body.ext.userSync; - if (syncOptions.iframeEnabled) { - (userSync.iframes || []).forEach(url => { + if (syncOptions.iframeEnabled && userSync?.iframes?.length) { + userSync.iframes.forEach(url => { syncs.push({ type: 'iframe', url @@ -210,6 +124,7 @@ export const spec = { }); }); } + return syncs; }, @@ -223,177 +138,33 @@ export const spec = { }, }; -function createBids(bidRes, reqData) { - if (!bidRes) { - return []; - } - const responseBids = bidRes.bids || bidRes.bidResponses; - if (!Array.isArray(responseBids) || responseBids.length < 1) { - return []; - } - - const bids = []; - const bidMap = {}; - (reqData.requests || reqData.bidRequests || []).forEach((bid) => { - bidMap[bid.bidId] = bid; - }); - - responseBids.forEach(function (bid) { - const requestId = bid.bidId || bid.requestId; - const reqBid = bidMap[requestId]; - const currentBidParams = reqBid.params; - const isViralize = !!reqBid.params.unitId; - const size = { - width: bid.width || bid.size.width, - height: bid.height || bid.size.height - }; - - let bidUnit = {}; - bidUnit.cpm = bid.cpm; - bidUnit.requestId = requestId; - bidUnit.adUnitCode = reqBid.adUnitCode; - bidUnit.currency = bid.currency; - bidUnit.mediaType = bid.mediaType || VIDEO; - bidUnit.ttl = TTL; - bidUnit.creativeId = 'c_' + requestId; - bidUnit.netRevenue = true; - bidUnit.width = size.width; - bidUnit.height = size.height; - bidUnit.meta = { - advertiserDomains: bid.adomain || [] - }; - if (bid.vastXml) { - bidUnit.vastXml = bid.vastXml; - bidUnit.adResponse = { - content: bid.vastXml, - }; - } - if (bid.vastTag || bid.vastUrl) { - bidUnit.vastUrl = bid.vastTag || bid.vastUrl; +function outstreamRender(response, renderConfig) { + response.renderer.push(() => { + const func = deepAccess(window, renderConfig.renderFunc); + if (!isFn(func)) { + return; } - if (bid.mediaType === BANNER) { - bidUnit.ad = getBannerHtml(bid, reqBid, reqData); - } else if (bid.context === 'outstream') { - const renderer = Renderer.install({ - id: requestId, - url: 'https://static.showheroes.com/renderer.js', - adUnitCode: reqBid.adUnitCode, - config: { - playerId: reqBid.playerId, - width: size.width, - height: size.height, - vastUrl: bid.vastTag, - vastXml: bid.vastXml, - ad: bid.ad, - debug: reqData.debug, - isStage: reqData.meta && !!reqData.meta.stage, - isViralize: isViralize, - customRender: getBidIdParameter('customRender', currentBidParams.outstreamOptions), - slot: getBidIdParameter('slot', currentBidParams.outstreamOptions), - iframe: getBidIdParameter('iframe', currentBidParams.outstreamOptions), - } - }); - renderer.setRender(outstreamRender); - bidUnit.renderer = renderer; + const renderPayload = { ...renderConfig.renderOptions }; + if (response.vastXml) { + renderPayload.adResponse = { + content: response.vastXml, + }; } - bids.push(bidUnit); + func(renderPayload); }); - - return bids; } -function outstreamRender(bid) { - let embedCode; - if (bid.renderer.config.isViralize) { - embedCode = createOutstreamEmbedCodeV2(bid); - } else { - embedCode = createOutstreamEmbedCode(bid); - } - if (typeof bid.renderer.config.customRender === 'function') { - bid.renderer.config.customRender(bid, embedCode); - } else { - try { - const inIframe = getBidIdParameter('iframe', bid.renderer.config); - if (inIframe && window.document.getElementById(inIframe).nodeName === 'IFRAME') { - const iframe = window.document.getElementById(inIframe); - let framedoc = iframe.contentDocument || (iframe.contentWindow && iframe.contentWindow.document); - framedoc.body.appendChild(embedCode); - return; - } - - const slot = getBidIdParameter('slot', bid.renderer.config) || bid.adUnitCode; - if (slot && window.document.getElementById(slot)) { - window.document.getElementById(slot).appendChild(embedCode); - } else if (slot) { - logError('[ShowHeroes][renderer] Error: spot not found'); - } - } catch (err) { - logError('[ShowHeroes][renderer] Error:' + err.message); - } - } -} - -function createOutstreamEmbedCode(bid) { - const isStage = getBidIdParameter('isStage', bid.renderer.config); - const urls = getEnvURLs(isStage); - - const fragment = window.document.createDocumentFragment(); - - let script = loadExternalScript(urls.pubTag, MODULE_TYPE_BIDDER, 'showheroes-bs', function () { - window.ShowheroesTag = this; +function createRenderer(bid, renderConfig) { + const renderer = Renderer.install({ + id: bid.id, + url: renderConfig.rendererUrl, + loaded: false, + adUnitCode: bid.adUnitCode, }); - script.setAttribute('data-player-host', urls.vlHost); - - const spot = window.document.createElement('div'); - spot.setAttribute('class', 'showheroes-spot'); - spot.setAttribute('data-player', getBidIdParameter('playerId', bid.renderer.config)); - spot.setAttribute('data-debug', getBidIdParameter('debug', bid.renderer.config)); - spot.setAttribute('data-ad-vast-tag', getBidIdParameter('vastUrl', bid.renderer.config)); - spot.setAttribute('data-stream-type', 'outstream'); - - fragment.appendChild(spot); - fragment.appendChild(script); - return fragment; -} - -function createOutstreamEmbedCodeV2(bid) { - const range = document.createRange(); - range.selectNode(document.getElementsByTagName('body')[0]); - return range.createContextualFragment(getBidIdParameter('ad', bid.renderer.config)); -} - -function getBannerHtml (bid, reqBid, reqData) { - const isStage = !!reqData.meta.stage; - const urls = getEnvURLs(isStage); - return ` -
- - - - - `; -} - -function getVideoSizes(bidRequest) { - return formatSizes(deepAccess(bidRequest, 'mediaTypes.video.playerSize') || []); -} - -function getBannerSizes(bidRequest) { - return formatSizes(deepAccess(bidRequest, 'mediaTypes.banner.sizes') || []); -} - -function formatSizes(sizes) { - if (!sizes || !sizes.length) { - return [] - } - return Array.isArray(sizes[0]) ? sizes : [sizes]; + renderer.setRender((render) => { + return outstreamRender(render, renderConfig); + }); + return renderer; } registerBidder(spec); diff --git a/modules/showheroes-bsBidAdapter.md b/modules/showheroes-bsBidAdapter.md index a32a77a2525..f306593a783 100644 --- a/modules/showheroes-bsBidAdapter.md +++ b/modules/showheroes-bsBidAdapter.md @@ -1,16 +1,14 @@ # Overview +``` Module Name: ShowHeroes Bidder Adapter - Module Type: Bidder Adapter - Alias: showheroesBs - Maintainer: tech@showheroes.com - +``` # Description -Module that connects to ShowHeroes demand source to fetch bids. +A module that connects to ShowHeroes demand source to fetch bids. # Test Parameters ``` @@ -27,122 +25,7 @@ Module that connects to ShowHeroes demand source to fetch bids. { bidder: "showheroes-bs", params: { - playerId: '0151f985-fb1a-4f37-bb26-cfc62e43ec05', - vpaidMode: true // by default is 'false' - } - } - ] - }, - { - // if you have adSlot renderer or oustream should be returned as banner - code: 'video', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'outstream', - } - }, - bids: [ - { - bidder: "showheroes-bs", - params: { - playerId: '0151f985-fb1a-4f37-bb26-cfc62e43ec05', - } - } - ] - }, - { - code: 'video', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'outstream', - } - }, - bids: [ - { - bidder: "showheroes-bs", - params: { - playerId: '0151f985-fb1a-4f37-bb26-cfc62e43ec05', - - outstreamOptions: { - // Required for the outstream renderer to exact node, one of - iframe: 'iframe_id', - // or - slot: 'slot_id' - } - } - } - ] - }, - { - code: 'video', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'outstream', - } - }, - bids: [ - { - bidder: "showheroes-bs", - params: { - playerId: '0151f985-fb1a-4f37-bb26-cfc62e43ec05', - - outstreamOptions: { - // Custom outstream rendering function - customRender: function(bid, embedCode) { - // Example with embedCode - someContainer.appendChild(embedCode); - - // bid config data - var vastUrl = bid.renderer.config.vastUrl; - var vastXML = bid.renderer.config.vastXML; - var videoWidth = bid.renderer.config.width; - var videoHeight = bid.renderer.config.height; - var playerId = bid.renderer.config.playerId; - }, - } - } - } - ] - }, - { - code: 'banner', - mediaTypes: { - banner: { - sizes: [[640, 480]], - } - }, - bids: [ - { - bidder: "showheroes-bs", - params: { - playerId: '0151f985-fb1a-4f37-bb26-cfc62e43ec05', - } - } - ] - } - ]; -``` - -# Test Parameters (V2) -``` - var adUnits = [ - { - code: 'video', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream', - } - }, - bids: [ - { - bidder: "showheroes-bs", - params: { - unitId: 'AACBWAcof-611K4U', - vpaidMode: true // by default is 'false' + unitId: '1234abcd-5678efgh', } } ] @@ -159,18 +42,10 @@ Module that connects to ShowHeroes demand source to fetch bids. { bidder: "showheroes-bs", params: { - unitId: 'AACBTwsZVANd9NlB', - - outstreamOptions: { - // Required for the outstream renderer to exact node, one of - iframe: 'iframe_id', - // or - slot: 'slot_id' - } + unitId: '1234abcd-5678efgh', } } ] } ]; ``` - diff --git a/test/spec/modules/showheroes-bsBidAdapter_spec.js b/test/spec/modules/showheroes-bsBidAdapter_spec.js index 30e95b04ccf..b03f6eb9a8a 100644 --- a/test/spec/modules/showheroes-bsBidAdapter_spec.js +++ b/test/spec/modules/showheroes-bsBidAdapter_spec.js @@ -1,98 +1,67 @@ -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' +import { expect } from 'chai' +import { spec } from 'modules/showheroes-bsBidAdapter.js' +import { syncAddFPDToBidderRequest } from '../../helpers/fpd.js'; +import 'modules/priceFloors.js'; +import 'modules/consentManagementTcf.js'; +import 'modules/consentManagementUsp.js'; +import 'modules/schain.js'; +import { VIDEO } from 'src/mediaTypes.js' const bidderRequest = { refererInfo: { - canonicalUrl: 'https://example.com' + page: 'https://example.com/home', + ref: 'https://referrer' } } const adomain = ['showheroes.com']; const gdpr = { - 'gdprConsent': { - 'apiVersion': 2, - 'consentString': 'BOEFEAyOEFEAyAHABDENAI4AAAB9vABAASA', - 'gdprApplies': true + gdprConsent: { + apiVersion: 2, + consentString: 'CONSENT', + vendorData: { purpose: { consents: { 1: true } } }, + gdprApplies: true, } } const uspConsent = '1---'; const schain = { - 'schain': { - 'validation': 'strict', - 'config': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ + schain: { + validation: 'strict', + config: { + ver: '1.0', + complete: 1, + nodes: [ { - 'asi': 'some.com', - 'sid': '00001', - 'hp': 1 + 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 bidRequestCommonParamsV2 = { - 'bidder': 'showheroes-bs', - 'params': { - 'unitId': 'AACBWAcof-611K4U', + bidder: 'showheroes-bs', + params: { + unitId: 'AACBWAcof-611K4U', }, - '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', - } - } - } + adUnitCode: 'adunit-code-1', + bidId: '38b373e1e31c18', + bidderRequestId: '12e3ade2543ba6', + auctionId: '43aa080090a47f', } const bidRequestVideoV2 = { ...bidRequestCommonParamsV2, ...{ - 'mediaTypes': { - 'video': { - 'playerSize': [640, 480], - 'context': 'instream', + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'instream', } } } @@ -101,541 +70,188 @@ const bidRequestVideoV2 = { const bidRequestOutstreamV2 = { ...bidRequestCommonParamsV2, ...{ - '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]] - } + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'outstream' + }, } } } -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 requestV1 = { - 'params': { - 'playerId': '47427aa0-f11a-4d24-abca-1295a46a46cd', - } - } - expect(spec.isBidRequestValid(requestV1)).to.equal(true) - - const requestV2 = { - 'params': { - 'unitId': 'AACBTwsZVANd9NlB', - } - } - expect(spec.isBidRequestValid(requestV2)).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') - - const requestV2 = spec.buildRequests([bidRequestVideoV2], bidderRequest) - expect(requestV2.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('should attach valid params to the payload when type is video (instream V2)', function () { - const request = spec.buildRequests([bidRequestVideoV2], bidderRequest) - const payload = request.data.bidRequests[0]; - expect(payload).to.be.an('object'); - expect(payload).to.have.property('unitId', 'AACBWAcof-611K4U'); - expect(payload.mediaTypes).to.eql({ - [VIDEO]: { - 'context': 'instream' - } - }); - }) - - it('should attach valid params to the payload when type is video (outstream V2)', function () { - const request = spec.buildRequests([bidRequestOutstreamV2], bidderRequest) - const payload = request.data.bidRequests[0]; - expect(payload).to.be.an('object'); - expect(payload).to.have.property('unitId', 'AACBWAcof-611K4U'); - expect(payload.mediaTypes).to.eql({ - [VIDEO]: { - 'context': 'outstream' - } - }); - }) - - it('passes gdpr & uspConsent if present', function () { - const request = spec.buildRequests([bidRequestVideo], { - ...bidderRequest, - ...gdpr, - uspConsent, - }) - const payload = request.data.requests[0]; - expect(payload).to.be.an('object'); - expect(payload.gdprConsent).to.eql(gdpr.gdprConsent) - expect(payload.uspConsent).to.eql(uspConsent) - }) - - it('passes gdpr & usp if present (V2)', function () { - const request = spec.buildRequests([bidRequestVideoV2], { - ...bidderRequest, - ...gdpr, - uspConsent, - }) - const context = request.data.context; - expect(context).to.be.an('object'); - expect(context.gdprConsent).to.eql(gdpr.gdprConsent) - expect(context.uspConsent).to.eql(uspConsent) - }) - - 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); - }) - - it('passes schain object if present (V2)', function() { - const request = spec.buildRequests([{ - ...bidRequestVideoV2, - ...schain - }], bidderRequest) - const context = request.data.context; - expect(context).to.be.an('object'); - expect(context.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://test.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 = '