Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/prebid/Prebid.js
Browse files Browse the repository at this point in the history
* 'master' of https://github.com/prebid/Prebid.js:
  Increment pre version
  Prebid 0.32.0 Release
  Commenting out tests that are failing in IE10 (prebid#1710)
  Update dfp.buildVideoUrl to accept adserver url (prebid#1663)
  Update rubicon adapter with new properties and 1.0 changes (prebid#1776)
  Added adUnitCode for compatibility (prebid#1781)
  Remove 'supported' from analytics adapter info (prebid#1780)
  Add TTL parameter to bid (prebid#1784)
  • Loading branch information
m.sorochuk committed Nov 1, 2017
2 parents e45235f + 5f40791 commit d548fb8
Show file tree
Hide file tree
Showing 13 changed files with 279 additions and 121 deletions.
71 changes: 67 additions & 4 deletions modules/dfpAdServerVideo.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

import { registerVideoSupport } from '../src/adServerManager';
import { getWinningBids } from '../src/targeting';
import { formatQS, format as buildUrl } from '../src/url';
import { parseSizesInput } from '../src/utils';
import { formatQS, format as buildUrl, parse } from '../src/url';
import { deepAccess, isEmpty, logError, parseSizesInput } from '../src/utils';
import { config } from '../src/config';

/**
* @typedef {Object} DfpVideoParams
Expand All @@ -31,8 +32,9 @@ import { parseSizesInput } from '../src/utils';
* @param [Object] bid The bid which should be considered alongside the rest of the adserver's demand.
* If this isn't defined, then we'll use the winning bid for the adUnit.
*
* @param {DfpVideoParams} params Query params which should be set on the DFP request.
* @param {DfpVideoParams} [params] Query params which should be set on the DFP request.
* These will override this module's defaults whenever they conflict.
* @param {string} [url] video adserver url
*/

/** Safe defaults which work on pretty much all video calls. */
Expand All @@ -55,9 +57,26 @@ const defaultParamConstants = {
* demand in DFP.
*/
export default function buildDfpVideoUrl(options) {
if (!options.params && !options.url) {
logError(`A params object or a url is required to use pbjs.adServers.dfp.buildVideoUrl`);
return;
}

const adUnit = options.adUnit;
const bid = options.bid || getWinningBids(adUnit.code)[0];

let urlComponents = {};

if (options.url) {
// when both `url` and `params` are given, parsed url will be overwriten
// with any matching param components
urlComponents = parse(options.url);

if (isEmpty(options.params)) {
return buildUrlFromAdserverUrlComponents(urlComponents, bid);
}
}

const derivedParams = {
correlator: Date.now(),
sz: parseSizesInput(adUnit.sizes).join('|'),
Expand All @@ -73,9 +92,14 @@ export default function buildDfpVideoUrl(options) {

const queryParams = Object.assign({},
defaultParamConstants,
urlComponents.search,
derivedParams,
options.params,
{ cust_params: encodeURIComponent(formatQS(customParams)) });
{ cust_params: encodeURIComponent(formatQS(customParams)) }
);

const descriptionUrl = getDescriptionUrl(bid, options, 'params');
if (descriptionUrl) { queryParams.description_url = descriptionUrl; }

return buildUrl({
protocol: 'https',
Expand All @@ -85,6 +109,45 @@ export default function buildDfpVideoUrl(options) {
});
}

/**
* Builds a video url from a base dfp video url and a winning bid, appending
* Prebid-specific key-values.
* @param {Object} components base video adserver url parsed into components object
* @param {AdapterBidResponse} bid winning bid object to append parameters from
* @return {string} video url
*/
function buildUrlFromAdserverUrlComponents(components, bid) {
const descriptionUrl = getDescriptionUrl(bid, components, 'search');
if (descriptionUrl) { components.search.description_url = descriptionUrl; }

const adserverTargeting = (bid && bid.adserverTargeting) || {};
const customParams = Object.assign({},
adserverTargeting,
);
components.search.cust_params = encodeURIComponent(formatQS(customParams));

return buildUrl(components);
}

/**
* Returns the encoded vast url if it exists on a bid object, only if prebid-cache
* is disabled, and description_url is not already set on a given input
* @param {AdapterBidResponse} bid object to check for vast url
* @param {Object} components the object to check that description_url is NOT set on
* @param {string} prop the property of components that would contain description_url
* @return {string | undefined} The encoded vast url if it exists, or undefined
*/
function getDescriptionUrl(bid, components, prop) {
if (config.getConfig('usePrebidCache')) { return; }

if (!deepAccess(components, `${prop}.description_url`)) {
const vastUrl = bid && bid.vastUrl;
if (vastUrl) { return encodeURIComponent(vastUrl); }
} else {
logError(`input cannnot contain description_url`);
}
}

registerVideoSupport('dfp', {
buildVideoUrl: buildDfpVideoUrl
});
1 change: 1 addition & 0 deletions modules/improvedigitalBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export const spec = {
bid.height = bidObject.h;
bid.netRevenue = bidObject.isNet ? bidObject.isNet : false;
bid.requestId = bidObject.id;
bid.ttl = 300;
bid.width = bidObject.w;

bids.push(bid);
Expand Down
27 changes: 13 additions & 14 deletions modules/rubiconBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import * as utils from 'src/utils';
import { registerBidder } from 'src/adapters/bidderFactory';
import { config } from 'src/config';

// use deferred function call since version isn't defined yet at this point
function getIntegration() {
return 'pbjs_lite_' + $$PREBID_GLOBAL$$.version;
}
const INTEGRATION = 'pbjs_lite_v$prebid.version$';

function isSecure() {
return location.protocol === 'https:';
Expand Down Expand Up @@ -113,7 +111,7 @@ export const spec = {
page_url: !params.referrer ? utils.getTopWindowUrl() : params.referrer,
resolution: _getScreenResolution(),
account_id: params.accountId,
integration: getIntegration(),
integration: INTEGRATION,
timeout: bidderRequest.timeout - (Date.now() - bidderRequest.auctionStart + TIMEOUT_BUFFER),
stash_creatives: true,
ae_pass_through_parameters: params.video.aeParams,
Expand All @@ -126,8 +124,8 @@ export const spec = {
zone_id: params.zoneId,
position: params.position || 'btf',
floor: parseFloat(params.floor) > 0.01 ? params.floor : 0.01,
element_id: bidRequest.placementCode,
name: bidRequest.placementCode,
element_id: bidRequest.adUnitCode,
name: bidRequest.adUnitCode,
language: params.video.language,
width: size[0],
height: size[1],
Expand Down Expand Up @@ -187,7 +185,7 @@ export const spec = {
'p_pos', position,
'rp_floor', floor,
'rp_secure', isSecure() ? '1' : '0',
'tk_flint', getIntegration(),
'tk_flint', INTEGRATION,
'tid', bidRequest.transactionId,
'p_screen_res', _getScreenResolution(),
'kw', keywords,
Expand Down Expand Up @@ -240,7 +238,7 @@ export const spec = {

// video ads array is wrapped in an object
if (typeof bidRequest === 'object' && bidRequest.mediaType === 'video' && typeof ads === 'object') {
ads = ads[bidRequest.placementCode];
ads = ads[bidRequest.adUnitCode];
}

// check the ad response
Expand All @@ -259,10 +257,11 @@ export const spec = {
let bid = {
requestId: bidRequest.bidId,
currency: 'USD',
creative_id: ad.creative_id,
bidderCode: spec.code,
creativeId: ad.creative_id,
cpm: ad.cpm || 0,
dealId: ad.deal
dealId: ad.deal,
ttl: 300, // 5 minutes
netRevenue: config.getConfig('rubicon.netRevenue') || false
};
if (bidRequest.mediaType === 'video') {
bid.width = bidRequest.params.video.playerWidth;
Expand All @@ -280,7 +279,7 @@ export const spec = {
.reduce((memo, item) => {
memo[item.key] = item.values[0];
return memo;
}, {'rpfl_elemid': bidRequest.placementCode});
}, {'rpfl_elemid': bidRequest.adUnitCode});

bids.push(bid);

Expand Down Expand Up @@ -308,7 +307,7 @@ function _getScreenResolution() {

function _getDigiTrustQueryParams() {
function getDigiTrustId() {
let digiTrustUser = window.DigiTrust && ($$PREBID_GLOBAL$$.getConfig('digiTrustId') || window.DigiTrust.getUser({member: 'T9QSFKPDN9'}));
let digiTrustUser = window.DigiTrust && (config.getConfig('digiTrustId') || window.DigiTrust.getUser({member: 'T9QSFKPDN9'}));
return (digiTrustUser && digiTrustUser.success && digiTrustUser.identity) || null;
}
let digiTrustId = getDigiTrustId();
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "prebid.js",
"version": "0.32.0-pre",
"version": "0.33.0-pre",
"description": "Header Bidding Management Library",
"main": "src/prebid.js",
"scripts": {
Expand Down
4 changes: 4 additions & 0 deletions src/adapters/bidderFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ export function newBidder(spec) {
const bidRequestMap = {};
validBidRequests.forEach(bid => {
bidRequestMap[bid.bidId] = bid;
// Delete this once we are 1.0
if (!bid.adUnitCode) {
bid.adUnitCode = bid.placementCode
}
});

let requests = spec.buildRequests(validBidRequests, bidderRequest);
Expand Down
2 changes: 1 addition & 1 deletion src/prebid.js
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ $$PREBID_GLOBAL$$.loadScript = function (tagSrc, callback, useCache) {
* For usage, see [Integrate with the Prebid Analytics
* API](http://prebid.org/dev-docs/integrate-with-the-prebid-analytics-api.html).
*
* For a list of supported analytics adapters, see [Analytics for
* For a list of analytics adapters, see [Analytics for
* Prebid](http://prebid.org/overview/analytics.html).
* @param {Object} config
* @param {string} config.provider The name of the provider, e.g., `"ga"` for Google Analytics.
Expand Down
2 changes: 1 addition & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ exports.isNumber = function(object) {
*/
exports.isEmpty = function (object) {
if (!object) return true;
if (this.isArray(object) || this.isStr(object)) {
if (exports.isArray(object) || exports.isStr(object)) {
return !(object.length > 0);
}

Expand Down
12 changes: 11 additions & 1 deletion src/video.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { videoAdapters } from './adaptermanager';
import { getBidRequest, deepAccess } from './utils';
import { getBidRequest, deepAccess, logError } from './utils';
import { config } from '../src/config';

const VIDEO_MEDIA_TYPE = 'video';
const OUTSTREAM = 'outstream';
Expand Down Expand Up @@ -32,6 +33,15 @@ export function isValidVideoBid(bid) {
// if context not defined assume default 'instream' for video bids
// instream bids require a vast url or vast xml content
if (!bidRequest || (videoMediaType && context !== OUTSTREAM)) {
// xml-only video bids require prebid-cache to be enabled
if (!config.getConfig('usePrebidCache') && bid.vastXml && !bid.vastUrl) {
logError(`
This bid contains only vastXml and will not work when prebid-cache is disabled.
Try enabling prebid-cache with pbjs.setConfig({ usePrebidCache: true });
`);
return false;
}

return !!(bid.vastUrl || bid.vastXml);
}

Expand Down
58 changes: 58 additions & 0 deletions test/spec/modules/dfpAdServerVideo_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import parse from 'url-parse';
import buildDfpVideoUrl from 'modules/dfpAdServerVideo';
import { parseQS } from 'src/url';
import adUnit from 'test/fixtures/video/adUnit';
import { newConfig } from 'src/config';

const bid = {
videoCacheKey: 'abc',
Expand Down Expand Up @@ -36,6 +37,43 @@ describe('The DFP video support module', () => {
expect(queryParams).to.have.property('url');
});

it('can take an adserver url as a parameter', () => {
const bidCopy = Object.assign({ }, bid);
bidCopy.vastUrl = 'vastUrl.example';

const url = parse(buildDfpVideoUrl({
adUnit: adUnit,
bid: bidCopy,
url: 'https://video.adserver.example/',
}));

expect(url.host).to.equal('video.adserver.example');

const queryObject = parseQS(url.query);
expect(queryObject.description_url).to.equal('vastUrl.example');
});

it('requires a params object or url', () => {
const url = buildDfpVideoUrl({
adUnit: adUnit,
bid: bid,
});

expect(url).to.be.undefined;
});

it('overwrites url params when both url and params object are given', () => {
const url = parse(buildDfpVideoUrl({
adUnit: adUnit,
bid: bid,
url: 'https://video.adserver.example/ads?sz=640x480&iu=/123/aduniturl&impl=s',
params: { iu: 'my/adUnit' }
}));

const queryObject = parseQS(url.query);
expect(queryObject.iu).to.equal('my/adUnit');
});

it('should override param defaults with user-provided ones', () => {
const url = parse(buildDfpVideoUrl({
adUnit: adUnit,
Expand Down Expand Up @@ -92,6 +130,26 @@ describe('The DFP video support module', () => {
expect(customParams).to.have.property('my_targeting', 'foo');
});

it('should not overwrite an existing description_url for object input and cache disabled', () => {
const config = newConfig();
config.setConfig({ usePrebidCache: true });

const bidCopy = Object.assign({}, bid);
bidCopy.vastUrl = 'vastUrl.example';

const url = parse(buildDfpVideoUrl({
adUnit: adUnit,
bid: bidCopy,
params: {
iu: 'my/adUnit',
description_url: 'descriptionurl.example'
}
}));

const queryObject = parseQS(url.query);
expect(queryObject.description_url).to.equal('descriptionurl.example');
});

it('should work with nobid responses', () => {
const url = buildDfpVideoUrl({
adUnit: adUnit,
Expand Down
2 changes: 2 additions & 0 deletions test/spec/modules/improvedigitalBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ describe('Improve Digital Adapter Tests', function () {
'height': 290,
'netRevenue': false,
'requestId': '33e9500b21129f',
'ttl': 300,
'width': 600
}
];
Expand All @@ -219,6 +220,7 @@ describe('Improve Digital Adapter Tests', function () {
'height': 400,
'netRevenue': true,
'requestId': '1234',
'ttl': 300,
'width': 700
}
];
Expand Down
Loading

0 comments on commit d548fb8

Please sign in to comment.