From d56d24893fbca270d5fa156aeed61d3376c3ce31 Mon Sep 17 00:00:00 2001 From: Patrick McCann Date: Mon, 8 May 2023 14:10:24 -0400 Subject: [PATCH] Prebid 8: Delete emx (#9918) * Delete emx_digitalBidAdapter.js * Delete emx_digitalBidAdapter.md * Delete emx_digitalBidAdapter_spec.js --- modules/emx_digitalBidAdapter.js | 400 --------- modules/emx_digitalBidAdapter.md | 62 -- .../modules/emx_digitalBidAdapter_spec.js | 768 ------------------ 3 files changed, 1230 deletions(-) delete mode 100644 modules/emx_digitalBidAdapter.js delete mode 100644 modules/emx_digitalBidAdapter.md delete mode 100644 test/spec/modules/emx_digitalBidAdapter_spec.js diff --git a/modules/emx_digitalBidAdapter.js b/modules/emx_digitalBidAdapter.js deleted file mode 100644 index 99f313b9484..00000000000 --- a/modules/emx_digitalBidAdapter.js +++ /dev/null @@ -1,400 +0,0 @@ -import { - _each, - deepAccess, - getBidIdParameter, - isArray, - isFn, - isPlainObject, - isStr, - logError, - logWarn -} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {Renderer} from '../src/Renderer.js'; -import {find, includes} from '../src/polyfill.js'; -import {parseDomain} from '../src/refererDetection.js'; - -const BIDDER_CODE = 'emx_digital'; -const ENDPOINT = 'hb.emxdgt.com'; -const RENDERER_URL = 'https://js.brealtime.com/outstream/1.30.0/bundle.js'; -const ADAPTER_VERSION = '1.5.1'; -const DEFAULT_CUR = 'USD'; - -const EIDS_SUPPORTED = [ - { key: 'idl_env', source: 'liveramp.com', rtiPartner: 'idl', queryParam: 'idl' }, - { key: 'uid2.id', source: 'uidapi.com', rtiPartner: 'UID2', queryParam: 'uid2' } -]; - -export const emxAdapter = { - validateSizes: (sizes) => { - if (!isArray(sizes) || typeof sizes[0] === 'undefined') { - logWarn(BIDDER_CODE + ': Sizes should be an array'); - return false; - } - return sizes.every(size => isArray(size) && size.length === 2); - }, - checkVideoContext: (bid) => { - return ((bid && bid.mediaTypes && bid.mediaTypes.video && bid.mediaTypes.video.context) && ((bid.mediaTypes.video.context === 'instream') || (bid.mediaTypes.video.context === 'outstream'))); - }, - buildBanner: (bid) => { - let sizes = []; - bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes ? sizes = bid.mediaTypes.banner.sizes : sizes = bid.sizes; - if (!emxAdapter.validateSizes(sizes)) { - logWarn(BIDDER_CODE + ': could not detect mediaType banner sizes. Assigning to bid sizes instead'); - sizes = bid.sizes - } - return { - format: sizes.map((size) => { - return { - w: size[0], - h: size[1] - }; - }), - w: sizes[0][0], - h: sizes[0][1] - }; - }, - formatVideoResponse: (bidResponse, emxBid, bidRequest) => { - bidResponse.vastXml = emxBid.adm; - if (bidRequest.bidderRequest && bidRequest.bidderRequest.bids && bidRequest.bidderRequest.bids.length > 0) { - const matchingBid = find(bidRequest.bidderRequest.bids, bid => bidResponse.requestId && bid.bidId && bidResponse.requestId === bid.bidId && bid.mediaTypes && bid.mediaTypes.video && bid.mediaTypes.video.context === 'outstream'); - if (matchingBid) { - bidResponse.renderer = emxAdapter.createRenderer(bidResponse, { - id: emxBid.id, - url: RENDERER_URL - }); - } - } - return bidResponse; - }, - isMobile: () => { - return (/(ios|ipod|ipad|iphone|android)/i).test(navigator.userAgent); - }, - isConnectedTV: () => { - return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(navigator.userAgent); - }, - getDevice: () => { - return { - ua: navigator.userAgent, - js: 1, - dnt: (navigator.doNotTrack === 'yes' || navigator.doNotTrack === '1' || navigator.msDoNotTrack === '1') ? 1 : 0, - h: screen.height, - w: screen.width, - devicetype: emxAdapter.isMobile() ? 1 : emxAdapter.isConnectedTV() ? 3 : 2, - language: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage), - }; - }, - cleanProtocols: (video) => { - if (video.protocols && includes(video.protocols, 7)) { - // not supporting VAST protocol 7 (VAST 4.0); - logWarn(BIDDER_CODE + ': VAST 4.0 is currently not supported. This protocol has been filtered out of the request.'); - video.protocols = video.protocols.filter(protocol => protocol !== 7); - } - return video; - }, - outstreamRender: (bid) => { - bid.renderer.push(function () { - let params = (bid && bid.params && bid.params[0] && bid.params[0].video) ? bid.params[0].video : {}; - window.emxVideoQueue = window.emxVideoQueue || []; - window.queueEmxVideo({ - id: bid.adUnitCode, - adsResponses: bid.vastXml, - options: params - }); - if (window.emxVideoReady && window.videojs) { - window.emxVideoReady(); - } - }); - }, - createRenderer: (bid, rendererParams) => { - const renderer = Renderer.install({ - id: rendererParams.id, - url: RENDERER_URL, - loaded: false - }); - try { - renderer.setRender(emxAdapter.outstreamRender); - } catch (err) { - logWarn('Prebid Error calling setRender on renderer', err); - } - - return renderer; - }, - buildVideo: (bid) => { - let videoObj = Object.assign(bid.mediaTypes.video, bid.params.video); - - if (isArray(bid.mediaTypes.video.playerSize[0])) { - videoObj['w'] = bid.mediaTypes.video.playerSize[0][0]; - videoObj['h'] = bid.mediaTypes.video.playerSize[0][1]; - } else { - videoObj['w'] = bid.mediaTypes.video.playerSize[0]; - videoObj['h'] = bid.mediaTypes.video.playerSize[1]; - } - return emxAdapter.cleanProtocols(videoObj); - }, - parseResponse: (bidResponseAdm) => { - try { - return decodeURIComponent(bidResponseAdm.replace(/%(?![0-9][0-9a-fA-F]+)/g, '%25')); - } catch (err) { - logError('emx_digitalBidAdapter', 'error', err); - } - }, - getSite: (refInfo) => { - // TODO: do the fallbacks make sense? - return { - domain: refInfo.domain || parseDomain(refInfo.topmostLocation), - page: refInfo.page || refInfo.topmostLocation, - ref: refInfo.ref || window.document.referrer - } - }, - getGdpr: (bidRequests, emxData) => { - if (bidRequests.gdprConsent) { - emxData.regs = { - ext: { - gdpr: bidRequests.gdprConsent.gdprApplies === true ? 1 : 0 - } - }; - } - if (bidRequests.gdprConsent && bidRequests.gdprConsent.gdprApplies) { - emxData.user = { - ext: { - consent: bidRequests.gdprConsent.consentString - } - }; - } - - return emxData; - }, - getSupplyChain: (bidderRequest, emxData) => { - if (bidderRequest.bids[0] && bidderRequest.bids[0].schain) { - emxData.source = { - ext: { - schain: bidderRequest.bids[0].schain - } - }; - } - - return emxData; - }, - // supporting eids - getEids(bidRequests) { - return EIDS_SUPPORTED - .map(emxAdapter.getUserId(bidRequests)) - .filter(x => x); - }, - getUserId(bidRequests) { - return ({ key, source, rtiPartner }) => { - let id = deepAccess(bidRequests, `userId.${key}`); - return id ? emxAdapter.formatEid(id, source, rtiPartner) : null; - }; - }, - formatEid(id, source, rtiPartner) { - return { - source, - uids: [{ - id, - ext: { rtiPartner } - }] - }; - } -}; - -export const spec = { - code: BIDDER_CODE, - gvlid: 183, - supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid: function (bid) { - if (!bid || !bid.params) { - logWarn(BIDDER_CODE + ': Missing bid or bid params.'); - return false; - } - - if (bid.bidder !== BIDDER_CODE) { - logWarn(BIDDER_CODE + ': Must use "emx_digital" as bidder code.'); - return false; - } - - if (!bid.params.tagid || !isStr(bid.params.tagid)) { - logWarn(BIDDER_CODE + ': Missing tagid param or tagid present and not type String.'); - return false; - } - - if (bid.mediaTypes && bid.mediaTypes.banner) { - let sizes; - bid.mediaTypes.banner.sizes ? sizes = bid.mediaTypes.banner.sizes : sizes = bid.sizes; - if (!emxAdapter.validateSizes(sizes)) { - logWarn(BIDDER_CODE + ': Missing sizes in bid'); - return false; - } - } else if (bid.mediaTypes && bid.mediaTypes.video) { - if (!emxAdapter.checkVideoContext(bid)) { - logWarn(BIDDER_CODE + ': Missing video context: instream or outstream'); - return false; - } - - if (!bid.mediaTypes.video.playerSize) { - logWarn(BIDDER_CODE + ': Missing video playerSize'); - return false; - } - } - - return true; - }, - buildRequests: function (validBidRequests, bidderRequest) { - const emxImps = []; - const timeout = bidderRequest.timeout || ''; - const timestamp = Date.now(); - const url = 'https://' + ENDPOINT + ('?t=' + timeout + '&ts=' + timestamp + '&src=pbjs'); - const secure = location.protocol.indexOf('https') > -1 ? 1 : 0; - const device = emxAdapter.getDevice(); - const site = emxAdapter.getSite(bidderRequest.refererInfo); - - _each(validBidRequests, function (bid) { - let tagid = getBidIdParameter('tagid', bid.params); - let bidfloor = parseFloat(getBidFloor(bid)) || 0; - let isVideo = !!bid.mediaTypes.video; - let data = { - id: bid.bidId, - tid: bid.transactionId, - tagid, - secure - }; - - // adding gpid support - let gpid = deepAccess(bid, 'ortb2Imp.ext.data.adserver.adslot'); - if (!gpid) { - gpid = deepAccess(bid, 'ortb2Imp.ext.data.pbadslot'); - } - if (gpid) { - data.ext = {gpid: gpid.toString()}; - } - let typeSpecifics = isVideo ? { video: emxAdapter.buildVideo(bid) } : { banner: emxAdapter.buildBanner(bid) }; - let bidfloorObj = bidfloor > 0 ? { bidfloor, bidfloorcur: DEFAULT_CUR } : {}; - let emxBid = Object.assign(data, typeSpecifics, bidfloorObj); - emxImps.push(emxBid); - }); - - let emxData = { - id: bidderRequest.auctionId, - imp: emxImps, - device, - site, - cur: DEFAULT_CUR, - version: ADAPTER_VERSION - }; - - emxData = emxAdapter.getGdpr(bidderRequest, Object.assign({}, emxData)); - emxData = emxAdapter.getSupplyChain(bidderRequest, Object.assign({}, emxData)); - if (bidderRequest && bidderRequest.uspConsent) { - emxData.us_privacy = bidderRequest.uspConsent; - } - - // adding eid support - if (bidderRequest.userId) { - let eids = emxAdapter.getEids(bidderRequest); - if (eids.length > 0) { - if (emxData.user && emxData.user.ext) { - emxData.user.ext.eids = eids; - } else { - emxData.user = { - ext: {eids} - }; - } - } - } - - return { - method: 'POST', - url, - data: JSON.stringify(emxData), - options: { - withCredentials: true - }, - bidderRequest - }; - }, - interpretResponse: function (serverResponse, bidRequest) { - let emxBidResponses = []; - let response = serverResponse.body || {}; - if (response.seatbid && response.seatbid.length > 0 && response.seatbid[0].bid) { - response.seatbid.forEach(function (emxBid) { - emxBid = emxBid.bid[0]; - let isVideo = false; - let adm = emxAdapter.parseResponse(emxBid.adm) || ''; - let bidResponse = { - requestId: emxBid.id, - cpm: emxBid.price, - width: emxBid.w, - height: emxBid.h, - creativeId: emxBid.crid || emxBid.id, - dealId: emxBid.dealid || null, - currency: 'USD', - netRevenue: true, - ttl: emxBid.ttl, - ad: adm - }; - if (emxBid.adm && emxBid.adm.indexOf(' -1) { - isVideo = true; - bidResponse = emxAdapter.formatVideoResponse(bidResponse, Object.assign({}, emxBid), bidRequest); - } - bidResponse.mediaType = (isVideo ? VIDEO : BANNER); - - // support for adomain in prebid 5.0 - if (emxBid.adomain && emxBid.adomain.length) { - bidResponse.meta = { - advertiserDomains: emxBid.adomain - }; - } - - emxBidResponses.push(bidResponse); - }); - } - return emxBidResponses; - }, - getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) { - const syncs = []; - const consentParams = []; - if (syncOptions.iframeEnabled) { - let url = 'https://biddr.brealtime.com/check.html'; - if (gdprConsent && typeof gdprConsent.consentString === 'string') { - // add 'gdpr' only if 'gdprApplies' is defined - if (typeof gdprConsent.gdprApplies === 'boolean') { - consentParams.push(`gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`); - } else { - consentParams.push(`?gdpr_consent=${gdprConsent.consentString}`); - } - } - if (uspConsent && typeof uspConsent.consentString === 'string') { - consentParams.push(`usp=${uspConsent.consentString}`); - } - if (consentParams.length > 0) { - url = url + '?' + consentParams.join('&'); - } - syncs.push({ - type: 'iframe', - url: url - }); - } - return syncs; - } -}; - -// support floors module in prebid 5.0 -function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return parseFloat(getBidIdParameter('bidfloor', bid.params)); - } - - let floor = bid.getFloor({ - currency: DEFAULT_CUR, - mediaType: '*', - size: '*' - }); - if (isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === 'USD') { - return floor.floor; - } - return null; -} - -registerBidder(spec); diff --git a/modules/emx_digitalBidAdapter.md b/modules/emx_digitalBidAdapter.md deleted file mode 100644 index 03ba554c5ad..00000000000 --- a/modules/emx_digitalBidAdapter.md +++ /dev/null @@ -1,62 +0,0 @@ -# Overview - -``` -Module Name: EMX Digital Adapter -Module Type: Bidder Adapter -Maintainer: git@emxdigital.com -``` - -# Description - -The EMX Digital adapter provides publishers with access to the EMX Marketplace. The adapter is GDPR compliant. Please note that the adapter supports Banner and Video (Instream & Outstream) media types. - -Note: The EMX Digital adapter requires approval and implementation guidelines from the EMX team, including existing publishers that work with EMX Digital. Please reach out to your account manager or prebid@emxdigital.com for more information. - -The bidder code should be ```emx_digital``` -The params used by the bidder are : -```tagid``` - string (mandatory) -```bidfloor``` - string (optional) - -# Test Parameters -``` -var adUnits = [{ - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [ - [300, 250], [300, 600] - } - }, - bids: [ - { - bidder: 'emx_digital', - params: { - tagid: '25251', - } - }] -}]; -``` - -# Video Example -``` -var adUnits = [{ - code: 'video-div', - mediaTypes: { - video: { - context: 'instream', // also applicable for 'outstream' - playerSize: [640, 480] - } - }, - bids: [ - { - bidder: 'emx_digital', - params: { - tagid: '25251', - video: { - skippable: true, - playback_methods: ['auto_play_sound_off'] - } - } - }] -}]; -``` diff --git a/test/spec/modules/emx_digitalBidAdapter_spec.js b/test/spec/modules/emx_digitalBidAdapter_spec.js deleted file mode 100644 index d80d0f3e875..00000000000 --- a/test/spec/modules/emx_digitalBidAdapter_spec.js +++ /dev/null @@ -1,768 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/emx_digitalBidAdapter.js'; -import * as utils from 'src/utils.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('emx_digital Adapter', function () { - describe('callBids', function () { - const adapter = newBidder(spec); - it('exists and is a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - describe('banner request validity', function () { - let bid = { - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - let badBid = { - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251' - }, - 'mediaTypes': { - 'banner': { - } - }, - 'adUnitCode': 'adunit-code', - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - let noBid = {}; - let otherBid = { - 'bidder': 'emxdigital', - 'params': { - 'tagid': '25251' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - let noMediaSizeBid = { - 'bidder': 'emxdigital', - 'params': { - 'tagid': '25251' - }, - 'mediaTypes': { - 'banner': {} - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - expect(spec.isBidRequestValid(badBid)).to.equal(false); - expect(spec.isBidRequestValid(noBid)).to.equal(false); - expect(spec.isBidRequestValid(otherBid)).to.equal(false); - expect(spec.isBidRequestValid(noMediaSizeBid)).to.equal(false); - }); - }); - - describe('video request validity', function () { - let bid = { - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251', - 'video': {} - }, - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': [640, 480] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - let noInstreamBid = { - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251', - 'video': { - 'protocols': [1, 7] - } - }, - 'mediaTypes': { - 'video': { - 'context': 'something_random' - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - - let outstreamBid = { - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251', - 'video': {} - }, - 'mediaTypes': { - 'video': { - 'context': 'outstream', - 'playerSize': [640, 480] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - expect(spec.isBidRequestValid(noInstreamBid)).to.equal(false); - expect(spec.isBidRequestValid(outstreamBid)).to.equal(true); - }); - - it('should contain tagid param', function () { - expect(spec.isBidRequestValid({ - bidder: 'emx_digital', - params: {}, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - bidder: 'emx_digital', - params: { - tagid: '' - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - bidder: 'emx_digital', - params: { - tagid: '123' - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - })).to.equal(true); - }); - }); - }); - - describe('buildRequests', function () { - let bidderRequest = { - 'bidderCode': 'emx_digital', - 'auctionId': 'e19f1eff-8b27-42a6-888d-9674e5a6130c', - 'bidderRequestId': '22edbae3120bf6', - 'timeout': 1500, - 'refererInfo': { - 'numIframes': 0, - 'reachedTop': true, - 'page': 'https://example.com/index.html?pbjs_debug=true', - 'domain': 'example.com', - 'ref': 'https://referrer.com' - }, - 'bids': [{ - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [300, 250], - [300, 600] - ] - } - }, - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'auctionId': 'e19f1eff-8b27-42a6-888d-9674e5a6130c', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - }] - }; - let request = spec.buildRequests(bidderRequest.bids, bidderRequest); - - it('sends bid request to ENDPOINT via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('contains the correct options', function () { - expect(request.options.withCredentials).to.equal(true); - }); - - it('contains a properly formatted endpoint url', function () { - const url = request.url.split('?'); - const queryParams = url[1].split('&'); - expect(queryParams[0]).to.match(new RegExp('^t=\d*', 'g')); - expect(queryParams[1]).to.match(new RegExp('^ts=\d*', 'g')); - }); - - it('builds bidfloor value from bid param when getFloor function does not exist', function () { - const bidRequestWithFloor = utils.deepClone(bidderRequest.bids); - bidRequestWithFloor[0].params.bidfloor = 1; - const requestWithFloor = spec.buildRequests(bidRequestWithFloor, bidderRequest); - const data = JSON.parse(requestWithFloor.data); - expect(data.imp[0].bidfloor).to.equal(bidRequestWithFloor[0].params.bidfloor); - }); - - it('builds bidfloor value from getFloor function when it exists', function () { - const floorResponse = { currency: 'USD', floor: 3 }; - const bidRequestWithGetFloor = utils.deepClone(bidderRequest.bids); - bidRequestWithGetFloor[0].getFloor = () => floorResponse; - const requestWithGetFloor = spec.buildRequests(bidRequestWithGetFloor, bidderRequest); - const data = JSON.parse(requestWithGetFloor.data); - expect(data.imp[0].bidfloor).to.equal(3); - }); - - it('builds bidfloor value from getFloor when both floor and getFloor function exists', function () { - const floorResponse = { currency: 'USD', floor: 3 }; - const bidRequestWithBothFloors = utils.deepClone(bidderRequest.bids); - bidRequestWithBothFloors[0].params.bidfloor = 1; - bidRequestWithBothFloors[0].getFloor = () => floorResponse; - const requestWithBothFloors = spec.buildRequests(bidRequestWithBothFloors, bidderRequest); - const data = JSON.parse(requestWithBothFloors.data); - expect(data.imp[0].bidfloor).to.equal(3); - }); - - it('empty bidfloor value when floor and getFloor is not defined', function () { - const bidRequestWithoutFloor = utils.deepClone(bidderRequest.bids); - const requestWithoutFloor = spec.buildRequests(bidRequestWithoutFloor, bidderRequest); - const data = JSON.parse(requestWithoutFloor.data); - expect(data.imp[0].bidfloor).to.not.exist; - }); - - it('builds request properly', function () { - const data = JSON.parse(request.data); - expect(Array.isArray(data.imp)).to.equal(true); - expect(data.id).to.equal(bidderRequest.auctionId); - expect(data.imp.length).to.equal(1); - expect(data.imp[0].id).to.equal('30b31c2501de1e'); - expect(data.imp[0].tid).to.equal('d7b773de-ceaa-484d-89ca-d9f51b8d61ec'); - expect(data.imp[0].tagid).to.equal('25251'); - expect(data.imp[0].secure).to.equal(0); - expect(data.imp[0].vastXml).to.equal(undefined); - }); - - it('properly sends site information and protocol', function () { - request = spec.buildRequests(bidderRequest.bids, bidderRequest); - request = JSON.parse(request.data); - expect(request.site).to.have.property('domain', 'example.com'); - expect(request.site).to.have.property('page', 'https://example.com/index.html?pbjs_debug=true'); - expect(request.site).to.have.property('ref', 'https://referrer.com'); - }); - - it('builds correctly formatted request banner object', function () { - let bidRequestWithBanner = utils.deepClone(bidderRequest.bids); - let request = spec.buildRequests(bidRequestWithBanner, bidderRequest); - const data = JSON.parse(request.data); - expect(data.imp[0].video).to.equal(undefined); - expect(data.imp[0].banner).to.exist.and.to.be.a('object'); - expect(data.imp[0].banner.w).to.equal(bidRequestWithBanner[0].mediaTypes.banner.sizes[0][0]); - expect(data.imp[0].banner.h).to.equal(bidRequestWithBanner[0].mediaTypes.banner.sizes[0][1]); - expect(data.imp[0].banner.format[0].w).to.equal(bidRequestWithBanner[0].mediaTypes.banner.sizes[0][0]); - expect(data.imp[0].banner.format[0].h).to.equal(bidRequestWithBanner[0].mediaTypes.banner.sizes[0][1]); - expect(data.imp[0].banner.format[1].w).to.equal(bidRequestWithBanner[0].mediaTypes.banner.sizes[1][0]); - expect(data.imp[0].banner.format[1].h).to.equal(bidRequestWithBanner[0].mediaTypes.banner.sizes[1][1]); - }); - - it('builds correctly formatted request video object for instream', function () { - let bidRequestWithVideo = utils.deepClone(bidderRequest.bids); - bidRequestWithVideo[0].mediaTypes = { - video: { - context: 'instream', - playerSize: [[640, 480]] - }, - }; - bidRequestWithVideo[0].params.video = {}; - let request = spec.buildRequests(bidRequestWithVideo, bidderRequest); - const data = JSON.parse(request.data); - expect(data.imp[0].video).to.exist.and.to.be.a('object'); - expect(data.imp[0].video.w).to.equal(bidRequestWithVideo[0].mediaTypes.video.playerSize[0][0]); - expect(data.imp[0].video.h).to.equal(bidRequestWithVideo[0].mediaTypes.video.playerSize[0][1]); - }); - - it('builds correctly formatted request video object for outstream', function () { - let bidRequestWithOutstreamVideo = utils.deepClone(bidderRequest.bids); - bidRequestWithOutstreamVideo[0].mediaTypes = { - video: { - context: 'outstream', - playerSize: [[640, 480]] - }, - }; - bidRequestWithOutstreamVideo[0].params.video = {}; - let request = spec.buildRequests(bidRequestWithOutstreamVideo, bidderRequest); - const data = JSON.parse(request.data); - expect(data.imp[0].video).to.exist.and.to.be.a('object'); - expect(data.imp[0].video.w).to.equal(bidRequestWithOutstreamVideo[0].mediaTypes.video.playerSize[0][0]); - expect(data.imp[0].video.h).to.equal(bidRequestWithOutstreamVideo[0].mediaTypes.video.playerSize[0][1]); - }); - - it('shouldn\'t contain a user obj without GDPR information', function () { - let request = spec.buildRequests(bidderRequest.bids, bidderRequest) - request = JSON.parse(request.data) - expect(request).to.not.have.property('user'); - }); - - it('should have the right gdpr info when enabled', function () { - let consentString = 'OIJSZsOAFsABAB8EMXZZZZZ+A=='; - const gdprBidderRequest = utils.deepClone(bidderRequest); - gdprBidderRequest.gdprConsent = { - 'consentString': consentString, - 'gdprApplies': true - }; - let request = spec.buildRequests(gdprBidderRequest.bids, gdprBidderRequest); - - request = JSON.parse(request.data) - expect(request.regs.ext).to.have.property('gdpr', 1); - expect(request.user.ext).to.have.property('consent', consentString); - }); - - it('should\'t contain consent string if gdpr isn\'t applied', function () { - const nonGdprBidderRequest = utils.deepClone(bidderRequest); - nonGdprBidderRequest.gdprConsent = { - 'gdprApplies': false - }; - let request = spec.buildRequests(nonGdprBidderRequest.bids, nonGdprBidderRequest); - request = JSON.parse(request.data) - expect(request.regs.ext).to.have.property('gdpr', 0); - expect(request).to.not.have.property('user'); - }); - - it('should add us privacy info to request', function() { - const uspBidderRequest = utils.deepClone(bidderRequest); - let consentString = '1YNN'; - uspBidderRequest.uspConsent = consentString; - let request = spec.buildRequests(uspBidderRequest.bids, uspBidderRequest); - request = JSON.parse(request.data); - expect(request.us_privacy).to.exist; - expect(request.us_privacy).to.exist.and.to.equal(consentString); - }); - - it('should add schain object to request', function() { - const schainBidderRequest = utils.deepClone(bidderRequest); - schainBidderRequest.bids[0].schain = { - 'complete': 1, - 'ver': '1.0', - 'nodes': [ - { - 'asi': 'testing.com', - 'sid': 'abc', - 'hp': 1 - } - ] - }; - let request = spec.buildRequests(schainBidderRequest.bids, schainBidderRequest); - request = JSON.parse(request.data); - expect(request.source.ext.schain).to.exist; - expect(request.source.ext.schain).to.have.property('complete', 1); - expect(request.source.ext.schain).to.have.property('ver', '1.0'); - expect(request.source.ext.schain.nodes[0].asi).to.equal(schainBidderRequest.bids[0].schain.nodes[0].asi); - }); - - it('should add liveramp identitylink id to request', () => { - const idl_env = '123'; - const bidRequestWithID = utils.deepClone(bidderRequest); - bidRequestWithID.userId = { idl_env }; - let requestWithID = spec.buildRequests(bidRequestWithID.bids, bidRequestWithID); - requestWithID = JSON.parse(requestWithID.data); - expect(requestWithID.user.ext.eids[0]).to.deep.equal({ - source: 'liveramp.com', - uids: [{ - id: idl_env, - ext: { - rtiPartner: 'idl' - } - }] - }); - }); - - it('should add gpid to request if present', () => { - const gpid = '/12345/my-gpt-tag-0'; - let bid = utils.deepClone(bidderRequest.bids[0]); - bid.ortb2Imp = { ext: { data: { adserver: { adslot: gpid } } } }; - bid.ortb2Imp = { ext: { data: { pbadslot: gpid } } }; - let requestWithGPID = spec.buildRequests([bid], bidderRequest); - requestWithGPID = JSON.parse(requestWithGPID.data); - expect(requestWithGPID.imp[0].ext.gpid).to.exist.and.equal(gpid); - }); - - it('should add UID 2.0 to request', () => { - const uid2 = { id: '456' }; - const bidRequestWithUID = utils.deepClone(bidderRequest); - bidRequestWithUID.userId = { uid2 }; - let requestWithUID = spec.buildRequests(bidRequestWithUID.bids, bidRequestWithUID); - requestWithUID = JSON.parse(requestWithUID.data); - expect(requestWithUID.user.ext.eids[0]).to.deep.equal({ - source: 'uidapi.com', - uids: [{ - id: uid2.id, - ext: { - rtiPartner: 'UID2' - } - }] - }); - }); - }); - - describe('interpretResponse', function () { - let bid = { - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251', - 'video': {} - }, - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': [640, 480] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - - const bid_outstream = { - 'bidderRequest': { - 'bids': [{ - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251', - 'video': {} - }, - 'mediaTypes': { - 'video': { - 'context': 'outstream', - 'playerSize': [640, 480] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '987654321cba', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }, { - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25252', - 'video': {} - }, - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': [640, 480] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '987654321dcb', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }] - } - }; - - const serverResponse = { - 'id': '12819a18-56e1-4256-b836-b69a10202668', - 'seatbid': [{ - 'bid': [{ - 'adid': '123456abcde', - 'adm': '', - 'crid': '3434abab34', - 'h': 250, - 'id': '987654321cba', - 'price': 0.5, - 'ttl': 300, - 'w': 300, - 'adomain': ['example.com'] - }], - 'seat': '1356' - }, { - 'bid': [{ - 'adid': '123456abcdf', - 'adm': '', - 'crid': '3434abab35', - 'h': 600, - 'id': '987654321dcb', - 'price': 0.5, - 'ttl': 300, - 'w': 300 - }] - }] - }; - - const expectedResponse = [{ - 'requestId': '12819a18-56e1-4256-b836-b69a10202668', - 'cpm': 0.5, - 'width': 300, - 'height': 250, - 'creativeId': '3434abab34', - 'dealId': null, - 'currency': 'USD', - 'netRevneue': true, - 'mediaType': 'banner', - 'ad': '', - 'ttl': 300, - 'meta': { - 'advertiserDomains': ['example.com'] - } - }, { - 'requestId': '12819a18-56e1-4256-b836-b69a10202668', - 'cpm': 0.7, - 'width': 300, - 'height': 600, - 'creativeId': '3434abab35', - 'dealId': null, - 'currency': 'USD', - 'netRevneue': true, - 'mediaType': 'banner', - 'ad': '', - 'ttl': 300 - }]; - - it('should properly format bid response', function () { - let result = spec.interpretResponse({ - body: serverResponse - }); - expect(Object.keys(result[0]).length).to.equal(Object.keys(expectedResponse[0]).length); - expect(Object.keys(result[0]).requestId).to.equal(Object.keys(expectedResponse[0]).requestId); - expect(Object.keys(result[0]).bidderCode).to.equal(Object.keys(expectedResponse[0]).bidderCode); - expect(Object.keys(result[0]).cpm).to.equal(Object.keys(expectedResponse[0]).cpm); - expect(Object.keys(result[0]).creativeId).to.equal(Object.keys(expectedResponse[0]).creativeId); - expect(Object.keys(result[0]).width).to.equal(Object.keys(expectedResponse[0]).width); - expect(Object.keys(result[0]).height).to.equal(Object.keys(expectedResponse[0]).height); - expect(Object.keys(result[0]).ttl).to.equal(Object.keys(expectedResponse[0]).ttl); - expect(Object.keys(result[0]).adId).to.equal(Object.keys(expectedResponse[0]).adId); - expect(Object.keys(result[0]).currency).to.equal(Object.keys(expectedResponse[0]).currency); - expect(Object.keys(result[0]).netRevenue).to.equal(Object.keys(expectedResponse[0]).netRevenue); - expect(Object.keys(result[0]).ad).to.equal(Object.keys(expectedResponse[0]).ad); - }); - - it('should return multiple bids', function () { - let result = spec.interpretResponse({ - body: serverResponse - }); - expect(Array.isArray(result.seatbid)) - - const ad0 = result[0]; - const ad1 = result[1]; - expect(ad0.ad).to.equal(serverResponse.seatbid[0].bid[0].adm); - expect(ad0.cpm).to.equal(serverResponse.seatbid[0].bid[0].price); - expect(ad0.creativeId).to.equal(serverResponse.seatbid[0].bid[0].crid); - expect(ad0.currency).to.equal('USD'); - expect(ad0.netRevenue).to.equal(true); - expect(ad0.requestId).to.equal(serverResponse.seatbid[0].bid[0].id); - expect(ad0.ttl).to.equal(300); - - expect(ad1.ad).to.equal(serverResponse.seatbid[1].bid[0].adm); - expect(ad1.cpm).to.equal(serverResponse.seatbid[1].bid[0].price); - expect(ad1.creativeId).to.equal(serverResponse.seatbid[1].bid[0].crid); - expect(ad1.currency).to.equal('USD'); - expect(ad1.netRevenue).to.equal(true); - expect(ad1.requestId).to.equal(serverResponse.seatbid[1].bid[0].id); - expect(ad1.ttl).to.equal(300); - }); - - it('returns a banner bid for non-xml creatives', function () { - let result = spec.interpretResponse({ - body: serverResponse - }, { bidRequest: bid } - ); - const ad0 = result[0]; - const ad1 = result[1]; - expect(ad0.mediaType).to.equal('banner'); - expect(ad0.ad.indexOf(''; - vastServerResponse.seatbid[1].bid[0].adm = ''; - - let result = spec.interpretResponse({ - body: vastServerResponse - }, { bidRequest: bid } - ); - const ad0 = result[0]; - const ad1 = result[1]; - expect(ad0.mediaType).to.equal('video'); - expect(ad0.ad.indexOf(' -1).to.equal(true); - expect(ad0.vastXml).to.equal(vastServerResponse.seatbid[0].bid[0].adm); - expect(ad0.ad).to.exist.and.to.be.a('string'); - expect(ad1.mediaType).to.equal('video'); - expect(ad1.ad.indexOf(' -1).to.equal(true); - expect(ad1.vastXml).to.equal(vastServerResponse.seatbid[1].bid[0].adm); - expect(ad1.ad).to.exist.and.to.be.a('string'); - }); - - it('returns a renderer for outstream video creatives', function () { - const vastServerResponse = utils.deepClone(serverResponse); - vastServerResponse.seatbid[0].bid[0].adm = ''; - vastServerResponse.seatbid[1].bid[0].adm = ''; - let result = spec.interpretResponse({body: vastServerResponse}, bid_outstream); - const ad0 = result[0]; - const ad1 = result[1]; - expect(ad0.renderer).to.exist.and.to.be.a('object'); - expect(ad0.renderer.url).to.equal('https://js.brealtime.com/outstream/1.30.0/bundle.js'); - expect(ad0.renderer.id).to.equal('987654321cba'); - expect(ad1.renderer).to.equal(undefined); - }); - - it('handles nobid responses', function () { - let serverResponse = { - 'bids': [] - }; - - let result = spec.interpretResponse({ - body: serverResponse - }); - expect(result.length).to.equal(0); - }); - - it('should not throw an error when decoding an improperly encoded adm', function () { - const badAdmServerResponse = utils.deepClone(serverResponse); - badAdmServerResponse.seatbid[0].bid[0].adm = '\\<\\/script\\>'; - badAdmServerResponse.seatbid[1].bid[0].adm = '%3F%%3Demx%3C3prebid'; - - assert.doesNotThrow(() => spec.interpretResponse({ - body: badAdmServerResponse - })); - }); - - it('returns valid advertiser domains', function () { - const bidResponse = utils.deepClone(serverResponse); - let result = spec.interpretResponse({body: bidResponse}); - expect(result[0].meta.advertiserDomains).to.deep.equal(expectedResponse[0].meta.advertiserDomains); - // case where adomains are not in request - expect(result[1].meta).to.not.exist; - }); - }); - - describe('getUserSyncs', function () { - it('should register the iframe sync url', function () { - let syncs = spec.getUserSyncs({ - iframeEnabled: true - }); - expect(syncs).to.not.be.an('undefined'); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.equal('https://biddr.brealtime.com/check.html') - }); - - it('should pass gdpr params', function () { - let syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, { - gdprApplies: false, consentString: 'test' - }); - expect(syncs).to.not.be.an('undefined'); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.contains('gdpr=0'); - expect(syncs[0].url).to.equal('https://biddr.brealtime.com/check.html?gdpr=0&gdpr_consent=test') - }); - - it('should pass us_privacy string', function () { - let syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, {}, { - consentString: 'test', - }); - expect(syncs).to.not.be.an('undefined'); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.contains('usp=test'); - }); - - it('should pass us_privacy and gdpr strings', function () { - let syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, - { - gdprApplies: true, - consentString: 'test' - }, - { - consentString: 'test' - }); - expect(syncs).to.not.be.an('undefined'); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.contains('gdpr=1'); - expect(syncs[0].url).to.contains('usp=test'); - expect(syncs[0].url).to.equal('https://biddr.brealtime.com/check.html?gdpr=1&gdpr_consent=test&usp=test') - }); - }); -});