From 71ad8dc2c0ab3106b9ccbafa6c1bc024c21d4a47 Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Tue, 8 Feb 2022 18:38:13 -0300 Subject: [PATCH 01/18] emits event even on loss --- modules/videoModule/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/videoModule/index.js b/modules/videoModule/index.js index b8593bf5921..a42bd3f0791 100644 --- a/modules/videoModule/index.js +++ b/modules/videoModule/index.js @@ -87,6 +87,7 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent function renderWinningBid(adUnit) { const highestCpmBids = pbGlobal.getHighestCpmBids(adUnit.code); if (!highestCpmBids.length) { + pbEvents.emit(AUCTION_AD_LOAD_ATTEMPT, {}); return; } From e893007aedb5e249d5523df9d7c783e8cd3c1169 Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Tue, 8 Feb 2022 19:58:12 -0300 Subject: [PATCH 02/18] registers video auction events --- modules/videoModule/constants/events.js | 4 ++++ modules/videoModule/index.js | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/videoModule/constants/events.js b/modules/videoModule/constants/events.js index 6a215ef1090..09e349d7557 100644 --- a/modules/videoModule/constants/events.js +++ b/modules/videoModule/constants/events.js @@ -53,6 +53,10 @@ export const allVideoEvents = [ export const AUCTION_AD_LOAD_ATTEMPT = 'auctionAdLoadAttempt'; +export const allVideoAuctionEvents = [ + AUCTION_AD_LOAD_ATTEMPT +]; + // Param options export const PLAYBACK_MODE = { VOD: 0, diff --git a/modules/videoModule/index.js b/modules/videoModule/index.js index a42bd3f0791..db7d2349610 100644 --- a/modules/videoModule/index.js +++ b/modules/videoModule/index.js @@ -1,6 +1,6 @@ import { config } from '../../src/config.js'; import events from '../../src/events.js'; -import { allVideoEvents, AUCTION_AD_LOAD_ATTEMPT } from './constants/events.js'; +import { allVideoEvents, AUCTION_AD_LOAD_ATTEMPT, allVideoAuctionEvents } from './constants/events.js'; import CONSTANTS from '../../src/constants.json'; import { videoCoreFactory } from './coreVideo.js'; import { coreAdServerFactory } from './adServer.js'; @@ -13,6 +13,7 @@ import { vastXmlEditorFactory } from './shared/vastXmlEditor.js'; */ events.addEvents(allVideoEvents); +events.addEvents(allVideoAuctionEvents); export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvents_, adServerCore_, vastXmlEditor_) { const videoCore = videoCore_; From df08b3fa23d25e0aa9ebf27841d42a86d76813af Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Wed, 9 Feb 2022 14:51:46 -0300 Subject: [PATCH 03/18] updates events --- src/events.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/events.js b/src/events.js index e52ac18b383..3bf2ddbc3ba 100644 --- a/src/events.js +++ b/src/events.js @@ -134,7 +134,7 @@ module.exports = (function () { }; _public.addEvents = function (events) { - allEvents.concat(events); + allEvents = allEvents.concat(events); } /** From 1963d01e9734f63bada0772f17326b3974564541 Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Wed, 9 Feb 2022 19:09:03 -0300 Subject: [PATCH 04/18] includes ad unit code in loss --- modules/videoModule/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/videoModule/index.js b/modules/videoModule/index.js index db7d2349610..6ed1368f243 100644 --- a/modules/videoModule/index.js +++ b/modules/videoModule/index.js @@ -86,9 +86,11 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent } function renderWinningBid(adUnit) { - const highestCpmBids = pbGlobal.getHighestCpmBids(adUnit.code); + const adUnitCode = adUnit.code; + const options = { adUnitCode }; + const highestCpmBids = pbGlobal.getHighestCpmBids(adUnitCode); if (!highestCpmBids.length) { - pbEvents.emit(AUCTION_AD_LOAD_ATTEMPT, {}); + pbEvents.emit(AUCTION_AD_LOAD_ATTEMPT, options); return; } @@ -100,8 +102,6 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent adUrl = adServerCore.getAdTagUrl(adServerConfig.vendorCode, adUnit, adServerConfig.baseAdTagUrl); } - const adUnitCode = adUnit.code; - const options = { adUnitCode }; if (adUrl) { loadAdTag(adUrl, divId, options); return; From 8f9246fd4c2876c76b6c5059ab54bce80a63fe9e Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Thu, 10 Feb 2022 19:16:25 -0300 Subject: [PATCH 05/18] uses config fallback --- modules/jwplayerVideoProvider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/jwplayerVideoProvider.js b/modules/jwplayerVideoProvider.js index 47f663a0da3..08c91ddfed5 100644 --- a/modules/jwplayerVideoProvider.js +++ b/modules/jwplayerVideoProvider.js @@ -72,7 +72,7 @@ export function JWPlayerProvider(config, jwplayer_, adState_, timeState_, callba if (!player) { return; } - const config = player.getConfig(); + const config = player.getConfig() || {}; const adConfig = config.advertising || {}; supportedMediaTypes = supportedMediaTypes || utils.getSupportedMediaTypes(MEDIA_TYPES); From ca8746afac8a76562c55f97baafbe4e636e48055 Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Tue, 22 Feb 2022 18:27:04 -0300 Subject: [PATCH 06/18] tracks bids sent for rendering --- modules/jwplayerVideoProvider.js | 1 + modules/videoModule/index.js | 28 +++++++++++++-------- modules/videoModule/shared/vastXmlEditor.js | 21 +++++++++++++--- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/modules/jwplayerVideoProvider.js b/modules/jwplayerVideoProvider.js index 08c91ddfed5..1bb2dbac5cc 100644 --- a/modules/jwplayerVideoProvider.js +++ b/modules/jwplayerVideoProvider.js @@ -923,6 +923,7 @@ export function adStateFactory() { waterfallCount: event.wcount, adPodCount: event.podcount, adPodIndex: event.sequence, + // need wrapper ad ids }; this.updateState(updates); } diff --git a/modules/videoModule/index.js b/modules/videoModule/index.js index 6ed1368f243..9a1334945c9 100644 --- a/modules/videoModule/index.js +++ b/modules/videoModule/index.js @@ -1,6 +1,6 @@ import { config } from '../../src/config.js'; import events from '../../src/events.js'; -import { allVideoEvents, AUCTION_AD_LOAD_ATTEMPT, allVideoAuctionEvents } from './constants/events.js'; +import { allVideoEvents, AUCTION_AD_LOAD_ATTEMPT, allVideoAuctionEvents, AD_IMPRESSION } from './constants/events.js'; import CONSTANTS from '../../src/constants.json'; import { videoCoreFactory } from './coreVideo.js'; import { coreAdServerFactory } from './adServer.js'; @@ -24,6 +24,7 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent const videoEvents = videoEvents_; const adServerCore = adServerCore_; const vastXmlEditor = vastXmlEditor_; + const trackedBids = {}; function init() { getConfig('video', ({ video }) => { @@ -61,7 +62,11 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent const videoConfig = adUnit && adUnit.video; const adServerConfig = videoConfig && videoConfig.adServer; const trackingConfig = adServerConfig && adServerConfig.tracking; - addTrackingNodesToVastXml(bid, trackingConfig); + addTrackingToVastXml(bid, trackingConfig); + }); + + pbEvents.on(AD_IMPRESSION, function (paylod) { + }); } @@ -125,16 +130,12 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent videoCore.setAdTagUrl(adUrl, divId, options); } - function addTrackingNodesToVastXml(bid, trackingConfig) { - if (!trackingConfig) { - return; - } - - let { vastXml, vastUrl, adId } = bid; + function addTrackingToVastXml(bid, trackingConfig = {}) { + let { vastXml, vastUrl, adId, adUnitCode, requestId, auctionId } = bid; let impressionUrl; let impressionId; let errorUrl; - + const adIdOverride = 'pb-' + generateId(12); const impressionTracking = trackingConfig.impression; const errorTracking = trackingConfig.error; @@ -148,13 +149,18 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent } if (vastXml) { - vastXml = vastXmlEditor.getVastXmlWithTrackingNodes(vastXml, impressionUrl, impressionId, errorUrl); + vastXml = vastXmlEditor.getVastXmlWithTracking(vastXml, adIdOverride, impressionUrl, impressionId, errorUrl); } else if (vastUrl) { - vastXml = vastXmlEditor.buildVastWrapper(adId, vastUrl, impressionUrl, impressionId, errorUrl); + vastXml = vastXmlEditor.buildVastWrapper(adIdOverride, vastUrl, impressionUrl, impressionId, errorUrl); } + trackedBids[adIdOverride] = { adId, adUnitCode, requestId, auctionId }; bid.vastXml = vastXml; } + + function generateId(length) { + return Math.floor(Math.random() * 10 ** length); + } } export function pbVideoFactory() { diff --git a/modules/videoModule/shared/vastXmlEditor.js b/modules/videoModule/shared/vastXmlEditor.js index c5cb113c299..988f31e8029 100644 --- a/modules/videoModule/shared/vastXmlEditor.js +++ b/modules/videoModule/shared/vastXmlEditor.js @@ -5,14 +5,20 @@ export const XML_MIME_TYPE = 'application/xml'; export function VastXmlEditor(xmlUtil_) { const xmlUtil = xmlUtil_; - function getVastXmlWithTrackingNodes(vastXml, impressionUrl, impressionId, errorUrl) { + function getVastXmlWithTracking(vastXml, adId, impressionUrl, impressionId, errorUrl) { const impressionDoc = getImpressionDoc(impressionUrl, impressionId); const errorDoc = getErrorDoc(errorUrl); - if (!impressionDoc && !errorDoc) { + if (!adId && !impressionDoc && !errorDoc) { return vastXml; } const vastXmlDoc = xmlUtil.parse(vastXml); + appendTrackingNodes(vastXmlDoc, impressionDoc, errorDoc); + replaceAdId(vastXmlDoc, adId); + return xmlUtil.serialize(vastXmlDoc); + } + + function appendTrackingNodes(vastXmlDoc, impressionDoc, errorDoc) { const nodes = vastXmlDoc.querySelectorAll('InLine,Wrapper'); const nodeCount = nodes.length; for (let i = 0; i < nodeCount; i++) { @@ -22,12 +28,19 @@ export function VastXmlEditor(xmlUtil_) { appendChild(node, impressionDoc, requiresCopy); appendChild(node, errorDoc, requiresCopy); } + } + + function replaceAdId(vastXmlDoc, adId) { + const adNode = vastXmlDoc.querySelector('Ad'); + if (!adNode) { + return; + } - return xmlUtil.serialize(vastXmlDoc); + adNode.id = adId; } return { - getVastXmlWithTrackingNodes, + getVastXmlWithTracking, buildVastWrapper } From e90f42259bf642c6eceb81e3d171164984f9c1f6 Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Wed, 23 Feb 2022 17:32:16 -0300 Subject: [PATCH 07/18] adds video impression verification --- .../videoModule/videoImpressionVerifier.js | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 modules/videoModule/videoImpressionVerifier.js diff --git a/modules/videoModule/videoImpressionVerifier.js b/modules/videoModule/videoImpressionVerifier.js new file mode 100644 index 00000000000..ca41d397722 --- /dev/null +++ b/modules/videoModule/videoImpressionVerifier.js @@ -0,0 +1,139 @@ +import find from 'core-js-pure/features/array/find'; +import URL from 'core-js-pure/web/url'; +import { vastXmlEditorFactory } from './shared/vastXmlEditor.js'; + +export function videoImpressionVerifierFactory(isCacheUsed) { + const vastXmlEditor = vastXmlEditorFactory(); + const bidTracker = tracker(); + if (isCacheUsed) { + return cachedVideoImpressionVerifier(vastXmlEditor, bidTracker); + } + + return videoImpressionVerifier(vastXmlEditor, bidTracker); +} + +function videoImpressionVerifier(vastXmlEditor_) { + const vastXmlEditor = vastXmlEditor_; + const trackedBids = {}; + + function trackBid(bid) { + let { vastXml, vastUrl, adId, adUnitCode, requestId, auctionId } = bid; + const uuid = 'pb-' + generateId(12); + + if (!vastXml && !vastUrl) { + return; + } + + if (vastUrl) { + const url = new URL(vastUrl); + url.searchParams.append('pb_uuid', uuid); + bid.vastUrl = url.toString(); + } else if (vastXml) { + bid.vastXml = vastXmlEditor.getVastXmlWithTracking(vastXml, uuid); + } + trackedBids[uuid] = { adId, adUnitCode, requestId, auctionId }; + } + + // get tracked Bid from adUrl ad id, adWrapper Ids + // get uuid from url, ad id, wrapper ids + // match to tracked bid + // find actual bid object + // remove from tracked + // return actual bid object + + function getTrackedBid(adId, adTagUrl, adWrapperIds) { + return trackedBids[adId] || getBidForAdTagUrl(adTagUrl) || getBidForAdWrappers(adWrapperIds); + } + + function getBidForAdTagUrl(adTagUrl) { + const url = new URL(adTagUrl); + const queryParams = url.searchParams; + let uuid = queryParams.get('pb_uuid'); + return uuid && trackedBids[uuid]; + } + + function getBidForAdWrappers(adWrapperIds) { + for (const wrapperId in adWrapperIds) { + const bid = trackedBids[wrapperId]; + if (bid) { + return bid; + } + } + } + + return { + trackBid, + getTrackedBid + }; +} + +function tracker() { + const model = {}; + + function store(key, value) { + model[key] = value; + } + + function remove(key) { + const value = model[key]; + if (!value) { + return; + } + + delete model[key]; + return value; + } + + return { + store, + remove + } +} + +function cachedVideoImpressionVerifier(vastXmlEditor_) { + const vastXmlEditor = vastXmlEditor_; + const trackedBids = {}; + + function registerBid(bid, globalAdUnits) { + let { vastXml, vastUrl, adId, adUnitCode, requestId, auctionId } = bid; + const adUnit = find(globalAdUnits, adUnit => adUnitCode === adUnit.code); + const videoConfig = adUnit && adUnit.video; + const adServerConfig = videoConfig && videoConfig.adServer; + const trackingConfig = adServerConfig && adServerConfig.tracking; + let impressionUrl; + let impressionId; + let errorUrl; + const adIdOverride = 'pb-' + generateId(12); + const impressionTracking = trackingConfig.impression; + const errorTracking = trackingConfig.error; + + if (impressionTracking) { + impressionUrl = impressionTracking.url; + impressionId = impressionTracking.id || adId + '-impression'; + } + + if (errorTracking) { + errorUrl = errorTracking.url; + } + + if (vastXml) { + vastXml = vastXmlEditor.getVastXmlWithTracking(vastXml, adIdOverride, impressionUrl, impressionId, errorUrl); + } else if (vastUrl) { + vastXml = vastXmlEditor.buildVastWrapper(adIdOverride, vastUrl, impressionUrl, impressionId, errorUrl); + } + + trackedBids[adIdOverride] = { adId, adUnitCode, requestId, auctionId }; + bid.vastXml = vastXml; + } + + // verify id from ad id or wrapper ids + + return { + registerBid, + getTrackedBid, + }; +} + +export function generateId(length) { + return Math.floor(Math.random() * 10 ** length); +} From c6e414bac8be68ce30f298b5fc34dc4380c864bc Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Wed, 23 Feb 2022 18:31:20 -0300 Subject: [PATCH 08/18] shares code --- .../videoModule/videoImpressionVerifier.js | 148 ++++++++++-------- 1 file changed, 87 insertions(+), 61 deletions(-) diff --git a/modules/videoModule/videoImpressionVerifier.js b/modules/videoModule/videoImpressionVerifier.js index ca41d397722..2c9d989e789 100644 --- a/modules/videoModule/videoImpressionVerifier.js +++ b/modules/videoModule/videoImpressionVerifier.js @@ -12,18 +12,19 @@ export function videoImpressionVerifierFactory(isCacheUsed) { return videoImpressionVerifier(vastXmlEditor, bidTracker); } -function videoImpressionVerifier(vastXmlEditor_) { +function videoImpressionVerifier(vastXmlEditor_, bidTracker_) { + const verifier = baseImpressionVerifier(bidTracker_); + const superTrackBid = verifier.trackBid; const vastXmlEditor = vastXmlEditor_; - const trackedBids = {}; - - function trackBid(bid) { - let { vastXml, vastUrl, adId, adUnitCode, requestId, auctionId } = bid; - const uuid = 'pb-' + generateId(12); + verifier.trackBid = function(bid) { + let { vastXml, vastUrl } = bid; if (!vastXml && !vastUrl) { return; } + const uuid = superTrackBid(bid); + if (vastUrl) { const url = new URL(vastUrl); url.searchParams.append('pb_uuid', uuid); @@ -31,7 +32,68 @@ function videoImpressionVerifier(vastXmlEditor_) { } else if (vastXml) { bid.vastXml = vastXmlEditor.getVastXmlWithTracking(vastXml, uuid); } - trackedBids[uuid] = { adId, adUnitCode, requestId, auctionId }; + + return uuid; + } + + return verifier; +} + +function cachedVideoImpressionVerifier(vastXmlEditor_, bidTracker_) { + const verifier = baseImpressionVerifier(bidTracker_); + const superTrackBid = verifier.trackBid; + const superGetTrackedBid = verifier.getTrackedBid; + const vastXmlEditor = vastXmlEditor_; + + verifier.trackBid = function (bid, globalAdUnits) { + const adIdOverride = superTrackBid(bid); + let { vastXml, vastUrl, adId, adUnitCode } = bid; + const adUnit = find(globalAdUnits, adUnit => adUnitCode === adUnit.code); + const videoConfig = adUnit && adUnit.video; + const adServerConfig = videoConfig && videoConfig.adServer; + const trackingConfig = adServerConfig && adServerConfig.tracking; + let impressionUrl; + let impressionId; + let errorUrl; + const impressionTracking = trackingConfig.impression; + const errorTracking = trackingConfig.error; + + if (impressionTracking) { + impressionUrl = impressionTracking.url; + impressionId = impressionTracking.id || adId + '-impression'; + } + + if (errorTracking) { + errorUrl = errorTracking.url; + } + + if (vastXml) { + vastXml = vastXmlEditor.getVastXmlWithTracking(vastXml, adIdOverride, impressionUrl, impressionId, errorUrl); + } else if (vastUrl) { + vastXml = vastXmlEditor.buildVastWrapper(adIdOverride, vastUrl, impressionUrl, impressionId, errorUrl); + } + + bid.vastXml = vastXml; + return adIdOverride; + } + + verifier.getTrackedBid = function (adId, adTagUrl, adWrapperIds) { + // When the video is cached, the ad tag loaded into the player is a parent wrapper of the cache url. + // As a result, the ad tag Url cannot include identifiers. + return superGetTrackedBid(adId, null, adWrapperIds); + } + + return verifier; +} + +function baseImpressionVerifier(bidTracker_) { + const bidTracker = bidTracker_; + + function trackBid(bid) { + let { adId, adUnitCode, requestId, auctionId } = bid; + const uuid = 'pb-' + generateId(12); + bidTracker.store(uuid, { adId, adUnitCode, requestId, auctionId }); + return uuid; } // get tracked Bid from adUrl ad id, adWrapper Ids @@ -42,29 +104,37 @@ function videoImpressionVerifier(vastXmlEditor_) { // return actual bid object function getTrackedBid(adId, adTagUrl, adWrapperIds) { - return trackedBids[adId] || getBidForAdTagUrl(adTagUrl) || getBidForAdWrappers(adWrapperIds); + return bidTracker.remove(adId) || getBidForAdTagUrl(adTagUrl) || getBidForAdWrappers(adWrapperIds); } + return { + trackBid, + getTrackedBid + }; + function getBidForAdTagUrl(adTagUrl) { + if (!adTagUrl) { + return; + } + const url = new URL(adTagUrl); const queryParams = url.searchParams; let uuid = queryParams.get('pb_uuid'); - return uuid && trackedBids[uuid]; + return uuid && bidTracker.remove(uuid); } function getBidForAdWrappers(adWrapperIds) { + if (!adWrapperIds || !adWrapperIds.length) { + return; + } + for (const wrapperId in adWrapperIds) { - const bid = trackedBids[wrapperId]; - if (bid) { - return bid; + const bidInfo = bidTracker.remove(wrapperId); + if (bidInfo) { + return bidInfo; } } } - - return { - trackBid, - getTrackedBid - }; } function tracker() { @@ -90,50 +160,6 @@ function tracker() { } } -function cachedVideoImpressionVerifier(vastXmlEditor_) { - const vastXmlEditor = vastXmlEditor_; - const trackedBids = {}; - - function registerBid(bid, globalAdUnits) { - let { vastXml, vastUrl, adId, adUnitCode, requestId, auctionId } = bid; - const adUnit = find(globalAdUnits, adUnit => adUnitCode === adUnit.code); - const videoConfig = adUnit && adUnit.video; - const adServerConfig = videoConfig && videoConfig.adServer; - const trackingConfig = adServerConfig && adServerConfig.tracking; - let impressionUrl; - let impressionId; - let errorUrl; - const adIdOverride = 'pb-' + generateId(12); - const impressionTracking = trackingConfig.impression; - const errorTracking = trackingConfig.error; - - if (impressionTracking) { - impressionUrl = impressionTracking.url; - impressionId = impressionTracking.id || adId + '-impression'; - } - - if (errorTracking) { - errorUrl = errorTracking.url; - } - - if (vastXml) { - vastXml = vastXmlEditor.getVastXmlWithTracking(vastXml, adIdOverride, impressionUrl, impressionId, errorUrl); - } else if (vastUrl) { - vastXml = vastXmlEditor.buildVastWrapper(adIdOverride, vastUrl, impressionUrl, impressionId, errorUrl); - } - - trackedBids[adIdOverride] = { adId, adUnitCode, requestId, auctionId }; - bid.vastXml = vastXml; - } - - // verify id from ad id or wrapper ids - - return { - registerBid, - getTrackedBid, - }; -} - export function generateId(length) { return Math.floor(Math.random() * 10 ** length); } From 0b67582a34e3aa56f67d9c466e76d6f36ff33a4c Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Wed, 23 Feb 2022 19:40:49 -0300 Subject: [PATCH 09/18] triggers bid video events --- modules/videoModule/constants/events.js | 2 + modules/videoModule/index.js | 70 +++++++------------------ 2 files changed, 22 insertions(+), 50 deletions(-) diff --git a/modules/videoModule/constants/events.js b/modules/videoModule/constants/events.js index 09e349d7557..ae47ecf388c 100644 --- a/modules/videoModule/constants/events.js +++ b/modules/videoModule/constants/events.js @@ -52,6 +52,8 @@ export const allVideoEvents = [ ]; export const AUCTION_AD_LOAD_ATTEMPT = 'auctionAdLoadAttempt'; +export const BID_VIDEO_IMPRESSION = 'bidVideoImpression'; +export const BID_VIDEO_ERROR = 'bidVideoError'; export const allVideoAuctionEvents = [ AUCTION_AD_LOAD_ATTEMPT diff --git a/modules/videoModule/index.js b/modules/videoModule/index.js index 9a1334945c9..62fa55ade61 100644 --- a/modules/videoModule/index.js +++ b/modules/videoModule/index.js @@ -1,11 +1,11 @@ import { config } from '../../src/config.js'; import events from '../../src/events.js'; -import { allVideoEvents, AUCTION_AD_LOAD_ATTEMPT, allVideoAuctionEvents, AD_IMPRESSION } from './constants/events.js'; +import { allVideoEvents, AUCTION_AD_LOAD_ATTEMPT, allVideoAuctionEvents, + AD_IMPRESSION, AD_ERROR, BID_VIDEO_IMPRESSION, BID_VIDEO_ERROR } from './constants/events.js'; import CONSTANTS from '../../src/constants.json'; import { videoCoreFactory } from './coreVideo.js'; import { coreAdServerFactory } from './adServer.js'; -import find from 'prebidjs-polyfill/find.js'; -import { vastXmlEditorFactory } from './shared/vastXmlEditor.js'; +import { videoImpressionVerifierFactory } from './videoImpressionVerifier.js'; /** * This module adds User Video support to prebid.js @@ -15,7 +15,7 @@ import { vastXmlEditorFactory } from './shared/vastXmlEditor.js'; events.addEvents(allVideoEvents); events.addEvents(allVideoAuctionEvents); -export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvents_, adServerCore_, vastXmlEditor_) { +export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvents_, adServerCore_, videoImpressionVerifierFactory_) { const videoCore = videoCore_; const getConfig = getConfig_; const pbGlobal = pbGlobal_; @@ -23,10 +23,12 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent const pbEvents = pbEvents_; const videoEvents = videoEvents_; const adServerCore = adServerCore_; - const vastXmlEditor = vastXmlEditor_; - const trackedBids = {}; + const videoImpressionVerifierFactory = videoImpressionVerifierFactory_; + let videoImpressionVerifier; function init() { + const cache = getConfig('cache'); + videoImpressionVerifier = videoImpressionVerifierFactory(!!cache); getConfig('video', ({ video }) => { video.providers.forEach(provider => { videoCore.registerProvider(provider); @@ -51,22 +53,18 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent }); }); - const cache = getConfig('cache'); - if (!cache) { - return; - } - pbEvents.on(CONSTANTS.EVENTS.BID_ADJUSTMENT, function (bid) { - const adUnitCode = bid.adUnitCode; - const adUnit = find(pbGlobal.adUnits, adUnit => adUnitCode === adUnit.code); - const videoConfig = adUnit && adUnit.video; - const adServerConfig = videoConfig && videoConfig.adServer; - const trackingConfig = adServerConfig && adServerConfig.tracking; - addTrackingToVastXml(bid, trackingConfig); + videoImpressionVerifier.trackBid(bid); }); - pbEvents.on(AD_IMPRESSION, function (paylod) { + pbEvents.on(AD_IMPRESSION, function (payload) { + const bid = getBid(payload); + pbEvents.emit(BID_VIDEO_IMPRESSION, { bid, adEvent: payload }); + }); + pbEvents.on(AD_ERROR, function (payload) { + const bid = getBid(payload); + pbEvents.emit(BID_VIDEO_ERROR, { bid, adEvent: payload }); }); } @@ -130,44 +128,16 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent videoCore.setAdTagUrl(adUrl, divId, options); } - function addTrackingToVastXml(bid, trackingConfig = {}) { - let { vastXml, vastUrl, adId, adUnitCode, requestId, auctionId } = bid; - let impressionUrl; - let impressionId; - let errorUrl; - const adIdOverride = 'pb-' + generateId(12); - const impressionTracking = trackingConfig.impression; - const errorTracking = trackingConfig.error; - - if (impressionTracking) { - impressionUrl = impressionTracking.url; - impressionId = impressionTracking.id || adId + '-impression'; - } - - if (errorTracking) { - errorUrl = errorTracking.url; - } - - if (vastXml) { - vastXml = vastXmlEditor.getVastXmlWithTracking(vastXml, adIdOverride, impressionUrl, impressionId, errorUrl); - } else if (vastUrl) { - vastXml = vastXmlEditor.buildVastWrapper(adIdOverride, vastUrl, impressionUrl, impressionId, errorUrl); - } - - trackedBids[adIdOverride] = { adId, adUnitCode, requestId, auctionId }; - bid.vastXml = vastXml; - } - - function generateId(length) { - return Math.floor(Math.random() * 10 ** length); + function getBid(adPayload) { + const { adId, adTagUrl, adWrapperIds } = adPayload; + const bidInfo = videoImpressionVerifier.getTrackedBid(adId, adTagUrl, adWrapperIds); } } export function pbVideoFactory() { const videoCore = videoCoreFactory(); const adServerCore = coreAdServerFactory(); - const vastXmlEditor = vastXmlEditorFactory(); - const pbVideo = PbVideo(videoCore, config.getConfig, $$PREBID_GLOBAL$$, events, allVideoEvents, adServerCore, vastXmlEditor); + const pbVideo = PbVideo(videoCore, config.getConfig, $$PREBID_GLOBAL$$, events, allVideoEvents, adServerCore, videoImpressionVerifierFactory); pbVideo.init(); return pbVideo; } From b060a1def87434feb86c0c78ad5b64be46eb575e Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Thu, 24 Feb 2022 17:30:47 -0300 Subject: [PATCH 10/18] matches ad event to bid --- modules/videoModule/index.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/modules/videoModule/index.js b/modules/videoModule/index.js index 62fa55ade61..a26a65cdec0 100644 --- a/modules/videoModule/index.js +++ b/modules/videoModule/index.js @@ -58,13 +58,11 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent }); pbEvents.on(AD_IMPRESSION, function (payload) { - const bid = getBid(payload); - pbEvents.emit(BID_VIDEO_IMPRESSION, { bid, adEvent: payload }); + triggerVideoBidEvent(BID_VIDEO_IMPRESSION, payload); }); pbEvents.on(AD_ERROR, function (payload) { - const bid = getBid(payload); - pbEvents.emit(BID_VIDEO_ERROR, { bid, adEvent: payload }); + triggerVideoBidEvent(BID_VIDEO_ERROR, payload); }); } @@ -128,9 +126,19 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent videoCore.setAdTagUrl(adUrl, divId, options); } + function triggerVideoBidEvent(eventName, adEventPayload) { + const bid = getBid(adEventPayload); + if (!bid) { + return; + } + pbEvents.emit(eventName, { bid, adEvent: adEventPayload }); + } + function getBid(adPayload) { const { adId, adTagUrl, adWrapperIds } = adPayload; - const bidInfo = videoImpressionVerifier.getTrackedBid(adId, adTagUrl, adWrapperIds); + const { bidAdId = adId, adUnitCode, requestId, auctionId } = videoImpressionVerifier.getTrackedBid(adId, adTagUrl, adWrapperIds); + const { bids } = pbGlobal.getBidResponsesForAdUnitCode(adUnitCode); + return bids.find(bid => bid.adId === bidAdId && bid.requestId === requestId && bid.auctionId === auctionId); } } From 33bed857a6c2ee183e4b0a454e5a95b24ec6cadf Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Thu, 24 Feb 2022 18:27:05 -0300 Subject: [PATCH 11/18] adds inline documentation --- modules/videoModule/index.js | 2 +- .../videoModule/videoImpressionVerifier.js | 61 ++++++++++++++----- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/modules/videoModule/index.js b/modules/videoModule/index.js index a26a65cdec0..12498be30fc 100644 --- a/modules/videoModule/index.js +++ b/modules/videoModule/index.js @@ -136,7 +136,7 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent function getBid(adPayload) { const { adId, adTagUrl, adWrapperIds } = adPayload; - const { bidAdId = adId, adUnitCode, requestId, auctionId } = videoImpressionVerifier.getTrackedBid(adId, adTagUrl, adWrapperIds); + const { bidAdId = adId, adUnitCode, requestId, auctionId } = videoImpressionVerifier.getBidIdentifiers(adId, adTagUrl, adWrapperIds); const { bids } = pbGlobal.getBidResponsesForAdUnitCode(adUnitCode); return bids.find(bid => bid.adId === bidAdId && bid.requestId === requestId && bid.auctionId === auctionId); } diff --git a/modules/videoModule/videoImpressionVerifier.js b/modules/videoModule/videoImpressionVerifier.js index 2c9d989e789..704441d9a97 100644 --- a/modules/videoModule/videoImpressionVerifier.js +++ b/modules/videoModule/videoImpressionVerifier.js @@ -2,6 +2,44 @@ import find from 'core-js-pure/features/array/find'; import URL from 'core-js-pure/web/url'; import { vastXmlEditorFactory } from './shared/vastXmlEditor.js'; +const PB_PREFIX = 'pb_'; +const UUID_MARKER = PB_PREFIX + 'uuid'; + +/** + * Video Impression Verifier interface. All implementations of a Video Impression Verifier must comply with this interface. + * @description adds tracking markers to an ad and extracts the bid identifiers from ad event information. + * @typedef {Object} VideoImpressionVerifier + * @function trackBid - requests that a bid's ad be tracked for impression verification. + * @function getBidIdentifiers - requests information from the ad event data that can be used to match the ad to a tracked bid. + */ + +/** + * @function VideoImpressionVerifier#trackBid + * @param {Object} bid - Bid that should be tracked. + * @return {String} - Identifier for the bid being tracked. + */ + +/** + * @function VideoImpressionVerifier#getBidIdentifiers + * @param {String} adId - In the VAST tag, this value is present in the Ad element's id property. + * @param {String} adTagUrl - The ad tag url that was loaded into the player. + * @param {[String]} adWrapperIds - List of ad id's that were obtained from the different wrappers. Each redirect points to an ad wrapper. + * @return {bidIdentifier} - Object allowing the bid matching the ad event to be identified. + */ + +/** + * @typedef {Object} bidIdentifier + * @property {String} adId - Bid identifier. + * @property {String} adUnitCode - Identifier for the Ad Unit for which the bid was made. + * @property {String} auctionId - Id of the auction in which the bid was made. + * @property {String} requestId - Id of the bid request which resulted in the bid. + */ + +/** + * Factory function for obtaining a Video Impression Verifier. + * @param {Boolean} isCacheUsed - wether Prebid is configured to use a cache. + * @return {VideoImpressionVerifier} + */ export function videoImpressionVerifierFactory(isCacheUsed) { const vastXmlEditor = vastXmlEditorFactory(); const bidTracker = tracker(); @@ -27,7 +65,7 @@ function videoImpressionVerifier(vastXmlEditor_, bidTracker_) { if (vastUrl) { const url = new URL(vastUrl); - url.searchParams.append('pb_uuid', uuid); + url.searchParams.append(UUID_MARKER, uuid); bid.vastUrl = url.toString(); } else if (vastXml) { bid.vastXml = vastXmlEditor.getVastXmlWithTracking(vastXml, uuid); @@ -42,7 +80,7 @@ function videoImpressionVerifier(vastXmlEditor_, bidTracker_) { function cachedVideoImpressionVerifier(vastXmlEditor_, bidTracker_) { const verifier = baseImpressionVerifier(bidTracker_); const superTrackBid = verifier.trackBid; - const superGetTrackedBid = verifier.getTrackedBid; + const superGetBidIdentifiers = verifier.getBidIdentifiers; const vastXmlEditor = vastXmlEditor_; verifier.trackBid = function (bid, globalAdUnits) { @@ -77,10 +115,10 @@ function cachedVideoImpressionVerifier(vastXmlEditor_, bidTracker_) { return adIdOverride; } - verifier.getTrackedBid = function (adId, adTagUrl, adWrapperIds) { + verifier.getBidIdentifiers = function (adId, adTagUrl, adWrapperIds) { // When the video is cached, the ad tag loaded into the player is a parent wrapper of the cache url. // As a result, the ad tag Url cannot include identifiers. - return superGetTrackedBid(adId, null, adWrapperIds); + return superGetBidIdentifiers(adId, null, adWrapperIds); } return verifier; @@ -91,25 +129,18 @@ function baseImpressionVerifier(bidTracker_) { function trackBid(bid) { let { adId, adUnitCode, requestId, auctionId } = bid; - const uuid = 'pb-' + generateId(12); + const uuid = PB_PREFIX + generateId(12); bidTracker.store(uuid, { adId, adUnitCode, requestId, auctionId }); return uuid; } - // get tracked Bid from adUrl ad id, adWrapper Ids - // get uuid from url, ad id, wrapper ids - // match to tracked bid - // find actual bid object - // remove from tracked - // return actual bid object - - function getTrackedBid(adId, adTagUrl, adWrapperIds) { + function getBidIdentifiers(adId, adTagUrl, adWrapperIds) { return bidTracker.remove(adId) || getBidForAdTagUrl(adTagUrl) || getBidForAdWrappers(adWrapperIds); } return { trackBid, - getTrackedBid + getBidIdentifiers }; function getBidForAdTagUrl(adTagUrl) { @@ -119,7 +150,7 @@ function baseImpressionVerifier(bidTracker_) { const url = new URL(adTagUrl); const queryParams = url.searchParams; - let uuid = queryParams.get('pb_uuid'); + let uuid = queryParams.get(UUID_MARKER); return uuid && bidTracker.remove(uuid); } From c4646fccee3d4907345159914136e0c8ffbdb18e Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Fri, 4 Mar 2022 11:50:17 -0300 Subject: [PATCH 12/18] allows URL import --- modules/videoModule/adServer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/videoModule/adServer.js b/modules/videoModule/adServer.js index 7cc9e9ba7ea..9ec30b6e800 100644 --- a/modules/videoModule/adServer.js +++ b/modules/videoModule/adServer.js @@ -45,7 +45,7 @@ export function AdServerCore(parentModule_) { const vendorCode = config.vendorCode; try { parentModule.registerSubmodule(vendorCode, vendorCode, config); - } catch(e) {} + } catch (e) {} } /** From fabe4353ad08a84da2afd28ad25bed5f3ac0879e Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Fri, 4 Mar 2022 15:56:12 -0300 Subject: [PATCH 13/18] updates vast xml editor tests --- modules/videoModule/shared/vastXmlEditor.js | 4 ++ .../videoModule/shared/vastXmlEditor_spec.js | 44 +++++++++++++++---- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/modules/videoModule/shared/vastXmlEditor.js b/modules/videoModule/shared/vastXmlEditor.js index 988f31e8029..b586e5b4c29 100644 --- a/modules/videoModule/shared/vastXmlEditor.js +++ b/modules/videoModule/shared/vastXmlEditor.js @@ -31,6 +31,10 @@ export function VastXmlEditor(xmlUtil_) { } function replaceAdId(vastXmlDoc, adId) { + if (!adId) { + return; + } + const adNode = vastXmlDoc.querySelector('Ad'); if (!adNode) { return; diff --git a/test/spec/modules/videoModule/shared/vastXmlEditor_spec.js b/test/spec/modules/videoModule/shared/vastXmlEditor_spec.js index 3040e54a571..087ac93d7bc 100644 --- a/test/spec/modules/videoModule/shared/vastXmlEditor_spec.js +++ b/test/spec/modules/videoModule/shared/vastXmlEditor_spec.js @@ -47,7 +47,7 @@ describe('Vast XML Editor', function () { const expectedErrorUrl = 'https://test.error.com/ping.gif'; it('should add Impression Nodes to the Ad Wrapper', function () { - const vastXml = vastXmlEditor.getVastXmlWithTrackingNodes(adWrapperXml, expectedImpressionUrl, expectedImpressionId); + const vastXml = vastXmlEditor.getVastXmlWithTracking(adWrapperXml, null, expectedImpressionUrl, expectedImpressionId); const expectedXml = ` @@ -60,7 +60,7 @@ describe('Vast XML Editor', function () { }); it('should add Impression Nodes to the InLine', function () { - const vastXml = vastXmlEditor.getVastXmlWithTrackingNodes(inlineXml, expectedImpressionUrl, expectedImpressionId); + const vastXml = vastXmlEditor.getVastXmlWithTracking(inlineXml, null, expectedImpressionUrl, expectedImpressionId); const expectedXml = ` @@ -73,7 +73,7 @@ describe('Vast XML Editor', function () { }); it('should add Impression Nodes to the Ad Wrapper and Inline', function () { - const vastXml = vastXmlEditor.getVastXmlWithTrackingNodes(inLineWithWrapper, expectedImpressionUrl, expectedImpressionId); + const vastXml = vastXmlEditor.getVastXmlWithTracking(inLineWithWrapper, null, expectedImpressionUrl, expectedImpressionId); const expectedXml = ` @@ -92,7 +92,7 @@ describe('Vast XML Editor', function () { }); it('should add Error Nodes to the Ad Wrapper', function () { - const vastXml = vastXmlEditor.getVastXmlWithTrackingNodes(adWrapperXml, null, null, expectedErrorUrl); + const vastXml = vastXmlEditor.getVastXmlWithTracking(adWrapperXml, null, null, null, expectedErrorUrl); const expectedXml = ` @@ -105,7 +105,7 @@ describe('Vast XML Editor', function () { }); it('should add Error Nodes to the InLine', function () { - const vastXml = vastXmlEditor.getVastXmlWithTrackingNodes(inlineXml, null, null, expectedErrorUrl); + const vastXml = vastXmlEditor.getVastXmlWithTracking(inlineXml, null, null, null, expectedErrorUrl); const expectedXml = ` @@ -118,7 +118,7 @@ describe('Vast XML Editor', function () { }); it('should add Error Nodes to the Ad Wrapper and Inline', function () { - const vastXml = vastXmlEditor.getVastXmlWithTrackingNodes(inLineWithWrapper, null, null, expectedErrorUrl); + const vastXml = vastXmlEditor.getVastXmlWithTracking(inLineWithWrapper, null, null, null, expectedErrorUrl); const expectedXml = ` @@ -137,7 +137,7 @@ describe('Vast XML Editor', function () { }); it('should add Impression Nodes and Error Nodes to the Ad Wrapper', function () { - const vastXml = vastXmlEditor.getVastXmlWithTrackingNodes(adWrapperXml, expectedImpressionUrl, expectedImpressionId, expectedErrorUrl); + const vastXml = vastXmlEditor.getVastXmlWithTracking(adWrapperXml, null, expectedImpressionUrl, expectedImpressionId, expectedErrorUrl); const expectedXml = ` @@ -150,7 +150,7 @@ describe('Vast XML Editor', function () { }); it('should add Impression Nodes and Error Nodes to the InLine', function () { - const vastXml = vastXmlEditor.getVastXmlWithTrackingNodes(inlineXml, expectedImpressionUrl, expectedImpressionId, expectedErrorUrl); + const vastXml = vastXmlEditor.getVastXmlWithTracking(inlineXml, null, expectedImpressionUrl, expectedImpressionId, expectedErrorUrl); const expectedXml = ` @@ -163,7 +163,7 @@ describe('Vast XML Editor', function () { }); it('should add Impression Nodes and Error Nodes to the Ad Wrapper and Inline', function () { - const vastXml = vastXmlEditor.getVastXmlWithTrackingNodes(inLineWithWrapper, expectedImpressionUrl, expectedImpressionId, expectedErrorUrl); + const vastXml = vastXmlEditor.getVastXmlWithTracking(inLineWithWrapper, null, expectedImpressionUrl, expectedImpressionId, expectedErrorUrl); const expectedXml = ` @@ -177,6 +177,32 @@ describe('Vast XML Editor', function () { Random Title +`; + expect(vastXml).to.equal(expectedXml); + }); + + it('should override the ad id in inline', function () { + const vastXml = vastXmlEditor.getVastXmlWithTracking(inlineXml, 'adIdOverride'); + const expectedXml = ` + + + Prebid org + Random Title + + +`; + expect(vastXml).to.equal(expectedXml); + }); + + it('should override the ad id in the Ad Wrapper', function () { + const vastXml = vastXmlEditor.getVastXmlWithTracking(adWrapperXml, 'adIdOverride'); + const expectedXml = ` + + + Prebid org + + + `; expect(vastXml).to.equal(expectedXml); }); From 3f7d02ef3de9aaed024b424a7e206085ee1bf28d Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Mon, 7 Mar 2022 17:11:06 -0300 Subject: [PATCH 14/18] tests ad event processsing --- test/spec/modules/videoModule/pbVideo_spec.js | 163 ++++++++---------- .../videoImpressionVerifier_spec.js | 86 +++++++++ 2 files changed, 160 insertions(+), 89 deletions(-) create mode 100644 test/spec/modules/videoModule/videoImpressionVerifier_spec.js diff --git a/test/spec/modules/videoModule/pbVideo_spec.js b/test/spec/modules/videoModule/pbVideo_spec.js index b46741312f0..36fff268e99 100644 --- a/test/spec/modules/videoModule/pbVideo_spec.js +++ b/test/spec/modules/videoModule/pbVideo_spec.js @@ -1,6 +1,7 @@ import { expect } from 'chai'; import { PbVideo } from 'modules/videoModule/index.js'; import CONSTANTS from 'src/constants.json'; +import { AD_IMPRESSION, AD_ERROR, BID_VIDEO_IMPRESSION, BID_VIDEO_ERROR } from 'modules/videoModule/constants/events.js'; let ortbParamsMock; let videoCoreMock; @@ -10,7 +11,8 @@ let pbGlobalMock; let pbEventsMock; let videoEventsMock; let adServerMock; -let vastXmlEditorMock; +let videoImpressionVerifierFactoryMock; +let videoImpressionVerifierMock; function resetTestVars() { ortbParamsMock = { @@ -29,7 +31,8 @@ function resetTestVars() { }; pbGlobalMock = { requestBids: requestBidsMock, - getHighestCpmBids: sinon.spy() + getHighestCpmBids: sinon.spy(), + getBidResponsesForAdUnitCode: sinon.spy() }; pbEventsMock = { emit: sinon.spy(), @@ -40,13 +43,16 @@ function resetTestVars() { registerAdServer: sinon.spy(), getAdTagUrl: sinon.spy() }; - vastXmlEditorMock = { - getVastXmlWithTrackingNodes: sinon.spy(), - buildVastWrapper: sinon.spy() + + videoImpressionVerifierMock = { + trackBid: sinon.spy(), + getBidIdentifiers: sinon.spy() }; + + videoImpressionVerifierFactoryMock = () => videoImpressionVerifierMock; } -let pbVideoFactory = (videoCore, getConfig, pbGlobal, pbEvents, videoEvents, adServer, vastXmlEditor) => { +let pbVideoFactory = (videoCore, getConfig, pbGlobal, pbEvents, videoEvents, adServer, videoImpressionVerifierFactory) => { const pbVideo = PbVideo( videoCore || videoCoreMock, getConfig || getConfigMock, @@ -54,7 +60,7 @@ let pbVideoFactory = (videoCore, getConfig, pbGlobal, pbEvents, videoEvents, adS pbEvents || pbEventsMock, videoEvents || videoEventsMock, adServer || adServerMock, - vastXmlEditor || vastXmlEditorMock + videoImpressionVerifierFactory || videoImpressionVerifierFactoryMock ); pbVideo.init(); return pbVideo; @@ -112,8 +118,9 @@ describe('Prebid Video', function () { it('should register the ad server provider', function () { expect(adServerMock.registerAdServer.calledOnce).to.be.true; - expect(adServerMock.registerAdServer.getCall(0).args[0]).to.be.equal(test_vendor_code); - expect(adServerMock.registerAdServer.getCall(0).args[1]).to.be.equal(test_params); + const adServerConfig = adServerMock.registerAdServer.getCall(0).args[0]; + expect(adServerConfig.vendorCode).to.be.equal(test_vendor_code); + expect(adServerConfig.params).to.be.deep.equal(test_params); }); }); }); @@ -154,7 +161,11 @@ describe('Prebid Video', function () { let auctionEndCallback; const pbEvents = { emit: () => {}, - on: (event, callback) => auctionEndCallback = callback + on: (event, callback) => { + if (event === CONSTANTS.EVENTS.AUCTION_END) { + auctionEndCallback = callback + } + } }; const expectedVendorCode = 5; @@ -224,103 +235,77 @@ describe('Prebid Video', function () { }); describe('Ad tracking', function () { + const expectedAdEventPayload = { adEventPayloadMarker: 'marker' }; + const expectedBid = { bidMarker: 'marker' }; let bidAdjustmentCb; - const adUnitCode = 'test_ad_unit_code'; - const sampleBid = { - adId: 'test_ad_id', - adUnitCode, - vastUrl: 'test_ad_url' - }; - const sampleAdUnit = { - code: adUnitCode, - }; + let adImpressionCb; + let adErrorCb; + const pbEvents = { on: (event, callback) => { if (event === CONSTANTS.EVENTS.BID_ADJUSTMENT) { bidAdjustmentCb = callback; + } else if (event === AD_IMPRESSION) { + adImpressionCb = callback; + } else if (event === AD_ERROR) { + adErrorCb = callback; } }, - emit: () => {} + emit: sinon.spy() }; - const expectedImpressionUrl = 'test_impression_url'; - const expectedImpressionId = 'test_impression_id'; - const expectedErrorUrl = 'test_error_url'; - const expectedVastXml = 'test_xml'; - - it('should not listen for bid adjustments when caching is not configured', function () { - pbVideoFactory(null, () => null); - expect(pbEventsMock.on.neverCalledWith(CONSTANTS.EVENTS.BID_ADJUSTMENT)).to.be.true; - }); - it('should not modify the bid\'s adXml when the tracking config is omitted', function () { - const adUnit = Object.assign({}, sampleAdUnit, { video: { adServer: { tracking: null } } }); - const pbGlobal = Object.assign({}, pbGlobalMock, { adUnits: [ adUnit ] }); - pbVideoFactory(null, () => ({}), pbGlobal, pbEvents); - - bidAdjustmentCb(sampleBid); - expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.called).to.be.false; - expect(vastXmlEditorMock.buildVastWrapper.called).to.be.false; + it('should ask Impression Verifier to track bid on Bid Adjustment', function () { + pbVideoFactory(null, null, null, pbEvents); + bidAdjustmentCb(); + expect(videoImpressionVerifierMock.trackBid.calledOnce).to.be.true; }); - it('should request a vast wrapper when only an ad url is provided', function () { - const adUnit = Object.assign({}, sampleAdUnit, { video: { adServer: { tracking: { } } } }); - const pbGlobal = Object.assign({}, pbGlobalMock, { adUnits: [ adUnit ] }); - pbVideoFactory(null, () => ({}), pbGlobal, pbEvents); + it('should trigger video bid impression when the bid matched', function () { + pbEvents.emit.resetHistory(); + const pbGlobal = Object.assign({}, pbGlobalMock, { getBidResponsesForAdUnitCode: () => ({ bids: [expectedBid] }) }); + const videoImpressionVerifier = Object.assign({}, videoImpressionVerifierMock, { getBidIdentifiers: () => ({}) }); + pbVideoFactory(null, null, pbGlobal, pbEvents, null, null, () => videoImpressionVerifier); + adImpressionCb(expectedAdEventPayload); + + expect(pbEvents.emit.calledOnce).to.be.true; + expect(pbEvents.emit.getCall(0).args[0]).to.be.equal(BID_VIDEO_IMPRESSION); + const payload = pbEvents.emit.getCall(0).args[1]; + expect(payload.bid).to.be.equal(expectedBid); + expect(payload.adEvent).to.be.equal(expectedAdEventPayload); + }); - bidAdjustmentCb(sampleBid); - expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.called).to.be.false; - expect(vastXmlEditorMock.buildVastWrapper.called).to.be.true; + it('should trigger video bid error when the bid matched', function () { + pbEvents.emit.resetHistory(); + const pbGlobal = Object.assign({}, pbGlobalMock, { getBidResponsesForAdUnitCode: () => ({ bids: [expectedBid] }) }); + const videoImpressionVerifier = Object.assign({}, videoImpressionVerifierMock, { getBidIdentifiers: () => ({}) }); + pbVideoFactory(null, null, pbGlobal, pbEvents, null, null, () => videoImpressionVerifier); + adErrorCb(expectedAdEventPayload); + + expect(pbEvents.emit.calledOnce).to.be.true; + expect(pbEvents.emit.getCall(0).args[0]).to.be.equal(BID_VIDEO_ERROR); + const payload = pbEvents.emit.getCall(0).args[1]; + expect(payload.bid).to.be.equal(expectedBid); + expect(payload.adEvent).to.be.equal(expectedAdEventPayload); }); - it('should request the addition of tracking nodes when an ad xml is provided', function () { - const adUnit = Object.assign({}, sampleAdUnit, { video: { adServer: { tracking: { } } } }); - const pbGlobal = Object.assign({}, pbGlobalMock, { adUnits: [ adUnit ] }); - pbVideoFactory(null, () => ({}), pbGlobal, pbEvents); + it('should not trigger a bid impression when the bid did not match', function () { + pbEvents.emit.resetHistory(); + const pbGlobal = Object.assign({}, pbGlobalMock, { getBidResponsesForAdUnitCode: () => ({ bids: [expectedBid] }) }); + const videoImpressionVerifier = Object.assign({}, videoImpressionVerifierMock, { getBidIdentifiers: () => ({ auctionId: 'id' }) }); + pbVideoFactory(null, null, pbGlobal, pbEvents, null, null, () => videoImpressionVerifier); + adImpressionCb(expectedAdEventPayload); - const bid = Object.assign({}, sampleBid, { vastXml: 'test_xml' }); - bidAdjustmentCb(bid); - expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.called).to.be.true; - expect(vastXmlEditorMock.buildVastWrapper.called).to.be.false; + expect(pbEvents.emit.called).to.be.false; }); - it('should pass the tracking information as args to the xml editing function', function () { - const adUnit = Object.assign({}, sampleAdUnit, { video: { adServer: { tracking: { - impression: { - url: expectedImpressionUrl, - id: expectedImpressionId - }, - error: { - url: expectedErrorUrl - } - } } } }); - const pbGlobal = Object.assign({}, pbGlobalMock, { adUnits: [ adUnit ] }); - pbVideoFactory(null, () => ({}), pbGlobal, pbEvents); - - const bid = Object.assign({}, sampleBid, { vastXml: expectedVastXml }); - bidAdjustmentCb(bid); - expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.called).to.be.true; - expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.calledWith(expectedVastXml, expectedImpressionUrl, expectedImpressionId, expectedErrorUrl)) - expect(vastXmlEditorMock.buildVastWrapper.called).to.be.false; - }); + it('should not trigger a bid error when the bid did not match', function () { + pbEvents.emit.resetHistory(); + const pbGlobal = Object.assign({}, pbGlobalMock, { getBidResponsesForAdUnitCode: () => ({ bids: [expectedBid] }) }); + const videoImpressionVerifier = Object.assign({}, videoImpressionVerifierMock, { getBidIdentifiers: () => ({ auctionId: 'id' }) }); + pbVideoFactory(null, null, pbGlobal, pbEvents, null, null, () => videoImpressionVerifier); + adErrorCb(expectedAdEventPayload); - it('should generate the impression id when not specified in config', function () { - const adUnit = Object.assign({}, sampleAdUnit, { video: { adServer: { tracking: { - impression: { - url: expectedImpressionUrl, - }, - error: { - url: expectedErrorUrl - } - } } } }); - const pbGlobal = Object.assign({}, pbGlobalMock, { adUnits: [ adUnit ] }); - pbVideoFactory(null, () => ({}), pbGlobal, pbEvents); - - const bid = Object.assign({}, sampleBid, { vastXml: expectedVastXml }); - bidAdjustmentCb(bid); - const expectedGeneratedId = sampleBid.adId + '-impression'; - expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.called).to.be.true; - expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.calledWith(expectedVastXml, expectedImpressionUrl, expectedGeneratedId, expectedErrorUrl)) - expect(vastXmlEditorMock.buildVastWrapper.called).to.be.false; + expect(pbEvents.emit.called).to.be.false; }); }); }); diff --git a/test/spec/modules/videoModule/videoImpressionVerifier_spec.js b/test/spec/modules/videoModule/videoImpressionVerifier_spec.js new file mode 100644 index 00000000000..4ce78256569 --- /dev/null +++ b/test/spec/modules/videoModule/videoImpressionVerifier_spec.js @@ -0,0 +1,86 @@ +const adUnitCode = 'test_ad_unit_code'; +const sampleBid = { + adId: 'test_ad_id', + adUnitCode, + vastUrl: 'test_ad_url' +}; +const sampleAdUnit = { + code: adUnitCode, +}; + +const expectedImpressionUrl = 'test_impression_url'; +const expectedImpressionId = 'test_impression_id'; +const expectedErrorUrl = 'test_error_url'; +const expectedVastXml = 'test_xml'; + + +it('should not modify the bid\'s adXml when the tracking config is omitted', function () { + const adUnit = Object.assign({}, sampleAdUnit, { video: { adServer: { tracking: null } } }); + const pbGlobal = Object.assign({}, pbGlobalMock, { adUnits: [ adUnit ] }); + pbVideoFactory(null, () => ({}), pbGlobal, pbEvents); + + bidAdjustmentCb(sampleBid); + // expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.called).to.be.false; + // expect(vastXmlEditorMock.buildVastWrapper.called).to.be.false; +}); + +it('should request a vast wrapper when only an ad url is provided', function () { + const adUnit = Object.assign({}, sampleAdUnit, { video: { adServer: { tracking: { } } } }); + const pbGlobal = Object.assign({}, pbGlobalMock, { adUnits: [ adUnit ] }); + pbVideoFactory(null, () => ({}), pbGlobal, pbEvents); + + bidAdjustmentCb(sampleBid); + // expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.called).to.be.false; + // expect(vastXmlEditorMock.buildVastWrapper.called).to.be.true; +}); + +it('should request the addition of tracking nodes when an ad xml is provided', function () { + const adUnit = Object.assign({}, sampleAdUnit, { video: { adServer: { tracking: { } } } }); + const pbGlobal = Object.assign({}, pbGlobalMock, { adUnits: [ adUnit ] }); + pbVideoFactory(null, () => ({}), pbGlobal, pbEvents); + + const bid = Object.assign({}, sampleBid, { vastXml: 'test_xml' }); + bidAdjustmentCb(bid); + // expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.called).to.be.true; + // expect(vastXmlEditorMock.buildVastWrapper.called).to.be.false; +}); + +it('should pass the tracking information as args to the xml editing function', function () { + const adUnit = Object.assign({}, sampleAdUnit, { video: { adServer: { tracking: { + impression: { + url: expectedImpressionUrl, + id: expectedImpressionId + }, + error: { + url: expectedErrorUrl + } + } } } }); + const pbGlobal = Object.assign({}, pbGlobalMock, { adUnits: [ adUnit ] }); + pbVideoFactory(null, () => ({}), pbGlobal, pbEvents); + + const bid = Object.assign({}, sampleBid, { vastXml: expectedVastXml }); + bidAdjustmentCb(bid); + // expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.called).to.be.true; + // expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.calledWith(expectedVastXml, expectedImpressionUrl, expectedImpressionId, expectedErrorUrl)) + // expect(vastXmlEditorMock.buildVastWrapper.called).to.be.false; +}); + +it('should generate the impression id when not specified in config', function () { + const adUnit = Object.assign({}, sampleAdUnit, { video: { adServer: { tracking: { + impression: { + url: expectedImpressionUrl, + }, + error: { + url: expectedErrorUrl + } + } } } }); + const pbGlobal = Object.assign({}, pbGlobalMock, { adUnits: [ adUnit ] }); + pbVideoFactory(null, () => ({}), pbGlobal, pbEvents); + + const bid = Object.assign({}, sampleBid, { vastXml: expectedVastXml }); + bidAdjustmentCb(bid); + const expectedGeneratedId = sampleBid.adId + '-impression'; + // expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.called).to.be.true; + // expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.calledWith(expectedVastXml, expectedImpressionUrl, expectedGeneratedId, expectedErrorUrl)) + // expect(vastXmlEditorMock.buildVastWrapper.called).to.be.false; +}); From 0d3c90f6d8db6f5ed7092ac1941cb1a1e26a3e45 Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Mon, 7 Mar 2022 18:39:55 -0300 Subject: [PATCH 15/18] includes ad wrapper ids --- modules/jwplayerVideoProvider.js | 14 +++++++++++++- modules/videoModule/index.js | 4 ++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/modules/jwplayerVideoProvider.js b/modules/jwplayerVideoProvider.js index 1bb2dbac5cc..eb8a27cf7fa 100644 --- a/modules/jwplayerVideoProvider.js +++ b/modules/jwplayerVideoProvider.js @@ -923,8 +923,13 @@ export function adStateFactory() { waterfallCount: event.wcount, adPodCount: event.podcount, adPodIndex: event.sequence, - // need wrapper ad ids + wrapperAdIds: event.wrapperAdIds }; + + if (event.client === 'googima' && !updates.wrapperAdIds) { + updates.wrapperAdIds = parseImaAdWrapperIds(event); + } + this.updateState(updates); } @@ -951,6 +956,13 @@ export function adStateFactory() { } } + function parseImaAdWrapperIds(adEvent) { + const ima = adEvent.ima; + const ad = ima && ima.ad; + const h = ad && ad.h; + return h && h.adWrapperIds; + } + return adState; } diff --git a/modules/videoModule/index.js b/modules/videoModule/index.js index 12498be30fc..2433b0cf458 100644 --- a/modules/videoModule/index.js +++ b/modules/videoModule/index.js @@ -135,8 +135,8 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent } function getBid(adPayload) { - const { adId, adTagUrl, adWrapperIds } = adPayload; - const { bidAdId = adId, adUnitCode, requestId, auctionId } = videoImpressionVerifier.getBidIdentifiers(adId, adTagUrl, adWrapperIds); + const { adId, adTagUrl, wrapperAdIds } = adPayload; + const { bidAdId = adId, adUnitCode, requestId, auctionId } = videoImpressionVerifier.getBidIdentifiers(adId, adTagUrl, wrapperAdIds); const { bids } = pbGlobal.getBidResponsesForAdUnitCode(adUnitCode); return bids.find(bid => bid.adId === bidAdId && bid.requestId === requestId && bid.auctionId === auctionId); } From dfabe92749034ad927d04207925427192ccb5bd1 Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Tue, 8 Mar 2022 14:52:40 -0300 Subject: [PATCH 16/18] updates ad tag injection tests --- test/spec/modules/videoModule/pbVideo_spec.js | 27 +++++++++++++--- .../videoImpressionVerifier_spec.js | 31 +++++++++---------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/test/spec/modules/videoModule/pbVideo_spec.js b/test/spec/modules/videoModule/pbVideo_spec.js index 36fff268e99..2292f28f494 100644 --- a/test/spec/modules/videoModule/pbVideo_spec.js +++ b/test/spec/modules/videoModule/pbVideo_spec.js @@ -184,16 +184,27 @@ describe('Prebid Video', function () { }; const auctionResults = { adUnits: [ expectedAdUnit, {} ] }; + beforeEach(() => { + adServerMock.getAdTagUrl.resetHistory(); + videoCoreMock.setAdTagUrl.resetHistory(); + }); + it('should request ad tag url from adServer when configured to use adServer', function () { - pbVideoFactory(null, null, null, pbEvents); + const expectedVastUrl = 'expectedVastUrl'; + const expectedVastXml = 'expectedVastXml'; + const pbGlobal = Object.assign({}, pbGlobalMock, { + getHighestCpmBids: () => [{ + vastUrl: expectedVastUrl, + vastXml: expectedVastXml + }, {}, {}, {}] + }); + pbVideoFactory(null, null, pbGlobal, pbEvents); auctionEndCallback(auctionResults); expect(adServerMock.getAdTagUrl.calledOnce).to.be.true; expect(adServerMock.getAdTagUrl.getCall(0).args[0]).is.equal(expectedVendorCode); expect(adServerMock.getAdTagUrl.getCall(0).args[1]).is.equal(expectedAdUnit); expect(adServerMock.getAdTagUrl.getCall(0).args[2]).is.equal(expectedAdTag); - - expect(videoCoreMock.setAdTagUrl.called).to.be.false; }); it('should load ad tag when ad server return ad tag', function () { @@ -201,7 +212,15 @@ describe('Prebid Video', function () { const adServerCore = Object.assign({}, adServerMock, { getAdTagUrl: () => expectedAdTag }); - pbVideoFactory(null, null, null, pbEvents, null, adServerCore); + const expectedVastUrl = 'expectedVastUrl'; + const expectedVastXml = 'expectedVastXml'; + const pbGlobal = Object.assign({}, pbGlobalMock, { + getHighestCpmBids: () => [{ + vastUrl: expectedVastUrl, + vastXml: expectedVastXml + }, {}, {}, {}] + }); + pbVideoFactory(null, null, pbGlobal, pbEvents, null, adServerCore); auctionEndCallback(auctionResults); expect(videoCoreMock.setAdTagUrl.calledOnce).to.be.true; expect(videoCoreMock.setAdTagUrl.args[0][0]).to.be.equal(expectedAdTag); diff --git a/test/spec/modules/videoModule/videoImpressionVerifier_spec.js b/test/spec/modules/videoModule/videoImpressionVerifier_spec.js index 4ce78256569..60953d75818 100644 --- a/test/spec/modules/videoModule/videoImpressionVerifier_spec.js +++ b/test/spec/modules/videoModule/videoImpressionVerifier_spec.js @@ -13,7 +13,6 @@ const expectedImpressionId = 'test_impression_id'; const expectedErrorUrl = 'test_error_url'; const expectedVastXml = 'test_xml'; - it('should not modify the bid\'s adXml when the tracking config is omitted', function () { const adUnit = Object.assign({}, sampleAdUnit, { video: { adServer: { tracking: null } } }); const pbGlobal = Object.assign({}, pbGlobalMock, { adUnits: [ adUnit ] }); @@ -47,14 +46,14 @@ it('should request the addition of tracking nodes when an ad xml is provided', f it('should pass the tracking information as args to the xml editing function', function () { const adUnit = Object.assign({}, sampleAdUnit, { video: { adServer: { tracking: { - impression: { - url: expectedImpressionUrl, - id: expectedImpressionId - }, - error: { - url: expectedErrorUrl - } - } } } }); + impression: { + url: expectedImpressionUrl, + id: expectedImpressionId + }, + error: { + url: expectedErrorUrl + } + } } } }); const pbGlobal = Object.assign({}, pbGlobalMock, { adUnits: [ adUnit ] }); pbVideoFactory(null, () => ({}), pbGlobal, pbEvents); @@ -67,13 +66,13 @@ it('should pass the tracking information as args to the xml editing function', f it('should generate the impression id when not specified in config', function () { const adUnit = Object.assign({}, sampleAdUnit, { video: { adServer: { tracking: { - impression: { - url: expectedImpressionUrl, - }, - error: { - url: expectedErrorUrl - } - } } } }); + impression: { + url: expectedImpressionUrl, + }, + error: { + url: expectedErrorUrl + } + } } } }); const pbGlobal = Object.assign({}, pbGlobalMock, { adUnits: [ adUnit ] }); pbVideoFactory(null, () => ({}), pbGlobal, pbEvents); From 2c8accb21bfe92058ff2608320ae7d7b9949e960 Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Wed, 9 Mar 2022 11:16:54 -0300 Subject: [PATCH 17/18] tests impression tracking --- .../videoModule/videoImpressionVerifier.js | 12 ++++----- .../videoImpressionVerifier_spec.js | 27 +++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/modules/videoModule/videoImpressionVerifier.js b/modules/videoModule/videoImpressionVerifier.js index 704441d9a97..3b090819f5a 100644 --- a/modules/videoModule/videoImpressionVerifier.js +++ b/modules/videoModule/videoImpressionVerifier.js @@ -2,8 +2,8 @@ import find from 'core-js-pure/features/array/find'; import URL from 'core-js-pure/web/url'; import { vastXmlEditorFactory } from './shared/vastXmlEditor.js'; -const PB_PREFIX = 'pb_'; -const UUID_MARKER = PB_PREFIX + 'uuid'; +export const PB_PREFIX = 'pb_'; +export const UUID_MARKER = PB_PREFIX + 'uuid'; /** * Video Impression Verifier interface. All implementations of a Video Impression Verifier must comply with this interface. @@ -50,7 +50,7 @@ export function videoImpressionVerifierFactory(isCacheUsed) { return videoImpressionVerifier(vastXmlEditor, bidTracker); } -function videoImpressionVerifier(vastXmlEditor_, bidTracker_) { +export function videoImpressionVerifier(vastXmlEditor_, bidTracker_) { const verifier = baseImpressionVerifier(bidTracker_); const superTrackBid = verifier.trackBid; const vastXmlEditor = vastXmlEditor_; @@ -77,7 +77,7 @@ function videoImpressionVerifier(vastXmlEditor_, bidTracker_) { return verifier; } -function cachedVideoImpressionVerifier(vastXmlEditor_, bidTracker_) { +export function cachedVideoImpressionVerifier(vastXmlEditor_, bidTracker_) { const verifier = baseImpressionVerifier(bidTracker_); const superTrackBid = verifier.trackBid; const superGetBidIdentifiers = verifier.getBidIdentifiers; @@ -124,7 +124,7 @@ function cachedVideoImpressionVerifier(vastXmlEditor_, bidTracker_) { return verifier; } -function baseImpressionVerifier(bidTracker_) { +export function baseImpressionVerifier(bidTracker_) { const bidTracker = bidTracker_; function trackBid(bid) { @@ -168,7 +168,7 @@ function baseImpressionVerifier(bidTracker_) { } } -function tracker() { +export function tracker() { const model = {}; function store(key, value) { diff --git a/test/spec/modules/videoModule/videoImpressionVerifier_spec.js b/test/spec/modules/videoModule/videoImpressionVerifier_spec.js index 60953d75818..45c04a2414a 100644 --- a/test/spec/modules/videoModule/videoImpressionVerifier_spec.js +++ b/test/spec/modules/videoModule/videoImpressionVerifier_spec.js @@ -1,3 +1,29 @@ +import { baseImpressionVerifier, PB_PREFIX } from 'modules/videoModule/videoImpressionVerifier.js'; + +let trackerMock; +trackerMock = { + store: sinon.spy(), + remove: sinon.spy() +} + +describe('Base Impression Verifier', function() { + describe('trackBid', function () { + it('should generate uuid', function () { + const baseVerifier = baseImpressionVerifier(trackerMock); + const uuid = baseVerifier.trackBid({}); + expect(uuid.substring(0, 3)).to.equal(PB_PREFIX); + expect(uuid.length).to.be.equal(15); + }); + }); + + describe('getBidIdentifiers', function () { + it('should match ad id to uuid', function () { + + }); + }); +}); + +/* const adUnitCode = 'test_ad_unit_code'; const sampleBid = { adId: 'test_ad_id', @@ -83,3 +109,4 @@ it('should generate the impression id when not specified in config', function () // expect(vastXmlEditorMock.getVastXmlWithTrackingNodes.calledWith(expectedVastXml, expectedImpressionUrl, expectedGeneratedId, expectedErrorUrl)) // expect(vastXmlEditorMock.buildVastWrapper.called).to.be.false; }); +*/ From dab81868042f0c9f3f81c14328baa8d4fefeda00 Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Wed, 9 Mar 2022 12:05:32 -0300 Subject: [PATCH 18/18] updates for new find --- modules/videoModule/videoImpressionVerifier.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/videoModule/videoImpressionVerifier.js b/modules/videoModule/videoImpressionVerifier.js index 3b090819f5a..5e6d1e24e9a 100644 --- a/modules/videoModule/videoImpressionVerifier.js +++ b/modules/videoModule/videoImpressionVerifier.js @@ -1,5 +1,4 @@ -import find from 'core-js-pure/features/array/find'; -import URL from 'core-js-pure/web/url'; +import find from 'prebidjs-polyfill/find.js'; import { vastXmlEditorFactory } from './shared/vastXmlEditor.js'; export const PB_PREFIX = 'pb_';