From 939c455a469703f0c98d021fd70d3b851ae69ba7 Mon Sep 17 00:00:00 2001 From: Olivier Date: Wed, 25 Nov 2020 16:41:39 +0100 Subject: [PATCH] Add support for `backupOnly` option in mediaType video renderer (#5972) * Add support for `backupOnly` option in mediaType video renderer * Improve readability --- src/Renderer.js | 18 +++++++++++++++++- src/auction.js | 6 +++--- test/spec/auctionmanager_spec.js | 32 ++++++++++++++++++++++++++++++++ test/spec/renderer_spec.js | 30 ++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 4 deletions(-) diff --git a/src/Renderer.js b/src/Renderer.js index f073d97d052..7cedf278537 100644 --- a/src/Renderer.js +++ b/src/Renderer.js @@ -115,5 +115,21 @@ function isRendererPreferredFromAdUnit(adUnitCode) { const adUnit = find(adUnits, adUnit => { return adUnit.code === adUnitCode; }); - return !!(adUnit && adUnit.renderer && adUnit.renderer.url && adUnit.renderer.render && !(utils.isBoolean(adUnit.renderer.backupOnly) && adUnit.renderer.backupOnly)); + + if (!adUnit) { + return false + } + + // renderer defined at adUnit level + const adUnitRenderer = utils.deepAccess(adUnit, 'renderer'); + const hasValidAdUnitRenderer = !!(adUnitRenderer && adUnitRenderer.url && adUnitRenderer.render); + + // renderer defined at adUnit.mediaTypes level + const mediaTypeRenderer = utils.deepAccess(adUnit, 'mediaTypes.video.renderer'); + const hasValidMediaTypeRenderer = !!(mediaTypeRenderer && mediaTypeRenderer.url && mediaTypeRenderer.render) + + return !!( + (hasValidAdUnitRenderer && !(adUnitRenderer.backupOnly === true)) || + (hasValidMediaTypeRenderer && !(mediaTypeRenderer.backupOnly === true)) + ); } diff --git a/src/auction.js b/src/auction.js index 6285bfdd905..c94e3adc9a7 100644 --- a/src/auction.js +++ b/src/auction.js @@ -57,7 +57,7 @@ * @property {function(): void} callBids - sends requests to all adapters for bids */ -import {flatten, timestamp, adUnitsFilter, deepAccess, getBidRequest, getValue, parseUrl, isBoolean} from './utils.js'; +import {flatten, timestamp, adUnitsFilter, deepAccess, getBidRequest, getValue, parseUrl} from './utils.js'; import { getPriceBucketString } from './cpmBucketManager.js'; import { getNativeTargeting } from './native.js'; import { getCacheUrl, store } from './videoCache.js'; @@ -533,9 +533,9 @@ function getPreparedBidForAuction({adUnitCode, bid, bidderRequest, auctionId}) { var renderer = null; // the renderer for the mediaType takes precendence - if (mediaTypeRenderer && mediaTypeRenderer.url && mediaTypeRenderer.render) { + if (mediaTypeRenderer && mediaTypeRenderer.url && !(mediaTypeRenderer.backupOnly === true && mediaTypeRenderer.render)) { renderer = mediaTypeRenderer; - } else if (adUnitRenderer && adUnitRenderer.url && !(adUnitRenderer.backupOnly && isBoolean(adUnitRenderer.backupOnly) && bid.renderer)) { + } else if (adUnitRenderer && adUnitRenderer.url && !(adUnitRenderer.backupOnly === true && bid.renderer)) { renderer = adUnitRenderer; } diff --git a/test/spec/auctionmanager_spec.js b/test/spec/auctionmanager_spec.js index d880ff0eaee..a50eba5e585 100644 --- a/test/spec/auctionmanager_spec.js +++ b/test/spec/auctionmanager_spec.js @@ -793,6 +793,38 @@ describe('auctionmanager.js', function () { assert.equal(addedBid.renderer.url, renderer.url); }); + it('installs bidder-defined renderer when onlyBackup is true in mediaTypes.video options ', function () { + const renderer = { + url: 'videoRenderer.js', + backupOnly: true, + render: (bid) => bid + }; + let myBid = mockBid(); + let bidRequest = mockBidRequest(myBid); + + bidRequest.bids[0] = { + ...bidRequest.bids[0], + mediaTypes: { + video: { + context: 'outstream', + renderer + } + } + }; + makeRequestsStub.returns([bidRequest]); + + myBid.mediaType = 'video'; + myBid.renderer = { + url: 'renderer.js', + render: sinon.spy() + }; + spec.interpretResponse.returns(myBid); + auction.callBids(); + + const addedBid = auction.getBidsReceived().pop(); + assert.strictEqual(addedBid.renderer.url, myBid.renderer.url); + }); + it('bid for a regular unit and a video unit', function() { let renderer = { url: 'renderer.js', diff --git a/test/spec/renderer_spec.js b/test/spec/renderer_spec.js index 9bf551f35e8..dcca94396cd 100644 --- a/test/spec/renderer_spec.js +++ b/test/spec/renderer_spec.js @@ -155,6 +155,36 @@ describe('Renderer', function () { expect(loadExternalScript.called).to.be.true; }); + it('should load external script instead of publisher-defined one when backupOnly option is true in mediaTypes.video options', function() { + $$PREBID_GLOBAL$$.adUnits = [{ + code: 'video1', + mediaTypes: { + video: { + context: 'outstream', + mimes: ['video/mp4'], + playerSize: [[400, 300]], + renderer: { + url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', + backupOnly: true, + render: sinon.spy() + }, + } + } + }] + + let testRenderer = Renderer.install({ + url: 'https://httpbin.org/post', + config: { test: 'config1' }, + id: 1, + adUnitCode: 'video1' + + }); + testRenderer.setRender(() => {}) + + testRenderer.render() + expect(loadExternalScript.called).to.be.true; + }); + it('should call loadExternalScript() for script not defined on adUnit, only when .render() is called', function() { $$PREBID_GLOBAL$$.adUnits = [{ code: 'video1',