From b97bacac3d07f58053582420a8865fc93210b41c Mon Sep 17 00:00:00 2001 From: Matt Lane Date: Wed, 24 May 2017 15:41:17 -0700 Subject: [PATCH 01/95] Map sponsor request param to endpoint param (#1219) --- src/adapters/appnexusAst.js | 3 ++- test/spec/adapters/appnexusAst_spec.js | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/adapters/appnexusAst.js b/src/adapters/appnexusAst.js index 11b1dfdf330..a3bd0e72441 100644 --- a/src/adapters/appnexusAst.js +++ b/src/adapters/appnexusAst.js @@ -19,7 +19,8 @@ const NATIVE_MAPPING = { required: true, sizes: [{}] } - } + }, + sponsoredBy: 'sponsored_by' }; /** diff --git a/test/spec/adapters/appnexusAst_spec.js b/test/spec/adapters/appnexusAst_spec.js index eb5a66851eb..db037f6d27b 100644 --- a/test/spec/adapters/appnexusAst_spec.js +++ b/test/spec/adapters/appnexusAst_spec.js @@ -133,7 +133,8 @@ describe('AppNexusAdapter', () => { REQUEST.bids[0].mediaType = 'native'; REQUEST.bids[0].nativeParams = { title: {required: true}, - body: {required: true} + body: {required: true}, + sponsoredBy: {required: true} }; adapter.callBids(REQUEST); @@ -141,7 +142,8 @@ describe('AppNexusAdapter', () => { const request = JSON.parse(requests[0].requestBody); expect(request.tags[0].native.layouts[0]).to.deep.equal({ title: {required: true}, - description: {required: true} + description: {required: true}, + sponsored_by: {required: true} }); delete REQUEST.bids[0].mediaType; From a4d5160535096231e5adfbbff7ef3948b698db0e Mon Sep 17 00:00:00 2001 From: Matt Kendall Date: Wed, 24 May 2017 21:43:48 -0400 Subject: [PATCH 02/95] Bugfix/target filtering api fix (#1220) * fix bug and unit tests * Fix space * PR review fix * Address review comments. Fix 1 more bug :) * Add back alias * Make sure we reset targeting properly based on input type. * update per review * defensive coding --- src/prebid.js | 11 ++++++----- src/targeting.js | 35 ++++++++++++++++++++++++++------- test/spec/unit/pbjs_api_spec.js | 16 ++++++++++++--- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/prebid.js b/src/prebid.js index 190d048fa40..3f5ae70f6e9 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -257,10 +257,11 @@ $$PREBID_GLOBAL$$.getBidResponsesForAdUnitCode = function (adUnitCode) { }; /** - * Set query string targeting on all GPT ad units. + * Set query string targeting on one or more GPT ad units. + * @param {(string|string[])} adUnit a single `adUnit.code` or multiple. * @alias module:$$PREBID_GLOBAL$$.setTargetingForGPTAsync */ -$$PREBID_GLOBAL$$.setTargetingForGPTAsync = function (adUnits) { +$$PREBID_GLOBAL$$.setTargetingForGPTAsync = function (adUnit) { utils.logInfo('Invoking $$PREBID_GLOBAL$$.setTargetingForGPTAsync', arguments); if (!isGptPubadsDefined()) { utils.logError('window.googletag is not defined on the page'); @@ -268,13 +269,13 @@ $$PREBID_GLOBAL$$.setTargetingForGPTAsync = function (adUnits) { } // get our ad unit codes - var adUnitCodes = targeting.getAllTargeting(adUnits); + var targetingSet = targeting.getAllTargeting(adUnit); // first reset any old targeting - targeting.resetPresetTargeting(adUnitCodes); + targeting.resetPresetTargeting(adUnit); // now set new targeting keys - targeting.setTargeting(adUnitCodes); + targeting.setTargeting(targetingSet); // emit event diff --git a/src/targeting.js b/src/targeting.js index 15809534c00..2d5e75e38a7 100644 --- a/src/targeting.js +++ b/src/targeting.js @@ -9,11 +9,12 @@ var pbTargetingKeys = []; targeting.resetPresetTargeting = function(adUnitCode) { if (isGptPubadsDefined()) { - const adUnitCodes = adUnitCode && adUnitCode.length ? [adUnitCode] : $$PREBID_GLOBAL$$._adUnitCodes; + const adUnitCodes = getAdUnitCodes(adUnitCode); + const adUnits = $$PREBID_GLOBAL$$.adUnits.filter(adUnit => adUnitCodes.includes(adUnit.code)); window.googletag.pubads().getSlots().forEach(slot => { pbTargetingKeys.forEach(function(key) { // reset only registered adunits - adUnitCodes.find(function(unit) { + adUnits.forEach(function(unit) { if (unit.code === slot.getAdUnitPath() || unit.code === slot.getSlotElementId()) { slot.setTargeting(key, null); @@ -25,7 +26,7 @@ targeting.resetPresetTargeting = function(adUnitCode) { }; targeting.getAllTargeting = function(adUnitCode) { - const adUnitCodes = adUnitCode && adUnitCode.length ? [adUnitCode] : $$PREBID_GLOBAL$$._adUnitCodes; + const adUnitCodes = getAdUnitCodes(adUnitCode); // Get targeting for the winning bid. Add targeting for any bids that have // `alwaysUseBid=true`. If sending all bids is enabled, add targeting for losing bids. @@ -64,9 +65,28 @@ targeting.setTargeting = function(targetingConfig) { }); }; +/** + * normlizes input to a `adUnit.code` array + * @param {(string|string[])} adUnitCode [description] + * @return {string[]} AdUnit code array + */ +function getAdUnitCodes(adUnitCode) { + if (typeof adUnitCode === 'string') { + return [adUnitCode]; + } + else if (utils.isArray(adUnitCode)) { + return adUnitCode; + } + return $$PREBID_GLOBAL$$._adUnitCodes || []; +} + +/** + * Returns top bids for a given adUnit or set of adUnits. + * @param {(string|string[])} adUnitCode adUnitCode or array of adUnitCodes + * @return {[type]} [description] + */ targeting.getWinningBids = function(adUnitCode) { - // use the given adUnitCode as a filter if present or all adUnitCodes if not - const adUnitCodes = adUnitCode ? [adUnitCode] : $$PREBID_GLOBAL$$._adUnitCodes; + const adUnitCodes = getAdUnitCodes(adUnitCode); return $$PREBID_GLOBAL$$._bidsReceived .filter(bid => adUnitCodes.includes(bid.adUnitCode)) @@ -101,8 +121,9 @@ targeting.setTargetingForAst = function() { ); }; -function getWinningBidTargeting() { - let winners = targeting.getWinningBids(); + +function getWinningBidTargeting(adUnitCodes) { + let winners = targeting.getWinningBids(adUnitCodes); let standardKeys = getStandardKeys(); winners = winners.map(winner => { diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index bbe1175db18..2f0559e99e2 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -383,12 +383,22 @@ describe('Unit: Prebid Module', function () { assert.deepEqual(slots[1].spySetTargeting.args, targeting, 'google tag targeting options not matching'); }); - it('should set targeting when passed an array of ad unit codes', function () { + it('should set targeting when passed a string ad unit code with enableSendAllBids', function () { var slots = createSlotArray(); window.googletag.pubads().setSlots(slots); + $$PREBID_GLOBAL$$.enableSendAllBids(); + + $$PREBID_GLOBAL$$.setTargetingForGPTAsync('/19968336/header-bid-tag-0'); + expect(slots[0].spySetTargeting.args).to.deep.contain.members([['hb_bidder', 'appnexus'], ['hb_adid_appnexus', '233bcbee889d46d'], ['hb_pb_appnexus', '10.00']]); + }); + + it('should set targeting when passed an array of ad unit codes with enableSendAllBids', function () { + var slots = createSlotArray(); + window.googletag.pubads().setSlots(slots); + $$PREBID_GLOBAL$$.enableSendAllBids(); - $$PREBID_GLOBAL$$.setTargetingForGPTAsync(config.adUnitElementIDs); - expect(slots[0].spySetTargeting.args).to.deep.contain.members([['hb_bidder', 'appnexus']]); + $$PREBID_GLOBAL$$.setTargetingForGPTAsync(['/19968336/header-bid-tag-0']); + expect(slots[0].spySetTargeting.args).to.deep.contain.members([['hb_bidder', 'appnexus'], ['hb_adid_appnexus', '233bcbee889d46d'], ['hb_pb_appnexus', '10.00']]); }); it('should set targeting from googletag data', function () { From ea7b5fa07cd7acc9d580133866ce102781617558 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Thu, 25 May 2017 20:17:45 +0100 Subject: [PATCH 03/95] Audience Network: separate size from format (#1218) --- src/adapters/audienceNetwork.js | 83 ++++++------- test/spec/adapters/audienceNetwork_spec.js | 138 +++++++++++++++++---- 2 files changed, 149 insertions(+), 72 deletions(-) diff --git a/src/adapters/audienceNetwork.js b/src/adapters/audienceNetwork.js index 10993924f17..867f3c6f89a 100644 --- a/src/adapters/audienceNetwork.js +++ b/src/adapters/audienceNetwork.js @@ -22,22 +22,10 @@ const validateBidRequest = bid => bid.params.placementId.length > 0 && Array.isArray(bid.sizes) && bid.sizes.length > 0; -/** - * Return a copy of a bid with slot sizes flattened and filtered - * @param {Object} bid - * @returns {Object} copy of bid - */ -const flattenBidRequestSizes = bid => { - const sizes = Array.isArray(bid.sizes) && bid.sizes - .map(flattenSize) - .filter(isValidSize); - return Object.assign({}, bid, { sizes }); -}; - /** * Flattens a 2-element [W, H] array as a 'WxH' string, * otherwise passes value through. - * @params {Array|String} size + * @param {Array|String} size * @returns {String} */ const flattenSize = size => @@ -46,9 +34,9 @@ const flattenSize = size => /** * Is this a valid slot size? * @param {String} size - * @returns {Boolean} + * @returns {Boolean} */ -const isValidSize = size => ['native', 'fullwidth', '300x250', '320x50'].includes(size); +const isValidSize = size => ['300x250', '320x50'].includes(size); /** * Does the search part of the URL contain "anhb_testmode" @@ -74,28 +62,21 @@ const parseJson = jsonAsString => { return data; }; -/** - * Is this a native advert size? - * @param {String} size - * @returns {Boolean} - */ -const isNative = (size) => ['native', 'fullwidth'].includes(size); - /** * Generate ad HTML for injection into an iframe * @param {String} placementId - * @param {String} size + * @param {String} format * @param {String} bidId * @returns {String} HTML */ -const createAdHtml = (placementId, size, bidId) => { - const nativeStyle = isNative(size) ? '' : ''; - const nativeContainer = isNative(size) ? '
' : ''; +const createAdHtml = (placementId, format, bidId) => { + const nativeStyle = format === 'native' ? '' : ''; + const nativeContainer = format === 'native' ? '
' : ''; return `${nativeStyle}
- - ${nativeContainer}
`; + +${nativeContainer}`; }; /** @@ -106,19 +87,18 @@ const createAdHtml = (placementId, size, bidId) => { * @param {Number} cpmCents * @returns {Object} Bid */ -const createSuccessBidResponse = (placementId, size, bidId, cpmCents) => { +const createSuccessBidResponse = (placementId, size, format, bidId, cpmCents) => { const bid = createBid(STATUS.GOOD, { bidId }); // Prebid attributes bid.bidderCode = getBidderCode(); bid.cpm = cpmCents / 100; - bid.ad = createAdHtml(placementId, size, bidId); - if (!isNative(size)) { - [bid.width, bid.height] = size.split('x').map(Number); - } + bid.ad = createAdHtml(placementId, format, bidId); + [bid.width, bid.height] = size.split('x').map(Number); + // Audience Network attributes bid.hb_bidder = 'fan'; bid.fb_bidid = bidId; - bid.fb_format = size; + bid.fb_format = format; bid.fb_placementid = placementId; return bid; }; @@ -140,23 +120,30 @@ const createFailureBidResponse = () => { * @param {String} params.bids[].placementCode - Prebid placement identifier * @param {Object} params.bids[].params * @param {String} params.bids[].params.placementId - Audience Network placement identifier - * @param {Array} params.bids[].sizes - list of accepted advert sizes - * @param {Array|String} params.bids[].sizes[] - one of 'native', '300x250', '300x50', [300, 250], [300, 50] + * @param {String} params.bids[].params.format - Optional format, one of 'native' or 'fullwidth' if set + * @param {Array} params.bids[].sizes - list of desired advert sizes + * @param {Array} params.bids[].sizes[] - Size arrays [h,w]: should include one of [300, 250], [320, 50]: first matched size is used * @returns {void} */ const callBids = bidRequest => { - // Build lists of adUnitCodes, placementids and adformats + // Build lists of adUnitCodes, placementids, adformats and sizes const adUnitCodes = []; const placementids = []; const adformats = []; + const sizes = []; bidRequest.bids - .map(flattenBidRequestSizes) .filter(validateBidRequest) - .forEach(bid => bid.sizes.forEach(size => { - adUnitCodes.push(bid.placementCode); - placementids.push(bid.params.placementId); - adformats.push(size); - })); + .forEach(bid => bid.sizes + .map(flattenSize) + .filter(isValidSize) + .slice(0, 1) + .forEach(size => { + adUnitCodes.push(bid.placementCode); + placementids.push(bid.params.placementId); + adformats.push(bid.params.format || size); + sizes.push(size); + }) + ); if (placementids.length) { // Build URL @@ -190,7 +177,11 @@ const callBids = bidRequest => { // call addBidResponse .forEach((bid, i) => addBidResponse(adUnitCodes[i], createSuccessBidResponse( - bid.placement_id, adformats[i], bid.bid_id, bid.bid_price_cents + bid.placement_id, + sizes[i], + adformats[i], + bid.bid_id, + bid.bid_price_cents )) ); } diff --git a/test/spec/adapters/audienceNetwork_spec.js b/test/spec/adapters/audienceNetwork_spec.js index 33b44e31171..fa8d2b31fb2 100644 --- a/test/spec/adapters/audienceNetwork_spec.js +++ b/test/spec/adapters/audienceNetwork_spec.js @@ -96,14 +96,68 @@ describe('AudienceNetwork adapter', () => { expect(logError.calledOnce).to.equal(true); }); - it('valid parameters', () => { + it('filter valid sizes', () => { // Valid parameters const params = { bidderCode, bids: [{ bidder: bidderCode, params: { placementId }, - sizes: [[320, 50], [300, 250], '300x250', 'fullwidth', '320x50', 'native'] + sizes: [[1, 1], [300, 250]] + }] + }; + // Request bids + AudienceNetwork().callBids(params); + // Verify attempt to fetch response + expect(requests).to.have.lengthOf(1); + expect(requests[0].method).to.equal('GET'); + expect(requests[0].url) + .to.contain('https://an.facebook.com/v2/placementbid.json?') + .and.to.contain('placementids[]=test-placement-id') + .and.to.contain('adformats[]=300x250'); + // Verify no attempt to log error + expect(logError.called).to.equal(false); + }); + + it('valid parameters', () => { + const params = { + bidderCode, + bids: [{ + bidder: bidderCode, + params: { placementId }, + sizes: [[300, 250], [320, 50]] + }, + { + bidder: bidderCode, + params: { placementId }, + sizes: [[320, 50], [300, 250]] + }] + }; + // Request bids + AudienceNetwork().callBids(params); + // Verify attempt to fetch response + expect(requests).to.have.lengthOf(1); + expect(requests[0].method).to.equal('GET'); + expect(requests[0].url) + .to.contain('https://an.facebook.com/v2/placementbid.json?') + .and.to.contain('placementids[]=test-placement-id&placementids[]=test-placement-id') + .and.to.contain('adformats[]=320x50') + .and.to.contain('adformats[]=300x250'); + // Verify no attempt to log error + expect(logError.called).to.equal(false); + }); + + it('fullwidth', () => { + // Valid parameters + const params = { + bidderCode, + bids: [{ + bidder: bidderCode, + params: { + placementId, + format: 'fullwidth' + }, + sizes: [[300, 250]] }] }; // Request bids @@ -111,12 +165,36 @@ describe('AudienceNetwork adapter', () => { // Verify attempt to fetch response expect(requests).to.have.lengthOf(1); expect(requests[0].method).to.equal('GET'); - expectToContain(requests[0].url, 'https://an.facebook.com/v2/placementbid.json?'); - expectToContain(requests[0].url, 'placementids[]=test-placement-id', 6); - expectToContain(requests[0].url, 'adformats[]=320x50', 2); - expectToContain(requests[0].url, 'adformats[]=300x250', 2); - expectToContain(requests[0].url, 'adformats[]=fullwidth'); - expectToContain(requests[0].url, 'adformats[]=native'); + expect(requests[0].url) + .to.contain('https://an.facebook.com/v2/placementbid.json?') + .and.to.contain('placementids[]=test-placement-id') + .and.to.contain('adformats[]=fullwidth'); + // Verify no attempt to log error + expect(logError.called).to.equal(false); + }); + + it('native', () => { + // Valid parameters + const params = { + bidderCode, + bids: [{ + bidder: bidderCode, + params: { + placementId, + format: 'native' + }, + sizes: [[300, 250]] + }] + }; + // Request bids + AudienceNetwork().callBids(params); + // Verify attempt to fetch response + expect(requests).to.have.lengthOf(1); + expect(requests[0].method).to.equal('GET'); + expect(requests[0].url) + .to.contain('https://an.facebook.com/v2/placementbid.json?') + .and.to.contain('placementids[]=test-placement-id') + .and.to.contain('adformats[]=native'); // Verify no attempt to log error expect(logError.called).to.equal(false); }); @@ -151,7 +229,7 @@ describe('AudienceNetwork adapter', () => { bids: [{ bidder: bidderCode, params: { placementId }, - sizes: ['native'] + sizes: [[300, 250]] }] }); server.respond(); @@ -185,8 +263,11 @@ describe('AudienceNetwork adapter', () => { bids: [{ bidder: bidderCode, placementCode, - params: { placementId }, - sizes: ['native'] + params: { + placementId, + format: 'native' + }, + sizes: [[300, 250]] }] }); server.respond(); @@ -199,11 +280,12 @@ describe('AudienceNetwork adapter', () => { expect(bidResponse.getStatusCode()).to.equal(STATUS.GOOD); expect(bidResponse.cpm).to.equal(1.23); expect(bidResponse.bidderCode).to.equal(bidderCode); - expect(bidResponse.width).to.equal(0); - expect(bidResponse.height).to.equal(0); - expect(bidResponse.ad).to.contain(`placementid:'${placementId}',format:'native',bidid:'test-bid-id'`, 'ad missing parameters'); - expect(bidResponse.ad).to.contain('getElementsByTagName("style")', 'ad missing native styles'); - expect(bidResponse.ad).to.contain('
', 'ad missing native container'); + expect(bidResponse.width).to.equal(300); + expect(bidResponse.height).to.equal(250); + expect(bidResponse.ad) + .to.contain(`placementid:'${placementId}',format:'native',bidid:'test-bid-id'`, 'ad missing parameters') + .and.to.contain('getElementsByTagName("style")', 'ad missing native styles') + .and.to.contain('
', 'ad missing native container'); // Verify Audience Network attributes in bid response expect(bidResponse.hb_bidder).to.equal('fan'); expect(bidResponse.fb_bidid).to.equal('test-bid-id'); @@ -234,7 +316,7 @@ describe('AudienceNetwork adapter', () => { bidder: bidderCode, placementCode, params: { placementId }, - sizes: ['300x250'] + sizes: [[300, 250]] }] }); server.respond(); @@ -249,9 +331,10 @@ describe('AudienceNetwork adapter', () => { expect(bidResponse.bidderCode).to.equal(bidderCode); expect(bidResponse.width).to.equal(300); expect(bidResponse.height).to.equal(250); - expect(bidResponse.ad).to.contain(`placementid:'${placementId}',format:'300x250',bidid:'test-bid-id'`, 'ad missing parameters'); - expect(bidResponse.ad).not.to.contain('getElementsByTagName("style")', 'ad should not contain native styles'); - expect(bidResponse.ad).not.to.contain('
', 'ad should not contain native container'); + expect(bidResponse.ad) + .to.contain(`placementid:'${placementId}',format:'300x250',bidid:'test-bid-id'`, 'ad missing parameters') + .and.not.to.contain('getElementsByTagName("style")', 'ad should not contain native styles') + .and.not.to.contain('
', 'ad should not contain native container'); // Verify no attempt to log error expect(logError.called).to.equal(false, 'logError called'); }); @@ -282,7 +365,7 @@ describe('AudienceNetwork adapter', () => { bidder: bidderCode, placementCode, params: { placementId }, - sizes: ['300x250'] + sizes: [[300, 250]] }] }); server.respond(); @@ -332,13 +415,16 @@ describe('AudienceNetwork adapter', () => { bids: [{ bidder: bidderCode, placementCode: placementCodeNative, - params: { placementId: placementIdNative }, - sizes: ['native'] + params: { + placementId: placementIdNative, + format: 'native' + }, + sizes: [[300, 250]] }, { bidder: bidderCode, placementCode: placementCodeIab, params: { placementId: placementIdIab }, - sizes: ['300x250'] + sizes: [[300, 250]] }] }); server.respond(); @@ -351,8 +437,8 @@ describe('AudienceNetwork adapter', () => { expect(addBidResponseNativeCall[1].getStatusCode()).to.equal(STATUS.GOOD); expect(addBidResponseNativeCall[1].cpm).to.equal(1.23); expect(addBidResponseNativeCall[1].bidderCode).to.equal(bidderCode); - expect(addBidResponseNativeCall[1].width).to.equal(0); - expect(addBidResponseNativeCall[1].height).to.equal(0); + expect(addBidResponseNativeCall[1].width).to.equal(300); + expect(addBidResponseNativeCall[1].height).to.equal(250); expect(addBidResponseNativeCall[1].ad).to.contain(`placementid:'${placementIdNative}',format:'native',bidid:'test-bid-id-native'`, 'ad missing parameters'); // Verify IAB const addBidResponseIabCall = addBidResponse.args[1]; From fb14458e631c6f63424d139f0d9bbbd6db1d1f34 Mon Sep 17 00:00:00 2001 From: protonate Date: Thu, 25 May 2017 15:13:53 -0700 Subject: [PATCH 04/95] tests: drop ie9 browserstack test --- browsers.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/browsers.json b/browsers.json index 85bbc6b10b0..4c753fe7072 100644 --- a/browsers.json +++ b/browsers.json @@ -95,14 +95,6 @@ "device": null, "os": "Windows" }, - "bs_ie_9_windows_7": { - "base": "BrowserStack", - "os_version": "7", - "browser": "ie", - "browser_version": "9.0", - "device": null, - "os": "Windows" - }, "bs_firefox_46_windows_7": { "base": "BrowserStack", "os_version": "7", From a2fb6c845ee21b107c1ebd78cd3970e95e1a9eb4 Mon Sep 17 00:00:00 2001 From: protonate Date: Thu, 25 May 2017 15:33:29 -0700 Subject: [PATCH 05/95] Prebid 0.24.1 Release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5c6a9072239..377c30591a8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "0.25.0-pre", + "version": "0.24.1", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 5170880fa7e3313738d7b11e0da1dd4eeb961dbc Mon Sep 17 00:00:00 2001 From: protonate Date: Thu, 25 May 2017 15:52:15 -0700 Subject: [PATCH 06/95] pre-release version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 377c30591a8..5c6a9072239 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "0.24.1", + "version": "0.25.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 9b6638013df70499e0abe68f050824b33a23505a Mon Sep 17 00:00:00 2001 From: Benjamin Clot Date: Fri, 26 May 2017 19:42:05 +0200 Subject: [PATCH 07/95] Missing 250x250 ad size (#1225) --- src/adapters/rubicon.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/adapters/rubicon.js b/src/adapters/rubicon.js index 0b30e7ce771..9bad92bfe4a 100644 --- a/src/adapters/rubicon.js +++ b/src/adapters/rubicon.js @@ -28,6 +28,7 @@ var sizeMap = { 8: '120x600', 9: '160x600', 10: '300x600', + 14: '250x250', 15: '300x250', 16: '336x280', 19: '300x100', From de09a979b2a2ecadaca727412359b2ddb5e55713 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Wed, 31 May 2017 18:33:06 -0400 Subject: [PATCH 08/95] Adding deal id to bid response (#1252) * Adding deal id to bid response * Added unit test for deal id --- src/adapters/prebidServer.js | 3 +++ test/spec/adapters/prebidServer_spec.js | 13 ++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/adapters/prebidServer.js b/src/adapters/prebidServer.js index dc83a04019b..e229da9b33f 100644 --- a/src/adapters/prebidServer.js +++ b/src/adapters/prebidServer.js @@ -154,6 +154,9 @@ function PrebidServer() { bidObject.ad = bidObj.adm; bidObject.width = bidObj.width; bidObject.height = bidObj.height; + if (bidObj.deal_id) { + bidObject.dealId = bidObj.deal_id; + } bidmanager.addBidResponse(bidObj.code, bidObject); }); diff --git a/test/spec/adapters/prebidServer_spec.js b/test/spec/adapters/prebidServer_spec.js index 0d047133c97..abc3525a8f4 100644 --- a/test/spec/adapters/prebidServer_spec.js +++ b/test/spec/adapters/prebidServer_spec.js @@ -66,7 +66,8 @@ const RESPONSE = { 'price': 0.5, 'adm': '', 'width': 300, - 'height': 250 + 'height': 250, + 'deal_id': 'test-dealid' } ] }; @@ -218,5 +219,15 @@ describe('S2S Adapter', () => { const response = bidmanager.addBidResponse.firstCall.args[1]; expect(response).to.have.property('statusMessage', 'Bid returned empty or error response'); }); + + it('should have dealId in bidObject', () => { + server.respondWith(JSON.stringify(RESPONSE)); + + adapter.setConfig(CONFIG); + adapter.callBids(REQUEST); + server.respond(); + const response = bidmanager.addBidResponse.firstCall.args[1]; + expect(response).to.have.property('dealId', 'test-dealid'); + }); }); }); From d4748d098bbd2a9639d7a829e75c84aaa32b508c Mon Sep 17 00:00:00 2001 From: Galphimbl Date: Mon, 5 Jun 2017 18:05:00 +0300 Subject: [PATCH 09/95] admixer adapter: add "video" mediaType support (#1200) * Atomx adapter: add "video" mediaType support * admixer adapter: fix lint errors --- adapters.json | 5 ++ src/adapters/admixer.js | 20 ++++- test/spec/adapters/admixer_spec.js | 125 ++++++++++++++++++++++++++--- 3 files changed, 139 insertions(+), 11 deletions(-) diff --git a/adapters.json b/adapters.json index b9ec1b70cd2..ae186789a57 100644 --- a/adapters.json +++ b/adapters.json @@ -143,5 +143,10 @@ "rhythmone": { "supportedMediaTypes": ["video"] } + }, + { + "admixer": { + "supportedMediaTypes": ["video"] + } } ] diff --git a/src/adapters/admixer.js b/src/adapters/admixer.js index 944aed276ce..24cf81bf9e9 100644 --- a/src/adapters/admixer.js +++ b/src/adapters/admixer.js @@ -10,6 +10,7 @@ var utils = require('../utils.js'); */ var AdmixerAdapter = function AdmixerAdapter() { var invUrl = '//inv-nets.admixer.net/prebid.aspx'; + var invVastUrl = '//inv-nets.admixer.net/videoprebid.aspx'; function _callBids(data) { var bids = data.bids || []; @@ -21,7 +22,16 @@ var AdmixerAdapter = function AdmixerAdapter() { 'callback_uid': bid.placementCode }; if (params.zone) { - _requestBid(invUrl, params); + if (bid.mediaType === 'video') { + var videoParams = {}; + if (typeof bid.video === 'object') { + Object.assign(videoParams, bid.video); + } + Object.assign(videoParams, params); + _requestBid(invVastUrl, params); + } else { + _requestBid(invUrl, params); + } } else { var bidObject = bidfactory.createBid(2); bidObject.bidderCode = 'admixer'; @@ -48,7 +58,13 @@ var AdmixerAdapter = function AdmixerAdapter() { bidObject = bidfactory.createBid(1); bidObject.bidderCode = 'admixer'; bidObject.cpm = bid.cpm; - bidObject.ad = bid.ad; + if (bid.vastUrl) { + bidObject.mediaType = 'video'; + bidObject.vastUrl = bid.vastUrl; + bidObject.descriptionUrl = bid.vastUrl; + } else { + bidObject.ad = bid.ad; + } bidObject.width = bid.width; bidObject.height = bid.height; } else { diff --git a/test/spec/adapters/admixer_spec.js b/test/spec/adapters/admixer_spec.js index 79174390b62..45f18ce7abc 100644 --- a/test/spec/adapters/admixer_spec.js +++ b/test/spec/adapters/admixer_spec.js @@ -39,6 +39,54 @@ describe('Admixer adapter', function () { } ] }; + var validVideoData_1 = { + bids: [ + { + mediaType: 'video', + bidder: 'admixer', + bidId: 'bid_id', + params: {zone: 'zone_id'}, + placementCode: 'ad-unit-1', + sizes: [[300, 250], [300, 600]] + } + ] + }; + var validVideoData_2 = { + bids: [ + { + mediaType: 'video', + bidder: 'admixer', + bidId: 'bid_id', + params: {zone: 'zone_id'}, + placementCode: 'ad-unit-1', + sizes: [300, 250] + } + ] + }; + var validVideoData_3 = { + bids: [ + { + mediaType: 'video', + bidder: 'admixer', + bidId: 'bid_id', + params: {zone: 'zone_id', video: {skippable: true}}, + placementCode: 'ad-unit-1', + sizes: [300, 250] + } + ] + }; + var invalidVideoData = { + bids: [ + { + mediaType: 'video', + bidder: 'admixer', + bidId: 'bid_id', + params: {}, + placementCode: 'ad-unit-1', + sizes: [[300, 250], [300, 600]] + } + ] + }; var responseWithAd = JSON.stringify({ 'result': { 'cpm': 2.2, @@ -57,13 +105,38 @@ describe('Admixer adapter', function () { }, 'callback_uid': 'ad-unit-1' }); + var responseWithVideoAd = JSON.stringify({ + 'result': { + 'cpm': 2.2, + 'vastUrl': 'http://inv-nets.admixer.net/vastxml.aspx?req=9d651544-daf4-48ed-ae0c-38a60a4e1920&vk=e914f026449e49aeb6eea07b9642a2ce', + 'width': 300, + 'height': 250 + }, + 'callback_uid': 'ad-unit-1' + }); + var responseWithoutVideoAd = JSON.stringify({ + 'result': { + 'cpm': 0, + 'vastUrl': '', + 'width': 0, + 'height': 0 + }, + 'callback_uid': 'ad-unit-1' + }); var responseEmpty = ''; var invUrl = '//inv-nets.admixer.net/prebid.aspx'; + var invVastUrl = '//inv-nets.admixer.net/videoprebid.aspx'; var validJsonParams = { zone: 'zone_id', callback_uid: 'ad-unit-1', sizes: '300x250-300x600' }; + var validJsonVideoParams = { + zone: 'zone_id', + callback_uid: 'ad-unit-1', + sizes: '300x250-300x600', + skippable: true + }; describe('bid request with valid data', function () { var stubAjax; beforeEach(function () { @@ -73,19 +146,32 @@ describe('Admixer adapter', function () { afterEach(function () { stubAjax.restore(); }); - it('bid request should be called. sizes style -> [[],[]]', function () { + it('display: bid request should be called. sizes style -> [[],[]]', function () { Adapter.callBids(validData_1); sinon.assert.calledOnce(stubAjax); }); - it('bid request should be called. sizes style -> []', function () { + it('video: bid request should be called. sizes style -> [[],[]]', function () { + Adapter.callBids(validVideoData_1); + sinon.assert.calledOnce(stubAjax); + }); + it('display: bid request should be called. sizes style -> []', function () { Adapter.callBids(validData_2); sinon.assert.calledOnce(stubAjax); }); - it('ajax params should be matched', function () { + it('video: bid request should be called. sizes style -> []', function () { + Adapter.callBids(validVideoData_2); + sinon.assert.calledOnce(stubAjax); + }); + it('display: ajax params should be matched', function () { Adapter.callBids(validData_1); sinon.assert.calledWith(stubAjax, sinon.match(invUrl, function () { }, validJsonParams, {method: 'GET'})); }); + it('video: ajax params should be matched', function () { + Adapter.callBids(validVideoData_3); + sinon.assert.calledWith(stubAjax, sinon.match(invVastUrl, function () { + }, validJsonVideoParams, {method: 'GET'})); + }); }); describe('bid request with invalid data', function () { var addBidResponse, stubAjax; @@ -98,15 +184,24 @@ describe('Admixer adapter', function () { addBidResponse.restore(); stubAjax.restore(); }); - it('ajax shouldn\'t be called', function () { + it('display: ajax shouldn\'t be called', function () { Adapter.callBids(invalidData); sinon.assert.notCalled(stubAjax); }); - it('bidmanager.addBidResponse status code must to be equal "' + CONSTANTS.STATUS.NO_BID + '"', function () { + it('video: ajax shouldn\'t be called', function () { + Adapter.callBids(invalidVideoData); + sinon.assert.notCalled(stubAjax); + }); + it('display: bidmanager.addBidResponse status code must to be equal "' + CONSTANTS.STATUS.NO_BID + '"', function () { Adapter.callBids(invalidData); expect(addBidResponse.firstCall.args[1].getStatusCode()).to.equal(CONSTANTS.STATUS.NO_BID); expect(addBidResponse.firstCall.args[1].bidderCode).to.equal('admixer'); }); + it('video: bidmanager.addBidResponse status code must to be equal "' + CONSTANTS.STATUS.NO_BID + '"', function () { + Adapter.callBids(invalidVideoData); + expect(addBidResponse.firstCall.args[1].getStatusCode()).to.equal(CONSTANTS.STATUS.NO_BID); + expect(addBidResponse.firstCall.args[1].bidderCode).to.equal('admixer'); + }); }); describe('bid response', function () { var addBidResponse; @@ -116,23 +211,35 @@ describe('Admixer adapter', function () { afterEach(function () { addBidResponse.restore(); }); - it('response with ad. bidmanager.addBidResponse status code must to be equal "' + CONSTANTS.STATUS.GOOD + '"', function () { + it('display: response with ad. bidmanager.addBidResponse status code must to be equal "' + CONSTANTS.STATUS.GOOD + '"', function () { Adapter.responseCallback(responseWithAd); var arg = addBidResponse.firstCall.args[1]; expect(arg.getStatusCode()).to.equal(CONSTANTS.STATUS.GOOD); expect(arg.bidderCode).to.equal('admixer'); }); - it('response without ad. bidmanager.addBidResponse status code must to be equal "' + CONSTANTS.STATUS.NO_BID, function () { + it('video: response with ad. bidmanager.addBidResponse status code must to be equal "' + CONSTANTS.STATUS.GOOD + '"', function () { + Adapter.responseCallback(responseWithVideoAd); + var arg = addBidResponse.firstCall.args[1]; + expect(arg.getStatusCode()).to.equal(CONSTANTS.STATUS.GOOD); + expect(arg.bidderCode).to.equal('admixer'); + }); + it('display: response without ad. bidmanager.addBidResponse status code must to be equal "' + CONSTANTS.STATUS.NO_BID, function () { Adapter.responseCallback(responseWithoutAd); var arg = addBidResponse.firstCall.args[1]; expect(arg.getStatusCode()).to.equal(CONSTANTS.STATUS.NO_BID); expect(arg.bidderCode).to.equal('admixer'); }); - it('response empty. bidmanager.addBidResponse status code must to be equal "' + CONSTANTS.STATUS.NO_BID, function () { + it('video: response without ad. bidmanager.addBidResponse status code must to be equal "' + CONSTANTS.STATUS.NO_BID, function () { + Adapter.responseCallback(responseWithoutVideoAd); + var arg = addBidResponse.firstCall.args[1]; + expect(arg.getStatusCode()).to.equal(CONSTANTS.STATUS.NO_BID); + expect(arg.bidderCode).to.equal('admixer'); + }); + it('display/video: response empty. bidmanager.addBidResponse status code must to be equal "' + CONSTANTS.STATUS.NO_BID, function () { Adapter.responseCallback(responseEmpty); var arg = addBidResponse.firstCall.args[1]; expect(arg.getStatusCode()).to.equal(CONSTANTS.STATUS.NO_BID); expect(arg.bidderCode).to.equal('admixer'); - }) + }); }); }); From 6b36d6444634be8929a626f12bdf123cf7cbada6 Mon Sep 17 00:00:00 2001 From: jbAdyoulike Date: Mon, 5 Jun 2017 17:11:31 +0200 Subject: [PATCH 10/95] create adapter adyoulike (#1155) * create adapter adyoulike * move bidRequests in callBids scope * update adyoulike.js and adyoulike_spec.js syntax * refactor getReferrerUrl and getCanonicalUrl --- adapters.json | 1 + src/adapters/adyoulike.js | 192 +++++++++++++++++ test/spec/adapters/adyoulike_spec.js | 308 +++++++++++++++++++++++++++ 3 files changed, 501 insertions(+) create mode 100644 src/adapters/adyoulike.js create mode 100644 test/spec/adapters/adyoulike_spec.js diff --git a/adapters.json b/adapters.json index ae186789a57..e2c09b9095e 100644 --- a/adapters.json +++ b/adapters.json @@ -7,6 +7,7 @@ "adform", "adkernel", "admedia", + "adyoulike", "bidfluence", "vertamedia", "aol", diff --git a/src/adapters/adyoulike.js b/src/adapters/adyoulike.js new file mode 100644 index 00000000000..3968de6ce8f --- /dev/null +++ b/src/adapters/adyoulike.js @@ -0,0 +1,192 @@ +import Adapter from 'src/adapters/adapter'; +import bidfactory from 'src/bidfactory'; +import bidmanager from 'src/bidmanager'; +import * as utils from 'src/utils'; +import { format } from 'src/url'; +import { ajax } from 'src/ajax'; +import { STATUS } from 'src/constants'; + +var AdyoulikeAdapter = function AdyoulikeAdapter() { + const _VERSION = '0.1'; + + const baseAdapter = Adapter.createNew('adyoulike'); + + baseAdapter.callBids = function (bidRequest) { + const bidRequests = {}; + const bids = bidRequest.bids || []; + + const validBids = bids.filter(valid); + validBids.forEach(bid => { bidRequests[bid.params.placement] = bid; }); + + const placements = validBids.map(bid => bid.params.placement); + if (!utils.isEmpty(placements)) { + const body = createBody(placements); + const endpoint = createEndpoint(); + ajax(endpoint, + (response) => { + handleResponse(bidRequests, response); + }, body, { + contentType: 'text/json', + withCredentials: true + }); + } + }; + + /* Create endpoint url */ + function createEndpoint() { + return format({ + protocol: (document.location.protocol === 'https:') ? 'https' : 'http', + host: 'hb-api.omnitagjs.com', + pathname: '/hb-api/prebid', + search: createEndpointQS() + }); + } + + /* Create endpoint query string */ + function createEndpointQS() { + const qs = {}; + + const ref = getReferrerUrl(); + if (ref) { + qs.RefererUrl = encodeURIComponent(ref); + } + + const can = getCanonicalUrl(); + if (can) { + qs.CanonicalUrl = encodeURIComponent(can); + } + + return qs; + } + + /* Create request body */ + function createBody(placements) { + const body = { + Version: _VERSION, + Placements: placements, + }; + + if (performance && performance.navigation) { + body.PageRefreshed = performance.navigation.type === performance.navigation.TYPE_RELOAD; + } + + return JSON.stringify(body); + } + + /* Response handler */ + function handleResponse(bidRequests, response) { + let responses = []; + try { + responses = JSON.parse(response); + } catch (error) { utils.logError(error); } + + const bidResponses = {}; + responses.forEach(response => { + bidResponses[response.Placement] = response; + }); + + Object.keys(bidRequests).forEach(placement => { + addResponse(placement, bidRequests[placement], bidResponses[placement]); + }); + } + + /* Check that a bid has required parameters */ + function valid(bid) { + const sizes = getSize(bid.sizes); + if (!bid.params.placement || !sizes.width || !sizes.height) { + return false; + } + return true; + } + + /* Get current page referrer url */ + function getReferrerUrl() { + let referer = ''; + if (window.self !== window.top) { + try { + referer = window.top.document.referrer; + } catch (e) { } + } else { + referer = document.referrer; + } + return referer; + } + + /* Get current page canonical url */ + function getCanonicalUrl() { + let link; + if (window.self !== window.top) { + try { + link = window.top.document.head.querySelector('link[rel="canonical"][href]'); + } catch (e) { } + } else { + link = document.head.querySelector('link[rel="canonical"][href]'); + } + + if (link) { + return link.href; + } + return ''; + } + + /* Get parsed size from request size */ + function getSize(requestSizes) { + const parsed = {}, + size = utils.parseSizesInput(requestSizes)[0]; + + if (typeof size !== 'string') { + return parsed; + } + + const parsedSize = size.toUpperCase().split('X'); + const width = parseInt(parsedSize[0], 10); + if (width) { + parsed.width = width; + } + + const height = parseInt(parsedSize[1], 10); + if (height) { + parsed.height = height; + } + + return parsed; + } + + /* Create bid from response */ + function createBid(placementId, bidRequest, response) { + let bid; + if (!response || !response.Banner) { + bid = bidfactory.createBid(STATUS.NO_BID, bidRequest); + } else { + bid = bidfactory.createBid(STATUS.GOOD, bidRequest); + const size = getSize(bidRequest.sizes); + bid.width = size.width; + bid.height = size.height; + bid.cpm = response.Price; + bid.ad = response.Banner; + } + + bid.bidderCode = baseAdapter.getBidderCode(); + + return bid; + } + + /* Add response to bidmanager */ + function addResponse(placementId, bidRequest, response) { + const bid = createBid(placementId, bidRequest, response); + const placement = bidRequest.placementCode; + bidmanager.addBidResponse(placement, bid); + } + + return { + createNew: AdyoulikeAdapter.createNew, + callBids: baseAdapter.callBids, + setBidderCode: baseAdapter.setBidderCode, + }; +}; + +AdyoulikeAdapter.createNew = function () { + return new AdyoulikeAdapter(); +}; + +module.exports = AdyoulikeAdapter; diff --git a/test/spec/adapters/adyoulike_spec.js b/test/spec/adapters/adyoulike_spec.js new file mode 100644 index 00000000000..d702b0ec283 --- /dev/null +++ b/test/spec/adapters/adyoulike_spec.js @@ -0,0 +1,308 @@ +import { expect } from 'chai'; +import { parse } from '../../../src/url'; +import AdyoulikAdapter from '../../../src/adapters/adyoulike'; +import bidmanager from 'src/bidmanager'; +import { STATUS } from 'src/constants'; + +describe('Adyoulike Adapter', () => { + const endpoint = 'http://hb-api.omnitagjs.com/hb-api/prebid'; + const canonicalUrl = 'http://canonical.url/?t=%26'; + const bidderCode = 'adyoulike'; + const bidRequestWithEmptyPlacement = { + 'bidderCode': 'adyoulike', + 'bids': [ + { + 'bidId': 'bid_id_0', + 'bidder': 'adyoulike', + 'placementCode': 'adunit/hb-0', + 'params': {}, + 'sizes': '300x250' + } + ], + }; + const bidRequestWithEmptySizes = { + 'bidderCode': 'adyoulike', + 'bids': [ + { + 'bidId': 'bid_id_0', + 'bidder': 'adyoulike', + 'placementCode': 'adunit/hb-0', + 'params': { + 'placement': 'placement_0' + } + } + ], + }; + const bidRequestWithSinglePlacement = { + 'bidderCode': 'adyoulike', + 'bids': [ + { + 'bidId': 'bid_id_0', + 'bidder': 'adyoulike', + 'placementCode': 'adunit/hb-0', + 'params': { + 'placement': 'placement_0' + }, + 'sizes': '300x250' + } + ], + }; + const bidRequestMultiPlacements = { + 'bidderCode': 'adyoulike', + 'bids': [ + { + 'bidId': 'bid_id_0', + 'bidder': 'adyoulike', + 'placementCode': 'adunit/hb-0', + 'params': { + 'placement': 'placement_0' + }, + 'sizes': '300x250' + }, + { + 'bidId': 'bid_id_1', + 'bidder': 'adyoulike', + 'placementCode': 'adunit/hb-1', + 'params': { + 'placement': 'placement_1' + }, + 'sizes': [[300, 600]] + }, + { + 'bidId': 'bid_id_2', + 'bidder': 'adyoulike', + 'placementCode': 'adunit/hb-2', + 'params': {}, + 'sizes': '300x400' + }, + { + 'bidId': 'bid_id_3', + 'bidder': 'adyoulike', + 'placementCode': 'adunit/hb-3', + 'params': { + 'placement': 'placement_3' + } + } + ], + }; + + const responseWithEmptyPlacement = [ + { + 'Placement': 'placement_0' + } + ]; + const responseWithSinglePlacement = [ + { + 'Placement': 'placement_0', + 'Banner': 'placement_0', + 'Price': 0.5 + } + ]; + const responseWithMultiplePlacements = [ + { + 'Placement': 'placement_0', + 'Banner': 'placement_0', + 'Price': 0.5 + }, + { + 'Placement': 'placement_1', + 'Banner': 'placement_1', + 'Price': 0.6 + } + ]; + + let adapter; + + beforeEach(() => { + adapter = new AdyoulikAdapter(); + }); + + describe('adapter public API', () => { + const adapter = AdyoulikAdapter.createNew(); + it('createNew', () => { + expect(adapter.createNew).to.be.a('function'); + }); + + it('setBidderCode', () => { + expect(adapter.setBidderCode).to.be.a('function'); + }); + it('callBids', () => { + expect(adapter.setBidderCode).to.be.a('function'); + }); + }); + + describe('request function', () => { + let requests; + let xhr; + let addBidResponse; + let canonicalQuery; + + beforeEach(() => { + requests = []; + + xhr = sinon.useFakeXMLHttpRequest(); + xhr.onCreate = request => requests.push(request); + + addBidResponse = sinon.stub(bidmanager, 'addBidResponse'); + + let canonical = document.createElement('link'); + canonical.rel = 'canonical'; + canonical.href = canonicalUrl; + canonicalQuery = sinon.stub(window.top.document.head, 'querySelector'); + canonicalQuery.withArgs('link[rel="canonical"][href]').returns(canonical); + }); + + afterEach(() => { + xhr.restore(); + bidmanager.addBidResponse.restore(); + canonicalQuery.restore(); + }); + + it('requires placement request', () => { + adapter.callBids(bidRequestWithEmptyPlacement); + expect(requests).to.be.empty; + expect(addBidResponse.calledOnce).to.equal(false); + }); + + it('requires sizes in request', () => { + adapter.callBids(bidRequestWithEmptySizes); + expect(requests).to.be.empty; + expect(addBidResponse.calledOnce).to.equal(false); + }); + + it('sends bid request to endpoint with single placement', () => { + adapter.callBids(bidRequestWithSinglePlacement); + expect(requests[0].url).to.contain(endpoint); + expect(requests[0].method).to.equal('POST'); + + expect(requests[0].url).to.contains('CanonicalUrl=' + encodeURIComponent(canonicalUrl)); + + let body = JSON.parse(requests[0].requestBody); + expect(body.Version).to.equal('0.1'); + expect(body.Placements).deep.equal(['placement_0']); + expect(body.PageRefreshed).to.equal(false); + }); + + it('sends bid request to endpoint with single placement without canonical', () => { + canonicalQuery.restore(); + + adapter.callBids(bidRequestWithSinglePlacement); + expect(requests[0].url).to.contain(endpoint); + expect(requests[0].method).to.equal('POST'); + + expect(requests[0].url).to.not.contains('CanonicalUrl=' + encodeURIComponent(canonicalUrl)); + + let body = JSON.parse(requests[0].requestBody); + expect(body.Version).to.equal('0.1'); + expect(body.Placements).deep.equal(['placement_0']); + expect(body.PageRefreshed).to.equal(false); + }); + + it('sends bid request to endpoint with multiple placements', () => { + adapter.callBids(bidRequestMultiPlacements); + expect(requests[0].url).to.contain(endpoint); + expect(requests[0].method).to.equal('POST'); + + expect(requests[0].url).to.contains('CanonicalUrl=' + encodeURIComponent(canonicalUrl)); + + let body = JSON.parse(requests[0].requestBody); + expect(body.Version).to.equal('0.1'); + expect(body.Placements).deep.equal(['placement_0', 'placement_1']); + expect(body.PageRefreshed).to.equal(false); + }); + }); + + describe('response function', () => { + let server; + let addBidResponse; + + beforeEach(() => { + server = sinon.fakeServer.create(); + addBidResponse = sinon.stub(bidmanager, 'addBidResponse'); + }); + + afterEach(() => { + server.restore(); + bidmanager.addBidResponse.restore(); + }); + + it('invalid json', () => { + server.respondWith('{'); + adapter.callBids(bidRequestWithSinglePlacement); + server.respond(); + + expect(addBidResponse.calledOnce).to.equal(true); + expect(addBidResponse.args[0]).to.have.lengthOf(2); + expect(addBidResponse.args[0][1].getStatusCode()).to.equal(STATUS.NO_BID); + expect(addBidResponse.args[0][1].bidderCode).to.equal(bidderCode); + }); + + it('receive reponse with empty placement', () => { + server.respondWith(JSON.stringify(responseWithEmptyPlacement)); + adapter.callBids(bidRequestWithSinglePlacement); + server.respond(); + + expect(addBidResponse.calledOnce).to.equal(true); + expect(addBidResponse.args[0]).to.have.lengthOf(2); + expect(addBidResponse.args[0][1].getStatusCode()).to.equal(STATUS.NO_BID); + expect(addBidResponse.args[0][1].bidderCode).to.equal(bidderCode); + }); + + it('receive reponse with single placement', () => { + server.respondWith(JSON.stringify(responseWithSinglePlacement)); + adapter.callBids(bidRequestWithSinglePlacement); + server.respond(); + + expect(addBidResponse.calledOnce).to.equal(true); + expect(addBidResponse.args[0]).to.have.lengthOf(2); + expect(addBidResponse.args[0][1].getStatusCode()).to.equal(STATUS.GOOD); + expect(addBidResponse.args[0][1].cpm).to.equal(0.5); + expect(addBidResponse.args[0][1].ad).to.equal('placement_0'); + expect(addBidResponse.args[0][1].width).to.equal(300); + expect(addBidResponse.args[0][1].height).to.equal(250); + }); + + it('receive reponse with multiple placement', () => { + server.respondWith(JSON.stringify(responseWithMultiplePlacements)); + adapter.callBids(bidRequestMultiPlacements); + server.respond(); + + expect(addBidResponse.calledTwice).to.equal(true); + + expect(addBidResponse.args[0]).to.have.lengthOf(2); + expect(addBidResponse.args[0][1].getStatusCode()).to.equal(STATUS.GOOD); + expect(addBidResponse.args[0][1].bidderCode).to.equal(bidderCode); + expect(addBidResponse.args[0][1].cpm).to.equal(0.5); + expect(addBidResponse.args[0][1].ad).to.equal('placement_0'); + expect(addBidResponse.args[0][1].width).to.equal(300); + expect(addBidResponse.args[0][1].height).to.equal(250); + + expect(addBidResponse.args[1]).to.have.lengthOf(2); + expect(addBidResponse.args[1][1].getStatusCode()).to.equal(STATUS.GOOD); + expect(addBidResponse.args[1][1].bidderCode).to.equal(bidderCode); + expect(addBidResponse.args[1][1].cpm).to.equal(0.6); + expect(addBidResponse.args[1][1].ad).to.equal('placement_1'); + expect(addBidResponse.args[1][1].width).to.equal(300); + expect(addBidResponse.args[1][1].height).to.equal(600); + }); + + it('receive reponse with invalid placement number', () => { + server.respondWith(JSON.stringify(responseWithSinglePlacement)); + adapter.callBids(bidRequestMultiPlacements); + server.respond(); + + expect(addBidResponse.calledTwice).to.equal(true); + + expect(addBidResponse.args[0]).to.have.lengthOf(2); + expect(addBidResponse.args[0][1].getStatusCode()).to.equal(STATUS.GOOD); + expect(addBidResponse.args[0][1].bidderCode).to.equal(bidderCode); + expect(addBidResponse.args[0][1].cpm).to.equal(0.5); + expect(addBidResponse.args[0][1].ad).to.equal('placement_0'); + expect(addBidResponse.args[0][1].width).to.equal(300); + expect(addBidResponse.args[0][1].height).to.equal(250); + + expect(addBidResponse.args[1]).to.have.lengthOf(2); + expect(addBidResponse.args[1][1].getStatusCode()).to.equal(STATUS.NO_BID); + }); + }); +}); From cf76e857dbb71ad99a57a43d36a72b71d5ce6835 Mon Sep 17 00:00:00 2001 From: Tomas Roos Date: Mon, 5 Jun 2017 18:16:36 +0200 Subject: [PATCH 11/95] Fixes #998 Allow keyvalues, gender and age to be passed in PubMatic (#1213) * Fixes #998 Allow keyvalues, gender and age to be passed in PubMatic's adapter * Linting and make sure to define variables --- src/adapters/pubmatic.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/adapters/pubmatic.js b/src/adapters/pubmatic.js index 44fb9bf97fc..be1f027a943 100644 --- a/src/adapters/pubmatic.js +++ b/src/adapters/pubmatic.js @@ -11,6 +11,9 @@ var bidmanager = require('../bidmanager.js'); var PubmaticAdapter = function PubmaticAdapter() { var bids; var _pm_pub_id; + var _pm_pub_age; + var _pm_pub_gender; + var _pm_pub_kvs; var _pm_optimize_adslots = []; let iframe; @@ -21,6 +24,9 @@ var PubmaticAdapter = function PubmaticAdapter() { var bid = bids[i]; // bidmanager.pbCallbackMap['' + bid.params.adSlot] = bid; _pm_pub_id = _pm_pub_id || bid.params.publisherId; + _pm_pub_age = _pm_pub_age || (bid.params.age || ''); + _pm_pub_gender = _pm_pub_gender || (bid.params.gender || ''); + _pm_pub_kvs = _pm_pub_kvs || (bid.params.kvs || ''); _pm_optimize_adslots.push(bid.params.adSlot); } @@ -51,11 +57,18 @@ var PubmaticAdapter = function PubmaticAdapter() { content += '' + 'window.pm_pub_id = "%%PM_PUB_ID%%";' + 'window.pm_optimize_adslots = [%%PM_OPTIMIZE_ADSLOTS%%];' + + 'window.kaddctr = "%%PM_ADDCTR%%;"' + + 'window.kadgender = "%%PM_GENDER%%;"' + + 'window.kadage = "%%PM_AGE%%;"' + 'window.pm_async_callback_fn = "window.parent.$$PREBID_GLOBAL$$.handlePubmaticCallback";'; + content += ''; var map = {}; map.PM_PUB_ID = _pm_pub_id; + map.PM_ADDCTR = _pm_pub_kvs; + map.PM_GENDER = _pm_pub_gender; + map.PM_AGE = _pm_pub_age; map.PM_OPTIMIZE_ADSLOTS = _pm_optimize_adslots.map(function (adSlot) { return "'" + adSlot + "'"; }).join(','); From ece853a2ade22c04d0a96abe9c74ba4772477cd4 Mon Sep 17 00:00:00 2001 From: Kenneth Kharma Date: Mon, 5 Jun 2017 11:51:36 -0700 Subject: [PATCH 12/95] remove superfluous parameter from openx adapter (#1237) --- src/adapters/openx.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/adapters/openx.js b/src/adapters/openx.js index 009dde53707..6341b860134 100644 --- a/src/adapters/openx.js +++ b/src/adapters/openx.js @@ -218,7 +218,6 @@ const OpenxAdapter = function OpenxAdapter() { ifr: isIfr, tz: startTime.getTimezoneOffset(), tws: getViewportDimensions(isIfr), - ee: 'api_sync_write', ef: 'bt%2Cdb', be: 1, bc: BIDDER_CONFIG From fd7ae19b65da98599590914ee310157c66dd6780 Mon Sep 17 00:00:00 2001 From: Jordan Manwaring Date: Wed, 7 Jun 2017 12:39:13 -0400 Subject: [PATCH 13/95] Fixed syntax error in iframe content template (#1272) --- src/adapters/pubmatic.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/adapters/pubmatic.js b/src/adapters/pubmatic.js index be1f027a943..5caa286eed9 100644 --- a/src/adapters/pubmatic.js +++ b/src/adapters/pubmatic.js @@ -57,9 +57,9 @@ var PubmaticAdapter = function PubmaticAdapter() { content += '' + 'window.pm_pub_id = "%%PM_PUB_ID%%";' + 'window.pm_optimize_adslots = [%%PM_OPTIMIZE_ADSLOTS%%];' + - 'window.kaddctr = "%%PM_ADDCTR%%;"' + - 'window.kadgender = "%%PM_GENDER%%;"' + - 'window.kadage = "%%PM_AGE%%;"' + + 'window.kaddctr = "%%PM_ADDCTR%%";' + + 'window.kadgender = "%%PM_GENDER%%";' + + 'window.kadage = "%%PM_AGE%%";' + 'window.pm_async_callback_fn = "window.parent.$$PREBID_GLOBAL$$.handlePubmaticCallback";'; content += ''; From 53abddd319efe7323ffe258dbdbd30e1f4e30a94 Mon Sep 17 00:00:00 2001 From: dbemiller Date: Wed, 7 Jun 2017 14:00:56 -0400 Subject: [PATCH 14/95] Fixed a bug in the gulpfile which caused bad /dev/ rebuilds when watching files with gulp serve (#1276) --- gulpfile.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 8450283c704..46334996870 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -46,7 +46,7 @@ gulp.task('clean', function () { .pipe(clean()); }); -gulp.task('devpack', function () { +gulp.task('devpack', ['clean'], function () { webpackConfig.devtool = 'source-map'; const analyticsSources = helpers.getAnalyticsSources(analyticsDirectory); return gulp.src([].concat(analyticsSources, 'src/prebid.js')) @@ -181,12 +181,11 @@ gulp.task('watch', function () { 'src/**/*.js', 'test/spec/**/*.js', '!test/spec/loaders/**/*.js' - ], ['lint', 'webpack', 'devpack', 'test']); + ], ['clean', 'lint', 'webpack', 'devpack', 'test']); gulp.watch([ 'loaders/**/*.js', 'test/spec/loaders/**/*.js' ], ['lint', 'mocha']); - gulp.watch(['integrationExamples/gpt/*.html'], ['test']); connect.server({ https: argv.https, port: port, From 78c1dc5b2fdb3f719f6ee46822f948dd24927a1d Mon Sep 17 00:00:00 2001 From: Raffael Vogler Date: Wed, 7 Jun 2017 21:24:42 +0200 Subject: [PATCH 15/95] the prebid global variable does not have to be 'pbjs'. (#1275) --- src/adapters/smartadserver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/adapters/smartadserver.js b/src/adapters/smartadserver.js index ae5ec38844c..21676beebc1 100644 --- a/src/adapters/smartadserver.js +++ b/src/adapters/smartadserver.js @@ -37,7 +37,7 @@ var SmartAdServer = function SmartAdServer() { var adCall = url.parse(bid.params.domain); adCall.pathname = '/prebid'; adCall.search = { - 'pbjscbk': 'pbjs.' + generateCallback(bid), + 'pbjscbk': '$$PREBID_GLOBAL$$.' + generateCallback(bid), 'siteid': bid.params.siteId, 'pgid': bid.params.pageId, 'fmtid': bid.params.formatId, From 3d174d12d5241aabb5af8e4de245ff3f8053ba27 Mon Sep 17 00:00:00 2001 From: trex-conversant Date: Wed, 7 Jun 2017 15:08:28 -0700 Subject: [PATCH 16/95] Adding Video Support for Conversant Adapter (#1153) * Added support for video * Added tag_id parameter * Added position parameter * Changed API endpoint * Added support for multiple sizes per ad unit --- adapters.json | 5 + src/adapters/conversant.js | 125 ++++++++++++++++------- test/spec/adapters/conversant_spec.js | 142 ++++++++++++++++++++++++-- 3 files changed, 226 insertions(+), 46 deletions(-) diff --git a/adapters.json b/adapters.json index e2c09b9095e..48ca7cefc35 100644 --- a/adapters.json +++ b/adapters.json @@ -147,6 +147,11 @@ }, { "admixer": { + "supportedMediaTypes": ["video"] + } + }, + { + "conversant": { "supportedMediaTypes": ["video"] } } diff --git a/src/adapters/conversant.js b/src/adapters/conversant.js index d8c15c1d7e7..974eb4c8100 100644 --- a/src/adapters/conversant.js +++ b/src/adapters/conversant.js @@ -1,21 +1,21 @@ 'use strict'; -var VERSION = '2.0.1', - CONSTANTS = require('../constants.json'), - utils = require('../utils.js'), - bidfactory = require('../bidfactory.js'), - bidmanager = require('../bidmanager.js'), - adloader = require('../adloader'), - ajax = require('../ajax').ajax; +var VERSION = '2.1.0'; +var CONSTANTS = require('../constants.json'); +var utils = require('../utils.js'); +var bidfactory = require('../bidfactory.js'); +var bidmanager = require('../bidmanager.js'); +var adloader = require('../adloader'); +var ajax = require('../ajax').ajax; /** * Adapter for requesting bids from Conversant */ var ConversantAdapter = function () { - var w = window, - n = navigator; + var w = window; + var n = navigator; // production endpoint - var conversantUrl = '//media.msg.dotomi.com/s2s/header?callback=$$PREBID_GLOBAL$$.conversantResponse'; + var conversantUrl = '//media.msg.dotomi.com/s2s/header/24?callback=$$PREBID_GLOBAL$$.conversantResponse'; // SSAPI returns JSONP with window.pbjs.conversantResponse as the cb var appendScript = function (code) { @@ -55,21 +55,26 @@ var ConversantAdapter = function () { var requestBids = function (bidReqs) { // build bid request object - var page = location.pathname + location.search + location.hash, - siteId = '', - conversantImps = [], - conversantBidReqs, - secure = 0; + var page = location.pathname + location.search + location.hash; + var siteId = ''; + var conversantImps = []; + var conversantBidReqs; + var secure = 0; // build impression array for conversant utils._each(bidReqs, function (bid) { - var bidfloor = utils.getBidIdParameter('bidfloor', bid.params), - adW = 0, - adH = 0, - imp; + var bidfloor = utils.getBidIdParameter('bidfloor', bid.params); + var adW = 0; + var adH = 0; + var format; + var tagId; + var pos; + var imp; secure = utils.getBidIdParameter('secure', bid.params) ? 1 : secure; siteId = utils.getBidIdParameter('site_id', bid.params) + ''; + tagId = utils.getBidIdParameter('tag_id', bid.params); + pos = utils.getBidIdParameter('position', bid.params); // Allow sizes to be overridden per placement var bidSizes = Array.isArray(bid.params.sizes) ? bid.params.sizes : bid.sizes; @@ -78,22 +83,69 @@ var ConversantAdapter = function () { adW = bidSizes[0]; adH = bidSizes[1]; } else { - adW = bidSizes[0][0]; - adH = bidSizes[0][1]; + format = []; + utils._each(bidSizes, function (bidSize) { + format.push({ + w: bidSize[0], + h: bidSize[1] + }); + }); } imp = { id: bid.bidId, - banner: { - w: adW, - h: adH - }, secure: secure, bidfloor: bidfloor || 0, displaymanager: 'Prebid.js', displaymanagerver: VERSION }; + if (tagId !== '') { + imp.tagid = tagId; + } + + if (bid.mediaType === 'video') { + var mimes = []; + var maxduration = 0; + var protocols = []; + var api = []; + + var video = Array.isArray(format) ? {format: format} : {w: adW, h: adH}; + + mimes = utils.getBidIdParameter('mimes', bid.params); + if (mimes !== '') { + video.mimes = mimes; + } + + maxduration = utils.getBidIdParameter('maxduration', bid.params); + if (maxduration !== '') { + video.maxduration = maxduration; + } + + protocols = utils.getBidIdParameter('protocols', bid.params); + if (protocols !== '') { + video.protocols = protocols; + } + + api = utils.getBidIdParameter('api', bid.params); + if (api !== '') { + video.api = api; + } + + if (pos !== '') { + video.pos = pos; + } + + imp.video = video; + } else { + var banner = Array.isArray(format) ? {format: format} : {w: adW, h: adH}; + + if (pos !== '') { + banner.pos = pos; + } + imp.banner = banner; + } + conversantImps.push(imp); }); @@ -135,13 +187,13 @@ var ConversantAdapter = function () { var parseSeatbid = function (bidResponse) { var placementsWithBidsBack = []; utils._each(bidResponse.bid, function (conversantBid) { - var responseCPM, - placementCode = '', - id = conversantBid.impid, - bid = {}, - responseAd, - responseNurl, - sizeArrayLength; + var responseCPM; + var placementCode = ''; + var id = conversantBid.impid; + var bid = {}; + var responseAd; + var responseNurl; + var sizeArrayLength; // Bid request we sent Conversant var bidRequested = $$PREBID_GLOBAL$$._bidsRequested.find(bidSet => bidSet.bidderCode === 'conversant').bids.find(bid => bid.bidId === id); @@ -162,11 +214,14 @@ var ConversantAdapter = function () { bid = bidfactory.createBid(1, bidRequested); bid.creative_id = conversantBid.id || ''; bid.bidderCode = 'conversant'; - bid.cpm = responseCPM; - // Track impression image onto returned html - bid.ad = responseAd + ''; + if (bidRequested.mediaType === 'video') { + bid.vastUrl = responseAd; + } else { + // Track impression image onto returned html + bid.ad = responseAd + ''; + } sizeArrayLength = bidRequested.sizes.length; if (sizeArrayLength === 2 && typeof bidRequested.sizes[0] === 'number' && typeof bidRequested.sizes[1] === 'number') { diff --git a/test/spec/adapters/conversant_spec.js b/test/spec/adapters/conversant_spec.js index 3c9d636a700..09d5132683f 100644 --- a/test/spec/adapters/conversant_spec.js +++ b/test/spec/adapters/conversant_spec.js @@ -16,10 +16,11 @@ describe('Conversant adapter tests', function () { sizes: [[300, 600]], params: { site_id: '87293', + position: 1, + tag_id: 'tagid-1', secure: false } - }, - { + }, { bidId: 'bidId2', bidder: 'conversant', placementCode: 'div2', @@ -28,14 +29,27 @@ describe('Conversant adapter tests', function () { site_id: '87293', secure: false } - }, - { + }, { bidId: 'bidId3', bidder: 'conversant', placementCode: 'div3', sizes: [[300, 600], [160, 600]], params: { site_id: '87293', + position: 1, + tag_id: '', + secure: false + } + }, { + bidId: 'bidId4', + bidder: 'conversant', + placementCode: 'div4', + mediaType: 'video', + sizes: [[480, 480]], + params: { + site_id: '89192', + pos: 1, + tagid: 'tagid-4', secure: false } } @@ -101,7 +115,7 @@ describe('Conversant adapter tests', function () { expect(thirdBid.bidderCode).to.equal('conversant'); expect(placementCode3).to.equal('div3'); - expect(addBidResponseSpy.getCalls().length).to.equal(3); + expect(addBidResponseSpy.getCalls().length).to.equal(4); }); it('Should submit bids with statuses of 2 to the bid manager for empty bid responses', function () { @@ -126,7 +140,7 @@ describe('Conversant adapter tests', function () { expect(thirdBid.getStatusCode()).to.equal(2); expect(thirdBid.bidderCode).to.equal('conversant'); - expect(addBidResponseSpy.getCalls().length).to.equal(3); + expect(addBidResponseSpy.getCalls().length).to.equal(4); }); it('Should submit valid bids to the bid manager', function () { @@ -150,8 +164,7 @@ describe('Conversant adapter tests', function () { adm: 'adm2', h: 300, w: 600 - }, - { + }, { id: 33333, impid: 'bidId3', price: 0.33, @@ -190,8 +203,34 @@ describe('Conversant adapter tests', function () { expect(thirdBid.ad).to.equal('adm3' + ''); expect(placementCode3).to.equal('div3'); - expect(addBidResponseSpy.getCalls().length).to.equal(3); + expect(addBidResponseSpy.getCalls().length).to.equal(4); }); + + it('Should submit video bid responses correctly.', function () { + var bidResponse = { + id: 123, + seatbid: [{ + bid: [{ + id: 1111111, + impid: 'bidId4', + price: 0.11, + nurl: 'imp_tracker', + adm: 'vasturl' + }] + }] + }; + + $$PREBID_GLOBAL$$.conversantResponse(bidResponse); + + var videoBid = addBidResponseSpy.getCall(0).args[1]; + var placementCode = addBidResponseSpy.getCall(0).args[0]; + + expect(videoBid.getStatusCode()).to.equal(1); + expect(videoBid.bidderCode).to.equal('conversant'); + expect(videoBid.cpm).to.equal(0.11); + expect(videoBid.vastUrl).to.equal('vasturl'); + expect(placementCode).to.equal('div4'); + }) }); describe('Should submit the correct headers in the xhr', function () { @@ -218,8 +257,7 @@ describe('Conversant adapter tests', function () { adm: 'adm2', h: 300, w: 600 - }, - { + }, { id: 3333, impid: 'bidId3', price: 0.33, @@ -253,4 +291,86 @@ describe('Conversant adapter tests', function () { expect(request.requestBody).to.not.be.empty; }); }); + describe('Should create valid bid requests.', function () { + var server, + adapter; + + var bidResponse = { + id: 123, + seatbid: [{ + bid: [{ + id: 1111, + impid: 'bidId1', + price: 0.11, + nurl: '', + adm: 'adm', + h: 250, + w: 300, + ext: {} + }, { + id: 2222, + impid: 'bidId2', + price: 0.22, + nurl: '', + adm: 'adm2', + h: 300, + w: 600 + }, { + id: 3333, + impid: 'bidId3', + price: 0.33, + nurl: '', + adm: 'adm3', + h: 160, + w: 600 + }] + }] + }; + + beforeEach(function () { + server = sinon.fakeServer.create(); + adapter = new Adapter(); + }); + + afterEach(function () { + server.restore(); + }); + + beforeEach(function () { + var resp = [200, {'Content-type': 'text/javascript'}, '$$PREBID_GLOBAL$$.conversantResponse(\'' + JSON.stringify(bidResponse) + '\')']; + server.respondWith('POST', new RegExp('media.msg.dotomi.com/s2s/header'), resp); + }); + + it('Should create valid bid requests.', function () { + adapter.callBids(bidderRequest); + server.respond(); + var request = JSON.parse(server.requests[0].requestBody); + expect(request.imp[0].banner.format[0].w).to.equal(300); + expect(request.imp[0].banner.format[0].h).to.equal(600); + expect(request.imp[0].tagid).to.equal('tagid-1'); + expect(request.imp[0].banner.pos).to.equal(1); + expect(request.imp[0].secure).to.equal(0); + expect(request.site.id).to.equal('89192'); + }); + + it('Should not pass empty or missing optional parameters on requests.', function () { + adapter.callBids(bidderRequest); + server.respond(); + + var request = JSON.parse(server.requests[0].requestBody); + expect(request.imp[1].tagid).to.equal(undefined); + expect(request.imp[2].tagid).to.equal(undefined); + expect(request.imp[1].pos).to.equal(undefined); + }); + + it('Should create the format objects correctly.', function () { + adapter.callBids(bidderRequest); + server.respond(); + + var request = JSON.parse(server.requests[0].requestBody); + expect(request.imp[2].banner.format.length).to.equal(2); + expect(request.imp[2].banner.format[0].w).to.equal(300); + expect(request.imp[2].banner.format[1].w).to.equal(160); + }); + }); }); From 66089e322eab50ed49f2a7208cad84de74417511 Mon Sep 17 00:00:00 2001 From: "Tom Riley (Coull)" Date: Wed, 7 Jun 2017 23:13:04 +0100 Subject: [PATCH 17/95] Prevent 'about:' protocol in _publisherTagUrl (#1170) * handle pubmatic targeting key value pairs if in DFP GPT format * hardcoded pubmatic request to https as protocol-less url prevents chrome req from injected iframe * add newline for consistency * specifically check for http prot, fall back to https in crit adapter * added spaces to pass eslint #1170 * removed blank line refs PR #1170 --- src/adapters/criteo.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/adapters/criteo.js b/src/adapters/criteo.js index aeea56f0851..c0e14fb3d51 100644 --- a/src/adapters/criteo.js +++ b/src/adapters/criteo.js @@ -3,7 +3,8 @@ var bidmanager = require('../bidmanager.js'); var adloader = require('../adloader'); var CriteoAdapter = function CriteoAdapter() { - var _publisherTagUrl = window.location.protocol + '//static.criteo.net/js/ld/publishertag.js'; + var sProt = (window.location.protocol === 'http:') ? 'http:' : 'https:'; + var _publisherTagUrl = sProt + '//static.criteo.net/js/ld/publishertag.js'; var _bidderCode = 'criteo'; var _profileId = 125; From adf68aee69cbe872f904a2ebefa259f4400f0b9a Mon Sep 17 00:00:00 2001 From: levjad Date: Thu, 8 Jun 2017 17:04:08 +0200 Subject: [PATCH 18/95] Rubicon Adapter - Adding 320x150 (#1279) --- src/adapters/rubicon.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/adapters/rubicon.js b/src/adapters/rubicon.js index 9bad92bfe4a..241e30c6fdf 100644 --- a/src/adapters/rubicon.js +++ b/src/adapters/rubicon.js @@ -46,6 +46,7 @@ var sizeMap = { 57: '970x250', 58: '1000x90', 59: '320x80', + 60: '320x150', 61: '1000x1000', 65: '640x480', 67: '320x480', From afd7da624770b9f64bc899266e228b28117bdaf3 Mon Sep 17 00:00:00 2001 From: Valentin Zhukovsky Date: Fri, 9 Jun 2017 19:16:41 +0300 Subject: [PATCH 19/95] Add drop pixels once feature to AOL Adapter (#1224) * Added drop pixels once feature. * Fixed code style. --- src/adapters/aol.js | 21 +- test/spec/adapters/aol_spec.js | 384 +++++++++++++-------------------- 2 files changed, 168 insertions(+), 237 deletions(-) diff --git a/src/adapters/aol.js b/src/adapters/aol.js index ee7a60e9b80..32039b14362 100644 --- a/src/adapters/aol.js +++ b/src/adapters/aol.js @@ -4,6 +4,10 @@ const bidfactory = require('../bidfactory.js'); const bidmanager = require('../bidmanager.js'); const constants = require('../constants.json'); +$$PREBID_GLOBAL$$.aolGlobals = { + pixelsDropped: false +}; + const AolAdapter = function AolAdapter() { let showCpmAdjustmentWarning = true; const pubapiTemplate = template`${'protocol'}://${'host'}/pubapi/3.0/${'network'}/${'placement'}/${'pageid'}/${'sizeid'}/ADTECH;v=2;cmd=bid;cors=yes;alias=${'alias'}${'bidfloor'};misc=${'misc'}`; @@ -42,8 +46,11 @@ const AolAdapter = function AolAdapter() { })(); function dropSyncCookies(pixels) { - let pixelElements = parsePixelItems(pixels); - renderPixelElements(pixelElements); + if (!$$PREBID_GLOBAL$$.aolGlobals.pixelsDropped) { + let pixelElements = parsePixelItems(pixels); + renderPixelElements(pixelElements); + $$PREBID_GLOBAL$$.aolGlobals.pixelsDropped = true; + } } function parsePixelItems(pixels) { @@ -202,7 +209,11 @@ const AolAdapter = function AolAdapter() { if (bid.params.userSyncOn === constants.EVENTS.BID_RESPONSE) { dropSyncCookies(response.ext.pixels); } else { - ad += response.ext.pixels; + let formattedPixels = response.ext.pixels.replace(/<\/?script( type=('|")text\/javascript('|")|)?>/g, ''); + + ad += ''; } } @@ -226,8 +237,8 @@ const AolAdapter = function AolAdapter() { if (bid.params.id && bid.params.imp && bid.params.imp[0]) { let imp = bid.params.imp[0]; return imp.id && imp.tagid && - ((imp.banner && imp.banner.w && imp.banner.h) || - (imp.video && imp.video.mimes && imp.video.minduration && imp.video.maxduration)); + ((imp.banner && imp.banner.w && imp.banner.h) || + (imp.video && imp.video.mimes && imp.video.minduration && imp.video.maxduration)); } } diff --git a/test/spec/adapters/aol_spec.js b/test/spec/adapters/aol_spec.js index 0359dfc7d70..aa41f92b75c 100644 --- a/test/spec/adapters/aol_spec.js +++ b/test/spec/adapters/aol_spec.js @@ -1,43 +1,45 @@ import {expect} from 'chai'; -import { cloneDeep } from 'lodash'; import * as utils from 'src/utils'; import AolAdapter from 'src/adapters/aol'; import bidmanager from 'src/bidmanager'; -import events from 'src/events'; -import constants from 'src/constants'; - -const DEFAULT_BIDDER_REQUEST = { - bidderCode: 'aol', - requestId: 'd3e07445-ab06-44c8-a9dd-5ef9af06d2a6', - bidderRequestId: '7101db09af0db2', - start: new Date().getTime(), - bids: [{ - bidder: 'aol', - bidId: '84ab500420319d', - bidderRequestId: '7101db09af0db2', - requestId: 'd3e07445-ab06-44c8-a9dd-5ef9af06d2a6', - placementCode: 'foo', - params: { - placement: 1234567, - network: '9599.1' - } - }] + +let getDefaultBidResponse = () => { + return { + id: '245730051428950632', + cur: 'USD', + seatbid: [{ + bid: [{ + id: 1, + impid: '245730051428950632', + price: 0.09, + adm: '', + crid: '0', + h: 90, + w: 728, + ext: {sizeid: 225} + }] + }] + }; }; -const DEFAULT_PUBAPI_RESPONSE = { - 'id': '245730051428950632', - 'cur': 'USD', - 'seatbid': [{ - 'bid': [{ - 'id': 1, - 'impid': '245730051428950632', - 'price': 0.09, - 'adm': "", - 'crid': '0', - 'h': 90, - 'w': 728, - 'ext': {'sizeid': 225} + +let getDefaultBidRequest = () => { + return { + bidderCode: 'aol', + requestId: 'd3e07445-ab06-44c8-a9dd-5ef9af06d2a6', + bidderRequestId: '7101db09af0db2', + start: new Date().getTime(), + bids: [{ + bidder: 'aol', + bidId: '84ab500420319d', + bidderRequestId: '7101db09af0db2', + requestId: 'd3e07445-ab06-44c8-a9dd-5ef9af06d2a6', + placementCode: 'foo', + params: { + placement: 1234567, + network: '9599.1' + } }] - }] + }; }; describe('AolAdapter', () => { @@ -46,7 +48,7 @@ describe('AolAdapter', () => { beforeEach(() => adapter = new AolAdapter()); function createBidderRequest({bids, params} = {}) { - var bidderRequest = cloneDeep(DEFAULT_BIDDER_REQUEST); + var bidderRequest = getDefaultBidRequest(); if (bids && Array.isArray(bids)) { bidderRequest.bids = bids; } @@ -80,7 +82,7 @@ describe('AolAdapter', () => { }); it('should hit the Marketplace api endpoint with the Marketplace config', () => { - adapter.callBids(DEFAULT_BIDDER_REQUEST); + adapter.callBids(getDefaultBidRequest()); expect(requests[0].url).to.contain('adserver-us.adtech.advertising.com/pubapi/3.0/'); }); @@ -118,17 +120,17 @@ describe('AolAdapter', () => { }); it('should be the pubapi bid request', () => { - adapter.callBids(DEFAULT_BIDDER_REQUEST); + adapter.callBids(getDefaultBidRequest()); expect(requests[0].url).to.contain('cmd=bid;'); }); it('should be the version 2 of pubapi', () => { - adapter.callBids(DEFAULT_BIDDER_REQUEST); + adapter.callBids(getDefaultBidRequest()); expect(requests[0].url).to.contain('v=2;'); }); it('should contain cache busting', () => { - adapter.callBids(DEFAULT_BIDDER_REQUEST); + adapter.callBids(getDefaultBidRequest()); expect(requests[0].url).to.match(/misc=\d+/); }); @@ -348,14 +350,14 @@ describe('AolAdapter', () => { }); it('should be added to bidmanager if returned from pubapi', () => { - server.respondWith(JSON.stringify(DEFAULT_PUBAPI_RESPONSE)); - adapter.callBids(DEFAULT_BIDDER_REQUEST); + server.respondWith(JSON.stringify(getDefaultBidResponse())); + adapter.callBids(getDefaultBidRequest()); server.respond(); expect(bidmanager.addBidResponse.calledOnce).to.be.true; }); it('should be added to bidmanager if returned from nexage GET bid request', () => { - server.respondWith(JSON.stringify(DEFAULT_PUBAPI_RESPONSE)); + server.respondWith(JSON.stringify(getDefaultBidResponse())); adapter.callBids(createBidderRequest({ params: { dcn: '54321123', @@ -367,7 +369,7 @@ describe('AolAdapter', () => { }); it('should be added to bidmanager if returned from nexage POST bid request', () => { - server.respondWith(JSON.stringify(DEFAULT_PUBAPI_RESPONSE)); + server.respondWith(JSON.stringify(getDefaultBidResponse())); adapter.callBids(createBidderRequest({ params: { id: 'id-1', @@ -387,25 +389,25 @@ describe('AolAdapter', () => { }); it('should be added to bidmanager with correct bidderCode', () => { - server.respondWith(JSON.stringify(DEFAULT_PUBAPI_RESPONSE)); - adapter.callBids(DEFAULT_BIDDER_REQUEST); + server.respondWith(JSON.stringify(getDefaultBidResponse())); + adapter.callBids(getDefaultBidRequest()); server.respond(); expect(bidmanager.addBidResponse.calledOnce).to.be.true; expect(bidmanager.addBidResponse.firstCall.args[1]).to.have.property('bidderCode', 'aol'); }); it('should have adId matching the bidId from related bid request', () => { - server.respondWith(JSON.stringify(DEFAULT_PUBAPI_RESPONSE)); - adapter.callBids(DEFAULT_BIDDER_REQUEST); + server.respondWith(JSON.stringify(getDefaultBidResponse())); + adapter.callBids(getDefaultBidRequest()); server.respond(); expect(bidmanager.addBidResponse.calledOnce).to.be.true; expect(bidmanager.addBidResponse.firstCall.args[1]) - .to.have.property('adId', DEFAULT_BIDDER_REQUEST.bids[0].bidId); + .to.have.property('adId', '84ab500420319d'); }); it('should be added to bidmanager as invalid in case of empty response', () => { server.respondWith(''); - adapter.callBids(DEFAULT_BIDDER_REQUEST); + adapter.callBids(getDefaultBidRequest()); server.respond(); expect(bidmanager.addBidResponse.calledOnce).to.be.true; expect(bidmanager.addBidResponse.firstCall.args[1].getStatusCode()).to.equal(2); @@ -413,238 +415,129 @@ describe('AolAdapter', () => { it('should be added to bidmanager as invalid in case of invalid JSON response', () => { server.respondWith('{foo:{bar:{baz:'); - adapter.callBids(DEFAULT_BIDDER_REQUEST); + adapter.callBids(getDefaultBidRequest()); server.respond(); expect(bidmanager.addBidResponse.calledOnce).to.be.true; expect(bidmanager.addBidResponse.firstCall.args[1].getStatusCode()).to.equal(2); }); it('should be added to bidmanager as invalid in case of no bid data', () => { - server.respondWith(JSON.stringify({ - 'id': '245730051428950632', - 'cur': 'USD', - 'seatbid': [] - })); - adapter.callBids(DEFAULT_BIDDER_REQUEST); + let bidResponse = getDefaultBidResponse(); + bidResponse.seatbid = []; + server.respondWith(JSON.stringify(bidResponse)); + + adapter.callBids(getDefaultBidRequest()); server.respond(); expect(bidmanager.addBidResponse.calledOnce).to.be.true; expect(bidmanager.addBidResponse.firstCall.args[1].getStatusCode()).to.equal(2); }); it('should have adId matching the bidId from bid request in case of no bid data', () => { - server.respondWith(JSON.stringify({ - 'id': '245730051428950632', - 'cur': 'USD', - 'seatbid': [] - })); - adapter.callBids(DEFAULT_BIDDER_REQUEST); + let bidResponse = getDefaultBidResponse(); + bidResponse.seatbid = []; + server.respondWith(JSON.stringify(bidResponse)); + + adapter.callBids(getDefaultBidRequest()); server.respond(); expect(bidmanager.addBidResponse.calledOnce).to.be.true; expect(bidmanager.addBidResponse.firstCall.args[1]) - .to.have.property('adId', DEFAULT_BIDDER_REQUEST.bids[0].bidId); + .to.have.property('adId', '84ab500420319d'); }); it('should be added to bidmanager as invalid in case of empty price', () => { - server.respondWith(JSON.stringify({ - 'id': '245730051428950632', - 'cur': 'USD', - 'seatbid': [{ - 'bid': [{ - 'id': 1, - 'impid': '245730051428950632', - 'adm': "", - 'crid': '0', - 'h': 90, - 'w': 728, - 'ext': {'sizeid': 225} - }] - }] - })); - adapter.callBids(DEFAULT_BIDDER_REQUEST); + let bidResponse = getDefaultBidResponse(); + bidResponse.seatbid[0].bid[0].price = undefined; + + server.respondWith(JSON.stringify(bidResponse)); + adapter.callBids(getDefaultBidRequest()); server.respond(); expect(bidmanager.addBidResponse.calledOnce).to.be.true; expect(bidmanager.addBidResponse.firstCall.args[1].getStatusCode()).to.equal(2); }); it('should be added to bidmanager with attributes from pubapi response', () => { - server.respondWith(JSON.stringify({ - 'id': '245730051428950632', - 'cur': 'USD', - 'seatbid': [{ - 'bid': [{ - 'id': 1, - 'impid': '245730051428950632', - 'price': 0.09, - 'adm': "", - 'crid': '12345', - 'h': 90, - 'w': 728, - 'ext': {'sizeid': 225} - }] - }] - })); - adapter.callBids(DEFAULT_BIDDER_REQUEST); + let bidResponse = getDefaultBidResponse(); + bidResponse.seatbid[0].bid[0].crid = '12345'; + + server.respondWith(JSON.stringify(bidResponse)); + adapter.callBids(getDefaultBidRequest()); server.respond(); expect(bidmanager.addBidResponse.calledOnce).to.be.true; - var bidResponse = bidmanager.addBidResponse.firstCall.args[1]; - expect(bidResponse.ad).to.equal(""); - expect(bidResponse.cpm).to.equal(0.09); - expect(bidResponse.width).to.equal(728); - expect(bidResponse.height).to.equal(90); - expect(bidResponse.creativeId).to.equal('12345'); - expect(bidResponse.pubapiId).to.equal('245730051428950632'); + let addedBidResponse = bidmanager.addBidResponse.firstCall.args[1]; + expect(addedBidResponse.ad).to.equal(''); + expect(addedBidResponse.cpm).to.equal(0.09); + expect(addedBidResponse.width).to.equal(728); + expect(addedBidResponse.height).to.equal(90); + expect(addedBidResponse.creativeId).to.equal('12345'); + expect(addedBidResponse.pubapiId).to.equal('245730051428950632'); }); it('should be added to bidmanager including pixels from pubapi response', () => { - server.respondWith(JSON.stringify({ - 'id': '245730051428950632', - 'cur': 'USD', - 'seatbid': [{ - 'bid': [{ - 'id': 1, - 'impid': '245730051428950632', - 'price': 0.09, - 'adm': "", - 'crid': '12345', - 'h': 90, - 'w': 728, - 'ext': {'sizeid': 225} - }] - }], - 'ext': { - 'pixels': "" - } - })); - adapter.callBids(DEFAULT_BIDDER_REQUEST); + let bidResponse = getDefaultBidResponse(); + bidResponse.ext = { + pixels: '' + }; + + server.respondWith(JSON.stringify(bidResponse)); + adapter.callBids(getDefaultBidRequest()); server.respond(); expect(bidmanager.addBidResponse.calledOnce).to.be.true; - var bidResponse = bidmanager.addBidResponse.firstCall.args[1]; - expect(bidResponse.ad).to.equal( - "" + - "" + let addedBidResponse = bidmanager.addBidResponse.firstCall.args[1]; + expect(addedBidResponse.ad).to.equal( + '' + + '' ); }); it('should be added to bidmanager including dealid from pubapi response', () => { - server.respondWith(JSON.stringify({ - 'id': '245730051428950632', - 'cur': 'USD', - 'seatbid': [{ - 'bid': [{ - 'id': 1, - 'impid': '245730051428950632', - 'dealid': '12345', - 'price': 0.09, - 'adm': "", - 'crid': '12345', - 'h': 90, - 'w': 728, - 'ext': { - 'sizeid': 225 - } - }] - }] - })); - adapter.callBids(DEFAULT_BIDDER_REQUEST); + let bidResponse = getDefaultBidResponse(); + bidResponse.seatbid[0].bid[0].dealid = '12345'; + + server.respondWith(JSON.stringify(bidResponse)); + adapter.callBids(getDefaultBidRequest()); server.respond(); expect(bidmanager.addBidResponse.calledOnce).to.be.true; - var bidResponse = bidmanager.addBidResponse.firstCall.args[1]; - expect(bidResponse.dealId).to.equal('12345'); + let addedBidResponse = bidmanager.addBidResponse.firstCall.args[1]; + expect(addedBidResponse.dealId).to.equal('12345'); }); it('should be added to bidmanager including encrypted price from pubapi response', () => { - server.respondWith(JSON.stringify({ - 'id': '245730051428950632', - 'cur': 'USD', - 'seatbid': [{ - 'bid': [{ - 'id': 1, - 'impid': '245730051428950632', - 'dealid': '12345', - 'price': 0.09, - 'adm': "", - 'crid': '12345', - 'h': 90, - 'w': 728, - 'ext': { - 'sizeid': 225, - 'encp': 'a9334987' - } - }] - }] - })); - adapter.callBids(DEFAULT_BIDDER_REQUEST); + let bidResponse = getDefaultBidResponse(); + bidResponse.seatbid[0].bid[0].ext.encp = 'a9334987'; + server.respondWith(JSON.stringify(bidResponse)); + + adapter.callBids(getDefaultBidRequest()); server.respond(); expect(bidmanager.addBidResponse.calledOnce).to.be.true; - var bidResponse = bidmanager.addBidResponse.firstCall.args[1]; - expect(bidResponse.cpm).to.equal('a9334987'); + let addedBidResponse = bidmanager.addBidResponse.firstCall.args[1]; + expect(addedBidResponse.cpm).to.equal('a9334987'); }); it('should not render pixels on pubapi response when no parameter is set', () => { - server.respondWith(JSON.stringify({ - 'id': '245730051428950632', - 'cur': 'USD', - 'seatbid': [{ - 'bid': [{ - 'id': 1, - 'impid': '245730051428950632', - 'price': 0.09, - 'adm': "", - 'crid': '12345', - 'h': 90, - 'w': 728, - 'ext': {'sizeid': 225} - }] - }], - 'ext': { - 'pixels': "" - } - })); - adapter.callBids(DEFAULT_BIDDER_REQUEST); + let bidResponse = getDefaultBidResponse(); + bidResponse.ext = { + pixels: '' + }; + server.respondWith(JSON.stringify(bidResponse)); + adapter.callBids(getDefaultBidRequest()); server.respond(); expect(bidmanager.addBidResponse.calledOnce).to.be.true; expect(document.body.querySelectorAll('iframe[src="pixels.org"]').length).to.equal(0); }); it('should render pixels from pubapi response when param userSyncOn is set with \'bidResponse\'', () => { - server.respondWith(JSON.stringify({ - 'id': '245730051428950632', - 'cur': 'USD', - 'seatbid': [{ - 'bid': [{ - 'id': 1, - 'impid': '245730051428950632', - 'price': 0.09, - 'adm': "", - 'crid': '12345', - 'h': 90, - 'w': 728, - 'ext': {'sizeid': 225} - }] - }], - 'ext': { - 'pixels': "" - } - })); - adapter.callBids({ - bidderCode: 'aol', - requestId: 'd3e07445-ab06-44c8-a9dd-5ef9af06d2a6', - bidderRequestId: '7101db09af0db2', - start: new Date().getTime(), - bids: [{ - bidder: 'aol', - bidId: '84ab500420319d', - bidderRequestId: '7101db09af0db2', - requestId: 'd3e07445-ab06-44c8-a9dd-5ef9af06d2a6', - placementCode: 'foo', - params: { - placement: 1234567, - network: '9599.1', - userSyncOn: 'bidResponse' - } - }] - }); + let bidResponse = getDefaultBidResponse(); + bidResponse.ext = { + pixels: '' + }; + + server.respondWith(JSON.stringify(bidResponse)); + let bidRequest = getDefaultBidRequest(); + bidRequest.bids[0].params.userSyncOn = 'bidResponse'; + adapter.callBids(bidRequest); server.respond(); expect(bidmanager.addBidResponse.calledOnce).to.be.true; @@ -659,6 +552,33 @@ describe('AolAdapter', () => { assertPixelsItem('iframe[src="pixels.org"]'); assertPixelsItem('iframe[src="pixels1.org"]'); + expect($$PREBID_GLOBAL$$.aolGlobals.pixelsDropped).to.be.true; + }); + + it('should not render pixels if it was rendered before', () => { + $$PREBID_GLOBAL$$.aolGlobals.pixelsDropped = true; + let bidResponse = getDefaultBidResponse(); + bidResponse.ext = { + pixels: '' + }; + server.respondWith(JSON.stringify(bidResponse)); + + let bidRequest = getDefaultBidRequest(); + bidRequest.bids[0].params.userSyncOn = 'bidResponse'; + adapter.callBids(bidRequest); + server.respond(); + + expect(bidmanager.addBidResponse.calledOnce).to.be.true; + + let assertPixelsItem = (pixelsItemSelector) => { + let pixelsItems = document.body.querySelectorAll(pixelsItemSelector); + + expect(pixelsItems.length).to.equal(0); + }; + + assertPixelsItem('iframe[src="test.com"]'); + assertPixelsItem('iframe[src="test2.com"]'); }); }); @@ -681,13 +601,13 @@ describe('AolAdapter', () => { it('should show warning in the console', function() { sinon.spy(utils, 'logWarn'); - server.respondWith(JSON.stringify(DEFAULT_PUBAPI_RESPONSE)); + server.respondWith(JSON.stringify(getDefaultBidResponse())); $$PREBID_GLOBAL$$.bidderSettings = { aol: { bidCpmAdjustment: function() {} } }; - adapter.callBids(DEFAULT_BIDDER_REQUEST); + adapter.callBids(getDefaultBidRequest()); server.respond(); expect(utils.logWarn.calledOnce).to.be.true; }); From 68a0f9ced1fec339589765accfb0b77d55e9f6b1 Mon Sep 17 00:00:00 2001 From: Kit Westneat Date: Fri, 9 Jun 2017 13:09:18 -0400 Subject: [PATCH 20/95] use request bidder code as default bidderCode for createBid (#1235) --- src/bidfactory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bidfactory.js b/src/bidfactory.js index 9b4da791311..74aa5b72a46 100644 --- a/src/bidfactory.js +++ b/src/bidfactory.js @@ -18,7 +18,7 @@ function Bid(statusCode, bidRequest) { var _bidId = bidRequest && bidRequest.bidId || utils.getUniqueIdentifierStr(); var _statusCode = statusCode || 0; - this.bidderCode = ''; + this.bidderCode = (bidRequest && bidRequest.bidder) || ''; this.width = 0; this.height = 0; this.statusMessage = _getStatus(); From d019890719d94b1153c12aad679e13e308c29521 Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Fri, 9 Jun 2017 13:57:52 -0400 Subject: [PATCH 21/95] Trion adapter (#1254) * Adding a new Trion Interactive Adapter and associated tests to prebid. * adding pub and section id grab before user sync is called * sending bid placement slot to trion url to be utilized by our endpoint. also utilizing prebid location util function for location * Revert "sending bid placement slot to trion url to be utilized by our endpoint. also utilizing prebid location util function for location" This reverts commit 2bab824b872bc2a6d40f8fc8525cbbf373189609. * Revert "Revert "sending bid placement slot to trion url to be utilized by our endpoint. also utilizing prebid location util function for location"" This reverts commit 7786302065f8fcf94a43afd43bb8f9dc3b474d3a. --- src/adapters/trion.js | 5 +++-- test/spec/adapters/trion_spec.js | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/adapters/trion.js b/src/adapters/trion.js index e3c5c34c794..c0320f262c3 100644 --- a/src/adapters/trion.js +++ b/src/adapters/trion.js @@ -58,16 +58,17 @@ TrionAdapter = function TrionAdapter() { var pubId = utils.getBidIdParameter('pubId', bid.params); var sectionId = utils.getBidIdParameter('sectionId', bid.params); var re = utils.getBidIdParameter('re', bid.params); - var url = window.location.href; + var url = utils.getTopWindowUrl(); var sizes = utils.parseSizesInput(bid.sizes).join(','); var trionUrl = BID_REQUEST_BASE_URL; - trionUrl = utils.tryAppendQueryString(trionUrl, 'callback', 'pbjs.handleTrionCB'); + trionUrl = utils.tryAppendQueryString(trionUrl, 'callback', '$$PREBID_GLOBAL$$.handleTrionCB'); trionUrl = utils.tryAppendQueryString(trionUrl, 'bidId', bidId); trionUrl = utils.tryAppendQueryString(trionUrl, 'pubId', pubId); trionUrl = utils.tryAppendQueryString(trionUrl, 'sectionId', sectionId); trionUrl = utils.tryAppendQueryString(trionUrl, 're', re); + trionUrl = utils.tryAppendQueryString(trionUrl, 'slot', bid.placementCode); if (url) { trionUrl += 'url=' + url + '&'; } diff --git a/test/spec/adapters/trion_spec.js b/test/spec/adapters/trion_spec.js index b5e79cf7312..dbbcf66ec87 100644 --- a/test/spec/adapters/trion_spec.js +++ b/test/spec/adapters/trion_spec.js @@ -1,6 +1,7 @@ import { expect } from 'chai'; import trionAdapter from 'src/adapters/trion'; import bidmanager from 'src/bidmanager'; +import * as utils from 'src/utils'; const CONSTANTS = require('src/constants.json'); const adloader = require('src/adloader'); @@ -106,7 +107,8 @@ describe('Trion adapter tests', () => { let bidUrl = spyLoadScript.getCall(0).args[0]; expect(bidUrl).to.include('re=1'); - expect(bidUrl).to.include(window.location.href); + expect(bidUrl).to.include(utils.getTopWindowUrl()); + expect(bidUrl).to.include('slot=' + PLACEMENT_CODE); delete params.re; }); From f17ec54ebda18fc0d9e460b3d8b5a44035af72d9 Mon Sep 17 00:00:00 2001 From: Anthony Jose Bruscantini Date: Fri, 9 Jun 2017 12:44:58 -0700 Subject: [PATCH 22/95] Getting DigiTrustID in GumGum adapter (#1256) * get DigiTrust ID from DigiTrust Object, if present, and send to our endpoint * no longer retrieving DigiTech.keyv from DigiTrust object as we are not using it - at least for the moment. And remaned dt.id query param to just dt --- src/adapters/gumgum.js | 20 ++++++++- test/spec/adapters/gumgum_spec.js | 68 +++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/adapters/gumgum.js b/src/adapters/gumgum.js index 1d589fa7041..4196287c520 100644 --- a/src/adapters/gumgum.js +++ b/src/adapters/gumgum.js @@ -15,6 +15,7 @@ const GumgumAdapter = function GumgumAdapter() { const requestCache = {}; const throttleTable = {}; const defaultThrottle = 3e4; + const dtCredentials = { member: 'YcXr87z2lpbB' }; try { topWindow = global.top; @@ -27,6 +28,22 @@ const GumgumAdapter = function GumgumAdapter() { return new Date().getTime(); } + function _getDigiTrustQueryParams() { + function getDigiTrustId () { + var digiTrustUser = (window.DigiTrust && window.DigiTrust.getUser) ? window.DigiTrust.getUser(dtCredentials) : {}; + return digiTrustUser && digiTrustUser.success && digiTrustUser.identity || ''; + }; + + let digiTrustId = getDigiTrustId(); + // Verify there is an ID and this user has not opted out + if (!digiTrustId || digiTrustId.privacy && digiTrustId.privacy.optout) { + return {}; + } + return { + 'dt': digiTrustId.id + }; + } + function _callBids({ bids }) { const browserParams = { vw: topWindow.innerWidth, @@ -37,6 +54,7 @@ const GumgumAdapter = function GumgumAdapter() { ce: navigator.cookieEnabled, dpr: topWindow.devicePixelRatio || 1 }; + utils._each(bids, bidRequest => { const { bidId , params = {} @@ -91,7 +109,7 @@ const GumgumAdapter = function GumgumAdapter() { const callback = { jsonp: `$$PREBID_GLOBAL$$.handleGumGumCB['${bidId}']` }; CALLBACKS[bidId] = _handleGumGumResponse(cachedBid); - const query = Object.assign(callback, browserParams, bid); + const query = Object.assign(callback, browserParams, bid, _getDigiTrustQueryParams()); const bidCall = `${bidEndpoint}?${utils.parseQueryStringParameters(query)}`; adloader.loadScript(bidCall); }); diff --git a/test/spec/adapters/gumgum_spec.js b/test/spec/adapters/gumgum_spec.js index 96e756d1052..a6d33dc5bd0 100644 --- a/test/spec/adapters/gumgum_spec.js +++ b/test/spec/adapters/gumgum_spec.js @@ -92,6 +92,74 @@ describe('gumgum adapter', () => { sandbox.restore(); }); + describe('DigiTrust params', () => { + beforeEach(() => { + sandbox.stub(adLoader, 'loadScript'); + }); + + it('should send digiTrust params', () => { + window.DigiTrust = { + getUser: function() {} + }; + sandbox.stub(window.DigiTrust, 'getUser', () => + ({ + success: true, + identity: { + privacy: {optout: false}, + id: 'testId' + } + }) + ); + + adapter.callBids(bidderRequest); + expect(adLoader.loadScript.firstCall.args[0]).to.include('&dt=testId'); + delete window.DigiTrust; + }); + + it('should not send DigiTrust params when DigiTrust is not loaded', () => { + adapter.callBids(bidderRequest); + expect(adLoader.loadScript.firstCall.args[0]).to.not.include('&dt'); + }); + + it('should not send DigiTrust params due to opt out', () => { + window.DigiTrust = { + getUser: function() {} + }; + sandbox.stub(window.DigiTrust, 'getUser', () => + ({ + success: true, + identity: { + privacy: {optout: true}, + id: 'testId' + } + }) + ); + + adapter.callBids(bidderRequest); + expect(adLoader.loadScript.firstCall.args[0]).to.not.include('&dt'); + delete window.DigiTrust; + }); + + it('should not send DigiTrust params on failure', () => { + window.DigiTrust = { + getUser: function() {} + }; + sandbox.stub(window.DigiTrust, 'getUser', () => + ({ + success: false, + identity: { + privacy: {optout: false}, + id: 'testId' + } + }) + ); + + adapter.callBids(bidderRequest); + expect(adLoader.loadScript.firstCall.args[0]).to.not.include('&dt'); + delete window.DigiTrust; + }); + }); + describe('callBids', () => { beforeEach(() => { sandbox.stub(adLoader, 'loadScript'); From b6803174392082c375d4bf310252c708b395c76c Mon Sep 17 00:00:00 2001 From: dbemiller Date: Fri, 9 Jun 2017 18:20:19 -0400 Subject: [PATCH 23/95] Integration test page for adapters (#1182) * Added a hello world example page for testing new adapter submissions. * Added a line to the README which (hopefully) will point adapter PRs to the new test page. * Updated the github PR template. --- .github/PULL_REQUEST_TEMPLATE.md | 3 + CONTRIBUTING.md | 2 + integrationExamples/gpt/.gitignore | 1 - integrationExamples/gpt/hello_world.html | 102 +++++++++++++++++++++++ 4 files changed, 107 insertions(+), 1 deletion(-) delete mode 100644 integrationExamples/gpt/.gitignore create mode 100644 integrationExamples/gpt/hello_world.html diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1dc04a9c2b7..61eb327fd2c 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -26,6 +26,9 @@ Thank you for your pull request. Please make sure this PR is scoped to one chang } } ``` + +Be sure to test the integration with your adserver using the [Hello World](/integrationExamples/gpt/hello_world.html) sample page. + - contact email of the adapter’s maintainer - [ ] official adapter submission diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3252375ac68..5856835f785 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,6 +31,8 @@ Before a Pull Request will be considered for merge: - All new and existing tests must pass - Added or modified code must have greater than 80% coverage +If you are submitting an adapter, you can also use the [Hello World](integrationExamples/gpt/hello_world.html) example page to test integration with your server. + ### Test Guidelines When you are adding code to Prebid.js, or modifying code that isn't covered by an existing test, test the code according to these guidelines: diff --git a/integrationExamples/gpt/.gitignore b/integrationExamples/gpt/.gitignore deleted file mode 100644 index fb64ad0cc6e..00000000000 --- a/integrationExamples/gpt/.gitignore +++ /dev/null @@ -1 +0,0 @@ -pbjs_adblade_example_gpt.html diff --git a/integrationExamples/gpt/hello_world.html b/integrationExamples/gpt/hello_world.html new file mode 100644 index 00000000000..0f5e24a301a --- /dev/null +++ b/integrationExamples/gpt/hello_world.html @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + +

Prebid.js Test

+
Div-1
+
+ +
+ + From e456fcf8fb1859b3743aef8298132f9cd85d95e4 Mon Sep 17 00:00:00 2001 From: Pupis Date: Mon, 12 Jun 2017 16:19:30 +0300 Subject: [PATCH 24/95] Pass through transactionId and set fd=1 (#1259) --- src/adapters/adform.js | 9 ++++++--- test/spec/adapters/adform_spec.js | 18 ++++++++++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/adapters/adform.js b/src/adapters/adform.js index 660c1c585b0..31eceba0b0d 100644 --- a/src/adapters/adform.js +++ b/src/adapters/adform.js @@ -10,11 +10,11 @@ function AdformAdapter() { }; function _callBids(params) { - var bid, _value, _key, i, j, k, l; + var bid, _value, _key, i, j, k, l, reqParams; var bids = params.bids; var request = []; var callbackName = '_adf_' + utils.getUniqueIdentifierStr(); - var globalParams = [ [ 'adxDomain', 'adx.adform.net' ], [ 'url', null ], [ 'tid', null ], [ 'callback', '$$PREBID_GLOBAL$$.' + callbackName ] ]; + var globalParams = [ [ 'adxDomain', 'adx.adform.net' ], ['fd', 1], [ 'url', null ], [ 'tid', null ], [ 'callback', '$$PREBID_GLOBAL$$.' + callbackName ] ]; for (i = 0, l = bids.length; i < l; i++) { bid = bids[i]; @@ -28,7 +28,9 @@ function AdformAdapter() { } } - request.push(formRequestUrl(bid.params)); + reqParams = bid.params; + reqParams.transactionId = bid.transactionId; + request.push(formRequestUrl(reqParams)); } request.unshift('//' + globalParams[0][1] + '/adx/?rp=4'); @@ -76,6 +78,7 @@ function AdformAdapter() { bidObject.width = adItem.width; bidObject.height = adItem.height; bidObject.dealId = adItem.deal_id; + bidObject.transactionId = bid.transactionId; bidmanager.addBidResponse(bid.placementCode, bidObject); } else { bidObject = bidfactory.createBid(STATUSCODES.NO_BID, bid); diff --git a/test/spec/adapters/adform_spec.js b/test/spec/adapters/adform_spec.js index 80511be92ac..8888dbfe899 100644 --- a/test/spec/adapters/adform_spec.js +++ b/test/spec/adapters/adform_spec.js @@ -30,15 +30,16 @@ describe('Adform adapter', () => { assert.equal(_query.callback.split('.')[1], '_adf_callback'); assert.equal(_query.tid, 145); assert.equal(_query.rp, 4); + assert.equal(_query.fd, 1); assert.equal(_query.url, encodeURIComponent('some// there')); }); it('should correctly form bid items', () => { const _items = parseUrl(adLoader.loadScript.args[0][0]).items; - assert.deepEqual(_items[0], { mid: '1' }); - assert.deepEqual(_items[1], { mid: '2', someVar: 'someValue' }); - assert.deepEqual(_items[2], { mid: '3', pdom: 'home' }); + assert.deepEqual(_items[0], { mid: '1', transactionId: 'transactionId' }); + assert.deepEqual(_items[1], { mid: '2', someVar: 'someValue', transactionId: 'transactionId' }); + assert.deepEqual(_items[2], { mid: '3', pdom: 'home', transactionId: 'transactionId' }); }); }); @@ -60,6 +61,7 @@ describe('Adform adapter', () => { assert.equal(_bidObject.width, 90); assert.equal(_bidObject.height, 90); assert.equal(_bidObject.dealId, 'deal-1'); + assert.equal(_bidObject.transactionId, 'transactionId'); }); it('should correctly form empty bid response object', () => { @@ -111,6 +113,7 @@ describe('Adform adapter', () => { }); beforeEach(() => { + var transactionId = 'transactionId'; _adapter = adapter(); utils.getUniqueIdentifierStr = () => 'callback'; sandbox = sinon.sandbox.create(); @@ -126,7 +129,8 @@ describe('Adform adapter', () => { url: 'some// there' }, adxDomain: 'newdomain', - tid: 45 + tid: 45, + transactionId: transactionId }, { bidId: '123', @@ -136,7 +140,8 @@ describe('Adform adapter', () => { mid: 2, tid: 145, someVar: 'someValue' - } + }, + transactionId: transactionId }, { bidId: 'a1b', @@ -145,7 +150,8 @@ describe('Adform adapter', () => { params: { mid: 3, pdom: 'home' - } + }, + transactionId: transactionId } ]}); }); From 961c82672790628f881f6f427cb636813d597e51 Mon Sep 17 00:00:00 2001 From: LiranMotola Date: Wed, 14 Jun 2017 00:39:10 +0300 Subject: [PATCH 25/95] Carambola Adapter (#1221) * Carambola adapter first check in including: Carambola.js adapters Carambola_spec.js test * adapters/carambola.js updated ad unit code in the response carambola_spec.js semantic changes * some small changes to improve code readability * carambola_spec.js unit test updates * coding styles changes * carambola.js : fixed: response is still a string and needs to be JSON.parsed (#1221) * carambola.js test commit * adapters/carambola_spec.js fixed did in the emulator (#1221) --- adapters.json | 1 + src/adapters/carambola.js | 193 +++++++++++++++++++++++++++ test/spec/adapters/carambola_spec.js | 139 +++++++++++++++++++ 3 files changed, 333 insertions(+) create mode 100644 src/adapters/carambola.js create mode 100644 test/spec/adapters/carambola_spec.js diff --git a/adapters.json b/adapters.json index 48ca7cefc35..691b0a55bc6 100644 --- a/adapters.json +++ b/adapters.json @@ -15,6 +15,7 @@ "appnexusAst", "beachfront", "audienceNetwork", + "carambola", "conversant", "districtmDMX", "fidelity", diff --git a/src/adapters/carambola.js b/src/adapters/carambola.js new file mode 100644 index 00000000000..18a7c154f6d --- /dev/null +++ b/src/adapters/carambola.js @@ -0,0 +1,193 @@ +/** + * Carambola adapter + */ + +var bidfactory = require('../bidfactory.js'); +var bidmanager = require('../bidmanager.js'); +const utils = require('../utils.js'); +const ajax = require('../ajax.js').ajax; + +const CarambolaAdapter = function CarambolaAdapter() { + const BIDDER_CODE = 'carambola'; + const REQUEST_PATH = 'hb/inimage/getHbBIdProcessedResponse'; + + function _addErrorBidResponse(bid, response = {}, errorMsg = '') { + const bidResponse = bidfactory.createBid(2, bid); + bidResponse.bidderCode = BIDDER_CODE; + bidResponse.reason = errorMsg; + bidmanager.addBidResponse(_getCustomAdUnitCode(bid), bidResponse); + } + // looking at the utils.js at getBidderRequest method. this is what is requested. + function _getCustomAdUnitCode(bid) { + return bid.placementCode; + } + + function _addBidResponse(bid, response) { + const bidResponse = bidfactory.createBid(1, bid); + bidResponse.bidderCode = BIDDER_CODE; + bidResponse.ad = response.ad; + bidResponse.cpm = response.cpm; + bidResponse.width = response.width; + bidResponse.height = response.height; + bidResponse.currencyCode = response.cur; + bidResponse.token = response.token; + bidResponse.pvid = response.pageViewId; + + bidmanager.addBidResponse(_getCustomAdUnitCode(bid), bidResponse); + } + + function _getPageViewId() { + window.Cbola = window.Cbola || {}; + window.Cbola.HB = window.Cbola.HB || {}; + window.Cbola.HB.pvid = window.Cbola.HB.pvid || _createPageViewId(); + return window.Cbola.HB.pvid; + } + + function _createPageViewId() { + function _pad(number) { + return number > 9 ? number : '0' + number + } + + const MIN = 10000; + const MAX = 90000; + let now = new Date(); + + var pvid = + _pad(now.getDate()) + + _pad(now.getMonth() + 1) + + _pad(now.getFullYear() % 100) + + _pad(now.getHours()) + + _pad(now.getMinutes()) + + _pad(now.getSeconds()) + + _pad(now.getMilliseconds() % 100) + + Math.floor((Math.random() * MAX) + MIN); + + return pvid; + } + + // sends a request for each bid + function _buildRequest(bids, params) { + if (!utils.isArray(bids)) { + return; + } + // iterate on every bid and return the response to the hb manager + utils._each(bids, bid => { + let tempParams = params || {}; + tempParams.cbolaMode = bid.params.cbolaMode || 0; + tempParams.wid = bid.params.wid || 0; + tempParams.pixel = bid.params.pixel || ''; + tempParams.bidFloor = bid.params.bidFloor || 0; + tempParams.pageViewId = _getPageViewId(); + tempParams.hb_token = utils.generateUUID(); + tempParams.sizes = utils.parseSizesInput(bid.sizes) + ''; + tempParams.bidsCount = bids.length; + + for (let customParam in bid.params.customParams) { + if (bid.params.customParams.hasOwnProperty(customParam)) { + tempParams['c_' + customParam] = bid.params.customParams[customParam]; + } + } + + let server = bid.params.server || 'route.carambo.la'; + let cbolaHbApiUrl = '//' + server + '/' + REQUEST_PATH; + + // the responses of the bid requests + ajax(cbolaHbApiUrl + _jsonToQueryString(tempParams), response => { + // no response + if (!response || response.cpm <= 0) { + utils.logError('Empty bid response', BIDDER_CODE, bid); + _addErrorBidResponse(bid, response, 'Empty bid response'); + return; + } + try { + response = JSON.parse(response); + if (response && response.cpm <= 0) + { + utils.logError('Bid response returned 0', BIDDER_CODE, bid); + _addErrorBidResponse(bid, response, 'Bid response returned 0'); + return; + } + } catch (e) { + utils.logError('Invalid JSON in bid response', BIDDER_CODE, bid); + _addErrorBidResponse(bid, response, 'Invalid JSON in bid response'); + return; + } + _addBidResponse(bid, response); + }, null, {method: 'GET'}); + }); + } + + // build the genral request to the server + function _callBids(params) { + let isIfr, + bids = params.bids || [], + currentURL = (window.parent !== window) ? document.referrer : window.location.href; + currentURL = currentURL && encodeURIComponent(currentURL); + try { + isIfr = window.self !== window.top; + } + catch (e) { + isIfr = false; + } + if (bids.length === 0) { + return; + } + + _buildRequest(bids, { + pageUrl: currentURL, + did: bids[0].params.did || 0, + pid: bids[0].params.pid || '', + res: _getScreenSize(screen), + ifr: isIfr, + viewPortDim: _getViewportDimensions(isIfr) + }); + } + + function _getScreenSize(screen) { + return screen ? `${screen.width}x${screen.height}x${screen.colorDepth}` : '0'; + } + + function _getViewportDimensions(isIfr) { + let width, + height, + tWin = window, + tDoc = document, + docEl = tDoc.documentElement, + body; + + if (isIfr) { + try { + tWin = window.top; + tDoc = window.top.document; + } + catch (e) { + return; + } + docEl = tDoc.documentElement; + body = tDoc.body; + width = tWin.innerWidth || docEl.clientWidth || body.clientWidth; + height = tWin.innerHeight || docEl.clientHeight || body.clientHeight; + } else { + docEl = tDoc.documentElement; + width = tWin.innerWidth || docEl.clientWidth; + height = tWin.innerHeight || docEl.clientHeight; + } + return `${width}x${height}`; + } + + function _jsonToQueryString(json) { + return '?' + + Object.keys(json).map(function(key) { + return encodeURIComponent(key) + '=' + + encodeURIComponent(json[key]); + }).join('&'); + } + + // Export the `callBids` function, so that Prebid.js can execute + // this function when the page asks to send out bid requests. + return { + callBids: _callBids + }; +}; + +module.exports = CarambolaAdapter; diff --git a/test/spec/adapters/carambola_spec.js b/test/spec/adapters/carambola_spec.js new file mode 100644 index 00000000000..fe856f66c21 --- /dev/null +++ b/test/spec/adapters/carambola_spec.js @@ -0,0 +1,139 @@ +import {expect} from 'chai'; +import * as utils from 'src/utils'; +import CarambolaAdapter from 'src/adapters/carambola'; +import bidmanager from 'src/bidmanager'; + +const DEFAULT_BIDDER_REQUEST = { + bidderCode: 'carambola', + requestId: 'c9ad932a-41d9-4821-b6dc-0c8146029faf', + adId: '2e3daacdeed03d', + start: new Date().getTime(), + bids: [{ + bidder: 'carambola', + adId: '2e3daacdeed03d', + requestId: 'c9ad932a-41d9-4821-b6dc-0c8146029faf', + adUnitCode: 'cbola_prebid_code_97', + token: 'CGYCLyIy', + pageViewId: '22478638', + params: { + pid: 'hbtest', + did: 112591, + wid: 0 + } + }] +}; + +const DEFAULT_HB_RESPONSE = { + cpm: 0.1693953107111156, + ad: ' ', + token: '9cd6bf9c-433d-4663-b67f-da727f4cebff', + width: '300', + height: '250', + currencyCode: 'USD', + pageViewId: '22478638', + requestStatus: 1 + +}; + +describe('carambolaAdapter', function () { + let adapter; + + beforeEach(() => adapter = new CarambolaAdapter()); + + function createBidderRequest({bids, params} = {}) { + var bidderRequest = utils.cloneJson(DEFAULT_BIDDER_REQUEST); + if (bids && Array.isArray(bids)) { + bidderRequest.bids = bids; + } + if (params) { + bidderRequest.bids.forEach(bid => bid.params = params); + } + return bidderRequest; + } + + describe('callBids()', () => { + it('exists and is a function', () => { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + + // bid request starts + describe('bid request', () => { + let xhr; + let requests; + + beforeEach(() => { + xhr = sinon.useFakeXMLHttpRequest(); + requests = []; + xhr.onCreate = request => requests.push(request); + }); + + afterEach(() => xhr.restore()); + + it('requires parameters to be made', () => { + adapter.callBids({}); + expect(requests[0]).to.be.empty; + }); + + it('should hit the default route.carambo.la endpoint', () => { + adapter.callBids(DEFAULT_BIDDER_REQUEST); + expect(requests[0].url).to.contain('route.carambo.la'); + }); + + it('should verifiy that a page_view_id is sent', () => { + adapter.callBids(DEFAULT_BIDDER_REQUEST); + expect(requests[0].url).to.contain('pageViewId='); + }); + + it('should should send the correct did', () => { + adapter.callBids(createBidderRequest({ + params: { + did: 112591, + wid: 0 + } + })); + expect(requests[0].url).to.contain('did=112591'); + }); + }); + // bid request ends + + // bid response starts + describe('bid response', () => { + let server; + + beforeEach(() => { + server = sinon.fakeServer.create(); + sinon.stub(bidmanager, 'addBidResponse'); + }); + + afterEach(() => { + server.restore(); + bidmanager.addBidResponse.restore(); + }); + + it('should be added to bidmanager if response is valid', () => { + server.respondWith(JSON.stringify(DEFAULT_HB_RESPONSE)); + adapter.callBids(DEFAULT_BIDDER_REQUEST); + server.respond(); + expect(bidmanager.addBidResponse.calledOnce).to.be.true; + }); + + it('should be added to bidmanager with correct bidderCode', () => { + server.respondWith(JSON.stringify(DEFAULT_HB_RESPONSE)); + adapter.callBids(DEFAULT_BIDDER_REQUEST); + server.respond(); + expect(bidmanager.addBidResponse.calledOnce).to.be.true; + expect(bidmanager.addBidResponse.firstCall.args[1]).to.have.property('bidderCode', 'carambola'); + }); + + it('should have pageViewId matching the pageViewId from related bid request', () => { + server.respondWith(JSON.stringify(DEFAULT_HB_RESPONSE)); + adapter.callBids(DEFAULT_BIDDER_REQUEST); + server.respond(); + expect(bidmanager.addBidResponse.calledOnce).to.be.true; + expect(bidmanager.addBidResponse.firstCall.args[1]) + .to.have.property('pvid', DEFAULT_BIDDER_REQUEST.bids[0].pageViewId); + }); + }); + // bid response ends + }); +}); From 89c6300cfb69c081b4c356e5e8576d3bfc759520 Mon Sep 17 00:00:00 2001 From: reynold-cox Date: Tue, 13 Jun 2017 14:56:22 -0700 Subject: [PATCH 26/95] New Cox adapter (#1228) * Cox adapter (new) * Unit test for cox adapter (new) * Added cox entry * Styling for ESLint * Styling for ESLint --- adapters.json | 1 + src/adapters/cox.js | 255 +++++++++++++++++++++++++++++++++ test/spec/adapters/cox_spec.js | 121 ++++++++++++++++ 3 files changed, 377 insertions(+) create mode 100644 src/adapters/cox.js create mode 100644 test/spec/adapters/cox_spec.js diff --git a/adapters.json b/adapters.json index 691b0a55bc6..704bb0bd388 100644 --- a/adapters.json +++ b/adapters.json @@ -70,6 +70,7 @@ "trion", "prebidServer", "adsupply", + "cox", { "appnexus": { "alias": "brealtime" diff --git a/src/adapters/cox.js b/src/adapters/cox.js new file mode 100644 index 00000000000..e0e2a053251 --- /dev/null +++ b/src/adapters/cox.js @@ -0,0 +1,255 @@ +var bidfactory = require('../bidfactory.js'); +var bidmanager = require('../bidmanager.js'); +var adLoader = require('../adloader.js'); + +var CoxAdapter = function CoxAdapter() { + var adZoneAttributeKeys = ['id', 'size', 'thirdPartyClickUrl'], + otherKeys = ['siteId', 'wrapper', 'referrerUrl'], + placementMap = {}, + W = window; + + var COX_BIDDER_CODE = 'cox'; + + function _callBids(params) { + var env = ''; + + // Create global cdsTag and CMT object (for the latter, only if needed ) + W.cdsTag = {}; + if (!W.CMT) W.CMT = _getCoxLite(); + + // Populate the tag with the info from prebid + var bids = params.bids || [], + tag = W.cdsTag, + i, + j; + for (i = 0; i < bids.length; i++) { + var bid = bids[i], + cfg = bid.params || {}; + + if (cfg.id) { + tag.zones = tag.zones || {}; + var zone = {}; + + for (j = 0; j < adZoneAttributeKeys.length; j++) { + if (cfg[adZoneAttributeKeys[j]]) zone[adZoneAttributeKeys[j]] = cfg[adZoneAttributeKeys[j]]; + } + for (j = 0; j < otherKeys.length; j++) { + if (cfg[otherKeys[j]]) tag[otherKeys[j]] = cfg[otherKeys[j]]; + } + var adZoneKey = 'as' + cfg.id; + tag.zones[adZoneKey] = zone; + + // Check for an environment setting + if (cfg.env) env = cfg.env; + + // Update the placement map + var xy = (cfg.size || '0x0').split('x'); + placementMap[adZoneKey] = { + p: bid.placementCode, + w: xy[0], + h: xy[1] + }; + } + } + if (tag.zones && Object.keys(tag.zones).length > 0) { + tag.__callback__ = function (r) { + tag.response = r; + _notify(); + }; + adLoader.loadScript(W.CMT.Service.buildSrc(tag, env)); + } + } + + function _notify() { + // Will execute in the context of a bid + // function finalizeAd(price) { + // this.ad = W.CMT.Service.setAuctionPrice(this.ad, price); + // return this; + // } + + for (var adZoneKey in placementMap) { + var bid = W.CMT.Service.getBidTrue(adZoneKey), + bidObj, + data = placementMap[adZoneKey]; + + if (bid > 0) { + bidObj = bidfactory.createBid(1); + bidObj.cpm = bid; + bidObj.ad = W.CMT.Service.getAd(adZoneKey); + bidObj.width = data.w; + bidObj.height = data.h; + // bidObj.floor = W.CMT.Service.getSecondPrice(adZoneKey); + // bidObj.finalizeAd = finalizeAd; + } else { + bidObj = bidfactory.createBid(2); + } + bidObj.bidderCode = COX_BIDDER_CODE; + bidmanager.addBidResponse(data.p, bidObj); + } + } + + function _getCoxLite() { + var CMT = {}; + + CMT.Util = (function () { + return { + + getRand: function getRand() { + return Math.round(Math.random() * 100000000); + }, + + encodeUriObject: function encodeUriObject(obj) { + return encodeURIComponent(JSON.stringify(obj)); + }, + + extractUrlInfo: function extractUrlInfo() { + function f2(callback) { + try { + if (!W.location.ancestorOrigins) return; + for (var i = 0, len = W.location.ancestorOrigins.length; len > i; i++) { + callback.call(null, W.location.ancestorOrigins[i], i); + } + } catch (ignore) { } + return []; + } + + function f1(callback) { + var oneWindow, + infoArray = []; + do { + try { + oneWindow = oneWindow ? oneWindow.parent : W; + callback.call(null, oneWindow, infoArray); + } catch (t) { + infoArray.push({ + referrer: null, + location: null, + isTop: !1 + }); + return infoArray; + } + } while (oneWindow !== W.top); + return infoArray; + } + var allInfo = f1(function (oneWindow, infoArray) { + try { + infoArray.push({ referrer: oneWindow.document.referrer || null, location: oneWindow.location.href || null, isTop: oneWindow === W.top }); + } catch (e) { + infoArray.push({ referrer: null, location: null, isTop: oneWindow === W.top }); + } + }); + f2(function (n, r) { + allInfo[r].ancestor = n; + }); + for (var t = '', e = !1, i = allInfo.length - 1, l = allInfo.length - 1; l >= 0; l--) { + t = allInfo[l].location; + if (!t && l > 0) { + t = allInfo[l - 1].referrer; + if (!t) t = allInfo[l - 1].ancestor; + if (t) { + e = W.location.ancestorOrigins ? !0 : l === allInfo.length - 1 && allInfo[allInfo.length - 1].isTop; + break; + } + } + } return { url: t, isTop: e, depth: i }; + }, + + srTestCapabilities: function srTestCapabilities() { + var plugins = navigator.plugins, + flashVer = -1, + sf = 'Shockwave Flash'; + + if (plugins && plugins.length > 0) { + if (plugins[sf + ' 2.0'] || plugins[sf]) { + var swVer2 = plugins[sf + ' 2.0'] ? ' 2.0' : ''; + var flashDescription = plugins[sf + swVer2].description; + flashVer = flashDescription.split(' ')[2].split('.')[0]; + } + } + if (flashVer > 4) return 15; else return 7; + } + + }; + }()); + + // Ad calling functionality + CMT.Service = (function () { + // Closure variables shared by the service functions + var U = CMT.Util; + + return { + + buildSrc: function buildSrc(tag, env) { + var src = (document.location.protocol === 'https:' ? 'https://' : 'http://') + (!env || env === 'PRD' ? '' : env === 'PPE' ? 'ppe-' : env === 'STG' ? 'staging-' : '') + 'ad.afy11.net/ad' + '?mode=11' + '&ct=' + U.srTestCapabilities() + '&nif=0' + '&sf=0' + '&sfd=0' + '&ynw=0' + '&rand=' + U.getRand() + '&hb=1' + '&rk1=' + U.getRand() + '&rk2=' + new Date().valueOf() / 1000; + + // Make sure we don't have a response object... + delete tag.response; + + // Extracted url info... + var urlInfo = U.extractUrlInfo(); + tag.pageUrl = urlInfo.url; + tag.puTop = urlInfo.isTop; + + // Attach the serialized tag to our string + src += '&ab=' + U.encodeUriObject(tag); + + return src; + }, + + getAd: function (zoneKey) { + if (!zoneKey) return; + + return this._getData(zoneKey, 'ad') + (this._getResponse().tpCookieSync || ''); // ...also append cookie sync if present + }, + + // getSecondPrice: function getSecondPrice(zoneKey) { + // if (zoneKey.substring(0, 2) !== 'as') zoneKey = 'as' + zoneKey; + // var bid = this.getBidTrue(zoneKey), + // floor = this._getData(zoneKey, 'floor'); + + // // If no floor, just set it to 80% of the bid + // if (!floor) floor = bid * 0.80; + + // // Adjust the floor if it's too high...it needs to always be lower + // if (floor >= bid) { + // floor = floor * 0.80; // Take off 20% to account for possible non-adjusted 2nd highest bid + + // // If it's still too high, just take 80% to 90% of the bid + // if (floor >= bid) floor = bid * ((Math.random() * 10) + 80) / 100; + // } + // return Math.round(floor * 100) / 100; + // }, + + // setAuctionPrice: function setAuctionPrice(ad, bid) { + // return ad ? ad.replace('${AUCTION_PRICE}', bid) : ad; + // }, + + getBidTrue: function getBidTrue(zoneKey) { + return Math.round(this._getData(zoneKey, 'price') * 100) / 100; + }, + + _getData: function (zoneKey, field) { + var response = this._getResponse(), + zoneResponseData = response.zones ? response.zones[zoneKey] : {}; + + return (zoneResponseData || {})[field] || null; + }, + + _getResponse: function () { + var tag = W.cdsTag; + return (tag && tag.response) ? tag.response : {}; + }, + }; + }()); + + return CMT; + } + + // Export the callBids function, so that prebid.js can execute this function + // when the page asks to send out bid requests. + return { + callBids: _callBids, + }; +}; + +module.exports = CoxAdapter; diff --git a/test/spec/adapters/cox_spec.js b/test/spec/adapters/cox_spec.js new file mode 100644 index 00000000000..3f1342230db --- /dev/null +++ b/test/spec/adapters/cox_spec.js @@ -0,0 +1,121 @@ +import Adapter from 'src/adapters/cox'; +import bidManager from 'src/bidmanager'; +import adLoader from 'src/adloader'; +import utils from 'src/utils'; +import {expect} from 'chai'; + +describe('CoxAdapter', () => { + let adapter; + let loadScriptStub; + let addBidResponseSpy; + + let emitScript = (script) => { + let node = document.createElement('script'); + node.type = 'text/javascript'; + node.appendChild(document.createTextNode(script)); + document.getElementsByTagName('head')[0].appendChild(node); + }; + + beforeEach(() => { + adapter = new Adapter(); + addBidResponseSpy = sinon.spy(bidManager, 'addBidResponse'); + }); + + afterEach(() => { + loadScriptStub.restore(); + addBidResponseSpy.restore(); + }); + + describe('response handling', () => { + const normalResponse = 'cdsTag.__callback__({"zones":{"as2000005991707":{"ad" : "

FOO<\/h1>","uid" : "","price" : 1.51,"floor" : 0,}},"tpCookieSync":"

FOOKIE<\/h1>"})'; + const zeroPriceResponse = 'cdsTag.__callback__({"zones":{"as2000005991707":{"ad" : "

DEFAULT FOO<\/h1>","uid" : "","price" : 0,"floor" : 0,}},"tpCookieSync":"

FOOKIE<\/h1>"})'; + const incompleteResponse = 'cdsTag.__callback__({"zones":{},"tpCookieSync":"

FOOKIE<\/h1>"})'; + + const oneBidConfig = { + bidderCode: 'cox', + bids: [{ + bidder: 'cox', + placementCode: 'FOO456789', + sizes: [300, 250], + params: { size: '300x250', id: 2000005991707, siteId: 2000100948180, env: 'PROD' }, + }] + }; + + // ===== 1 + it('should provide a correctly populated Bid given a valid response', () => { + loadScriptStub = sinon.stub(adLoader, 'loadScript', () => { emitScript(normalResponse); }) + + adapter.callBids(oneBidConfig); + + let bid = addBidResponseSpy.args[0][1]; + expect(bid.cpm).to.equal(1.51); + expect(bid.ad).to.be.a('string'); + expect(bid.bidderCode).to.equal('cox'); + }); + + // ===== 2 + it('should provide an empty Bid given a zero-price response', () => { + loadScriptStub = sinon.stub(adLoader, 'loadScript', () => { emitScript(zeroPriceResponse); }) + + adapter.callBids(oneBidConfig); + + let bid = addBidResponseSpy.args[0][1]; + expect(bid.cpm).to.not.be.ok + expect(bid.ad).to.not.be.ok; + }); + + // ===== 3 + it('should provide an empty Bid given an incomplete response', () => { + loadScriptStub = sinon.stub(adLoader, 'loadScript', () => { emitScript(incompleteResponse); }) + + adapter.callBids(oneBidConfig); + + let bid = addBidResponseSpy.args[0][1]; + expect(bid.cpm).to.not.be.ok + expect(bid.ad).to.not.be.ok; + }); + + // ===== 4 + it('should not provide a Bid given no response', () => { + loadScriptStub = sinon.stub(adLoader, 'loadScript', () => { emitScript(''); }); + + adapter.callBids(oneBidConfig); + + expect(addBidResponseSpy.callCount).to.equal(0); + }); + }); + + describe('request generation', () => { + const missingBidsConfig = { + bidderCode: 'cox', + bids: null, + }; + const missingParamsConfig = { + bidderCode: 'cox', + bids: [{ + bidder: 'cox', + placementCode: 'FOO456789', + sizes: [300, 250], + params: null, + }] + }; + + // ===== 5 + it('should not make an ad call given missing bids in config', () => { + loadScriptStub = sinon.stub(adLoader, 'loadScript'); + + adapter.callBids(missingBidsConfig); + + expect(loadScriptStub.callCount).to.equal(0); + }); + + // ===== 6 + it('should not make an ad call given missing params in config', () => { + loadScriptStub = sinon.stub(adLoader, 'loadScript'); + + adapter.callBids(missingParamsConfig); + + expect(loadScriptStub.callCount).to.equal(0); + }); + }); +}); From 7cb6ce84c2125e520a95153c407497e564c379c2 Mon Sep 17 00:00:00 2001 From: Dmitriy Shashkin Date: Wed, 14 Jun 2017 17:51:08 +0300 Subject: [PATCH 27/95] Generate no-bid response for ech bid request not matched by a bid (#1216) --- src/adapters/prebidServer.js | 41 +++++++++------------ test/spec/adapters/prebidServer_spec.js | 49 ++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/adapters/prebidServer.js b/src/adapters/prebidServer.js index e229da9b33f..5dc78008060 100644 --- a/src/adapters/prebidServer.js +++ b/src/adapters/prebidServer.js @@ -108,34 +108,12 @@ function PrebidServer() { if (result.status === 'OK') { if (result.bidder_status) { result.bidder_status.forEach(bidder => { - if (bidder.no_bid || bidder.no_cookie) { - // store a "No Bid" bid response - - if (!bidder.ad_unit) { - utils.getBidderRequestAllAdUnits(bidder.bidder).bids.forEach(bid => { - let bidObject = bidfactory.createBid(STATUS.NO_BID, bid); - bidObject.adUnitCode = bid.placementCode; - bidObject.bidderCode = bidder.bidder; - - bidmanager.addBidResponse(bid.placementCode, bidObject); - }); - } else { - let bidObject = bidfactory.createBid(STATUS.NO_BID, { - bidId: bidder.bid_id - }); - - bidObject.adUnitCode = bidder.ad_unit; - bidObject.bidderCode = bidder.bidder; - - bidmanager.addBidResponse(bidObject.adUnitCode, bidObject); - } - } if (bidder.no_cookie) { - // if no cookie is present then no bids were made, we don't store a bid response queueSync({bidder: bidder.bidder, url: bidder.usersync.url, type: bidder.usersync.type}); } }); } + if (result.bids) { result.bids.forEach(bidObj => { let bidRequest = utils.getBidRequest(bidObj.bid_id); @@ -161,6 +139,23 @@ function PrebidServer() { bidmanager.addBidResponse(bidObj.code, bidObject); }); } + + const receivedBidIds = result.bids ? result.bids.map(bidObj => bidObj.bid_id) : []; + + // issue a no-bid response for every bid request that can not be matched with received bids + config.bidders.forEach(bidder => { + utils + .getBidderRequestAllAdUnits(bidder) + .bids.filter(bidRequest => !receivedBidIds.includes(bidRequest.bidId)) + .forEach(bidRequest => { + let bidObject = bidfactory.createBid(STATUS.NO_BID, bidRequest); + + bidObject.adUnitCode = bidRequest.placementCode; + bidObject.bidderCode = bidRequest.bidder; + + bidmanager.addBidResponse(bidObject.adUnitCode, bidObject); + }); + }); } else if (result.status === 'no_cookie') { // cookie sync diff --git a/test/spec/adapters/prebidServer_spec.js b/test/spec/adapters/prebidServer_spec.js index abc3525a8f4..fe1cb7e9894 100644 --- a/test/spec/adapters/prebidServer_spec.js +++ b/test/spec/adapters/prebidServer_spec.js @@ -144,16 +144,20 @@ describe('S2S Adapter', () => { sinon.stub(bidmanager, 'addBidResponse'); sinon.stub(utils, 'getBidderRequestAllAdUnits').returns({ bids: [{ - bidId: '32167', + bidId: '123', placementCode: 'div-gpt-ad-1460505748561-0' }] }); + sinon.stub(utils, 'getBidRequest').returns({ + bidId: '123' + }); }); afterEach(() => { server.restore(); bidmanager.addBidResponse.restore(); utils.getBidderRequestAllAdUnits.restore(); + utils.getBidRequest.restore(); }); it('registers bids', () => { @@ -167,9 +171,10 @@ describe('S2S Adapter', () => { const response = bidmanager.addBidResponse.firstCall.args[1]; expect(response).to.have.property('statusMessage', 'Bid available'); expect(response).to.have.property('cpm', 0.5); + expect(response).to.have.property('adId', '123'); }); - it('registers no bid response when ad unit not set', () => { + it('registers no-bid response when ad unit not set', () => { server.respondWith(JSON.stringify(RESPONSE_NO_BID_NO_UNIT)); adapter.setConfig(CONFIG); @@ -184,10 +189,10 @@ describe('S2S Adapter', () => { expect(response).to.have.property('statusMessage', 'Bid returned empty or error response'); const bid_request_passed = bidmanager.addBidResponse.firstCall.args[1]; - expect(bid_request_passed).to.have.property('adId', '32167'); + expect(bid_request_passed).to.have.property('adId', '123'); }); - it('registers no bid response when server requests cookie sync', () => { + it('registers no-bid response when server requests cookie sync', () => { server.respondWith(JSON.stringify(RESPONSE_NO_COOKIE)); adapter.setConfig(CONFIG); @@ -202,10 +207,10 @@ describe('S2S Adapter', () => { expect(response).to.have.property('statusMessage', 'Bid returned empty or error response'); const bid_request_passed = bidmanager.addBidResponse.firstCall.args[1]; - expect(bid_request_passed).to.have.property('adId', '32167'); + expect(bid_request_passed).to.have.property('adId', '123'); }); - it('registers no bid response when ad unit is set', () => { + it('registers no-bid response when ad unit is set', () => { server.respondWith(JSON.stringify(RESPONSE_NO_BID_UNIT_SET)); adapter.setConfig(CONFIG); @@ -220,6 +225,38 @@ describe('S2S Adapter', () => { expect(response).to.have.property('statusMessage', 'Bid returned empty or error response'); }); + it('registers no-bid response when there are less bids than requests', () => { + utils.getBidderRequestAllAdUnits.restore(); + sinon.stub(utils, 'getBidderRequestAllAdUnits').returns({ + bids: [{ + bidId: '123', + placementCode: 'div-gpt-ad-1460505748561-0' + }, { + bidId: '101111', + placementCode: 'div-gpt-ad-1460505748561-1' + }] + }); + + server.respondWith(JSON.stringify(RESPONSE)); + + adapter.setConfig(CONFIG); + adapter.callBids(REQUEST); + server.respond(); + + sinon.assert.calledTwice(bidmanager.addBidResponse); + + expect(bidmanager.addBidResponse.firstCall.args[0]).to.equal('div-gpt-ad-1460505748561-0'); + expect(bidmanager.addBidResponse.secondCall.args[0]).to.equal('div-gpt-ad-1460505748561-1'); + + expect(bidmanager.addBidResponse.firstCall.args[1]).to.have.property('adId', '123'); + expect(bidmanager.addBidResponse.secondCall.args[1]).to.have.property('adId', '101111'); + + expect(bidmanager.addBidResponse.firstCall.args[1]) + .to.have.property('statusMessage', 'Bid available'); + expect(bidmanager.addBidResponse.secondCall.args[1]) + .to.have.property('statusMessage', 'Bid returned empty or error response'); + }); + it('should have dealId in bidObject', () => { server.respondWith(JSON.stringify(RESPONSE)); From c8bbc235541351a067c2768914079e8b949dddda Mon Sep 17 00:00:00 2001 From: Matt Lane Date: Wed, 14 Jun 2017 10:11:53 -0700 Subject: [PATCH 28/95] Use Renderer command queue to render outstream (#1283) * Use Renderer command queue to render outstream * Abstract automatic processing in renderer --- src/Renderer.js | 42 ++++++++++++++++++++++++++++++++----- src/adapters/appnexusAst.js | 26 +++++++++++------------ test/spec/renderer_spec.js | 35 +++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 19 deletions(-) diff --git a/src/Renderer.js b/src/Renderer.js index c4e926ca4d5..c81049fa1f6 100644 --- a/src/Renderer.js +++ b/src/Renderer.js @@ -2,19 +2,37 @@ import { loadScript } from 'src/adloader'; import * as utils from 'src/utils'; export function Renderer(options) { - const { url, config, id, callback } = options; + const { url, config, id, callback, loaded } = options; this.url = url; this.config = config; - this.callback = callback; this.handlers = {}; this.id = id; + // a renderer may push to the command queue to delay rendering until the + // render function is loaded by loadScript, at which point the the command + // queue will be processed + this.loaded = loaded; + this.cmd = []; + this.push = func => { + if (typeof func !== 'function') { + utils.logError('Commands given to Renderer.push must be wrapped in a function'); + return; + } + this.loaded ? func.call() : this.cmd.push(func); + }; + + // bidders may override this with the `callback` property given to `install` + this.callback = callback || (() => { + this.loaded = true; + this.process(); + }); + // we expect to load a renderer url once only so cache the request to load script - loadScript(url, callback, true); + loadScript(url, this.callback, true); } -Renderer.install = function({ url, config, id, callback }) { - return new Renderer({ url, config, id, callback }); +Renderer.install = function({ url, config, id, callback, loaded }) { + return new Renderer({ url, config, id, callback, loaded }); }; Renderer.prototype.getConfig = function() { @@ -36,3 +54,17 @@ Renderer.prototype.handleVideoEvent = function({ id, eventName }) { utils.logMessage(`Prebid Renderer event for id ${id} type ${eventName}`); }; + +/* + * Calls functions that were pushed to the command queue before the + * renderer was loaded by `loadScript` + */ +Renderer.prototype.process = function() { + while (this.cmd.length > 0) { + try { + this.cmd.shift().call(); + } catch (error) { + utils.logError('Error processing Renderer command: ', error); + } + } +}; diff --git a/src/adapters/appnexusAst.js b/src/adapters/appnexusAst.js index a3bd0e72441..4ad2fe4502c 100644 --- a/src/adapters/appnexusAst.js +++ b/src/adapters/appnexusAst.js @@ -269,18 +269,17 @@ function AppnexusAstAdapter() { } function outstreamRender(bid) { - window.ANOutstreamVideo.renderAd({ - tagId: bid.adResponse.tag_id, - sizes: [bid.getSize().split('x')], - targetId: bid.adUnitCode, // target div id to render video - uuid: bid.adResponse.uuid, - adResponse: bid.adResponse, - rendererOptions: bid.renderer.getConfig() - }, handleOutstreamRendererEvents.bind(bid)); - } - - function onOutstreamRendererLoaded() { - // setup code for renderer, if any + // push to render queue because ANOutstreamVideo may not be loaded yet + bid.renderer.push(() => { + window.ANOutstreamVideo.renderAd({ + tagId: bid.adResponse.tag_id, + sizes: [bid.getSize().split('x')], + targetId: bid.adUnitCode, // target div id to render video + uuid: bid.adResponse.uuid, + adResponse: bid.adResponse, + rendererOptions: bid.renderer.getConfig() + }, handleOutstreamRendererEvents.bind(bid)); + }); } function handleOutstreamRendererEvents(id, eventName) { @@ -313,9 +312,8 @@ function AppnexusAstAdapter() { id: ad.renderer_id, url: ad.renderer_url, config: { adText: `AppNexus Outstream Video Ad via Prebid.js` }, - callback: () => onOutstreamRendererLoaded.call(null, bid) + loaded: false, }); - try { bid.renderer.setRender(outstreamRender); } catch (err) { diff --git a/test/spec/renderer_spec.js b/test/spec/renderer_spec.js index ba60923ed2a..282c4841ac0 100644 --- a/test/spec/renderer_spec.js +++ b/test/spec/renderer_spec.js @@ -53,4 +53,39 @@ describe('Renderer: A renderer installed on a bid response', () => { testRenderer1.handleVideoEvent({ id: 1, eventName: 'testEvent' }); expect(spyEventHandler.called).to.equal(true); }); + + it('pushes commands to queue if renderer is not loaded', () => { + testRenderer1.push(spyRenderFn); + + expect(testRenderer1.cmd.length).to.equal(1); + + // clear queue for next tests + testRenderer1.cmd = []; + }); + + it('fires commands immediately if the renderer is loaded', () => { + const func = sinon.spy(); + + testRenderer1.loaded = true; + testRenderer1.push(func); + + expect(testRenderer1.cmd.length).to.equal(0); + sinon.assert.calledOnce(func); + }); + + it('processes queue by calling each function in queue', () => { + testRenderer1.loaded = false; + const func1 = sinon.spy(); + const func2 = sinon.spy(); + + testRenderer1.push(func1); + testRenderer1.push(func2); + expect(testRenderer1.cmd.length).to.equal(2); + + testRenderer1.process(); + + sinon.assert.calledOnce(func1); + sinon.assert.calledOnce(func2); + expect(testRenderer1.cmd.length).to.equal(0); + }); }); From c47b01d51dbd93c6ff5ca5acd498c9bf4dd45b51 Mon Sep 17 00:00:00 2001 From: Seba Perez Date: Wed, 14 Jun 2017 16:23:37 -0300 Subject: [PATCH 29/95] Add eplanning adapter (#1245) * Added eplanning adapter * Added protocol by default --- adapters.json | 1 + src/adapters/eplanning.js | 280 +++++++++++++++++++++++++++ test/spec/adapters/eplanning_spec.js | 112 +++++++++++ 3 files changed, 393 insertions(+) create mode 100644 src/adapters/eplanning.js create mode 100644 test/spec/adapters/eplanning_spec.js diff --git a/adapters.json b/adapters.json index 704bb0bd388..71dc5fbb0a2 100644 --- a/adapters.json +++ b/adapters.json @@ -68,6 +68,7 @@ "atomx", "tapsense", "trion", + "eplanning", "prebidServer", "adsupply", "cox", diff --git a/src/adapters/eplanning.js b/src/adapters/eplanning.js new file mode 100644 index 00000000000..fd4acc0e047 --- /dev/null +++ b/src/adapters/eplanning.js @@ -0,0 +1,280 @@ +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); + +var EPlanningAdapter = function EPlanningAdapter() { + (function() { + var win = window, doc = win.document, pbjs = win.pbjs, _global = {}, _default = { 'sv': 'ads.us.e-planning.net', 't': 0 }, rnd, FILE = 'file', CALLBACK_FUNCTION = 'hbpb.rH', NULL_SIZE = '1x1', _csRequested = [], PROTO = location.protocol === 'https:' ? 'https:' : 'http:', ISV = 'aklc.img.e-planning.net'; + function Hbpb() { + var slots = (function() { + var _data = []; + function Slot(slotId) { + var data = _data[slotId]; + function hasAds() { + return _data[slotId].ads.length; + } + function getSizes() { + return data.sizes; + } + function getSizesString() { + var s = [], i, sizes = getSizes(); + if (sizes && sizes.length) { + if (typeof sizes[0] === 'object') { + for (i = 0; i < sizes.length; i++) { + s.push(sizes[i][0] + 'x' + sizes[i][1]); + } + } else { + s.push(sizes[0] + 'x' + sizes[1]); + } + } else { + return NULL_SIZE; + } + return s.join(','); + } + return { + getPlacementCode: function() { + return data.placementCode; + }, + getString: function() { + return this.getPlacementCode() + ':' + getSizesString(); + }, + addAd: function(ad) { + _data[slotId].ads.push(ad); + }, + getFormatedResponse: function() { + var ad, that = this; + if (hasAds()) { + ad = data.ads[0]; + return { + 'placementCode': that.getPlacementCode(), + 'ad': { + 'ad': ad.adm, + 'cpm': ad.pr, + 'width': ad.size.w, + 'height': ad.size.h + } + }; + } else { + return { 'placementCode': that.getPlacementCode() }; + } + } + }; + } + function findAll() { + var i = 0, r = []; + for (i = 0; i < _data.length; i++) { + r.push(new Slot(i)); + } + return r; + } + return { + add: function(slot) { + slot.ads = []; + _data.push(slot); + }, + get: function(slotId) { + return new Slot(slotId); + }, + getString: function() { + var _slots = [], i, slot; + for (i = 0; i < _data.length; i++) { + slot = this.get(i); + _slots.push(slot.getString()); + } + return _slots.join('+'); + }, + findByPlacementCode: function(placementCode) { + var i, _slots = findAll(); + for (i = 0; i < _slots.length; i++) { + if (_slots[i].getPlacementCode() === placementCode) { + return _slots[i]; + } + } + }, + getFormatedResponse: function() { + var _slots = findAll(), i, r = []; + for (i = 0; i < _slots.length; i++) { + r.push(_slots[i].getFormatedResponse()); + } + return { + 'bids': r + }; + } + }; + })(); + function call(params) { + var i, bids = params.bids; + for (i = 0; i < bids.length; i++) { + slots.add({ + _raw: bids[i], + placementCode: bids[i].placementCode, + sizes: bids[i].sizes + }); + setGlobalParam('sv', bids[i]); + setGlobalParam('ci', bids[i]); + setGlobalParam('t', bids[i]); + } + doRequest(); + } + function setGlobalParam(param, bid) { + if (!_global[param]) { + if (bid && bid.params && bid.params[param]) { + _global[param] = bid.params[param]; + } + } + } + function getGlobalParam(param) { + return (_global[param] || _default[param]); + } + function getRandom() { + if (!rnd) { + rnd = Math.random(); + } + return rnd; + } + function getDocURL() { + return escape(win.location.href || FILE); + } + function getReferrerURL() { + return doc.referrer; + } + function getCallbackFunction() { + return CALLBACK_FUNCTION; + } + function doRequest() { + var clienteId = getGlobalParam('ci'), url, dfpClienteId = '1', sec = 'ROS', params = [], t = getGlobalParam('t'); + if (clienteId && !t) { + url = PROTO + '//' + getGlobalParam('sv') + '/hb/1/' + clienteId + '/' + dfpClienteId + '/' + (win.location.hostname || FILE) + '/' + sec + '?'; + params.push('rnd=' + getRandom()); + params.push('e=' + slots.getString()); + if (getDocURL()) { + params.push('ur=' + getDocURL()); + } + if (getReferrerURL()) { + params.push('fr=' + getReferrerURL()); + } + params.push('cb=' + getCallbackFunction()); + params.push('r=pbjs'); + url += params.join('&'); + load(url); + } else if (t) { + url = PROTO + '//' + ISV + '/layers/t_pbjs_' + t + '.js'; + load(url); + } + } + function load(url) { + var script = doc.createElement('script'); + script.src = url; + doc.body.appendChild(script); + } + function callback(response) { + if (pbjs && pbjs.processEPlanningResponse && typeof pbjs.processEPlanningResponse === 'function') { + pbjs.processEPlanningResponse(response); + } + } + function syncUsers(cs) { + var i, e, d; + for (i = 0; i < cs.length; i++) { + if (typeof cs[i] === 'string' && _csRequested.indexOf(cs[i]) === -1) { + (new Image()).src = cs[i]; + _csRequested.push(cs[i]); + } else if (typeof cs[i] === 'object' && _csRequested.indexOf(cs[i].u) === -1) { + if (cs[i].j) { + e = doc.createElement('script'); + e.src = cs[i].u; + } else if (cs[i].ifr) { + e = doc.createElement('iframe'); + e.src = cs[i].u; + e.style.width = e.style.height = '1px'; + e.display = 'none'; + } + if (cs[i].data) { + for (d in cs[i].data) { + if (cs[i].data.hasOwnProperty(d)) { + e.setAttribute('data-' + d, cs[i].data[d]); + } + } + } + doc.body.appendChild(e); + _csRequested.push(cs[i].u); + } + } + } + function rH(response) { + var slot, i, o; + if (response && response.sp && response.sp.length) { + for (i = 0; i < response.sp.length; i++) { + if (response.sp[i].a) { + slot = slots.findByPlacementCode(response.sp[i].k); + if (slot) { + for (o = 0; o < response.sp[i].a.length; o++) { + slot.addAd({ + 'adm': response.sp[i].a[o].adm, + 'pr': response.sp[i].a[o].pr, + 'size': { + 'w': response.sp[i].a[o].w, + 'h': response.sp[i].a[o].h + } + }); + } + } + } + } + callback(slots.getFormatedResponse()); + } + if (response && response.cs && response.cs.length) { + syncUsers(response.cs); + } + } + return { + call: function(params) { + return call(params); + }, + rH: function(response) { + return rH(response); + } + }; + } + win.hbpb = win.hbpb || new Hbpb(); + })(); + + window.pbjs = window.pbjs || {}; + window.pbjs.processEPlanningResponse = function(response) { + var bids, bidObject, i; + if (response) { + bids = response.bids; + for (i = 0; i < bids.length; i++) { + if (bids[i].ad) { + bidObject = getBidObject(bids[i]); + bidmanager.addBidResponse(bids[i].placementCode, bidObject); + } else { + bidObject = bidfactory.createBid(2); + bidObject.bidderCode = 'eplanning'; + bidmanager.addBidResponse(bids[i].placementCode, bidObject); + } + } + } + }; + + function getBidObject(bid) { + var bidObject = bidfactory.createBid(1), i; + bidObject.bidderCode = 'eplanning'; + for (i in bid.ad) { + if (bid.ad.hasOwnProperty(i)) { + bidObject[i] = bid.ad[i]; + } + } + return bidObject; + } + + function _callBids(params) { + if (window.hbpb) { + window.hbpb.call(params); + } + } + + return { + callBids: _callBids + }; +}; + +module.exports = EPlanningAdapter; diff --git a/test/spec/adapters/eplanning_spec.js b/test/spec/adapters/eplanning_spec.js new file mode 100644 index 00000000000..668392c169b --- /dev/null +++ b/test/spec/adapters/eplanning_spec.js @@ -0,0 +1,112 @@ +describe('eplanning adapter tests', function () { + var urlParse = require('url-parse'); + var querystringify = require('querystringify'); + var adapter = require('src/adapters/eplanning'); + var adLoader = require('src/adloader'); + var expect = require('chai').expect; + var bidmanager = require('src/bidmanager'); + var CONSTANTS = require('src/constants.json'); + + var DEFAULT_PARAMS = { + bidderCode: 'eplanning', + bids: [{ + code: 'div-gpt-ad-1460505748561-0', + sizes: [[300, 250], [300, 200]], + bidder: 'eplanning', + params: { + ci: '18f66' + } + }] + }; + + var PARAMS_SERVER_TEST = { + bidderCode: 'eplanning', + bids: [{ + code: 'div-gpt-ad-1460505748561-0', + sizes: [[300, 250], [300, 600]], + bidder: 'eplanning', + params: { + ci: '18f66', + t: '1' + } + }] + }; + + var RESPONSE_AD = { + bids: [{ + placementCode: 'div-gpt-ad-1460505748561-0', + ad: { + ad: '

test ad

', + cpm: 1, + width: 300, + height: 250 + } + }] + }; + + var RESPONSE_EMPTY = { + bids: [{ + placementCode: 'div-gpt-ad-1460505748561-0' + }] + }; + + var stubAddBidResponse; + + describe('eplanning tests', function() { + beforeEach(function() { + stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); + }); + afterEach(function() { + stubAddBidResponse.restore(); + }); + + it('callback function should exist', function() { + expect(pbjs.processEPlanningResponse).to.exist.and.to.be.a('function'); + }); + + it('creates a bid response if bid exists', function() { + adapter().callBids(DEFAULT_PARAMS); + pbjs.processEPlanningResponse(RESPONSE_AD); + + var bidPlacementCode = stubAddBidResponse.getCall(0).args[0]; + var bidObject = stubAddBidResponse.getCall(0).args[1]; + + expect(bidPlacementCode).to.equal('div-gpt-ad-1460505748561-0'); + expect(bidObject.cpm).to.equal(1); + expect(bidObject.ad).to.equal('

test ad

'); + expect(bidObject.width).to.equal(300); + expect(bidObject.height).to.equal(250); + expect(bidObject.getStatusCode()).to.equal(1); + expect(bidObject.bidderCode).to.equal('eplanning'); + }); + + it('creates an empty bid response if there is no bid', function() { + adapter().callBids(DEFAULT_PARAMS); + pbjs.processEPlanningResponse(RESPONSE_EMPTY); + + var bidPlacementCode = stubAddBidResponse.getCall(0).args[0]; + var bidObject = stubAddBidResponse.getCall(0).args[1]; + + expect(bidPlacementCode).to.equal('div-gpt-ad-1460505748561-0'); + expect(bidObject.getStatusCode()).to.equal(2); + expect(bidObject.bidderCode).to.equal('eplanning'); + }); + + it('creates a bid response and sync users register ad', function() { + adapter().callBids(DEFAULT_PARAMS); + window.hbpb.rH({ + 'sI': { 'k': '18f66' }, + 'sec': { 'k': 'ROS' }, + 'sp': [ { 'k': 'div-gpt-ad-1460505748561-0', 'a': [{ 'w': 300, 'h': 250, 'adm': '

test ad

', 'pr': 1 }] } ], + 'cs': [ + '//test.gif', + { 'j': true, u: '//test.js' }, + { 'ifr': true, u: '//test.html', data: { 'test': 1 } } + ] + }); + var bidPlacementCode = stubAddBidResponse.getCall(0).args[0]; + var bidObject = stubAddBidResponse.getCall(0).args[1]; + expect(bidObject.getStatusCode()).to.equal(2); + }); + }); +}); From ebe79057e243b6ba83eb09bfd10745dd3d1effa4 Mon Sep 17 00:00:00 2001 From: Matt Kendall Date: Wed, 14 Jun 2017 15:39:41 -0400 Subject: [PATCH 30/95] fix protocol detection in iframe (#1293) --- src/adapters/appnexus.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/adapters/appnexus.js b/src/adapters/appnexus.js index 0dea42daf41..fee88da7bf3 100644 --- a/src/adapters/appnexus.js +++ b/src/adapters/appnexus.js @@ -43,10 +43,7 @@ AppNexusAdapter = function AppNexusAdapter() { var query = utils.getBidIdParameter('query', bid.params); var referrer = utils.getBidIdParameter('referrer', bid.params); var altReferrer = utils.getBidIdParameter('alt_referrer', bid.params); - - // build our base tag, based on if we are http or https - - var jptCall = 'http' + (document.location.protocol === 'https:' ? 's://secure.adnxs.com/jpt?' : '://ib.adnxs.com/jpt?'); + var jptCall = '//ib.adnxs.com/jpt?'; jptCall = utils.tryAppendQueryString(jptCall, 'callback', '$$PREBID_GLOBAL$$.handleAnCB'); jptCall = utils.tryAppendQueryString(jptCall, 'callback_uid', callbackId); From b9973524f03b717744965cea0500f4fdd5359750 Mon Sep 17 00:00:00 2001 From: Matt Kendall Date: Wed, 14 Jun 2017 15:40:29 -0400 Subject: [PATCH 31/95] hide overflow to prevent scrolling (#1294) --- src/prebid.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/prebid.js b/src/prebid.js index 3f5ae70f6e9..66f4889a506 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -344,6 +344,7 @@ $$PREBID_GLOBAL$$.renderAd = function (doc, id) { iframe.height = height; iframe.width = width; iframe.style.display = 'inline'; + iframe.style.overflow = 'hidden'; iframe.src = url; utils.insertElement(iframe, doc, 'body'); From a1399f0aa54f04927c7b2e1ad35687d248133bc1 Mon Sep 17 00:00:00 2001 From: dbemiller Date: Thu, 15 Jun 2017 10:04:41 -0400 Subject: [PATCH 32/95] Fixing Adyoulike adapter for Safari iOS7 (#1296) * Added a try/catch block around the troublesome code. * Defaulted to false, to make the unit tests pass. --- src/adapters/adyoulike.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/adapters/adyoulike.js b/src/adapters/adyoulike.js index 3968de6ce8f..7ee65eebe06 100644 --- a/src/adapters/adyoulike.js +++ b/src/adapters/adyoulike.js @@ -66,8 +66,17 @@ var AdyoulikeAdapter = function AdyoulikeAdapter() { Placements: placements, }; - if (performance && performance.navigation) { - body.PageRefreshed = performance.navigation.type === performance.navigation.TYPE_RELOAD; + // performance isn't supported by mobile safari iOS7. window.performance works, but + // evaluates to true on a unit test which expects false. + // + // try/catch was added to un-block the Prebid 0.25 release, but the adyoulike adapter + // maintainers should revisit this and see if it's really what they want. + try { + if (performance && performance.navigation) { + body.PageRefreshed = performance.navigation.type === performance.navigation.TYPE_RELOAD; + } + } catch (e) { + body.PageRefreshed = false; } return JSON.stringify(body); From a31864253e7d4edf4c4948d77e835de3e36b72c9 Mon Sep 17 00:00:00 2001 From: Unruly Developers Date: Thu, 15 Jun 2017 16:34:45 +0000 Subject: [PATCH 33/95] Added Unruly adapter (#1264) --- src/adapters/unruly.js | 108 ++++++++++++ test/spec/adapters/unruly_spec.js | 278 ++++++++++++++++++++++++++++++ 2 files changed, 386 insertions(+) create mode 100644 src/adapters/unruly.js create mode 100644 test/spec/adapters/unruly_spec.js diff --git a/src/adapters/unruly.js b/src/adapters/unruly.js new file mode 100644 index 00000000000..c9fbfde1ecc --- /dev/null +++ b/src/adapters/unruly.js @@ -0,0 +1,108 @@ +import { ajax } from 'src/ajax' +import bidfactory from 'src/bidfactory' +import bidmanager from 'src/bidmanager' +import * as utils from 'src/utils' +import { STATUS } from 'src/constants' +import { Renderer } from 'src/Renderer' + +function createRenderHandler({ bidResponseBid, rendererConfig }) { + function createApi() { + parent.window.unruly.native.prebid = parent.window.unruly.native.prebid || {} + parent.window.unruly.native.prebid.uq = parent.window.unruly.native.prebid.uq || [] + + return { + render(bidResponseBid) { + parent.window.unruly.native.prebid.uq.push(['render', bidResponseBid]) + }, + onLoaded(bidResponseBid) {} + } + } + + parent.window.unruly = parent.window.unruly || {} + parent.window.unruly.native = parent.window.unruly.native || {} + parent.window.unruly.native.siteId = parent.window.unruly.native.siteId || rendererConfig.siteId + + const api = createApi() + return { + render() { + api.render(bidResponseBid) + }, + onRendererLoad() { + api.onLoaded(bidResponseBid) + } + } +} + +function createBidResponseHandler(bidRequestBids) { + return { + onBidResponse(responseBody) { + try { + const exchangeResponse = JSON.parse(responseBody) + exchangeResponse.bids.forEach((exchangeBid) => { + const bidResponseBid = bidfactory.createBid(exchangeBid.ext.statusCode, exchangeBid) + + Object.assign( + bidResponseBid, + exchangeBid + ) + + if (exchangeBid.ext.renderer) { + const rendererParams = exchangeBid.ext.renderer + const renderHandler = createRenderHandler({ + bidResponseBid, + rendererConfig: rendererParams.config + }) + + bidResponseBid.renderer = Renderer.install( + Object.assign( + {}, + rendererParams, + { callback: () => renderHandler.onRendererLoad() } + ) + ) + bidResponseBid.renderer.setRender(() => renderHandler.render()) + } + + bidmanager.addBidResponse(exchangeBid.ext.placementCode, bidResponseBid) + }) + } catch (error) { + utils.logError(error); + bidRequestBids.forEach(bidRequestBid => { + const bidResponseBid = bidfactory.createBid(STATUS.NO_BID) + bidmanager.addBidResponse(bidRequestBid.placementCode, bidResponseBid) + }) + } + } + } +} + +function createUnrulyAdapter() { + const adapter = { + exchangeUrl: 'https://targeting.unrulymedia.com/prebid', + callBids({ bids: bidRequestBids }) { + if (!bidRequestBids || bidRequestBids.length === 0) { + return + } + + const payload = { + bidRequests: bidRequestBids + } + + const bidResponseHandler = createBidResponseHandler(bidRequestBids) + + ajax( + adapter.exchangeUrl, + bidResponseHandler.onBidResponse, + JSON.stringify(payload), + { + contentType: 'application/json', + withCredentials: true + } + ) + } + } + + return adapter +} + +module.exports = createUnrulyAdapter diff --git a/test/spec/adapters/unruly_spec.js b/test/spec/adapters/unruly_spec.js new file mode 100644 index 00000000000..de0aa683bc9 --- /dev/null +++ b/test/spec/adapters/unruly_spec.js @@ -0,0 +1,278 @@ +/* globals describe, it, beforeEach, afterEach, sinon */ +import { expect } from 'chai' +import bidfactory from 'src/bidfactory' +import bidmanager from 'src/bidmanager' +import * as utils from 'src/utils' +import { STATUS } from 'src/constants' +import { Renderer } from 'src/Renderer' +import createUnrulyAdapter from 'src/adapters/unruly' + +describe('UnrulyAdapter', () => { + function createBidRequestBid({ placementCode }) { + return { + 'bidder': 'unruly', + 'params': { + 'uuid': '74544e00-d43b-4f3a-a799-69d22ce979ce', + 'siteId': 794599, + 'placementId': '5768085' + }, + 'placementCode': placementCode, + 'mediaType': 'video', + 'transactionId': '62890707-3770-497c-a3b8-d905a2d0cb98', + 'sizes': [ + 640, + 480 + ], + 'bidId': '23b86d8f6335ce', + 'bidderRequestId': '1d5b7474eb5416', + 'requestId': '406fe12b-fa3b-4bd3-b3c8-043951b4dac1' + } + } + + function createParams(...bids) { + return { + 'bidderCode': 'unruly', + 'requestId': '406fe12b-fa3b-4bd3-b3c8-043951b4dac1', + 'bidderRequestId': '1d5b7474eb5416', + 'bids': bids, + 'start': 1495794517251, + 'auctionStart': 1495794517250, + 'timeout': 3000 + } + } + + function createOutStreamExchangeBid({ placementCode, statusCode = 1 }) { + return { + 'ext': { + 'statusCode': statusCode, + 'renderer': { + 'id': 'unruly_inarticle', + 'config': {}, + 'url': 'https://video.unrulymedia.com/native/prebid-loader.js' + }, + 'placementCode': placementCode + }, + 'cpm': 20, + 'bidderCode': 'unruly', + 'width': 323, + 'vastUrl': 'https://targeting.unrulymedia.com/in_article?uuid=74544e00-d43b-4f3a-a799-69d22ce979ce&supported_mime_type=application/javascript&supported_mime_type=video/mp4&tj=%7B%22site%22%3A%7B%22lang%22%3A%22en-GB%22%2C%22ref%22%3A%22%22%2C%22page%22%3A%22http%3A%2F%2Fdemo.unrulymedia.com%2FinArticle%2Finarticle_nypost_upbeat%2Ftravel_magazines.html%22%2C%22domain%22%3A%22demo.unrulymedia.com%22%7D%2C%22user%22%3A%7B%22profile%22%3A%7B%22quantcast%22%3A%7B%22segments%22%3A%5B%7B%22id%22%3A%22D%22%7D%2C%7B%22id%22%3A%22T%22%7D%5D%7D%7D%7D%7D&video_width=618&video_height=347', + 'bidId': 'foo', + 'height': 323 + } + } + + function createInStreamExchangeBid({ placementCode, statusCode = 1 }) { + return { + 'ext': { + 'statusCode': statusCode, + 'placementCode': placementCode + }, + 'cpm': 20, + 'bidderCode': 'unruly', + 'width': 323, + 'vastUrl': 'https://targeting.unrulymedia.com/in_article?uuid=74544e00-d43b-4f3a-a799-69d22ce979ce&supported_mime_type=application/javascript&supported_mime_type=video/mp4&tj=%7B%22site%22%3A%7B%22lang%22%3A%22en-GB%22%2C%22ref%22%3A%22%22%2C%22page%22%3A%22http%3A%2F%2Fdemo.unrulymedia.com%2FinArticle%2Finarticle_nypost_upbeat%2Ftravel_magazines.html%22%2C%22domain%22%3A%22demo.unrulymedia.com%22%7D%2C%22user%22%3A%7B%22profile%22%3A%7B%22quantcast%22%3A%7B%22segments%22%3A%5B%7B%22id%22%3A%22D%22%7D%2C%7B%22id%22%3A%22T%22%7D%5D%7D%7D%7D%7D&video_width=618&video_height=347', + 'bidId': 'foo', + 'height': 323 + } + } + + function createExchangeResponse(...bids) { + return { + 'bids': bids + } + } + + let adapter + let server + let sandbox + let fakeRenderer + + beforeEach(() => { + adapter = createUnrulyAdapter() + adapter.exchangeUrl = 'http://localhost:9000/prebid' + + sandbox = sinon.sandbox.create() + sandbox.stub(bidmanager, 'addBidResponse') + sandbox.stub(bidfactory, 'createBid') + sandbox.stub(utils, 'logError') + + fakeRenderer = { + setRender: sinon.stub() + } + + sandbox.stub(Renderer, 'install') + Renderer.install.returns(fakeRenderer) + + server = sinon.fakeServer.create() + }) + + afterEach(() => { + sandbox.restore() + server.restore() + delete parent.window.unruly + }) + + describe('callBids', () => { + it('exists and is a function', () => { + expect(adapter.callBids).to.exist.and.to.be.a('function') + }) + + it('requires bids to make request', () => { + adapter.callBids({}) + expect(server.requests).to.be.empty + }) + + it('requires at least one bid to make request', () => { + adapter.callBids({ bids: [] }) + expect(server.requests).to.be.empty + }) + + it('passes bids through to exchange', () => { + const params = createParams(createBidRequestBid({ placementCode: 'placement1' })) + + adapter.callBids(params) + + expect(server.requests).to.have.length(1) + expect(server.requests[0].url).to.equal('http://localhost:9000/prebid') + + const requestBody = JSON.parse(server.requests[0].requestBody) + expect(requestBody).to.deep.equal({ + 'bidRequests': params.bids + }) + }) + + it('creates a bid response using status code from exchange for each bid and passes in the exchange response', () => { + const params = createParams(createBidRequestBid({ placementCode: 'placement1' })) + + const exchangeBid1 = createOutStreamExchangeBid({ placementCode: 'placement1' }) + const exchangeBid2 = createOutStreamExchangeBid({ placementCode: 'placement2', statusCode: 2 }) + const exchangeResponse = createExchangeResponse(exchangeBid1, exchangeBid2) + + server.respondWith(JSON.stringify(exchangeResponse)) + bidfactory.createBid.returns({}) + + adapter.callBids(params) + server.respond() + + sinon.assert.calledTwice(bidfactory.createBid) + sinon.assert.calledWith(bidfactory.createBid, exchangeBid1.ext.statusCode, exchangeResponse.bids[0]) + sinon.assert.calledWith(bidfactory.createBid, exchangeBid2.ext.statusCode, exchangeResponse.bids[1]) + }) + + it('adds the bid response to the bid manager', () => { + const fakeBid = {} + + const params = createParams(createBidRequestBid({ placementCode: 'placement1' })) + const exchangeBid = createOutStreamExchangeBid({ placementCode: 'placement1' }) + const exchangeResponse = createExchangeResponse(exchangeBid) + + server.respondWith(JSON.stringify(exchangeResponse)) + bidfactory.createBid.withArgs(exchangeBid.ext.statusCode).returns(fakeBid) + + adapter.callBids(params) + server.respond() + + sinon.assert.calledOnce(bidmanager.addBidResponse) + sinon.assert.calledWith(bidmanager.addBidResponse, exchangeBid.ext.placementCode, fakeBid) + }) + + describe('on invalid exchange response', () => { + it('should create NO_BID response for each bid request bid', () => { + const bidRequestBid1 = createBidRequestBid({ placementCode: 'placement1' }) + const bidRequestBid2 = createBidRequestBid({ placementCode: 'placement2' }) + const params = createParams(bidRequestBid1, bidRequestBid2) + const expectedBid = { 'some': 'props' } + + server.respondWith('this is not json') + bidfactory.createBid.withArgs(STATUS.NO_BID).returns(expectedBid) + + adapter.callBids(params) + server.respond() + + sinon.assert.calledOnce(utils.logError) + sinon.assert.calledTwice(bidmanager.addBidResponse) + sinon.assert.calledWith(bidmanager.addBidResponse, bidRequestBid1.placementCode, expectedBid) + sinon.assert.calledWith(bidmanager.addBidResponse, bidRequestBid2.placementCode, expectedBid) + }) + }) + + describe('InStream', () => { + it('merges bid response defaults', () => { + const params = createParams(createBidRequestBid({ placementCode: 'placement1' })) + + const fakeBidDefaults = { some: 'default' } + const fakeBid = Object.assign({}, fakeBidDefaults) + + const exchangeBid = createInStreamExchangeBid({ placementCode: 'placement1' }) + const exchangeResponse = createExchangeResponse(exchangeBid) + server.respondWith(JSON.stringify(exchangeResponse)) + + bidfactory.createBid.withArgs(exchangeBid.ext.statusCode).returns(fakeBid) + + adapter.callBids(params) + server.respond() + + sinon.assert.notCalled(Renderer.install) + expect(fakeBid).to.deep.equal(Object.assign( + {}, + fakeBidDefaults, + exchangeBid + )) + }) + }) + + describe('OutStream', () => { + it('merges bid response defaults with exchange bid and renderer', () => { + const params = createParams(createBidRequestBid({ placementCode: 'placement1' })) + + const fakeBidDefaults = { some: 'default' } + const fakeBid = Object.assign({}, fakeBidDefaults) + + const exchangeBid = createOutStreamExchangeBid({ placementCode: 'placement1' }) + const exchangeResponse = createExchangeResponse(exchangeBid) + server.respondWith(JSON.stringify(exchangeResponse)) + + bidfactory.createBid.withArgs(exchangeBid.ext.statusCode).returns(fakeBid) + + const fakeRenderer = {} + Renderer.install.withArgs(Object.assign( + {}, + exchangeBid.ext.renderer, + { callback: sinon.match.func } + )).returns(fakeRenderer) + + adapter.callBids(params) + server.respond() + + expect(fakeBid).to.deep.equal(Object.assign( + {}, + fakeBidDefaults, + exchangeBid, + { renderer: fakeRenderer } + )) + }) + + it('bid is placed on the bid queue when render is called', () => { + const params = createParams(createBidRequestBid({ placementCode: 'placement1' })) + + const fakeBidDefaults = { some: 'default' } + const fakeBid = Object.assign({}, fakeBidDefaults) + + const exchangeBid = createOutStreamExchangeBid({ placementCode: 'placement1' }) + const exchangeResponse = createExchangeResponse(exchangeBid) + server.respondWith(JSON.stringify(exchangeResponse)) + + bidfactory.createBid.withArgs(exchangeBid.ext.statusCode).returns(fakeBid) + + adapter.callBids(params) + server.respond() + + sinon.assert.calledOnce(fakeRenderer.setRender) + fakeRenderer.setRender.firstCall.args[0]() + + expect(window.top).to.have.deep.property('unruly.native.prebid.uq'); + expect(window.top.unruly.native.prebid.uq).to.deep.equal([['render', fakeBid]]) + }) + }) + }) +}) From f4ccc1edc0d990554ecd9fbc3a21ae7a0ffc2e0b Mon Sep 17 00:00:00 2001 From: Dave Bemiller Date: Thu, 15 Jun 2017 14:10:34 -0400 Subject: [PATCH 34/95] Prebid 0.25.0 Release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5c6a9072239..9ec2e7b1546 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "0.25.0-pre", + "version": "0.25.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From e6e4c3290a8cdee213632aab88a347d8ebecc09e Mon Sep 17 00:00:00 2001 From: Dave Bemiller Date: Thu, 15 Jun 2017 15:14:03 -0400 Subject: [PATCH 35/95] Increment pre version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9ec2e7b1546..f4c751dea7b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "0.25.0", + "version": "0.26.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From a46e12b5e000822ff4b5983d814b274291f849d3 Mon Sep 17 00:00:00 2001 From: Matt Lane Date: Mon, 19 Jun 2017 11:25:05 -0700 Subject: [PATCH 36/95] Use local module path (#1303) --- src/prebid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prebid.js b/src/prebid.js index 66f4889a506..98242bf3aff 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -4,7 +4,7 @@ import { getGlobal } from './prebidGlobal'; import { flatten, uniques, isGptPubadsDefined, adUnitsFilter } from './utils'; import { videoAdUnit, hasNonVideoBidder } from './video'; import { nativeAdUnit, nativeBidder, hasNonNativeBidder } from './native'; -import 'polyfill'; +import './polyfill'; import { parse as parseURL, format as formatURL } from './url'; import { isValidePriceConfig } from './cpmBucketManager'; import { listenMessagesFromCreative } from './secureCreatives'; From d5e13bc91d1d0911ec73ca14c870611222bb6f17 Mon Sep 17 00:00:00 2001 From: Dmitriy Shashkin Date: Thu, 22 Jun 2017 01:39:47 +0300 Subject: [PATCH 37/95] Empty bidRequests in AST adapter each time new auction begins (#1305) When error occurs adapter issues response for each bid in `bidRequests` therefore bidRequests must be emptied each time new auction begins Fixes #1304 --- src/adapters/appnexusAst.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/adapters/appnexusAst.js b/src/adapters/appnexusAst.js index 4ad2fe4502c..193d12fa049 100644 --- a/src/adapters/appnexusAst.js +++ b/src/adapters/appnexusAst.js @@ -35,6 +35,8 @@ function AppnexusAstAdapter() { /* Prebid executes this function when the page asks to send out bid requests */ baseAdapter.callBids = function(bidRequest) { + bidRequests = {}; + const bids = bidRequest.bids || []; var member = 0; let userObj; @@ -194,8 +196,11 @@ function AppnexusAstAdapter() { if (type === 'native') bid.mediaType = 'native'; if (type === 'video') bid.mediaType = 'video'; if (type === 'video-outstream') bid.mediaType = 'video-outstream'; - const placement = bidRequests[bid.adId].placementCode; - bidmanager.addBidResponse(placement, bid); + + if (bid.adId in bidRequests) { + const placement = bidRequests[bid.adId].placementCode; + bidmanager.addBidResponse(placement, bid); + } }); if (!usersync) { From a3c8e1063689842852bc681a1ee3936641d8949a Mon Sep 17 00:00:00 2001 From: Hugo Duthil Date: Thu, 22 Jun 2017 19:31:27 +0200 Subject: [PATCH 38/95] Isolate unit tests by stubbing external lib (#1308) --- test/spec/adapters/criteo_spec.js | 45 +++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/test/spec/adapters/criteo_spec.js b/test/spec/adapters/criteo_spec.js index e6f2033c738..d45393570e7 100644 --- a/test/spec/adapters/criteo_spec.js +++ b/test/spec/adapters/criteo_spec.js @@ -2,10 +2,55 @@ import Adapter from '../../../src/adapters/criteo'; import bidManager from '../../../src/bidmanager'; +import {ajax} from '../../../src/ajax' import {expect} from 'chai'; var CONSTANTS = require('../../../src/constants'); +/* ------------ Publishertag stub begin ------------ */ +before(() => { + window.Criteo = { + PubTag: { + DirectBidding: { + DirectBiddingSlot: function DirectBiddingSlot(placementCode, zoneid, nativeCallback, transactionId, sizes) { + return { + impId: placementCode + }; + }, + + DirectBiddingUrlBuilder: function DirectBiddingUrlBuilder(isAudit) { return {} }, + + DirectBiddingEvent: function DirectBiddingEvent(profileId, urlBuilder, slots, success, error, timeout) { + return { + slots: slots, + eval: function () { + var callbacks = { + error: error, + success: success + } + ajax('//bidder.criteo.com/cdb', callbacks) + } + } + } + } + } + }; + + window.criteo_pubtag = window.criteo_pubtag || { + push: function (event) { + event.eval(); + } + } + + window.Criteo.events = window.Criteo.events || []; + window.Criteo.events.push = function (elem) { + if (typeof elem === 'function') { + elem(); + } + }; +}); +/* ------------ Publishertag stub end ------------ */ + describe('criteo adapter test', () => { let adapter; let stubAddBidResponse; From 3c513ea114b557e7f5c94f0a25599f2f586bb9b6 Mon Sep 17 00:00:00 2001 From: dbemiller Date: Thu, 22 Jun 2017 14:26:05 -0400 Subject: [PATCH 39/95] Removed all jshint comments. (#1315) --- src/adaptermanager.js | 2 +- src/adapters/getintent.js | 2 -- src/adapters/indexExchange.js | 3 +-- src/adapters/lifestreet.js | 1 - src/adapters/nginad.js | 1 - src/adapters/pubmatic.js | 2 +- src/polyfill.js | 1 - src/utils.js | 2 +- test/spec/adapters/adform_spec.js | 2 -- test/spec/adapters/criteo_spec.js | 2 -- test/spec/adapters/inneractive_spec.js | 4 ++-- test/spec/adapters/serverbid_spec.js | 3 --- test/spec/adapters/underdogmedia_spec.js | 2 -- test/spec/adapters/yieldbot_spec.js | 2 -- 14 files changed, 6 insertions(+), 23 deletions(-) diff --git a/src/adaptermanager.js b/src/adaptermanager.js index 381d7514358..106f0f80e48 100644 --- a/src/adaptermanager.js +++ b/src/adaptermanager.js @@ -108,7 +108,7 @@ exports.callBids = ({adUnits, cbTimeout}) => { }); let s2sBidRequest = {tid, 'ad_units': adUnitsCopy}; - let s2sAdapter = _bidderRegistry[_s2sConfig.adapter]; // jshint ignore:line + let s2sAdapter = _bidderRegistry[_s2sConfig.adapter]; utils.logMessage(`CALLING S2S HEADER BIDDERS ==== ${adaptersServerSide.join(',')}`); s2sAdapter.setConfig(_s2sConfig); s2sAdapter.callBids(s2sBidRequest); diff --git a/src/adapters/getintent.js b/src/adapters/getintent.js index e8cbb837e72..604294a7a22 100644 --- a/src/adapters/getintent.js +++ b/src/adapters/getintent.js @@ -1,5 +1,3 @@ -/* jshint loopfunc: true */ - import { STATUS } from 'src/constants'; var bidfactory = require('../bidfactory.js'); diff --git a/src/adapters/indexExchange.js b/src/adapters/indexExchange.js index d9b464cb62c..133ee8e3cf2 100644 --- a/src/adapters/indexExchange.js +++ b/src/adapters/indexExchange.js @@ -1,5 +1,4 @@ // Factory for creating the bidderAdaptor -// jshint ignore:start var utils = require('../utils.js'); var bidfactory = require('../bidfactory.js'); var bidmanager = require('../bidmanager.js'); @@ -140,7 +139,7 @@ window.headertag_render = function(doc, targetID, slotID) { window.cygnus_index_args = {}; -var cygnus_index_adunits = [[728, 90], [120, 600], [300, 250], [160, 600], [336, 280], [234, 60], [300, 600], [300, 50], [320, 50], [970, 250], [300, 1050], [970, 90], [180, 150]]; // jshint ignore:line +var cygnus_index_adunits = [[728, 90], [120, 600], [300, 250], [160, 600], [336, 280], [234, 60], [300, 600], [300, 50], [320, 50], [970, 250], [300, 1050], [970, 90], [180, 150]]; var getIndexDebugMode = function() { return getParameterByName(CONSTANTS.INDEX_DEBUG_MODE.queryParam).toUpperCase(); diff --git a/src/adapters/lifestreet.js b/src/adapters/lifestreet.js index f1a5f14669d..a38c1a080da 100644 --- a/src/adapters/lifestreet.js +++ b/src/adapters/lifestreet.js @@ -82,7 +82,6 @@ const LifestreetAdapter = function LifestreetAdapter() { slotTagParams[property] = bid.params[property]; } } - /* jshint newcap: false */ LSM_Slot(slotTagParams); window.addEventListener('message', (ev) => { let key = ev.message ? 'message' : 'data'; diff --git a/src/adapters/nginad.js b/src/adapters/nginad.js index f13d8340d69..cedebfbd1e1 100644 --- a/src/adapters/nginad.js +++ b/src/adapters/nginad.js @@ -137,7 +137,6 @@ var NginAdAdapter = function NginAdAdapter() { var id = nginadBid.impid; // try to fetch the bid request we sent NginAd - /* jshint -W083 */ var bidObj = $$PREBID_GLOBAL$$._bidsRequested.find(bidSet => bidSet.bidderCode === 'nginad').bids .find(bid => bid.bidId === id); if (!bidObj) { diff --git a/src/adapters/pubmatic.js b/src/adapters/pubmatic.js index 5caa286eed9..5ad17a1dccd 100644 --- a/src/adapters/pubmatic.js +++ b/src/adapters/pubmatic.js @@ -127,7 +127,7 @@ var PubmaticAdapter = function PubmaticAdapter() { adResponse.bidderCode = 'pubmatic'; adResponse.adSlot = bid.adSlot; adResponse.cpm = Number(adUnitInfo.bid); - adResponse.ad = unescape(adUnit.creative_tag); // jshint ignore:line + adResponse.ad = unescape(adUnit.creative_tag); adResponse.ad += utils.createTrackPixelIframeHtml(decodeURIComponent(adUnit.tracking_url)); adResponse.width = dimensions[0]; adResponse.height = dimensions[1]; diff --git a/src/polyfill.js b/src/polyfill.js index d1b316f41e3..31c3607ece3 100644 --- a/src/polyfill.js +++ b/src/polyfill.js @@ -1,7 +1,6 @@ /** @module polyfill Misc polyfills */ -/* jshint -W121 */ require('core-js/fn/array/find'); require('core-js/fn/array/includes'); require('core-js/fn/object/assign'); diff --git a/src/utils.js b/src/utils.js index a3fbc401e64..4b7ed3dea27 100644 --- a/src/utils.js +++ b/src/utils.js @@ -340,7 +340,7 @@ exports.isNumber = function(object) { exports.isEmpty = function (object) { if (!object) return true; if (this.isArray(object) || this.isStr(object)) { - return !(object.length > 0); // jshint ignore:line + return !(object.length > 0); } for (var k in object) { diff --git a/test/spec/adapters/adform_spec.js b/test/spec/adapters/adform_spec.js index 8888dbfe899..df97cd7bc82 100644 --- a/test/spec/adapters/adform_spec.js +++ b/test/spec/adapters/adform_spec.js @@ -1,5 +1,3 @@ -// jshint esversion: 6 - import { assert } from 'chai'; import * as utils from '../../../src/utils'; import adLoader from '../../../src/adloader'; diff --git a/test/spec/adapters/criteo_spec.js b/test/spec/adapters/criteo_spec.js index d45393570e7..5cf1549eef6 100644 --- a/test/spec/adapters/criteo_spec.js +++ b/test/spec/adapters/criteo_spec.js @@ -1,5 +1,3 @@ -/* jshint -W030 */ - import Adapter from '../../../src/adapters/criteo'; import bidManager from '../../../src/bidmanager'; import {ajax} from '../../../src/ajax' diff --git a/test/spec/adapters/inneractive_spec.js b/test/spec/adapters/inneractive_spec.js index 1aade6e9c26..be062ed29dd 100644 --- a/test/spec/adapters/inneractive_spec.js +++ b/test/spec/adapters/inneractive_spec.js @@ -122,7 +122,7 @@ describe('InneractiveAdapter', function () { delete bidRequest.bids; adapter.callBids(bidRequest); - expect(bidRequests).to.be.empty; // jshint ignore:line + expect(bidRequests).to.be.empty; }); }); @@ -133,7 +133,7 @@ describe('InneractiveAdapter', function () { adapter.callBids(bidRequest); for (let id = 0; id < INVALID_BIDS_COUNT; id++) { - expect(adapter._isValidRequest.getCall(id).returned(false)).to.be.true; // jshint ignore:line + expect(adapter._isValidRequest.getCall(id).returned(false)).to.be.true; } adapter._isValidRequest.restore(); diff --git a/test/spec/adapters/serverbid_spec.js b/test/spec/adapters/serverbid_spec.js index 29d51058888..6151c99b21a 100644 --- a/test/spec/adapters/serverbid_spec.js +++ b/test/spec/adapters/serverbid_spec.js @@ -1,6 +1,3 @@ -/* jshint -W024 */ -/* jshint expr:true */ - import { expect } from 'chai'; import Adapter from 'src/adapters/serverbid'; import bidmanager from 'src/bidmanager'; diff --git a/test/spec/adapters/underdogmedia_spec.js b/test/spec/adapters/underdogmedia_spec.js index 9b1a15793ad..25842034bee 100644 --- a/test/spec/adapters/underdogmedia_spec.js +++ b/test/spec/adapters/underdogmedia_spec.js @@ -1,5 +1,3 @@ -/* jshint -W030 */ - import Adapter from '../../../src/adapters/underdogmedia'; import bidManager from '../../../src/bidmanager'; import adloader from '../../../src/adloader'; diff --git a/test/spec/adapters/yieldbot_spec.js b/test/spec/adapters/yieldbot_spec.js index bce80df0b84..3a8f52ca05e 100644 --- a/test/spec/adapters/yieldbot_spec.js +++ b/test/spec/adapters/yieldbot_spec.js @@ -42,7 +42,6 @@ const YB_BID_FIXTURE = { }; function createYieldbotMockLib() { - // jshint unused:false window.yieldbot = { _initialized: false, pub: (psn) => {}, @@ -54,7 +53,6 @@ function createYieldbotMockLib() { return YB_BID_FIXTURE[slotName] || {ybot_ad: 'n'}; } }; - // jshint unused:true } function restoreYieldbotMockLib() { From 1cafca13804386126ee9696a0c633af6de5ea37f Mon Sep 17 00:00:00 2001 From: dbemiller Date: Thu, 22 Jun 2017 14:30:24 -0400 Subject: [PATCH 40/95] Fix preconditions and side-effects in fragile tests (#1318) --- test/spec/unit/pbjs_api_spec.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index 2f0559e99e2..95aed3b396f 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -137,6 +137,10 @@ describe('Unit: Prebid Module', function () { $$PREBID_GLOBAL$$.adUnits = []; }) describe('getAdserverTargetingForAdUnitCodeStr', function () { + beforeEach(() => { + resetAuction(); + }); + it('should return targeting info as a string', function () { const adUnitCode = config.adUnitCodes[0]; $$PREBID_GLOBAL$$.enableSendAllBids(); @@ -331,10 +335,9 @@ describe('Unit: Prebid Module', function () { }); describe('getBidResponses', function () { - var result = $$PREBID_GLOBAL$$.getBidResponses(); - var compare = getBidResponsesFromAPI(); - it('should return expected bid responses when not passed an adunitCode', function () { + var result = $$PREBID_GLOBAL$$.getBidResponses(); + var compare = getBidResponsesFromAPI(); assert.deepEqual(result, compare, 'expected bid responses are returned'); }); From 28b379c0a3c862fa822fb24f0b39ceda1b638836 Mon Sep 17 00:00:00 2001 From: Mikhail Khazov Date: Fri, 23 Jun 2017 17:58:16 +0300 Subject: [PATCH 41/95] Incorrect param type in addAdUnits JSDoc (#1321) (#1322) --- src/prebid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prebid.js b/src/prebid.js index 98242bf3aff..03762858d27 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -472,7 +472,7 @@ $$PREBID_GLOBAL$$.requestBids = function ({ bidsBackHandler, timeout, adUnits, a /** * * Add adunit(s) - * @param {Array|String} adUnitArr Array of adUnits or single adUnit Object. + * @param {Array|Object} adUnitArr Array of adUnits or single adUnit Object. * @alias module:$$PREBID_GLOBAL$$.addAdUnits */ $$PREBID_GLOBAL$$.addAdUnits = function (adUnitArr) { From f6449d6e73cc61dedc0a4d017eb226e2e00fa305 Mon Sep 17 00:00:00 2001 From: Rich Snapp Date: Mon, 26 Jun 2017 15:45:30 -0600 Subject: [PATCH 42/95] Modules (#1177) * initial implementation of module system * express module * conversion of rubicon adapter to module system * use var instead of let in node scripts * example of using modules for concatenation through webpack code-splitting * fixes for webpack code-splitting * changes including config through setConfig and getConfig callback * external modules working, but node_modules in project still needs babel-laoder fix * gulp watch bundle building * fix for babel-loader node_modules exclusion and bundle only * updated express module to work in new webpack module format * gulp default, don't bundle * updated rubicon adapter to latest * added appnexus and appnexusAst to modules. added support for native and video registering * added logging for files getting bundled * fixed bug in bundling external modules * aardvark bid adapter converted to module * upadte appnexus bid adpater names and get ride of mocha loader tests * adblade bid adapter converted to module * adblund bid adapter converted to module * adbutler bid adapter converted to module * adequant bid adapter converted to module * adform bid adapter converted to module * adkernel bid adapter converted to module * admedia bid adapter converted to module * admixer bid adapter converted to module * fix pbjs global for tests so load order doesn't matter * adsuppply bid adpater converted to module * use $$PREBID_GLOBAL$$ rather than pbjs in test files * adyoulike bid adapter converted to module * fixed adapter location in some adapters * aol bid adapter converted to module * atomx bid adapter converted to module * audienceNetwork bid adapter converted to module * beachfront bid adapter converted to module * bidfluence bid adapter converted to module * brightcom bid adapter converted to module * centro bid adapter converted to module * rubicon spec file name changed * conversant bid adapter converted to module * criteo bid adapter converted to module * districtmDMX bid adapter converted to module * fidelity bid adapter converted to module * getintent bid adapter converted to module * gumgum bid adapter converted to module * hiromedia bid adapter converted to module * huddledmasses bid adapter converted to module * indexExchange bid adapter converted to module * inneractive bid adapter converted to module * innity bid adapter converted to module * jcm bid adapter converted to module * komoona bid adapter converted to module * kruxlink bid adapter converted to module * lifestreet bid adapter converted to module * mantis bid adapter converted to module * memeglobal bid adapter converted to module * nginad bid adapter converted to module * openx bid adapter converted to module * piximedia bid adapter converted to module * prebidServer bid adapter converted to module * pubgears bid adapter converted to module * pubmatic bid adapter converted to module * pulsepoint and pulsepointLite bid adapter converted to module * quantcast bid adapter converted to module * rhythmone bid adapter converted to module * added adkernel alias to headbidding to adkernalBidAdapter module * roxot bid adapter converted to module * sekindoUM bid adapter converted to module * remove baseAdapter * serverbid bid adapter converted to module * sharethrough bid adapter converted to module * smartyads bid adapter converted to module * update conversantBidAdapter to support video * get rubiconBidAdapter latest * move rubicon adapter to module properly * sonobi bid adapter converted to module * sovrn bid adapter converted to module * springserve bid adpater converted to module * stickyadstv bid adapter converted to module (and removed console logs) * convert tapsense bid adapter to module * thoughtleadr bid adapter converted to module * trion bid adapter converted to module * triplelift bid adapter converted to module * twenga bid adapter converted to module * underdogmedia bid adapter converted to module * vertamedia bid adapter converted to module * vertoz bid adapter converted to module * wideorbit bid adapter converted to module * widespace bid adapter converted to module * xhb bid adapter converted to module * yieldbot converted from bid adapter to module * smartadserver bid adapter converted to module * remove old adapter class in adapter folder * converted analytics adapters to modules * removed loaders from build * added plugin to remove file manifest and jsonp code from webpack runtime * cox bid adapter converted to module * carambola bid adapter converted to module * eplanning bid adapter converted to module * --modules arg allows .json file as parameter * removing config module for now * don't bundle AnalyticsAdapter.js in common chunk * unruly bid adapter converted to module * fixed case-sensitivity in including webpack plugin * can't use class keyword, updated to constructor function for plugin * added jsdoc to express and new webpack plugin * fixed sourcemaps for concat step in bundle * use external sourcemap for bundle instead of inline * rename prebid.js to prebid-core.js and main bundle outputs prebid.js now * updated README.md to be module specific * added filter to ignore hidden files in modules directory --- README.md | 37 +- adapters.json | 161 --- analytics.json | 1 - gulpHelpers.js | 111 +- gulpfile.js | 99 +- karma.conf.js | 10 +- loaders/adapterLoader.js | 160 --- loaders/analyticsLoader.js | 41 - loaders/getAdapters.js | 33 - loaders/nativeLoader.js | 45 - .../aardvarkBidAdapter.js | 15 +- .../adbladeBidAdapter.js | 11 +- .../adbund.js => modules/adbundBidAdapter.js | 13 +- .../adbutlerBidAdapter.js | 11 +- .../adequantBidAdapter.js | 19 +- .../adform.js => modules/adformBidAdapter.js | 13 +- .../adkernelBidAdapter.js | 6 +- .../admediaBidAdapter.js | 15 +- .../admixerBidAdapter.js | 13 +- .../adsupplyBidAdapter.js | 12 +- .../adyoulikeBidAdapter.js | 5 +- .../aol.js => modules/aolBidAdapter.js | 13 +- modules/appnexusAnalyticsAdapter.js | 19 + .../appnexusAstBidAdapter.js | 7 +- .../appnexusBidAdapter.js | 24 +- .../atomx.js => modules/atomxBidAdapter.js | 14 +- .../audienceNetworkBidAdapter.js | 17 +- .../beachfrontBidAdapter.js | 7 +- .../bidfluenceBidAdapter.js | 109 +- .../brightcomBidAdapter.js | 13 +- .../carambolaBidAdapter.js | 15 +- .../centro.js => modules/centroBidAdapter.js | 11 +- .../conversantBidAdapter.js | 17 +- .../cox.js => modules/coxBidAdapter.js | 513 ++++---- .../criteo.js => modules/criteoBidAdapter.js | 9 +- .../districtmDMXBidAdapter.js | 9 +- .../eplanningBidAdapter.js | 7 +- modules/express.js | 209 ++++ .../fidelityBidAdapter.js | 13 +- .../getintentBidAdapter.js | 11 +- .../googleAnalyticsAdapter.js | 12 +- .../gumgum.js => modules/gumgumBidAdapter.js | 11 +- .../hiromediaBidAdapter.js | 729 +++++------ .../huddledmassesBidAdapter.js | 5 +- .../indexExchangeBidAdapter.js | 11 +- .../inneractiveBidAdapter.js | 12 +- .../innity.js => modules/innityBidAdapter.js | 13 +- .../jcm.js => modules/jcmBidAdapter.js | 3 + .../komoonaBidAdapter.js | 5 +- .../kruxlinkBidAdapter.js | 15 +- .../lifestreetBidAdapter.js | 11 +- .../mantis.js => modules/mantisBidAdapter.js | 17 +- .../memeglobalBidAdapter.js | 13 +- .../nginad.js => modules/nginadBidAdapter.js | 13 +- .../openx.js => modules/openxBidAdapter.js | 13 +- .../piximediaBidAdapter.js | 15 +- .../prebidServerBidAdapter.js | 5 +- .../pubgearsBidAdapter.js | 11 +- .../pubmaticBidAdapter.js | 13 +- .../pubwiseAnalyticsAdapter.js | 11 +- modules/pulsepointAnalyticsAdapter.js | 19 + .../pulsepointBidAdapter.js | 11 +- .../pulsepointLiteBidAdapter.js | 3 + .../quantcastBidAdapter.js | 12 +- .../rhythmoneBidAdapter.js | 19 +- .../roxotAnalyticsAdapter.js | 10 +- .../roxot.js => modules/roxotBidAdapter.js | 13 +- .../rubiconBidAdapter.js | 8 +- .../sekindoUMBidAdapter.js | 15 +- .../serverbidBidAdapter.js | 5 +- .../sharethroughAnalyticsAdapter.js | 14 +- .../sharethroughBidAdapter.js | 11 +- .../smartadserverBidAdapter.js | 11 +- .../smartyadsBidAdapter.js | 5 +- .../sonobi.js => modules/sonobiBidAdapter.js | 11 +- .../sovrn.js => modules/sovrnBidAdapter.js | 13 +- .../springserveBidAdapter.js | 9 +- .../stickyadstvBidAdapter.js | 17 +- .../tapsenseBidAdapter.js | 11 +- .../thoughtleadrBidAdapter.js | 11 +- .../trion.js => modules/trionBidAdapter.js | 22 +- .../tripleliftBidAdapter.js | 12 +- .../twenga.js => modules/twengaBidAdapter.js | 24 +- .../underdogmediaBidAdapter.js | 15 +- .../unruly.js => modules/unrulyBidAdapter.js | 3 + .../vertamediaBidAdapter.js | 7 +- .../vertoz.js => modules/vertozBidAdapter.js | 17 +- .../wideorbitBidAdapter.js | 15 +- .../widespaceBidAdapter.js | 15 +- .../xhb.js => modules/xhbBidAdapter.js | 23 +- .../yieldbotBidAdapter.js | 15 +- package.json | 8 +- plugins/RequireEnsureWithoutJsonp.js | 30 + .../analytics => }/AnalyticsAdapter.js | 2 +- src/{adapters => }/adapter.js | 0 src/adaptermanager.js | 35 +- src/adapters/analytics/appnexus.js | 11 - src/adapters/analytics/example.js | 2 +- src/adapters/analytics/example2.js | 2 +- src/adapters/analytics/pulsepoint.js | 11 - src/adapters/baseAdapter.js | 17 - src/native.js | 6 +- src/prebid.js | 104 +- test/helpers/prebidGlobal.js | 3 + .../analytics => }/AnalyticsAdapter_spec.js | 7 +- test/spec/loaders/adapterLoader_spec.js | 38 - test/spec/loaders/getAdapters_spec.js | 81 -- .../aardvarkBidAdapter_spec.js} | 2 +- .../adbladeBidAdapter_spec.js} | 2 +- .../adbundBidAdapter_spec.js} | 2 +- .../adbutlerBidAdapter_spec.js} | 7 +- .../adformBidAdapter_spec.js} | 2 +- .../adkernelBidAdapter_spec.js} | 2 +- .../admixerBidAdapter_spec.js} | 3 +- .../adsupplyBidAdapter_spec.js} | 7 +- .../adyoulikeBidAdapter_spec.js} | 2 +- .../aolBidAdapter_spec.js} | 2 +- .../appnexusAnalyticsAdapter_spec.js} | 2 +- .../appnexusAstBidAdapter_spec.js} | 2 +- .../appnexusBidAdapter_spec.js} | 2 +- .../atomxBidAdapter_spec.js} | 3 +- .../audienceNetworkBidAdapter_spec.js} | 2 +- .../beachfrontBidAdapter_spec.js} | 2 +- .../bidfluenceBidAdapter_spec.js} | 6 +- .../carambolaBidAdapter_spec.js} | 2 +- .../centroBidAdapter_spec.js} | 31 +- .../conversantBidAdapter_spec.js} | 2 +- .../coxBidAdapter_spec.js} | 241 ++-- .../criteoBidAdapter_spec.js} | 2 +- .../districtmDMXBidAdapter_spec.js} | 2 +- .../eplanningBidAdapter_spec.js} | 2 +- .../fidelityBidAdapter_spec.js} | 12 +- .../getintentBidAdapter_spec.js} | 2 +- .../googleAnalyticsAdapter_spec.js} | 2 +- .../gumgumBidAdapter_spec.js} | 6 +- .../hiromediaBidAdapter_spec.js} | 626 +++++----- .../huddledmassesBidAdapter_spec.js} | 2 +- .../indexExchangeBidAdapter_request_spec.js} | 5 +- .../indexExchangeBidAdapter_response_spec.js} | 4 +- ...dexExchangeBidAdapter_validadtion_spec.js} | 5 +- .../inneractiveBidAdapter_spec.js} | 2 +- .../innityBidAdapter_spec.js} | 2 +- .../jcmBidAdapter_spec.js} | 54 +- .../komoonaBidAdapter_spec.js} | 2 +- .../lifestreetBidAdapter_spec.js} | 2 +- .../mantisBidAdapter_spec.js} | 2 +- .../memeglobalBidAdapter_spec.js} | 12 +- .../openxBidAdapter_spec.js} | 16 +- .../piximediaBidAdapter_spec.js} | 85 +- .../prebidServerBidAdapter_spec.js} | 3 +- .../pubgearsBidAdapter_spec.js} | 2 +- .../pubwiseAnalyticsAdapter_spec.js} | 8 +- .../pulsepointBidAdapter_spec.js} | 2 +- .../pulsepointLiteBidAdapter_spec.js} | 2 +- .../quantcastBidAdapter_spec.js} | 2 +- .../rhythmoneBidAdapter_spec.js} | 2 +- .../roxotAnalyticsAdapter_spec.js} | 8 +- .../roxotBidAdapter_spec.js} | 12 +- .../rubiconBidAdapter_spec.js} | 3 +- .../sekindoUMBidAdapter_spec.js} | 2 +- .../serverbidBidAdapter_spec.js} | 2 +- .../sharethroughAnalyticsAdapter_spec.js} | 2 +- .../sharethroughBidAdapter_spec.js} | 10 +- .../smartadserverBidAdapter_spec.js} | 2 +- .../smartyadsBidAdapter_spec.js} | 2 +- .../sonobiBidAdapter_spec.js} | 2 +- .../sovrnBidAdapter_spec.js} | 12 +- .../stickyadstvBidAdapter_spec.js} | 9 +- .../tapsenseBidAdapter_spec.js} | 14 +- .../thoughtleadrBidAdapter_spec.js} | 2 +- .../trionBidAdapter_spec.js} | 30 +- .../tripleliftBidAdapter_spec.js} | 26 +- .../twengaBidAdapter_spec.js} | 2 +- .../underdogmediaBidAdapter_spec.js} | 2 +- .../unrulyBidAdapter_spec.js} | 2 +- .../vertamediaBidAdapter_spec.js} | 2 +- .../vertozBidAdapter_spec.js} | 14 +- .../wideorbitBidAdapter_spec.js} | 2 +- .../widespaceBidAdapter_spec.js} | 12 +- .../yieldbotBidAdapter_spec.js} | 12 +- test/spec/unit/pbjs_api_spec.js | 4 + webpack.conf.js | 66 +- yarn.lock | 1102 +++++++++++++---- 183 files changed, 3393 insertions(+), 2718 deletions(-) delete mode 100644 adapters.json delete mode 100644 analytics.json delete mode 100644 loaders/adapterLoader.js delete mode 100644 loaders/analyticsLoader.js delete mode 100644 loaders/getAdapters.js delete mode 100644 loaders/nativeLoader.js rename src/adapters/aardvark.js => modules/aardvarkBidAdapter.js (92%) rename src/adapters/adblade.js => modules/adbladeBidAdapter.js (92%) rename src/adapters/adbund.js => modules/adbundBidAdapter.js (83%) rename src/adapters/adbutler.js => modules/adbutlerBidAdapter.js (93%) rename src/adapters/adequant.js => modules/adequantBidAdapter.js (85%) rename src/adapters/adform.js => modules/adformBidAdapter.js (92%) rename src/adapters/adkernel.js => modules/adkernelBidAdapter.js (97%) rename src/adapters/admedia.js => modules/admediaBidAdapter.js (88%) rename src/adapters/admixer.js => modules/admixerBidAdapter.js (87%) rename src/adapters/adsupply.js => modules/adsupplyBidAdapter.js (90%) rename src/adapters/adyoulike.js => modules/adyoulikeBidAdapter.js (97%) rename src/adapters/aol.js => modules/aolBidAdapter.js (96%) create mode 100644 modules/appnexusAnalyticsAdapter.js rename src/adapters/appnexusAst.js => modules/appnexusAstBidAdapter.js (98%) rename src/adapters/appnexus.js => modules/appnexusBidAdapter.js (89%) rename src/adapters/atomx.js => modules/atomxBidAdapter.js (85%) rename src/adapters/audienceNetwork.js => modules/audienceNetworkBidAdapter.js (96%) rename src/adapters/beachfront.js => modules/beachfrontBidAdapter.js (95%) rename src/adapters/bidfluence.js => modules/bidfluenceBidAdapter.js (82%) rename src/adapters/brightcom.js => modules/brightcomBidAdapter.js (95%) rename src/adapters/carambola.js => modules/carambolaBidAdapter.js (94%) rename src/adapters/centro.js => modules/centroBidAdapter.js (92%) rename src/adapters/conversant.js => modules/conversantBidAdapter.js (95%) rename src/adapters/cox.js => modules/coxBidAdapter.js (94%) rename src/adapters/criteo.js => modules/criteoBidAdapter.js (93%) rename src/adapters/districtmDMX.js => modules/districtmDMXBidAdapter.js (84%) rename src/adapters/eplanning.js => modules/eplanningBidAdapter.js (98%) create mode 100644 modules/express.js rename src/adapters/fidelity.js => modules/fidelityBidAdapter.js (91%) rename src/adapters/getintent.js => modules/getintentBidAdapter.js (87%) rename src/adapters/analytics/ga.js => modules/googleAnalyticsAdapter.js (96%) rename src/adapters/gumgum.js => modules/gumgumBidAdapter.js (94%) rename src/adapters/hiromedia.js => modules/hiromediaBidAdapter.js (96%) rename src/adapters/huddledmasses.js => modules/huddledmassesBidAdapter.js (96%) rename src/adapters/indexExchange.js => modules/indexExchangeBidAdapter.js (98%) rename src/adapters/inneractive.js => modules/inneractiveBidAdapter.js (98%) rename src/adapters/innity.js => modules/innityBidAdapter.js (86%) rename src/adapters/jcm.js => modules/jcmBidAdapter.js (94%) rename src/adapters/komoona.js => modules/komoonaBidAdapter.js (95%) rename src/adapters/kruxlink.js => modules/kruxlinkBidAdapter.js (87%) rename src/adapters/lifestreet.js => modules/lifestreetBidAdapter.js (94%) rename src/adapters/mantis.js => modules/mantisBidAdapter.js (93%) rename src/adapters/memeglobal.js => modules/memeglobalBidAdapter.js (91%) rename src/adapters/nginad.js => modules/nginadBidAdapter.js (93%) rename src/adapters/openx.js => modules/openxBidAdapter.js (94%) rename src/adapters/piximedia.js => modules/piximediaBidAdapter.js (93%) rename src/adapters/prebidServer.js => modules/prebidServerBidAdapter.js (97%) rename src/adapters/pubgears.js => modules/pubgearsBidAdapter.js (94%) rename src/adapters/pubmatic.js => modules/pubmaticBidAdapter.js (94%) rename src/adapters/analytics/pubwiseanalytics.js => modules/pubwiseAnalyticsAdapter.js (85%) create mode 100644 modules/pulsepointAnalyticsAdapter.js rename src/adapters/pulsepoint.js => modules/pulsepointBidAdapter.js (88%) rename src/adapters/pulsepointLite.js => modules/pulsepointLiteBidAdapter.js (95%) rename src/adapters/quantcast.js => modules/quantcastBidAdapter.js (91%) rename src/adapters/rhythmone.js => modules/rhythmoneBidAdapter.js (95%) rename src/adapters/analytics/roxot.js => modules/roxotAnalyticsAdapter.js (91%) rename src/adapters/roxot.js => modules/roxotBidAdapter.js (89%) rename src/adapters/rubicon.js => modules/rubiconBidAdapter.js (97%) rename src/adapters/sekindoUM.js => modules/sekindoUMBidAdapter.js (88%) rename src/adapters/serverbid.js => modules/serverbidBidAdapter.js (96%) rename src/adapters/analytics/sharethrough_analytics.js => modules/sharethroughAnalyticsAdapter.js (86%) rename src/adapters/sharethrough.js => modules/sharethroughBidAdapter.js (92%) rename src/adapters/smartadserver.js => modules/smartadserverBidAdapter.js (87%) rename src/adapters/smartyads.js => modules/smartyadsBidAdapter.js (96%) rename src/adapters/sonobi.js => modules/sonobiBidAdapter.js (93%) rename src/adapters/sovrn.js => modules/sovrnBidAdapter.js (93%) rename src/adapters/springserve.js => modules/springserveBidAdapter.js (93%) rename src/adapters/stickyadstv.js => modules/stickyadstvBidAdapter.js (92%) rename src/adapters/tapsense.js => modules/tapsenseBidAdapter.js (88%) rename src/adapters/thoughtleadr.js => modules/thoughtleadrBidAdapter.js (91%) rename src/adapters/trion.js => modules/trionBidAdapter.js (89%) rename src/adapters/triplelift.js => modules/tripleliftBidAdapter.js (93%) rename src/adapters/twenga.js => modules/twengaBidAdapter.js (89%) rename src/adapters/underdogmedia.js => modules/underdogmediaBidAdapter.js (89%) rename src/adapters/unruly.js => modules/unrulyBidAdapter.js (96%) rename src/adapters/vertamedia.js => modules/vertamediaBidAdapter.js (93%) rename src/adapters/vertoz.js => modules/vertozBidAdapter.js (84%) rename src/adapters/wideorbit.js => modules/wideorbitBidAdapter.js (95%) rename src/adapters/widespace.js => modules/widespaceBidAdapter.js (89%) rename src/adapters/xhb.js => modules/xhbBidAdapter.js (92%) rename src/adapters/yieldbot.js => modules/yieldbotBidAdapter.js (93%) create mode 100644 plugins/RequireEnsureWithoutJsonp.js rename src/{adapters/analytics => }/AnalyticsAdapter.js (99%) rename src/{adapters => }/adapter.js (100%) delete mode 100644 src/adapters/analytics/appnexus.js delete mode 100644 src/adapters/analytics/pulsepoint.js delete mode 100644 src/adapters/baseAdapter.js create mode 100644 test/helpers/prebidGlobal.js rename test/spec/{unit/adapters/analytics => }/AnalyticsAdapter_spec.js (95%) delete mode 100644 test/spec/loaders/adapterLoader_spec.js delete mode 100644 test/spec/loaders/getAdapters_spec.js rename test/spec/{adapters/aardvark_spec.js => modules/aardvarkBidAdapter_spec.js} (99%) rename test/spec/{adapters/adblade_spec.js => modules/adbladeBidAdapter_spec.js} (98%) rename test/spec/{adapters/adbund_spec.js => modules/adbundBidAdapter_spec.js} (97%) rename test/spec/{adapters/adbutler_spec.js => modules/adbutlerBidAdapter_spec.js} (98%) rename test/spec/{adapters/adform_spec.js => modules/adformBidAdapter_spec.js} (99%) rename test/spec/{adapters/adkernel_spec.js => modules/adkernelBidAdapter_spec.js} (99%) rename test/spec/{adapters/admixer_spec.js => modules/admixerBidAdapter_spec.js} (98%) rename test/spec/{adapters/adsupply_spec.js => modules/adsupplyBidAdapter_spec.js} (98%) rename test/spec/{adapters/adyoulike_spec.js => modules/adyoulikeBidAdapter_spec.js} (99%) rename test/spec/{adapters/aol_spec.js => modules/aolBidAdapter_spec.js} (99%) rename test/spec/{unit/adapters/analytics/appnexus_spec.js => modules/appnexusAnalyticsAdapter_spec.js} (93%) rename test/spec/{adapters/appnexusAst_spec.js => modules/appnexusAstBidAdapter_spec.js} (99%) rename test/spec/{adapters/appnexus_spec.js => modules/appnexusBidAdapter_spec.js} (94%) rename test/spec/{adapters/atomx_spec.js => modules/atomxBidAdapter_spec.js} (98%) rename test/spec/{adapters/audienceNetwork_spec.js => modules/audienceNetworkBidAdapter_spec.js} (99%) rename test/spec/{adapters/beachfront_spec.js => modules/beachfrontBidAdapter_spec.js} (98%) rename test/spec/{adapters/bidfluence_spec.js => modules/bidfluenceBidAdapter_spec.js} (91%) rename test/spec/{adapters/carambola_spec.js => modules/carambolaBidAdapter_spec.js} (98%) rename test/spec/{adapters/centro_spec.js => modules/centroBidAdapter_spec.js} (91%) rename test/spec/{adapters/conversant_spec.js => modules/conversantBidAdapter_spec.js} (99%) rename test/spec/{adapters/cox_spec.js => modules/coxBidAdapter_spec.js} (95%) rename test/spec/{adapters/criteo_spec.js => modules/criteoBidAdapter_spec.js} (99%) rename test/spec/{adapters/districtm_spec.js => modules/districtmDMXBidAdapter_spec.js} (98%) rename test/spec/{adapters/eplanning_spec.js => modules/eplanningBidAdapter_spec.js} (98%) rename test/spec/{adapters/fidelity_spec.js => modules/fidelityBidAdapter_spec.js} (93%) rename test/spec/{adapters/getintent_spec.js => modules/getintentBidAdapter_spec.js} (98%) rename test/spec/{ga_spec.js => modules/googleAnalyticsAdapter_spec.js} (87%) rename test/spec/{adapters/gumgum_spec.js => modules/gumgumBidAdapter_spec.js} (97%) rename test/spec/{adapters/hiromedia_spec.js => modules/hiromediaBidAdapter_spec.js} (96%) rename test/spec/{adapters/huddledmasses_spec.js => modules/huddledmassesBidAdapter_spec.js} (98%) rename test/spec/{adapters/indexExchange_request_spec.js => modules/indexExchangeBidAdapter_request_spec.js} (99%) rename test/spec/{adapters/indexExchange_response_spec.js => modules/indexExchangeBidAdapter_response_spec.js} (99%) rename test/spec/{adapters/indexExchange_validation_spec.js => modules/indexExchangeBidAdapter_validadtion_spec.js} (99%) rename test/spec/{adapters/inneractive_spec.js => modules/inneractiveBidAdapter_spec.js} (99%) rename test/spec/{adapters/innity_spec.js => modules/innityBidAdapter_spec.js} (98%) rename test/spec/{adapters/jcm_spec.js => modules/jcmBidAdapter_spec.js} (83%) rename test/spec/{adapters/komoona_spec.js => modules/komoonaBidAdapter_spec.js} (98%) rename test/spec/{adapters/lifestreet_spec.js => modules/lifestreetBidAdapter_spec.js} (99%) rename test/spec/{adapters/mantis_spec.js => modules/mantisBidAdapter_spec.js} (98%) rename test/spec/{adapters/memeglobal_spec.js => modules/memeglobalBidAdapter_spec.js} (92%) rename test/spec/{adapters/openx_spec.js => modules/openxBidAdapter_spec.js} (94%) rename test/spec/{adapters/piximedia_spec.js => modules/piximediaBidAdapter_spec.js} (81%) rename test/spec/{adapters/prebidServer_spec.js => modules/prebidServerBidAdapter_spec.js} (98%) rename test/spec/{adapters/pubgears_spec.js => modules/pubgearsBidAdapter_spec.js} (99%) rename test/spec/{adapters/analytics/pubwiseanalytics_spec.js => modules/pubwiseAnalyticsAdapter_spec.js} (79%) rename test/spec/{adapters/pulsepoint_spec.js => modules/pulsepointBidAdapter_spec.js} (98%) rename test/spec/{adapters/pulsepointLite_spec.js => modules/pulsepointLiteBidAdapter_spec.js} (98%) rename test/spec/{adapters/quantcast_spec.js => modules/quantcastBidAdapter_spec.js} (99%) rename test/spec/{adapters/rhythmone_spec.js => modules/rhythmoneBidAdapter_spec.js} (98%) rename test/spec/{adapters/analytics/roxot_analytic_spec.js => modules/roxotAnalyticsAdapter_spec.js} (77%) rename test/spec/{adapters/roxot_spec.js => modules/roxotBidAdapter_spec.js} (90%) rename test/spec/{adapters/rubicon_spec.js => modules/rubiconBidAdapter_spec.js} (99%) rename test/spec/{adapters/sekindoUM_spec.js => modules/sekindoUMBidAdapter_spec.js} (96%) rename test/spec/{adapters/serverbid_spec.js => modules/serverbidBidAdapter_spec.js} (98%) rename test/spec/{unit/adapters/analytics/sharethrough_analytics_spec.js => modules/sharethroughAnalyticsAdapter_spec.js} (97%) rename test/spec/{adapters/sharethrough_spec.js => modules/sharethroughBidAdapter_spec.js} (94%) rename test/spec/{adapters/smartadserver_spec.js => modules/smartadserverBidAdapter_spec.js} (98%) rename test/spec/{adapters/smartyads_spec.js => modules/smartyadsBidAdapter_spec.js} (98%) rename test/spec/{adapters/sonobi_spec.js => modules/sonobiBidAdapter_spec.js} (99%) rename test/spec/{adapters/sovrn_spec.js => modules/sovrnBidAdapter_spec.js} (93%) rename test/spec/{adapters/stickyadstv_spec.js => modules/stickyadstvBidAdapter_spec.js} (97%) rename test/spec/{adapters/tapsense_spec.js => modules/tapsenseBidAdapter_spec.js} (94%) rename test/spec/{adapters/thoughtleadr_spec.js => modules/thoughtleadrBidAdapter_spec.js} (98%) rename test/spec/{adapters/trion_spec.js => modules/trionBidAdapter_spec.js} (89%) rename test/spec/{adapters/triplelift_spec.js => modules/tripleliftBidAdapter_spec.js} (89%) rename test/spec/{adapters/twenga_spec.js => modules/twengaBidAdapter_spec.js} (98%) rename test/spec/{adapters/underdogmedia_spec.js => modules/underdogmediaBidAdapter_spec.js} (98%) rename test/spec/{adapters/unruly_spec.js => modules/unrulyBidAdapter_spec.js} (99%) rename test/spec/{adapters/vertamedia_spec.js => modules/vertamediaBidAdapter_spec.js} (98%) rename test/spec/{adapters/vertoz_spec.js => modules/vertozBidAdapter_spec.js} (89%) rename test/spec/{adapters/wideorbit_spec.js => modules/wideorbitBidAdapter_spec.js} (99%) rename test/spec/{adapters/widespace_spec.js => modules/widespaceBidAdapter_spec.js} (92%) rename test/spec/{adapters/yieldbot_spec.js => modules/yieldbotBidAdapter_spec.js} (93%) diff --git a/README.md b/README.md index 6aa65288645..947ddbf2dfd 100644 --- a/README.md +++ b/README.md @@ -51,17 +51,11 @@ This runs some code quality checks, starts a web server at `http://localhost:999 ### Build Optimization -The standard build output contains all the available bidder adapters listed in `adapters.json`. +The standard build output contains all the available modules from within the `modules` folder. -You might want to exclude some/most of them from the final bundle. To make sure the build only includes the adapters you want, you can make your own adapters file. +You might want to exclude some/most of them from the final bundle. To make sure the build only includes the modules you want, you can specify the modules to be included with the `--modules` CLI argument. -For example, in `path/to/your/list-of-adapters.json`, write: - - [ - "openx", - "rubicon", - "sovrn" - ] +For example, when running the serve command: `gulp serve --modules=openxBidAdapter,rubiconBidAdapter,sovrnBidAdapter` Building with just these adapters will result in a smaller bundle which should allow your pages to load faster. @@ -71,26 +65,35 @@ Prebid now supports the `yarn` npm client. This is an alternative to using `npm` For more info about yarn see https://yarnpkg.com - Clone the repo, run `yarn install` -- Duplicate `adapters.json` to e.g. `list-of-adapters.json` -- Remove the unnecessary adapters from `list-of-adapters.json` - Then run the build: - $ gulp build --adapters path/to/your/list-of-adapters.json + $ gulp build --modules=openxBidAdapter,rubiconBidAdapter,sovrnBidAdapter + +Alternatively, a `.json` file can be specified that contains a list of modules you would like to include. + + $ gulp build --modules=modules.json + +With `modules.json` containing the following +```json modules.json +[ + "openxBidAdapter", + "rubiconBidAdapter", + "sovrnBidAdapter" +] +``` **Build prebid.js using Yarn for bundling** In case you'd like to explicitly show that your project uses `prebid.js` and want a reproducible build, consider adding it as an `yarn` dependency. - Add `prebid.js` as a `yarn` dependency of your project: `yarn add prebid.js` -- Duplicate `node_modules/prebid.js/adapters.json` to under your project path, e.g. `path/to/your/list-of-adapters.json` -- Remove the unnecessary adapters - Run the `prebid.js` build under the `node_modules/prebid.js/` folder - $ gulp build --adapters path/to/your/list-of-adapters.json + $ gulp build --modules=path/to/your/list-of-modules.json Most likely your custom `prebid.js` will only change when there's: -- A change in your list of adapters +- A change in your list of modules - A new release of `prebid.js` Having said that, you are probably safe to check your custom bundle into your project. You can also generate it in your build process. @@ -156,7 +159,7 @@ Our PR review process can be found [here](https://github.com/prebid/Prebid.js/tr ### Add a Bidder Adapter -To add a bidder adapter, see the instructions in [How to add a bidder adaptor](http://prebid.org/dev-docs/bidder-adaptor.html). +To add a bidder adapter module, see the instructions in [How to add a bidder adaptor](http://prebid.org/dev-docs/bidder-adaptor.html). Please **do NOT load Prebid.js inside your adapter**. If you do this, we will reject or remove your adapter as appropriate. diff --git a/adapters.json b/adapters.json deleted file mode 100644 index 71dc5fbb0a2..00000000000 --- a/adapters.json +++ /dev/null @@ -1,161 +0,0 @@ -[ - "aardvark", - "adblade", - "adbund", - "adbutler", - "adequant", - "adform", - "adkernel", - "admedia", - "adyoulike", - "bidfluence", - "vertamedia", - "aol", - "appnexus", - "appnexusAst", - "beachfront", - "audienceNetwork", - "carambola", - "conversant", - "districtmDMX", - "fidelity", - "gumgum", - "hiromedia", - "indexExchange", - "innity", - "kruxlink", - "getintent", - "inneractive", - "komoona", - "lifestreet", - "mantis", - "openx", - "piximedia", - "pubmatic", - "pubgears", - "pulsepoint", - "pulsepointLite", - "quantcast", - "rhythmone", - "rubicon", - "smartyads", - "huddledmasses", - "smartadserver", - "sekindoUM", - "serverbid", - "sonobi", - "sovrn", - "springserve", - "thoughtleadr", - "stickyadstv", - "triplelift", - "twenga", - "yieldbot", - "nginad", - "brightcom", - "wideorbit", - "jcm", - "underdogmedia", - "memeglobal", - "criteo", - "centro", - "xhb", - "sharethrough", - "roxot", - "vertoz", - "widespace", - "admixer", - "atomx", - "tapsense", - "trion", - "eplanning", - "prebidServer", - "adsupply", - "cox", - { - "appnexus": { - "alias": "brealtime" - } - }, - { - "appnexus": { - "alias": "pagescience" - } - }, - { - "appnexus": { - "alias": "defymedia" - } - }, - { - "appnexus": { - "alias": "gourmetads" - } - }, - { - "appnexusAst": { - "supportedMediaTypes": ["video", "native"] - } - }, - { - "vertamedia": { - "supportedMediaTypes": ["video"] - } - }, - { - "beachfront": { - "supportedMediaTypes": ["video"] - } - }, - { - "appnexus": { - "alias": "matomy" - } - }, - { - "rubicon": { - "alias": "rubiconLite", - "supportedMediaTypes": ["video"] - } - }, - { - "appnexus": { - "alias": "featureforward" - } - }, - { - "appnexus": { - "alias": "oftmedia" - } - }, - { - "adkernel": { - "alias": "headbidding" - } - }, - { - "getintent": { - "supportedMediaTypes" : ["video"] - } - }, - { - "stickyadstv": { - "alias": "freewheel-ssp" - } - }, - { - "rhythmone": { - "supportedMediaTypes": ["video"] - } - }, - { - "admixer": { - "supportedMediaTypes": ["video"] - } - }, - { - "conversant": { - "supportedMediaTypes": ["video"] - } - } -] diff --git a/analytics.json b/analytics.json deleted file mode 100644 index fe51488c706..00000000000 --- a/analytics.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/gulpHelpers.js b/gulpHelpers.js index 6091dc4c495..5225cfb32e8 100644 --- a/gulpHelpers.js +++ b/gulpHelpers.js @@ -4,6 +4,26 @@ const path = require('path'); const argv = require('yargs').argv; const MANIFEST = 'package.json'; const exec = require('child_process').exec; +const through = require('through2'); +const _ = require('lodash'); +const gutil = require('gulp-util'); + +const MODULE_PATH = './modules'; +const BUILD_PATH = './build/dist'; +const DEV_PATH = './build/dev'; + + +// get only subdirectories that contain package.json with 'main' property +function isModuleDirectory(filePath) { + try { + const manifestPath = path.join(filePath, MANIFEST); + if (fs.statSync(manifestPath).isFile()) { + const module = require(manifestPath); + return module && module.main; + } + } + catch (error) {} +} module.exports = { parseBrowserArgs: function (argv) { @@ -20,6 +40,85 @@ module.exports = { .replace(/<\//g, '<\\/') .replace(/\/>/g, '\\/>'); }, + getArgModules() { + var modules = (argv.modules || '').split(',').filter(module => !!module); + + try { + if (modules.length === 1 && path.extname(modules[0]).toLowerCase() === '.json') { + var moduleFile = modules[0]; + + modules = JSON.parse( + fs.readFileSync(moduleFile, 'utf8') + ); + } + } catch(e) { + throw new gutil.PluginError({ + plugin: 'modules', + message: 'failed reading: ' + argv.modules + }); + } + + return modules; + }, + getModules: _.memoize(function(externalModules) { + externalModules = externalModules || []; + var internalModules; + try { + internalModules = fs.readdirSync(MODULE_PATH) + .filter(file => !(/(^|\/)\.[^\/\.]/g).test(file)) + .reduce((memo, file) => { + var moduleName = file.split(new RegExp('[.' + path.sep + ']'))[0]; + var filePath = path.join(MODULE_PATH, file); + var modulePath = path.join(__dirname, filePath) + if (fs.lstatSync(filePath).isDirectory()) { + modulePath = path.join(__dirname, filePath, "index.js") + } + memo[modulePath] = moduleName; + return memo; + }, {}); + } catch(err) { + internalModules = {}; + } + return Object.assign(externalModules.reduce((memo, module) => { + try { + var modulePath = require.resolve(module); + memo[modulePath] = module; + } catch(err) { + // do something + } + return memo; + }, internalModules)); + }), + + getBuiltModules: function(dev, externalModules) { + var modules = this.getModuleNames(externalModules); + if(Array.isArray(externalModules)) { + modules = _.intersection(modules, externalModules); + } + return modules.map(name => path.join(__dirname, dev ? DEV_PATH : BUILD_PATH, name + '.js')); + }, + + getBuiltPrebidCoreFile: function(dev) { + return path.join(__dirname, dev ? DEV_PATH : BUILD_PATH, 'prebid-core' + '.js'); + }, + + getModulePaths: function(externalModules) { + var modules = this.getModules(externalModules); + return Object.keys(modules); + }, + + getModuleNames: function(externalModules) { + return _.values(this.getModules(externalModules)); + }, + + nameModules: function(externalModules) { + var modules = this.getModules(externalModules); + return through.obj(function(file, enc, done) { + file.named = modules[file.path] ? modules[file.path] : 'prebid'; + this.push(file); + done(); + }) + }, /* * Get source files for analytics subdirectories in top-level `analytics` @@ -37,18 +136,6 @@ module.exports = { const module = require(path.join(directory, moduleDirectory, MANIFEST)); return path.join(directory, moduleDirectory, module.main); }); - - // get only subdirectories that contain package.json with 'main' property - function isModuleDirectory(filePath) { - try { - const manifestPath = path.join(filePath, MANIFEST); - if (fs.statSync(manifestPath).isFile()) { - const module = require(manifestPath); - return module && module.main; - } - } - catch (error) {} - } }, createEnd2EndTestReport : function(targetDestinationDir) { diff --git a/gulpfile.js b/gulpfile.js index 46334996870..5a7b588820f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,3 +1,7 @@ +'use strict'; + +var _ = require('lodash'); +var argv = require('yargs').argv; var gulp = require('gulp'); var argv = require('yargs').argv; var gutil = require('gulp-util'); @@ -6,7 +10,6 @@ var webpack = require('webpack-stream'); var uglify = require('gulp-uglify'); var clean = require('gulp-clean'); var karma = require('gulp-karma'); -var mocha = require('gulp-mocha'); var opens = require('open'); var webpackConfig = require('./webpack.conf.js'); var helpers = require('./gulpHelpers'); @@ -14,11 +17,15 @@ var del = require('del'); var gulpJsdoc2md = require('gulp-jsdoc-to-markdown'); var concat = require('gulp-concat'); var header = require('gulp-header'); +var footer = require('gulp-footer'); var zip = require('gulp-zip'); var replace = require('gulp-replace'); var shell = require('gulp-shell'); var optimizejs = require('gulp-optimize-js'); -const eslint = require('gulp-eslint'); +var eslint = require('gulp-eslint'); +var gulpif = require('gulp-if'); +var sourcemaps = require('gulp-sourcemaps'); +var fs = require('fs'); var CI_MODE = process.env.NODE_ENV === 'ci'; var prebid = require('./package.json'); @@ -29,15 +36,15 @@ var analyticsDirectory = '../analytics'; var port = 9999; // Tasks -gulp.task('default', ['clean', 'lint', 'webpack']); +gulp.task('default', ['clean', 'webpack']); -gulp.task('serve', ['clean', 'lint', 'devpack', 'webpack', 'watch', 'test']); +gulp.task('serve', ['clean', 'lint', 'build-bundle-dev', 'watch', 'test']); gulp.task('serve-nw', ['clean', 'lint', 'devpack', 'webpack', 'watch', 'e2etest']); -gulp.task('run-tests', ['clean', 'lint', 'webpack', 'test', 'mocha']); +gulp.task('run-tests', ['clean', 'lint', 'webpack', 'test']); -gulp.task('build', ['webpack']); +gulp.task('build', ['build-bundle-prod']); gulp.task('clean', function () { return gulp.src(['build'], { @@ -46,10 +53,53 @@ gulp.task('clean', function () { .pipe(clean()); }); +function bundle(dev) { + var modules = helpers.getArgModules(), + allModules = helpers.getModuleNames(modules); + + if(modules.length === 0) { + modules = allModules; + } else { + var diff = _.difference(modules, allModules); + if(diff.length !== 0) { + throw new gutil.PluginError({ + plugin: 'bundle', + message: 'invalid modules: ' + diff.join(', ') + }); + } + } + + var entries = [helpers.getBuiltPrebidCoreFile(dev)].concat(helpers.getBuiltModules(dev, modules)); + + gutil.log('Concatenating files:\n', entries); + gutil.log('Appending ' + prebid.globalVarName + '.processQueue();'); + + return gulp.src( + entries + ) + .pipe(gulpif(dev, sourcemaps.init({loadMaps: true}))) + .pipe(concat(argv.bundleName ? argv.bundleName : 'prebid.js')) + .pipe(gulpif(!argv.manualEnable, footer('\n<%= global %>.processQueue();', { + global: prebid.globalVarName + } + ))) + .pipe(gulpif(dev, sourcemaps.write('.'))) + .pipe(gulp.dest('build/' + (dev ? 'dev' : 'dist'))); +} + +gulp.task('build-bundle-dev', ['devpack'], bundle.bind(null, true)); +gulp.task('build-bundle-prod', ['webpack'], bundle.bind(null, false)); +gulp.task('bundle', bundle.bind(null, false)); // used for just concatenating pre-built files with no build step + gulp.task('devpack', ['clean'], function () { webpackConfig.devtool = 'source-map'; + var externalModules = helpers.getArgModules(); + const analyticsSources = helpers.getAnalyticsSources(analyticsDirectory); - return gulp.src([].concat(analyticsSources, 'src/prebid.js')) + const moduleSources = helpers.getModulePaths(externalModules); + + return gulp.src([].concat(moduleSources, analyticsSources, 'src/prebid.js')) + .pipe(helpers.nameModules(externalModules)) .pipe(webpack(webpackConfig)) .pipe(replace('$prebid.version$', prebid.version)) .pipe(gulp.dest('build/dev')) @@ -65,12 +115,17 @@ gulp.task('webpack', ['clean'], function () { webpackConfig.devtool = null; + var externalModules = helpers.getArgModules(); + const analyticsSources = helpers.getAnalyticsSources(analyticsDirectory); - return gulp.src([].concat(analyticsSources, 'src/prebid.js')) + const moduleSources = helpers.getModulePaths(externalModules); + + return gulp.src([].concat(moduleSources, analyticsSources, 'src/prebid.js')) + .pipe(helpers.nameModules(externalModules)) .pipe(webpack(webpackConfig)) .pipe(replace('$prebid.version$', prebid.version)) .pipe(uglify()) - .pipe(header(banner, { prebid: prebid })) + .pipe(gulpif(file => file.basename === 'prebid.js', header(banner, { prebid: prebid }))) .pipe(optimizejs()) .pipe(gulp.dest('build/dist')) .pipe(connect.reload()); @@ -134,26 +189,6 @@ gulp.task('test', ['clean'], function () { })); }); -// -// Making this task depend on lint is a bit of a hack. The `run-tests` command is the entrypoint for the CI process, -// and it needs to run all these tasks together. However, the "lint" and "mocha" tasks explode when used in parallel, -// resulting in some mysterious "ShellJS: internal error TypeError: Cannot read property 'isFile' of undefined" -// errors. -// -// Gulp doesn't support serial dependencies (until gulp 4.0... which is most likely never coming out)... so we have -// to trick it by declaring 'lint' as a dependency here. See https://github.com/gulpjs/gulp/blob/master/docs/recipes/running-tasks-in-series.md -// -gulp.task('mocha', ['webpack', 'lint'], function() { - return gulp.src(['test/spec/loaders/**/*.js'], { read: false }) - .pipe(mocha({ - reporter: 'spec', - globals: { - expect: require('chai').expect - } - })) - .on('error', gutil.log); -}); - // Small task to load coverage reports in the browser gulp.task('coverage', function (done) { var coveragePort = 1999; @@ -179,13 +214,15 @@ gulp.task('watch', function () { gulp.watch([ 'src/**/*.js', + 'modules/**/*.js', 'test/spec/**/*.js', '!test/spec/loaders/**/*.js' - ], ['clean', 'lint', 'webpack', 'devpack', 'test']); + ], ['lint', 'build-bundle-dev', 'test']); gulp.watch([ 'loaders/**/*.js', 'test/spec/loaders/**/*.js' - ], ['lint', 'mocha']); + ], ['lint']); + gulp.watch(['integrationExamples/gpt/*.html'], ['test']); connect.server({ https: argv.https, port: port, diff --git a/karma.conf.js b/karma.conf.js index 3da7b378cbd..97a40d8430e 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -9,6 +9,9 @@ webpackConfig.module.postLoaders = [ } ]; +// remove optimize plugin for tests +webpackConfig.plugins.pop(); + var CI_MODE = process.env.NODE_ENV === 'ci'; module.exports = function (config) { @@ -38,19 +41,16 @@ module.exports = function (config) { // list of files / patterns to load in the browser files: [ + 'test/helpers/prebidGlobal.js', 'test/**/*_spec.js', 'test/helpers/karma-init.js' ], - // list of files to exclude - exclude: [ - 'test/spec/loaders/**/*.js' - ], - // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { 'test/**/*_spec.js': ['webpack'], + 'test/helpers/prebidGlobal.js': ['webpack'], '!test/**/*_spec.js': 'coverage', 'src/**/*.js': ['webpack', 'coverage'] }, diff --git a/loaders/adapterLoader.js b/loaders/adapterLoader.js deleted file mode 100644 index 65c189584c2..00000000000 --- a/loaders/adapterLoader.js +++ /dev/null @@ -1,160 +0,0 @@ -/** adapterLoader - * Webpack loader to insert dynamic javascript into `./src/adaptermanager.js` - * This is used in `./webpack.conf.js` - * */ - -'use strict'; -const fs = require('fs'); -const blockLoader = require('block-loader'); -const getAdapters = require('./getAdapters'); - -const adapters = getAdapters('adapters.json', 'adapters'); -const files = fs.readdirSync('src/adapters').map((file) => file.replace(/\.[^/.]+$/, '')); -const adapterNames = adapters.filter(getStandardAdapters).filter(getUniques); -//adapters loaded from `srcPath` -const customAdapters = adapters.map(getCustomAdapters).filter(adapter => { - //filter undefined - return !!adapter; -}); -const aliases = adapters.filter(getAliases); -const videoAdapters = adapters.filter(getVideoAdapters).map(getNames); - -var options = { - start: '/** INSERT ADAPTERS - DO NOT EDIT OR REMOVE */', - end: '/** END INSERT ADAPTERS */', - process: insertAdapters -}; - -/** - * Returns a block of javascript statements to load adapter modules, register the adapters and - * set adapter aliases - * @returns {*} - */ -function insertAdapters() { - - if (!adapters) { - console.log('Prebid Warning: adapters config not found in adapters.json, no adapters will' + - ' be loaded'); - return ''; - } - - let inserts = adapterNames.map(name => { - if (files.includes(name)) { - return name; - } else { - console.log(`Prebid Warning: no adapter found for ${name}, continuing.`); - } - }); - - inserts = inserts.map(name => { - return `var ${adapterName(name)} = require('./adapters/${name}.js'); - exports.registerBidAdapter(new ${adapterName(name)}(), '${name}');\n`; - }) - .concat(customAdapters.map(adapter => { - return `let ${adapter.name} = require('${adapter.srcPath}'); - exports.registerBidAdapter(new ${adapter.name}, '${adapter.name}');\n`; - })) - .concat(aliases.map(adapter => { - const name = getNameStr(adapter); - return `exports.aliasBidAdapter('${name}','${adapter[name].alias}');\n`; - })) - .concat(`exports.videoAdapters = ${JSON.stringify(videoAdapters)};`) - .join(''); - - if (!inserts.length) { - console.log('No matching adapters found for config, no adapters will be loaded.'); - return ''; - } - return inserts; -} - -/** - * Derive the variable name to use for the adapter - * @param adapter - * @returns {string} - */ -function adapterName(adapter) { - if (adapter) { - const result = adapter.split(''); - return result[0].toUpperCase() + result.join('').substr(1) + 'Adapter'; - } - return ''; -} - -/** - * Filter an array to return unique values - * @param value current array element value - * @param index current array element index - * @param self current array - * @returns {boolean} if true the current array element is returned - * - * http://stackoverflow.com/questions/1960473/unique-values-in-an-array - */ -function getUniques(value, index, self) { - return self.indexOf(value) === index; -} - -/** - * Filter to derive the adapter name from array elements as strings or objects - * @param adapter - * @returns {*} - */ -function getNames(adapter) { - // if `length` then `adapter` is a string, otherwise an object - return adapter.length ? adapter : getNameStr(adapter); -} - -/** - * Return adapter objects that have an alias field - * @param adapter - * @returns {*} - */ -function getAliases(adapter) { - const name = getNameStr(adapter); - return adapter && name && adapter[name].alias; -} - -/** - * Returns adapter objects that support video - */ -function getVideoAdapters(adapter) { - const name = getNameStr(adapter); - return adapter && name && adapter[name].supportedMediaTypes && - adapter[name].supportedMediaTypes.includes('video'); -} - -function getNameStr(adapter) { - return Object.keys(adapter)[0]; -} - -function getStandardAdapters(adapter) { - if (typeof adapter === 'string') { - return adapter; - } -} - -function getCustomAdapters(adapter) { - const srcPath = getSrcPath(adapter); - if (srcPath === '') { - return; - } - if (!fileExists(srcPath)) { - console.warn(`Not able to locate adapter at: ${srcPath} continuing`); - return; - } - return { - name: getNames(adapter), - srcPath: srcPath - }; -} - -function getSrcPath(adapter) { - const name = getNameStr(adapter); - return name && adapter[name].srcPath ? adapter[name].srcPath : ''; -} - -function fileExists(path) { - return fs.existsSync(path); -} - -module.exports = blockLoader(options); diff --git a/loaders/analyticsLoader.js b/loaders/analyticsLoader.js deleted file mode 100644 index 7e76a2819d6..00000000000 --- a/loaders/analyticsLoader.js +++ /dev/null @@ -1,41 +0,0 @@ -'use strict'; - -const fs = require('fs'); -const blockLoader = require('block-loader'); -const getAdapters = require('./getAdapters'); -let analyticsAdapters = getAdapters('analytics.json', 'analyticsAdapters'); - -var options = { - start: '/** INSERT ANALYTICS - DO NOT EDIT OR REMOVE */', - end: '/** END INSERT ANALYTICS */', - process: function insertAnalytics() { - // read directory for analytics adapter file names, map the file names to String.replace, - // use a regex to remove file extensions, then return the array of adapter names - const files = fs.readdirSync('src/adapters/analytics') - .map(file => file.replace(/\.[^/.]+$/, '')); - - let adapters = analyticsAdapters.map(adapter => adapter.length ? adapter : Object.keys(adapter)[0]); - - let inserts = adapters.filter(adapter => { - if (files.includes(adapter)) { - return adapter; - } else { - console.log(`Prebid Warning: no adapter found for ${adapter}, continuing.`); - } - }); - - // if no matching adapters and no adapter files found, exit - if (!inserts || !inserts.length) { - return null; - } - - // return the javascript strings to insert into adaptermanager.js - return inserts.map((adapter) => { - return `var ${adapter} = require('./adapters/analytics/${adapter}.js').default - || require('./adapters/analytics/${adapter}.js'); - exports.registerAnalyticsAdapter({ adapter: ${adapter}, code: '${adapter}' });\n`; - }).join(''); - } -}; - -module.exports = blockLoader(options); diff --git a/loaders/getAdapters.js b/loaders/getAdapters.js deleted file mode 100644 index b69a534fc7f..00000000000 --- a/loaders/getAdapters.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const argv = require('yargs').argv; - -function load(file) { - try { - const buffer = fs.readFileSync(file); - return JSON.parse(buffer.toString()); - } catch (e) { - return []; - } -} - -module.exports = function getAdapters(defaultAdapters, argName) { - let customAdapters = argv[argName]; - - if (!customAdapters) { - return load(defaultAdapters); - } - - customAdapters = path.resolve(process.cwd(), customAdapters); - - try { - fs.statSync(customAdapters); - return load(customAdapters); - } catch (e) { - console.log(`Prebid Warning: custom adapters config cannot be loaded from ${customAdapters}, ` + - `using default ${defaultAdapters}`); - return load(defaultAdapters); - } -}; diff --git a/loaders/nativeLoader.js b/loaders/nativeLoader.js deleted file mode 100644 index c8384135264..00000000000 --- a/loaders/nativeLoader.js +++ /dev/null @@ -1,45 +0,0 @@ -const blockLoader = require('block-loader'); -const getAdapters = require('./getAdapters'); - -const adapters = getAdapters('adapters.json', 'adapters'); -const nativeAdapters = adapters.filter(getNativeAdapters).map(getNames); - -const options = { - start: '/** INSERT NATIVE ADAPTERS - DO NOT EDIT OR REMOVE */', - end: '/** END INSERT NATIVE ADAPTERS */', - process: insertAdapters -}; - -/** - * Returns a block of javascript statements to load adapter modules, register the adapters and - * set adapter aliases - * @returns {*} - */ -function insertAdapters() { - return `const nativeAdapters = ${JSON.stringify(nativeAdapters)};`; -} - -/** - * Filter to derive the adapter name from array elements as strings or objects - * @param adapter - * @returns {*} - */ -function getNames(adapter) { - // if `length` then `adapter` is a string, otherwise an object - return adapter.length ? adapter : getNameStr(adapter); -} - -/** - * Returns adapter objects that support native - */ -function getNativeAdapters(adapter) { - const name = getNameStr(adapter); - return adapter && name && adapter[name].supportedMediaTypes && - adapter[name].supportedMediaTypes.includes('native'); -} - -function getNameStr(adapter) { - return Object.keys(adapter)[0]; -} - -module.exports = blockLoader(options); diff --git a/src/adapters/aardvark.js b/modules/aardvarkBidAdapter.js similarity index 92% rename from src/adapters/aardvark.js rename to modules/aardvarkBidAdapter.js index e8a3cc5ab38..65c90b3be47 100644 --- a/src/adapters/aardvark.js +++ b/modules/aardvarkBidAdapter.js @@ -4,12 +4,13 @@ * or for additional integration support please contact sales@rtk.io */ -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader.js'); -var adapter = require('./adapter.js'); -var constants = require('../constants.json'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader.js'); +var adapter = require('src/adapter.js'); +var constants = require('src/constants.json'); +var adaptermanager = require('src/adaptermanager'); var AARDVARK_CALLBACK_NAME = 'aardvarkResponse', AARDVARK_REQUESTS_MAP = 'aardvarkRequests', @@ -123,4 +124,6 @@ exports.createNew = function() { return new AardvarkAdapter(); }; +adaptermanager.registerBidAdapter(new AardvarkAdapter, 'aardvark'); + module.exports = AardvarkAdapter; diff --git a/src/adapters/adblade.js b/modules/adbladeBidAdapter.js similarity index 92% rename from src/adapters/adblade.js rename to modules/adbladeBidAdapter.js index 9e781561dc3..ab0a7a83cb3 100644 --- a/src/adapters/adblade.js +++ b/modules/adbladeBidAdapter.js @@ -1,7 +1,8 @@ -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader'); +var adaptermanager = require('src/adaptermanager'); /** * Adapter for requesting bids from Adblade @@ -129,4 +130,6 @@ var AdbladeAdapter = function AdbladeAdapter() { }; }; +adaptermanager.registerBidAdapter(new AdbladeAdapter, 'adblade'); + module.exports = AdbladeAdapter; diff --git a/src/adapters/adbund.js b/modules/adbundBidAdapter.js similarity index 83% rename from src/adapters/adbund.js rename to modules/adbundBidAdapter.js index 19630ce7007..a7c2bd45257 100644 --- a/src/adapters/adbund.js +++ b/modules/adbundBidAdapter.js @@ -1,8 +1,9 @@ -var CONSTANTS = require('../constants.json'); -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader'); +var CONSTANTS = require('src/constants.json'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader'); +var adaptermanager = require('src/adaptermanager'); var adBundAdapter = function adBundAdapter() { var timezone = (new Date()).getTimezoneOffset(); @@ -63,4 +64,6 @@ var adBundAdapter = function adBundAdapter() { }; }; +adaptermanager.registerBidAdapter(new adBundAdapter, 'adbund'); + module.exports = adBundAdapter; diff --git a/src/adapters/adbutler.js b/modules/adbutlerBidAdapter.js similarity index 93% rename from src/adapters/adbutler.js rename to modules/adbutlerBidAdapter.js index 428f7b3831a..8fbbba305ac 100644 --- a/src/adapters/adbutler.js +++ b/modules/adbutlerBidAdapter.js @@ -5,10 +5,11 @@ 'use strict'; -var utils = require('../utils.js'); -var adloader = require('../adloader.js'); -var bidmanager = require('../bidmanager.js'); -var bidfactory = require('../bidfactory.js'); +var utils = require('src/utils.js'); +var adloader = require('src/adloader.js'); +var bidmanager = require('src/bidmanager.js'); +var bidfactory = require('src/bidfactory.js'); +var adaptermanager = require('src/adaptermanager'); var AdButlerAdapter = function AdButlerAdapter() { function _callBids(params) { @@ -138,4 +139,6 @@ var AdButlerAdapter = function AdButlerAdapter() { }; }; +adaptermanager.registerBidAdapter(new AdButlerAdapter, 'adbutler'); + module.exports = AdButlerAdapter; diff --git a/src/adapters/adequant.js b/modules/adequantBidAdapter.js similarity index 85% rename from src/adapters/adequant.js rename to modules/adequantBidAdapter.js index f756b7e9aaa..b45b976ac28 100644 --- a/src/adapters/adequant.js +++ b/modules/adequantBidAdapter.js @@ -1,10 +1,11 @@ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader.js'); -var utils = require('../utils.js'); -var CONSTANTS = require('../constants.json'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader.js'); +var utils = require('src/utils.js'); +var CONSTANTS = require('src/constants.json'); +var adaptermanager = require('src/adaptermanager'); -module.exports = function() { +function AdequantAdapter() { var req_url_base = 'https://rex.adequant.com/rex/c2s_prebid?'; function _callBids(params) { @@ -70,4 +71,8 @@ module.exports = function() { return { callBids: _callBids }; -}; +} + +adaptermanager.registerBidAdapter(new AdequantAdapter, 'adequant'); + +module.exports = AdequantAdapter; diff --git a/src/adapters/adform.js b/modules/adformBidAdapter.js similarity index 92% rename from src/adapters/adform.js rename to modules/adformBidAdapter.js index 31eceba0b0d..7f7cc13d059 100644 --- a/src/adapters/adform.js +++ b/modules/adformBidAdapter.js @@ -1,8 +1,9 @@ -var utils = require('../utils.js'); -var adloader = require('../adloader.js'); -var bidmanager = require('../bidmanager.js'); -var bidfactory = require('../bidfactory.js'); -var STATUSCODES = require('../constants.json').STATUS; +var utils = require('src/utils.js'); +var adloader = require('src/adloader.js'); +var bidmanager = require('src/bidmanager.js'); +var bidfactory = require('src/bidfactory.js'); +var STATUSCODES = require('src/constants.json').STATUS; +var adaptermanager = require('src/adaptermanager'); function AdformAdapter() { return { @@ -161,4 +162,6 @@ function AdformAdapter() { } } +adaptermanager.registerBidAdapter(new AdformAdapter, 'adform'); + module.exports = AdformAdapter; diff --git a/src/adapters/adkernel.js b/modules/adkernelBidAdapter.js similarity index 97% rename from src/adapters/adkernel.js rename to modules/adkernelBidAdapter.js index 32415bcba41..cd0ec8eb3cd 100644 --- a/src/adapters/adkernel.js +++ b/modules/adkernelBidAdapter.js @@ -2,7 +2,8 @@ import bidmanager from 'src/bidmanager'; import bidfactory from 'src/bidfactory'; import * as utils from 'src/utils'; import {ajax} from 'src/ajax'; -import Adapter from 'src/adapters/adapter'; +import Adapter from 'src/adapter'; +import adaptermanager from 'src/adaptermanager'; /** * Adapter for requesting bids from AdKernel white-label platform @@ -267,4 +268,7 @@ AdKernelAdapter.createNew = function() { return new AdKernelAdapter(); }; +adaptermanager.registerBidAdapter(new AdKernelAdapter, 'adkernel'); +adaptermanager.aliasBidAdapter('adkernel', 'headbidding'); + module.exports = AdKernelAdapter; diff --git a/src/adapters/admedia.js b/modules/admediaBidAdapter.js similarity index 88% rename from src/adapters/admedia.js rename to modules/admediaBidAdapter.js index 7fb81868cfd..e933911d537 100644 --- a/src/adapters/admedia.js +++ b/modules/admediaBidAdapter.js @@ -1,9 +1,10 @@ -import { getBidRequest } from '../utils.js'; -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader.js'); -var utils = require('../utils.js'); -var CONSTANTS = require('../constants.json'); +import { getBidRequest } from 'src/utils'; +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader.js'); +var utils = require('src/utils.js'); +var CONSTANTS = require('src/constants.json'); +var adaptermanager = require('src/adaptermanager'); /** * Adapter for requesting bids from AdMedia. @@ -99,4 +100,6 @@ var AdmediaAdapter = function AdmediaAdapter() { }; }; +adaptermanager.registerBidAdapter(new AdmediaAdapter, 'admedia'); + module.exports = AdmediaAdapter; diff --git a/src/adapters/admixer.js b/modules/admixerBidAdapter.js similarity index 87% rename from src/adapters/admixer.js rename to modules/admixerBidAdapter.js index 24cf81bf9e9..d0b4515133a 100644 --- a/src/adapters/admixer.js +++ b/modules/admixerBidAdapter.js @@ -1,7 +1,8 @@ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var Ajax = require('../ajax'); -var utils = require('../utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var Ajax = require('src/ajax'); +var utils = require('src/utils.js'); +var adaptermanager = require('src/adaptermanager'); /** * Adapter for requesting bids from Admixer. @@ -80,4 +81,8 @@ var AdmixerAdapter = function AdmixerAdapter() { }; }; +adaptermanager.registerBidAdapter(new AdmixerAdapter, 'admixer', { + supportedMediaTypes: ['video'] +}); + module.exports = AdmixerAdapter; diff --git a/src/adapters/adsupply.js b/modules/adsupplyBidAdapter.js similarity index 90% rename from src/adapters/adsupply.js rename to modules/adsupplyBidAdapter.js index d6c3cda6334..8d7aa1ef4a6 100644 --- a/src/adapters/adsupply.js +++ b/modules/adsupplyBidAdapter.js @@ -1,7 +1,9 @@ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader'); -var utils = require('../utils'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader'); +var utils = require('src/utils'); +var adaptermanager = require('src/adaptermanager'); + const ADSUPPLY_CODE = 'adsupply'; var AdSupplyAdapter = function AdSupplyAdapter() { @@ -83,4 +85,6 @@ var AdSupplyAdapter = function AdSupplyAdapter() { }; }; +adaptermanager.registerBidAdapter(new AdSupplyAdapter, 'adsupply'); + module.exports = AdSupplyAdapter; diff --git a/src/adapters/adyoulike.js b/modules/adyoulikeBidAdapter.js similarity index 97% rename from src/adapters/adyoulike.js rename to modules/adyoulikeBidAdapter.js index 7ee65eebe06..b9e958ac16b 100644 --- a/src/adapters/adyoulike.js +++ b/modules/adyoulikeBidAdapter.js @@ -1,10 +1,11 @@ -import Adapter from 'src/adapters/adapter'; +import Adapter from 'src/adapter'; import bidfactory from 'src/bidfactory'; import bidmanager from 'src/bidmanager'; import * as utils from 'src/utils'; import { format } from 'src/url'; import { ajax } from 'src/ajax'; import { STATUS } from 'src/constants'; +import adaptermanager from 'src/adaptermanager'; var AdyoulikeAdapter = function AdyoulikeAdapter() { const _VERSION = '0.1'; @@ -198,4 +199,6 @@ AdyoulikeAdapter.createNew = function () { return new AdyoulikeAdapter(); }; +adaptermanager.registerBidAdapter(new AdyoulikeAdapter, 'adyoulike'); + module.exports = AdyoulikeAdapter; diff --git a/src/adapters/aol.js b/modules/aolBidAdapter.js similarity index 96% rename from src/adapters/aol.js rename to modules/aolBidAdapter.js index 32039b14362..1f0b3a5bbb0 100644 --- a/src/adapters/aol.js +++ b/modules/aolBidAdapter.js @@ -1,8 +1,9 @@ -const utils = require('../utils.js'); -const ajax = require('../ajax.js').ajax; -const bidfactory = require('../bidfactory.js'); -const bidmanager = require('../bidmanager.js'); -const constants = require('../constants.json'); +const utils = require('src/utils.js'); +const ajax = require('src/ajax.js').ajax; +const bidfactory = require('src/bidfactory.js'); +const bidmanager = require('src/bidmanager.js'); +const constants = require('src/constants.json'); +const adaptermanager = require('src/adaptermanager'); $$PREBID_GLOBAL$$.aolGlobals = { pixelsDropped: false @@ -302,4 +303,6 @@ const AolAdapter = function AolAdapter() { }; }; +adaptermanager.registerBidAdapter(new AolAdapter, 'aol'); + module.exports = AolAdapter; diff --git a/modules/appnexusAnalyticsAdapter.js b/modules/appnexusAnalyticsAdapter.js new file mode 100644 index 00000000000..f9756de23e3 --- /dev/null +++ b/modules/appnexusAnalyticsAdapter.js @@ -0,0 +1,19 @@ +/** + * appnexus.js - AppNexus Prebid Analytics Adapter + */ + +import adapter from 'src/AnalyticsAdapter'; +import adaptermanager from 'src/adaptermanager'; + +var appnexusAdapter = adapter({ + global: 'AppNexusPrebidAnalytics', + handler: 'on', + analyticsType: 'bundle' +}); + +adaptermanager.registerAnalyticsAdapter({ + adapter: appnexusAdapter, + code: 'appnexus' +}); + +export default appnexusAdapter; diff --git a/src/adapters/appnexusAst.js b/modules/appnexusAstBidAdapter.js similarity index 98% rename from src/adapters/appnexusAst.js rename to modules/appnexusAstBidAdapter.js index 193d12fa049..c7434680349 100644 --- a/src/adapters/appnexusAst.js +++ b/modules/appnexusAstBidAdapter.js @@ -1,10 +1,11 @@ -import Adapter from 'src/adapters/adapter'; +import Adapter from 'src/adapter'; import { Renderer } from 'src/Renderer'; import bidfactory from 'src/bidfactory'; import bidmanager from 'src/bidmanager'; import * as utils from 'src/utils'; import { ajax } from 'src/ajax'; import { STATUS } from 'src/constants'; +import adaptermanager from 'src/adaptermanager'; const ENDPOINT = '//ib.adnxs.com/ut/v3/prebid'; const SUPPORTED_AD_TYPES = ['banner', 'video', 'video-outstream', 'native']; @@ -376,4 +377,8 @@ AppnexusAstAdapter.createNew = function() { return new AppnexusAstAdapter(); }; +adaptermanager.registerBidAdapter(new AppnexusAstAdapter, 'appnexusAst', { + supportedMediaTypes: ['video', 'native'] +}); + module.exports = AppnexusAstAdapter; diff --git a/src/adapters/appnexus.js b/modules/appnexusBidAdapter.js similarity index 89% rename from src/adapters/appnexus.js rename to modules/appnexusBidAdapter.js index fee88da7bf3..46b08314d7b 100644 --- a/src/adapters/appnexus.js +++ b/modules/appnexusBidAdapter.js @@ -1,11 +1,12 @@ -import { getBidRequest } from '../utils.js'; +import { getBidRequest } from 'src/utils'; +import adaptermanager from 'src/adaptermanager'; -var CONSTANTS = require('../constants.json'); -var utils = require('../utils.js'); -var adloader = require('../adloader.js'); -var bidmanager = require('../bidmanager.js'); -var bidfactory = require('../bidfactory.js'); -var Adapter = require('./adapter.js'); +var CONSTANTS = require('src/constants'); +var utils = require('src/utils'); +var adloader = require('src/adloader'); +var bidmanager = require('src/bidmanager'); +var bidfactory = require('src/bidfactory'); +var Adapter = require('src/adapter'); var AppNexusAdapter; AppNexusAdapter = function AppNexusAdapter() { @@ -225,4 +226,13 @@ AppNexusAdapter.createNew = function () { return new AppNexusAdapter(); }; +adaptermanager.registerBidAdapter(new AppNexusAdapter, 'appnexus'); +adaptermanager.aliasBidAdapter('appnexus', 'brealtime'); +adaptermanager.aliasBidAdapter('appnexus', 'pagescience'); +adaptermanager.aliasBidAdapter('appnexus', 'defymedia'); +adaptermanager.aliasBidAdapter('appnexus', 'gourmetads'); +adaptermanager.aliasBidAdapter('appnexus', 'matomy'); +adaptermanager.aliasBidAdapter('appnexus', 'featureforward'); +adaptermanager.aliasBidAdapter('appnexus', 'oftmedia'); + module.exports = AppNexusAdapter; diff --git a/src/adapters/atomx.js b/modules/atomxBidAdapter.js similarity index 85% rename from src/adapters/atomx.js rename to modules/atomxBidAdapter.js index 4935382123a..9acf2339af9 100644 --- a/src/adapters/atomx.js +++ b/modules/atomxBidAdapter.js @@ -1,9 +1,10 @@ -var CONSTANTS = require('../constants.json'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); +var CONSTANTS = require('src/constants.json'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); var adloader = require('src/adloader.js'); -var Ajax = require('../ajax'); -var utils = require('../utils.js'); +var Ajax = require('src/ajax'); +var utils = require('src/utils.js'); +var adaptermanager = require('src/adaptermanager'); /** * Adapter for requesting bids from Atomx. @@ -72,4 +73,7 @@ var AtomxAdapter = function AtomxAdapter() { }; }; + +adaptermanager.registerBidAdapter(new AtomxAdapter, 'atomx'); + module.exports = AtomxAdapter; diff --git a/src/adapters/audienceNetwork.js b/modules/audienceNetworkBidAdapter.js similarity index 96% rename from src/adapters/audienceNetwork.js rename to modules/audienceNetworkBidAdapter.js index 867f3c6f89a..7e054fe7d54 100644 --- a/src/adapters/audienceNetwork.js +++ b/modules/audienceNetworkBidAdapter.js @@ -1,13 +1,14 @@ /** * @file AudienceNetwork adapter. */ -import { ajax } from '../ajax'; -import { createBid } from '../bidfactory'; -import { addBidResponse } from '../bidmanager'; -import { STATUS } from '../constants.json'; -import { format } from '../url'; -import { logError } from '../utils'; -import { createNew } from './adapter'; +import { ajax } from 'src/ajax'; +import { createBid } from 'src/bidfactory'; +import { addBidResponse } from 'src/bidmanager'; +import { STATUS } from 'src/constants.json'; +import { format } from 'src/url'; +import { logError } from 'src/utils'; +import { createNew } from 'src/adapter'; +import adaptermanager from 'src/adaptermanager'; const { setBidderCode, getBidderCode } = createNew('audienceNetwork'); @@ -201,4 +202,6 @@ const callBids = bidRequest => { */ const AudienceNetwork = () => ({ callBids, setBidderCode, getBidderCode }); +adaptermanager.registerBidAdapter(new AudienceNetwork, 'audienceNetwork'); + module.exports = AudienceNetwork; diff --git a/src/adapters/beachfront.js b/modules/beachfrontBidAdapter.js similarity index 95% rename from src/adapters/beachfront.js rename to modules/beachfrontBidAdapter.js index de596f76e7e..059d15ac79d 100644 --- a/src/adapters/beachfront.js +++ b/modules/beachfrontBidAdapter.js @@ -1,9 +1,10 @@ -import Adapter from 'src/adapters/adapter'; +import Adapter from 'src/adapter'; import bidfactory from 'src/bidfactory'; import bidmanager from 'src/bidmanager'; import * as utils from 'src/utils'; import { ajax } from 'src/ajax'; import { STATUS } from 'src/constants'; +import adaptermanager from 'src/adaptermanager'; const ENDPOINT = '//reachms.bfmio.com/bid.json?exchange_id='; @@ -132,4 +133,8 @@ BeachfrontAdapter.createNew = function () { return new BeachfrontAdapter(); }; +adaptermanager.registerBidAdapter(new BeachfrontAdapter, 'beachfront', { + supportedMediaTypes: ['video'] +}); + module.exports = BeachfrontAdapter; diff --git a/src/adapters/bidfluence.js b/modules/bidfluenceBidAdapter.js similarity index 82% rename from src/adapters/bidfluence.js rename to modules/bidfluenceBidAdapter.js index c3c32c579f1..da22096b7e6 100644 --- a/src/adapters/bidfluence.js +++ b/modules/bidfluenceBidAdapter.js @@ -1,55 +1,58 @@ -const bidmanager = require('../bidmanager.js'); -const bidfactory = require('../bidfactory.js'); -const utils = require('../utils.js'); -const adloader = require('../adloader'); - +const bidmanager = require('src/bidmanager'); +const bidfactory = require('src/bidfactory'); +const utils = require('src/utils'); +const adloader = require('src/adloader'); +const adaptermanager = require('src/adaptermanager'); + var BidfluenceAdapter = function BidfluenceAdapter() { - const scriptUrl = '//cdn.bidfluence.com/forge.js'; - - $$PREBID_GLOBAL$$.bfPbjsCB = function (bfr) { - var bidRequest = utils.getBidRequest(bfr.cbID); - var bidObject = null; - if (bfr.cpm > 0) { - bidObject = bidfactory.createBid(1, bidRequest); - bidObject.bidderCode = 'bidfluence'; - bidObject.cpm = bfr.cpm; - bidObject.ad = bfr.ad; - bidObject.width = bfr.width; - bidObject.height = bfr.height; - } else { - bidObject = bidfactory.createBid(2, bidRequest); - bidObject.bidderCode = 'bidfluence'; - } - - bidmanager.addBidResponse(bfr.placementCode, bidObject); - }; - - function _callBids(params) { - var bfbids = params.bids || []; - for (var i = 0; i < bfbids.length; i++) { - var bid = bfbids[i]; - call(bid); - } - } + const scriptUrl = '//cdn.bidfluence.com/forge.js'; + + $$PREBID_GLOBAL$$.bfPbjsCB = function (bfr) { + var bidRequest = utils.getBidRequest(bfr.cbID); + var bidObject = null; + if (bfr.cpm > 0) { + bidObject = bidfactory.createBid(1, bidRequest); + bidObject.bidderCode = 'bidfluence'; + bidObject.cpm = bfr.cpm; + bidObject.ad = bfr.ad; + bidObject.width = bfr.width; + bidObject.height = bfr.height; + } else { + bidObject = bidfactory.createBid(2, bidRequest); + bidObject.bidderCode = 'bidfluence'; + } + + bidmanager.addBidResponse(bfr.placementCode, bidObject); + }; + + function _callBids(params) { + var bfbids = params.bids || []; + for (var i = 0; i < bfbids.length; i++) { + var bid = bfbids[i]; + call(bid); + } + } function call(bid) { - var adunitId = utils.getBidIdParameter('adunitId', bid.params); - var publisherId = utils.getBidIdParameter('pubId', bid.params); - var reservePrice = utils.getBidIdParameter('reservePrice', bid.params); - var pbjsBfobj = { - placementCode: bid.placementCode, - cbID: bid.bidId - }; - - var cb = function () { - /* globals FORGE */ - FORGE.init([adunitId, publisherId, pbjsBfobj, reservePrice]); - }; - - adloader.loadScript(scriptUrl, cb); - } - return { - callBids: _callBids - }; -}; - -module.exports = BidfluenceAdapter; + var adunitId = utils.getBidIdParameter('adunitId', bid.params); + var publisherId = utils.getBidIdParameter('pubId', bid.params); + var reservePrice = utils.getBidIdParameter('reservePrice', bid.params); + var pbjsBfobj = { + placementCode: bid.placementCode, + cbID: bid.bidId + }; + + var cb = function () { + /* globals FORGE */ + FORGE.init([adunitId, publisherId, pbjsBfobj, reservePrice]); + }; + + adloader.loadScript(scriptUrl, cb); + } + return { + callBids: _callBids + }; +}; + +adaptermanager.registerBidAdapter(new BidfluenceAdapter, 'bidfluence'); + +module.exports = BidfluenceAdapter; diff --git a/src/adapters/brightcom.js b/modules/brightcomBidAdapter.js similarity index 95% rename from src/adapters/brightcom.js rename to modules/brightcomBidAdapter.js index 23cd6269b40..2f6d30275ea 100644 --- a/src/adapters/brightcom.js +++ b/modules/brightcomBidAdapter.js @@ -1,8 +1,9 @@ -var CONSTANTS = require('../constants.json'); -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader'); +var CONSTANTS = require('src/constants.json'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader'); +var adaptermanager = require('src/adaptermanager'); /** * Adapter for requesting bids from Brightcom @@ -199,4 +200,6 @@ var BrightcomAdapter = function BrightcomAdapter() { }; }; +adaptermanager.registerBidAdapter(new BrightcomAdapter, 'brightcom'); + module.exports = BrightcomAdapter; diff --git a/src/adapters/carambola.js b/modules/carambolaBidAdapter.js similarity index 94% rename from src/adapters/carambola.js rename to modules/carambolaBidAdapter.js index 18a7c154f6d..ae064e93ce1 100644 --- a/src/adapters/carambola.js +++ b/modules/carambolaBidAdapter.js @@ -2,12 +2,13 @@ * Carambola adapter */ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -const utils = require('../utils.js'); -const ajax = require('../ajax.js').ajax; +const bidfactory = require('src/bidfactory.js'); +const bidmanager = require('src/bidmanager.js'); +const utils = require('src/utils.js'); +const ajax = require('src/ajax.js').ajax; +const adaptermanager = require('src/adaptermanager'); -const CarambolaAdapter = function CarambolaAdapter() { +function CarambolaAdapter() { const BIDDER_CODE = 'carambola'; const REQUEST_PATH = 'hb/inimage/getHbBIdProcessedResponse'; @@ -188,6 +189,8 @@ const CarambolaAdapter = function CarambolaAdapter() { return { callBids: _callBids }; -}; +} + +adaptermanager.registerBidAdapter(new CarambolaAdapter, 'carambola'); module.exports = CarambolaAdapter; diff --git a/src/adapters/centro.js b/modules/centroBidAdapter.js similarity index 92% rename from src/adapters/centro.js rename to modules/centroBidAdapter.js index 903d475d712..5a04f330820 100644 --- a/src/adapters/centro.js +++ b/modules/centroBidAdapter.js @@ -1,7 +1,8 @@ -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader'); +var adaptermanager = require('src/adaptermanager'); var CentroAdapter = function CentroAdapter() { var baseUrl = '//t.brand-server.com/hb', @@ -114,4 +115,6 @@ var CentroAdapter = function CentroAdapter() { }; }; +adaptermanager.registerBidAdapter(new CentroAdapter, 'centro'); + module.exports = CentroAdapter; diff --git a/src/adapters/conversant.js b/modules/conversantBidAdapter.js similarity index 95% rename from src/adapters/conversant.js rename to modules/conversantBidAdapter.js index 974eb4c8100..12984b521db 100644 --- a/src/adapters/conversant.js +++ b/modules/conversantBidAdapter.js @@ -1,11 +1,12 @@ 'use strict'; var VERSION = '2.1.0'; -var CONSTANTS = require('../constants.json'); -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader'); -var ajax = require('../ajax').ajax; +var CONSTANTS = require('src/constants.json'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader'); +var ajax = require('src/ajax').ajax; +var adaptermanager = require('src/adaptermanager'); /** * Adapter for requesting bids from Conversant @@ -270,4 +271,8 @@ var ConversantAdapter = function () { }; }; +adaptermanager.registerBidAdapter(new ConversantAdapter, 'conversant', { + supportedMediaTypes: ['video'] +}); + module.exports = ConversantAdapter; diff --git a/src/adapters/cox.js b/modules/coxBidAdapter.js similarity index 94% rename from src/adapters/cox.js rename to modules/coxBidAdapter.js index e0e2a053251..0d0f5047c06 100644 --- a/src/adapters/cox.js +++ b/modules/coxBidAdapter.js @@ -1,255 +1,258 @@ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adLoader = require('../adloader.js'); - -var CoxAdapter = function CoxAdapter() { - var adZoneAttributeKeys = ['id', 'size', 'thirdPartyClickUrl'], - otherKeys = ['siteId', 'wrapper', 'referrerUrl'], - placementMap = {}, - W = window; - - var COX_BIDDER_CODE = 'cox'; - - function _callBids(params) { - var env = ''; - - // Create global cdsTag and CMT object (for the latter, only if needed ) - W.cdsTag = {}; - if (!W.CMT) W.CMT = _getCoxLite(); - - // Populate the tag with the info from prebid - var bids = params.bids || [], - tag = W.cdsTag, - i, - j; - for (i = 0; i < bids.length; i++) { - var bid = bids[i], - cfg = bid.params || {}; - - if (cfg.id) { - tag.zones = tag.zones || {}; - var zone = {}; - - for (j = 0; j < adZoneAttributeKeys.length; j++) { - if (cfg[adZoneAttributeKeys[j]]) zone[adZoneAttributeKeys[j]] = cfg[adZoneAttributeKeys[j]]; - } - for (j = 0; j < otherKeys.length; j++) { - if (cfg[otherKeys[j]]) tag[otherKeys[j]] = cfg[otherKeys[j]]; - } - var adZoneKey = 'as' + cfg.id; - tag.zones[adZoneKey] = zone; - - // Check for an environment setting - if (cfg.env) env = cfg.env; - - // Update the placement map - var xy = (cfg.size || '0x0').split('x'); - placementMap[adZoneKey] = { - p: bid.placementCode, - w: xy[0], - h: xy[1] - }; - } - } - if (tag.zones && Object.keys(tag.zones).length > 0) { - tag.__callback__ = function (r) { - tag.response = r; - _notify(); - }; - adLoader.loadScript(W.CMT.Service.buildSrc(tag, env)); - } - } - - function _notify() { - // Will execute in the context of a bid - // function finalizeAd(price) { - // this.ad = W.CMT.Service.setAuctionPrice(this.ad, price); - // return this; - // } - - for (var adZoneKey in placementMap) { - var bid = W.CMT.Service.getBidTrue(adZoneKey), - bidObj, - data = placementMap[adZoneKey]; - - if (bid > 0) { - bidObj = bidfactory.createBid(1); - bidObj.cpm = bid; - bidObj.ad = W.CMT.Service.getAd(adZoneKey); - bidObj.width = data.w; - bidObj.height = data.h; - // bidObj.floor = W.CMT.Service.getSecondPrice(adZoneKey); - // bidObj.finalizeAd = finalizeAd; - } else { - bidObj = bidfactory.createBid(2); - } - bidObj.bidderCode = COX_BIDDER_CODE; - bidmanager.addBidResponse(data.p, bidObj); - } - } - - function _getCoxLite() { - var CMT = {}; - - CMT.Util = (function () { - return { - - getRand: function getRand() { - return Math.round(Math.random() * 100000000); - }, - - encodeUriObject: function encodeUriObject(obj) { - return encodeURIComponent(JSON.stringify(obj)); - }, - - extractUrlInfo: function extractUrlInfo() { - function f2(callback) { - try { - if (!W.location.ancestorOrigins) return; - for (var i = 0, len = W.location.ancestorOrigins.length; len > i; i++) { - callback.call(null, W.location.ancestorOrigins[i], i); - } - } catch (ignore) { } - return []; - } - - function f1(callback) { - var oneWindow, - infoArray = []; - do { - try { - oneWindow = oneWindow ? oneWindow.parent : W; - callback.call(null, oneWindow, infoArray); - } catch (t) { - infoArray.push({ - referrer: null, - location: null, - isTop: !1 - }); - return infoArray; - } - } while (oneWindow !== W.top); - return infoArray; - } - var allInfo = f1(function (oneWindow, infoArray) { - try { - infoArray.push({ referrer: oneWindow.document.referrer || null, location: oneWindow.location.href || null, isTop: oneWindow === W.top }); - } catch (e) { - infoArray.push({ referrer: null, location: null, isTop: oneWindow === W.top }); - } - }); - f2(function (n, r) { - allInfo[r].ancestor = n; - }); - for (var t = '', e = !1, i = allInfo.length - 1, l = allInfo.length - 1; l >= 0; l--) { - t = allInfo[l].location; - if (!t && l > 0) { - t = allInfo[l - 1].referrer; - if (!t) t = allInfo[l - 1].ancestor; - if (t) { - e = W.location.ancestorOrigins ? !0 : l === allInfo.length - 1 && allInfo[allInfo.length - 1].isTop; - break; - } - } - } return { url: t, isTop: e, depth: i }; - }, - - srTestCapabilities: function srTestCapabilities() { - var plugins = navigator.plugins, - flashVer = -1, - sf = 'Shockwave Flash'; - - if (plugins && plugins.length > 0) { - if (plugins[sf + ' 2.0'] || plugins[sf]) { - var swVer2 = plugins[sf + ' 2.0'] ? ' 2.0' : ''; - var flashDescription = plugins[sf + swVer2].description; - flashVer = flashDescription.split(' ')[2].split('.')[0]; - } - } - if (flashVer > 4) return 15; else return 7; - } - - }; - }()); - - // Ad calling functionality - CMT.Service = (function () { - // Closure variables shared by the service functions - var U = CMT.Util; - - return { - - buildSrc: function buildSrc(tag, env) { - var src = (document.location.protocol === 'https:' ? 'https://' : 'http://') + (!env || env === 'PRD' ? '' : env === 'PPE' ? 'ppe-' : env === 'STG' ? 'staging-' : '') + 'ad.afy11.net/ad' + '?mode=11' + '&ct=' + U.srTestCapabilities() + '&nif=0' + '&sf=0' + '&sfd=0' + '&ynw=0' + '&rand=' + U.getRand() + '&hb=1' + '&rk1=' + U.getRand() + '&rk2=' + new Date().valueOf() / 1000; - - // Make sure we don't have a response object... - delete tag.response; - - // Extracted url info... - var urlInfo = U.extractUrlInfo(); - tag.pageUrl = urlInfo.url; - tag.puTop = urlInfo.isTop; - - // Attach the serialized tag to our string - src += '&ab=' + U.encodeUriObject(tag); - - return src; - }, - - getAd: function (zoneKey) { - if (!zoneKey) return; - - return this._getData(zoneKey, 'ad') + (this._getResponse().tpCookieSync || ''); // ...also append cookie sync if present - }, - - // getSecondPrice: function getSecondPrice(zoneKey) { - // if (zoneKey.substring(0, 2) !== 'as') zoneKey = 'as' + zoneKey; - // var bid = this.getBidTrue(zoneKey), - // floor = this._getData(zoneKey, 'floor'); - - // // If no floor, just set it to 80% of the bid - // if (!floor) floor = bid * 0.80; - - // // Adjust the floor if it's too high...it needs to always be lower - // if (floor >= bid) { - // floor = floor * 0.80; // Take off 20% to account for possible non-adjusted 2nd highest bid - - // // If it's still too high, just take 80% to 90% of the bid - // if (floor >= bid) floor = bid * ((Math.random() * 10) + 80) / 100; - // } - // return Math.round(floor * 100) / 100; - // }, - - // setAuctionPrice: function setAuctionPrice(ad, bid) { - // return ad ? ad.replace('${AUCTION_PRICE}', bid) : ad; - // }, - - getBidTrue: function getBidTrue(zoneKey) { - return Math.round(this._getData(zoneKey, 'price') * 100) / 100; - }, - - _getData: function (zoneKey, field) { - var response = this._getResponse(), - zoneResponseData = response.zones ? response.zones[zoneKey] : {}; - - return (zoneResponseData || {})[field] || null; - }, - - _getResponse: function () { - var tag = W.cdsTag; - return (tag && tag.response) ? tag.response : {}; - }, - }; - }()); - - return CMT; - } - - // Export the callBids function, so that prebid.js can execute this function - // when the page asks to send out bid requests. - return { - callBids: _callBids, - }; -}; - -module.exports = CoxAdapter; +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adLoader = require('src/adloader.js'); +var adaptermanager = require('src/adaptermanager'); + +function CoxAdapter() { + var adZoneAttributeKeys = ['id', 'size', 'thirdPartyClickUrl'], + otherKeys = ['siteId', 'wrapper', 'referrerUrl'], + placementMap = {}, + W = window; + + var COX_BIDDER_CODE = 'cox'; + + function _callBids(params) { + var env = ''; + + // Create global cdsTag and CMT object (for the latter, only if needed ) + W.cdsTag = {}; + if (!W.CMT) W.CMT = _getCoxLite(); + + // Populate the tag with the info from prebid + var bids = params.bids || [], + tag = W.cdsTag, + i, + j; + for (i = 0; i < bids.length; i++) { + var bid = bids[i], + cfg = bid.params || {}; + + if (cfg.id) { + tag.zones = tag.zones || {}; + var zone = {}; + + for (j = 0; j < adZoneAttributeKeys.length; j++) { + if (cfg[adZoneAttributeKeys[j]]) zone[adZoneAttributeKeys[j]] = cfg[adZoneAttributeKeys[j]]; + } + for (j = 0; j < otherKeys.length; j++) { + if (cfg[otherKeys[j]]) tag[otherKeys[j]] = cfg[otherKeys[j]]; + } + var adZoneKey = 'as' + cfg.id; + tag.zones[adZoneKey] = zone; + + // Check for an environment setting + if (cfg.env) env = cfg.env; + + // Update the placement map + var xy = (cfg.size || '0x0').split('x'); + placementMap[adZoneKey] = { + p: bid.placementCode, + w: xy[0], + h: xy[1] + }; + } + } + if (tag.zones && Object.keys(tag.zones).length > 0) { + tag.__callback__ = function (r) { + tag.response = r; + _notify(); + }; + adLoader.loadScript(W.CMT.Service.buildSrc(tag, env)); + } + } + + function _notify() { + // Will execute in the context of a bid + // function finalizeAd(price) { + // this.ad = W.CMT.Service.setAuctionPrice(this.ad, price); + // return this; + // } + + for (var adZoneKey in placementMap) { + var bid = W.CMT.Service.getBidTrue(adZoneKey), + bidObj, + data = placementMap[adZoneKey]; + + if (bid > 0) { + bidObj = bidfactory.createBid(1); + bidObj.cpm = bid; + bidObj.ad = W.CMT.Service.getAd(adZoneKey); + bidObj.width = data.w; + bidObj.height = data.h; + // bidObj.floor = W.CMT.Service.getSecondPrice(adZoneKey); + // bidObj.finalizeAd = finalizeAd; + } else { + bidObj = bidfactory.createBid(2); + } + bidObj.bidderCode = COX_BIDDER_CODE; + bidmanager.addBidResponse(data.p, bidObj); + } + } + + function _getCoxLite() { + var CMT = {}; + + CMT.Util = (function () { + return { + + getRand: function getRand() { + return Math.round(Math.random() * 100000000); + }, + + encodeUriObject: function encodeUriObject(obj) { + return encodeURIComponent(JSON.stringify(obj)); + }, + + extractUrlInfo: function extractUrlInfo() { + function f2(callback) { + try { + if (!W.location.ancestorOrigins) return; + for (var i = 0, len = W.location.ancestorOrigins.length; len > i; i++) { + callback.call(null, W.location.ancestorOrigins[i], i); + } + } catch (ignore) { } + return []; + } + + function f1(callback) { + var oneWindow, + infoArray = []; + do { + try { + oneWindow = oneWindow ? oneWindow.parent : W; + callback.call(null, oneWindow, infoArray); + } catch (t) { + infoArray.push({ + referrer: null, + location: null, + isTop: !1 + }); + return infoArray; + } + } while (oneWindow !== W.top); + return infoArray; + } + var allInfo = f1(function (oneWindow, infoArray) { + try { + infoArray.push({ referrer: oneWindow.document.referrer || null, location: oneWindow.location.href || null, isTop: oneWindow === W.top }); + } catch (e) { + infoArray.push({ referrer: null, location: null, isTop: oneWindow === W.top }); + } + }); + f2(function (n, r) { + allInfo[r].ancestor = n; + }); + for (var t = '', e = !1, i = allInfo.length - 1, l = allInfo.length - 1; l >= 0; l--) { + t = allInfo[l].location; + if (!t && l > 0) { + t = allInfo[l - 1].referrer; + if (!t) t = allInfo[l - 1].ancestor; + if (t) { + e = W.location.ancestorOrigins ? !0 : l === allInfo.length - 1 && allInfo[allInfo.length - 1].isTop; + break; + } + } + } return { url: t, isTop: e, depth: i }; + }, + + srTestCapabilities: function srTestCapabilities() { + var plugins = navigator.plugins, + flashVer = -1, + sf = 'Shockwave Flash'; + + if (plugins && plugins.length > 0) { + if (plugins[sf + ' 2.0'] || plugins[sf]) { + var swVer2 = plugins[sf + ' 2.0'] ? ' 2.0' : ''; + var flashDescription = plugins[sf + swVer2].description; + flashVer = flashDescription.split(' ')[2].split('.')[0]; + } + } + if (flashVer > 4) return 15; else return 7; + } + + }; + }()); + + // Ad calling functionality + CMT.Service = (function () { + // Closure variables shared by the service functions + var U = CMT.Util; + + return { + + buildSrc: function buildSrc(tag, env) { + var src = (document.location.protocol === 'https:' ? 'https://' : 'http://') + (!env || env === 'PRD' ? '' : env === 'PPE' ? 'ppe-' : env === 'STG' ? 'staging-' : '') + 'ad.afy11.net/ad' + '?mode=11' + '&ct=' + U.srTestCapabilities() + '&nif=0' + '&sf=0' + '&sfd=0' + '&ynw=0' + '&rand=' + U.getRand() + '&hb=1' + '&rk1=' + U.getRand() + '&rk2=' + new Date().valueOf() / 1000; + + // Make sure we don't have a response object... + delete tag.response; + + // Extracted url info... + var urlInfo = U.extractUrlInfo(); + tag.pageUrl = urlInfo.url; + tag.puTop = urlInfo.isTop; + + // Attach the serialized tag to our string + src += '&ab=' + U.encodeUriObject(tag); + + return src; + }, + + getAd: function (zoneKey) { + if (!zoneKey) return; + + return this._getData(zoneKey, 'ad') + (this._getResponse().tpCookieSync || ''); // ...also append cookie sync if present + }, + + // getSecondPrice: function getSecondPrice(zoneKey) { + // if (zoneKey.substring(0, 2) !== 'as') zoneKey = 'as' + zoneKey; + // var bid = this.getBidTrue(zoneKey), + // floor = this._getData(zoneKey, 'floor'); + + // // If no floor, just set it to 80% of the bid + // if (!floor) floor = bid * 0.80; + + // // Adjust the floor if it's too high...it needs to always be lower + // if (floor >= bid) { + // floor = floor * 0.80; // Take off 20% to account for possible non-adjusted 2nd highest bid + + // // If it's still too high, just take 80% to 90% of the bid + // if (floor >= bid) floor = bid * ((Math.random() * 10) + 80) / 100; + // } + // return Math.round(floor * 100) / 100; + // }, + + // setAuctionPrice: function setAuctionPrice(ad, bid) { + // return ad ? ad.replace('${AUCTION_PRICE}', bid) : ad; + // }, + + getBidTrue: function getBidTrue(zoneKey) { + return Math.round(this._getData(zoneKey, 'price') * 100) / 100; + }, + + _getData: function (zoneKey, field) { + var response = this._getResponse(), + zoneResponseData = response.zones ? response.zones[zoneKey] : {}; + + return (zoneResponseData || {})[field] || null; + }, + + _getResponse: function () { + var tag = W.cdsTag; + return (tag && tag.response) ? tag.response : {}; + }, + }; + }()); + + return CMT; + } + + // Export the callBids function, so that prebid.js can execute this function + // when the page asks to send out bid requests. + return { + callBids: _callBids, + }; +} + +adaptermanager.registerBidAdapter(new CoxAdapter, 'cox'); + +module.exports = CoxAdapter; diff --git a/src/adapters/criteo.js b/modules/criteoBidAdapter.js similarity index 93% rename from src/adapters/criteo.js rename to modules/criteoBidAdapter.js index c0e14fb3d51..c380a2885f9 100644 --- a/src/adapters/criteo.js +++ b/modules/criteoBidAdapter.js @@ -1,6 +1,7 @@ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader'); +var adaptermanager = require('src/adaptermanager'); var CriteoAdapter = function CriteoAdapter() { var sProt = (window.location.protocol === 'http:') ? 'http:' : 'https:'; @@ -134,4 +135,6 @@ var CriteoAdapter = function CriteoAdapter() { }; }; +adaptermanager.registerBidAdapter(new CriteoAdapter, 'criteo'); + module.exports = CriteoAdapter; diff --git a/src/adapters/districtmDMX.js b/modules/districtmDMXBidAdapter.js similarity index 84% rename from src/adapters/districtmDMX.js rename to modules/districtmDMXBidAdapter.js index d8e78d97401..d07985097ef 100644 --- a/src/adapters/districtmDMX.js +++ b/modules/districtmDMXBidAdapter.js @@ -1,6 +1,7 @@ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adLoader = require('../adloader'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adLoader = require('src/adloader'); +var adaptermanager = require('src/adaptermanager'); var DistrictmAdaptor = function districtmAdaptor() { let districtmUrl = window.location.protocol + '//prebid.districtm.ca/lib.js'; @@ -50,4 +51,6 @@ var DistrictmAdaptor = function districtmAdaptor() { }; }; +adaptermanager.registerBidAdapter(new DistrictmAdaptor, 'districtmDMX'); + module.exports = DistrictmAdaptor; diff --git a/src/adapters/eplanning.js b/modules/eplanningBidAdapter.js similarity index 98% rename from src/adapters/eplanning.js rename to modules/eplanningBidAdapter.js index fd4acc0e047..b08c6ad1a81 100644 --- a/src/adapters/eplanning.js +++ b/modules/eplanningBidAdapter.js @@ -1,7 +1,8 @@ var bidfactory = require('src/bidfactory.js'); var bidmanager = require('src/bidmanager.js'); +var adaptermanager = require('src/adaptermanager'); -var EPlanningAdapter = function EPlanningAdapter() { +function EPlanningAdapter() { (function() { var win = window, doc = win.document, pbjs = win.pbjs, _global = {}, _default = { 'sv': 'ads.us.e-planning.net', 't': 0 }, rnd, FILE = 'file', CALLBACK_FUNCTION = 'hbpb.rH', NULL_SIZE = '1x1', _csRequested = [], PROTO = location.protocol === 'https:' ? 'https:' : 'http:', ISV = 'aklc.img.e-planning.net'; function Hbpb() { @@ -275,6 +276,8 @@ var EPlanningAdapter = function EPlanningAdapter() { return { callBids: _callBids }; -}; +} + +adaptermanager.registerBidAdapter(new EPlanningAdapter, 'eplanning'); module.exports = EPlanningAdapter; diff --git a/modules/express.js b/modules/express.js new file mode 100644 index 00000000000..8a855245e36 --- /dev/null +++ b/modules/express.js @@ -0,0 +1,209 @@ + +import * as utils from 'src/utils'; + +const MODULE_NAME = 'express'; + +/** + * Express Module + * + * The express module allows the initiation of Prebid.js auctions automatically based on calls such as gpt.defineSlot. + * It works by monkey-patching the gpt methods and overloading their functionality. In order for this module to be + * used gpt must be included in the page, this module must be included in the Prebid.js bundle, and a call to + * pbjs.express() must be made. + * + * @param {Object[]} [adUnits = pbjs.adUnits] - an array of adUnits for express to operate on. + */ +$$PREBID_GLOBAL$$.express = function(adUnits = $$PREBID_GLOBAL$$.adUnits) { + + utils.logMessage('loading ' + MODULE_NAME); + + if (adUnits.length === 0) { + utils.logWarn('no valid adUnits found, not loading ' + MODULE_NAME); + } + +// put adUnits in a more performant hash lookup by code. + var adUnitsCache = adUnits.reduce(function (cache, adUnit) { + if (adUnit.code && adUnit.bids) { + cache[adUnit.code] = adUnit; + } else { + utils.logError('misconfigured adUnit', null, adUnit); + } + return cache; + }, {}); + + window.googletag = window.googletag || {}; + window.googletag.cmd = window.googletag.cmd || []; + window.googletag.cmd.push(function () { + // verify all necessary gpt functions exist + var gpt = window.googletag; + var pads = gpt.pubads; + if (!gpt.display || !gpt.enableServices || typeof pads !== 'function' || !pads().refresh || !pads().disableInitialLoad || !pads().getSlots || !pads().enableSingleRequest) { + utils.logError('could not bind to gpt googletag api'); + return; + } + utils.logMessage('running'); + + + // function to convert google tag slot sizes to [[w,h],...] + function mapGptSlotSizes(aGPTSlotSizes) { + var aSlotSizes = []; + for (var i = 0; i < aGPTSlotSizes.length; i++) { + try { + aSlotSizes.push([aGPTSlotSizes[i].getWidth(), aGPTSlotSizes[i].getHeight()]); + } catch (e) { + utils.logWarn('slot size ' + aGPTSlotSizes[i].toString() + ' not supported by' + MODULE_NAME); + } + } + return aSlotSizes; + } + + // a helper function to verify slots or get slots if not present + function defaultSlots(slots) { + return Array.isArray(slots) ? + slots.slice() : + googletag.pubads().getSlots().slice(); + } + + // maps gpt slots to adUnits, matches are copied to new array and removed from passed array. + function pickAdUnits(gptSlots) { + var adUnits = []; + // traverse backwards (since gptSlots is mutated) to find adUnits in cache and remove non-mapped slots + for (var i = gptSlots.length - 1; i > -1; i--) { + var gptSlot = gptSlots[i], + elemId = gptSlot.getSlotElementId(), + adUnit = adUnitsCache[elemId]; + + if (adUnit) { + adUnit._gptSlot = gptSlot; + adUnit.sizes = adUnit.sizes || mapGptSlotSizes(gptSlot.getSizes()); + adUnits.push(adUnit); + gptSlots.splice(i, 1); + } + } + + return adUnits; + } + + // store original gpt functions that will be overridden + var fGptDisplay = gpt.display; + var fGptEnableServices = gpt.enableServices; + var fGptRefresh = pads().refresh; + var fGptDisableInitialLoad = pads().disableInitialLoad; + var fGptEnableSingleRequest = pads().enableSingleRequest; + + // override googletag.enableServices() + // - make sure fGptDisableInitialLoad() has been called so we can + // better control when slots are displayed, then call original + // fGptEnableServices() + gpt.enableServices = function () { + if (!bInitialLoadDisabled) { + fGptDisableInitialLoad.apply(pads()); + } + return fGptEnableServices.apply(gpt, arguments); + }; + + // override googletag.display() + // - call the real fGptDisplay(). this won't initiate auctions because we've disabled initial load + // - define all corresponding rubicon slots + // - if disableInitialLoad() has been called by the pub, done + // - else run an auction and call the real fGptRefresh() to + // initiate the DFP request + gpt.display = function (sElementId) { + utils.logInfo('display:', sElementId); + // call original gpt display() function + fGptDisplay.apply(gpt, arguments); + + // if not SRA mode, get only the gpt slot corresponding to sEementId + var aGptSlots; + if (!bEnabledSRA) { + aGptSlots = googletag.pubads().getSlots().filter(function (oGptSlot) { + return oGptSlot.getSlotElementId() === sElementId; + }); + } + + aGptSlots = defaultSlots(aGptSlots).filter(function (gptSlot) { + return !gptSlot._displayed; + }); + + aGptSlots.forEach(function (gptSlot) { + gptSlot._displayed = true; + }); + + var adUnits = pickAdUnits(/* mutated: */ aGptSlots); + + if (!bInitialLoadDisabled) { + if (aGptSlots.length) { + fGptRefresh.apply(pads(), [aGptSlots]); + } + + if (adUnits.length) { + $$PREBID_GLOBAL$$.requestBids({ + adUnits: adUnits, + bidsBackHandler: function () { + $$PREBID_GLOBAL$$.setTargetingForGPTAsync(); + fGptRefresh.apply(pads(), [ + adUnits.map(function (adUnit) { + return adUnit._gptSlot; + }) + ]); + } + }); + } + } + + }; + + // override gpt refresh() function + // - run auctions for provided gpt slots, then initiate ad-server call + pads().refresh = function (aGptSlots, options) { + utils.logInfo('refresh:', aGptSlots); + // get already displayed adUnits from aGptSlots if provided, else all defined gptSlots + aGptSlots = defaultSlots(aGptSlots); + var adUnits = pickAdUnits(/* mutated: */ aGptSlots).filter(function (adUnit) { + return adUnit._gptSlot._displayed; + }); + + if (aGptSlots.length) { + fGptRefresh.apply(pads(), [aGptSlots, options]); + } + + if (adUnits.length) { + $$PREBID_GLOBAL$$.requestBids({ + adUnits: adUnits, + bidsBackHandler: function () { + $$PREBID_GLOBAL$$.setTargetingForGPTAsync(); + fGptRefresh.apply(pads(), [ + adUnits.map(function (adUnit) { + return adUnit._gptSlot + }), + options + ]); + } + }); + } + }; + + // override gpt disableInitialLoad function + // Register that initial load was called, meaning calls to display() + // should not initiate an ad-server request. Instead a call to + // refresh() will be needed to iniate the request. + // We will assume the pub is using this the correct way, calling it + // before enableServices() + var bInitialLoadDisabled = false; + pads().disableInitialLoad = function () { + bInitialLoadDisabled = true; + return fGptDisableInitialLoad.apply(window.googletag.pubads(), arguments); + }; + + // override gpt useSingleRequest function + // Register that SRA has been turned on + // We will assume the pub is using this the correct way, calling it + // before enableServices() + var bEnabledSRA = false; + pads().enableSingleRequest = function () { + bEnabledSRA = true; + return fGptEnableSingleRequest.apply(window.googletag.pubads(), arguments); + }; + }); + +}; diff --git a/src/adapters/fidelity.js b/modules/fidelityBidAdapter.js similarity index 91% rename from src/adapters/fidelity.js rename to modules/fidelityBidAdapter.js index 0d623bfd162..2bd585c15c1 100644 --- a/src/adapters/fidelity.js +++ b/modules/fidelityBidAdapter.js @@ -1,8 +1,9 @@ -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader'); -var STATUS = require('../constants').STATUS; +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader'); +var STATUS = require('src/constants').STATUS; +var adaptermanager = require('src/adaptermanager'); var FidelityAdapter = function FidelityAdapter() { var FIDELITY_BIDDER_NAME = 'fidelity'; @@ -96,4 +97,6 @@ var FidelityAdapter = function FidelityAdapter() { }; }; +adaptermanager.registerBidAdapter(new FidelityAdapter, 'fidelity'); + module.exports = FidelityAdapter; diff --git a/src/adapters/getintent.js b/modules/getintentBidAdapter.js similarity index 87% rename from src/adapters/getintent.js rename to modules/getintentBidAdapter.js index 604294a7a22..909b767e508 100644 --- a/src/adapters/getintent.js +++ b/modules/getintentBidAdapter.js @@ -1,8 +1,9 @@ import { STATUS } from 'src/constants'; +import adaptermanager from 'src/adaptermanager'; -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader.js'); var GetIntentAdapter = function GetIntentAdapter() { var headerBiddingStaticJS = window.location.protocol + '//cdn.adhigh.net/adserver/hb.js'; @@ -69,4 +70,8 @@ var GetIntentAdapter = function GetIntentAdapter() { }; }; +adaptermanager.registerBidAdapter(new GetIntentAdapter, 'getintent', { + supportedMediaTypes: ['video'] +}); + module.exports = GetIntentAdapter; diff --git a/src/adapters/analytics/ga.js b/modules/googleAnalyticsAdapter.js similarity index 96% rename from src/adapters/analytics/ga.js rename to modules/googleAnalyticsAdapter.js index 13b852427fa..816fa9e5952 100644 --- a/src/adapters/analytics/ga.js +++ b/modules/googleAnalyticsAdapter.js @@ -2,9 +2,10 @@ * ga.js - analytics adapter for google analytics */ -var events = require('./../../events'); -var utils = require('./../../utils'); -var CONSTANTS = require('./../../constants.json'); +var events = require('src/events'); +var utils = require('src/utils'); +var CONSTANTS = require('src/constants.json'); +var adaptermanager = require('src/adaptermanager'); var BID_REQUESTED = CONSTANTS.EVENTS.BID_REQUESTED; var BID_TIMEOUT = CONSTANTS.EVENTS.BID_TIMEOUT; @@ -21,6 +22,11 @@ var _enableDistribution = false; var _trackerSend = null; var _sampled = true; +adaptermanager.registerAnalyticsAdapter({ + adapter: exports, + code: 'ga' +}); + /** * This will enable sending data to google analytics. Only call once, or duplicate data will be sent! * @param {object} provider use to set GA global (if renamed); diff --git a/src/adapters/gumgum.js b/modules/gumgumBidAdapter.js similarity index 94% rename from src/adapters/gumgum.js rename to modules/gumgumBidAdapter.js index 4196287c520..7d99cfbff69 100644 --- a/src/adapters/gumgum.js +++ b/modules/gumgumBidAdapter.js @@ -1,7 +1,8 @@ -const bidfactory = require('../bidfactory'); -const bidmanager = require('../bidmanager'); -const utils = require('../utils'); -const adloader = require('../adloader'); +const bidfactory = require('src/bidfactory'); +const bidmanager = require('src/bidmanager'); +const utils = require('src/utils'); +const adloader = require('src/adloader'); +var adaptermanager = require('src/adaptermanager'); const BIDDER_CODE = 'gumgum'; const CALLBACKS = {}; @@ -170,4 +171,6 @@ const GumgumAdapter = function GumgumAdapter() { }; }; +adaptermanager.registerBidAdapter(new GumgumAdapter, 'gumgum'); + module.exports = GumgumAdapter; diff --git a/src/adapters/hiromedia.js b/modules/hiromediaBidAdapter.js similarity index 96% rename from src/adapters/hiromedia.js rename to modules/hiromediaBidAdapter.js index 8bef4bc6cd3..5a2fe8a0f8a 100644 --- a/src/adapters/hiromedia.js +++ b/modules/hiromediaBidAdapter.js @@ -1,372 +1,375 @@ /** - * Adapter for HIRO Media - * - * @module HiroMediaAdapter - * - * @requires src/ajax - * @requires src/bidfactory - * @requires src/bidmanager - * @requires src/constants - * @requires src/utils - */ -var Ajax = require('src/ajax'); -var bidfactory = require('src/bidfactory'); -var bidmanager = require('src/bidmanager'); -var utils = require('src/utils'); -var STATUS = require('src/constants').STATUS; - -var HiroMediaAdapter = function HiroMediaAdapter() { - 'use strict'; - - /** - * Bidder code - * - * @memberof module:HiroMediaAdapter~ - * @constant {string} - * @private - */ - var BIDDER_CODE = 'hiromedia'; - - /** - * Adapter version - * - * @memberof module:HiroMediaAdapter~ - * @constant {number} - * @private - */ - var ADAPTER_VERSION = 3; - - /** - * Default bid param values - * - * @memberof module:HiroMediaAdapter~ - * @constant {array.} - * @private - */ - var REQUIRED_BID_PARAMS = ['accountId']; - - /** - * Default bid param values - * - * @memberof module:HiroMediaAdapter~ - * @constant {module:HiroMediaAdapter~bidParams} - * @private - */ - var DEFAULT_BID_PARAMS = { - bidUrl: 'https://hb-rtb.ktdpublishers.com/bid/get' - }; - - /** - * Returns true if the given value is `undefined` - * - * @memberof module:HiroMediaAdapter~ - * @private - * - * @param {*} value value to check - * @return {boolean} true if the given value is `undefined`, false otherwise - */ - function isUndefined(value) { - return typeof value === 'undefined'; - } - - /** - * Call bidmanager.addBidResponse - * - * Simple wrapper that will create a bid object with the correct status - * and add the response for the placement. - * - * @memberof module:HiroMediaAdapter~ - * @private - * - * @param {object} bid bid object connected to the response - * @param {object|boolean} [bidResponse] response object for bid, if not - * set the response will be an empty bid response. - */ - function addBidResponse(bid, bidResponse) { - var placementCode = bid.placementCode; - var bidStatus = bidResponse ? STATUS.GOOD : STATUS.NO_BID; - var bidObject = bidfactory.createBid(bidStatus, bid); - - bidObject.bidderCode = BIDDER_CODE; - - if (bidResponse) { - bidObject.cpm = bidResponse.cpm; - bidObject.ad = bidResponse.ad; - bidObject.width = bidResponse.width; - bidObject.height = bidResponse.height; - } - - utils.logMessage('hiromedia.callBids, addBidResponse for ' + placementCode + ' status: ' + bidStatus); - bidmanager.addBidResponse(placementCode, bidObject); - } - - /** - * Return `true` if sampling is larger than a newly created random value - * - * @memberof module:HiroMediaAdapter~ - * @private - * - * @param {number} sampling the value to check - * @return {boolean} `true` if the sampling is larger, `false` otherwise - */ - function checkChance(sampling) { - return Math.random() < sampling; - } - - /** - * Apply a response for all pending bids that have the same response batch key - * - * @memberof module:HiroMediaAdapter~ - * @private - * - * @param {object} response bid response object - * @param {object} bid bid object connected to response - */ - function handleResponse(response, bid) { - // Sample the bid responses according to `response.chance`, - // if `response.chance` is not provided, sample at 100%. - if (isUndefined(response.chance) || checkChance(response.chance)) { - addBidResponse(bid, response); - } else { - addBidResponse(bid, false); - } - } - - /** - * Find browser name and version - * - * Super basic UA parser for the major browser configurations. - * - * @memberof module:HiroMediaAdapter~ - * @private - * - * @return {module:HiroMediaAdapter~browserInfo} object containing name and version of browser - * or empty strings. - */ - function getBrowser() { - var ua = navigator.userAgent; - var browsers = [{ - name: 'Mobile', - stringSearch: 'Mobi' - }, { - name: 'Edge' - }, { - name: 'Chrome' - }, { - name: 'Firefox' - }, { - name: 'IE', - versionSearch: /MSIE\s(\d+)/ - }, { - name: 'IE', - stringSearch: 'Trident', - versionSearch: /rv:(\d+)/ - }]; - - var name = ''; - var version = ''; - - browsers.some(function (browser) { - var nameSearch = browser.stringSearch || browser.name; - var defaultVersionSearch = nameSearch + '\\/(\\d+)'; - var versionSearch = browser.versionSearch || defaultVersionSearch; - var versionMatch; - - if (ua.indexOf(nameSearch) !== -1) { - name = browser.name; - versionMatch = ua.match(versionSearch); - if (versionMatch) { - version = versionMatch && versionMatch[1]; - } - return true; - } - }); - - return { - name: name, - version: version - }; - } - - /** - * Return top context domain - * - * @memberof module:HiroMediaAdapter~ - * @private - * - * @return {string} domain of top context url. - */ - function getDomain() { - var a = document.createElement('a'); - a.href = utils.getTopWindowUrl(); - return a.hostname; - } - - /** - * Apply default parameters to an object if the parameters are not set - * - * @memberof module:HiroMediaAdapter~ - * @private - * - * @param {module:HiroMediaAdapter~bidParams} bidParams custom parameters for bid - * @return {module:HiroMediaAdapter~bidParams} `bidParams` shallow merged with - * {@linkcode module:HiroMediaAdapter~DEFAULT_BID_PARAMS|DEFAULT_BID_PARAMS} - */ - function defaultParams(bidParams) { - return Object.assign({}, DEFAULT_BID_PARAMS, bidParams); - } - - /** - * Build a {@linkcode module:HiroMediaAdapter~bidInfo|bidInfo} object based on a - * bid sent to {@linkcode module:HiroMediaAdapter#callBids|callBids} - * - * @memberof module:HiroMediaAdapter~ - * @private - * - * @param {object} bid bid from `Prebid.js` - * @return {module:HiroMediaAdapter~bidInfo} information for bid request - */ - function processBid(bid) { - var sizes = utils.parseSizesInput(bid.sizes); - var bidParams = defaultParams(bid.params); - var hasValidBidRequest = utils.hasValidBidRequest(bidParams, REQUIRED_BID_PARAMS, BIDDER_CODE); - var shouldBid = hasValidBidRequest; - var bidInfo = { - bidParams: bidParams, - shouldBid: shouldBid, - selectedSize: sizes[0], - additionalSizes: sizes.slice(1).join(',') - }; - - return bidInfo; - } - - /** - * Wrapper around `JSON.parse()` that returns false on error - * - * @memberof module:HiroMediaAdapter~ - * @private - * - * @param {string} text potential JSON string to convert to object - * @return {object|boolean} object parsed from text or `false` in case of and error - */ - function tryJson(text) { - var object = false; - - try { - object = JSON.parse(text); - } catch (ignore) { - // Ignored - } - - return object; - } - - /** - * Receive a set of bid placements and create bid requests and responses accordingly - * - * @alias module:HiroMediaAdapter#callBids - * - * @param {object} params placement and bid data from `Prebid.js` - */ - function _callBids(params) { - var browser = getBrowser(); - var domain = getDomain(); - var bids = params && params.bids; - var ajaxOptions = { - method: 'GET', - withCredentials: true - }; - - // Fixed data, shared by all requests - var fixedRequest = { - adapterVersion: ADAPTER_VERSION, - browser: browser.name, - browserVersion: browser.version, - domain: domain - }; - - utils.logMessage('hiromedia.callBids'); - - if (bids && bids.length) { - bids.forEach(function (bid) { - var bidInfo = processBid(bid); - var bidParams = bidInfo.bidParams; - utils.logMessage('hiromedia.callBids, bidInfo ' + bid.placementCode + ' ' + bidInfo.shouldBid); + * Adapter for HIRO Media + * + * @module HiroMediaAdapter + * + * @requires src/ajax + * @requires src/bidfactory + * @requires src/bidmanager + * @requires src/constants + * @requires src/utils + */ +var Ajax = require('src/ajax'); +var bidfactory = require('src/bidfactory'); +var bidmanager = require('src/bidmanager'); +var utils = require('src/utils'); +var STATUS = require('src/constants').STATUS; +var adaptermanager = require('src/adaptermanager'); + +var HiroMediaAdapter = function HiroMediaAdapter() { + 'use strict'; + + /** + * Bidder code + * + * @memberof module:HiroMediaAdapter~ + * @constant {string} + * @private + */ + var BIDDER_CODE = 'hiromedia'; + + /** + * Adapter version + * + * @memberof module:HiroMediaAdapter~ + * @constant {number} + * @private + */ + var ADAPTER_VERSION = 3; + + /** + * Default bid param values + * + * @memberof module:HiroMediaAdapter~ + * @constant {array.} + * @private + */ + var REQUIRED_BID_PARAMS = ['accountId']; + + /** + * Default bid param values + * + * @memberof module:HiroMediaAdapter~ + * @constant {module:HiroMediaAdapter~bidParams} + * @private + */ + var DEFAULT_BID_PARAMS = { + bidUrl: 'https://hb-rtb.ktdpublishers.com/bid/get' + }; + + /** + * Returns true if the given value is `undefined` + * + * @memberof module:HiroMediaAdapter~ + * @private + * + * @param {*} value value to check + * @return {boolean} true if the given value is `undefined`, false otherwise + */ + function isUndefined(value) { + return typeof value === 'undefined'; + } + + /** + * Call bidmanager.addBidResponse + * + * Simple wrapper that will create a bid object with the correct status + * and add the response for the placement. + * + * @memberof module:HiroMediaAdapter~ + * @private + * + * @param {object} bid bid object connected to the response + * @param {object|boolean} [bidResponse] response object for bid, if not + * set the response will be an empty bid response. + */ + function addBidResponse(bid, bidResponse) { + var placementCode = bid.placementCode; + var bidStatus = bidResponse ? STATUS.GOOD : STATUS.NO_BID; + var bidObject = bidfactory.createBid(bidStatus, bid); + + bidObject.bidderCode = BIDDER_CODE; + + if (bidResponse) { + bidObject.cpm = bidResponse.cpm; + bidObject.ad = bidResponse.ad; + bidObject.width = bidResponse.width; + bidObject.height = bidResponse.height; + } + + utils.logMessage('hiromedia.callBids, addBidResponse for ' + placementCode + ' status: ' + bidStatus); + bidmanager.addBidResponse(placementCode, bidObject); + } + + /** + * Return `true` if sampling is larger than a newly created random value + * + * @memberof module:HiroMediaAdapter~ + * @private + * + * @param {number} sampling the value to check + * @return {boolean} `true` if the sampling is larger, `false` otherwise + */ + function checkChance(sampling) { + return Math.random() < sampling; + } + + /** + * Apply a response for all pending bids that have the same response batch key + * + * @memberof module:HiroMediaAdapter~ + * @private + * + * @param {object} response bid response object + * @param {object} bid bid object connected to response + */ + function handleResponse(response, bid) { + // Sample the bid responses according to `response.chance`, + // if `response.chance` is not provided, sample at 100%. + if (isUndefined(response.chance) || checkChance(response.chance)) { + addBidResponse(bid, response); + } else { + addBidResponse(bid, false); + } + } + + /** + * Find browser name and version + * + * Super basic UA parser for the major browser configurations. + * + * @memberof module:HiroMediaAdapter~ + * @private + * + * @return {module:HiroMediaAdapter~browserInfo} object containing name and version of browser + * or empty strings. + */ + function getBrowser() { + var ua = navigator.userAgent; + var browsers = [{ + name: 'Mobile', + stringSearch: 'Mobi' + }, { + name: 'Edge' + }, { + name: 'Chrome' + }, { + name: 'Firefox' + }, { + name: 'IE', + versionSearch: /MSIE\s(\d+)/ + }, { + name: 'IE', + stringSearch: 'Trident', + versionSearch: /rv:(\d+)/ + }]; + + var name = ''; + var version = ''; + + browsers.some(function (browser) { + var nameSearch = browser.stringSearch || browser.name; + var defaultVersionSearch = nameSearch + '\\/(\\d+)'; + var versionSearch = browser.versionSearch || defaultVersionSearch; + var versionMatch; + + if (ua.indexOf(nameSearch) !== -1) { + name = browser.name; + versionMatch = ua.match(versionSearch); + if (versionMatch) { + version = versionMatch && versionMatch[1]; + } + return true; + } + }); + + return { + name: name, + version: version + }; + } + + /** + * Return top context domain + * + * @memberof module:HiroMediaAdapter~ + * @private + * + * @return {string} domain of top context url. + */ + function getDomain() { + var a = document.createElement('a'); + a.href = utils.getTopWindowUrl(); + return a.hostname; + } + + /** + * Apply default parameters to an object if the parameters are not set + * + * @memberof module:HiroMediaAdapter~ + * @private + * + * @param {module:HiroMediaAdapter~bidParams} bidParams custom parameters for bid + * @return {module:HiroMediaAdapter~bidParams} `bidParams` shallow merged with + * {@linkcode module:HiroMediaAdapter~DEFAULT_BID_PARAMS|DEFAULT_BID_PARAMS} + */ + function defaultParams(bidParams) { + return Object.assign({}, DEFAULT_BID_PARAMS, bidParams); + } + + /** + * Build a {@linkcode module:HiroMediaAdapter~bidInfo|bidInfo} object based on a + * bid sent to {@linkcode module:HiroMediaAdapter#callBids|callBids} + * + * @memberof module:HiroMediaAdapter~ + * @private + * + * @param {object} bid bid from `Prebid.js` + * @return {module:HiroMediaAdapter~bidInfo} information for bid request + */ + function processBid(bid) { + var sizes = utils.parseSizesInput(bid.sizes); + var bidParams = defaultParams(bid.params); + var hasValidBidRequest = utils.hasValidBidRequest(bidParams, REQUIRED_BID_PARAMS, BIDDER_CODE); + var shouldBid = hasValidBidRequest; + var bidInfo = { + bidParams: bidParams, + shouldBid: shouldBid, + selectedSize: sizes[0], + additionalSizes: sizes.slice(1).join(',') + }; + + return bidInfo; + } + + /** + * Wrapper around `JSON.parse()` that returns false on error + * + * @memberof module:HiroMediaAdapter~ + * @private + * + * @param {string} text potential JSON string to convert to object + * @return {object|boolean} object parsed from text or `false` in case of and error + */ + function tryJson(text) { + var object = false; + + try { + object = JSON.parse(text); + } catch (ignore) { + // Ignored + } + + return object; + } + + /** + * Receive a set of bid placements and create bid requests and responses accordingly + * + * @alias module:HiroMediaAdapter#callBids + * + * @param {object} params placement and bid data from `Prebid.js` + */ + function _callBids(params) { + var browser = getBrowser(); + var domain = getDomain(); + var bids = params && params.bids; + var ajaxOptions = { + method: 'GET', + withCredentials: true + }; + + // Fixed data, shared by all requests + var fixedRequest = { + adapterVersion: ADAPTER_VERSION, + browser: browser.name, + browserVersion: browser.version, + domain: domain + }; + + utils.logMessage('hiromedia.callBids'); + + if (bids && bids.length) { + bids.forEach(function (bid) { + var bidInfo = processBid(bid); + var bidParams = bidInfo.bidParams; + utils.logMessage('hiromedia.callBids, bidInfo ' + bid.placementCode + ' ' + bidInfo.shouldBid); if (bidInfo.shouldBid) { - var url = bidParams.bidUrl; - var requestParams = Object.assign({}, fixedRequest, bidInfo.bidParams, { - placementCode: bid.placementCode, - selectedSize: bidInfo.selectedSize, - additionalSizes: bidInfo.additionalSizes + var url = bidParams.bidUrl; + var requestParams = Object.assign({}, fixedRequest, bidInfo.bidParams, { + placementCode: bid.placementCode, + selectedSize: bidInfo.selectedSize, + additionalSizes: bidInfo.additionalSizes }); Object.keys(requestParams).forEach(function (key) { - if (requestParams[key] === '' || isUndefined(requestParams[key])) { - delete requestParams[key]; - } + if (requestParams[key] === '' || isUndefined(requestParams[key])) { + delete requestParams[key]; + } }); - utils.logMessage('hiromedia.callBids, bid request ' + url + ' ' + JSON.stringify(bidInfo.bidRequest)); - - Ajax.ajax(url, { - - success: function(responseText) { + utils.logMessage('hiromedia.callBids, bid request ' + url + ' ' + JSON.stringify(bidInfo.bidRequest)); + + Ajax.ajax(url, { + + success: function(responseText) { var response = tryJson(responseText); - handleResponse(response, bid); - }, - - error: function(err, xhr) { - utils.logError('hiromedia.callBids, bid request error', xhr.status, err); + handleResponse(response, bid); + }, + + error: function(err, xhr) { + utils.logError('hiromedia.callBids, bid request error', xhr.status, err); addBidResponse(bid, false); - } - - }, requestParams, ajaxOptions); - } else { - // No bid - addBidResponse(bid, false); - } - }); - } - } - - return { - callBids: _callBids - }; - - - // JSDoc typedefs - - /** - * Parameters for bids to HIRO Media adapter - * - * @typedef {object} module:HiroMediaAdapter~bidParams - * @private - * - * @property {string} bidUrl the bid server endpoint url - */ - - /** - * Bid object wrapper - * - * @typedef {object} module:HiroMediaAdapter~bidInfo - * @private - * - * @property {string} selectedSize the first size in the the placement sizes array - * @property {string} additionalSizes list of sizes in the placement sizes array besides the first - * @property {module:HiroMediaAdapter~bidParams} bidParams original params passed for bid in #callBids - * @property {boolean} shouldBid flag to determine if the bid is valid for bidding or not - */ - - /** - * browserInfo - * - * @typedef {object} module:HiroMediaAdapter~browserInfo - * @private - * - * @property {string} name browser name (e.g. `'Chrome'` or `'Firefox'`) - * @property {string} version browser major version (e.g. `'53'`) - */ -}; - -module.exports = HiroMediaAdapter; + } + + }, requestParams, ajaxOptions); + } else { + // No bid + addBidResponse(bid, false); + } + }); + } + } + + return { + callBids: _callBids + }; + + + // JSDoc typedefs + + /** + * Parameters for bids to HIRO Media adapter + * + * @typedef {object} module:HiroMediaAdapter~bidParams + * @private + * + * @property {string} bidUrl the bid server endpoint url + */ + + /** + * Bid object wrapper + * + * @typedef {object} module:HiroMediaAdapter~bidInfo + * @private + * + * @property {string} selectedSize the first size in the the placement sizes array + * @property {string} additionalSizes list of sizes in the placement sizes array besides the first + * @property {module:HiroMediaAdapter~bidParams} bidParams original params passed for bid in #callBids + * @property {boolean} shouldBid flag to determine if the bid is valid for bidding or not + */ + + /** + * browserInfo + * + * @typedef {object} module:HiroMediaAdapter~browserInfo + * @private + * + * @property {string} name browser name (e.g. `'Chrome'` or `'Firefox'`) + * @property {string} version browser major version (e.g. `'53'`) + */ +}; + +adaptermanager.registerBidAdapter(new HiroMediaAdapter, 'hiromedia'); + +module.exports = HiroMediaAdapter; diff --git a/src/adapters/huddledmasses.js b/modules/huddledmassesBidAdapter.js similarity index 96% rename from src/adapters/huddledmasses.js rename to modules/huddledmassesBidAdapter.js index 8fdfee0fc4d..0014f4d3fe6 100644 --- a/src/adapters/huddledmasses.js +++ b/modules/huddledmassesBidAdapter.js @@ -1,9 +1,10 @@ -import * as Adapter from './adapter.js'; +import * as Adapter from 'src/adapter.js'; import bidfactory from 'src/bidfactory'; import bidmanager from 'src/bidmanager'; import * as utils from 'src/utils'; import {ajax} from 'src/ajax'; import {STATUS} from 'src/constants'; +import adaptermanager from 'src/adaptermanager'; var BIDDER_CODE = 'huddledmasses'; @@ -166,4 +167,6 @@ HuddledMassesAdapter.createNew = function () { return new HuddledMassesAdapter(); }; +adaptermanager.registerBidAdapter(new HuddledMassesAdapter, 'huddledmasses'); + module.exports = HuddledMassesAdapter; diff --git a/src/adapters/indexExchange.js b/modules/indexExchangeBidAdapter.js similarity index 98% rename from src/adapters/indexExchange.js rename to modules/indexExchangeBidAdapter.js index 133ee8e3cf2..f411fa93cfd 100644 --- a/src/adapters/indexExchange.js +++ b/modules/indexExchangeBidAdapter.js @@ -1,8 +1,9 @@ // Factory for creating the bidderAdaptor -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader.js'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader.js'); +var adaptermanager = require('src/adaptermanager'); var ADAPTER_NAME = 'INDEXEXCHANGE'; var ADAPTER_CODE = 'indexExchange'; @@ -661,4 +662,6 @@ var IndexExchangeAdapter = function IndexExchangeAdapter() { }; }; +adaptermanager.registerBidAdapter(new IndexExchangeAdapter, 'indexExchange'); + module.exports = IndexExchangeAdapter; diff --git a/src/adapters/inneractive.js b/modules/inneractiveBidAdapter.js similarity index 98% rename from src/adapters/inneractive.js rename to modules/inneractiveBidAdapter.js index 77fb3999834..84b53f12798 100644 --- a/src/adapters/inneractive.js +++ b/modules/inneractiveBidAdapter.js @@ -1,10 +1,11 @@ -import * as utils from '../utils'; -import Adapter from './adapter'; -import {ajax} from '../ajax'; +import * as utils from 'src/utils'; +import Adapter from 'src/adapter'; +import {ajax} from 'src/ajax'; import bidManager from 'src/bidmanager'; import bidFactory from 'src/bidfactory'; import {STATUS} from 'src/constants'; -import {formatQS} from '../url'; +import {formatQS} from 'src/url'; +import adaptermanager from 'src/adaptermanager'; /** * @type {{IA_JS: string, ADAPTER_NAME: string, V: string, RECTANGLE_SIZE: {W: number, H: number}, SPOT_TYPES: {INTERSTITIAL: string, RECTANGLE: string, FLOATING: string, BANNER: string}, DISPLAY_AD: number, ENDPOINT_URL: string, EVENTS_ENDPOINT_URL: string, RESPONSE_HEADERS_NAME: {PRICING_VALUE: string, AD_H: string, AD_W: string}}} @@ -457,4 +458,7 @@ class InnerActiveAdapter { return new InnerActiveAdapter(); } } + +adaptermanager.registerBidAdapter(new InnerActiveAdapter, 'inneractive'); + module.exports = InnerActiveAdapter; diff --git a/src/adapters/innity.js b/modules/innityBidAdapter.js similarity index 86% rename from src/adapters/innity.js rename to modules/innityBidAdapter.js index b49f297e8e6..23e2b0c9527 100644 --- a/src/adapters/innity.js +++ b/modules/innityBidAdapter.js @@ -1,8 +1,9 @@ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader.js'); -var utils = require('../utils.js'); -var CONSTANTS = require('../constants.json'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader.js'); +var utils = require('src/utils.js'); +var CONSTANTS = require('src/constants.json'); +var adaptermanager = require('src/adaptermanager'); var InnityAdapter = function InnityAdapter() { function _callBids(params) { @@ -52,4 +53,6 @@ var InnityAdapter = function InnityAdapter() { }; }; +adaptermanager.registerBidAdapter(new InnityAdapter, 'innity'); + module.exports = InnityAdapter; diff --git a/src/adapters/jcm.js b/modules/jcmBidAdapter.js similarity index 94% rename from src/adapters/jcm.js rename to modules/jcmBidAdapter.js index cb429156dac..b1648e1731f 100644 --- a/src/adapters/jcm.js +++ b/modules/jcmBidAdapter.js @@ -2,6 +2,7 @@ var bidfactory = require('src/bidfactory.js'); var bidmanager = require('src/bidmanager.js'); var adloader = require('src/adloader.js'); var utils = require('src/utils.js'); +var adaptermanager = require('src/adaptermanager'); var JCMAdapter = function JCMAdapter() { window.pbjs = window.pbjs || {}; @@ -63,4 +64,6 @@ var JCMAdapter = function JCMAdapter() { }; }; +adaptermanager.registerBidAdapter(new JCMAdapter, 'jcm'); + module.exports = JCMAdapter; diff --git a/src/adapters/komoona.js b/modules/komoonaBidAdapter.js similarity index 95% rename from src/adapters/komoona.js rename to modules/komoonaBidAdapter.js index 33fb798facb..35cc4cbaa36 100644 --- a/src/adapters/komoona.js +++ b/modules/komoonaBidAdapter.js @@ -1,9 +1,10 @@ -import Adapter from 'src/adapters/adapter'; +import Adapter from 'src/adapter'; import bidfactory from 'src/bidfactory'; import bidmanager from 'src/bidmanager'; import * as utils from 'src/utils'; import { ajax } from 'src/ajax'; import { STATUS } from 'src/constants'; +import adaptermanager from 'src/adaptermanager'; const ENDPOINT = '//bidder.komoona.com/v1/GetSBids'; @@ -116,4 +117,6 @@ KomoonaAdapter.createNew = function() { return new KomoonaAdapter(); }; +adaptermanager.registerBidAdapter(new KomoonaAdapter, 'komoona'); + module.exports = KomoonaAdapter; diff --git a/src/adapters/kruxlink.js b/modules/kruxlinkBidAdapter.js similarity index 87% rename from src/adapters/kruxlink.js rename to modules/kruxlinkBidAdapter.js index 37f258284c2..4606a27958b 100644 --- a/src/adapters/kruxlink.js +++ b/modules/kruxlinkBidAdapter.js @@ -1,6 +1,7 @@ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader.js'); +var adaptermanager = require('src/adaptermanager'); function _qs(key, value) { return encodeURIComponent(key) + '=' + encodeURIComponent(value); @@ -78,8 +79,12 @@ function _callBids(params) { adloader.loadScript(url); } -module.exports = function KruxAdapter() { +function KruxAdapter() { return { callBids: _callBids }; -}; +} + +adaptermanager.registerBidAdapter(new KruxAdapter, 'kruxlink'); + +module.exports = KruxAdapter; diff --git a/src/adapters/lifestreet.js b/modules/lifestreetBidAdapter.js similarity index 94% rename from src/adapters/lifestreet.js rename to modules/lifestreetBidAdapter.js index a38c1a080da..fa05d2f7c4e 100644 --- a/src/adapters/lifestreet.js +++ b/modules/lifestreetBidAdapter.js @@ -1,7 +1,8 @@ -const bidfactory = require('../bidfactory.js'); -const bidmanager = require('../bidmanager'); -const utils = require('../utils.js'); -const adloader = require('../adloader'); +const bidfactory = require('src/bidfactory.js'); +const bidmanager = require('src/bidmanager'); +const utils = require('src/utils.js'); +const adloader = require('src/adloader'); +const adaptermanager = require('src/adaptermanager'); const LifestreetAdapter = function LifestreetAdapter() { const BIDDER_CODE = 'lifestreet'; @@ -160,4 +161,6 @@ const LifestreetAdapter = function LifestreetAdapter() { }; }; +adaptermanager.registerBidAdapter(new LifestreetAdapter, 'lifestreet'); + module.exports = LifestreetAdapter; diff --git a/src/adapters/mantis.js b/modules/mantisBidAdapter.js similarity index 93% rename from src/adapters/mantis.js rename to modules/mantisBidAdapter.js index f4bb2f56e41..8c01c7bb888 100644 --- a/src/adapters/mantis.js +++ b/modules/mantisBidAdapter.js @@ -1,9 +1,10 @@ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader'); -var constants = require('../constants.json'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader'); +var constants = require('src/constants.json'); +var adaptermanager = require('src/adaptermanager'); -module.exports = function () { +function MantisAdapter () { function inIframe() { try { return window.self !== window.top && !window.mantis_link; @@ -220,4 +221,8 @@ module.exports = function () { }; return new Prebid(bidfactory, bidmanager, adloader, constants); -}; +} + +adaptermanager.registerBidAdapter(new MantisAdapter, 'mantis'); + +module.exports = MantisAdapter; diff --git a/src/adapters/memeglobal.js b/modules/memeglobalBidAdapter.js similarity index 91% rename from src/adapters/memeglobal.js rename to modules/memeglobalBidAdapter.js index 1f70d18e666..fecd09899a7 100644 --- a/src/adapters/memeglobal.js +++ b/modules/memeglobalBidAdapter.js @@ -1,8 +1,9 @@ -var CONSTANTS = require('../constants.json'); -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader'); +var CONSTANTS = require('src/constants.json'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader'); +var adaptermanager = require('src/adaptermanager'); var defaultPlacementForBadBid = null; var bidderName = 'memeglobal'; @@ -122,4 +123,6 @@ var MemeGlobalAdapter = function MemeGlobalAdapter() { }; }; +adaptermanager.registerBidAdapter(new MemeGlobalAdapter, 'memeglobal'); + module.exports = MemeGlobalAdapter; diff --git a/src/adapters/nginad.js b/modules/nginadBidAdapter.js similarity index 93% rename from src/adapters/nginad.js rename to modules/nginadBidAdapter.js index cedebfbd1e1..b94e68fe9ab 100644 --- a/src/adapters/nginad.js +++ b/modules/nginadBidAdapter.js @@ -1,8 +1,9 @@ -var CONSTANTS = require('../constants.json'); -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader'); +var CONSTANTS = require('src/constants.json'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader'); +var adaptermanager = require('src/adaptermanager'); var defaultPlacementForBadBid = null; @@ -180,4 +181,6 @@ var NginAdAdapter = function NginAdAdapter() { }; }; +adaptermanager.registerBidAdapter(new NginAdAdapter, 'nginad'); + module.exports = NginAdAdapter; diff --git a/src/adapters/openx.js b/modules/openxBidAdapter.js similarity index 94% rename from src/adapters/openx.js rename to modules/openxBidAdapter.js index 6341b860134..8dddd138e3b 100644 --- a/src/adapters/openx.js +++ b/modules/openxBidAdapter.js @@ -1,8 +1,9 @@ -const bidfactory = require('../bidfactory.js'); -const bidmanager = require('../bidmanager.js'); -const adloader = require('../adloader'); -const CONSTANTS = require('../constants.json'); -const utils = require('../utils.js'); +const bidfactory = require('src/bidfactory.js'); +const bidmanager = require('src/bidmanager.js'); +const adloader = require('src/adloader'); +const CONSTANTS = require('src/constants.json'); +const utils = require('src/utils.js'); +const adaptermanager = require('src/adaptermanager'); const OpenxAdapter = function OpenxAdapter() { const BIDDER_CODE = 'openx'; @@ -230,4 +231,6 @@ const OpenxAdapter = function OpenxAdapter() { }; }; +adaptermanager.registerBidAdapter(new OpenxAdapter, 'openx'); + module.exports = OpenxAdapter; diff --git a/src/adapters/piximedia.js b/modules/piximediaBidAdapter.js similarity index 93% rename from src/adapters/piximedia.js rename to modules/piximediaBidAdapter.js index b075259fae9..8d79f6f4468 100644 --- a/src/adapters/piximedia.js +++ b/modules/piximediaBidAdapter.js @@ -1,9 +1,10 @@ -var CONSTANTS = require('../constants.json'); -var utils = require('../utils.js'); -var bidmanager = require('../bidmanager.js'); -var bidfactory = require('../bidfactory.js'); -var adloader = require('../adloader.js'); -var Adapter = require('./adapter.js'); +var CONSTANTS = require('src/constants.json'); +var utils = require('src/utils.js'); +var bidmanager = require('src/bidmanager.js'); +var bidfactory = require('src/bidfactory.js'); +var adloader = require('src/adloader.js'); +var Adapter = require('src/adapter.js'); +var adaptermanager = require('src/adaptermanager'); var PiximediaAdapter = function PiximediaAdapter() { var PREBID_URL = '//static.adserver.pm/prebid'; @@ -149,4 +150,6 @@ var PiximediaAdapter = function PiximediaAdapter() { }; }; +adaptermanager.registerBidAdapter(new PiximediaAdapter, 'piximedia'); + module.exports = PiximediaAdapter; diff --git a/src/adapters/prebidServer.js b/modules/prebidServerBidAdapter.js similarity index 97% rename from src/adapters/prebidServer.js rename to modules/prebidServerBidAdapter.js index 5dc78008060..96821bc6211 100644 --- a/src/adapters/prebidServer.js +++ b/modules/prebidServerBidAdapter.js @@ -1,10 +1,11 @@ -import Adapter from 'src/adapters/adapter'; +import Adapter from 'src/adapter'; import bidfactory from 'src/bidfactory'; import bidmanager from 'src/bidmanager'; import * as utils from 'src/utils'; import { ajax } from 'src/ajax'; import { STATUS } from 'src/constants'; import { queueSync, persist } from 'src/cookie'; +import adaptermanager from 'src/adaptermanager'; const TYPE = 's2s'; const cookiePersistMessage = `Your browser may be blocking 3rd party cookies. By clicking on this page you allow Prebid Server and other advertising partners to place cookies to help us advertise. You can opt out of their cookies
here.`; @@ -183,4 +184,6 @@ PrebidServer.createNew = function() { return new PrebidServer(); }; +adaptermanager.registerBidAdapter(new PrebidServer, 'prebidServer'); + module.exports = PrebidServer; diff --git a/src/adapters/pubgears.js b/modules/pubgearsBidAdapter.js similarity index 94% rename from src/adapters/pubgears.js rename to modules/pubgearsBidAdapter.js index 2da723606c0..354fe8a7f59 100644 --- a/src/adapters/pubgears.js +++ b/modules/pubgearsBidAdapter.js @@ -1,7 +1,8 @@ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var consts = require('../constants.json'); -var utils = require('../utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var consts = require('src/constants.json'); +var utils = require('src/utils.js'); +var adaptermanager = require('src/adaptermanager'); var d = document; var SCRIPT = 'script'; var PARAMS = 'params'; @@ -32,6 +33,8 @@ var CREATIVE_TEMPLATE = decodeURIComponent("%3Cscript%3E%0A(function(define)%7B% var TAG_URL = '//c.pubgears.com/tags/h'; var publisher = ''; +adaptermanager.registerBidAdapter(new PubGearsAdapter, BIDDER_CODE); + module.exports = PubGearsAdapter; function PubGearsAdapter() { diff --git a/src/adapters/pubmatic.js b/modules/pubmaticBidAdapter.js similarity index 94% rename from src/adapters/pubmatic.js rename to modules/pubmaticBidAdapter.js index 5ad17a1dccd..e573daf68d3 100644 --- a/src/adapters/pubmatic.js +++ b/modules/pubmaticBidAdapter.js @@ -1,6 +1,7 @@ -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adaptermanager = require('src/adaptermanager'); /** * Adapter for requesting bids from Pubmatic. @@ -8,7 +9,7 @@ var bidmanager = require('../bidmanager.js'); * @returns {{callBids: _callBids}} * @constructor */ -var PubmaticAdapter = function PubmaticAdapter() { +function PubmaticAdapter() { var bids; var _pm_pub_id; var _pm_pub_age; @@ -146,6 +147,8 @@ var PubmaticAdapter = function PubmaticAdapter() { return { callBids: _callBids }; -}; +} + +adaptermanager.registerBidAdapter(new PubmaticAdapter, 'pubmatic'); module.exports = PubmaticAdapter; diff --git a/src/adapters/analytics/pubwiseanalytics.js b/modules/pubwiseAnalyticsAdapter.js similarity index 85% rename from src/adapters/analytics/pubwiseanalytics.js rename to modules/pubwiseAnalyticsAdapter.js index 5a2cb348f3b..f3779ab28ef 100644 --- a/src/adapters/analytics/pubwiseanalytics.js +++ b/modules/pubwiseAnalyticsAdapter.js @@ -1,6 +1,7 @@ import {ajax} from 'src/ajax'; -import adapter from 'AnalyticsAdapter'; -const utils = require('../../utils'); +import adapter from 'src/AnalyticsAdapter'; +import adaptermanager from 'src/adaptermanager'; +const utils = require('src/utils'); /**** * PubWise.io Analytics @@ -42,5 +43,11 @@ let pubwiseAnalytics = Object.assign(adapter( ); } }); + +adaptermanager.registerAnalyticsAdapter({ + adapter: pubwiseAnalytics, + code: 'pubwise' +}); + export default pubwiseAnalytics; diff --git a/modules/pulsepointAnalyticsAdapter.js b/modules/pulsepointAnalyticsAdapter.js new file mode 100644 index 00000000000..3a321fb0692 --- /dev/null +++ b/modules/pulsepointAnalyticsAdapter.js @@ -0,0 +1,19 @@ +/** + * pulsepoint.js - Analytics Adapter for PulsePoint + */ + +import adapter from 'src/AnalyticsAdapter'; +import adaptermanager from 'src/adaptermanager'; + +var pulsepointAdapter = adapter({ + global: 'PulsePointPrebidAnalytics', + handler: 'on', + analyticsType: 'bundle' +}); + +adaptermanager.registerAnalyticsAdapter({ + adapter: pulsepointAdapter, + code: 'pulsepoint' +}); + +export default pulsepointAdapter; diff --git a/src/adapters/pulsepoint.js b/modules/pulsepointBidAdapter.js similarity index 88% rename from src/adapters/pulsepoint.js rename to modules/pulsepointBidAdapter.js index 9a426bc5815..bff36bbda64 100644 --- a/src/adapters/pulsepoint.js +++ b/modules/pulsepointBidAdapter.js @@ -1,7 +1,8 @@ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader.js'); -var utils = require('../utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader.js'); +var utils = require('src/utils.js'); +var adaptermanager = require('src/adaptermanager'); var PulsePointAdapter = function PulsePointAdapter() { var getJsStaticUrl = window.location.protocol + '//tag-st.contextweb.com/getjs.static.js'; @@ -79,4 +80,6 @@ var PulsePointAdapter = function PulsePointAdapter() { }; }; +adaptermanager.registerBidAdapter(new PulsePointAdapter, 'pulsepoint'); + module.exports = PulsePointAdapter; diff --git a/src/adapters/pulsepointLite.js b/modules/pulsepointLiteBidAdapter.js similarity index 95% rename from src/adapters/pulsepointLite.js rename to modules/pulsepointLiteBidAdapter.js index be2fc01934a..807477f729d 100644 --- a/src/adapters/pulsepointLite.js +++ b/modules/pulsepointLiteBidAdapter.js @@ -3,6 +3,7 @@ import {addBidResponse} from 'src/bidmanager'; import {logError, getTopWindowLocation} from 'src/utils'; import {ajax} from 'src/ajax'; import {STATUS} from 'src/constants'; +import adaptermanager from 'src/adaptermanager'; function PulsePointLiteAdapter() { const bidUrl = window.location.protocol + '//bid.contextweb.com/header/tag?'; @@ -85,4 +86,6 @@ function PulsePointLiteAdapter() { }; } +adaptermanager.registerBidAdapter(new PulsePointLiteAdapter, 'pulsepointLite'); + module.exports = PulsePointLiteAdapter; diff --git a/src/adapters/quantcast.js b/modules/quantcastBidAdapter.js similarity index 91% rename from src/adapters/quantcast.js rename to modules/quantcastBidAdapter.js index 1cdbbac00c1..52d28a6361e 100644 --- a/src/adapters/quantcast.js +++ b/modules/quantcastBidAdapter.js @@ -1,8 +1,9 @@ -const utils = require('../utils.js'); -const bidfactory = require('../bidfactory.js'); -const bidmanager = require('../bidmanager.js'); -const ajax = require('../ajax.js'); -const CONSTANTS = require('../constants.json'); +const utils = require('src/utils.js'); +const bidfactory = require('src/bidfactory.js'); +const bidmanager = require('src/bidmanager.js'); +const ajax = require('src/ajax.js'); +const CONSTANTS = require('src/constants.json'); +const adaptermanager = require('src/adaptermanager'); const QUANTCAST_CALLBACK_URL = 'http://global.qc.rtb.quantserve.com:8080/qchb'; var QuantcastAdapter = function QuantcastAdapter() { @@ -128,5 +129,6 @@ exports.createNew = function() { return new QuantcastAdapter(); }; +adaptermanager.registerBidAdapter(new QuantcastAdapter, 'quantcast'); module.exports = QuantcastAdapter; diff --git a/src/adapters/rhythmone.js b/modules/rhythmoneBidAdapter.js similarity index 95% rename from src/adapters/rhythmone.js rename to modules/rhythmoneBidAdapter.js index 17264350009..b8bf79ac765 100644 --- a/src/adapters/rhythmone.js +++ b/modules/rhythmoneBidAdapter.js @@ -1,10 +1,11 @@ -var bidmanager = require('../bidmanager.js'), - bidfactory = require('../bidfactory.js'), - CONSTANTS = require('../constants.json'); +import {ajax} from 'src/ajax'; +import adaptermanager from 'src/adaptermanager'; -import {ajax} from '../ajax'; +var bidmanager = require('src/bidmanager.js'), + bidfactory = require('src/bidfactory.js'), + CONSTANTS = require('src/constants.json'); -module.exports = function(bidManager, global, loader) { +function RhythmoneAdapter (bidManager, global, loader) { var version = '0.9.0.0', defaultZone = '1r', defaultPath = 'mvo', @@ -290,4 +291,10 @@ module.exports = function(bidManager, global, loader) { logToConsole('version: ' + version); }; -}; +} + +adaptermanager.registerBidAdapter(new RhythmoneAdapter, 'rhythmone', { + supportedMediaTypes: ['video'] +}); + +module.exports = RhythmoneAdapter; diff --git a/src/adapters/analytics/roxot.js b/modules/roxotAnalyticsAdapter.js similarity index 91% rename from src/adapters/analytics/roxot.js rename to modules/roxotAnalyticsAdapter.js index e74aee712cd..905da96df6a 100644 --- a/src/adapters/analytics/roxot.js +++ b/modules/roxotAnalyticsAdapter.js @@ -1,8 +1,9 @@ import {ajax} from 'src/ajax'; -import adapter from 'AnalyticsAdapter'; +import adapter from 'src/AnalyticsAdapter'; import CONSTANTS from 'src/constants.json'; +import adaptermanager from 'src/adaptermanager'; -const utils = require('../../utils'); +const utils = require('src/utils'); const url = '//pa.rxthdr.com/analytic'; const analyticsType = 'endpoint'; @@ -95,4 +96,9 @@ roxotAdapter.enableAnalytics = function (config) { roxotAdapter.originEnableAnalytics(config); }; +adaptermanager.registerAnalyticsAdapter({ + adapter: roxotAdapter, + code: 'roxot' +}); + export default roxotAdapter; diff --git a/src/adapters/roxot.js b/modules/roxotBidAdapter.js similarity index 89% rename from src/adapters/roxot.js rename to modules/roxotBidAdapter.js index 21d40597d7b..a106342ae4f 100644 --- a/src/adapters/roxot.js +++ b/modules/roxotBidAdapter.js @@ -1,8 +1,9 @@ -var CONSTANTS = require('../constants.json'); -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader'); +var CONSTANTS = require('src/constants.json'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader'); +var adaptermanager = require('src/adaptermanager'); var RoxotAdapter = function RoxotAdapter() { var roxotUrl = 'r.rxthdr.com'; @@ -110,4 +111,6 @@ var RoxotAdapter = function RoxotAdapter() { } }; +adaptermanager.registerBidAdapter(new RoxotAdapter, 'roxot'); + module.exports = RoxotAdapter; diff --git a/src/adapters/rubicon.js b/modules/rubiconBidAdapter.js similarity index 97% rename from src/adapters/rubicon.js rename to modules/rubiconBidAdapter.js index 241e30c6fdf..c9d91a11430 100644 --- a/src/adapters/rubicon.js +++ b/modules/rubiconBidAdapter.js @@ -1,6 +1,7 @@ -import * as Adapter from './adapter.js'; +import * as Adapter from 'src/adapter'; import bidfactory from 'src/bidfactory'; import bidmanager from 'src/bidmanager'; +import adaptermanager from 'src/adaptermanager'; import * as utils from 'src/utils'; import { ajax } from 'src/ajax'; import { STATUS } from 'src/constants'; @@ -414,5 +415,10 @@ RubiconAdapter.createNew = function() { return new RubiconAdapter(); }; +adaptermanager.registerBidAdapter(new RubiconAdapter, RUBICON_BIDDER_CODE, { + supportedMediaTypes: ['video'] +}); +adaptermanager.aliasBidAdapter(RUBICON_BIDDER_CODE, 'rubiconLite'); + module.exports = RubiconAdapter; diff --git a/src/adapters/sekindoUM.js b/modules/sekindoUMBidAdapter.js similarity index 88% rename from src/adapters/sekindoUM.js rename to modules/sekindoUMBidAdapter.js index 62be5c2095d..caf4e82cf81 100755 --- a/src/adapters/sekindoUM.js +++ b/modules/sekindoUMBidAdapter.js @@ -1,9 +1,10 @@ -import { getBidRequest } from '../utils.js'; -var CONSTANTS = require('../constants.json'); -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader.js'); +import { getBidRequest } from 'src/utils.js'; +var CONSTANTS = require('src/constants.json'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader.js'); +var adaptermanager = require('src/adaptermanager'); var sekindoUMAdapter; sekindoUMAdapter = function sekindoUMAdapter() { @@ -84,4 +85,6 @@ sekindoUMAdapter = function sekindoUMAdapter() { }; }; +adaptermanager.registerBidAdapter(new sekindoUMAdapter, 'sekindoUM'); + module.exports = sekindoUMAdapter; diff --git a/src/adapters/serverbid.js b/modules/serverbidBidAdapter.js similarity index 96% rename from src/adapters/serverbid.js rename to modules/serverbidBidAdapter.js index a7ba5f6a57e..c29e1bc8617 100644 --- a/src/adapters/serverbid.js +++ b/modules/serverbidBidAdapter.js @@ -1,8 +1,9 @@ -import Adapter from 'src/adapters/adapter'; +import Adapter from 'src/adapter'; import bidfactory from 'src/bidfactory'; import bidmanager from 'src/bidmanager'; import * as utils from 'src/utils'; import { ajax } from 'src/ajax'; +import adaptermanager from 'src/adaptermanager'; const ServerBidAdapter = function ServerBidAdapter() { const baseAdapter = Adapter.createNew('serverbid'); @@ -150,4 +151,6 @@ ServerBidAdapter.createNew = function() { return new ServerBidAdapter(); }; +adaptermanager.registerBidAdapter(new ServerBidAdapter, 'serverbid'); + module.exports = ServerBidAdapter; diff --git a/src/adapters/analytics/sharethrough_analytics.js b/modules/sharethroughAnalyticsAdapter.js similarity index 86% rename from src/adapters/analytics/sharethrough_analytics.js rename to modules/sharethroughAnalyticsAdapter.js index a7c17cc525f..57724864b16 100644 --- a/src/adapters/analytics/sharethrough_analytics.js +++ b/modules/sharethroughAnalyticsAdapter.js @@ -1,12 +1,13 @@ -import adapter from 'AnalyticsAdapter'; -const utils = require('../../utils'); +import adapter from 'src/AnalyticsAdapter'; +import adaptermanager from 'src/adaptermanager'; +const utils = require('src/utils'); const emptyUrl = ''; const analyticsType = 'endpoint'; const STR_BIDDER_CODE = 'sharethrough'; const STR_VERSION = '0.1.0'; -export default Object.assign(adapter( +var sharethroughAdapter = Object.assign(adapter( { emptyUrl, analyticsType @@ -61,3 +62,10 @@ export default Object.assign(adapter( img.src = theUrl; } }); + +adaptermanager.registerAnalyticsAdapter({ + adapter: sharethroughAdapter, + code: 'sharethrough' +}); + +export default sharethroughAdapter; diff --git a/src/adapters/sharethrough.js b/modules/sharethroughBidAdapter.js similarity index 92% rename from src/adapters/sharethrough.js rename to modules/sharethroughBidAdapter.js index c8d4ca12e2d..9ab67af89bb 100644 --- a/src/adapters/sharethrough.js +++ b/modules/sharethroughBidAdapter.js @@ -1,7 +1,8 @@ -var utils = require('../utils.js'); -var bidmanager = require('../bidmanager.js'); -var bidfactory = require('../bidfactory.js'); -var ajax = require('../ajax.js').ajax; +var utils = require('src/utils.js'); +var bidmanager = require('src/bidmanager.js'); +var bidfactory = require('src/bidfactory.js'); +var ajax = require('src/ajax.js').ajax; +var adaptermanager = require('src/adaptermanager'); const STR_BIDDER_CODE = 'sharethrough'; const STR_VERSION = '1.2.0'; @@ -103,4 +104,6 @@ var SharethroughAdapter = function SharethroughAdapter() { }; }; +adaptermanager.registerBidAdapter(new SharethroughAdapter, 'sharethrough'); + module.exports = SharethroughAdapter; diff --git a/src/adapters/smartadserver.js b/modules/smartadserverBidAdapter.js similarity index 87% rename from src/adapters/smartadserver.js rename to modules/smartadserverBidAdapter.js index 21676beebc1..9d39cfc5c8d 100644 --- a/src/adapters/smartadserver.js +++ b/modules/smartadserverBidAdapter.js @@ -1,8 +1,9 @@ -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); var adloader = require('src/adloader.js'); -var url = require('url'); +var url = require('src/url.js'); +var adaptermanager = require('src/adaptermanager'); var SmartAdServer = function SmartAdServer() { var generateCallback = function(bid) { @@ -54,4 +55,6 @@ var SmartAdServer = function SmartAdServer() { }; }; +adaptermanager.registerBidAdapter(new SmartAdServer, 'smartadserver'); + module.exports = SmartAdServer; diff --git a/src/adapters/smartyads.js b/modules/smartyadsBidAdapter.js similarity index 96% rename from src/adapters/smartyads.js rename to modules/smartyadsBidAdapter.js index 8416f90a701..2c6cde0c8e8 100755 --- a/src/adapters/smartyads.js +++ b/modules/smartyadsBidAdapter.js @@ -1,9 +1,10 @@ -import * as Adapter from './adapter.js'; +import * as Adapter from 'src/adapter.js'; import bidfactory from 'src/bidfactory'; import bidmanager from 'src/bidmanager'; import * as utils from 'src/utils'; import {ajax} from 'src/ajax'; import {STATUS} from 'src/constants'; +import adaptermanager from 'src/adaptermanager'; const SMARTYADS_BIDDER_CODE = 'smartyads'; @@ -179,4 +180,6 @@ SmartyadsAdapter.createNew = function () { return new SmartyadsAdapter(); }; +adaptermanager.registerBidAdapter(new SmartyadsAdapter, 'smartyads'); + module.exports = SmartyadsAdapter; diff --git a/src/adapters/sonobi.js b/modules/sonobiBidAdapter.js similarity index 93% rename from src/adapters/sonobi.js rename to modules/sonobiBidAdapter.js index cfec52257cf..f8ee391050d 100644 --- a/src/adapters/sonobi.js +++ b/modules/sonobiBidAdapter.js @@ -1,7 +1,8 @@ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader.js'); -var utils = require('../utils'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader.js'); +var utils = require('src/utils'); +var adaptermanager = require('src/adaptermanager'); var SonobiAdapter = function SonobiAdapter() { var keymakerAssoc = {}; // Remember placement codes for callback mapping @@ -112,4 +113,6 @@ var SonobiAdapter = function SonobiAdapter() { }; }; +adaptermanager.registerBidAdapter(new SonobiAdapter, 'sonobi'); + module.exports = SonobiAdapter; diff --git a/src/adapters/sovrn.js b/modules/sovrnBidAdapter.js similarity index 93% rename from src/adapters/sovrn.js rename to modules/sovrnBidAdapter.js index 968ce3985fa..e5d59ad637f 100644 --- a/src/adapters/sovrn.js +++ b/modules/sovrnBidAdapter.js @@ -1,8 +1,9 @@ -var CONSTANTS = require('../constants.json'); -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader'); +var CONSTANTS = require('src/constants.json'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader'); +var adaptermanager = require('src/adaptermanager'); /** * Adapter for requesting bids from Sovrn @@ -157,4 +158,6 @@ var SovrnAdapter = function SovrnAdapter() { }; }; +adaptermanager.registerBidAdapter(new SovrnAdapter, 'sovrn'); + module.exports = SovrnAdapter; diff --git a/src/adapters/springserve.js b/modules/springserveBidAdapter.js similarity index 93% rename from src/adapters/springserve.js rename to modules/springserveBidAdapter.js index 84e5002827a..d0ec313e7e2 100644 --- a/src/adapters/springserve.js +++ b/modules/springserveBidAdapter.js @@ -1,6 +1,7 @@ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader'); +var adaptermanager = require('src/adaptermanager'); var SpringServeAdapter; SpringServeAdapter = function SpringServeAdapter() { @@ -110,4 +111,6 @@ SpringServeAdapter = function SpringServeAdapter() { }; }; +adaptermanager.registerBidAdapter(new SpringServeAdapter, 'springserveg'); + module.exports = SpringServeAdapter; diff --git a/src/adapters/stickyadstv.js b/modules/stickyadstvBidAdapter.js similarity index 92% rename from src/adapters/stickyadstv.js rename to modules/stickyadstvBidAdapter.js index d0095541a8f..27ebb4ef31a 100644 --- a/src/adapters/stickyadstv.js +++ b/modules/stickyadstvBidAdapter.js @@ -1,7 +1,9 @@ -var Adapter = require('./adapter.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader.js'); +var Adapter = require('src/adapter.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader.js'); +var utils = require('src/utils.js'); +var adaptermanager = require('src/adaptermanager'); var StickyAdsTVAdapter = function StickyAdsTVAdapter() { var STICKYADS_BIDDERCODE = 'stickyadstv'; @@ -21,7 +23,7 @@ var StickyAdsTVAdapter = function StickyAdsTVAdapter() { if (bid.placementCode && bid.params.zoneId) { sendBidRequest(bid); } else { - console.warn('StickyAdsTV: Missing mandatory field(s).'); + utils.logWarn('StickyAdsTV: Missing mandatory field(s).'); } } } @@ -200,7 +202,7 @@ var StickyAdsTVAdapter = function StickyAdsTVAdapter() { var priceData = vast.getPricing(); if (!priceData) { - console.warn("StickyAdsTV: Bid pricing Can't be retreived. You may need to enable pricing on you're zone. Please get in touch with your sticky contact."); + utils.logWarn("StickyAdsTV: Bid pricing Can't be retreived. You may need to enable pricing on you're zone. Please get in touch with your sticky contact."); } return priceData; @@ -271,4 +273,7 @@ StickyAdsTVAdapter.createNew = function() { return new StickyAdsTVAdapter(); }; +adaptermanager.registerBidAdapter(new StickyAdsTVAdapter, 'stickyadstv'); +adaptermanager.aliasBidAdapter('stickyadstv', 'freewheel-ssp'); + module.exports = StickyAdsTVAdapter; diff --git a/src/adapters/tapsense.js b/modules/tapsenseBidAdapter.js similarity index 88% rename from src/adapters/tapsense.js rename to modules/tapsenseBidAdapter.js index 9ac7cf2c0e2..cfd2fae1c2f 100644 --- a/src/adapters/tapsense.js +++ b/modules/tapsenseBidAdapter.js @@ -1,9 +1,10 @@ // v0.0.1 -const bidfactory = require('../bidfactory.js'); -const bidmanager = require('../bidmanager.js'); -const adloader = require('../adloader'); -const utils = require('../utils.js'); +const bidfactory = require('src/bidfactory.js'); +const bidmanager = require('src/bidmanager.js'); +const adloader = require('src/adloader'); +const utils = require('src/utils.js'); +const adaptermanager = require('src/adaptermanager'); const TapSenseAdapter = function TapSenseAdapter() { const version = '0.0.1'; @@ -83,4 +84,6 @@ const TapSenseAdapter = function TapSenseAdapter() { }; }; +adaptermanager.registerBidAdapter(new TapSenseAdapter, 'tapsense'); + module.exports = TapSenseAdapter; diff --git a/src/adapters/thoughtleadr.js b/modules/thoughtleadrBidAdapter.js similarity index 91% rename from src/adapters/thoughtleadr.js rename to modules/thoughtleadrBidAdapter.js index 70ffe2e610e..17092fc1819 100644 --- a/src/adapters/thoughtleadr.js +++ b/modules/thoughtleadrBidAdapter.js @@ -1,8 +1,9 @@ 'use strict'; -var bidfactory = require('../bidfactory'); -var bidmanager = require('../bidmanager'); -var utils = require('../utils'); -var adloader_1 = require('../adloader'); +var bidfactory = require('src/bidfactory'); +var bidmanager = require('src/bidmanager'); +var utils = require('src/utils'); +var adloader_1 = require('src/adloader'); +var adaptermanager = require('src/adaptermanager'); var ROOT_URL = '//cdn.thoughtleadr.com/v4/'; var BID_AVAILABLE = 1; @@ -96,4 +97,6 @@ var ThoughtleadrAdapter = (function () { return ThoughtleadrAdapter; }()); +adaptermanager.registerBidAdapter(new ThoughtleadrAdapter, 'thoughtleadr'); + module.exports = ThoughtleadrAdapter; diff --git a/src/adapters/trion.js b/modules/trionBidAdapter.js similarity index 89% rename from src/adapters/trion.js rename to modules/trionBidAdapter.js index c0320f262c3..4b2b1e9f508 100644 --- a/src/adapters/trion.js +++ b/modules/trionBidAdapter.js @@ -1,17 +1,15 @@ -import { getBidRequest } from '../utils.js'; - -var CONSTANTS = require('../constants.json'); -var utils = require('../utils.js'); -var adloader = require('../adloader.js'); -var bidmanager = require('../bidmanager.js'); -var bidfactory = require('../bidfactory.js'); -var Adapter = require('./adapter.js'); +var CONSTANTS = require('src/constants.json'); +var utils = require('src/utils.js'); +var adloader = require('src/adloader.js'); +var bidmanager = require('src/bidmanager.js'); +var bidfactory = require('src/bidfactory.js'); +var Adapter = require('src/adapter.js'); +var adaptermanager = require('src/adaptermanager'); const BID_REQUEST_BASE_URL = 'https://in-appadvertising.com/api/bidRequest?'; const USER_SYNC_URL = 'https://in-appadvertising.com/api/userSync.js'; -var TrionAdapter; -TrionAdapter = function TrionAdapter() { +function TrionAdapter() { var baseAdapter = Adapter.createNew('trion'); var userTag = null; @@ -98,7 +96,7 @@ TrionAdapter = function TrionAdapter() { var bidId = trionResponseObj.bidId; var result = trionResponseObj && trionResponseObj.result; - bidObj = getBidRequest(bidId); + bidObj = utils.getBidRequest(bidId); if (bidObj) { bidCode = bidObj.bidder; placementCode = bidObj.placementCode; @@ -132,4 +130,6 @@ TrionAdapter.createNew = function () { return new TrionAdapter(); }; +adaptermanager.registerBidAdapter(new TrionAdapter, 'trion'); + module.exports = TrionAdapter; diff --git a/src/adapters/triplelift.js b/modules/tripleliftBidAdapter.js similarity index 93% rename from src/adapters/triplelift.js rename to modules/tripleliftBidAdapter.js index bc17682f8ea..b029d9a2c14 100644 --- a/src/adapters/triplelift.js +++ b/modules/tripleliftBidAdapter.js @@ -1,7 +1,8 @@ -var utils = require('../utils.js'); -var adloader = require('../adloader.js'); -var bidmanager = require('../bidmanager.js'); -var bidfactory = require('../bidfactory.js'); +var utils = require('src/utils.js'); +var adloader = require('src/adloader.js'); +var bidmanager = require('src/bidmanager.js'); +var bidfactory = require('src/bidfactory.js'); +var adaptermanager = require('src/adaptermanager'); /* TripleLift bidder factory function * Use to create a TripleLiftAdapter object @@ -126,4 +127,7 @@ var TripleLiftAdapter = function TripleLiftAdapter() { }; }; + +adaptermanager.registerBidAdapter(new TripleLiftAdapter, 'triplelift'); + module.exports = TripleLiftAdapter; diff --git a/src/adapters/twenga.js b/modules/twengaBidAdapter.js similarity index 89% rename from src/adapters/twenga.js rename to modules/twengaBidAdapter.js index 5951e16bc2d..34a4bef444b 100644 --- a/src/adapters/twenga.js +++ b/modules/twengaBidAdapter.js @@ -1,14 +1,12 @@ -import { getBidRequest } from '../utils.js'; - -var CONSTANTS = require('../constants.json'); -var utils = require('../utils.js'); -var adloader = require('../adloader.js'); -var bidmanager = require('../bidmanager.js'); -var bidfactory = require('../bidfactory.js'); -var Adapter = require('./adapter.js'); - -var TwengaAdapter; -TwengaAdapter = function TwengaAdapter() { +var CONSTANTS = require('src/constants.json'); +var utils = require('src/utils.js'); +var adloader = require('src/adloader.js'); +var bidmanager = require('src/bidmanager.js'); +var bidfactory = require('src/bidfactory.js'); +var Adapter = require('src/adapter.js'); +var adaptermanager = require('src/adaptermanager'); + +function TwengaAdapter() { var baseAdapter = Adapter.createNew('twenga'); baseAdapter.callBids = function (params) { @@ -66,7 +64,7 @@ TwengaAdapter = function TwengaAdapter() { var responseCPM; var id = bidResponseObj.callback_uid; var placementCode = ''; - var bidObj = getBidRequest(id); + var bidObj = utils.getBidRequest(id); if (bidObj) { bidCode = bidObj.bidder; @@ -138,4 +136,6 @@ TwengaAdapter.createNew = function () { return new TwengaAdapter(); }; +adaptermanager.registerBidAdapter(new TwengaAdapter, 'twenga'); + module.exports = TwengaAdapter; diff --git a/src/adapters/underdogmedia.js b/modules/underdogmediaBidAdapter.js similarity index 89% rename from src/adapters/underdogmedia.js rename to modules/underdogmediaBidAdapter.js index b027fd46902..ac708d97278 100644 --- a/src/adapters/underdogmedia.js +++ b/modules/underdogmediaBidAdapter.js @@ -1,9 +1,10 @@ -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader.js'); -var utils = require('../utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader.js'); +var utils = require('src/utils.js'); +var adaptermanager = require('src/adaptermanager'); -var UnderdogMediaAdapter = function UnderdogMediaAdapter() { +function UnderdogMediaAdapter() { const UDM_ADAPTER_VERSION = '1.0.0'; var getJsStaticUrl = window.location.protocol + '//udmserve.net/udm/img.fetch?tid=1;dt=9;callback=$$PREBID_GLOBAL$$.handleUnderdogMediaCB;'; var bidParams = {}; @@ -104,6 +105,8 @@ var UnderdogMediaAdapter = function UnderdogMediaAdapter() { return { callBids: _callBids }; -}; +} + +adaptermanager.registerBidAdapter(new UnderdogMediaAdapter, 'underdogmedia'); module.exports = UnderdogMediaAdapter; diff --git a/src/adapters/unruly.js b/modules/unrulyBidAdapter.js similarity index 96% rename from src/adapters/unruly.js rename to modules/unrulyBidAdapter.js index c9fbfde1ecc..54c6c9412be 100644 --- a/src/adapters/unruly.js +++ b/modules/unrulyBidAdapter.js @@ -4,6 +4,7 @@ import bidmanager from 'src/bidmanager' import * as utils from 'src/utils' import { STATUS } from 'src/constants' import { Renderer } from 'src/Renderer' +import adaptermanager from 'src/adaptermanager' function createRenderHandler({ bidResponseBid, rendererConfig }) { function createApi() { @@ -105,4 +106,6 @@ function createUnrulyAdapter() { return adapter } +adaptermanager.registerBidAdapter(new createUnrulyAdapter, 'unruly') + module.exports = createUnrulyAdapter diff --git a/src/adapters/vertamedia.js b/modules/vertamediaBidAdapter.js similarity index 93% rename from src/adapters/vertamedia.js rename to modules/vertamediaBidAdapter.js index ecce8c1d84f..9afdd2a7fa2 100644 --- a/src/adapters/vertamedia.js +++ b/modules/vertamediaBidAdapter.js @@ -1,9 +1,10 @@ -import Adapter from 'src/adapters/adapter'; +import Adapter from 'src/adapter'; import bidfactory from 'src/bidfactory'; import bidmanager from 'src/bidmanager'; import * as utils from 'src/utils'; import { ajax } from 'src/ajax'; import { STATUS } from 'src/constants'; +import adaptermanager from 'src/adaptermanager'; const ENDPOINT = '//rtb.vertamedia.com/hb/'; @@ -116,4 +117,8 @@ VertamediaAdapter.createNew = function () { return new VertamediaAdapter(); }; +adaptermanager.registerBidAdapter(new VertamediaAdapter, 'vertamedia', { + supportedMediaTypes: ['video'] +}); + module.exports = VertamediaAdapter; diff --git a/src/adapters/vertoz.js b/modules/vertozBidAdapter.js similarity index 84% rename from src/adapters/vertoz.js rename to modules/vertozBidAdapter.js index 9f9767998d8..77731cbc2fa 100755 --- a/src/adapters/vertoz.js +++ b/modules/vertozBidAdapter.js @@ -1,10 +1,11 @@ -var CONSTANTS = require('../constants.json'); -var utils = require('../utils.js'); -var bidfactory = require('../bidfactory.js'); -var bidmanager = require('../bidmanager.js'); -var adloader = require('../adloader.js'); +var CONSTANTS = require('src/constants.json'); +var utils = require('src/utils.js'); +var bidfactory = require('src/bidfactory.js'); +var bidmanager = require('src/bidmanager.js'); +var adloader = require('src/adloader.js'); +var adaptermanager = require('src/adaptermanager'); -var VertozAdapter = function VertozAdapter() { +function VertozAdapter() { const BASE_URI = '//banner.vrtzads.com/vzhbidder/bid?'; const BIDDER_NAME = 'vertoz'; const QUERY_PARAM_KEY = 'q'; @@ -60,6 +61,8 @@ var VertozAdapter = function VertozAdapter() { bidmanager.addBidResponse(adSpaceId, bidObject); }; return { callBids: _callBids }; -}; +} + +adaptermanager.registerBidAdapter(new VertozAdapter, 'vertoz'); module.exports = VertozAdapter; diff --git a/src/adapters/wideorbit.js b/modules/wideorbitBidAdapter.js similarity index 95% rename from src/adapters/wideorbit.js rename to modules/wideorbitBidAdapter.js index 857def5c790..67f4b147622 100644 --- a/src/adapters/wideorbit.js +++ b/modules/wideorbitBidAdapter.js @@ -1,9 +1,10 @@ -var bidfactory = require('../bidfactory.js'), - bidmanager = require('../bidmanager.js'), - utils = require('../utils.js'), - adloader = require('../adloader'); +var bidfactory = require('src/bidfactory.js'), + bidmanager = require('src/bidmanager.js'), + utils = require('src/utils.js'), + adloader = require('src/adloader'), + adaptermanager = require('src/adaptermanager'); -var WideOrbitAdapter = function WideOrbitAdapter() { +function WideOrbitAdapter() { var pageImpression = 'JSAdservingMP.ashx?pc={pc}&pbId={pbId}&clk=&exm=&jsv=1.0&tsv=1.0&cts={cts}&arp=0&fl=0&vitp=&vit=&jscb=window.$$PREBID_GLOBAL$$.handleWideOrbitCallback&url={referrer}&fp=&oid=&exr=&mraid=&apid=&apbndl=&mpp=0&uid=&cb={cb}&hb=1', pageRepeatCommonParam = '&gid{o}={gid}&pp{o}=&clk{o}=&rpos{o}={rpos}&ecpm{o}={ecpm}&ntv{o}=&ntl{o}=&adsid{o}=', pageRepeatParamId = '&pId{o}={pId}&rank{o}={rank}', @@ -213,6 +214,8 @@ var WideOrbitAdapter = function WideOrbitAdapter() { return { callBids: _callBids }; -}; +} + +adaptermanager.registerBidAdapter(new WideOrbitAdapter, 'wideorbit'); module.exports = WideOrbitAdapter; diff --git a/src/adapters/widespace.js b/modules/widespaceBidAdapter.js similarity index 89% rename from src/adapters/widespace.js rename to modules/widespaceBidAdapter.js index cd8669f99be..a5a3925cab5 100644 --- a/src/adapters/widespace.js +++ b/modules/widespaceBidAdapter.js @@ -1,10 +1,9 @@ -import { getBidRequest } from '../utils.js'; - -const utils = require('../utils.js'); -const adloader = require('../adloader.js'); -const bidmanager = require('../bidmanager.js'); -const bidfactory = require('../bidfactory.js'); +const utils = require('src/utils.js'); +const adloader = require('src/adloader.js'); +const bidmanager = require('src/bidmanager.js'); +const bidfactory = require('src/bidfactory.js'); +const adaptermanager = require('src/adaptermanager'); const WS_ADAPTER_VERSION = '1.0.2'; function WidespaceAdapter() { @@ -72,7 +71,7 @@ function WidespaceAdapter() { bid.sizes = {height: bid.height, width: bid.width}; - var inBid = getBidRequest(bid.callbackUid); + var inBid = utils.getBidRequest(bid.callbackUid); if (inBid) { bidCode = inBid.bidder; @@ -113,4 +112,6 @@ function WidespaceAdapter() { }; } +adaptermanager.registerBidAdapter(new WidespaceAdapter, 'widespace'); + module.exports = WidespaceAdapter; diff --git a/src/adapters/xhb.js b/modules/xhbBidAdapter.js similarity index 92% rename from src/adapters/xhb.js rename to modules/xhbBidAdapter.js index 811f7b971e2..79c53b7d53c 100644 --- a/src/adapters/xhb.js +++ b/modules/xhbBidAdapter.js @@ -1,12 +1,11 @@ -import {getBidRequest} from '../utils.js'; - -const CONSTANTS = require('../constants.json'); -const utils = require('../utils.js'); -const adloader = require('../adloader.js'); -const bidmanager = require('../bidmanager.js'); -const bidfactory = require('../bidfactory.js'); - -const XhbAdapter = function XhbAdapter() { +const CONSTANTS = require('src/constants.json'); +const utils = require('src/utils.js'); +const adloader = require('src/adloader.js'); +const bidmanager = require('src/bidmanager.js'); +const bidfactory = require('src/bidfactory.js'); +const adaptermanager = require('src/adaptermanager'); + +function XhbAdapter() { const _defaultBidderSettings = { alwaysUseBid: true, adserverTargeting: [ @@ -109,7 +108,7 @@ const XhbAdapter = function XhbAdapter() { let responseCPM; let id = jptResponseObj.callback_uid; let placementCode = ''; - let bidObj = getBidRequest(id); + let bidObj = utils.getBidRequest(id); if (bidObj) { bidCode = bidObj.bidder; placementCode = bidObj.placementCode; @@ -158,6 +157,8 @@ const XhbAdapter = function XhbAdapter() { return { callBids: _callBids }; -}; +} + +adaptermanager.registerBidAdapter(new XhbAdapter, 'xhb'); module.exports = XhbAdapter; diff --git a/src/adapters/yieldbot.js b/modules/yieldbotBidAdapter.js similarity index 93% rename from src/adapters/yieldbot.js rename to modules/yieldbotBidAdapter.js index 1dc77a30f73..1d52d6b181a 100644 --- a/src/adapters/yieldbot.js +++ b/modules/yieldbotBidAdapter.js @@ -2,10 +2,11 @@ * @overview Yieldbot sponsored Prebid.js adapter. * @author elljoh */ -var adloader = require('../adloader'); -var bidfactory = require('../bidfactory'); -var bidmanager = require('../bidmanager'); -var utils = require('../utils'); +var adloader = require('src/adloader'); +var bidfactory = require('src/bidfactory'); +var bidmanager = require('src/bidmanager'); +var utils = require('src/utils'); +var adaptermanager = require('src/adaptermanager'); /** * Adapter for requesting bids from Yieldbot. @@ -13,7 +14,7 @@ var utils = require('../utils'); * @returns {Object} Object containing implementation for invocation in {@link module:adaptermanger.callBids} * @class */ -var YieldbotAdapter = function YieldbotAdapter() { +function YieldbotAdapter() { window.ybotq = window.ybotq || []; var ybotlib = { @@ -136,6 +137,8 @@ var YieldbotAdapter = function YieldbotAdapter() { return { callBids: ybotlib.callBids }; -}; +} + +adaptermanager.registerBidAdapter(new YieldbotAdapter, 'yieldbot'); module.exports = YieldbotAdapter; diff --git a/package.json b/package.json index f4c751dea7b..abe66a0aca3 100644 --- a/package.json +++ b/package.json @@ -45,10 +45,12 @@ "gulp-concat": "^2.6.0", "gulp-connect": "^2.0.6", "gulp-eslint": "^3.0.1", + "gulp-footer": "^1.0.5", "gulp-header": "^1.7.1", + "gulp-if": "^2.0.2", + "gulp-jscs": "^3.0.2", "gulp-jsdoc-to-markdown": "^1.2.1", "gulp-karma": "0.0.4", - "gulp-mocha": "^2.2.0", "gulp-optimize-js": "^1.1.0", "gulp-rename": "^1.2.0", "gulp-replace": "^0.4.0", @@ -94,6 +96,7 @@ "requirejs": "^2.1.20", "sinon": "^1.12.1", "string-replace-webpack-plugin": "0.0.3", + "through2": "^2.0.3", "uglify-js": "^2.8.10", "url-parse": "^1.0.5", "webpack": "^1.12.3", @@ -102,6 +105,7 @@ }, "dependencies": { "babel-plugin-transform-object-assign": "^6.22.0", - "core-js": "^2.4.1" + "core-js": "^2.4.1", + "gulp-sourcemaps": "^2.6.0" } } diff --git a/plugins/RequireEnsureWithoutJsonp.js b/plugins/RequireEnsureWithoutJsonp.js new file mode 100644 index 00000000000..b3b38f5e336 --- /dev/null +++ b/plugins/RequireEnsureWithoutJsonp.js @@ -0,0 +1,30 @@ +/** + * RequireEnsureWithoutJsonp + * + * This plugin redefines the behavior of require.ensure that is used by webpack to load chunks. Usually require.ensure + * includes code that allows the asynchronous loading of webpack chunks through jsonp requests AND includes a manifest + * of all the build chunks so that they can be requested by name (e.g. require.ensure('./module.js'). Since that + * functionality is not required and we plan on loading all of our chunks manually (either by concatenating all the + * files together or including as individual scripts) we don't want the overhead of including that loading code or the + * file manifest. In this plugin, that code is replaced with an error message if a module is requested that hasn't been + * loaded manually. + * + * @constructor + */ +function RequireEnsureWithoutJsonp() {} +RequireEnsureWithoutJsonp.prototype.apply = function(compiler) { + compiler.plugin('compilation', function(compilation) { + compilation.mainTemplate.plugin('require-ensure', function(_, chunk, hash) { + return ( +` +if(installedChunks[chunkId] === 0) + return callback.call(null, __webpack_require__); +else + console.error('webpack chunk not found and jsonp disabled'); +` + ).trim(); + }); + }); +}; + +module.exports = RequireEnsureWithoutJsonp; diff --git a/src/adapters/analytics/AnalyticsAdapter.js b/src/AnalyticsAdapter.js similarity index 99% rename from src/adapters/analytics/AnalyticsAdapter.js rename to src/AnalyticsAdapter.js index 34357ecb1d1..58c5048f929 100644 --- a/src/adapters/analytics/AnalyticsAdapter.js +++ b/src/AnalyticsAdapter.js @@ -3,7 +3,7 @@ import { loadScript } from 'src/adloader'; import { ajax } from 'src/ajax'; const events = require('src/events'); -const utils = require('../../utils'); +const utils = require('src/utils'); const AUCTION_INIT = CONSTANTS.EVENTS.AUCTION_INIT; const AUCTION_END = CONSTANTS.EVENTS.AUCTION_END; diff --git a/src/adapters/adapter.js b/src/adapter.js similarity index 100% rename from src/adapters/adapter.js rename to src/adapter.js diff --git a/src/adaptermanager.js b/src/adaptermanager.js index 106f0f80e48..97ed301ee1d 100644 --- a/src/adaptermanager.js +++ b/src/adaptermanager.js @@ -2,12 +2,11 @@ import { flatten, getBidderCodes, shuffle } from './utils'; import { mapSizes } from './sizeMapping'; -import native from './native'; +import { processNativeAdUnitParams, nativeAdapters } from './native'; var utils = require('./utils.js'); var CONSTANTS = require('./constants.json'); var events = require('./events'); -import { BaseAdapter } from './adapters/baseAdapter'; var _bidderRegistry = {}; exports.bidderRegistry = _bidderRegistry; @@ -32,7 +31,7 @@ function getBids({bidderCode, requestId, bidderRequestId, adUnits}) { if (adUnit.nativeParams) { bid = Object.assign({}, bid, { - nativeParams: native(adUnit.nativeParams), + nativeParams: processNativeAdUnitParams(adUnit.nativeParams), }); } @@ -154,10 +153,19 @@ function transformHeightWidth(adUnit) { return sizesObj; } -exports.registerBidAdapter = function (bidAdaptor, bidderCode) { +exports.videoAdapters = []; // added by adapterLoader for now + +exports.registerBidAdapter = function (bidAdaptor, bidderCode, {supportedMediaTypes = []} = {}) { if (bidAdaptor && bidderCode) { if (typeof bidAdaptor.callBids === CONSTANTS.objectType_function) { _bidderRegistry[bidderCode] = bidAdaptor; + + if (supportedMediaTypes.includes('video')) { + exports.videoAdapters.push(bidderCode); + } + if (supportedMediaTypes.includes('native')) { + nativeAdapters.push(bidderCode); + } } else { utils.logError('Bidder adaptor error for bidder code: ' + bidderCode + 'bidder must implement a callBids() function'); } @@ -177,14 +185,9 @@ exports.aliasBidAdapter = function (bidderCode, alias) { } else { try { let newAdapter = null; - if (bidAdaptor instanceof BaseAdapter) { - // newAdapter = new bidAdaptor.constructor(alias); - utils.logError(bidderCode + ' bidder does not currently support aliasing.', 'adaptermanager.aliasBidAdapter'); - } else { - newAdapter = bidAdaptor.createNew(); - newAdapter.setBidderCode(alias); - this.registerBidAdapter(newAdapter, alias); - } + newAdapter = bidAdaptor.createNew(); + newAdapter.setBidderCode(alias); + this.registerBidAdapter(newAdapter, alias); } catch (e) { utils.logError(bidderCode + ' bidder does not currently support aliasing.', 'adaptermanager.aliasBidAdapter'); } @@ -231,11 +234,3 @@ exports.setBidderSequence = function (order) { exports.setS2SConfig = function (config) { _s2sConfig = config; }; - -/** INSERT ADAPTERS - DO NOT EDIT OR REMOVE */ - -/** END INSERT ADAPTERS */ - -/** INSERT ANALYTICS - DO NOT EDIT OR REMOVE */ - -/** END INSERT ANALYTICS */ diff --git a/src/adapters/analytics/appnexus.js b/src/adapters/analytics/appnexus.js deleted file mode 100644 index 2c862ba16c1..00000000000 --- a/src/adapters/analytics/appnexus.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * appnexus.js - AppNexus Prebid Analytics Adapter - */ - -import adapter from 'AnalyticsAdapter'; - -export default adapter({ - global: 'AppNexusPrebidAnalytics', - handler: 'on', - analyticsType: 'bundle' -}); diff --git a/src/adapters/analytics/example.js b/src/adapters/analytics/example.js index f79a350630a..37ef0ff8fe3 100644 --- a/src/adapters/analytics/example.js +++ b/src/adapters/analytics/example.js @@ -2,7 +2,7 @@ * example.js - analytics adapter for Example Analytics Library example */ -import adapter from 'AnalyticsAdapter'; +import adapter from '../../AnalyticsAdapter'; export default adapter( { diff --git a/src/adapters/analytics/example2.js b/src/adapters/analytics/example2.js index b55a02d4cb6..8a9b8beb3ec 100644 --- a/src/adapters/analytics/example2.js +++ b/src/adapters/analytics/example2.js @@ -4,7 +4,7 @@ import { ajax } from 'src/ajax'; * example2.js - analytics adapter for Example2 Analytics Endpoint example */ -import adapter from 'AnalyticsAdapter'; +import adapter from '../../AnalyticsAdapter'; const url = 'https://httpbin.org/post'; const analyticsType = 'endpoint'; diff --git a/src/adapters/analytics/pulsepoint.js b/src/adapters/analytics/pulsepoint.js deleted file mode 100644 index f334c0f042f..00000000000 --- a/src/adapters/analytics/pulsepoint.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * pulsepoint.js - Analytics Adapter for PulsePoint - */ - -import adapter from 'AnalyticsAdapter'; - -export default adapter({ - global: 'PulsePointPrebidAnalytics', - handler: 'on', - analyticsType: 'bundle' -}); diff --git a/src/adapters/baseAdapter.js b/src/adapters/baseAdapter.js deleted file mode 100644 index 819436b4fee..00000000000 --- a/src/adapters/baseAdapter.js +++ /dev/null @@ -1,17 +0,0 @@ -export class BaseAdapter { - constructor(code) { - this.code = code; - } - - getCode() { - return this.code; - } - - setCode(code) { - this.code = code; - } - - callBids() { - throw 'adapter implementation must override callBids method'; - } -} diff --git a/src/native.js b/src/native.js index e2a96bca2f8..537296305d4 100644 --- a/src/native.js +++ b/src/native.js @@ -1,8 +1,6 @@ import { getBidRequest, logError, insertPixel } from './utils'; -/** INSERT NATIVE ADAPTERS - DO NOT EDIT OR REMOVE */ -const nativeAdapters = []; -/** END INSERT NATIVE ADAPTERS */ +export const nativeAdapters = []; export const NATIVE_KEYS = { title: 'hb_native_title', @@ -35,7 +33,7 @@ const SUPPORTED_TYPES = { * passes them on directly. If they were of type 'type', translate * them into the predefined specific asset requests for that type of native ad. */ -export default function processNativeAdUnitParams(params) { +export function processNativeAdUnitParams(params) { if (params && params.type && typeIsSupported(params.type)) { return SUPPORTED_TYPES[params.type]; } diff --git a/src/prebid.js b/src/prebid.js index 03762858d27..e211c447a1b 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -77,54 +77,6 @@ $$PREBID_GLOBAL$$.adUnits = $$PREBID_GLOBAL$$.adUnits || []; // delay to request cookie sync to stay out of critical path $$PREBID_GLOBAL$$.cookieSyncDelay = $$PREBID_GLOBAL$$.cookieSyncDelay || 100; - -/** - * This queue lets users load Prebid asynchronously, but run functions the same way regardless of whether it gets loaded - * before or after their script executes. For example, given the code: - * - * - * - * - * If the page's script runs before prebid loads, then their function gets added to the queue, and executed - * by prebid once it's done loading. If it runs after prebid loads, then this monkey-patch causes their - * function to execute immediately. - * - * @param {function} cmd A function which takes no arguments. This is guaranteed to run exactly once, and only after - * the Prebid script has been fully loaded. - * @alias module:$$PREBID_GLOBAL$$.cmd.push - */ -$$PREBID_GLOBAL$$.cmd.push = function(cmd) { - if (typeof cmd === objectType_function) { - try { - cmd.call(); - } catch (e) { - utils.logError('Error processing command :' + e.message); - } - } else { - utils.logError('Commands written into $$PREBID_GLOBAL$$.cmd.push must be wrapped in a function'); - } -}; - -$$PREBID_GLOBAL$$.que.push = $$PREBID_GLOBAL$$.cmd.push; - -function processQueue(queue) { - queue.forEach(function(cmd) { - if (typeof cmd.called === objectType_undefined) { - try { - cmd.call(); - cmd.called = true; - } - catch (e) { - utils.logError('Error processing command :', 'prebid.js', e); - } - } - }); -} - function checkDefinedPlacement(id) { var placementCodes = $$PREBID_GLOBAL$$._bidsRequested.map(bidSet => bidSet.bids.map(bid => bid.placementCode)) .reduce(flatten) @@ -777,6 +729,56 @@ $$PREBID_GLOBAL$$.setS2SConfig = function(options) { adaptermanager.setS2SConfig(config); }; -$$PREBID_GLOBAL$$.cmd.push(() => listenMessagesFromCreative()); -processQueue($$PREBID_GLOBAL$$.cmd); -processQueue($$PREBID_GLOBAL$$.que); +$$PREBID_GLOBAL$$.que.push(() => listenMessagesFromCreative()); + +/** + * This queue lets users load Prebid asynchronously, but run functions the same way regardless of whether it gets loaded + * before or after their script executes. For example, given the code: + * + * + * + * + * If the page's script runs before prebid loads, then their function gets added to the queue, and executed + * by prebid once it's done loading. If it runs after prebid loads, then this monkey-patch causes their + * function to execute immediately. + * + * @param {function} cmd A function which takes no arguments. This is guaranteed to run exactly once, and only after + * the Prebid script has been fully loaded. + * @alias module:$$PREBID_GLOBAL$$.cmd.push + */ +$$PREBID_GLOBAL$$.cmd.push = function(cmd) { + if (typeof cmd === objectType_function) { + try { + cmd.call(); + } catch (e) { + utils.logError('Error processing command :' + e.message); + } + } else { + utils.logError('Commands written into $$PREBID_GLOBAL$$.cmd.push must be wrapped in a function'); + } +}; + +$$PREBID_GLOBAL$$.que.push = $$PREBID_GLOBAL$$.cmd.push; + +function processQueue(queue) { + queue.forEach(function(cmd) { + if (typeof cmd.called === objectType_undefined) { + try { + cmd.call(); + cmd.called = true; + } + catch (e) { + utils.logError('Error processing command :', 'prebid.js', e); + } + } + }); +} + +$$PREBID_GLOBAL$$.processQueue = function() { + processQueue($$PREBID_GLOBAL$$.que); + processQueue($$PREBID_GLOBAL$$.cmd); +}; diff --git a/test/helpers/prebidGlobal.js b/test/helpers/prebidGlobal.js new file mode 100644 index 00000000000..597076ab0db --- /dev/null +++ b/test/helpers/prebidGlobal.js @@ -0,0 +1,3 @@ +window.$$PREBID_GLOBAL$$ = (window.$$PREBID_GLOBAL$$ || {}); +window.$$PREBID_GLOBAL$$.cmd = window.$$PREBID_GLOBAL$$.cmd || []; +window.$$PREBID_GLOBAL$$.que = window.$$PREBID_GLOBAL$$.que || []; diff --git a/test/spec/unit/adapters/analytics/AnalyticsAdapter_spec.js b/test/spec/AnalyticsAdapter_spec.js similarity index 95% rename from test/spec/unit/adapters/analytics/AnalyticsAdapter_spec.js rename to test/spec/AnalyticsAdapter_spec.js index 2301ce177c2..822ce76b081 100644 --- a/test/spec/unit/adapters/analytics/AnalyticsAdapter_spec.js +++ b/test/spec/AnalyticsAdapter_spec.js @@ -1,13 +1,12 @@ import { assert } from 'chai'; -import adaptermanager from '../../../../../src/adaptermanager'; -import events from '../../../../../src/events'; -import CONSTANTS from '../../../../../src/constants.json'; +import events from 'src/events'; +import CONSTANTS from 'src/constants.json'; const BID_REQUESTED = CONSTANTS.EVENTS.BID_REQUESTED; const BID_RESPONSE = CONSTANTS.EVENTS.BID_RESPONSE; const BID_WON = CONSTANTS.EVENTS.BID_WON; const BID_TIMEOUT = CONSTANTS.EVENTS.BID_TIMEOUT; -const AnalyticsAdapter = require('../../../../../src/adapters/analytics/AnalyticsAdapter').default; +const AnalyticsAdapter = require('src/AnalyticsAdapter').default; const config = { url: 'http://localhost:9999/src/adapters/analytics/libraries/example.js', analyticsType: 'library', diff --git a/test/spec/loaders/adapterLoader_spec.js b/test/spec/loaders/adapterLoader_spec.js deleted file mode 100644 index f5687e6f3f2..00000000000 --- a/test/spec/loaders/adapterLoader_spec.js +++ /dev/null @@ -1,38 +0,0 @@ -'use strict'; - -const proxyquire = require('proxyquire'); -const allAdapters = require('../../fixtures/allAdapters'); -const expect = require('chai').expect; -require('../../../loaders/adapterLoader'); - -const defaultAdapters = ['aardvark', 'adblade', 'adbutler', 'adequant', 'adform', 'admedia', 'aol', 'appnexus', 'appnexusAst', 'getintent', 'hiromedia', 'indexExchange', 'kruxlink', 'komoona', 'openx', 'piximedia', 'pubmatic', 'pulsepoint', 'rubicon', 'sonobi', 'sovrn', 'springserve', 'thoughtleadr', 'triplelift', 'twenga', 'yieldbot', 'nginad', 'brightcom', 'wideorbit', 'jcm', 'underdogmedia', 'memeglobal', 'centro', 'roxot', {'appnexus': {'alias': 'brealtime'}}, {'appnexus': {'alias': 'pagescience'}}, {'appnexus': {'alias': 'defymedia'}}, {'appnexusAst': {'supportedMediaTypes': ['video']}}]; - -const input = `/** INSERT ADAPTERS - DO NOT EDIT OR REMOVE */ - /** END INSERT ADAPTERS */`; - -describe('adapterLoader.js', () => { - it('should replace with the default set of adapters', () => { - const getAdapterStub = () => defaultAdapters; - const loader = proxyquire('../../../loaders/adapterLoader', {'./getAdapters': getAdapterStub}); - let output = loader(input); - expect(output).to.equal(allAdapters.getAllAdaptersString()); - }); - - it('should return custom adapter list if file exists', () => { - const customAdapter = [{customAdapterName: {srcPath: '/somepath/customAdapterName.js'}}]; - const getAdapterStub = () => customAdapter; - const loader = proxyquire('../../../loaders/adapterLoader', {'fs': {existsSync: () => true }, './getAdapters': getAdapterStub}); - let output = loader(input); - const expected = 'let customAdapterName = require(\'/somepath/customAdapterName.js\');\n exports.registerBidAdapter(new customAdapterName, \'customAdapterName\');\nexports.videoAdapters = [];'; - expect(output).to.equal(expected); - }); - - it('should ignore custom adapters that that do not exist', () => { - const customAdapter = ['appnexus', {customAdapterName: {srcPath: '/somepath/customAdapterName.js'}}]; - const getAdapterStub = () => customAdapter; - const loader = proxyquire('../../../loaders/adapterLoader', {'fs': {existsSync: () => false }, './getAdapters': getAdapterStub}); - let output = loader(input); - const expected = 'var AppnexusAdapter = require(\'./adapters/appnexus.js\');\n exports.registerBidAdapter(new AppnexusAdapter(), \'appnexus\');\nexports.videoAdapters = [];'; - expect(output).to.equal(expected); - }); -}); diff --git a/test/spec/loaders/getAdapters_spec.js b/test/spec/loaders/getAdapters_spec.js deleted file mode 100644 index cd544b1acb3..00000000000 --- a/test/spec/loaders/getAdapters_spec.js +++ /dev/null @@ -1,81 +0,0 @@ -'use strict'; - -const mockfs = require('mock-fs'); -const proxyquire = require('proxyquire'); -const expect = require('chai').expect; - -require('../../../loaders/getAdapters'); - -describe('loaders/getAdapters', () => { - let defaultAdapters; - let customAdapters; - const defaultAdaptersFile = 'adapters.json'; - const adaptersArg = 'adapters'; - - beforeEach(() => { - defaultAdapters = [ 'adapter 1', 'adapter 2', 'adapter 3' ]; - customAdapters = [ 'adapter 1' ]; - }); - - afterEach(() => { - mockfs.restore(); - }); - - describe('when custom adapter list is defined', () => { - describe('and exists', () => { - it('should return custom adapter list', () => { - mockfs({ - 'adapters.json': JSON.stringify(defaultAdapters), - 'custom-adapters.json': JSON.stringify(customAdapters) - }); - const getAdapters = proxyquire('../../../loaders/getAdapters', { - yargs: { argv: { adapters: 'custom-adapters.json' } } - }); - expect(getAdapters(defaultAdaptersFile, adaptersArg)).to.deep.equal(customAdapters); - }); - }); - - describe('and does not exist', () => { - it('should return default adapter list and show warning', () => { - let log; - const consoleLog = console.log.bind(console); - console.log = (message) => { - log = message; - }; - mockfs({ - 'adapters.json': JSON.stringify(defaultAdapters) - }); - const getAdapters = proxyquire('../../../loaders/getAdapters', { - yargs: { argv: { adapters: 'non-existent-adapters.json' } } - }); - expect(getAdapters(defaultAdaptersFile, adaptersArg)).to.deep.equal(defaultAdapters); - expect(log).to.match(/non-existent-adapters.json/); - console.log = consoleLog; - }); - }); - }); - - describe('when custom adapter list is not defined', () => { - it('should return default adapter list', () => { - mockfs({ - 'adapters.json': JSON.stringify(defaultAdapters) - }); - const getAdapters = proxyquire('../../../loaders/getAdapters', { - yargs: { argv: {} } - }); - expect(getAdapters(defaultAdaptersFile, adaptersArg)).to.deep.equal(defaultAdapters); - }); - }); - - describe('when default adapter list cannot be found', () => { - it('should return empty array', () => { - mockfs({ - 'adapters.json': mockfs.file({ mode: 0x000 }) - }); - const getAdapters = proxyquire('../../../loaders/getAdapters', { - yargs: { argv: {} } - }); - expect(getAdapters(defaultAdaptersFile, adaptersArg)).to.deep.equal([]); - }); - }); -}); diff --git a/test/spec/adapters/aardvark_spec.js b/test/spec/modules/aardvarkBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/aardvark_spec.js rename to test/spec/modules/aardvarkBidAdapter_spec.js index 46a90378bcd..5edf7ce0b25 100644 --- a/test/spec/adapters/aardvark_spec.js +++ b/test/spec/modules/aardvarkBidAdapter_spec.js @@ -1,6 +1,6 @@ describe('aardvark adapter tests', function () { const expect = require('chai').expect; - const adapter = require('src/adapters/aardvark'); + const adapter = require('modules/aardvarkBidAdapter'); const bidmanager = require('src/bidmanager'); const adloader = require('src/adloader'); const constants = require('src/constants.json'); diff --git a/test/spec/adapters/adblade_spec.js b/test/spec/modules/adbladeBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/adblade_spec.js rename to test/spec/modules/adbladeBidAdapter_spec.js index db5155a7d79..c66bfe70d3f 100644 --- a/test/spec/adapters/adblade_spec.js +++ b/test/spec/modules/adbladeBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import Adapter from '../../../src/adapters/adblade'; +import Adapter from '../../../modules/adbladeBidAdapter'; import bidManager from '../../../src/bidmanager'; import adLoader from '../../../src/adloader'; diff --git a/test/spec/adapters/adbund_spec.js b/test/spec/modules/adbundBidAdapter_spec.js similarity index 97% rename from test/spec/adapters/adbund_spec.js rename to test/spec/modules/adbundBidAdapter_spec.js index 868b9a9258d..9ee9e9ccfe7 100644 --- a/test/spec/adapters/adbund_spec.js +++ b/test/spec/modules/adbundBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import Adapter from '../../../src/adapters/adbund'; +import Adapter from '../../../modules/adbundBidAdapter'; import bidManager from 'src/bidmanager'; import CONSTANTS from 'src/constants.json'; diff --git a/test/spec/adapters/adbutler_spec.js b/test/spec/modules/adbutlerBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/adbutler_spec.js rename to test/spec/modules/adbutlerBidAdapter_spec.js index ed08fb1888a..ec7073545b2 100644 --- a/test/spec/adapters/adbutler_spec.js +++ b/test/spec/modules/adbutlerBidAdapter_spec.js @@ -1,14 +1,9 @@ describe('adbutler adapter tests', function () { var expect = require('chai').expect; - var adapter = require('src/adapters/adbutler'); + var adapter = require('modules/adbutlerBidAdapter'); var adLoader = require('src/adloader'); var bidmanager = require('src/bidmanager'); - window.pbjs = window.pbjs || {}; - if (typeof (pbjs) === 'undefined') { - var pbjs = window.pbjs; - } - describe('creation of bid url', function () { var stubLoadScript; diff --git a/test/spec/adapters/adform_spec.js b/test/spec/modules/adformBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/adform_spec.js rename to test/spec/modules/adformBidAdapter_spec.js index df97cd7bc82..0d2d1e19b68 100644 --- a/test/spec/adapters/adform_spec.js +++ b/test/spec/modules/adformBidAdapter_spec.js @@ -2,7 +2,7 @@ import { assert } from 'chai'; import * as utils from '../../../src/utils'; import adLoader from '../../../src/adloader'; import bidManager from '../../../src/bidmanager'; -import adapter from '../../../src/adapters/adform'; +import adapter from '../../../modules/adformBidAdapter'; describe('Adform adapter', () => { let _adapter, sandbox; diff --git a/test/spec/adapters/adkernel_spec.js b/test/spec/modules/adkernelBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/adkernel_spec.js rename to test/spec/modules/adkernelBidAdapter_spec.js index dd7eb82060a..031caa6996a 100644 --- a/test/spec/adapters/adkernel_spec.js +++ b/test/spec/modules/adkernelBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import Adapter from 'src/adapters/adkernel'; +import Adapter from 'modules/adkernelBidAdapter'; import * as ajax from 'src/ajax'; import * as utils from 'src/utils'; import bidmanager from 'src/bidmanager'; diff --git a/test/spec/adapters/admixer_spec.js b/test/spec/modules/admixerBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/admixer_spec.js rename to test/spec/modules/admixerBidAdapter_spec.js index 45f18ce7abc..0b66f8a9469 100644 --- a/test/spec/adapters/admixer_spec.js +++ b/test/spec/modules/admixerBidAdapter_spec.js @@ -1,6 +1,5 @@ -window.pbjs = window.pbjs || {}; var chai = require('chai'); -var Adapter = require('src/adapters/admixer')(); +var Adapter = require('modules/admixerBidAdapter')(); var Ajax = require('src/ajax'); var bidmanager = require('src/bidmanager.js'); var CONSTANTS = require('src/constants.json'); diff --git a/test/spec/adapters/adsupply_spec.js b/test/spec/modules/adsupplyBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/adsupply_spec.js rename to test/spec/modules/adsupplyBidAdapter_spec.js index 59f7dc42d41..040c08e0ac1 100644 --- a/test/spec/adapters/adsupply_spec.js +++ b/test/spec/modules/adsupplyBidAdapter_spec.js @@ -1,14 +1,15 @@ describe('adsupply adapter tests', function () { const expect = require('chai').expect; - const AdSupplyAdapter = require('../../../src/adapters/adsupply'); + const AdSupplyAdapter = require('../../../modules/adsupplyBidAdapter'); const adloader = require('../../../src/adloader'); const bidmanager = require('../../../src/bidmanager'); const CONSTANTS = require('../../../src/constants.json'); let adsupplyAdapter = new AdSupplyAdapter(); - // before(() => sinon.stub(document.body, 'appendChild')); - // after(() => document.body.appendChild.restore()); + beforeEach(() => { + pbjs._bidsRequested = []; + }); it('adsupply response handler should exist and be a function', function () { expect(pbjs.adSupplyResponseHandler).to.exist.and.to.be.a('function'); diff --git a/test/spec/adapters/adyoulike_spec.js b/test/spec/modules/adyoulikeBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/adyoulike_spec.js rename to test/spec/modules/adyoulikeBidAdapter_spec.js index d702b0ec283..539fd2da85c 100644 --- a/test/spec/adapters/adyoulike_spec.js +++ b/test/spec/modules/adyoulikeBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; import { parse } from '../../../src/url'; -import AdyoulikAdapter from '../../../src/adapters/adyoulike'; +import AdyoulikAdapter from '../../../modules/adyoulikeBidAdapter'; import bidmanager from 'src/bidmanager'; import { STATUS } from 'src/constants'; diff --git a/test/spec/adapters/aol_spec.js b/test/spec/modules/aolBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/aol_spec.js rename to test/spec/modules/aolBidAdapter_spec.js index aa41f92b75c..d48de9eb37b 100644 --- a/test/spec/adapters/aol_spec.js +++ b/test/spec/modules/aolBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; import * as utils from 'src/utils'; -import AolAdapter from 'src/adapters/aol'; +import AolAdapter from 'modules/aolBidAdapter'; import bidmanager from 'src/bidmanager'; let getDefaultBidResponse = () => { diff --git a/test/spec/unit/adapters/analytics/appnexus_spec.js b/test/spec/modules/appnexusAnalyticsAdapter_spec.js similarity index 93% rename from test/spec/unit/adapters/analytics/appnexus_spec.js rename to test/spec/modules/appnexusAnalyticsAdapter_spec.js index 4d241c2897c..7f68359de07 100644 --- a/test/spec/unit/adapters/analytics/appnexus_spec.js +++ b/test/spec/modules/appnexusAnalyticsAdapter_spec.js @@ -1,4 +1,4 @@ -import appnexusAnalytics from 'src/adapters/analytics/appnexus'; +import appnexusAnalytics from 'modules/appnexusAnalyticsAdapter'; import { assert } from 'chai'; import { getBidRequestedPayload } from 'test/fixtures/fixtures'; diff --git a/test/spec/adapters/appnexusAst_spec.js b/test/spec/modules/appnexusAstBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/appnexusAst_spec.js rename to test/spec/modules/appnexusAstBidAdapter_spec.js index db037f6d27b..0f125917614 100644 --- a/test/spec/adapters/appnexusAst_spec.js +++ b/test/spec/modules/appnexusAstBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import Adapter from 'src/adapters/appnexusAst'; +import Adapter from 'modules/appnexusAstBidAdapter'; import bidmanager from 'src/bidmanager'; const ENDPOINT = '//ib.adnxs.com/ut/v3/prebid'; diff --git a/test/spec/adapters/appnexus_spec.js b/test/spec/modules/appnexusBidAdapter_spec.js similarity index 94% rename from test/spec/adapters/appnexus_spec.js rename to test/spec/modules/appnexusBidAdapter_spec.js index 7479f7960ff..e7f5310d90c 100644 --- a/test/spec/adapters/appnexus_spec.js +++ b/test/spec/modules/appnexusBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import Adapter from '../../../src/adapters/appnexus'; +import Adapter from '../../../modules/appnexusBidAdapter'; import bidManager from '../../../src/bidmanager'; import adLoader from '../../../src/adloader'; diff --git a/test/spec/adapters/atomx_spec.js b/test/spec/modules/atomxBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/atomx_spec.js rename to test/spec/modules/atomxBidAdapter_spec.js index db865057d68..1a62bac28a1 100644 --- a/test/spec/adapters/atomx_spec.js +++ b/test/spec/modules/atomxBidAdapter_spec.js @@ -1,6 +1,5 @@ -window.pbjs = window.pbjs || {}; var chai = require('chai'); -var Adapter = require('src/adapters/atomx')(); +var Adapter = require('modules/atomxBidAdapter')(); var Ajax = require('src/ajax'); var adLoader = require('src/adloader'); var bidmanager = require('src/bidmanager.js'); diff --git a/test/spec/adapters/audienceNetwork_spec.js b/test/spec/modules/audienceNetworkBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/audienceNetwork_spec.js rename to test/spec/modules/audienceNetworkBidAdapter_spec.js index fa8d2b31fb2..0ed80086802 100644 --- a/test/spec/adapters/audienceNetwork_spec.js +++ b/test/spec/modules/audienceNetworkBidAdapter_spec.js @@ -7,7 +7,7 @@ import bidmanager from 'src/bidmanager'; import { STATUS } from 'src/constants.json'; import * as utils from 'src/utils'; -import AudienceNetwork from 'src/adapters/audienceNetwork'; +import AudienceNetwork from 'modules/audienceNetworkBidAdapter'; const bidderCode = 'audienceNetwork'; const placementId = 'test-placement-id'; diff --git a/test/spec/adapters/beachfront_spec.js b/test/spec/modules/beachfrontBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/beachfront_spec.js rename to test/spec/modules/beachfrontBidAdapter_spec.js index 3d5396b7b76..ad313acc84a 100644 --- a/test/spec/adapters/beachfront_spec.js +++ b/test/spec/modules/beachfrontBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import BeachfrontAdapter from 'src/adapters/beachfront'; +import BeachfrontAdapter from 'modules/beachfrontBidAdapter'; import bidmanager from 'src/bidmanager'; const ENDPOINT = '//reachms.bfmio.com/bid.json?exchange_id=11bc5dd5-7421-4dd8-c926-40fa653bec76'; diff --git a/test/spec/adapters/bidfluence_spec.js b/test/spec/modules/bidfluenceBidAdapter_spec.js similarity index 91% rename from test/spec/adapters/bidfluence_spec.js rename to test/spec/modules/bidfluenceBidAdapter_spec.js index 1e5510c4532..f623954fa9f 100644 --- a/test/spec/adapters/bidfluence_spec.js +++ b/test/spec/modules/bidfluenceBidAdapter_spec.js @@ -1,6 +1,6 @@ describe('Bidfluence Adapter', () => { const expect = require('chai').expect; - const adapter = require('src/adapters/bidfluence'); + const adapter = require('modules/bidfluenceBidAdapter'); const bidmanager = require('src/bidmanager'); var REQUEST = { @@ -38,7 +38,7 @@ describe('Bidfluence Adapter', () => { it('Shoud push a valid bid', () => { var stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); - pbjs._bidsRequested.push(REQUEST); + $$PREBID_GLOBAL$$._bidsRequested.push(REQUEST); adapter(); $$PREBID_GLOBAL$$.bfPbjsCB(RESPONSE); @@ -54,7 +54,7 @@ describe('Bidfluence Adapter', () => { it('Shoud push an empty bid', () => { var stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); - pbjs._bidsRequested.push(REQUEST); + $$PREBID_GLOBAL$$._bidsRequested.push(REQUEST); adapter(); $$PREBID_GLOBAL$$.bfPbjsCB(NO_RESPONSE); diff --git a/test/spec/adapters/carambola_spec.js b/test/spec/modules/carambolaBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/carambola_spec.js rename to test/spec/modules/carambolaBidAdapter_spec.js index fe856f66c21..660944b4f28 100644 --- a/test/spec/adapters/carambola_spec.js +++ b/test/spec/modules/carambolaBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; import * as utils from 'src/utils'; -import CarambolaAdapter from 'src/adapters/carambola'; +import CarambolaAdapter from 'modules/carambolaBidAdapter'; import bidmanager from 'src/bidmanager'; const DEFAULT_BIDDER_REQUEST = { diff --git a/test/spec/adapters/centro_spec.js b/test/spec/modules/centroBidAdapter_spec.js similarity index 91% rename from test/spec/adapters/centro_spec.js rename to test/spec/modules/centroBidAdapter_spec.js index 73dcf287ff0..53283a92afe 100644 --- a/test/spec/adapters/centro_spec.js +++ b/test/spec/modules/centroBidAdapter_spec.js @@ -4,16 +4,11 @@ describe('centro adapter tests', function () { var urlParse = require('url-parse'); var querystringify = require('querystringify'); - var adapter = require('src/adapters/centro'); + var adapter = require('modules/centroBidAdapter'); var bidmanager = require('src/bidmanager'); var adLoader = require('src/adloader'); var utils = require('src/utils'); - window.pbjs = window.pbjs || {}; - if (typeof (pbjs) === 'undefined') { - var pbjs = window.pbjs; - } - let stubLoadScript; beforeEach(function () { stubLoadScript = sinon.stub(adLoader, 'loadScript'); @@ -33,8 +28,8 @@ describe('centro adapter tests', function () { }); describe('creation of bid url', function () { - if (typeof (pbjs._bidsRequested) === 'undefined') { - pbjs._bidsRequested = []; + if (typeof ($$PREBID_GLOBAL$$._bidsRequested) === 'undefined') { + $$PREBID_GLOBAL$$._bidsRequested = []; } it('should fix parameter name', function () { @@ -103,14 +98,14 @@ describe('centro adapter tests', function () { }); describe('handling of the callback response', function () { - if (typeof (pbjs._bidsReceived) === 'undefined') { - pbjs._bidsReceived = []; + if (typeof ($$PREBID_GLOBAL$$._bidsReceived) === 'undefined') { + $$PREBID_GLOBAL$$._bidsReceived = []; } - if (typeof (pbjs._bidsRequested) === 'undefined') { - pbjs._bidsRequested = []; + if (typeof ($$PREBID_GLOBAL$$._bidsRequested) === 'undefined') { + $$PREBID_GLOBAL$$._bidsRequested = []; } - if (typeof (pbjs._adsReceived) === 'undefined') { - pbjs._adsReceived = []; + if (typeof ($$PREBID_GLOBAL$$._adsReceived) === 'undefined') { + $$PREBID_GLOBAL$$._adsReceived = []; } var params = { @@ -172,13 +167,13 @@ describe('centro adapter tests', function () { unit.sizes = [[300, 250], [728, 90]]; adUnits.push(unit); - if (typeof (pbjs._bidsRequested) === 'undefined') { - pbjs._bidsRequested = [params]; + if (typeof ($$PREBID_GLOBAL$$._bidsRequested) === 'undefined') { + $$PREBID_GLOBAL$$._bidsRequested = [params]; } else { - pbjs._bidsRequested.push(params); + $$PREBID_GLOBAL$$._bidsRequested.push(params); } - pbjs.adUnits = adUnits; + $$PREBID_GLOBAL$$.adUnits = adUnits; var response = {'adTag': '
test content
', 'statusMessage': 'Bid available', 'height': 250, '_comment': '', 'value': 0.2, 'width': 300, 'sectionID': 28136}; var response2 = {'adTag': '', 'statusMessage': 'No bid.', 'height': 0, 'value': 0, 'width': 0, 'sectionID': 111111}; diff --git a/test/spec/adapters/conversant_spec.js b/test/spec/modules/conversantBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/conversant_spec.js rename to test/spec/modules/conversantBidAdapter_spec.js index 09d5132683f..57cd9411e66 100644 --- a/test/spec/adapters/conversant_spec.js +++ b/test/spec/modules/conversantBidAdapter_spec.js @@ -1,5 +1,5 @@ var expect = require('chai').expect; -var Adapter = require('src/adapters/conversant'); +var Adapter = require('modules/conversantBidAdapter'); var bidManager = require('src/bidmanager'); describe('Conversant adapter tests', function () { diff --git a/test/spec/adapters/cox_spec.js b/test/spec/modules/coxBidAdapter_spec.js similarity index 95% rename from test/spec/adapters/cox_spec.js rename to test/spec/modules/coxBidAdapter_spec.js index 3f1342230db..ee1eb991f23 100644 --- a/test/spec/adapters/cox_spec.js +++ b/test/spec/modules/coxBidAdapter_spec.js @@ -1,121 +1,120 @@ -import Adapter from 'src/adapters/cox'; -import bidManager from 'src/bidmanager'; -import adLoader from 'src/adloader'; -import utils from 'src/utils'; -import {expect} from 'chai'; - -describe('CoxAdapter', () => { - let adapter; - let loadScriptStub; - let addBidResponseSpy; - - let emitScript = (script) => { - let node = document.createElement('script'); - node.type = 'text/javascript'; - node.appendChild(document.createTextNode(script)); - document.getElementsByTagName('head')[0].appendChild(node); - }; - - beforeEach(() => { - adapter = new Adapter(); - addBidResponseSpy = sinon.spy(bidManager, 'addBidResponse'); - }); - - afterEach(() => { - loadScriptStub.restore(); - addBidResponseSpy.restore(); - }); - - describe('response handling', () => { - const normalResponse = 'cdsTag.__callback__({"zones":{"as2000005991707":{"ad" : "

FOO<\/h1>","uid" : "","price" : 1.51,"floor" : 0,}},"tpCookieSync":"

FOOKIE<\/h1>"})'; - const zeroPriceResponse = 'cdsTag.__callback__({"zones":{"as2000005991707":{"ad" : "

DEFAULT FOO<\/h1>","uid" : "","price" : 0,"floor" : 0,}},"tpCookieSync":"

FOOKIE<\/h1>"})'; - const incompleteResponse = 'cdsTag.__callback__({"zones":{},"tpCookieSync":"

FOOKIE<\/h1>"})'; - - const oneBidConfig = { - bidderCode: 'cox', - bids: [{ - bidder: 'cox', - placementCode: 'FOO456789', - sizes: [300, 250], - params: { size: '300x250', id: 2000005991707, siteId: 2000100948180, env: 'PROD' }, - }] - }; - - // ===== 1 - it('should provide a correctly populated Bid given a valid response', () => { - loadScriptStub = sinon.stub(adLoader, 'loadScript', () => { emitScript(normalResponse); }) - - adapter.callBids(oneBidConfig); - - let bid = addBidResponseSpy.args[0][1]; - expect(bid.cpm).to.equal(1.51); - expect(bid.ad).to.be.a('string'); - expect(bid.bidderCode).to.equal('cox'); - }); - - // ===== 2 - it('should provide an empty Bid given a zero-price response', () => { - loadScriptStub = sinon.stub(adLoader, 'loadScript', () => { emitScript(zeroPriceResponse); }) - - adapter.callBids(oneBidConfig); - - let bid = addBidResponseSpy.args[0][1]; - expect(bid.cpm).to.not.be.ok - expect(bid.ad).to.not.be.ok; - }); - - // ===== 3 - it('should provide an empty Bid given an incomplete response', () => { - loadScriptStub = sinon.stub(adLoader, 'loadScript', () => { emitScript(incompleteResponse); }) - - adapter.callBids(oneBidConfig); - - let bid = addBidResponseSpy.args[0][1]; - expect(bid.cpm).to.not.be.ok - expect(bid.ad).to.not.be.ok; - }); - - // ===== 4 - it('should not provide a Bid given no response', () => { - loadScriptStub = sinon.stub(adLoader, 'loadScript', () => { emitScript(''); }); - - adapter.callBids(oneBidConfig); - - expect(addBidResponseSpy.callCount).to.equal(0); - }); - }); - - describe('request generation', () => { - const missingBidsConfig = { - bidderCode: 'cox', - bids: null, - }; - const missingParamsConfig = { - bidderCode: 'cox', - bids: [{ - bidder: 'cox', - placementCode: 'FOO456789', - sizes: [300, 250], - params: null, - }] - }; - - // ===== 5 - it('should not make an ad call given missing bids in config', () => { - loadScriptStub = sinon.stub(adLoader, 'loadScript'); - - adapter.callBids(missingBidsConfig); - - expect(loadScriptStub.callCount).to.equal(0); - }); - - // ===== 6 - it('should not make an ad call given missing params in config', () => { - loadScriptStub = sinon.stub(adLoader, 'loadScript'); - - adapter.callBids(missingParamsConfig); - - expect(loadScriptStub.callCount).to.equal(0); - }); - }); -}); +import Adapter from 'modules/coxBidAdapter'; +import bidManager from 'src/bidmanager'; +import adLoader from 'src/adloader'; +import {expect} from 'chai'; + +describe('CoxAdapter', () => { + let adapter; + let loadScriptStub; + let addBidResponseSpy; + + let emitScript = (script) => { + let node = document.createElement('script'); + node.type = 'text/javascript'; + node.appendChild(document.createTextNode(script)); + document.getElementsByTagName('head')[0].appendChild(node); + }; + + beforeEach(() => { + adapter = new Adapter(); + addBidResponseSpy = sinon.spy(bidManager, 'addBidResponse'); + }); + + afterEach(() => { + loadScriptStub.restore(); + addBidResponseSpy.restore(); + }); + + describe('response handling', () => { + const normalResponse = 'cdsTag.__callback__({"zones":{"as2000005991707":{"ad" : "

FOO<\/h1>","uid" : "","price" : 1.51,"floor" : 0,}},"tpCookieSync":"

FOOKIE<\/h1>"})'; + const zeroPriceResponse = 'cdsTag.__callback__({"zones":{"as2000005991707":{"ad" : "

DEFAULT FOO<\/h1>","uid" : "","price" : 0,"floor" : 0,}},"tpCookieSync":"

FOOKIE<\/h1>"})'; + const incompleteResponse = 'cdsTag.__callback__({"zones":{},"tpCookieSync":"

FOOKIE<\/h1>"})'; + + const oneBidConfig = { + bidderCode: 'cox', + bids: [{ + bidder: 'cox', + placementCode: 'FOO456789', + sizes: [300, 250], + params: { size: '300x250', id: 2000005991707, siteId: 2000100948180, env: 'PROD' }, + }] + }; + + // ===== 1 + it('should provide a correctly populated Bid given a valid response', () => { + loadScriptStub = sinon.stub(adLoader, 'loadScript', () => { emitScript(normalResponse); }) + + adapter.callBids(oneBidConfig); + + let bid = addBidResponseSpy.args[0][1]; + expect(bid.cpm).to.equal(1.51); + expect(bid.ad).to.be.a('string'); + expect(bid.bidderCode).to.equal('cox'); + }); + + // ===== 2 + it('should provide an empty Bid given a zero-price response', () => { + loadScriptStub = sinon.stub(adLoader, 'loadScript', () => { emitScript(zeroPriceResponse); }) + + adapter.callBids(oneBidConfig); + + let bid = addBidResponseSpy.args[0][1]; + expect(bid.cpm).to.not.be.ok + expect(bid.ad).to.not.be.ok; + }); + + // ===== 3 + it('should provide an empty Bid given an incomplete response', () => { + loadScriptStub = sinon.stub(adLoader, 'loadScript', () => { emitScript(incompleteResponse); }) + + adapter.callBids(oneBidConfig); + + let bid = addBidResponseSpy.args[0][1]; + expect(bid.cpm).to.not.be.ok + expect(bid.ad).to.not.be.ok; + }); + + // ===== 4 + it('should not provide a Bid given no response', () => { + loadScriptStub = sinon.stub(adLoader, 'loadScript', () => { emitScript(''); }); + + adapter.callBids(oneBidConfig); + + expect(addBidResponseSpy.callCount).to.equal(0); + }); + }); + + describe('request generation', () => { + const missingBidsConfig = { + bidderCode: 'cox', + bids: null, + }; + const missingParamsConfig = { + bidderCode: 'cox', + bids: [{ + bidder: 'cox', + placementCode: 'FOO456789', + sizes: [300, 250], + params: null, + }] + }; + + // ===== 5 + it('should not make an ad call given missing bids in config', () => { + loadScriptStub = sinon.stub(adLoader, 'loadScript'); + + adapter.callBids(missingBidsConfig); + + expect(loadScriptStub.callCount).to.equal(0); + }); + + // ===== 6 + it('should not make an ad call given missing params in config', () => { + loadScriptStub = sinon.stub(adLoader, 'loadScript'); + + adapter.callBids(missingParamsConfig); + + expect(loadScriptStub.callCount).to.equal(0); + }); + }); +}); diff --git a/test/spec/adapters/criteo_spec.js b/test/spec/modules/criteoBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/criteo_spec.js rename to test/spec/modules/criteoBidAdapter_spec.js index 5cf1549eef6..c686f284134 100644 --- a/test/spec/adapters/criteo_spec.js +++ b/test/spec/modules/criteoBidAdapter_spec.js @@ -1,4 +1,4 @@ -import Adapter from '../../../src/adapters/criteo'; +import Adapter from '../../../modules/criteoBidAdapter'; import bidManager from '../../../src/bidmanager'; import {ajax} from '../../../src/ajax' import {expect} from 'chai'; diff --git a/test/spec/adapters/districtm_spec.js b/test/spec/modules/districtmDMXBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/districtm_spec.js rename to test/spec/modules/districtmDMXBidAdapter_spec.js index 6c703bff191..6fc83d88e6d 100644 --- a/test/spec/adapters/districtm_spec.js +++ b/test/spec/modules/districtmDMXBidAdapter_spec.js @@ -4,7 +4,7 @@ import {expect} from 'chai'; import {should} from 'chai'; -import Adaptor from '../../../src/adapters/districtmDMX'; +import Adaptor from '../../../modules/districtmDMXBidAdapter'; import adLoader from '../../../src/adloader'; diff --git a/test/spec/adapters/eplanning_spec.js b/test/spec/modules/eplanningBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/eplanning_spec.js rename to test/spec/modules/eplanningBidAdapter_spec.js index 668392c169b..ca7c498c610 100644 --- a/test/spec/adapters/eplanning_spec.js +++ b/test/spec/modules/eplanningBidAdapter_spec.js @@ -1,7 +1,7 @@ describe('eplanning adapter tests', function () { var urlParse = require('url-parse'); var querystringify = require('querystringify'); - var adapter = require('src/adapters/eplanning'); + var adapter = require('modules/eplanningBidAdapter'); var adLoader = require('src/adloader'); var expect = require('chai').expect; var bidmanager = require('src/bidmanager'); diff --git a/test/spec/adapters/fidelity_spec.js b/test/spec/modules/fidelityBidAdapter_spec.js similarity index 93% rename from test/spec/adapters/fidelity_spec.js rename to test/spec/modules/fidelityBidAdapter_spec.js index 3b852713bff..5777c6af8cd 100644 --- a/test/spec/adapters/fidelity_spec.js +++ b/test/spec/modules/fidelityBidAdapter_spec.js @@ -1,6 +1,6 @@ describe('fidelity adapter tests', function() { const expect = require('chai').expect; - const adapter = require('src/adapters/fidelity'); + const adapter = require('modules/fidelityBidAdapter'); const adLoader = require('src/adloader'); const bidmanager = require('src/bidmanager'); const STATUS = require('src/constants').STATUS; @@ -98,7 +98,7 @@ describe('fidelity adapter tests', function() { describe('fidelityResponse', function () { it('should exist and be a function', function () { - expect(pbjs.fidelityResponse).to.exist.and.to.be.a('function'); + expect($$PREBID_GLOBAL$$.fidelityResponse).to.exist.and.to.be.a('function'); }); it('should add empty bid response if no bids returned', function () { @@ -124,11 +124,11 @@ describe('fidelity adapter tests', function() { 'seatbid': [] }; - pbjs._bidsRequested.push(bidderRequest); + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); // adapter needs to be called, in order for the stub to register. adapter() - pbjs.fidelityResponse(response); + $$PREBID_GLOBAL$$.fidelityResponse(response); var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; var bidObject1 = stubAddBidResponse.getCall(0).args[1]; @@ -172,11 +172,11 @@ describe('fidelity adapter tests', function() { } ] }; - pbjs._bidsRequested.push(bidderRequest); + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); // adapter needs to be called, in order for the stub to register. adapter() - pbjs.fidelityResponse(response); + $$PREBID_GLOBAL$$.fidelityResponse(response); var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; var bidObject1 = stubAddBidResponse.getCall(0).args[1]; diff --git a/test/spec/adapters/getintent_spec.js b/test/spec/modules/getintentBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/getintent_spec.js rename to test/spec/modules/getintentBidAdapter_spec.js index 3537564f029..e66d2138eaf 100644 --- a/test/spec/adapters/getintent_spec.js +++ b/test/spec/modules/getintentBidAdapter_spec.js @@ -1,4 +1,4 @@ -import Adapter from '../../../src/adapters/getintent'; +import Adapter from '../../../modules/getintentBidAdapter'; import bidManager from '../../../src/bidmanager'; import {expect} from 'chai'; diff --git a/test/spec/ga_spec.js b/test/spec/modules/googleAnalyticsAdapter_spec.js similarity index 87% rename from test/spec/ga_spec.js rename to test/spec/modules/googleAnalyticsAdapter_spec.js index ffbaf3a94a1..4260a831cad 100644 --- a/test/spec/ga_spec.js +++ b/test/spec/modules/googleAnalyticsAdapter_spec.js @@ -1,5 +1,5 @@ var assert = require('assert'); -var ga = require('../../src/adapters/analytics/ga'); +var ga = require('modules/googleAnalyticsAdapter'); describe('Ga', function () { describe('enableAnalytics', function () { diff --git a/test/spec/adapters/gumgum_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js similarity index 97% rename from test/spec/adapters/gumgum_spec.js rename to test/spec/modules/gumgumBidAdapter_spec.js index a6d33dc5bd0..b90a1a48b15 100644 --- a/test/spec/adapters/gumgum_spec.js +++ b/test/spec/modules/gumgumBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import Adapter from '../../../src/adapters/gumgum'; +import Adapter from '../../../modules/gumgumBidAdapter'; import bidManager from '../../../src/bidmanager'; import adLoader from '../../../src/adloader'; import * as utils from '../../../src/utils'; @@ -79,7 +79,7 @@ describe('gumgum adapter', () => { sandbox.stub(bidManager, 'addBidResponse'); sandbox.stub(adLoader, 'loadScript'); adapter.callBids(bidderRequest); - pbjs.handleGumGumCB['InScreenBidId'](response); + $$PREBID_GLOBAL$$.handleGumGumCB['InScreenBidId'](response); return bidManager.addBidResponse.firstCall.args[1]; } @@ -207,7 +207,7 @@ describe('gumgum adapter', () => { describe('handleGumGumCB[...]', () => { it('exists and is function', () => { - expect(pbjs.handleGumGumCB['InScreenBidId']).to.exist.and.to.be.a('function'); + expect($$PREBID_GLOBAL$$.handleGumGumCB['InScreenBidId']).to.exist.and.to.be.a('function'); }); }); diff --git a/test/spec/adapters/hiromedia_spec.js b/test/spec/modules/hiromediaBidAdapter_spec.js similarity index 96% rename from test/spec/adapters/hiromedia_spec.js rename to test/spec/modules/hiromediaBidAdapter_spec.js index 643379b4ff2..c1ed4ee6e11 100644 --- a/test/spec/adapters/hiromedia_spec.js +++ b/test/spec/modules/hiromediaBidAdapter_spec.js @@ -1,331 +1,331 @@ import { expect } from 'chai'; -import urlParse from 'url-parse'; - -import Adapter from 'src/adapters/hiromedia'; -import bidmanager from 'src/bidmanager'; -import { STATUS } from 'src/constants'; -import * as utils from 'src/utils'; - -describe('hiromedia adapter', function () { - const BIDDER_CODE = 'hiromedia'; - const DEFAULT_ENDPOINT = 'https://hb-rtb.ktdpublishers.com/bid/get'; - - let adapter; - let sandbox; - let xhr; - let addBidResponseStub; - let hasValidBidRequestSpy; - let placementId = 0; - - window.$$PREBID_GLOBAL$$ = window.$$PREBID_GLOBAL$$ || {}; - - beforeEach(() => { - adapter = new Adapter(); - sandbox = sinon.sandbox.create(); - - // Used to spy on bid requests - xhr = sandbox.useFakeXMLHttpRequest(); - - // Used to spy on bid responses - addBidResponseStub = sandbox.stub(bidmanager, 'addBidResponse'); - - // Used to spy on bid validation - hasValidBidRequestSpy = sandbox.spy(utils, 'hasValidBidRequest'); - - placementId = 0; - }); - - afterEach(() => { - sandbox.restore(); - }); - - // Helper function that asserts that no bidding activity (requests nor responses) - // was made during a test. - const assertNoBids = () => { - expect(xhr.requests.length).to.be.equal(0); - sinon.assert.notCalled(addBidResponseStub); - }; - - // Helper function to generate a 'mock' bid object - const makePlacement = (size) => { - placementId += 1; - - return { - bidder: BIDDER_CODE, - sizes: [size], - params: { - accountId: '1337' - }, - placementCode: 'div-gpt-ad-12345-' + placementId - }; - }; - - // 300x250 are in the allowed size by default - const tilePlacement = () => makePlacement([300, 250]); - - // anything else should have no bid by default - const leaderPlacement = () => makePlacement([728, 90]); - - describe('callbids', () => { - it('exists and is a function', () => { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - - it('tolerates empty arguments', () => { - expect(adapter.callBids).to.not.throw(Error); - assertNoBids(); - }); - - it('tolerates empty params', () => { - expect(adapter.callBids.bind(adapter, {})).to.not.throw(Error); - assertNoBids(); - }); - - it('tolerates empty bids', () => { - expect(adapter.callBids.bind(adapter, {bids: []})).to.not.throw(Error); - assertNoBids(); - }); - - it('invokes a bid request per placement', () => { - const expectedRequests = [{ - placementCode: 'div-gpt-ad-12345-1', - selectedSize: '300x250' - }, { - placementCode: 'div-gpt-ad-12345-2', - selectedSize: '728x90' - }, { - placementCode: 'div-gpt-ad-12345-3', - selectedSize: '300x250' - }]; - - const params = { - bids: [tilePlacement(), leaderPlacement(), tilePlacement()] - }; - - adapter.callBids(params); - expect(xhr.requests.length).to.equal(3); - sinon.assert.notCalled(addBidResponseStub); - sinon.assert.calledThrice(hasValidBidRequestSpy); - - expectedRequests.forEach(function(request, index) { - expect(hasValidBidRequestSpy.returnValues[index]).to.be.equal(true); - - // validate request - const bidRequest = xhr.requests[index].url; - const defaultBidUrl = urlParse(DEFAULT_ENDPOINT); - const bidUrl = urlParse(bidRequest, true); - const query = bidUrl.query; - - expect(bidUrl.hostname).to.equal(defaultBidUrl.hostname); - expect(bidUrl.pathname).to.equal(defaultBidUrl.pathname); - - expect(query).to.have.property('adapterVersion').and.to.equal('3'); - expect(query).to.have.property('placementCode').and.to.equal(request.placementCode); - expect(query).to.have.property('accountId').and.to.equal('1337'); - expect(query).to.have.property('selectedSize').and.to.equal(request.selectedSize); - expect(query).to.not.have.property('additionalSizes'); - expect(query).to.have.property('domain').and.to.equal(window.top.location.hostname); - }); - }); - - // Test additionalSizes parameter - it('attaches multiple sizes to additionalSizes', () => { - const placement = tilePlacement(); - - // Append additional - placement.sizes.push([300, 600]); - placement.sizes.push([300, 900]); - - const params = { - bids: [placement] - }; - - adapter.callBids(params); - expect(xhr.requests.length).to.be.equal(1); - - const bidRequest = xhr.requests[0].url; - const bidUrl = urlParse(bidRequest, true); - const query = bidUrl.query; - - expect(query).to.have.property('selectedSize').and.to.equal('300x250'); - expect(query).to.have.property('additionalSizes').and.to.equal('300x600,300x900'); - }); - - // Test `params.accountId` validation - it('invalidates bids with no id', () => { - const placement = tilePlacement(); - delete placement.params; - - const params = { - bids: [placement] - }; - - adapter.callBids(params); - expect(xhr.requests.length).to.be.equal(0); - sinon.assert.calledOnce(hasValidBidRequestSpy); - sinon.assert.calledOnce(addBidResponseStub); - - expect(hasValidBidRequestSpy.returnValues[0]).to.be.equal(false); - const placementCode = addBidResponseStub.getCall(0).args[0]; - const bidObject = addBidResponseStub.getCall(0).args[1]; - - expect(placementCode).to.be.equal('div-gpt-ad-12345-1'); - expect(bidObject.getStatusCode()).to.be.equal(STATUS.NO_BID); - }); - - // Test `params.bidUrl` - it('accepts a custom bid endpoint url', () => { - const placement = tilePlacement(); - placement.params.bidUrl = DEFAULT_ENDPOINT + '?someparam=value'; - - const params = { - bids: [placement] - }; - - adapter.callBids(params); - expect(xhr.requests.length).to.be.equal(1); - - const bidRequest = xhr.requests[0].url; - const defaultBidUrl = urlParse(DEFAULT_ENDPOINT); - const bidUrl = urlParse(bidRequest, true); - const query = bidUrl.query; - - expect(bidUrl.hostname).to.equal(defaultBidUrl.hostname); - expect(bidUrl.pathname).to.equal(defaultBidUrl.pathname); - - expect(query).to.have.property('someparam').and.to.equal('value'); +import urlParse from 'url-parse'; + +import Adapter from 'modules/hiromediaBidAdapter'; +import bidmanager from 'src/bidmanager'; +import { STATUS } from 'src/constants'; +import * as utils from 'src/utils'; + +describe('hiromedia adapter', function () { + const BIDDER_CODE = 'hiromedia'; + const DEFAULT_ENDPOINT = 'https://hb-rtb.ktdpublishers.com/bid/get'; + + let adapter; + let sandbox; + let xhr; + let addBidResponseStub; + let hasValidBidRequestSpy; + let placementId = 0; + + window.$$PREBID_GLOBAL$$ = window.$$PREBID_GLOBAL$$ || {}; + + beforeEach(() => { + adapter = new Adapter(); + sandbox = sinon.sandbox.create(); + + // Used to spy on bid requests + xhr = sandbox.useFakeXMLHttpRequest(); + + // Used to spy on bid responses + addBidResponseStub = sandbox.stub(bidmanager, 'addBidResponse'); + + // Used to spy on bid validation + hasValidBidRequestSpy = sandbox.spy(utils, 'hasValidBidRequest'); + + placementId = 0; + }); + + afterEach(() => { + sandbox.restore(); + }); + + // Helper function that asserts that no bidding activity (requests nor responses) + // was made during a test. + const assertNoBids = () => { + expect(xhr.requests.length).to.be.equal(0); + sinon.assert.notCalled(addBidResponseStub); + }; + + // Helper function to generate a 'mock' bid object + const makePlacement = (size) => { + placementId += 1; + + return { + bidder: BIDDER_CODE, + sizes: [size], + params: { + accountId: '1337' + }, + placementCode: 'div-gpt-ad-12345-' + placementId + }; + }; + + // 300x250 are in the allowed size by default + const tilePlacement = () => makePlacement([300, 250]); + + // anything else should have no bid by default + const leaderPlacement = () => makePlacement([728, 90]); + + describe('callbids', () => { + it('exists and is a function', () => { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + + it('tolerates empty arguments', () => { + expect(adapter.callBids).to.not.throw(Error); + assertNoBids(); + }); + + it('tolerates empty params', () => { + expect(adapter.callBids.bind(adapter, {})).to.not.throw(Error); + assertNoBids(); + }); + + it('tolerates empty bids', () => { + expect(adapter.callBids.bind(adapter, {bids: []})).to.not.throw(Error); + assertNoBids(); + }); + + it('invokes a bid request per placement', () => { + const expectedRequests = [{ + placementCode: 'div-gpt-ad-12345-1', + selectedSize: '300x250' + }, { + placementCode: 'div-gpt-ad-12345-2', + selectedSize: '728x90' + }, { + placementCode: 'div-gpt-ad-12345-3', + selectedSize: '300x250' + }]; + + const params = { + bids: [tilePlacement(), leaderPlacement(), tilePlacement()] + }; + + adapter.callBids(params); + expect(xhr.requests.length).to.equal(3); + sinon.assert.notCalled(addBidResponseStub); + sinon.assert.calledThrice(hasValidBidRequestSpy); + + expectedRequests.forEach(function(request, index) { + expect(hasValidBidRequestSpy.returnValues[index]).to.be.equal(true); + + // validate request + const bidRequest = xhr.requests[index].url; + const defaultBidUrl = urlParse(DEFAULT_ENDPOINT); + const bidUrl = urlParse(bidRequest, true); + const query = bidUrl.query; + + expect(bidUrl.hostname).to.equal(defaultBidUrl.hostname); + expect(bidUrl.pathname).to.equal(defaultBidUrl.pathname); + + expect(query).to.have.property('adapterVersion').and.to.equal('3'); + expect(query).to.have.property('placementCode').and.to.equal(request.placementCode); + expect(query).to.have.property('accountId').and.to.equal('1337'); + expect(query).to.have.property('selectedSize').and.to.equal(request.selectedSize); + expect(query).to.not.have.property('additionalSizes'); + expect(query).to.have.property('domain').and.to.equal(window.top.location.hostname); + }); + }); + + // Test additionalSizes parameter + it('attaches multiple sizes to additionalSizes', () => { + const placement = tilePlacement(); + + // Append additional + placement.sizes.push([300, 600]); + placement.sizes.push([300, 900]); + + const params = { + bids: [placement] + }; + + adapter.callBids(params); + expect(xhr.requests.length).to.be.equal(1); + + const bidRequest = xhr.requests[0].url; + const bidUrl = urlParse(bidRequest, true); + const query = bidUrl.query; + + expect(query).to.have.property('selectedSize').and.to.equal('300x250'); + expect(query).to.have.property('additionalSizes').and.to.equal('300x600,300x900'); + }); + + // Test `params.accountId` validation + it('invalidates bids with no id', () => { + const placement = tilePlacement(); + delete placement.params; + + const params = { + bids: [placement] + }; + + adapter.callBids(params); + expect(xhr.requests.length).to.be.equal(0); + sinon.assert.calledOnce(hasValidBidRequestSpy); + sinon.assert.calledOnce(addBidResponseStub); + + expect(hasValidBidRequestSpy.returnValues[0]).to.be.equal(false); + const placementCode = addBidResponseStub.getCall(0).args[0]; + const bidObject = addBidResponseStub.getCall(0).args[1]; + + expect(placementCode).to.be.equal('div-gpt-ad-12345-1'); + expect(bidObject.getStatusCode()).to.be.equal(STATUS.NO_BID); + }); + + // Test `params.bidUrl` + it('accepts a custom bid endpoint url', () => { + const placement = tilePlacement(); + placement.params.bidUrl = DEFAULT_ENDPOINT + '?someparam=value'; + + const params = { + bids: [placement] + }; + + adapter.callBids(params); + expect(xhr.requests.length).to.be.equal(1); + + const bidRequest = xhr.requests[0].url; + const defaultBidUrl = urlParse(DEFAULT_ENDPOINT); + const bidUrl = urlParse(bidRequest, true); + const query = bidUrl.query; + + expect(bidUrl.hostname).to.equal(defaultBidUrl.hostname); + expect(bidUrl.pathname).to.equal(defaultBidUrl.pathname); + + expect(query).to.have.property('someparam').and.to.equal('value'); }); }); describe('response handler', () => { let server; - beforeEach(() => { - server = sandbox.useFakeServer(); + beforeEach(() => { + server = sandbox.useFakeServer(); }); const assertSingleFailedBidResponse = () => { - sinon.assert.calledOnce(addBidResponseStub); - const placementCode = addBidResponseStub.getCall(0).args[0]; - const bidObject = addBidResponseStub.getCall(0).args[1]; - - expect(placementCode).to.be.equal('div-gpt-ad-12345-1'); + sinon.assert.calledOnce(addBidResponseStub); + const placementCode = addBidResponseStub.getCall(0).args[0]; + const bidObject = addBidResponseStub.getCall(0).args[1]; + + expect(placementCode).to.be.equal('div-gpt-ad-12345-1'); expect(bidObject.getStatusCode()).to.be.equal(STATUS.NO_BID); - }; - + }; + it('tolerates an empty response', () => { - server.respondWith(''); - adapter.callBids({bids: [tilePlacement()]}); - server.respond(); - + server.respondWith(''); + adapter.callBids({bids: [tilePlacement()]}); + server.respond(); + assertSingleFailedBidResponse(); - }); - + }); + it('tolerates a response error', () => { - server.respondWith([500, {}, '']); - adapter.callBids({bids: [tilePlacement()]}); - server.respond(); - + server.respondWith([500, {}, '']); + adapter.callBids({bids: [tilePlacement()]}); + server.respond(); + assertSingleFailedBidResponse(); - }); - + }); + it('tolerates an invalid response', () => { - server.respondWith('not json'); - adapter.callBids({bids: [tilePlacement()]}); - server.respond(); - + server.respondWith('not json'); + adapter.callBids({bids: [tilePlacement()]}); + server.respond(); + assertSingleFailedBidResponse(); - }); - - it('adds a bid reponse for each pending bid', () => { - const responses = [{ - width: '300', - height: '250', - cpm: 0.4, - ad: '' - }, { - width: '728', - height: '90', - cpm: 0.4, - ad: '' - }]; - - let id = 0; - server.respondWith((request) => { - request.respond(200, {}, JSON.stringify(responses[id])); - id += 1; - }); - - const params = { - bids: [tilePlacement(), leaderPlacement()] - }; - - adapter.callBids(params); - server.respond(); - - expect(server.requests.length).to.be.equal(2); - sinon.assert.calledTwice(addBidResponseStub); - - responses.forEach((expectedResponse, i) => { - const placementCode = addBidResponseStub.getCall(i).args[0]; - const bidObject = addBidResponseStub.getCall(i).args[1]; - - expect(placementCode).to.be.equal('div-gpt-ad-12345-' + (i + 1)); - - expect(bidObject.getStatusCode()).to.be.equal(STATUS.GOOD); - expect(bidObject).to.have.property('cpm').and.to.equal(expectedResponse.cpm); - expect(bidObject).to.have.property('ad').and.to.equal(expectedResponse.ad); - expect(bidObject).to.have.property('width').and.to.equal(expectedResponse.width); - expect(bidObject).to.have.property('height').and.to.equal(expectedResponse.height); - }); - }); - - // We want to check that responses are added according to a sampling value, - // this is possible by stubbing `Math.random`, to ensure the effect is - // limited to the area we check, we create a self destructing stub which - // restores itself once called. - it('adds responses according to the sampling defined in the response', () => { - const response = { - cpm: 0.4, - chance: 0.25, - ad: '' - }; - - // List of "random" values. We check that the first two pass and the last - // one is skipped. - const randomValues = [0.2, 0.3]; - let randomIndex = 0; - + }); + + it('adds a bid reponse for each pending bid', () => { + const responses = [{ + width: '300', + height: '250', + cpm: 0.4, + ad: '' + }, { + width: '728', + height: '90', + cpm: 0.4, + ad: '' + }]; + + let id = 0; server.respondWith((request) => { - const mathRandomStub = sandbox.stub(Math, 'random', function () { - const randomValue = randomValues[randomIndex]; - - randomIndex += 1; - mathRandomStub.restore(); // self destruct on call - - return randomValue; - }); - - request.respond(200, {}, JSON.stringify(response)); - - mathRandomStub.restore(); - }); - - const params = { - bids: [tilePlacement()] - }; - - adapter.callBids(params); - adapter.callBids(params); - server.respond(); - - sinon.assert.calledTwice(addBidResponseStub); - - const firstBidObject = addBidResponseStub.getCall(0).args[1]; - const secondBidObject = addBidResponseStub.getCall(1).args[1]; - - expect(firstBidObject.getStatusCode()).to.be.equal(STATUS.GOOD); - expect(secondBidObject.getStatusCode()).to.be.equal(STATUS.NO_BID); - }); - }); -}); + request.respond(200, {}, JSON.stringify(responses[id])); + id += 1; + }); + + const params = { + bids: [tilePlacement(), leaderPlacement()] + }; + + adapter.callBids(params); + server.respond(); + + expect(server.requests.length).to.be.equal(2); + sinon.assert.calledTwice(addBidResponseStub); + + responses.forEach((expectedResponse, i) => { + const placementCode = addBidResponseStub.getCall(i).args[0]; + const bidObject = addBidResponseStub.getCall(i).args[1]; + + expect(placementCode).to.be.equal('div-gpt-ad-12345-' + (i + 1)); + + expect(bidObject.getStatusCode()).to.be.equal(STATUS.GOOD); + expect(bidObject).to.have.property('cpm').and.to.equal(expectedResponse.cpm); + expect(bidObject).to.have.property('ad').and.to.equal(expectedResponse.ad); + expect(bidObject).to.have.property('width').and.to.equal(expectedResponse.width); + expect(bidObject).to.have.property('height').and.to.equal(expectedResponse.height); + }); + }); + + // We want to check that responses are added according to a sampling value, + // this is possible by stubbing `Math.random`, to ensure the effect is + // limited to the area we check, we create a self destructing stub which + // restores itself once called. + it('adds responses according to the sampling defined in the response', () => { + const response = { + cpm: 0.4, + chance: 0.25, + ad: '' + }; + + // List of "random" values. We check that the first two pass and the last + // one is skipped. + const randomValues = [0.2, 0.3]; + let randomIndex = 0; + + server.respondWith((request) => { + const mathRandomStub = sandbox.stub(Math, 'random', function () { + const randomValue = randomValues[randomIndex]; + + randomIndex += 1; + mathRandomStub.restore(); // self destruct on call + + return randomValue; + }); + + request.respond(200, {}, JSON.stringify(response)); + + mathRandomStub.restore(); + }); + + const params = { + bids: [tilePlacement()] + }; + + adapter.callBids(params); + adapter.callBids(params); + server.respond(); + + sinon.assert.calledTwice(addBidResponseStub); + + const firstBidObject = addBidResponseStub.getCall(0).args[1]; + const secondBidObject = addBidResponseStub.getCall(1).args[1]; + + expect(firstBidObject.getStatusCode()).to.be.equal(STATUS.GOOD); + expect(secondBidObject.getStatusCode()).to.be.equal(STATUS.NO_BID); + }); + }); +}); diff --git a/test/spec/adapters/huddledmasses_spec.js b/test/spec/modules/huddledmassesBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/huddledmasses_spec.js rename to test/spec/modules/huddledmassesBidAdapter_spec.js index e045d96f997..34218ed8e83 100644 --- a/test/spec/adapters/huddledmasses_spec.js +++ b/test/spec/modules/huddledmassesBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import Adapter from '../../../src/adapters/huddledmasses'; +import Adapter from '../../../modules/huddledmassesBidAdapter'; import adapterManager from 'src/adaptermanager'; import bidManager from 'src/bidmanager'; import CONSTANTS from 'src/constants.json'; diff --git a/test/spec/adapters/indexExchange_request_spec.js b/test/spec/modules/indexExchangeBidAdapter_request_spec.js similarity index 99% rename from test/spec/adapters/indexExchange_request_spec.js rename to test/spec/modules/indexExchangeBidAdapter_request_spec.js index df143b6476c..3a20b6a6d22 100644 --- a/test/spec/adapters/indexExchange_request_spec.js +++ b/test/spec/modules/indexExchangeBidAdapter_request_spec.js @@ -1,5 +1,4 @@ -import Adapter from '../../../src/adapters/indexExchange'; -import bidManager from '../../../src/bidmanager'; +import Adapter from '../../../modules/indexExchangeBidAdapter'; import adLoader from '../../../src/adloader'; var assert = require('chai').assert; @@ -8,8 +7,6 @@ var HeaderTagRequest = '/cygnus'; var SlotThreshold = 20; var ADAPTER_CODE = 'indexExchange'; -window.pbjs = window.pbjs || {}; - describe('indexExchange adapter - Request', function () { let adapter; let sandbox; diff --git a/test/spec/adapters/indexExchange_response_spec.js b/test/spec/modules/indexExchangeBidAdapter_response_spec.js similarity index 99% rename from test/spec/adapters/indexExchange_response_spec.js rename to test/spec/modules/indexExchangeBidAdapter_response_spec.js index 2e563b13398..86a73a25c81 100644 --- a/test/spec/adapters/indexExchange_response_spec.js +++ b/test/spec/modules/indexExchangeBidAdapter_response_spec.js @@ -1,4 +1,4 @@ -import Adapter from '../../../src/adapters/indexExchange'; +import Adapter from '../../../modules/indexExchangeBidAdapter'; import bidManager from '../../../src/bidmanager'; import adLoader from '../../../src/adloader'; @@ -10,7 +10,7 @@ var ADAPTER_CODE = 'indexExchange'; var DefaultValue = { dealID: 'IXDeal' }; -window.pbjs = window.pbjs || {}; + var ResponseStatus = { noBid: 'Bid returned empty or error response' }; diff --git a/test/spec/adapters/indexExchange_validation_spec.js b/test/spec/modules/indexExchangeBidAdapter_validadtion_spec.js similarity index 99% rename from test/spec/adapters/indexExchange_validation_spec.js rename to test/spec/modules/indexExchangeBidAdapter_validadtion_spec.js index fbb3e05f5b0..da0907cbf48 100644 --- a/test/spec/adapters/indexExchange_validation_spec.js +++ b/test/spec/modules/indexExchangeBidAdapter_validadtion_spec.js @@ -1,5 +1,4 @@ -import Adapter from '../../../src/adapters/indexExchange'; -import bidManager from '../../../src/bidmanager'; +import Adapter from '../../../modules/indexExchangeBidAdapter'; import adLoader from '../../../src/adloader'; var assert = require('chai').assert; @@ -7,8 +6,6 @@ var IndexUtils = require('../../helpers/index_adapter_utils.js'); var HeaderTagRequest = '/cygnus'; var ADAPTER_CODE = 'indexExchange'; -window.pbjs = window.pbjs || {}; - describe('indexExchange adapter - Validation', function () { let adapter; let sandbox; diff --git a/test/spec/adapters/inneractive_spec.js b/test/spec/modules/inneractiveBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/inneractive_spec.js rename to test/spec/modules/inneractiveBidAdapter_spec.js index be062ed29dd..b92c173d78b 100644 --- a/test/spec/adapters/inneractive_spec.js +++ b/test/spec/modules/inneractiveBidAdapter_spec.js @@ -1,7 +1,7 @@ /* globals context */ import {expect} from 'chai'; -import {default as InneractiveAdapter} from 'src/adapters/inneractive'; +import {default as InneractiveAdapter} from 'modules/inneractiveBidAdapter'; import bidmanager from 'src/bidmanager'; // Using plain-old-style functions, why? see: http://mochajs.org/#arrow-functions diff --git a/test/spec/adapters/innity_spec.js b/test/spec/modules/innityBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/innity_spec.js rename to test/spec/modules/innityBidAdapter_spec.js index c87c8deca22..7e4ac147c68 100644 --- a/test/spec/adapters/innity_spec.js +++ b/test/spec/modules/innityBidAdapter_spec.js @@ -2,7 +2,7 @@ describe('innity adapter tests', function () { var expect = require('chai').expect; var urlParse = require('url-parse'); var querystringify = require('querystringify'); - var adapter = require('src/adapters/innity'); + var adapter = require('modules/innityBidAdapter'); var adLoader = require('src/adloader'); var bidmanager = require('src/bidmanager'); diff --git a/test/spec/adapters/jcm_spec.js b/test/spec/modules/jcmBidAdapter_spec.js similarity index 83% rename from test/spec/adapters/jcm_spec.js rename to test/spec/modules/jcmBidAdapter_spec.js index 9d92fcb8e1e..59f95dfe6e6 100644 --- a/test/spec/adapters/jcm_spec.js +++ b/test/spec/modules/jcmBidAdapter_spec.js @@ -5,14 +5,10 @@ describe('jcm adapter tests', function () { // FYI: querystringify will perform encoding/decoding var querystringify = require('querystringify'); - var adapter = require('src/adapters/jcm'); + var adapter = require('modules/jcmBidAdapter'); var adLoader = require('src/adloader'); var bidmanager = require('src/bidmanager'); - window.pbjs = window.pbjs || {}; - if (typeof (pbjs) === 'undefined') { - var pbjs = window.pbjs; - } let stubLoadScript; beforeEach(function () { @@ -24,14 +20,14 @@ describe('jcm adapter tests', function () { }); describe('creation of bid url', function () { - if (typeof (pbjs._bidsReceived) === 'undefined') { - pbjs._bidsReceived = []; + if (typeof ($$PREBID_GLOBAL$$._bidsReceived) === 'undefined') { + $$PREBID_GLOBAL$$._bidsReceived = []; } - if (typeof (pbjs._bidsRequested) === 'undefined') { - pbjs._bidsRequested = []; + if (typeof ($$PREBID_GLOBAL$$._bidsRequested) === 'undefined') { + $$PREBID_GLOBAL$$._bidsRequested = []; } - if (typeof (pbjs._adsReceived) === 'undefined') { - pbjs._adsReceived = []; + if (typeof ($$PREBID_GLOBAL$$._adsReceived) === 'undefined') { + $$PREBID_GLOBAL$$._adsReceived = []; } it('should be called only once', function () { @@ -98,14 +94,14 @@ describe('jcm adapter tests', function () { }); describe('placement by size', function () { - if (typeof (pbjs._bidsReceived) === 'undefined') { - pbjs._bidsReceived = []; + if (typeof ($$PREBID_GLOBAL$$._bidsReceived) === 'undefined') { + $$PREBID_GLOBAL$$._bidsReceived = []; } - if (typeof (pbjs._bidsRequested) === 'undefined') { - pbjs._bidsRequested = []; + if (typeof ($$PREBID_GLOBAL$$._bidsRequested) === 'undefined') { + $$PREBID_GLOBAL$$._bidsRequested = []; } - if (typeof (pbjs._adsReceived) === 'undefined') { - pbjs._adsReceived = []; + if (typeof ($$PREBID_GLOBAL$$._adsReceived) === 'undefined') { + $$PREBID_GLOBAL$$._adsReceived = []; } it('should be called with specific parameters for two bids', function () { @@ -164,14 +160,14 @@ describe('jcm adapter tests', function () { }); describe('handling of the callback response', function () { - if (typeof (pbjs._bidsReceived) === 'undefined') { - pbjs._bidsReceived = []; + if (typeof ($$PREBID_GLOBAL$$._bidsReceived) === 'undefined') { + $$PREBID_GLOBAL$$._bidsReceived = []; } - if (typeof (pbjs._bidsRequested) === 'undefined') { - pbjs._bidsRequested = []; + if (typeof ($$PREBID_GLOBAL$$._bidsRequested) === 'undefined') { + $$PREBID_GLOBAL$$._bidsRequested = []; } - if (typeof (pbjs._adsReceived) === 'undefined') { - pbjs._adsReceived = []; + if (typeof ($$PREBID_GLOBAL$$._adsReceived) === 'undefined') { + $$PREBID_GLOBAL$$._adsReceived = []; } var params = { @@ -202,7 +198,7 @@ describe('jcm adapter tests', function () { var response = '{"bids":[{"width":300,"cpm":3,"ad":"%3Cimg+src%3D%22http%3A%2F%2Fmedia.adfrontiers.com%2Fimgs%2Fpartnership_300x250.png%22%3E","callbackId":"3c9408cdbf2f68","height":250},{"width":728,"cpm":0,"ad":"%3Cimg+src%3D%22http%3A%2F%2Fmedia.adfrontiers.com%2Fimgs%2Fpartnership_728x90.png%22%3E","callbackId":"3c9408cdbf2f69","height":90}]}'; it('callback function should exist', function () { - expect(pbjs.processJCMResponse).to.exist.and.to.be.a('function'); + expect($$PREBID_GLOBAL$$.processJCMResponse).to.exist.and.to.be.a('function'); }); it('bidmanager.addBidResponse should be called twice with correct arguments', function () { @@ -217,13 +213,13 @@ describe('jcm adapter tests', function () { unit.sizes = [[300, 250], [728, 90]]; adUnits.push(unit); - if (typeof (pbjs._bidsRequested) === 'undefined') { - pbjs._bidsRequested = [params]; + if (typeof ($$PREBID_GLOBAL$$._bidsRequested) === 'undefined') { + $$PREBID_GLOBAL$$._bidsRequested = [params]; } else { - pbjs._bidsRequested.push(params); + $$PREBID_GLOBAL$$._bidsRequested.push(params); } - pbjs.adUnits = adUnits; - pbjs.processJCMResponse(response); + $$PREBID_GLOBAL$$.adUnits = adUnits; + $$PREBID_GLOBAL$$.processJCMResponse(response); var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; var bidObject1 = stubAddBidResponse.getCall(0).args[1]; diff --git a/test/spec/adapters/komoona_spec.js b/test/spec/modules/komoonaBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/komoona_spec.js rename to test/spec/modules/komoonaBidAdapter_spec.js index 30ba04a508e..f0e4a7086d3 100644 --- a/test/spec/adapters/komoona_spec.js +++ b/test/spec/modules/komoonaBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import Adapter from 'src/adapters/komoona'; +import Adapter from 'modules/komoonaBidAdapter'; import bidmanager from 'src/bidmanager'; const ENDPOINT = '//bidder.komoona.com/v1/GetSBids'; diff --git a/test/spec/adapters/lifestreet_spec.js b/test/spec/modules/lifestreetBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/lifestreet_spec.js rename to test/spec/modules/lifestreetBidAdapter_spec.js index 63922799a4c..bb93ad90ef2 100644 --- a/test/spec/adapters/lifestreet_spec.js +++ b/test/spec/modules/lifestreetBidAdapter_spec.js @@ -2,7 +2,7 @@ import {expect} from 'chai'; import {cloneJson} from 'src/utils'; import adloader from 'src/adloader'; import bidmanager from 'src/bidmanager'; -import LifestreetAdapter from 'src/adapters/lifestreet'; +import LifestreetAdapter from 'modules/lifestreetBidAdapter'; const BIDDER_REQUEST = { auctionStart: new Date().getTime(), diff --git a/test/spec/adapters/mantis_spec.js b/test/spec/modules/mantisBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/mantis_spec.js rename to test/spec/modules/mantisBidAdapter_spec.js index 29332dacf7e..7803bf947e2 100644 --- a/test/spec/adapters/mantis_spec.js +++ b/test/spec/modules/mantisBidAdapter_spec.js @@ -2,7 +2,7 @@ describe('mantis adapter tests', function () { const expect = require('chai').expect; - const adapter = require('src/adapters/mantis.js'); + const adapter = require('modules/mantisBidAdapter'); const bidmanager = require('src/bidmanager'); const adloader = require('src/adloader'); const constants = require('src/constants.json'); diff --git a/test/spec/adapters/memeglobal_spec.js b/test/spec/modules/memeglobalBidAdapter_spec.js similarity index 92% rename from test/spec/adapters/memeglobal_spec.js rename to test/spec/modules/memeglobalBidAdapter_spec.js index 6aeaf161838..6f770c290d0 100644 --- a/test/spec/adapters/memeglobal_spec.js +++ b/test/spec/modules/memeglobalBidAdapter_spec.js @@ -1,6 +1,6 @@ describe('memeglobal adapter tests', function () { const expect = require('chai').expect; - const adapter = require('src/adapters/memeglobal'); + const adapter = require('modules/memeglobalBidAdapter'); const bidmanager = require('src/bidmanager'); const adLoader = require('src/adloader'); var bidderName = 'memeglobal'; @@ -15,7 +15,7 @@ describe('memeglobal adapter tests', function () { }); function getBidSetForBidder() { - return pbjs._bidsRequested.find(bidSet => bidSet.bidderCode === bidderName); + return $$PREBID_GLOBAL$$._bidsRequested.find(bidSet => bidSet.bidderCode === bidderName); } function checkBidsRequestedInit() { @@ -28,13 +28,13 @@ describe('memeglobal adapter tests', function () { bidderCode: 'memeglobal', bids: [] }; - pbjs._bidsRequested.push(bidderRequest); + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); } } describe('functions and initialization', function () { it('should exist and be a function', function () { - expect(pbjs.mgres).to.exist.and.to.be.a('function'); + expect($$PREBID_GLOBAL$$.mgres).to.exist.and.to.be.a('function'); }); it('callBids with params', function () { @@ -101,7 +101,7 @@ describe('memeglobal adapter tests', function () { // adapter needs to be called for stub registration. adapter() - pbjs.mgres(response); + $$PREBID_GLOBAL$$.mgres(response); expect(stubAddBidResponse.getCall(0)).to.equal(null); // var bidPlacementCode = stubAddBidResponse.getCall(0).args[0]; @@ -149,7 +149,7 @@ describe('memeglobal adapter tests', function () { var bidSet = getBidSetForBidder(); bidSet.bids.push(bid); adapter() - pbjs.mgres(response); + $$PREBID_GLOBAL$$.mgres(response); var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; var bidObject1 = stubAddBidResponse.getCall(0).args[1]; diff --git a/test/spec/adapters/openx_spec.js b/test/spec/modules/openxBidAdapter_spec.js similarity index 94% rename from test/spec/adapters/openx_spec.js rename to test/spec/modules/openxBidAdapter_spec.js index 437561a9621..c828aacda6a 100644 --- a/test/spec/adapters/openx_spec.js +++ b/test/spec/modules/openxBidAdapter_spec.js @@ -1,7 +1,7 @@ describe('openx adapter tests', function () { const expect = require('chai').expect; const assert = require('chai').assert; - const adapter = require('src/adapters/openx'); + const adapter = require('modules/openxBidAdapter'); const bidmanager = require('src/bidmanager'); const adloader = require('src/adloader'); const CONSTANTS = require('src/constants.json'); @@ -11,7 +11,7 @@ describe('openx adapter tests', function () { describe('test openx callback responce', function () { it('should exist and be a function', function () { - expect(pbjs.oxARJResponse).to.exist.and.to.be.a('function'); + expect($$PREBID_GLOBAL$$.oxARJResponse).to.exist.and.to.be.a('function'); }); it('should add empty bid responses if no bids returned', function () { @@ -44,11 +44,11 @@ describe('openx adapter tests', function () { } }; - pbjs._bidsRequested.push(bidderRequest); + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); // adapter needs to be called, in order for the stub to register. adapter(); - pbjs.oxARJResponse(response); + $$PREBID_GLOBAL$$.oxARJResponse(response); let bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; let bidResponse1 = stubAddBidResponse.getCall(0).args[1]; @@ -116,11 +116,11 @@ describe('openx adapter tests', function () { } }; - pbjs._bidsRequested.push(bidderRequest); + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); // adapter needs to be called, in order for the stub to register. adapter(); - pbjs.oxARJResponse(response); + $$PREBID_GLOBAL$$.oxARJResponse(response); let bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; let bidResponse1 = stubAddBidResponse.getCall(0).args[1]; @@ -193,11 +193,11 @@ describe('openx adapter tests', function () { } }; - pbjs._bidsRequested.push(bidderRequest); + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); // adapter needs to be called, in order for the stub to register. adapter(); - pbjs.oxARJResponse(response); + $$PREBID_GLOBAL$$.oxARJResponse(response); let bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; let bidResponse1 = stubAddBidResponse.getCall(0).args[1]; diff --git a/test/spec/adapters/piximedia_spec.js b/test/spec/modules/piximediaBidAdapter_spec.js similarity index 81% rename from test/spec/adapters/piximedia_spec.js rename to test/spec/modules/piximediaBidAdapter_spec.js index f6168390182..76e4ded1b1b 100644 --- a/test/spec/adapters/piximedia_spec.js +++ b/test/spec/modules/piximediaBidAdapter_spec.js @@ -4,13 +4,12 @@ describe('Piximedia adapter tests', function () { // var querystringify = require('querystringify'); - var adapter = require('src/adapters/piximedia'); + var adapter = require('modules/piximediaBidAdapter'); var adLoader = require('src/adloader'); var bidmanager = require('src/bidmanager'); var utils = require('src/utils'); var CONSTANTS = require('src/constants.json'); - var pbjs = window.pbjs = window.pbjs || {}; let stubLoadScript; beforeEach(function () { @@ -22,14 +21,14 @@ describe('Piximedia adapter tests', function () { }); describe('creation of prebid url', function () { - if (typeof (pbjs._bidsReceived) === 'undefined') { - pbjs._bidsReceived = []; + if (typeof ($$PREBID_GLOBAL$$._bidsReceived) === 'undefined') { + $$PREBID_GLOBAL$$._bidsReceived = []; } - if (typeof (pbjs._bidsRequested) === 'undefined') { - pbjs._bidsRequested = []; + if (typeof ($$PREBID_GLOBAL$$._bidsRequested) === 'undefined') { + $$PREBID_GLOBAL$$._bidsRequested = []; } - if (typeof (pbjs._adsReceived) === 'undefined') { - pbjs._adsReceived = []; + if (typeof ($$PREBID_GLOBAL$$._adsReceived) === 'undefined') { + $$PREBID_GLOBAL$$._adsReceived = []; } it('should call the Piximedia prebid URL once on valid calls', function () { @@ -125,7 +124,7 @@ describe('Piximedia adapter tests', function () { expect(parsedBidUrl.hostname).to.equal('static.adserver.pm'); expect(parsedBidUrl.query).to.equal(''); - expect(parsedBidUrl.pathname.replace(/cbid=[a-f0-9]+/, 'cbid=210af5668b1e23').replace(/rand=[0-9]+$/, 'rand=42')).to.equal('/prebid/site_id=TEST/placement_id=TEST/l_id=1295/custom=bespoke/custom2=bespoke2/custom3=/custom4=/jsonp=pbjs.handlePiximediaCallback/sizes=300x250/cbid=210af5668b1e23/rand=42'); + expect(parsedBidUrl.pathname.replace(/cbid=[a-f0-9]+/, 'cbid=210af5668b1e23').replace(/rand=[0-9]+$/, 'rand=42')).to.equal('/prebid/site_id=TEST/placement_id=TEST/l_id=1295/custom=bespoke/custom2=bespoke2/custom3=/custom4=/jsonp=$$PREBID_GLOBAL$$.handlePiximediaCallback/sizes=300x250/cbid=210af5668b1e23/rand=42'); }); it('should call the correct Prebid URL when using the default URL and overridding sizes', function () { @@ -153,7 +152,7 @@ describe('Piximedia adapter tests', function () { expect(parsedBidUrl.hostname).to.equal('static.adserver.pm'); expect(parsedBidUrl.query).to.equal(''); - expect(parsedBidUrl.pathname.replace(/cbid=[a-f0-9]+/, 'cbid=210af5668b1e23').replace(/rand=[0-9]+$/, 'rand=42')).to.equal('/prebid/site_id=TEST/placement_id=TEST/jsonp=pbjs.handlePiximediaCallback/sizes=300x600%2C728x90/cbid=210af5668b1e23/rand=42'); + expect(parsedBidUrl.pathname.replace(/cbid=[a-f0-9]+/, 'cbid=210af5668b1e23').replace(/rand=[0-9]+$/, 'rand=42')).to.equal('/prebid/site_id=TEST/placement_id=TEST/jsonp=$$PREBID_GLOBAL$$.handlePiximediaCallback/sizes=300x600%2C728x90/cbid=210af5668b1e23/rand=42'); }); it('should call the correct Prebid URL when supplying a custom URL', function () { @@ -181,19 +180,19 @@ describe('Piximedia adapter tests', function () { expect(parsedBidUrl.hostname).to.equal('resources.pm'); expect(parsedBidUrl.query).to.equal(''); - expect(parsedBidUrl.pathname.replace(/cbid=[a-f0-9]+/, 'cbid=210af5668b1e23').replace(/rand=[0-9]+$/, 'rand=42')).to.equal('/tests/prebid/bids.js/site_id=TEST/placement_id=TEST/jsonp=pbjs.handlePiximediaCallback/sizes=300x250/cbid=210af5668b1e23/rand=42'); + expect(parsedBidUrl.pathname.replace(/cbid=[a-f0-9]+/, 'cbid=210af5668b1e23').replace(/rand=[0-9]+$/, 'rand=42')).to.equal('/tests/prebid/bids.js/site_id=TEST/placement_id=TEST/jsonp=$$PREBID_GLOBAL$$.handlePiximediaCallback/sizes=300x250/cbid=210af5668b1e23/rand=42'); }); }); describe('handling of the callback response', function () { - if (typeof (pbjs._bidsReceived) === 'undefined') { - pbjs._bidsReceived = []; + if (typeof ($$PREBID_GLOBAL$$._bidsReceived) === 'undefined') { + $$PREBID_GLOBAL$$._bidsReceived = []; } - if (typeof (pbjs._bidsRequested) === 'undefined') { - pbjs._bidsRequested = []; + if (typeof ($$PREBID_GLOBAL$$._bidsRequested) === 'undefined') { + $$PREBID_GLOBAL$$._bidsRequested = []; } - if (typeof (pbjs._adsReceived) === 'undefined') { - pbjs._adsReceived = []; + if (typeof ($$PREBID_GLOBAL$$._adsReceived) === 'undefined') { + $$PREBID_GLOBAL$$._adsReceived = []; } var params = { @@ -212,7 +211,7 @@ describe('Piximedia adapter tests', function () { }; it('Piximedia callback function should exist', function () { - expect(pbjs.handlePiximediaCallback).to.exist.and.to.be.a('function'); + expect($$PREBID_GLOBAL$$.handlePiximediaCallback).to.exist.and.to.be.a('function'); }); it('bidmanager.addBidResponse should be called once with correct arguments', function () { @@ -238,15 +237,15 @@ describe('Piximedia adapter tests', function () { unit.sizes = [[300, 250], [728, 90]]; adUnits.push(unit); - if (typeof (pbjs._bidsRequested) === 'undefined') { - pbjs._bidsRequested = [params]; + if (typeof ($$PREBID_GLOBAL$$._bidsRequested) === 'undefined') { + $$PREBID_GLOBAL$$._bidsRequested = [params]; } else { - pbjs._bidsRequested.push(params); + $$PREBID_GLOBAL$$._bidsRequested.push(params); } - pbjs.adUnits = adUnits; + $$PREBID_GLOBAL$$.adUnits = adUnits; response.cbid = stubGetUniqueIdentifierStr.returnValues[0]; - pbjs.handlePiximediaCallback(response); + $$PREBID_GLOBAL$$.handlePiximediaCallback(response); sinon.assert.calledOnce(stubAddBidResponse); var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; @@ -288,15 +287,15 @@ describe('Piximedia adapter tests', function () { unit.sizes = [[300, 250], [728, 90]]; adUnits.push(unit); - if (typeof (pbjs._bidsRequested) === 'undefined') { - pbjs._bidsRequested = [params]; + if (typeof ($$PREBID_GLOBAL$$._bidsRequested) === 'undefined') { + $$PREBID_GLOBAL$$._bidsRequested = [params]; } else { - pbjs._bidsRequested.push(params); + $$PREBID_GLOBAL$$._bidsRequested.push(params); } - pbjs.adUnits = adUnits; + $$PREBID_GLOBAL$$.adUnits = adUnits; response.cbid = stubGetUniqueIdentifierStr.returnValues[0]; - pbjs.handlePiximediaCallback(response); + $$PREBID_GLOBAL$$.handlePiximediaCallback(response); sinon.assert.calledOnce(stubAddBidResponse); var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; @@ -331,15 +330,15 @@ describe('Piximedia adapter tests', function () { unit.sizes = [[300, 250], [728, 90]]; adUnits.push(unit); - if (typeof (pbjs._bidsRequested) === 'undefined') { - pbjs._bidsRequested = [params]; + if (typeof ($$PREBID_GLOBAL$$._bidsRequested) === 'undefined') { + $$PREBID_GLOBAL$$._bidsRequested = [params]; } else { - pbjs._bidsRequested.push(params); + $$PREBID_GLOBAL$$._bidsRequested.push(params); } - pbjs.adUnits = adUnits; + $$PREBID_GLOBAL$$.adUnits = adUnits; response.cbid = stubGetUniqueIdentifierStr.returnValues[0]; - pbjs.handlePiximediaCallback(response); + $$PREBID_GLOBAL$$.handlePiximediaCallback(response); sinon.assert.calledOnce(stubAddBidResponse); var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; @@ -370,15 +369,15 @@ describe('Piximedia adapter tests', function () { unit.sizes = [[300, 250], [728, 90]]; adUnits.push(unit); - if (typeof (pbjs._bidsRequested) === 'undefined') { - pbjs._bidsRequested = [params]; + if (typeof ($$PREBID_GLOBAL$$._bidsRequested) === 'undefined') { + $$PREBID_GLOBAL$$._bidsRequested = [params]; } else { - pbjs._bidsRequested.push(params); + $$PREBID_GLOBAL$$._bidsRequested.push(params); } - pbjs.adUnits = adUnits; + $$PREBID_GLOBAL$$.adUnits = adUnits; response.cbid = stubGetUniqueIdentifierStr.returnValues[0] + '_BOGUS'; - pbjs.handlePiximediaCallback(response); + $$PREBID_GLOBAL$$.handlePiximediaCallback(response); sinon.assert.notCalled(stubAddBidResponse); @@ -400,14 +399,14 @@ describe('Piximedia adapter tests', function () { unit.sizes = [[300, 250], [728, 90]]; adUnits.push(unit); - if (typeof (pbjs._bidsRequested) === 'undefined') { - pbjs._bidsRequested = [params]; + if (typeof ($$PREBID_GLOBAL$$._bidsRequested) === 'undefined') { + $$PREBID_GLOBAL$$._bidsRequested = [params]; } else { - pbjs._bidsRequested.push(params); + $$PREBID_GLOBAL$$._bidsRequested.push(params); } - pbjs.adUnits = adUnits; + $$PREBID_GLOBAL$$.adUnits = adUnits; - pbjs.handlePiximediaCallback(response); + $$PREBID_GLOBAL$$.handlePiximediaCallback(response); sinon.assert.notCalled(stubAddBidResponse); diff --git a/test/spec/adapters/prebidServer_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/prebidServer_spec.js rename to test/spec/modules/prebidServerBidAdapter_spec.js index fe1cb7e9894..0216937a788 100644 --- a/test/spec/adapters/prebidServer_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import Adapter from 'src/adapters/prebidServer'; +import Adapter from 'modules/prebidServerBidAdapter'; import bidmanager from 'src/bidmanager'; import CONSTANTS from 'src/constants.json'; import * as utils from 'src/utils'; @@ -160,6 +160,7 @@ describe('S2S Adapter', () => { utils.getBidRequest.restore(); }); + // TODO: test dependent on pbjs_api_spec. Needs to be isolated it('registers bids', () => { server.respondWith(JSON.stringify(RESPONSE)); diff --git a/test/spec/adapters/pubgears_spec.js b/test/spec/modules/pubgearsBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/pubgears_spec.js rename to test/spec/modules/pubgearsBidAdapter_spec.js index 724b9dcd368..c0179bc0d83 100644 --- a/test/spec/adapters/pubgears_spec.js +++ b/test/spec/modules/pubgearsBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import Adapter from 'src/adapters/pubgears' +import Adapter from 'modules/pubgearsBidAdapter' import bidmanager from 'src/bidmanager' describe('PubGearsAdapter', () => { diff --git a/test/spec/adapters/analytics/pubwiseanalytics_spec.js b/test/spec/modules/pubwiseAnalyticsAdapter_spec.js similarity index 79% rename from test/spec/adapters/analytics/pubwiseanalytics_spec.js rename to test/spec/modules/pubwiseAnalyticsAdapter_spec.js index 62c6e463ca9..4c3919172d8 100644 --- a/test/spec/adapters/analytics/pubwiseanalytics_spec.js +++ b/test/spec/modules/pubwiseAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ -import pubwiseAnalytics from 'src/adapters/analytics/pubwiseanalytics'; -let events = require('../../../../src/events'); -let adaptermanager = require('../../../../src/adaptermanager'); -let constants = require('../../../../src/constants.json'); +import pubwiseAnalytics from 'modules/pubwiseAnalyticsAdapter'; +let events = require('src/events'); +let adaptermanager = require('src/adaptermanager'); +let constants = require('src/constants.json'); describe('PubWise Prebid Analytics', function () { describe('enableAnalytics', function () { diff --git a/test/spec/adapters/pulsepoint_spec.js b/test/spec/modules/pulsepointBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/pulsepoint_spec.js rename to test/spec/modules/pulsepointBidAdapter_spec.js index cd56485b91a..07639310c36 100644 --- a/test/spec/adapters/pulsepoint_spec.js +++ b/test/spec/modules/pulsepointBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import PulsePointAdapter from '../../../src/adapters/pulsepoint'; +import PulsePointAdapter from '../../../modules/pulsepointBidAdapter'; import bidManager from '../../../src/bidmanager'; import adLoader from '../../../src/adloader'; diff --git a/test/spec/adapters/pulsepointLite_spec.js b/test/spec/modules/pulsepointLiteBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/pulsepointLite_spec.js rename to test/spec/modules/pulsepointLiteBidAdapter_spec.js index 85eb28ef46b..f48d361d4cd 100644 --- a/test/spec/adapters/pulsepointLite_spec.js +++ b/test/spec/modules/pulsepointLiteBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import PulsePointAdapter from 'src/adapters/pulsepointLite'; +import PulsePointAdapter from 'modules/pulsepointLiteBidAdapter'; import bidManager from 'src/bidmanager'; import * as ajax from 'src/ajax'; import {parse as parseURL} from 'src/url'; diff --git a/test/spec/adapters/quantcast_spec.js b/test/spec/modules/quantcastBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/quantcast_spec.js rename to test/spec/modules/quantcastBidAdapter_spec.js index daebdd4e470..0d139ac3ec2 100644 --- a/test/spec/adapters/quantcast_spec.js +++ b/test/spec/modules/quantcastBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import Adapter from '../../../src/adapters/quantcast'; +import Adapter from '../../../modules/quantcastBidAdapter'; import * as ajax from 'src/ajax'; import bidManager from '../../../src/bidmanager'; import adLoader from '../../../src/adloader'; diff --git a/test/spec/adapters/rhythmone_spec.js b/test/spec/modules/rhythmoneBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/rhythmone_spec.js rename to test/spec/modules/rhythmoneBidAdapter_spec.js index efc964b6b6e..002d021b574 100644 --- a/test/spec/adapters/rhythmone_spec.js +++ b/test/spec/modules/rhythmoneBidAdapter_spec.js @@ -1,4 +1,4 @@ -var r1 = require('../../../src/adapters/rhythmone.js'); +var r1 = require('../../../modules/rhythmoneBidAdapter'); var assert = require('assert'); describe('rhythmone adapter tests', function () { diff --git a/test/spec/adapters/analytics/roxot_analytic_spec.js b/test/spec/modules/roxotAnalyticsAdapter_spec.js similarity index 77% rename from test/spec/adapters/analytics/roxot_analytic_spec.js rename to test/spec/modules/roxotAnalyticsAdapter_spec.js index 78da9489ca8..fbd298c7e3b 100644 --- a/test/spec/adapters/analytics/roxot_analytic_spec.js +++ b/test/spec/modules/roxotAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ -import roxotAnalytic from 'src/adapters/analytics/roxot'; -let events = require('../../../../src/events'); -let adaptermanager = require('../../../../src/adaptermanager'); -let constants = require('../../../../src/constants.json'); +import roxotAnalytic from 'modules/roxotAnalyticsAdapter'; +let events = require('src/events'); +let adaptermanager = require('src/adaptermanager'); +let constants = require('src/constants.json'); describe('Roxot Prebid Analytic', function () { describe('enableAnalytics', function () { diff --git a/test/spec/adapters/roxot_spec.js b/test/spec/modules/roxotBidAdapter_spec.js similarity index 90% rename from test/spec/adapters/roxot_spec.js rename to test/spec/modules/roxotBidAdapter_spec.js index 471d97d9a22..af7bef291e1 100644 --- a/test/spec/adapters/roxot_spec.js +++ b/test/spec/modules/roxotBidAdapter_spec.js @@ -1,11 +1,11 @@ describe('Roxot adapter tests', function() { const expect = require('chai').expect; - const adapter = require('src/adapters/roxot'); + const adapter = require('modules/roxotBidAdapter'); const bidmanager = require('src/bidmanager'); describe('roxotResponseHandler', function () { it('should exist and be a function', function () { - expect(pbjs.roxotResponseHandler).to.exist.and.to.be.a('function'); + expect($$PREBID_GLOBAL$$.roxotResponseHandler).to.exist.and.to.be.a('function'); }); it('should add empty bid responses if no bids returned', function () { @@ -35,12 +35,12 @@ describe('Roxot adapter tests', function() { 'bids': [] }; - pbjs._bidsRequested.push(bidderRequest); + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); // adapter needs to be called, in order for the stub to register. adapter(); - pbjs.roxotResponseHandler(response); + $$PREBID_GLOBAL$$.roxotResponseHandler(response); var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; var bidObject1 = stubAddBidResponse.getCall(0).args[1]; @@ -93,12 +93,12 @@ describe('Roxot adapter tests', function() { } ]}; - pbjs._bidsRequested.push(bidderRequest); + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); // adapter needs to be called, in order for the stub to register. adapter(); - pbjs.roxotResponseHandler(response); + $$PREBID_GLOBAL$$.roxotResponseHandler(response); var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; var bidObject1 = stubAddBidResponse.getCall(0).args[1]; diff --git a/test/spec/adapters/rubicon_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/rubicon_spec.js rename to test/spec/modules/rubiconBidAdapter_spec.js index 94a4fea82b9..254ab205439 100644 --- a/test/spec/adapters/rubicon_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -1,8 +1,7 @@ import { expect } from 'chai'; -import adloader from 'src/adloader'; import adapterManager from 'src/adaptermanager'; import bidManager from 'src/bidmanager'; -import RubiconAdapter from 'src/adapters/rubicon'; +import RubiconAdapter from 'modules/rubiconBidAdapter'; import {parse as parseQuery} from 'querystring'; var CONSTANTS = require('src/constants.json'); diff --git a/test/spec/adapters/sekindoUM_spec.js b/test/spec/modules/sekindoUMBidAdapter_spec.js similarity index 96% rename from test/spec/adapters/sekindoUM_spec.js rename to test/spec/modules/sekindoUMBidAdapter_spec.js index d1bd1d4b9f5..074e51b3a9d 100644 --- a/test/spec/adapters/sekindoUM_spec.js +++ b/test/spec/modules/sekindoUMBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import sekindoUMAdapter from '../../../src/adapters/sekindoUM'; +import sekindoUMAdapter from '../../../modules/sekindoUMBidAdapter'; var bidManager = require('src/bidmanager'); describe('sekindoUM Adapter Tests', () => { diff --git a/test/spec/adapters/serverbid_spec.js b/test/spec/modules/serverbidBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/serverbid_spec.js rename to test/spec/modules/serverbidBidAdapter_spec.js index 6151c99b21a..ed1a227235f 100644 --- a/test/spec/adapters/serverbid_spec.js +++ b/test/spec/modules/serverbidBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import Adapter from 'src/adapters/serverbid'; +import Adapter from 'modules/serverbidBidAdapter'; import bidmanager from 'src/bidmanager'; import * as utils from 'src/utils'; diff --git a/test/spec/unit/adapters/analytics/sharethrough_analytics_spec.js b/test/spec/modules/sharethroughAnalyticsAdapter_spec.js similarity index 97% rename from test/spec/unit/adapters/analytics/sharethrough_analytics_spec.js rename to test/spec/modules/sharethroughAnalyticsAdapter_spec.js index 0a1ad57ce43..8968e0461fb 100644 --- a/test/spec/unit/adapters/analytics/sharethrough_analytics_spec.js +++ b/test/spec/modules/sharethroughAnalyticsAdapter_spec.js @@ -1,4 +1,4 @@ -import sharethroughAnalytics from 'src/adapters/analytics/sharethrough_analytics'; +import sharethroughAnalytics from 'modules/sharethroughAnalyticsAdapter'; import { expect } from 'chai'; describe('sharethrough analytics adapter', () => { diff --git a/test/spec/adapters/sharethrough_spec.js b/test/spec/modules/sharethroughBidAdapter_spec.js similarity index 94% rename from test/spec/adapters/sharethrough_spec.js rename to test/spec/modules/sharethroughBidAdapter_spec.js index 8f0bef53a4a..070f20958bb 100644 --- a/test/spec/adapters/sharethrough_spec.js +++ b/test/spec/modules/sharethroughBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import Adapter from '../../../src/adapters/sharethrough'; +import Adapter from '../../../modules/sharethroughBidAdapter'; import bidManager from '../../../src/bidmanager'; describe('sharethrough adapter', () => { @@ -34,14 +34,14 @@ describe('sharethrough adapter', () => { beforeEach(() => { adapter = new Adapter(); sandbox = sinon.sandbox.create(); - bidsRequestedOriginal = pbjs._bidsRequested; - pbjs._bidsRequested = []; + bidsRequestedOriginal = $$PREBID_GLOBAL$$._bidsRequested; + $$PREBID_GLOBAL$$._bidsRequested = []; }); afterEach(() => { sandbox.restore(); - pbjs._bidsRequested = bidsRequestedOriginal; + $$PREBID_GLOBAL$$._bidsRequested = bidsRequestedOriginal; }); describe('callBids', () => { @@ -74,7 +74,7 @@ describe('sharethrough adapter', () => { sandbox.stub(bidManager, 'addBidResponse'); server = sinon.fakeServer.create(); - pbjs._bidsRequested.push(bidderRequest); + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); adapter.str.placementCodeSet['foo'] = {}; adapter.str.placementCodeSet['bar'] = {}; // respond diff --git a/test/spec/adapters/smartadserver_spec.js b/test/spec/modules/smartadserverBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/smartadserver_spec.js rename to test/spec/modules/smartadserverBidAdapter_spec.js index 9f0b736d2d5..85d345da368 100644 --- a/test/spec/adapters/smartadserver_spec.js +++ b/test/spec/modules/smartadserverBidAdapter_spec.js @@ -1,7 +1,7 @@ describe('smartadserver adapter tests', function () { var urlParse = require('url-parse'); var querystringify = require('querystringify'); - var adapter = require('src/adapters/smartadserver'); + var adapter = require('modules/smartadserverBidAdapter'); var adLoader = require('src/adloader'); var expect = require('chai').expect; var bidmanager = require('src/bidmanager'); diff --git a/test/spec/adapters/smartyads_spec.js b/test/spec/modules/smartyadsBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/smartyads_spec.js rename to test/spec/modules/smartyadsBidAdapter_spec.js index 7d568573646..88213504a7d 100644 --- a/test/spec/adapters/smartyads_spec.js +++ b/test/spec/modules/smartyadsBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import Adapter from '../../../src/adapters/smartyads'; +import Adapter from '../../../modules/smartyadsBidAdapter'; import adapterManager from 'src/adaptermanager'; import bidManager from 'src/bidmanager'; import CONSTANTS from 'src/constants.json'; diff --git a/test/spec/adapters/sonobi_spec.js b/test/spec/modules/sonobiBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/sonobi_spec.js rename to test/spec/modules/sonobiBidAdapter_spec.js index f5f4ab49a52..346fc18e637 100644 --- a/test/spec/adapters/sonobi_spec.js +++ b/test/spec/modules/sonobiBidAdapter_spec.js @@ -1,6 +1,6 @@ const chai = require('chai'); const expect = require('chai').expect; -const Adapter = require('src/adapters/sonobi'); +const Adapter = require('modules/sonobiBidAdapter'); const bidManager = require('src/bidmanager'); const adLoader = require('src/adloader'); const utils = require('src/utils'); diff --git a/test/spec/adapters/sovrn_spec.js b/test/spec/modules/sovrnBidAdapter_spec.js similarity index 93% rename from test/spec/adapters/sovrn_spec.js rename to test/spec/modules/sovrnBidAdapter_spec.js index ee36fee5f3b..e0be789c1bf 100644 --- a/test/spec/adapters/sovrn_spec.js +++ b/test/spec/modules/sovrnBidAdapter_spec.js @@ -1,11 +1,11 @@ describe('sovrn adapter tests', function () { const expect = require('chai').expect; - const adapter = require('src/adapters/sovrn'); + const adapter = require('modules/sovrnBidAdapter'); const bidmanager = require('src/bidmanager'); describe('sovrnResponse', function () { it('should exist and be a function', function () { - expect(pbjs.sovrnResponse).to.exist.and.to.be.a('function'); + expect($$PREBID_GLOBAL$$.sovrnResponse).to.exist.and.to.be.a('function'); }); it('should add empty bid responses if no bids returned', function () { @@ -50,11 +50,11 @@ describe('sovrn adapter tests', function () { 'seatbid': [] }; - pbjs._bidsRequested.push(bidderRequest); + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); // adapter needs to be called, in order for the stub to register. adapter() - pbjs.sovrnResponse(response); + $$PREBID_GLOBAL$$.sovrnResponse(response); var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; var bidObject1 = stubAddBidResponse.getCall(0).args[1]; @@ -133,11 +133,11 @@ describe('sovrn adapter tests', function () { } ] }; - pbjs._bidsRequested.push(bidderRequest); + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); // adapter needs to be called, in order for the stub to register. adapter() - pbjs.sovrnResponse(response); + $$PREBID_GLOBAL$$.sovrnResponse(response); var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; var bidObject1 = stubAddBidResponse.getCall(0).args[1]; diff --git a/test/spec/adapters/stickyadstv_spec.js b/test/spec/modules/stickyadstvBidAdapter_spec.js similarity index 97% rename from test/spec/adapters/stickyadstv_spec.js rename to test/spec/modules/stickyadstvBidAdapter_spec.js index 96a589ea07d..276b8d4fb96 100644 --- a/test/spec/adapters/stickyadstv_spec.js +++ b/test/spec/modules/stickyadstvBidAdapter_spec.js @@ -1,7 +1,6 @@ import {expect} from 'chai'; import {assert} from 'chai'; -import Adapter from '../../../src/adapters/stickyadstv'; -import bidManager from '../../../src/bidmanager'; +import Adapter from '../../../modules/stickyadstvBidAdapter'; import adLoader from '../../../src/adloader'; describe('StickyAdsTV Adapter', function () { @@ -49,13 +48,13 @@ describe('StickyAdsTV Adapter', function () { beforeEach(function () { adapter = new Adapter(); sandbox = sinon.sandbox.create(); - bidsRequestBuff = pbjs._bidsRequested; - pbjs._bidsRequested = []; + bidsRequestBuff = $$PREBID_GLOBAL$$._bidsRequested; + $$PREBID_GLOBAL$$._bidsRequested = []; }); afterEach(function () { sandbox.restore(); - pbjs._bidsRequested = bidsRequestBuff; + $$PREBID_GLOBAL$$._bidsRequested = bidsRequestBuff; }); describe('callBids', function () { diff --git a/test/spec/adapters/tapsense_spec.js b/test/spec/modules/tapsenseBidAdapter_spec.js similarity index 94% rename from test/spec/adapters/tapsense_spec.js rename to test/spec/modules/tapsenseBidAdapter_spec.js index 162a8307443..997f0ca6c6e 100644 --- a/test/spec/adapters/tapsense_spec.js +++ b/test/spec/modules/tapsenseBidAdapter_spec.js @@ -1,11 +1,9 @@ import { expect } from 'chai'; -import Adapter from 'src/adapters/tapsense'; +import Adapter from 'modules/tapsenseBidAdapter'; import bidmanager from 'src/bidmanager'; import adloader from 'src/adloader'; import * as utils from 'src/utils'; -window.pbjs = window.pbjs || {}; - const DEFAULT_BIDDER_REQUEST = { 'bidderCode': 'tapsense', 'bidderRequestId': '141ed07a281ca3', @@ -31,7 +29,7 @@ const DEFAULT_BIDDER_REQUEST = { } } ] -} +}; const SUCCESSFUL_RESPONSE = { 'count_ad_units': 1, @@ -202,7 +200,7 @@ describe('TapSenseAdapter', () => { }); it('generates callback in namespaced object with correct bidder id', () => { makeSuccessfulRequest(adapter); - expect(pbjs.tapsense.callback_with_price_2b211418dd0575).to.exist.and.to.be.a('function'); + expect($$PREBID_GLOBAL$$.tapsense.callback_with_price_2b211418dd0575).to.exist.and.to.be.a('function'); }) }); @@ -220,7 +218,7 @@ describe('TapSenseAdapter', () => { }); describe('successful response', () => { beforeEach(() => { - pbjs.tapsense.callback_with_price_2b211418dd0575(SUCCESSFUL_RESPONSE, 1.2); + $$PREBID_GLOBAL$$.tapsense.callback_with_price_2b211418dd0575(SUCCESSFUL_RESPONSE, 1.2); }); it('called the bidmanager and registers a bid', () => { sinon.assert.calledOnce(bidmanager.addBidResponse); @@ -233,7 +231,7 @@ describe('TapSenseAdapter', () => { }); describe('unsuccessful response', () => { beforeEach(() => { - pbjs.tapsense.callback_with_price_2b211418dd0575(UNSUCCESSFUL_RESPONSE, 1.2); + $$PREBID_GLOBAL$$.tapsense.callback_with_price_2b211418dd0575(UNSUCCESSFUL_RESPONSE, 1.2); }) it('should call the bidmanger and register an invalid bid', () => { sinon.assert.calledOnce(bidmanager.addBidResponse); @@ -251,7 +249,7 @@ describe('TapSenseAdapter', () => { describe('edge cases', () => { it('does not register a bid if no price is supplied', () => { sandbox.stub(utils, 'logMessage'); - pbjs.tapsense.callback_with_price_2b211418dd0575(SUCCESSFUL_RESPONSE); + $$PREBID_GLOBAL$$.tapsense.callback_with_price_2b211418dd0575(SUCCESSFUL_RESPONSE); sinon.assert.notCalled(bidmanager.addBidResponse); }); }); diff --git a/test/spec/adapters/thoughtleadr_spec.js b/test/spec/modules/thoughtleadrBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/thoughtleadr_spec.js rename to test/spec/modules/thoughtleadrBidAdapter_spec.js index 7fa6703ae10..43c13ebc21f 100644 --- a/test/spec/adapters/thoughtleadr_spec.js +++ b/test/spec/modules/thoughtleadrBidAdapter_spec.js @@ -1,6 +1,6 @@ 'use strict'; var chai_1 = require('chai'); -var ta = require('../../../src/adapters/thoughtleadr'); +var ta = require('../../../modules/thoughtleadrBidAdapter'); var adloader = require('../../../src/adloader'); var bidfactory = require('../../../src/bidfactory'); var Adapter = ta; diff --git a/test/spec/adapters/trion_spec.js b/test/spec/modules/trionBidAdapter_spec.js similarity index 89% rename from test/spec/adapters/trion_spec.js rename to test/spec/modules/trionBidAdapter_spec.js index dbbcf66ec87..50988c564ec 100644 --- a/test/spec/adapters/trion_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import trionAdapter from 'src/adapters/trion'; +import trionAdapter from 'modules/trionBidAdapter'; import bidmanager from 'src/bidmanager'; import * as utils from 'src/utils'; const CONSTANTS = require('src/constants.json'); @@ -198,8 +198,8 @@ describe('Trion adapter tests', () => { }); it('when there is no response do not bid', function () { - pbjs._bidsRequested.push(TRION_BID_REQUEST); - pbjs.handleTrionCB(); + $$PREBID_GLOBAL$$._bidsRequested.push(TRION_BID_REQUEST); + $$PREBID_GLOBAL$$.handleTrionCB(); sinon.assert.calledOnce(bidmanager.addBidResponse); const response = bidmanager.addBidResponse.firstCall.args[1]; expect(response.getStatusCode()).to.equal(CONSTANTS.STATUS.NO_BID); @@ -207,8 +207,8 @@ describe('Trion adapter tests', () => { it('when place bid is returned as false', function () { TRION_BID_RESPONSE.result.placeBid = false; - pbjs._bidsRequested.push(TRION_BID_REQUEST); - pbjs.handleTrionCB(TRION_BID_RESPONSE); + $$PREBID_GLOBAL$$._bidsRequested.push(TRION_BID_REQUEST); + $$PREBID_GLOBAL$$.handleTrionCB(TRION_BID_RESPONSE); sinon.assert.calledOnce(bidmanager.addBidResponse); const response = bidmanager.addBidResponse.firstCall.args[1]; expect(response.getStatusCode()).to.equal(CONSTANTS.STATUS.NO_BID); @@ -217,8 +217,8 @@ describe('Trion adapter tests', () => { it('when no cpm is in the response', function () { TRION_BID_RESPONSE.result.cpm = 0; - pbjs._bidsRequested.push(TRION_BID_REQUEST); - pbjs.handleTrionCB(TRION_BID_RESPONSE); + $$PREBID_GLOBAL$$._bidsRequested.push(TRION_BID_REQUEST); + $$PREBID_GLOBAL$$.handleTrionCB(TRION_BID_RESPONSE); sinon.assert.calledOnce(bidmanager.addBidResponse); const response = bidmanager.addBidResponse.firstCall.args[1]; expect(response.getStatusCode()).to.equal(CONSTANTS.STATUS.NO_BID); @@ -227,8 +227,8 @@ describe('Trion adapter tests', () => { it('when no ad is in the response', function () { TRION_BID_RESPONSE.result.ad = null; - pbjs._bidsRequested.push(TRION_BID_REQUEST); - pbjs.handleTrionCB(TRION_BID_RESPONSE); + $$PREBID_GLOBAL$$._bidsRequested.push(TRION_BID_REQUEST); + $$PREBID_GLOBAL$$.handleTrionCB(TRION_BID_RESPONSE); sinon.assert.calledOnce(bidmanager.addBidResponse); const response = bidmanager.addBidResponse.firstCall.args[1]; expect(response.getStatusCode()).to.equal(CONSTANTS.STATUS.NO_BID); @@ -236,8 +236,8 @@ describe('Trion adapter tests', () => { }); it('bid response is formatted correctly', function () { - pbjs._bidsRequested.push(TRION_BID_REQUEST); - pbjs.handleTrionCB(TRION_BID_RESPONSE); + $$PREBID_GLOBAL$$._bidsRequested.push(TRION_BID_REQUEST); + $$PREBID_GLOBAL$$.handleTrionCB(TRION_BID_RESPONSE); const placementCode = bidmanager.addBidResponse.firstCall.args[0]; const response = bidmanager.addBidResponse.firstCall.args[1]; expect(placementCode).to.equal(PLACEMENT_CODE); @@ -250,8 +250,8 @@ describe('Trion adapter tests', () => { let bidHeight = '2'; TRION_BID_RESPONSE.result.width = bidWidth; TRION_BID_RESPONSE.result.height = bidHeight; - pbjs._bidsRequested.push(TRION_BID_REQUEST); - pbjs.handleTrionCB(TRION_BID_RESPONSE); + $$PREBID_GLOBAL$$._bidsRequested.push(TRION_BID_REQUEST); + $$PREBID_GLOBAL$$.handleTrionCB(TRION_BID_RESPONSE); const placementCode = bidmanager.addBidResponse.firstCall.args[0]; const response = bidmanager.addBidResponse.firstCall.args[1]; expect(response.width).to.equal(bidWidth); @@ -263,8 +263,8 @@ describe('Trion adapter tests', () => { it('cpm is properly set and transformed to cents', function () { let bidCpm = 2; TRION_BID_RESPONSE.result.cpm = bidCpm * 100; - pbjs._bidsRequested.push(TRION_BID_REQUEST); - pbjs.handleTrionCB(TRION_BID_RESPONSE); + $$PREBID_GLOBAL$$._bidsRequested.push(TRION_BID_REQUEST); + $$PREBID_GLOBAL$$.handleTrionCB(TRION_BID_RESPONSE); const response = bidmanager.addBidResponse.firstCall.args[1]; expect(response.cpm).to.equal(bidCpm); TRION_BID_RESPONSE.result.cpm = 100; diff --git a/test/spec/adapters/triplelift_spec.js b/test/spec/modules/tripleliftBidAdapter_spec.js similarity index 89% rename from test/spec/adapters/triplelift_spec.js rename to test/spec/modules/tripleliftBidAdapter_spec.js index cae78d95e30..95658883fd0 100644 --- a/test/spec/adapters/triplelift_spec.js +++ b/test/spec/modules/tripleliftBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import Adapter from '../../../src/adapters/triplelift'; +import Adapter from '../../../modules/tripleliftBidAdapter'; import bidManager from '../../../src/bidmanager'; import adLoader from '../../../src/adloader'; import {parse as parseURL} from '../../../src/url'; @@ -35,8 +35,8 @@ describe('triplelift adapter', () => { }; beforeEach(() => { - bidsRequestedOriginal = pbjs._bidsRequested; - pbjs._bidsRequested = []; + bidsRequestedOriginal = $$PREBID_GLOBAL$$._bidsRequested; + $$PREBID_GLOBAL$$._bidsRequested = []; adapter = new Adapter(); sandbox = sinon.sandbox.create(); @@ -45,7 +45,7 @@ describe('triplelift adapter', () => { afterEach(() => { sandbox.restore(); - pbjs._bidsRequested = bidsRequestedOriginal; + $$PREBID_GLOBAL$$._bidsRequested = bidsRequestedOriginal; }); describe('callBids', () => { @@ -68,14 +68,14 @@ describe('triplelift adapter', () => { expect(secondBidScriptURL).to.contain(route); let firstScriptParams = parseURL(firstBidScriptURL).search; - expect(firstScriptParams).to.have.property('callback', 'pbjs.TLCB'); + expect(firstScriptParams).to.have.property('callback', '$$PREBID_GLOBAL$$.TLCB'); expect(firstScriptParams).to.have.property('callback_id', 'bidId1'); expect(firstScriptParams).to.have.property('inv_code', 'codeA'); expect(firstScriptParams).to.have.property('size', '728x90'); expect(firstScriptParams).to.have.property('referrer'); let secondScriptParams = parseURL(secondBidScriptURL).search; - expect(secondScriptParams).to.have.property('callback', 'pbjs.TLCB'); + expect(secondScriptParams).to.have.property('callback', '$$PREBID_GLOBAL$$.TLCB'); expect(secondScriptParams).to.have.property('callback_id', 'bidId2'); expect(secondScriptParams).to.have.property('inv_code', 'codeB'); expect(secondScriptParams).to.have.property('size', '300x600'); @@ -86,7 +86,7 @@ describe('triplelift adapter', () => { describe('TLCB', () => { it('should exist and be a function', () => { - expect(pbjs.TLCB).to.exist.and.to.be.a('function'); + expect($$PREBID_GLOBAL$$.TLCB).to.exist.and.to.be.a('function'); }); }); @@ -97,7 +97,7 @@ describe('triplelift adapter', () => { beforeEach(() => { sandbox.stub(bidManager, 'addBidResponse'); - pbjs._bidsRequested.push(bidderRequest); + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); // respond let bidderReponse1 = { @@ -119,8 +119,8 @@ describe('triplelift adapter', () => { 'deal_id': 'dealA' }; - pbjs.TLCB(bidderReponse1); - pbjs.TLCB(bidderReponse2); + $$PREBID_GLOBAL$$.TLCB(bidderReponse1); + $$PREBID_GLOBAL$$.TLCB(bidderReponse2); firstBid = bidManager.addBidResponse.firstCall.args[1]; secondBid = bidManager.addBidResponse.secondCall.args[1]; @@ -183,14 +183,14 @@ describe('triplelift adapter', () => { beforeEach(() => { sandbox.stub(bidManager, 'addBidResponse'); - pbjs._bidsRequested.push(bidderRequest); + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); // respond let bidderReponse1 = {'status': 'no_bid', 'callback_id': 'bidId1'}; let bidderReponse2 = {'status': 'no_bid', 'callback_id': 'bidId2'}; - pbjs.TLCB(bidderReponse1); - pbjs.TLCB(bidderReponse2); + $$PREBID_GLOBAL$$.TLCB(bidderReponse1); + $$PREBID_GLOBAL$$.TLCB(bidderReponse2); firstBid = bidManager.addBidResponse.firstCall.args[1]; secondBid = bidManager.addBidResponse.secondCall.args[1]; diff --git a/test/spec/adapters/twenga_spec.js b/test/spec/modules/twengaBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/twenga_spec.js rename to test/spec/modules/twengaBidAdapter_spec.js index 9bbeb4c1d7b..d5dd92fd0a6 100644 --- a/test/spec/adapters/twenga_spec.js +++ b/test/spec/modules/twengaBidAdapter_spec.js @@ -1,7 +1,7 @@ describe('twenga adapter tests', function () { var urlParse = require('url-parse'); var querystringify = require('querystringify'); - var adapter = require('src/adapters/twenga'); + var adapter = require('modules/twengaBidAdapter'); var adLoader = require('src/adloader'); var expect = require('chai').expect; var bidmanager = require('src/bidmanager'); diff --git a/test/spec/adapters/underdogmedia_spec.js b/test/spec/modules/underdogmediaBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/underdogmedia_spec.js rename to test/spec/modules/underdogmediaBidAdapter_spec.js index 25842034bee..c93246eab4c 100644 --- a/test/spec/adapters/underdogmedia_spec.js +++ b/test/spec/modules/underdogmediaBidAdapter_spec.js @@ -1,4 +1,4 @@ -import Adapter from '../../../src/adapters/underdogmedia'; +import Adapter from '../../../modules/underdogmediaBidAdapter'; import bidManager from '../../../src/bidmanager'; import adloader from '../../../src/adloader'; diff --git a/test/spec/adapters/unruly_spec.js b/test/spec/modules/unrulyBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/unruly_spec.js rename to test/spec/modules/unrulyBidAdapter_spec.js index de0aa683bc9..dfa7a72b8ad 100644 --- a/test/spec/adapters/unruly_spec.js +++ b/test/spec/modules/unrulyBidAdapter_spec.js @@ -5,7 +5,7 @@ import bidmanager from 'src/bidmanager' import * as utils from 'src/utils' import { STATUS } from 'src/constants' import { Renderer } from 'src/Renderer' -import createUnrulyAdapter from 'src/adapters/unruly' +import createUnrulyAdapter from 'modules/unrulyBidAdapter' describe('UnrulyAdapter', () => { function createBidRequestBid({ placementCode }) { diff --git a/test/spec/adapters/vertamedia_spec.js b/test/spec/modules/vertamediaBidAdapter_spec.js similarity index 98% rename from test/spec/adapters/vertamedia_spec.js rename to test/spec/modules/vertamediaBidAdapter_spec.js index c96103ce61f..ebcd439a124 100644 --- a/test/spec/adapters/vertamedia_spec.js +++ b/test/spec/modules/vertamediaBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import Adapter from 'src/adapters/vertamedia'; +import Adapter from 'modules/vertamediaBidAdapter'; import bidmanager from 'src/bidmanager'; const ENDPOINT = 'http://rtb.vertamedia.com/hb/?aid=22489&w=640&h=480&domain=localhost'; diff --git a/test/spec/adapters/vertoz_spec.js b/test/spec/modules/vertozBidAdapter_spec.js similarity index 89% rename from test/spec/adapters/vertoz_spec.js rename to test/spec/modules/vertozBidAdapter_spec.js index b3881091df4..e882c901c75 100755 --- a/test/spec/adapters/vertoz_spec.js +++ b/test/spec/modules/vertozBidAdapter_spec.js @@ -1,6 +1,6 @@ import {expect} from 'chai'; import {assert} from 'chai'; -import Adapter from '../../../src/adapters/vertoz'; +import Adapter from '../../../modules/vertozBidAdapter'; import bidManager from '../../../src/bidmanager'; import adLoader from '../../../src/adloader'; @@ -46,13 +46,13 @@ describe('Vertoz Adapter', () => { beforeEach(() => { adapter = new Adapter(); sandbox = sinon.sandbox.create(); - bidsRequestBuff = pbjs._bidsRequested; - pbjs._bidsRequested = []; + bidsRequestBuff = $$PREBID_GLOBAL$$._bidsRequested; + $$PREBID_GLOBAL$$._bidsRequested = []; }); afterEach(() => { sandbox.restore(); - pbjs._bidsRequested = bidsRequestBuff; + $$PREBID_GLOBAL$$._bidsRequested = bidsRequestBuff; }); describe('callBids', () => { @@ -81,7 +81,7 @@ describe('Vertoz Adapter', () => { }; beforeEach(() => { - pbjs._bidsRequested.push(bidderRequest); + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); }); describe('success', () => { @@ -90,7 +90,7 @@ describe('Vertoz Adapter', () => { beforeEach(() => { sandbox.stub(bidManager, 'addBidResponse'); - pbjs.vzResponse(bidderReponse); + $$PREBID_GLOBAL$$.vzResponse(bidderReponse); firstBidReg = bidManager.addBidResponse.firstCall.args[1]; adSpaceId = bidManager.addBidResponse.firstCall.args[0]; }); @@ -121,7 +121,7 @@ describe('Vertoz Adapter', () => { beforeEach(() => { sandbox.stub(bidManager, 'addBidResponse'); - pbjs.vzResponse(bidderResponse); + $$PREBID_GLOBAL$$.vzResponse(bidderResponse); secondBidReg = bidManager.addBidResponse.firstCall.args[1]; adSpaceId = bidManager.addBidResponse.firstCall.args[0]; }); diff --git a/test/spec/adapters/wideorbit_spec.js b/test/spec/modules/wideorbitBidAdapter_spec.js similarity index 99% rename from test/spec/adapters/wideorbit_spec.js rename to test/spec/modules/wideorbitBidAdapter_spec.js index c2b8d416e1e..b524632597b 100644 --- a/test/spec/adapters/wideorbit_spec.js +++ b/test/spec/modules/wideorbitBidAdapter_spec.js @@ -5,7 +5,7 @@ describe('wideorbit adapter tests', function () { // FYI: querystringify will perform encoding/decoding var querystringify = require('querystringify'); - var adapter = require('src/adapters/wideorbit'); + var adapter = require('modules/wideorbitBidAdapter'); var adLoader = require('src/adloader'); var bidmanager = require('src/bidmanager'); diff --git a/test/spec/adapters/widespace_spec.js b/test/spec/modules/widespaceBidAdapter_spec.js similarity index 92% rename from test/spec/adapters/widespace_spec.js rename to test/spec/modules/widespaceBidAdapter_spec.js index 95f4a16458c..651d22b4606 100644 --- a/test/spec/adapters/widespace_spec.js +++ b/test/spec/modules/widespaceBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; import adLoader from '../../../src/adloader'; import bidManager from '../../../src/bidmanager'; -import Adapter from '../../../src/adapters/widespace'; +import Adapter from '../../../modules/widespaceBidAdapter'; const ENDPOINT = '//engine.widespace.com/map/engine/hb/dynamic'; @@ -118,7 +118,7 @@ describe('WidespaceAdapter', () => { describe('widespaceHandleCB', () => { it('should exist and be a function', () => { - expect(pbjs.widespaceHandleCB).to.exist.and.to.be.a('function'); + expect($$PREBID_GLOBAL$$.widespaceHandleCB).to.exist.and.to.be.a('function'); }); }); @@ -131,8 +131,8 @@ describe('WidespaceAdapter', () => { sandbox.stub(adLoader, 'loadScript'); adapter.callBids(BID_REQUEST); - pbjs._bidsRequested.push(BID_REQUEST); - pbjs.widespaceHandleCB(BID_RESPONSE); + $$PREBID_GLOBAL$$._bidsRequested.push(BID_REQUEST); + $$PREBID_GLOBAL$$.widespaceHandleCB(BID_RESPONSE); successfulBid = bidManager.addBidResponse.firstCall.args[1]; placementCode = bidManager.addBidResponse.firstCall.args[0]; @@ -168,8 +168,8 @@ describe('WidespaceAdapter', () => { sandbox.stub(adLoader, 'loadScript'); adapter.callBids(BID_REQUEST); - pbjs._bidsRequested.push(BID_REQUEST); - pbjs.widespaceHandleCB(BID_NOAD_RESPONSE); + $$PREBID_GLOBAL$$._bidsRequested.push(BID_REQUEST); + $$PREBID_GLOBAL$$.widespaceHandleCB(BID_NOAD_RESPONSE); noadBid = bidManager.addBidResponse.firstCall.args[1]; }); diff --git a/test/spec/adapters/yieldbot_spec.js b/test/spec/modules/yieldbotBidAdapter_spec.js similarity index 93% rename from test/spec/adapters/yieldbot_spec.js rename to test/spec/modules/yieldbotBidAdapter_spec.js index 3a8f52ca05e..400aa409a4a 100644 --- a/test/spec/adapters/yieldbot_spec.js +++ b/test/spec/modules/yieldbotBidAdapter_spec.js @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import YieldbotAdapter from 'src/adapters/yieldbot'; +import YieldbotAdapter from 'modules/yieldbotBidAdapter'; import bidManager from 'src/bidmanager'; import adLoader from 'src/adloader'; @@ -71,8 +71,8 @@ let sandbox; let bidManagerStub; let yieldbotLibStub; -before(function() { - window.pbjs._bidsRequested.push(bidderRequest); +beforeEach(function() { + window.$$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); }); describe('Yieldbot adapter tests', function() { @@ -184,7 +184,7 @@ describe('Yieldbot adapter tests', function() { expect(window.yieldbot._initialized).to.equal(true); - window.pbjs._bidsRequested = window.pbjs._bidsRequested.filter(o => { + window.$$PREBID_GLOBAL$$._bidsRequested = window.$$PREBID_GLOBAL$$._bidsRequested.filter(o => { return o.bidderCode !== 'yieldbot'; }); @@ -194,7 +194,7 @@ describe('Yieldbot adapter tests', function() { }); it('should not add empty bidResponse on callBids without bidsRequested', function() { - window.pbjs._bidsRequested = window.pbjs._bidsRequested.filter(o => { + window.$$PREBID_GLOBAL$$._bidsRequested = window.$$PREBID_GLOBAL$$._bidsRequested.filter(o => { return o.bidderCode !== 'yieldbot'; }); @@ -202,7 +202,7 @@ describe('Yieldbot adapter tests', function() { adapter.callBids(bidderRequest); mockYieldbotInitBidRequest(); - let bidResponses = window.pbjs._bidsReceived.filter(o => { + let bidResponses = window.$$PREBID_GLOBAL$$._bidsReceived.filter(o => { return o.bidderCode === 'yieldbot'; }); diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index 95aed3b396f..d4a0f5a5fa0 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -23,6 +23,10 @@ var events = require('src/events'); var adserver = require('src/adserver'); var CONSTANTS = require('src/constants.json'); +// These bid adapters are required to be loaded for the following tests to work +require('modules/appnexusAstBidAdapter'); +require('modules/adequantBidAdapter'); + var config = require('test/fixtures/config.json'); $$PREBID_GLOBAL$$ = $$PREBID_GLOBAL$$ || {}; diff --git a/webpack.conf.js b/webpack.conf.js index 60aed503740..52fc3ff923c 100644 --- a/webpack.conf.js +++ b/webpack.conf.js @@ -1,25 +1,46 @@ var prebid = require('./package.json'); var StringReplacePlugin = require('string-replace-webpack-plugin'); var path = require('path'); +var webpack = require('webpack'); +var helpers = require('./gulpHelpers'); +var RequireEnsureWithoutJsonp = require('./plugins/RequireEnsureWithoutJsonp.js'); + +// list of module names to never include in the common bundle chunk +var neverBundle = [ + 'AnalyticsAdapter.js' +]; module.exports = { - output: { - filename: 'prebid.js' - }, devtool: 'source-map', resolve: { - modulesDirectories: ['', 'node_modules', 'src'] + root: [ + path.resolve('.') + ], + modulesDirectories: ['', 'node_modules'] }, resolveLoader: { - modulesDirectories: ['loaders', 'node_modules'] + root: [ + path.resolve('./loaders'), + path.resolve('./node_modules') + ] + }, + output: { + jsonpFunction: 'pbjsChunk' }, module: { loaders: [ { test: /\.js$/, - include: /(src|test)/, - exclude: path.resolve(__dirname, 'node_modules'), - loader: 'babel', // 'babel-loader' is also a legal name to reference + exclude: path.resolve('./node_modules'), // required to prevent loader from choking non-Prebid.js node_modules + loader: 'babel', + query: { + presets: ['es2015'] + } + }, + { // This makes sure babel-loader is ran on our intended Prebid.js modules that happen to be in node_modules + test: /\.js$/, + include: helpers.getArgModules().map(module => new RegExp('node_modules/' + module + '/')), + loader: 'babel', query: { presets: ['es2015'] } @@ -28,21 +49,6 @@ module.exports = { test: /\.json$/, loader: 'json' }, - { - test: /adaptermanager.js/, - include: /(src)/, - loader: 'analyticsLoader' - }, - { - test: /adaptermanager.js/, - include: /(src)/, - loader: 'adapterLoader' - }, - { - test: /native.js/, - include: /(src)/, - loader: 'nativeLoader' - }, { test: /constants.json$/, include: /(src)/, @@ -59,7 +65,7 @@ module.exports = { }, { test: /\.js$/, - include: /(src|test|integrationExamples)/, + include: /(src|test|modules|integrationExamples)/, loader: StringReplacePlugin.replace({ replacements: [ { @@ -74,6 +80,16 @@ module.exports = { ] }, plugins: [ - new StringReplacePlugin() + new StringReplacePlugin(), + new RequireEnsureWithoutJsonp(), + + // this plugin must be last so it can be easily removed for karma unit tests + new webpack.optimize.CommonsChunkPlugin({ + name: 'prebid', + filename: 'prebid-core.js', + minChunks: function(module, count) { + return !(count < 2 || neverBundle.includes(path.basename(module.resource))) + } + }) ] }; diff --git a/yarn.lock b/yarn.lock index f47012ba413..2ea12377d1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,27 @@ # yarn lockfile v1 +"@gulp-sourcemaps/identity-map@1.X": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/identity-map/-/identity-map-1.0.1.tgz#cfa23bc5840f9104ce32a65e74db7e7a974bbee1" + dependencies: + acorn "^5.0.3" + css "^2.2.1" + normalize-path "^2.1.1" + source-map "^0.5.6" + through2 "^2.0.3" + +"@gulp-sourcemaps/map-sources@1.X": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz#890ae7c5d8c877f6d384860215ace9d7ec945bda" + dependencies: + normalize-path "^2.0.1" + through2 "^2.0.3" + +"JSV@>= 4.0.x": + version "4.0.2" + resolved "https://registry.yarnpkg.com/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57" + abbrev@1, abbrev@1.0.x: version "1.0.9" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" @@ -26,15 +47,15 @@ acorn-jsx@^3.0.0: dependencies: acorn "^3.0.4" +acorn@4.X, acorn@^4.0.3: + version "4.0.13" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" + acorn@^3.0.0, acorn@^3.0.4, acorn@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" -acorn@^4.0.3: - version "4.0.11" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.11.tgz#edcda3bd937e7556410d42ed5860f67399c794c0" - -acorn@^5.0.1: +acorn@^5.0.1, acorn@^5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d" @@ -47,8 +68,8 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" agent-base@2: - version "2.0.1" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.0.1.tgz#bd8f9e86a8eb221fffa07bd14befd55df142815e" + version "2.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7" dependencies: extend "~3.0.0" semver "~5.0.1" @@ -119,6 +140,10 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" +ansi-styles@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" + anymatch@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" @@ -138,8 +163,8 @@ app-usage-stats@^0.4.0: usage-stats "^0.8.2" aproba@^1.0.3: - version "1.1.1" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.1.tgz#95d3600f07710aa0e9298c726ad5ecf2eacbabab" + version "1.1.2" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.2.tgz#45c6629094de4e96f693ef7eab74ae079c240fc1" archiver@~0.14.0, archiver@~0.14.3: version "0.14.4" @@ -165,7 +190,7 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" -argparse@^1.0.7: +argparse@^1.0.2, argparse@^1.0.7: version "1.0.9" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" dependencies: @@ -294,18 +319,18 @@ ast-types@0.8.12: version "0.8.12" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.12.tgz#a0d90e4351bb887716c83fd637ebf818af4adfcc" -ast-types@0.9.6: +ast-types@0.9.6, ast-types@0.x.x: version "0.9.6" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9" -ast-types@0.x.x: - version "0.9.11" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.11.tgz#371177bb59232ff5ceaa1d09ee5cad705b1a5aa9" - async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" +async@0.2.x, async@~0.2.10, async@~0.2.6, async@~0.2.9: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + async@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/async/-/async-0.9.0.tgz#ac3613b1da9bed1b47510bb4651b8931e47146c7" @@ -319,15 +344,11 @@ async@^0.9.0, async@~0.9.0: resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" async@^2.0.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.4.0.tgz#4990200f18ea5b837c2cc4f8c031a6985c385611" + version "2.4.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.4.1.tgz#62a56b279c98a11d0987096a01cc3eeb8eb7bbd7" dependencies: lodash "^4.14.0" -async@~0.2.10, async@~0.2.6: - version "0.2.10" - resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" - async@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" @@ -408,6 +429,57 @@ babel-core@^6.24.1: slash "^1.0.0" source-map "^0.5.0" +babel-core@~5.8.3: + version "5.8.38" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-5.8.38.tgz#1fcaee79d7e61b750b00b8e54f6dfc9d0af86558" + dependencies: + babel-plugin-constant-folding "^1.0.1" + babel-plugin-dead-code-elimination "^1.0.2" + babel-plugin-eval "^1.0.1" + babel-plugin-inline-environment-variables "^1.0.1" + babel-plugin-jscript "^1.0.4" + babel-plugin-member-expression-literals "^1.0.1" + babel-plugin-property-literals "^1.0.1" + babel-plugin-proto-to-assign "^1.0.3" + babel-plugin-react-constant-elements "^1.0.3" + babel-plugin-react-display-name "^1.0.3" + babel-plugin-remove-console "^1.0.1" + babel-plugin-remove-debugger "^1.0.1" + babel-plugin-runtime "^1.0.7" + babel-plugin-undeclared-variables-check "^1.0.2" + babel-plugin-undefined-to-void "^1.1.6" + babylon "^5.8.38" + bluebird "^2.9.33" + chalk "^1.0.0" + convert-source-map "^1.1.0" + core-js "^1.0.0" + debug "^2.1.1" + detect-indent "^3.0.0" + esutils "^2.0.0" + fs-readdir-recursive "^0.1.0" + globals "^6.4.0" + home-or-tmp "^1.0.0" + is-integer "^1.0.4" + js-tokens "1.0.1" + json5 "^0.4.0" + lodash "^3.10.0" + minimatch "^2.0.3" + output-file-sync "^1.1.0" + path-exists "^1.0.0" + path-is-absolute "^1.0.0" + private "^0.1.6" + regenerator "0.8.40" + regexpu "^1.3.0" + repeating "^1.1.2" + resolve "^1.1.6" + shebang-regex "^1.0.0" + slash "^1.0.0" + source-map "^0.5.0" + source-map-support "^0.2.10" + to-fast-properties "^1.0.0" + trim-right "^1.0.0" + try-resolve "^1.0.0" + babel-generator@^6.22.0, babel-generator@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.1.tgz#e715f486c58ded25649d888944d52aa07c5d9497" @@ -496,6 +568,13 @@ babel-helpers@^6.22.0, babel-helpers@^6.24.1: babel-runtime "^6.22.0" babel-template "^6.24.1" +babel-jscs@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/babel-jscs/-/babel-jscs-2.0.5.tgz#0a347046b48145acbca56e8c8ed5f736bc54f9d0" + dependencies: + babel-core "~5.8.3" + lodash.assign "^3.2.0" + babel-loader@6.4.1: version "6.4.1" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.4.1.tgz#0b34112d5b0748a8dcdbf51acf6f9bd42d50b8ca" @@ -517,6 +596,60 @@ babel-plugin-check-es2015-constants@^6.22.0: dependencies: babel-runtime "^6.22.0" +babel-plugin-constant-folding@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-constant-folding/-/babel-plugin-constant-folding-1.0.1.tgz#8361d364c98e449c3692bdba51eff0844290aa8e" + +babel-plugin-dead-code-elimination@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-dead-code-elimination/-/babel-plugin-dead-code-elimination-1.0.2.tgz#5f7c451274dcd7cccdbfbb3e0b85dd28121f0f65" + +babel-plugin-eval@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-eval/-/babel-plugin-eval-1.0.1.tgz#a2faed25ce6be69ade4bfec263f70169195950da" + +babel-plugin-inline-environment-variables@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-inline-environment-variables/-/babel-plugin-inline-environment-variables-1.0.1.tgz#1f58ce91207ad6a826a8bf645fafe68ff5fe3ffe" + +babel-plugin-jscript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/babel-plugin-jscript/-/babel-plugin-jscript-1.0.4.tgz#8f342c38276e87a47d5fa0a8bd3d5eb6ccad8fcc" + +babel-plugin-member-expression-literals@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-member-expression-literals/-/babel-plugin-member-expression-literals-1.0.1.tgz#cc5edb0faa8dc927170e74d6d1c02440021624d3" + +babel-plugin-property-literals@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-property-literals/-/babel-plugin-property-literals-1.0.1.tgz#0252301900192980b1c118efea48ce93aab83336" + +babel-plugin-proto-to-assign@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/babel-plugin-proto-to-assign/-/babel-plugin-proto-to-assign-1.0.4.tgz#c49e7afd02f577bc4da05ea2df002250cf7cd123" + dependencies: + lodash "^3.9.3" + +babel-plugin-react-constant-elements@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/babel-plugin-react-constant-elements/-/babel-plugin-react-constant-elements-1.0.3.tgz#946736e8378429cbc349dcff62f51c143b34e35a" + +babel-plugin-react-display-name@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/babel-plugin-react-display-name/-/babel-plugin-react-display-name-1.0.3.tgz#754fe38926e8424a4e7b15ab6ea6139dee0514fc" + +babel-plugin-remove-console@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-remove-console/-/babel-plugin-remove-console-1.0.1.tgz#d8f24556c3a05005d42aaaafd27787f53ff013a7" + +babel-plugin-remove-debugger@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-remove-debugger/-/babel-plugin-remove-debugger-1.0.1.tgz#fd2ea3cd61a428ad1f3b9c89882ff4293e8c14c7" + +babel-plugin-runtime@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/babel-plugin-runtime/-/babel-plugin-runtime-1.0.7.tgz#bf7c7d966dd56ecd5c17fa1cb253c9acb7e54aaf" + babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" @@ -716,6 +849,16 @@ babel-plugin-transform-strict-mode@^6.24.1: babel-runtime "^6.22.0" babel-types "^6.24.1" +babel-plugin-undeclared-variables-check@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-undeclared-variables-check/-/babel-plugin-undeclared-variables-check-1.0.2.tgz#5cf1aa539d813ff64e99641290af620965f65dee" + dependencies: + leven "^1.0.2" + +babel-plugin-undefined-to-void@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/babel-plugin-undefined-to-void/-/babel-plugin-undefined-to-void-1.1.6.tgz#7f578ef8b78dfae6003385d8417a61eda06e2f81" + babel-polyfill@^6.13.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" @@ -805,9 +948,13 @@ babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.24.1: lodash "^4.2.0" to-fast-properties "^1.0.1" +babylon@^5.8.38: + version "5.8.38" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-5.8.38.tgz#ec9b120b11bf6ccd4173a18bf217e60b79859ffd" + babylon@^6.11.0, babylon@^6.15.0: - version "6.17.1" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.1.tgz#17f14fddf361b695981fe679385e4f1c01ebd86f" + version "6.17.2" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.2.tgz#201d25ef5f892c41bae49488b08db0dd476e9f5c" backo2@1.0.2: version "1.0.2" @@ -906,7 +1053,7 @@ block-stream@*: dependencies: inherits "~2.0.0" -bluebird@^2.9.27, bluebird@^2.9.30: +bluebird@^2.9.27, bluebird@^2.9.30, bluebird@^2.9.33: version "2.11.0" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" @@ -915,19 +1062,19 @@ bluebird@~3.4.6: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" body-parser@^1.12.4: - version "1.17.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.1.tgz#75b3bc98ddd6e7e0d8ffe750dfaca5c66993fa47" + version "1.17.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.2.tgz#f8892abc8f9e627d42aedafbca66bf5ab99104ee" dependencies: bytes "2.4.0" content-type "~1.0.2" - debug "2.6.1" + debug "2.6.7" depd "~1.1.0" http-errors "~1.6.1" iconv-lite "0.4.15" on-finished "~2.3.0" qs "6.4.0" raw-body "~2.2.0" - type-is "~1.6.14" + type-is "~1.6.15" body-parser@~1.13.3: version "1.13.3" @@ -1028,10 +1175,6 @@ buffer-crc32@~0.2.1, buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" -buffer-shims@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" - buffer@^4.9.0: version "4.9.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" @@ -1173,7 +1316,7 @@ chalk@^0.5.0: strip-ansi "^0.3.0" supports-color "^0.2.0" -chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3, chalk@~1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -1183,6 +1326,14 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" +chalk@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" + dependencies: + ansi-styles "~1.0.0" + has-color "~0.1.0" + strip-ansi "~0.1.0" + chokidar@^1.0.0, chokidar@^1.4.1: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" @@ -1217,6 +1368,12 @@ cli-cursor@^1.0.1: dependencies: restore-cursor "^1.0.1" +cli-table@~0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" + dependencies: + colors "1.0.3" + cli-width@^1.0.1: version "1.1.1" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-1.1.1.tgz#a4d293ef67ebb7b88d4a4d42c0ccf00c4d1e366d" @@ -1310,6 +1467,14 @@ collect-json@^1.0.1, collect-json@^1.0.7, collect-json@^1.0.8: stream-connect "^1.0.2" stream-via "^1.0.3" +colors@0.6.x: + version "0.6.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc" + +colors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + colors@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" @@ -1415,12 +1580,18 @@ commander@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" -commander@2.9.0, commander@^2.5.0, commander@^2.8.1, commander@^2.9.0: +commander@2.9.0, commander@^2.5.0, commander@^2.8.1, commander@^2.9.0, commander@~2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" dependencies: graceful-readlink ">= 1.0.0" +comment-parser@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-0.3.1.tgz#fd657aac8c1492d308c9a6100fc9b49d2435aba1" + dependencies: + readable-stream "^2.0.4" + common-sequence@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/common-sequence/-/common-sequence-1.0.2.tgz#30e07f3f8f6f7f9b3dee854f20b2d39eee086de8" @@ -1569,11 +1740,11 @@ connect@^2.30.0: vhost "~3.0.1" connect@^3.3.5: - version "3.6.1" - resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.1.tgz#b7760693a74f0454face1d9378edb3f885b43227" + version "3.6.2" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.2.tgz#694e8d20681bfe490282c8ab886be98f09f42fe7" dependencies: - debug "2.6.3" - finalhandler "1.0.1" + debug "2.6.7" + finalhandler "1.0.3" parseurl "~1.3.1" utils-merge "1.0.0" @@ -1599,7 +1770,7 @@ content-type@~1.0.1, content-type@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" -convert-source-map@^1.1.0: +convert-source-map@1.X, convert-source-map@^1.1.0: version "1.5.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" @@ -1622,6 +1793,10 @@ cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + core-js@^2.0.1, core-js@^2.1.0, core-js@^2.4.0, core-js@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" @@ -1698,7 +1873,7 @@ css-value@~0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/css-value/-/css-value-0.0.1.tgz#5efd6c2eea5ea1fd6b6ac57ec0427b18452424ea" -css@^2.0.0: +css@2.X, css@^2.0.0, css@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/css/-/css-2.2.1.tgz#73a4c81de85db664d4ee674f7d47085e3b2d55dc" dependencies: @@ -1734,13 +1909,17 @@ custom-event@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" +cycle@1.0.x: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" + d@1: version "1.0.0" resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" dependencies: es5-ext "^0.10.9" -"dargs@github:christian-bromann/dargs": +dargs@christian-bromann/dargs: version "4.0.1" resolved "https://codeload.github.com/christian-bromann/dargs/tar.gz/7d6d4164a7c4106dbd14ef39ed8d95b7b5e9b770" dependencies: @@ -1784,15 +1963,22 @@ ddata@~0.1.25: string-tools "^1.0.0" test-value "^2.0.0" +debug-fabulous@0.1.X: + version "0.1.0" + resolved "https://registry.yarnpkg.com/debug-fabulous/-/debug-fabulous-0.1.0.tgz#ad0ea07a5d519324fb55842a8f34ee59c7f8ff6c" + dependencies: + debug "2.X" + object-assign "4.1.0" + debug@0.7.4: version "0.7.4" resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" -debug@2, debug@^2.1.1, debug@^2.2.0: - version "2.6.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.6.tgz#a9fa6fbe9ca43cf1e79f73b75c0189cbb7d6db5a" +debug@2, debug@2.6.8, debug@2.X, debug@^2.1.1, debug@^2.2.0: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: - ms "0.7.3" + ms "2.0.0" debug@2.0.0: version "2.0.0" @@ -1812,17 +1998,11 @@ debug@2.3.3: dependencies: ms "0.7.2" -debug@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.1.tgz#79855090ba2c4e3115cc7d8769491d58f0491351" +debug@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.7.tgz#92bad1f6d05bbb6bba22cca88bcd0ec894c2861e" dependencies: - ms "0.7.2" - -debug@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d" - dependencies: - ms "0.7.2" + ms "2.0.0" decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" @@ -1834,6 +2014,10 @@ deep-eql@0.1.3, deep-eql@^0.1.3: dependencies: type-detect "0.1.1" +deep-equal@*: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + deep-extend@~0.4.0, deep-extend@~0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" @@ -1929,12 +2113,24 @@ detect-file@^0.1.0: dependencies: fs-exists-sync "^0.1.0" +detect-indent@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-3.0.1.tgz#9dc5e5ddbceef8325764b9451b02bc6d54084f75" + dependencies: + get-stdin "^4.0.1" + minimist "^1.1.0" + repeating "^1.1.0" + detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" dependencies: repeating "^2.0.0" +detect-newline@2.X: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + detective@^4.3.1: version "4.5.0" resolved "https://registry.yarnpkg.com/detective/-/detective-4.5.0.tgz#6e5a8c6b26e6c7a254b1c6b6d7490d98ec91edd1" @@ -1998,10 +2194,38 @@ dom-serialize@^2.2.0: extend "^3.0.0" void-elements "^2.0.0" +dom-serializer@0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" + dependencies: + domelementtype "~1.1.1" + entities "~1.1.1" + domain-browser@^1.1.1: version "1.1.7" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" +domelementtype@1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" + +domelementtype@~1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" + +domhandler@2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738" + dependencies: + domelementtype "1" + +domutils@1.5: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + dependencies: + dom-serializer "0" + domelementtype "1" + duplexer2@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" @@ -2012,6 +2236,15 @@ duplexer@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" +duplexify@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.0.tgz#1aa773002e1578457e9d9d4a50b0ccaaebcbd604" + dependencies: + end-of-stream "1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" @@ -2038,11 +2271,11 @@ encodeurl@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" -end-of-stream@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" +end-of-stream@1.0.0, end-of-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.0.0.tgz#d4596e702734a93e40e9af864319eabd99ff2f0e" dependencies: - once "^1.4.0" + once "~1.3.0" end-of-stream@~0.1.5: version "0.1.5" @@ -2101,6 +2334,14 @@ ent@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" +entities@1.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26" + +entities@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" + errno@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" @@ -2121,8 +2362,8 @@ errorhandler@~1.4.2: escape-html "~1.0.3" es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: - version "0.10.18" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.18.tgz#dc239d3dce4c22b9c939aa180878837a3c0b5c92" + version "0.10.23" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.23.tgz#7578b51be974207a5487821b56538c224e4e7b38" dependencies: es6-iterator "2" es6-symbol "~3.1" @@ -2184,11 +2425,11 @@ escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" -escape-string-regexp@1.0.2, escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2: +escape-string-regexp@1.0.2, escape-string-regexp@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5, escape-string-regexp@~1.0.5: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.5, escape-string-regexp@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -2203,7 +2444,7 @@ escodegen@1.7.x, escodegen@1.x.x: optionalDependencies: source-map "~0.2.0" -escope@^3.6.0: +escope@^3.2.0, escope@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" dependencies: @@ -2232,8 +2473,8 @@ eslint-module-utils@^2.0.0: pkg-dir "^1.0.0" eslint-plugin-import@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz#72ba306fad305d67c4816348a4699a4229ac8b4e" + version "2.3.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.3.0.tgz#37c801e0ada0e296cbdf20c3f393acb5b52af36b" dependencies: builtin-modules "^1.1.1" contains-path "^0.1.0" @@ -2244,7 +2485,7 @@ eslint-plugin-import@^2.2.0: has "^1.0.1" lodash.cond "^4.3.0" minimatch "^3.0.3" - pkg-up "^1.0.0" + read-pkg-up "^2.0.0" eslint-plugin-node@^4.2.2: version "4.2.2" @@ -2334,7 +2575,7 @@ esprima@3.x.x, esprima@~3.1.0: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" -esprima@^2.6.0: +esprima@^2.6.0, esprima@~2.7.0: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" @@ -2355,7 +2596,7 @@ estraverse@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" -estraverse@^4.0.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" @@ -2371,7 +2612,7 @@ estree-walker@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.3.1.tgz#e6b1a51cf7292524e7237c312e5fe6660c1ce1aa" -esutils@^2.0.2: +esutils@^2.0.0, esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -2386,7 +2627,7 @@ event-emitter@~0.3.5: d "1" es5-ext "~0.10.14" -event-stream@^3.3.2: +event-stream@*, event-stream@^3.3.2: version "3.3.4" resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" dependencies: @@ -2422,6 +2663,10 @@ exit-hook@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" +exit@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + expand-braces@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea" @@ -2496,6 +2741,10 @@ extsprintf@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" +eyes@0.1.x: + version "0.1.8" + resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + faker@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/faker/-/faker-3.1.0.tgz#0f908faf4e6ec02524e54a57e432c5c013e08c9f" @@ -2621,11 +2870,11 @@ finalhandler@0.4.0: on-finished "~2.3.0" unpipe "~1.0.0" -finalhandler@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.1.tgz#bcd15d1689c0e5ed729b6f7f541a6df984117db8" +finalhandler@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.3.tgz#ef47e77950e999780e86022a560e3217e0d0cc89" dependencies: - debug "2.6.3" + debug "2.6.7" encodeurl "~1.0.1" escape-html "~1.0.3" on-finished "~2.3.0" @@ -2659,6 +2908,12 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + findup-sync@^0.4.2: version "0.4.3" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.4.3.tgz#40043929e7bc60adf0b7f4827c4c6e75a0deca12" @@ -2719,6 +2974,10 @@ forever-agent@~0.6.0, forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" +fork-stream@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/fork-stream/-/fork-stream-0.0.4.tgz#db849fce77f6708a5f8f386ae533a0907b54ae70" + form-data@~0.1.0: version "0.1.4" resolved "https://registry.yarnpkg.com/form-data/-/form-data-0.1.4.tgz#91abd788aba9702b1aabfa8bc01031a2ac9e3b12" @@ -2794,6 +3053,10 @@ fs-extra@~0.6.1: ncp "~0.4.2" rimraf "~2.2.0" +fs-readdir-recursive@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz#315b4fb8c1ca5b8c47defef319d073dad3568059" + fs-then-native@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/fs-then-native/-/fs-then-native-1.0.2.tgz#ac8d3807c9f1bbd1279607fb228e0ab649bb41fe" @@ -2946,14 +3209,7 @@ glob2base@^0.0.12: dependencies: find-index "^0.1.1" -glob@3.2.11, glob@3.x: - version "3.2.11" - resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" - dependencies: - inherits "2" - minimatch "0.3" - -glob@3.2.3: +glob@3.2.3, glob@3.x: version "3.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.3.tgz#e313eeb249c7affaa5c475286b0e115b59839467" dependencies: @@ -2961,7 +3217,7 @@ glob@3.2.3: inherits "2" minimatch "~0.2.11" -glob@5.x, glob@^5.0.10, glob@^5.0.15: +glob@5.x, glob@^5.0.1, glob@^5.0.10, glob@^5.0.15: version "5.0.15" resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" dependencies: @@ -2992,13 +3248,13 @@ glob@^4, glob@^4.3.1: once "^1.3.0" glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.0: - version "7.1.1" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.0.2" + minimatch "^3.0.4" once "^1.3.0" path-is-absolute "^1.0.0" @@ -3035,9 +3291,13 @@ global-prefix@^0.1.4: is-windows "^0.2.0" which "^1.2.12" +globals@^6.4.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/globals/-/globals-6.4.1.tgz#8498032b3b6d1cc81eebc5f79690d8fe29fabf4f" + globals@^9.0.0, globals@^9.14.0: - version "9.17.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286" + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" globby@^5.0.0: version "5.0.0" @@ -3064,16 +3324,16 @@ glogg@^1.0.0: dependencies: sparkles "^1.0.0" +graceful-fs@4.X, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + graceful-fs@^3.0.0, graceful-fs@~3.0.2: version "3.0.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" dependencies: natives "^1.1.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - graceful-fs@~1.2.0: version "1.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" @@ -3139,6 +3399,14 @@ gulp-eslint@^3.0.1: eslint "^3.0.0" gulp-util "^3.0.6" +gulp-footer@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/gulp-footer/-/gulp-footer-1.0.5.tgz#e84ca777e266be7bbc2d45d2df0e7eba8dfa3e54" + dependencies: + event-stream "*" + gulp-util "*" + lodash.assign "*" + gulp-header@^1.7.1: version "1.8.8" resolved "https://registry.yarnpkg.com/gulp-header/-/gulp-header-1.8.8.tgz#4509c64677aab56b5ee8e4669a79b1655933a49e" @@ -3148,6 +3416,23 @@ gulp-header@^1.7.1: object-assign "*" through2 "^2.0.0" +gulp-if@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/gulp-if/-/gulp-if-2.0.2.tgz#a497b7e7573005041caa2bc8b7dda3c80444d629" + dependencies: + gulp-match "^1.0.3" + ternary-stream "^2.0.1" + through2 "^2.0.1" + +gulp-jscs@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/gulp-jscs/-/gulp-jscs-3.0.2.tgz#dc7fbb01ce2bfc8325bba7cbbf95d65e43530478" + dependencies: + gulp-util "^3.0.4" + jscs "^2.1.1" + through2 "^2.0.0" + tildify "^1.0.0" + gulp-jsdoc-to-markdown@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/gulp-jsdoc-to-markdown/-/gulp-jsdoc-to-markdown-1.2.2.tgz#bd0e267e3972bc169e7bdb992f967823b023fefd" @@ -3165,16 +3450,11 @@ gulp-karma@0.0.4: optimist "~0.6.0" xtend "~2.1.1" -gulp-mocha@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/gulp-mocha/-/gulp-mocha-2.2.0.tgz#1ce5eba4b94b40c7436afec3c4982c8eea894192" +gulp-match@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/gulp-match/-/gulp-match-1.0.3.tgz#91c7c0d7f29becd6606d57d80a7f8776a87aba8e" dependencies: - gulp-util "^3.0.0" - mocha "^2.0.1" - plur "^2.1.0" - resolve-from "^1.0.0" - temp "^0.8.3" - through "^2.3.4" + minimatch "^3.0.3" gulp-optimize-js@^1.1.0: version "1.1.0" @@ -3206,6 +3486,23 @@ gulp-shell@^0.5.2: lodash "^4.0.0" through2 "^2.0.0" +gulp-sourcemaps@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-2.6.0.tgz#7ccce899a8a3bfca1593a3348d0fbf41dd3f51e5" + dependencies: + "@gulp-sourcemaps/identity-map" "1.X" + "@gulp-sourcemaps/map-sources" "1.X" + acorn "4.X" + convert-source-map "1.X" + css "2.X" + debug-fabulous "0.1.X" + detect-newline "2.X" + graceful-fs "4.X" + source-map "0.X" + strip-bom-string "1.X" + through2 "2.X" + vinyl "1.X" + gulp-uglify@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/gulp-uglify/-/gulp-uglify-0.3.2.tgz#fa37bf6d4ad9a29a349c6cba862abb22eba67aac" @@ -3332,8 +3629,8 @@ handlebars@^3.0.0, handlebars@^3.0.3: uglify-js "~2.3" handlebars@^4.0.1: - version "4.0.8" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.8.tgz#22b875cd3f0e6cbea30314f144e82bc7a72ff420" + version "4.0.10" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f" dependencies: async "^1.4.0" optimist "^0.6.1" @@ -3388,6 +3685,10 @@ has-binary@0.1.7: dependencies: isarray "0.0.1" +has-color@~0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + has-cors@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" @@ -3454,6 +3755,13 @@ hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" +home-or-tmp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-1.0.0.tgz#4b9f1e40800c3e50c6c27f781676afcce71f3985" + dependencies: + os-tmpdir "^1.0.1" + user-home "^1.1.1" + home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" @@ -3461,7 +3769,7 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" -home-path@^1.0.3: +home-path@^1.0.3, home-path@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/home-path/-/home-path-1.0.5.tgz#788b29815b12d53bacf575648476e6f9041d133f" @@ -3475,6 +3783,16 @@ hosted-git-info@^2.1.4: version "2.4.2" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67" +htmlparser2@3.8.3: + version "3.8.3" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068" + dependencies: + domelementtype "1" + domhandler "2.3" + domutils "1.5" + entities "1.0" + readable-stream "1.1" + http-errors@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.3.1.tgz#197e22cdebd4198585e8694ef6786197b91ed942" @@ -3534,6 +3852,10 @@ https-proxy-agent@1, https-proxy-agent@1.0.0: debug "2" extend "3" +i@0.3.x: + version "0.3.5" + resolved "https://registry.yarnpkg.com/i/-/i-0.3.5.tgz#1d2b854158ec8169113c6cb7f6b6801e99e211d5" + ibrik@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ibrik/-/ibrik-2.0.0.tgz#89a2434f2a5c82b92166c3d97de3b5636eea2e9c" @@ -3565,8 +3887,8 @@ ieee754@^1.1.4: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" ignore@^3.0.11, ignore@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.0.tgz#3812d22cbe9125f2c2b4915755a1b8abd745a001" + version "3.3.3" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" imurmurhash@^0.1.4: version "0.1.4" @@ -3589,6 +3911,10 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" +inherit@^2.2.2: + version "2.2.6" + resolved "https://registry.yarnpkg.com/inherit/-/inherit-2.2.6.tgz#f1614b06c8544e8128e4229c86347db73ad9788d" + inherits@1: version "1.0.2" resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" @@ -3658,10 +3984,6 @@ ip@^1.1.4: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" -irregular-plurals@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.2.0.tgz#38f299834ba8c00c30be9c554e137269752ff3ac" - is-absolute@^0.2.3: version "0.2.6" resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.2.6.tgz#20de69f3db942ef2d87b9c2da36f172235b1b5eb" @@ -3690,8 +4012,8 @@ is-builtin-module@^1.0.0: builtin-modules "^1.0.0" is-dotfile@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" is-equal-shallow@^0.1.3: version "0.1.3" @@ -3733,6 +4055,12 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" +is-integer@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-integer/-/is-integer-1.0.7.tgz#6bde81aacddf78b659b6629d629cadc51a886d5c" + dependencies: + is-finite "^1.0.0" + is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.0, is-my-json-valid@^2.12.4: version "2.16.0" resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" @@ -3840,7 +4168,7 @@ isobject@^2.0.0: dependencies: isarray "1.0.0" -isstream@~0.1.1, isstream@~0.1.2: +isstream@0.1.x, isstream@~0.1.1, isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -3883,11 +4211,9 @@ jade@0.26.3: commander "0.6.1" mkdirp "0.3.0" -jodid25519@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" - dependencies: - jsbn "~0.1.0" +js-tokens@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-1.0.1.tgz#cc435a5c8b94ad15acb7983140fc80182c89aeae" js-tokens@^3.0.0: version "3.0.1" @@ -3900,6 +4226,14 @@ js-yaml@3.6.1, js-yaml@3.x, js-yaml@^3.5.1: argparse "^1.0.7" esprima "^2.6.0" +js-yaml@~3.4.0: + version "3.4.6" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.4.6.tgz#6be1b23f6249f53d293370fd4d1aaa63ce1b4eb0" + dependencies: + argparse "^1.0.2" + esprima "^2.6.0" + inherit "^2.2.2" + js2xmlparser@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-1.0.0.tgz#5a170f2e8d6476ce45405e04823242513782fe30" @@ -3908,6 +4242,50 @@ jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" +jscs-jsdoc@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/jscs-jsdoc/-/jscs-jsdoc-1.3.2.tgz#1f2c82b6ab4b97524da958f46b4e562e0305f9a7" + dependencies: + comment-parser "^0.3.1" + jsdoctypeparser "~1.2.0" + +jscs-preset-wikimedia@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/jscs-preset-wikimedia/-/jscs-preset-wikimedia-1.0.0.tgz#fff563342038fc2e8826b7bb7309c3ae3406fc7e" + +jscs@^2.1.1: + version "2.11.0" + resolved "https://registry.yarnpkg.com/jscs/-/jscs-2.11.0.tgz#6e11ef0caaa07731f9dcc2b2b27d8ecee1ddbcb6" + dependencies: + babel-jscs "^2.0.0" + chalk "~1.1.0" + cli-table "~0.3.1" + commander "~2.9.0" + escope "^3.2.0" + esprima "~2.7.0" + estraverse "^4.1.0" + exit "~0.1.2" + glob "^5.0.1" + htmlparser2 "3.8.3" + js-yaml "~3.4.0" + jscs-jsdoc "^1.3.1" + jscs-preset-wikimedia "~1.0.0" + jsonlint "~1.6.2" + lodash "~3.10.0" + minimatch "~3.0.0" + natural-compare "~1.2.2" + pathval "~0.1.1" + prompt "~0.2.14" + reserved-words "^0.1.1" + resolve "^1.1.6" + strip-bom "^2.0.0" + strip-json-comments "~1.0.2" + to-double-quotes "^2.0.0" + to-single-quotes "^2.0.0" + vow "~0.4.8" + vow-fs "~0.3.4" + xmlbuilder "^3.1.0" + jsdoc-75lb@^3.5.6: version "3.6.0" resolved "https://registry.yarnpkg.com/jsdoc-75lb/-/jsdoc-75lb-3.6.0.tgz#a807119528b4009ccbcab49b7522f63fec6cd0bd" @@ -3980,6 +4358,12 @@ jsdoc2md-stats@^1.0.3: app-usage-stats "^0.4.0" feature-detect-es6 "^1.3.1" +jsdoctypeparser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/jsdoctypeparser/-/jsdoctypeparser-1.2.0.tgz#e7dedc153a11849ffc5141144ae86a7ef0c25392" + dependencies: + lodash "^3.7.0" + jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" @@ -4010,6 +4394,10 @@ json3@3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" +json5@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.4.0.tgz#054352e4c4c80c86c0923877d449de176a732c8d" + json5@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" @@ -4028,6 +4416,13 @@ jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" +jsonlint@~1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/jsonlint/-/jsonlint-1.6.2.tgz#5737045085f55eb455c68b1ff4ebc01bd50e8830" + dependencies: + JSV ">= 4.0.x" + nomnom ">= 1.5.x" + jsonpointer@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" @@ -4221,6 +4616,10 @@ lcov-parse@0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" +leven@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/leven/-/leven-1.0.2.tgz#9144b6eebca5f1d0680169f1a6770dcea60b75c3" + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -4263,6 +4662,15 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + loader-utils@^0.2.11, loader-utils@^0.2.16, loader-utils@^0.2.5, loader-utils@~0.2.2, loader-utils@~0.2.3, loader-utils@~0.2.5: version "0.2.17" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" @@ -4281,6 +4689,13 @@ localtunnel@^1.3.0: request "2.78.0" yargs "3.29.0" +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + lodash._arraycopy@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1" @@ -4335,6 +4750,14 @@ lodash._bindcallback@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" +lodash._createassigner@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" + dependencies: + lodash._bindcallback "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash.restparam "^3.0.0" + lodash._escapehtmlchar@~2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz#df67c3bb6b7e8e1e831ab48bfa0795b92afe899d" @@ -4402,10 +4825,18 @@ lodash._stack@^4.0.0: version "4.1.3" resolved "https://registry.yarnpkg.com/lodash._stack/-/lodash._stack-4.1.3.tgz#751aa76c1b964b047e76d14fc72a093fcb5e2dd0" -lodash.assign@^4.0.3, lodash.assign@^4.0.6: +lodash.assign@*, lodash.assign@^4.0.3, lodash.assign@^4.0.6: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" +lodash.assign@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa" + dependencies: + lodash._baseassign "^3.0.0" + lodash._createassigner "^3.0.0" + lodash.keys "^3.0.0" + lodash.assignwith@^4.0.7: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz#127a97f02adc41751a954d24b0de17e100e038eb" @@ -4586,7 +5017,7 @@ lodash@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.5.0.tgz#19bb3f4d51278f0b8c818ed145c74ecf9fe40e6d" -lodash@^3.10.1, lodash@^3.3.1, lodash@^3.5.0, lodash@^3.8.0: +lodash@^3.10.0, lodash@^3.10.1, lodash@^3.3.1, lodash@^3.5.0, lodash@^3.7.0, lodash@^3.8.0, lodash@^3.9.3, lodash@~3.10.0: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" @@ -4646,11 +5077,7 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" -lru-cache@2: - version "2.7.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" - -lru-cache@2.2.x: +lru-cache@2, lru-cache@2.2.x: version "2.2.4" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d" @@ -4732,14 +5159,20 @@ merge-descriptors@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" +merge-stream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + dependencies: + readable-stream "^2.0.1" + method-override@~2.3.5: - version "2.3.8" - resolved "https://registry.yarnpkg.com/method-override/-/method-override-2.3.8.tgz#178234bf4bab869f89df9444b06fc6147b44828c" + version "2.3.9" + resolved "https://registry.yarnpkg.com/method-override/-/method-override-2.3.9.tgz#bd151f2ce34cf01a76ca400ab95c012b102d8f71" dependencies: - debug "2.6.3" + debug "2.6.8" methods "~1.1.2" parseurl "~1.3.1" - vary "~1.1.0" + vary "~1.1.1" methods@~1.1.2: version "1.1.2" @@ -4799,20 +5232,20 @@ mime@~1.2.11: version "1.2.11" resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10" -minimatch@0.3, minimatch@0.x, minimatch@~0.3.0: +minimatch@0.x, minimatch@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" dependencies: lru-cache "2" sigmund "~1.0.0" -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3: +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: brace-expansion "^1.1.7" -minimatch@2.x, minimatch@^2.0.1: +minimatch@2.x, minimatch@^2.0.1, minimatch@^2.0.3: version "2.0.10" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" dependencies: @@ -4843,7 +5276,7 @@ minimist@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.2.0.tgz#4dffe525dae2b864c66c2e23c6271d7afdecefce" -mkdirp2@^1.0.2: +mkdirp2@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/mkdirp2/-/mkdirp2-1.0.3.tgz#cc8dd8265f1f06e2d8f5b10b6e52f4e050bed21b" @@ -4855,7 +5288,7 @@ mkdirp@0.3.x, mkdirp@~0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7" -mkdirp@0.5, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@0.5, mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -4900,21 +5333,6 @@ mocha@^1.21.4: jade "0.26.3" mkdirp "0.5.0" -mocha@^2.0.1: - version "2.5.3" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-2.5.3.tgz#161be5bdeb496771eb9b35745050b622b5aefc58" - dependencies: - commander "2.3.0" - debug "2.2.0" - diff "1.4.0" - escape-string-regexp "1.0.2" - glob "3.2.11" - growl "1.9.2" - jade "0.26.3" - mkdirp "0.5.1" - supports-color "1.2.0" - to-iso-string "0.0.2" - mock-fs@^3.11.0: version "3.12.1" resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-3.12.1.tgz#ff27824cd6ab263a7eb05a115239d41d3631f5f8" @@ -4948,9 +5366,9 @@ ms@0.7.2: version "0.7.2" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" -ms@0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.3.tgz#708155a5e44e33f5fd0fc53e81d0d40a91be1fff" +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" mu2@~0.5.19: version "0.5.21" @@ -4973,7 +5391,7 @@ mute-stream@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.4.tgz#a9219960a6d5d5d046597aee51252c6655f7177e" -mute-stream@0.0.5: +mute-stream@0.0.5, mute-stream@~0.0.4: version "0.0.5" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" @@ -4989,7 +5407,11 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" -ncp@~0.4.2: +natural-compare@~1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.2.2.tgz#1f96d60e3141cac1b6d05653ce0daeac763af6aa" + +ncp@0.4.x, ncp@~0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/ncp/-/ncp-0.4.2.tgz#abcc6cbd3ec2ed2a729ff6e7c1fa8f01784a8574" @@ -5053,8 +5475,8 @@ node-libs-browser@^0.7.0: vm-browserify "0.0.4" node-pre-gyp@^0.6.29: - version "0.6.34" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.34.tgz#94ad1c798a11d7fc67381b50d47f8cc18d9799f7" + version "0.6.36" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786" dependencies: mkdirp "^0.5.1" nopt "^4.0.1" @@ -5070,6 +5492,13 @@ node-uuid@~1.4.0, node-uuid@~1.4.7: version "1.4.8" resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" +"nomnom@>= 1.5.x": + version "1.8.1" + resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" + dependencies: + chalk "~0.4.0" + underscore "~1.6.0" + nopt@3.x: version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" @@ -5092,7 +5521,7 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.0.1: +normalize-path@^2.0.1, normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" dependencies: @@ -5189,7 +5618,7 @@ on-headers@~1.0.0, on-headers@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" -once@1.x, once@^1.3.0, once@^1.3.3, once@^1.4.0: +once@1.x, once@^1.3.0, once@^1.3.3: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: @@ -5299,10 +5728,28 @@ osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" +output-file-sync@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" + dependencies: + graceful-fs "^4.1.4" + mkdirp "^0.5.1" + object-assign "^4.1.0" + "over@>= 0.0.5 < 1": version "0.0.5" resolved "https://registry.yarnpkg.com/over/-/over-0.0.5.tgz#f29852e70fd7e25f360e013a8ec44c82aedb5708" +p-limit@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + pac-proxy-agent@1: version "1.0.0" resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-1.0.0.tgz#dcd5b746581367430a236e88eacfd4e5b8d068a5" @@ -5384,12 +5831,20 @@ path-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" +path-exists@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-1.0.0.tgz#d5a8998eb71ef37a74c34eb0d9eba6e878eea081" + path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" dependencies: pinkie-promise "^2.0.0" +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -5420,6 +5875,16 @@ path-type@^1.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + dependencies: + pify "^2.0.0" + +pathval@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-0.1.1.tgz#08f911cdca9cce5942880da7817bc0b723b66d82" + pause-stream@0.0.11: version "0.0.11" resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" @@ -5475,17 +5940,13 @@ pkg-dir@^1.0.0: dependencies: find-up "^1.0.0" -pkg-up@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26" - dependencies: - find-up "^1.0.0" +pkginfo@0.3.x: + version "0.3.1" + resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21" -plur@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" - dependencies: - irregular-plurals "^1.0.0" +pkginfo@0.x.x: + version "0.4.0" + resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.0.tgz#349dbb7ffd38081fcadc0853df687f0c7744cd65" pluralize@^1.2.1: version "1.2.1" @@ -5529,6 +5990,16 @@ promise.prototype.finally@^1.0.1: dependencies: asap "~2.0.3" +prompt@~0.2.14: + version "0.2.14" + resolved "https://registry.yarnpkg.com/prompt/-/prompt-0.2.14.tgz#57754f64f543fd7b0845707c818ece618f05ffdc" + dependencies: + pkginfo "0.x.x" + read "1.0.x" + revalidator "0.1.x" + utile "0.2.x" + winston "0.8.x" + proxy-agent@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-2.0.0.tgz#57eb5347aa805d74ec681cb25649dba39c933499" @@ -5682,6 +6153,13 @@ read-pkg-up@^1.0.1: find-up "^1.0.0" read-pkg "^1.0.0" +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" @@ -5690,7 +6168,21 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" -readable-stream@1.1.x, readable-stream@~1.1.8, readable-stream@~1.1.9: +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read@1.0.x: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + dependencies: + mute-stream "~0.0.4" + +readable-stream@1.1, readable-stream@1.1.x, readable-stream@~1.1.8, readable-stream@~1.1.9: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" dependencies: @@ -5699,15 +6191,15 @@ readable-stream@1.1.x, readable-stream@~1.1.8, readable-stream@~1.1.9: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@2, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6: - version "2.2.9" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.9.tgz#cf78ec6f4a6d1eb43d26488cac97f042e74b7fc8" +readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6: + version "2.2.11" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.11.tgz#0796b31f8d7688007ff0b93a8088d34aa17c0f72" dependencies: - buffer-shims "~1.0.0" core-util-is "~1.0.0" inherits "~2.0.1" isarray "~1.0.0" process-nextick-args "~1.0.6" + safe-buffer "~5.0.1" string_decoder "~1.0.0" util-deprecate "~1.0.1" @@ -5755,7 +6247,7 @@ readline2@^1.0.1: is-fullwidth-code-point "^1.0.0" mute-stream "0.0.5" -recast@0.10.33: +recast@0.10.33, recast@^0.10.10: version "0.10.33" resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.33.tgz#942808f7aa016f1fa7142c461d7e5704aaa8d697" dependencies: @@ -5814,10 +6306,6 @@ regenerator-runtime@^0.10.0: version "0.10.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" -regenerator-runtime@~0.9.5: - version "0.9.6" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz#d33eb95d0d2001a4be39659707c51b0cb71ce029" - regenerator-transform@0.9.11: version "0.9.11" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.11.tgz#3a7d067520cb7b7176769eb5ff868691befe1283" @@ -5826,16 +6314,15 @@ regenerator-transform@0.9.11: babel-types "^6.19.0" private "^0.1.6" -regenerator@~0.8.13: - version "0.8.46" - resolved "https://registry.yarnpkg.com/regenerator/-/regenerator-0.8.46.tgz#154c327686361ed52cad69b2545efc53a3d07696" +regenerator@0.8.40, regenerator@~0.8.13: + version "0.8.40" + resolved "https://registry.yarnpkg.com/regenerator/-/regenerator-0.8.40.tgz#a0e457c58ebdbae575c9f8cd75127e93756435d8" dependencies: commoner "~0.10.3" defs "~1.1.0" esprima-fb "~15001.1001.0-dev-harmony-fb" private "~0.1.5" recast "0.10.33" - regenerator-runtime "~0.9.5" through "~2.3.8" regex-cache@^0.4.2: @@ -5853,6 +6340,16 @@ regexpu-core@^2.0.0: regjsgen "^0.2.0" regjsparser "^0.1.4" +regexpu@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/regexpu/-/regexpu-1.3.0.tgz#e534dc991a9e5846050c98de6d7dd4a55c9ea16d" + dependencies: + esprima "^2.6.0" + recast "^0.10.10" + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + regjsgen@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" @@ -5864,8 +6361,8 @@ regjsparser@^0.1.4: jsesc "~0.5.0" remove-trailing-separator@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz#615ebb96af559552d4bf4057c8436d486ab63cc4" + version "1.0.2" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz#69b062d978727ad14dc6b56ba4ab772fd8d70511" repeat-element@^1.1.2: version "1.1.2" @@ -5879,6 +6376,12 @@ repeat-string@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" +repeating@^1.1.0, repeating@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-1.1.3.tgz#3d4114218877537494f97f77f9785fab810fa4ac" + dependencies: + is-finite "^1.0.0" + repeating@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" @@ -5899,7 +6402,7 @@ replacestream@0.1.3: dependencies: through "~2.3.4" -req-then@^0.5.1: +req-then@0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/req-then/-/req-then-0.5.1.tgz#31c6e0b56f4ddd2acd6de0ba1bcea77b6079dfdf" dependencies: @@ -6090,6 +6593,10 @@ requizzle@~0.2.1: dependencies: underscore "~1.6.0" +reserved-words@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/reserved-words/-/reserved-words-0.1.1.tgz#6f7c15e5e5614c50da961630da46addc87c0cef2" + resolve-dir@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e" @@ -6129,6 +6636,10 @@ restore-cursor@^1.0.1: exit-hook "^1.0.0" onetime "^1.0.0" +revalidator@0.1.x: + version "0.1.8" + resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b" + rewire@2.5.2: version "2.5.2" resolved "https://registry.yarnpkg.com/rewire/-/rewire-2.5.2.tgz#6427de7b7feefa7d36401507eb64a5385bc58dc7" @@ -6143,7 +6654,7 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@2, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.5.1, rimraf@^2.6.1: +rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.5.1, rimraf@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" dependencies: @@ -6153,7 +6664,7 @@ rimraf@2.2.6: version "2.2.6" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.6.tgz#c59597569b14d956ad29cacc42bdddf5f0ea4f4c" -rimraf@~2.2.0, rimraf@~2.2.6: +rimraf@~2.2.0: version "2.2.8" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" @@ -6179,7 +6690,7 @@ rx@^2.4.3: version "2.5.3" resolved "https://registry.yarnpkg.com/rx/-/rx-2.5.3.tgz#21adc7d80f02002af50dae97fd9dbf248755f566" -safe-buffer@^5.0.1: +safe-buffer@^5.0.1, safe-buffer@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" @@ -6282,9 +6793,13 @@ sha.js@2.2.6: version "2.2.6" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.2.6.tgz#17ddeddc5f722fb66501658895461977867315ba" +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + shelljs@^0.7.5: - version "0.7.7" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1" + version "0.7.8" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -6390,8 +6905,8 @@ socket.io@^1.4.5: socket.io-parser "2.3.1" socks-proxy-agent@2: - version "2.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-2.0.0.tgz#c674842d70410fb28ae1e92e6135a927854bc275" + version "2.1.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-2.1.0.tgz#ddfb01b5dbea5fc879490ca38a25fe87d3d15912" dependencies: agent-base "2" extend "3" @@ -6425,6 +6940,12 @@ source-map-resolve@^0.3.0: source-map-url "~0.3.0" urix "~0.1.0" +source-map-support@^0.2.10: + version "0.2.10" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.2.10.tgz#ea5a3900a1c1cb25096a0ae8cc5c2b4b10ded3dc" + dependencies: + source-map "0.1.32" + source-map-support@^0.4.2: version "0.4.15" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1" @@ -6435,6 +6956,16 @@ source-map-url@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9" +source-map@0.1.32: + version "0.1.32" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.32.tgz#c8b6c167797ba4740a8ea33252162ff08591b266" + dependencies: + amdefine ">=0.0.4" + +source-map@0.X, source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + source-map@^0.1.38, source-map@^0.1.40, source-map@^0.1.41, source-map@~0.1.38, source-map@~0.1.7: version "0.1.43" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" @@ -6447,10 +6978,6 @@ source-map@^0.4.4, source-map@~0.4.1: dependencies: amdefine ">=0.0.4" -source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.1: - version "0.5.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" - source-map@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" @@ -6492,8 +7019,8 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" sshpk@^1.7.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c" + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -6502,7 +7029,6 @@ sshpk@^1.7.0: optionalDependencies: bcrypt-pbkdf "^1.0.0" ecc-jsbn "~0.1.1" - jodid25519 "^1.0.0" jsbn "~0.1.0" tweetnacl "~0.14.0" @@ -6510,6 +7036,10 @@ stable@~0.1.3: version "0.1.6" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.6.tgz#910f5d2aed7b520c6e777499c1f32e139fdecb10" +stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + statuses@1, "statuses@>= 1.3.1 < 2", statuses@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" @@ -6564,6 +7094,10 @@ stream-http@^2.3.1: to-arraybuffer "^1.0.0" xtend "^4.0.0" +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + stream-to-buffer@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/stream-to-buffer/-/stream-to-buffer-0.1.0.tgz#26799d903ab2025c9bd550ac47171b00f8dd80a9" @@ -6575,8 +7109,8 @@ stream-to@~0.2.0: resolved "https://registry.yarnpkg.com/stream-to/-/stream-to-0.2.2.tgz#84306098d85fdb990b9fa300b1b3ccf55e8ef01d" stream-via@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/stream-via/-/stream-via-1.0.3.tgz#cebd32a5a59d74b3b68e3404942e867184ad4ac9" + version "1.0.4" + resolved "https://registry.yarnpkg.com/stream-via/-/stream-via-1.0.4.tgz#8dccbb0ac909328eb8bc8e2a4bd3934afdaf606c" stream-via@~0.1.0: version "0.1.1" @@ -6620,10 +7154,10 @@ string_decoder@^0.10.25, string_decoder@~0.10.x: resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" string_decoder@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.0.tgz#f06f41157b664d86069f84bdbdc9b0d8ab281667" + version "1.0.2" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.2.tgz#b29e1f4e1125fa97a10382b8a533737b7491e179" dependencies: - buffer-shims "~1.0.0" + safe-buffer "~5.0.1" stringmap@~0.2.2: version "0.2.2" @@ -6655,6 +7189,14 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" +strip-ansi@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" + +strip-bom-string@1.X: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" + strip-bom@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-1.0.0.tgz#85b8862f3844b5a6d5ec8467a93598173a36f794" @@ -6678,6 +7220,10 @@ strip-indent@^1.0.1: dependencies: get-stdin "^4.0.1" +strip-json-comments@~1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" + strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -6688,10 +7234,6 @@ style-loader@^0.8.3: dependencies: loader-utils "^0.2.5" -supports-color@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-1.2.0.tgz#ff1ed1e61169d06b3cf2d588e188b18d8847e17e" - supports-color@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" @@ -6780,12 +7322,14 @@ temp-path@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/temp-path/-/temp-path-1.0.0.tgz#24b1543973ab442896d9ad367dd9cbdbfafe918b" -temp@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" +ternary-stream@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ternary-stream/-/ternary-stream-2.0.1.tgz#064e489b4b5bf60ba6a6b7bc7f2f5c274ecf8269" dependencies: - os-tmpdir "^1.0.0" - rimraf "~2.2.6" + duplexify "^3.5.0" + fork-stream "^0.0.4" + merge-stream "^1.0.0" + through2 "^2.0.1" test-value@^1.0.1, test-value@^1.1.0: version "1.1.0" @@ -6819,6 +7363,13 @@ throttleit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" +through2@2.X, through2@^2.0.0, through2@^2.0.1, through2@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + "through2@>=0.6.1 <1.0.0-0", through2@^0.6.1, through2@^0.6.5: version "0.6.5" resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" @@ -6840,14 +7391,7 @@ through2@^0.5.0: readable-stream "~1.0.17" xtend "~3.0.0" -through2@^2.0.0, through2@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" - dependencies: - readable-stream "^2.1.5" - xtend "~4.0.1" - -through@2, through@^2.3.4, through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.1, through@~2.3.4, through@~2.3.8: +through@2, through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.1, through@~2.3.4, through@~2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -6896,13 +7440,17 @@ to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" -to-fast-properties@^1.0.1: +to-double-quotes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-double-quotes/-/to-double-quotes-2.0.0.tgz#aaf231d6fa948949f819301bbab4484d8588e4a7" + +to-fast-properties@^1.0.0, to-fast-properties@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" -to-iso-string@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/to-iso-string/-/to-iso-string-0.0.2.tgz#4dc19e664dfccbe25bd8db508b00c6da158255d1" +to-single-quotes@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/to-single-quotes/-/to-single-quotes-2.0.1.tgz#7cc29151f0f5f2c41946f119f5932fe554170125" tough-cookie@>=0.12.0, tough-cookie@~2.3.0: version "2.3.2" @@ -6922,10 +7470,14 @@ trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" -trim-right@^1.0.1: +trim-right@^1.0.0, trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" +try-resolve@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/try-resolve/-/try-resolve-1.0.1.tgz#cfde6fabd72d63e5797cfaab873abbe8e700e912" + tryit@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" @@ -6970,7 +7522,7 @@ type-detect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" -type-is@~1.6.10, type-is@~1.6.14, type-is@~1.6.6: +type-is@~1.6.10, type-is@~1.6.15, type-is@~1.6.6: version "1.6.15" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" dependencies: @@ -6981,9 +7533,9 @@ typedarray@^0.0.6, typedarray@~0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -typical@^2.1, typical@^2.2, typical@^2.3.0, typical@^2.4.2, typical@^2.5.0, typical@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.0.tgz#89d51554ab139848a65bcc2c8772f8fb450c40ed" +typical@^2.1, typical@^2.2, typical@^2.3.0, typical@^2.4.2, typical@^2.5.0, typical@^2.6.0, typical@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" uglify-js@2.4.6: version "2.4.6" @@ -6995,8 +7547,8 @@ uglify-js@2.4.6: uglify-to-browserify "~1.0.0" uglify-js@^2.6, uglify-js@^2.8.10: - version "2.8.26" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.26.tgz#3a1db8ae0a0aba7f92e1ddadadbd0293d549f90e" + version "2.8.28" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.28.tgz#e335032df9bb20dcb918f164589d5af47f38834a" dependencies: source-map "~0.5.1" yargs "~3.10.0" @@ -7111,18 +7663,18 @@ url@~0.10.3: querystring "0.2.0" usage-stats@^0.8.2: - version "0.8.5" - resolved "https://registry.yarnpkg.com/usage-stats/-/usage-stats-0.8.5.tgz#5054336ba78b14b8d8f9399fd699708f5cecff69" + version "0.8.6" + resolved "https://registry.yarnpkg.com/usage-stats/-/usage-stats-0.8.6.tgz#ec92559f648845c2021cbf5b4adea17af7513830" dependencies: - array-back "^1.0.3" + array-back "^1.0.4" cli-commands "0.1.0" core-js "^2.4.1" feature-detect-es6 "^1.3.1" - home-path "^1.0.3" - mkdirp2 "^1.0.2" - req-then "^0.5.1" - typical "^2.6.0" - uuid "^3.0.0" + home-path "^1.0.5" + mkdirp2 "^1.0.3" + req-then "0.5.1" + typical "^2.6.1" + uuid "^3.0.1" user-home@^1.1.1: version "1.1.1" @@ -7151,11 +7703,26 @@ util@0.10.3, "util@>=0.10.3 <1", util@^0.10.3: dependencies: inherits "2.0.1" +utile@0.2.x: + version "0.2.1" + resolved "https://registry.yarnpkg.com/utile/-/utile-0.2.1.tgz#930c88e99098d6220834c356cbd9a770522d90d7" + dependencies: + async "~0.2.9" + deep-equal "*" + i "0.3.x" + mkdirp "0.x.x" + ncp "0.4.x" + rimraf "2.x.x" + utils-merge@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" -uuid@^3.0.0: +uuid@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + +uuid@^3.0.0, uuid@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" @@ -7180,7 +7747,7 @@ vary@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/vary/-/vary-1.0.1.tgz#99e4981566a286118dfb2b817357df7993376d10" -vary@~1.1.0: +vary@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37" @@ -7213,6 +7780,14 @@ vinyl-sourcemaps-apply@^0.2.0: dependencies: source-map "^0.5.1" +vinyl@1.X, vinyl@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + vinyl@^0.2.1: version "0.2.3" resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.2.3.tgz#bca938209582ec5a49ad538a00fa1f125e513252" @@ -7234,14 +7809,6 @@ vinyl@^0.5.0: clone-stats "^0.0.1" replace-ext "0.0.1" -vinyl@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" - dependencies: - clone "^1.0.0" - clone-stats "^0.0.1" - replace-ext "0.0.1" - vinyl@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.0.2.tgz#0a3713d8d4e9221c58f10ca16c0116c9e25eda7c" @@ -7268,6 +7835,25 @@ void-elements@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" +vow-fs@~0.3.4: + version "0.3.6" + resolved "https://registry.yarnpkg.com/vow-fs/-/vow-fs-0.3.6.tgz#2d4c59be22e2bf2618ddf597ab4baa923be7200d" + dependencies: + glob "^7.0.5" + uuid "^2.0.2" + vow "^0.4.7" + vow-queue "^0.4.1" + +vow-queue@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/vow-queue/-/vow-queue-0.4.2.tgz#e7fe17160e15c7c4184d1b666a9bc64e18e30184" + dependencies: + vow "~0.4.0" + +vow@^0.4.7, vow@~0.4.0, vow@~0.4.8: + version "0.4.16" + resolved "https://registry.yarnpkg.com/vow/-/vow-0.4.16.tgz#bb9d54d938d5f80520d658a740e7a895e30feeeb" + walk-back@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/walk-back/-/walk-back-2.0.1.tgz#554e2a9d874fac47a8cb006bf44c2f0c4998a0a4" @@ -7414,6 +8000,18 @@ window-size@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" +winston@0.8.x: + version "0.8.3" + resolved "https://registry.yarnpkg.com/winston/-/winston-0.8.3.tgz#64b6abf4cd01adcaefd5009393b1d8e8bec19db0" + dependencies: + async "0.2.x" + colors "0.6.x" + cycle "1.0.x" + eyes "0.1.x" + isstream "0.1.x" + pkginfo "0.3.x" + stack-trace "0.0.x" + wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" @@ -7477,7 +8075,7 @@ wtf-8@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a" -xmlbuilder@3.1.0: +xmlbuilder@3.1.0, xmlbuilder@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-3.1.0.tgz#2c86888f2d4eade850fa38ca7f7223f7209516e1" dependencies: From 45ff4f523dc759f3c7736b3113a00e9ae4494c77 Mon Sep 17 00:00:00 2001 From: Matt Kendall Date: Tue, 27 Jun 2017 14:39:50 -0400 Subject: [PATCH 43/95] fix sending timeout to analytics (#1327) --- src/adaptermanager.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/adaptermanager.js b/src/adaptermanager.js index 97ed301ee1d..7aa9a4f8cb4 100644 --- a/src/adaptermanager.js +++ b/src/adaptermanager.js @@ -56,6 +56,7 @@ exports.callBids = ({adUnits, cbTimeout}) => { const auctionInit = { timestamp: auctionStart, requestId, + timeout: cbTimeout }; events.emit(CONSTANTS.EVENTS.AUCTION_INIT, auctionInit); From 871878cabeed87726ec59a5487de619c35d239bf Mon Sep 17 00:00:00 2001 From: Matt Kendall Date: Wed, 28 Jun 2017 17:20:29 -0400 Subject: [PATCH 44/95] Improvement include bid response from prebid server w/ cookie sync (#1319) * always use the bid and sync * update unit tests and add s2s type on bids --- modules/prebidServerBidAdapter.js | 7 +- .../modules/prebidServerBidAdapter_spec.js | 83 +++++++++++++++++++ 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/modules/prebidServerBidAdapter.js b/modules/prebidServerBidAdapter.js index 96821bc6211..3cd698c7ccd 100644 --- a/modules/prebidServerBidAdapter.js +++ b/modules/prebidServerBidAdapter.js @@ -106,7 +106,7 @@ function PrebidServer() { try { result = JSON.parse(response); - if (result.status === 'OK') { + if (result.status === 'OK' || result.status === 'no_cookie') { if (result.bidder_status) { result.bidder_status.forEach(bidder => { if (bidder.no_cookie) { @@ -127,6 +127,7 @@ function PrebidServer() { } let bidObject = bidfactory.createBid(status, bidRequest); + bidObject.source = TYPE; bidObject.creative_id = bidObj.creative_id; bidObject.bidderCode = bidObj.bidder; bidObject.cpm = cpm; @@ -150,7 +151,7 @@ function PrebidServer() { .bids.filter(bidRequest => !receivedBidIds.includes(bidRequest.bidId)) .forEach(bidRequest => { let bidObject = bidfactory.createBid(STATUS.NO_BID, bidRequest); - + bidObject.source = TYPE; bidObject.adUnitCode = bidRequest.placementCode; bidObject.bidderCode = bidRequest.bidder; @@ -158,7 +159,7 @@ function PrebidServer() { }); }); } - else if (result.status === 'no_cookie') { + if (result.status === 'no_cookie') { // cookie sync persist(cookiePersistUrl, cookiePersistMessage); } diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js index 0216937a788..4e5e70e44da 100644 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -3,6 +3,7 @@ import Adapter from 'modules/prebidServerBidAdapter'; import bidmanager from 'src/bidmanager'; import CONSTANTS from 'src/constants.json'; import * as utils from 'src/utils'; +import cookie from 'src/cookie'; let CONFIG = { accountId: '1', @@ -106,6 +107,47 @@ const RESPONSE_NO_COOKIE = { }] }; +const RESPONSE_NO_PBS_COOKIE = { + 'tid': '882fe33e-2981-4257-bd44-bd3b03945f48', + 'status': 'no_cookie', + 'bidder_status': [{ + 'bidder': 'rubicon', + 'no_cookie': true, + 'usersync': { + 'url': 'https://pixel.rubiconproject.com/exchange/sync.php?p=prebid', + 'type': 'redirect' + } + }, { + 'bidder': 'pubmatic', + 'no_cookie': true, + 'usersync': { + 'url': '//ads.pubmatic.com/AdServer/js/user_sync.html?predirect=https%3A%2F%2Fprebid.adnxs.com%2Fpbs%2Fv1%2Fsetuid%3Fbidder%3Dpubmatic%26uid%3D', + 'type': 'iframe' + } + }, { + 'bidder': 'appnexus', + 'response_time_ms': 162, + 'num_bids': 1, + 'debug': [{ + 'request_uri': 'http://ib.adnxs.com/openrtb2', + 'request_body': '{"id":"882fe33e-2981-4257-bd44-bd3b03945f48","imp":[{"id":"/19968336/header-bid-tag-0","banner":{"w":300,"h":250,"format":[{"w":300,"h":250}]},"secure":1,"ext":{"appnexus":{"placement_id":5914989}}}],"site":{"domain":"nytimes.com","page":"http://www.nytimes.com"},"device":{"ua":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36","ip":"75.97.0.47"},"user":{"id":"3519479852893340159","buyeruid":"3519479852893340159"},"at":1,"tmax":1000,"source":{"fd":1,"tid":"882fe33e-2981-4257-bd44-bd3b03945f48"}}', + 'response_body': '{"id":"882fe33e-2981-4257-bd44-bd3b03945f48"}', + 'status_code': 200 + }] + }], + 'bids': [{ + 'bid_id': '123', + 'code': 'div-gpt-ad-1460505748561-0', + 'creative_id': '70928274', + 'bidder': 'appnexus', + 'price': 0.07425, + 'adm': '', + 'width': 300, + 'height': 250, + 'response_time_ms': 162 + }] +}; + describe('S2S Adapter', () => { let adapter; @@ -141,6 +183,8 @@ describe('S2S Adapter', () => { beforeEach(() => { server = sinon.fakeServer.create(); + sinon.stub(cookie, 'queueSync'); + sinon.stub(cookie, 'persist'); sinon.stub(bidmanager, 'addBidResponse'); sinon.stub(utils, 'getBidderRequestAllAdUnits').returns({ bids: [{ @@ -158,6 +202,8 @@ describe('S2S Adapter', () => { bidmanager.addBidResponse.restore(); utils.getBidderRequestAllAdUnits.restore(); utils.getBidRequest.restore(); + cookie.queueSync.restore(); + cookie.persist.restore(); }); // TODO: test dependent on pbjs_api_spec. Needs to be isolated @@ -267,5 +313,42 @@ describe('S2S Adapter', () => { const response = bidmanager.addBidResponse.firstCall.args[1]; expect(response).to.have.property('dealId', 'test-dealid'); }); + + it('registers bid responses when server requests cookie sync', () => { + server.respondWith(JSON.stringify(RESPONSE_NO_PBS_COOKIE)); + + adapter.setConfig(CONFIG); + adapter.callBids(REQUEST); + server.respond(); + sinon.assert.calledOnce(bidmanager.addBidResponse); + + const ad_unit_code = bidmanager.addBidResponse.firstCall.args[0]; + expect(ad_unit_code).to.equal('div-gpt-ad-1460505748561-0'); + + const response = bidmanager.addBidResponse.firstCall.args[1]; + expect(response).to.have.property('statusMessage', 'Bid available'); + expect(response).to.have.property('source', 's2s'); + + const bid_request_passed = bidmanager.addBidResponse.firstCall.args[1]; + expect(bid_request_passed).to.have.property('adId', '123'); + }); + + it('queue cookie sync when no_cookie response', () => { + server.respondWith(JSON.stringify(RESPONSE_NO_PBS_COOKIE)); + + adapter.setConfig(CONFIG); + adapter.callBids(REQUEST); + server.respond(); + sinon.assert.calledTwice(cookie.queueSync); + }); + + it('persist cookie sync when no_cookie response', () => { + server.respondWith(JSON.stringify(RESPONSE_NO_PBS_COOKIE)); + + adapter.setConfig(CONFIG); + adapter.callBids(REQUEST); + server.respond(); + sinon.assert.calledOnce(cookie.persist); + }); }); }); From a9c1d06894f892b4d12e5d16215bda95acdbcb9c Mon Sep 17 00:00:00 2001 From: Rich Snapp Date: Thu, 29 Jun 2017 15:54:26 -0600 Subject: [PATCH 45/95] Clean up gulp task dependencies, fixes #1333 and #1334 (#1336) --- gulpfile.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 5a7b588820f..9efdda3ce98 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -36,13 +36,13 @@ var analyticsDirectory = '../analytics'; var port = 9999; // Tasks -gulp.task('default', ['clean', 'webpack']); +gulp.task('default', ['webpack']); -gulp.task('serve', ['clean', 'lint', 'build-bundle-dev', 'watch', 'test']); +gulp.task('serve', ['lint', 'build-bundle-dev', 'watch', 'test']); -gulp.task('serve-nw', ['clean', 'lint', 'devpack', 'webpack', 'watch', 'e2etest']); +gulp.task('serve-nw', ['lint', 'watch', 'e2etest']); -gulp.task('run-tests', ['clean', 'lint', 'webpack', 'test']); +gulp.task('run-tests', ['lint', 'test']); gulp.task('build', ['build-bundle-prod']); @@ -132,7 +132,7 @@ gulp.task('webpack', ['clean'], function () { }); //zip up for release -gulp.task('zip', ['clean', 'webpack'], function () { +gulp.task('zip', ['webpack'], function () { return gulp.src(['build/dist/*', 'integrationExamples/gpt/*']) .pipe(zip(packageNameVersion + '.zip')) .pipe(gulp.dest('./')); @@ -222,7 +222,6 @@ gulp.task('watch', function () { 'loaders/**/*.js', 'test/spec/loaders/**/*.js' ], ['lint']); - gulp.watch(['integrationExamples/gpt/*.html'], ['test']); connect.server({ https: argv.https, port: port, @@ -252,7 +251,7 @@ gulp.task('docs', ['clean-docs'], function () { .pipe(gulp.dest('docs')); }); -gulp.task('e2etest', function() { +gulp.task('e2etest', ['devpack', 'webpack'], function() { var cmdQueue = []; if(argv.browserstack) { var browsers = require('./browsers.json'); From d0b73f4c3e27111a6db157a36f68b0c37faa4d4b Mon Sep 17 00:00:00 2001 From: Matt Lane Date: Fri, 30 Jun 2017 07:03:39 -0700 Subject: [PATCH 46/95] Remove unused zip task (#1339) --- gulpfile.js | 8 -------- package.json | 1 - 2 files changed, 9 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 9efdda3ce98..d0da499048a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -18,7 +18,6 @@ var gulpJsdoc2md = require('gulp-jsdoc-to-markdown'); var concat = require('gulp-concat'); var header = require('gulp-header'); var footer = require('gulp-footer'); -var zip = require('gulp-zip'); var replace = require('gulp-replace'); var shell = require('gulp-shell'); var optimizejs = require('gulp-optimize-js'); @@ -131,13 +130,6 @@ gulp.task('webpack', ['clean'], function () { .pipe(connect.reload()); }); -//zip up for release -gulp.task('zip', ['webpack'], function () { - return gulp.src(['build/dist/*', 'integrationExamples/gpt/*']) - .pipe(zip(packageNameVersion + '.zip')) - .pipe(gulp.dest('./')); -}); - // Karma Continuous Testing // Pass your browsers by using --browsers=chrome,firefox,ie9 // Run CI by passing --watch diff --git a/package.json b/package.json index abe66a0aca3..a115545f597 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,6 @@ "gulp-uglify": "^0.3.1", "gulp-util": "^3.0.0", "gulp-webdriver": "^1.0.1", - "gulp-zip": "^3.1.0", "istanbul": "^0.3.2", "istanbul-instrumenter-loader": "^0.1.2", "json-loader": "^0.5.1", From 27fe1c272867207b0974bff7024c8ebd06784f6d Mon Sep 17 00:00:00 2001 From: Matt Kendall Date: Fri, 30 Jun 2017 12:47:57 -0400 Subject: [PATCH 47/95] Improvement/rad 1689 s2s drop empty bid (#1330) * fix sending empty bids + tests * add unit tests * Include `src` on bidRequest object. --- modules/prebidServerBidAdapter.js | 6 +-- src/adaptermanager.js | 13 +++++-- src/constants.json | 3 +- test/spec/core/adapterManager_spec.js | 55 +++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 test/spec/core/adapterManager_spec.js diff --git a/modules/prebidServerBidAdapter.js b/modules/prebidServerBidAdapter.js index 3cd698c7ccd..67348059f5f 100644 --- a/modules/prebidServerBidAdapter.js +++ b/modules/prebidServerBidAdapter.js @@ -3,11 +3,11 @@ import bidfactory from 'src/bidfactory'; import bidmanager from 'src/bidmanager'; import * as utils from 'src/utils'; import { ajax } from 'src/ajax'; -import { STATUS } from 'src/constants'; +import { STATUS, S2S } from 'src/constants'; import { queueSync, persist } from 'src/cookie'; import adaptermanager from 'src/adaptermanager'; -const TYPE = 's2s'; +const TYPE = S2S.SRC; const cookiePersistMessage = `Your browser may be blocking 3rd party cookies. By clicking on this page you allow Prebid Server and other advertising partners to place cookies to help us advertise. You can opt out of their cookies here.`; const cookiePersistUrl = '//ib.adnxs.com/seg?add=1&redir='; @@ -185,6 +185,6 @@ PrebidServer.createNew = function() { return new PrebidServer(); }; -adaptermanager.registerBidAdapter(new PrebidServer, 'prebidServer'); +adaptermanager.registerBidAdapter(new PrebidServer(), 'prebidServer'); module.exports = PrebidServer; diff --git a/src/adaptermanager.js b/src/adaptermanager.js index 7aa9a4f8cb4..bafe77f6fc1 100644 --- a/src/adaptermanager.js +++ b/src/adaptermanager.js @@ -90,6 +90,11 @@ exports.callBids = ({adUnits, cbTimeout}) => { }); }); + // don't send empty requests + adUnitsCopy = adUnitsCopy.filter(adUnit => { + return adUnit.bids.length !== 0; + }); + let tid = utils.generateUUID(); adaptersServerSide.forEach(bidderCode => { const bidderRequestId = utils.getUniqueIdentifierStr(); @@ -101,10 +106,12 @@ exports.callBids = ({adUnits, cbTimeout}) => { bids: getBids({bidderCode, requestId, bidderRequestId, 'adUnits': adUnitsCopy}), start: new Date().getTime(), auctionStart: auctionStart, - timeout: _s2sConfig.timeout + timeout: _s2sConfig.timeout, + src: CONSTANTS.S2S.SRC }; - // Pushing server side bidder - $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); + if (bidderRequest.bids.length !== 0) { + $$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); + } }); let s2sBidRequest = {tid, 'ad_units': adUnitsCopy}; diff --git a/src/constants.json b/src/constants.json index 4cf0aac447d..e64828d4474 100644 --- a/src/constants.json +++ b/src/constants.json @@ -61,6 +61,7 @@ "hb_deal" ], "S2S" : { - "DEFAULT_ENDPOINT" : "https://prebid.adnxs.com/pbs/v1/auction" + "DEFAULT_ENDPOINT" : "https://prebid.adnxs.com/pbs/v1/auction", + "SRC" : "s2s" } } diff --git a/test/spec/core/adapterManager_spec.js b/test/spec/core/adapterManager_spec.js new file mode 100644 index 00000000000..79f20534174 --- /dev/null +++ b/test/spec/core/adapterManager_spec.js @@ -0,0 +1,55 @@ +import { expect } from 'chai'; +import AdapterManager from 'src/adaptermanager'; +import { getAdUnits } from 'test/fixtures/fixtures'; +import CONSTANTS from 'src/constants.json'; + +const CONFIG = { + enabled: true, + endpoint: CONSTANTS.S2S.DEFAULT_ENDPOINT, + timeout: 1000, + maxBids: 1, + adapter: 'prebidServer', + bidders: ['appnexus'] +}; +var prebidServerAdapterMock = { + bidder: 'prebidServer', + callBids: sinon.stub(), + setConfig: sinon.stub() +}; + +describe('adapterManager tests', () => { + describe('S2S tests', () => { + beforeEach(() => { + AdapterManager.setS2SConfig(CONFIG); + AdapterManager.bidderRegistry['prebidServer'] = prebidServerAdapterMock; + prebidServerAdapterMock.callBids.reset(); + }); + + it('invokes callBids on the S2S adapter', () => { + AdapterManager.callBids({adUnits: getAdUnits()}); + sinon.assert.calledOnce(prebidServerAdapterMock.callBids); + }); + + it('invokes callBids with only s2s bids', () => { + const adUnits = getAdUnits(); + // adUnit without appnexus bidder + adUnits.push({ + 'code': '123', + 'sizes': [300, 250], + 'bids': [ + { + 'bidder': 'adequant', + 'params': { + 'publisher_id': '1234567', + 'bidfloor': 0.01 + } + } + ] + }); + AdapterManager.callBids({adUnits: adUnits}); + const requestObj = prebidServerAdapterMock.callBids.firstCall.args[0]; + expect(requestObj.ad_units.length).to.equal(2); + sinon.assert.calledOnce(prebidServerAdapterMock.callBids); + }); + }); // end s2s tests +}); From 0f8de0c1f6d7b1463b0e105015d4c43d7e28c8a1 Mon Sep 17 00:00:00 2001 From: Rich Snapp Date: Wed, 5 Jul 2017 09:36:02 -0600 Subject: [PATCH 48/95] fixes #1331 module bundling on windows (#1332) --- gulpHelpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulpHelpers.js b/gulpHelpers.js index 5225cfb32e8..9ca2d242d81 100644 --- a/gulpHelpers.js +++ b/gulpHelpers.js @@ -67,7 +67,7 @@ module.exports = { internalModules = fs.readdirSync(MODULE_PATH) .filter(file => !(/(^|\/)\.[^\/\.]/g).test(file)) .reduce((memo, file) => { - var moduleName = file.split(new RegExp('[.' + path.sep + ']'))[0]; + var moduleName = file.split(new RegExp('[.\\' + path.sep + ']'))[0]; var filePath = path.join(MODULE_PATH, file); var modulePath = path.join(__dirname, filePath) if (fs.lstatSync(filePath).isDirectory()) { From 8bf983c2b1e543388bcedf491884714e387c925b Mon Sep 17 00:00:00 2001 From: Matt Kendall Date: Thu, 6 Jul 2017 10:50:59 -0400 Subject: [PATCH 49/95] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 947ddbf2dfd..ce51b04515f 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,7 @@ For instructions on writing tests for Prebid.js, see [Testing Prebid.js](http:// ### Supported Browsers -Prebid.js is supported on IE9+ and modern browsers. +Prebid.js is supported on IE10+ and modern browsers. ### Governance Review our governance model [here](https://github.com/prebid/Prebid.js/tree/master/governance.md). From 5897f0b9a60f9612202a407c953798091c94bb13 Mon Sep 17 00:00:00 2001 From: dbemiller Date: Thu, 6 Jul 2017 15:25:31 -0400 Subject: [PATCH 50/95] Upgrade eslint (#1346) * Replaced the deprecated .eslintrc format with a supported .eslintrc.js one * Updated versions of things for Node 8. * Added exceptions for the new rules. * Added a missing semicolon. * Updated the yarn lockfile. * Removed the new exceptions, and ran eslint --fix on the src and test directories. --- .eslintrc => .eslintrc.js | 4 +- package.json | 6 +- src/AnalyticsAdapter.js | 2 +- src/adaptermanager.js | 2 +- src/adapters/analytics/example2.js | 12 +- src/bidmanager.js | 8 +- src/targeting.js | 22 +- src/utils.js | 4 +- test/{.eslintrc => .eslintrc.js} | 4 +- test/helpers/index_adapter_utils.js | 4 +- test/spec/AnalyticsAdapter_spec.js | 212 ++--- test/spec/core/adapterManager_spec.js | 2 +- test/spec/cpmBucketManager_spec.js | 2 +- test/spec/modules/aardvarkBidAdapter_spec.js | 2 +- test/spec/modules/adbundBidAdapter_spec.js | 20 +- test/spec/modules/adsupplyBidAdapter_spec.js | 18 +- .../spec/modules/beachfrontBidAdapter_spec.js | 12 +- test/spec/modules/centroBidAdapter_spec.js | 4 +- .../modules/huddledmassesBidAdapter_spec.js | 22 +- .../indexExchangeBidAdapter_request_spec.js | 2 +- .../indexExchangeBidAdapter_response_spec.js | 70 +- ...ndexExchangeBidAdapter_validadtion_spec.js | 38 +- .../modules/inneractiveBidAdapter_spec.js | 14 +- test/spec/modules/jcmBidAdapter_spec.js | 2 +- test/spec/modules/komoonaBidAdapter_spec.js | 2 +- test/spec/modules/mantisBidAdapter_spec.js | 4 +- .../spec/modules/memeglobalBidAdapter_spec.js | 12 +- test/spec/modules/piximediaBidAdapter_spec.js | 4 +- test/spec/modules/pubgearsBidAdapter_spec.js | 4 +- test/spec/modules/rubiconBidAdapter_spec.js | 2 +- test/spec/modules/smartyadsBidAdapter_spec.js | 22 +- .../modules/stickyadstvBidAdapter_spec.js | 2 +- test/spec/modules/twengaBidAdapter_spec.js | 6 +- .../modules/underdogmediaBidAdapter_spec.js | 4 +- .../spec/modules/vertamediaBidAdapter_spec.js | 12 +- test/spec/modules/vertozBidAdapter_spec.js | 6 +- test/spec/modules/wideorbitBidAdapter_spec.js | 450 +++++----- test/spec/modules/widespaceBidAdapter_spec.js | 4 +- test/spec/sizeMapping_spec.js | 2 +- test/spec/unit/pbjs_api_spec.js | 2 +- yarn.lock | 815 ++++++++++-------- 41 files changed, 946 insertions(+), 895 deletions(-) rename .eslintrc => .eslintrc.js (98%) rename test/{.eslintrc => .eslintrc.js} (98%) diff --git a/.eslintrc b/.eslintrc.js similarity index 98% rename from .eslintrc rename to .eslintrc.js index cd5dd0cb267..706768d6a45 100644 --- a/.eslintrc +++ b/.eslintrc.js @@ -1,4 +1,4 @@ -{ +module.exports = { "env": { "browser": true, "commonjs": true @@ -39,4 +39,4 @@ "standard/object-curly-even-spacing": "off", "valid-typeof": "off" } -} +}; diff --git a/package.json b/package.json index a115545f597..8fdfec1f680 100644 --- a/package.json +++ b/package.json @@ -32,9 +32,9 @@ "del": "^2.2.0", "ejs": "^2.5.1", "es5-shim": "^4.5.2", - "eslint-config-standard": "^10.2.0", + "eslint-config-standard": "^10.2.1", "eslint-plugin-import": "^2.2.0", - "eslint-plugin-node": "^4.2.2", + "eslint-plugin-node": "^5.1.0", "eslint-plugin-promise": "^3.5.0", "eslint-plugin-standard": "^3.0.1", "faker": "^3.1.0", @@ -44,7 +44,7 @@ "gulp-clean": "^0.3.2", "gulp-concat": "^2.6.0", "gulp-connect": "^2.0.6", - "gulp-eslint": "^3.0.1", + "gulp-eslint": "^4.0.0", "gulp-footer": "^1.0.5", "gulp-header": "^1.7.1", "gulp-if": "^2.0.2", diff --git a/src/AnalyticsAdapter.js b/src/AnalyticsAdapter.js index 58c5048f929..badc764d5cf 100644 --- a/src/AnalyticsAdapter.js +++ b/src/AnalyticsAdapter.js @@ -108,7 +108,7 @@ export default function AnalyticsAdapter({ url, analyticsType, global, handler } [BID_ADJUSTMENT]: args => this.enqueue({ eventType: BID_ADJUSTMENT, args }), [AUCTION_END]: args => this.enqueue({ eventType: AUCTION_END, args }), [AUCTION_INIT]: args => { - args.config = config.options; // enableAnaltyics configuration object + args.config = config.options; // enableAnaltyics configuration object this.enqueue({ eventType: AUCTION_INIT, args }); } }; diff --git a/src/adaptermanager.js b/src/adaptermanager.js index bafe77f6fc1..08b637e7712 100644 --- a/src/adaptermanager.js +++ b/src/adaptermanager.js @@ -161,7 +161,7 @@ function transformHeightWidth(adUnit) { return sizesObj; } -exports.videoAdapters = []; // added by adapterLoader for now +exports.videoAdapters = []; // added by adapterLoader for now exports.registerBidAdapter = function (bidAdaptor, bidderCode, {supportedMediaTypes = []} = {}) { if (bidAdaptor && bidderCode) { diff --git a/src/adapters/analytics/example2.js b/src/adapters/analytics/example2.js index 8a9b8beb3ec..6888507010d 100644 --- a/src/adapters/analytics/example2.js +++ b/src/adapters/analytics/example2.js @@ -15,10 +15,10 @@ export default Object.assign(adapter( analyticsType } ), - { +{ // Override AnalyticsAdapter functions by supplying custom methods - track({ eventType, args }) { - console.log('track function override for Example2 Analytics'); - ajax(url, (result) => console.log('Analytics Endpoint Example2: result = ' + result), JSON.stringify({ eventType, args })); - } - }); + track({ eventType, args }) { + console.log('track function override for Example2 Analytics'); + ajax(url, (result) => console.log('Analytics Endpoint Example2: result = ' + result), JSON.stringify({ eventType, args })); + } +}); diff --git a/src/bidmanager.js b/src/bidmanager.js index 895f224cecf..2f1cad4dbf0 100644 --- a/src/bidmanager.js +++ b/src/bidmanager.js @@ -50,8 +50,8 @@ function bidsBackAdUnit(adUnitCode) { .reduce(flatten, []) .map(bid => { return bid.bidder === 'indexExchange' - ? bid.sizes.length - : 1; + ? bid.sizes.length + : 1; }).reduce(add, 0); const received = $$PREBID_GLOBAL$$._bidsReceived.filter(bid => bid.adUnitCode === adUnitCode).length; @@ -293,8 +293,8 @@ function processCallbacks(callbackQueue, singleAdUnitCode) { callbackQueue.forEach(callback => { const adUnitCodes = singleAdUnitCode || $$PREBID_GLOBAL$$._adUnitCodes; const bids = [$$PREBID_GLOBAL$$._bidsReceived - .filter(adUnitsFilter.bind(this, adUnitCodes)) - .reduce(groupByPlacement, {})]; + .filter(adUnitsFilter.bind(this, adUnitCodes)) + .reduce(groupByPlacement, {})]; callback.apply($$PREBID_GLOBAL$$, bids); }); diff --git a/src/targeting.js b/src/targeting.js index 2d5e75e38a7..90b93ce191e 100644 --- a/src/targeting.js +++ b/src/targeting.js @@ -31,8 +31,8 @@ targeting.getAllTargeting = function(adUnitCode) { // Get targeting for the winning bid. Add targeting for any bids that have // `alwaysUseBid=true`. If sending all bids is enabled, add targeting for losing bids. var targeting = getWinningBidTargeting(adUnitCodes) - .concat(getAlwaysUseBidTargeting(adUnitCodes)) - .concat($$PREBID_GLOBAL$$._sendAllBids ? getBidLandscapeTargeting(adUnitCodes) : []); + .concat(getAlwaysUseBidTargeting(adUnitCodes)) + .concat($$PREBID_GLOBAL$$._sendAllBids ? getBidLandscapeTargeting(adUnitCodes) : []); // store a reference of the targeting keys targeting.map(adUnitCode => { @@ -96,12 +96,12 @@ targeting.getWinningBids = function(adUnitCode) { .map(adUnitCode => $$PREBID_GLOBAL$$._bidsReceived .filter(bid => bid.adUnitCode === adUnitCode ? bid : null) .reduce(getHighestCpm, - { - adUnitCode: adUnitCode, - cpm: 0, - adserverTargeting: {}, - timeToRespond: 0 - })); + { + adUnitCode: adUnitCode, + cpm: 0, + adserverTargeting: {}, + timeToRespond: 0 + })); }; targeting.setTargetingForAst = function() { @@ -141,9 +141,9 @@ function getWinningBidTargeting(adUnitCodes) { } function getStandardKeys() { - return bidmanager.getStandardBidderAdServerTargeting() // in case using a custom standard key set - .map(targeting => targeting.key) - .concat(CONSTANTS.TARGETING_KEYS).filter(uniques); // standard keys defined in the library. + return bidmanager.getStandardBidderAdServerTargeting() // in case using a custom standard key set + .map(targeting => targeting.key) + .concat(CONSTANTS.TARGETING_KEYS).filter(uniques); // standard keys defined in the library. } /** diff --git a/src/utils.js b/src/utils.js index 4b7ed3dea27..ba608a1f1b7 100644 --- a/src/utils.js +++ b/src/utils.js @@ -90,7 +90,7 @@ exports.parseQueryStringParameters = function (queryObj) { var result = ''; for (var k in queryObj) { if (queryObj.hasOwnProperty(k)) - { result += k + '=' + encodeURIComponent(queryObj[k]) + '&'; } + { result += k + '=' + encodeURIComponent(queryObj[k]) + '&'; } } return result; @@ -663,6 +663,6 @@ export function getBidderRequestAllAdUnits(bidder) { export function getBidderRequest(bidder, adUnitCode) { return $$PREBID_GLOBAL$$._bidsRequested.find(request => { return request.bids - .filter(bid => bid.bidder === bidder && bid.placementCode === adUnitCode).length > 0; + .filter(bid => bid.bidder === bidder && bid.placementCode === adUnitCode).length > 0; }) || { start: null, requestId: null }; } diff --git a/test/.eslintrc b/test/.eslintrc.js similarity index 98% rename from test/.eslintrc rename to test/.eslintrc.js index bdbda915293..29f57acb446 100644 --- a/test/.eslintrc +++ b/test/.eslintrc.js @@ -1,4 +1,4 @@ -{ +module.exports = { "env": { "browser": true, "mocha": true @@ -47,4 +47,4 @@ "standard/no-callback-literal": "off", "standard/object-curly-even-spacing": "off" } -} +}; diff --git a/test/helpers/index_adapter_utils.js b/test/helpers/index_adapter_utils.js index 9c1063bf026..716ec1ff4f3 100644 --- a/test/helpers/index_adapter_utils.js +++ b/test/helpers/index_adapter_utils.js @@ -46,7 +46,7 @@ function _createBidSlot(placementCode, indexSlotID, sizes, config) { bid.params.siteID = ('siteID' in config) ? config.siteID : DefaultSiteID; bid.sizes = sizes; - // optional parameter + // optional parameter if (typeof config.timeout !== 'undefined') { bid.params.timeout = config.timeout; } @@ -60,7 +60,7 @@ function _createBidSlot(placementCode, indexSlotID, sizes, config) { bid.params.size = config.slotSize; } - // special parameter + // special parameter if (typeof (config.missingSlotID) !== 'undefined') { delete bid.params.id; } diff --git a/test/spec/AnalyticsAdapter_spec.js b/test/spec/AnalyticsAdapter_spec.js index 822ce76b081..3eeb5a9efee 100644 --- a/test/spec/AnalyticsAdapter_spec.js +++ b/test/spec/AnalyticsAdapter_spec.js @@ -21,152 +21,152 @@ FEATURE: Analytics Adapters API SCENARIO: A publisher enables analytics GIVEN a global object \`window['testGlobal']\` AND an \`example\` instance of \`AnalyticsAdapter\`\n`, () => { - describe(`WHEN an event occurs that is to be tracked\n`, () => { - const eventType = BID_REQUESTED; - const args = { some: 'data' }; - const adapter = new AnalyticsAdapter(config); - var spyTestGlobal = sinon.spy(window, config.global); - - adapter.track({ eventType, args }); - - it(`THEN should call \`window.${config.global}\` function\n`, () => { - assert.ok(spyTestGlobal.args[0][1] === eventType, `with expected event type\n`); - assert.deepEqual(spyTestGlobal.args[0][2], args, `with expected event data\n`); - }); - window[config.global].restore(); - }); - - describe(`WHEN an event occurs before tracking library is available\n`, () => { - const eventType = BID_RESPONSE; - const args = { wat: 'wot' }; - const adapter = new AnalyticsAdapter(config); - - window[config.global] = null; - events.emit(BID_RESPONSE, args); - - describe(`AND the adapter is then enabled\n`, () => { - window[config.global] = () => {}; - + describe(`WHEN an event occurs that is to be tracked\n`, () => { + const eventType = BID_REQUESTED; + const args = { some: 'data' }; + const adapter = new AnalyticsAdapter(config); var spyTestGlobal = sinon.spy(window, config.global); - adapter.enableAnalytics(); + adapter.track({ eventType, args }); - it(`THEN should queue the event first and then track it\n`, () => { + it(`THEN should call \`window.${config.global}\` function\n`, () => { assert.ok(spyTestGlobal.args[0][1] === eventType, `with expected event type\n`); assert.deepEqual(spyTestGlobal.args[0][2], args, `with expected event data\n`); }); - - adapter.disableAnalytics(); window[config.global].restore(); }); - }); - describe(`WHEN an event occurs after enable analytics\n`, () => { - var spyTestGlobal, - adapter; + describe(`WHEN an event occurs before tracking library is available\n`, () => { + const eventType = BID_RESPONSE; + const args = { wat: 'wot' }; + const adapter = new AnalyticsAdapter(config); - beforeEach(() => { - adapter = new AnalyticsAdapter(config); - spyTestGlobal = sinon.spy(window, config.global); + window[config.global] = null; + events.emit(BID_RESPONSE, args); - sinon.stub(events, 'getEvents', () => []); // these tests shouldn't be affected by previous tests - }); + describe(`AND the adapter is then enabled\n`, () => { + window[config.global] = () => {}; - afterEach(() => { - adapter.disableAnalytics(); - window[config.global].restore(); + var spyTestGlobal = sinon.spy(window, config.global); - events.getEvents.restore(); - }); + adapter.enableAnalytics(); - it('SHOULD call global when a bidWon event occurs', () => { - const eventType = BID_WON; - const args = { more: 'info' }; - - adapter.enableAnalytics(); - events.emit(eventType, args); + it(`THEN should queue the event first and then track it\n`, () => { + assert.ok(spyTestGlobal.args[0][1] === eventType, `with expected event type\n`); + assert.deepEqual(spyTestGlobal.args[0][2], args, `with expected event data\n`); + }); - assert.ok(spyTestGlobal.args[0][1] === eventType, `with expected event type\n`); - assert.deepEqual(spyTestGlobal.args[0][2], args, `with expected event data\n`); + adapter.disableAnalytics(); + window[config.global].restore(); + }); }); - it('SHOULD call global when a bidRequest event occurs', () => { - const eventType = BID_REQUESTED; - const args = { call: 'request' }; + describe(`WHEN an event occurs after enable analytics\n`, () => { + var spyTestGlobal, + adapter; - adapter.enableAnalytics(); - events.emit(eventType, args); + beforeEach(() => { + adapter = new AnalyticsAdapter(config); + spyTestGlobal = sinon.spy(window, config.global); - assert.ok(spyTestGlobal.args[0][1] === eventType, `with expected event type\n`); - assert.deepEqual(spyTestGlobal.args[0][2], args, `with expected event data\n`); - }); + sinon.stub(events, 'getEvents', () => []); // these tests shouldn't be affected by previous tests + }); - it('SHOULD call global when a bidResponse event occurs', () => { - const eventType = BID_RESPONSE; - const args = { call: 'response' }; + afterEach(() => { + adapter.disableAnalytics(); + window[config.global].restore(); - adapter.enableAnalytics(); - events.emit(eventType, args); + events.getEvents.restore(); + }); - assert.ok(spyTestGlobal.args[0][1] === eventType, `with expected event type\n`); - assert.deepEqual(spyTestGlobal.args[0][2], args, `with expected event data\n`); - }); + it('SHOULD call global when a bidWon event occurs', () => { + const eventType = BID_WON; + const args = { more: 'info' }; - it('SHOULD call global when a bidTimeout event occurs', () => { - const eventType = BID_TIMEOUT; - const args = { call: 'timeout' }; + adapter.enableAnalytics(); + events.emit(eventType, args); - adapter.enableAnalytics(); - events.emit(eventType, args); + assert.ok(spyTestGlobal.args[0][1] === eventType, `with expected event type\n`); + assert.deepEqual(spyTestGlobal.args[0][2], args, `with expected event data\n`); + }); - assert.ok(spyTestGlobal.args[0][1] === eventType, `with expected event type\n`); - assert.deepEqual(spyTestGlobal.args[0][2], args, `with expected event data\n`); - }); + it('SHOULD call global when a bidRequest event occurs', () => { + const eventType = BID_REQUESTED; + const args = { call: 'request' }; - it('SHOULD NOT call global again when adapter.enableAnalytics is called with previous timeout', () => { - const eventType = BID_TIMEOUT; - const args = { call: 'timeout' }; + adapter.enableAnalytics(); + events.emit(eventType, args); - events.emit(eventType, args); - adapter.enableAnalytics(); - events.emit(eventType, args); + assert.ok(spyTestGlobal.args[0][1] === eventType, `with expected event type\n`); + assert.deepEqual(spyTestGlobal.args[0][2], args, `with expected event data\n`); + }); - assert(spyTestGlobal.calledOnce === true); - }); + it('SHOULD call global when a bidResponse event occurs', () => { + const eventType = BID_RESPONSE; + const args = { call: 'response' }; - describe(`AND sampling is enabled\n`, () => { - const eventType = BID_WON; - const args = { more: 'info' }; + adapter.enableAnalytics(); + events.emit(eventType, args); - beforeEach(() => { - sinon.stub(Math, 'random', () => 0.5); + assert.ok(spyTestGlobal.args[0][1] === eventType, `with expected event type\n`); + assert.deepEqual(spyTestGlobal.args[0][2], args, `with expected event data\n`); }); - afterEach(() => { - Math.random.restore(); + it('SHOULD call global when a bidTimeout event occurs', () => { + const eventType = BID_TIMEOUT; + const args = { call: 'timeout' }; + + adapter.enableAnalytics(); + events.emit(eventType, args); + + assert.ok(spyTestGlobal.args[0][1] === eventType, `with expected event type\n`); + assert.deepEqual(spyTestGlobal.args[0][2], args, `with expected event data\n`); }); - it(`THEN should enable analytics when random number is in sample range`, () => { - adapter.enableAnalytics({ - options: { - sampling: 0.75 - } - }); + it('SHOULD NOT call global again when adapter.enableAnalytics is called with previous timeout', () => { + const eventType = BID_TIMEOUT; + const args = { call: 'timeout' }; + + events.emit(eventType, args); + adapter.enableAnalytics(); events.emit(eventType, args); - assert(spyTestGlobal.called === true); + assert(spyTestGlobal.calledOnce === true); }); - it(`THEN should disable analytics when random number is outside sample range`, () => { - adapter.enableAnalytics({ - options: { - sampling: 0.25 - } + describe(`AND sampling is enabled\n`, () => { + const eventType = BID_WON; + const args = { more: 'info' }; + + beforeEach(() => { + sinon.stub(Math, 'random', () => 0.5); }); - events.emit(eventType, args); - assert(spyTestGlobal.called === false); + afterEach(() => { + Math.random.restore(); + }); + + it(`THEN should enable analytics when random number is in sample range`, () => { + adapter.enableAnalytics({ + options: { + sampling: 0.75 + } + }); + events.emit(eventType, args); + + assert(spyTestGlobal.called === true); + }); + + it(`THEN should disable analytics when random number is outside sample range`, () => { + adapter.enableAnalytics({ + options: { + sampling: 0.25 + } + }); + events.emit(eventType, args); + + assert(spyTestGlobal.called === false); + }); }); }); }); -}); diff --git a/test/spec/core/adapterManager_spec.js b/test/spec/core/adapterManager_spec.js index 79f20534174..45c37cc2267 100644 --- a/test/spec/core/adapterManager_spec.js +++ b/test/spec/core/adapterManager_spec.js @@ -32,7 +32,7 @@ describe('adapterManager tests', () => { it('invokes callBids with only s2s bids', () => { const adUnits = getAdUnits(); - // adUnit without appnexus bidder + // adUnit without appnexus bidder adUnits.push({ 'code': '123', 'sizes': [300, 250], diff --git a/test/spec/cpmBucketManager_spec.js b/test/spec/cpmBucketManager_spec.js index 18ca2c38bdd..1590a647417 100644 --- a/test/spec/cpmBucketManager_spec.js +++ b/test/spec/cpmBucketManager_spec.js @@ -43,7 +43,7 @@ describe('cpmBucketManager', () => { 'increment': 0.01, }, { - // missing min prop + // missing min prop 'max': 18, 'increment': 0.05, 'cap': true diff --git a/test/spec/modules/aardvarkBidAdapter_spec.js b/test/spec/modules/aardvarkBidAdapter_spec.js index 5edf7ce0b25..9ea97dcccc5 100644 --- a/test/spec/modules/aardvarkBidAdapter_spec.js +++ b/test/spec/modules/aardvarkBidAdapter_spec.js @@ -67,7 +67,7 @@ describe('aardvark adapter tests', function () { ] }, - // respond + // respond bidderResponse = [ { 'adm': '
', diff --git a/test/spec/modules/adbundBidAdapter_spec.js b/test/spec/modules/adbundBidAdapter_spec.js index 9ee9e9ccfe7..da9b2e2e9b9 100644 --- a/test/spec/modules/adbundBidAdapter_spec.js +++ b/test/spec/modules/adbundBidAdapter_spec.js @@ -56,21 +56,21 @@ describe('adbund adapter tests', function () { bidderRequest = adapter.callBids.getCall(0).args[0]; expect(bidderRequest).to.have.property('bids') - .that.is.an('array') - .with.lengthOf(1); + .that.is.an('array') + .with.lengthOf(1); expect(bidderRequest).to.have.deep.property('bids[0]') - .to.have.property('bidder', 'adbund'); + .to.have.property('bidder', 'adbund'); expect(bidderRequest).to.have.deep.property('bids[0]') - .with.property('sizes') - .that.is.an('array') - .with.lengthOf(1) - .that.deep.equals(request.bids[0].sizes); + .with.property('sizes') + .that.is.an('array') + .with.lengthOf(1) + .that.deep.equals(request.bids[0].sizes); expect(bidderRequest).to.have.deep.property('bids[0]') - .with.property('params') - .to.have.property('bidfloor', 0.036); + .with.property('params') + .to.have.property('bidfloor', 0.036); }); it('Valid bid-response', () => { @@ -79,7 +79,7 @@ describe('adbund adapter tests', function () { sandbox.stub(bidManager, 'addBidResponse'); adapter.callBids(request); bidderResponse = bidManager.addBidResponse.getCall(0) || - bidManager.addBidResponse.getCall(1); + bidManager.addBidResponse.getCall(1); if (bidderResponse && bidderResponse.args && bidderResponse.args[1]) { bidderResponse = bidderResponse.args[1]; diff --git a/test/spec/modules/adsupplyBidAdapter_spec.js b/test/spec/modules/adsupplyBidAdapter_spec.js index 040c08e0ac1..4d089aaa0ef 100644 --- a/test/spec/modules/adsupplyBidAdapter_spec.js +++ b/test/spec/modules/adsupplyBidAdapter_spec.js @@ -236,17 +236,17 @@ describe('adsupply adapter tests', function () { it('Response handler invalid data', function () { let stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); - // adapter needs to be called, in order for the stub to register. + // adapter needs to be called, in order for the stub to register. new AdSupplyAdapter(); - // bidId is not valid + // bidId is not valid pbjs.adSupplyResponseHandler(null); - // bidRequest object is not found + // bidRequest object is not found pbjs.adSupplyResponseHandler('bidId1'); let clientId = 'g5d384afa-c050-4bac-b202-dab8fb06e381'; - // Zone property is not found + // Zone property is not found let bidderRequest = { bidderCode: 'adsupply', bids: [{ @@ -264,7 +264,7 @@ describe('adsupply adapter tests', function () { pbjs._bidsRequested.push(bidderRequest); pbjs.adSupplyResponseHandler('bidId1'); - // Media is not found + // Media is not found window[clientId] = window[clientId] || {}; window[clientId]['b111'] = window[clientId]['b111'] || {}; pbjs.adSupplyResponseHandler('bidId1'); @@ -277,11 +277,11 @@ describe('adsupply adapter tests', function () { it('No Fill response', function () { let stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); - // adapter needs to be called, in order for the stub to register. + // adapter needs to be called, in order for the stub to register. new AdSupplyAdapter(); let clientId = 'g5d384afa-c050-4bac-b202-dab8fb06e381'; - // Zone property is not found + // Zone property is not found let bidderRequest = { bidderCode: 'adsupply', bids: [{ @@ -318,11 +318,11 @@ describe('adsupply adapter tests', function () { it('Fill response', function () { let stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); - // adapter needs to be called, in order for the stub to register. + // adapter needs to be called, in order for the stub to register. new AdSupplyAdapter(); let clientId = 'g5d384afa-c050-4bac-b202-dab8fb06e381'; - // Zone property is not found + // Zone property is not found let bidderRequest = { bidderCode: 'adsupply', bids: [{ diff --git a/test/spec/modules/beachfrontBidAdapter_spec.js b/test/spec/modules/beachfrontBidAdapter_spec.js index ad313acc84a..0b0f868f108 100644 --- a/test/spec/modules/beachfrontBidAdapter_spec.js +++ b/test/spec/modules/beachfrontBidAdapter_spec.js @@ -109,9 +109,9 @@ describe('BeachfrontAdapter', () => { const response = bidmanager.addBidResponse.firstCall.args[1]; expect(response).to.have.property( - 'statusMessage', - 'Bid returned empty or error response' - ); + 'statusMessage', + 'Bid returned empty or error response' + ); }); it('handles JSON.parse errors', () => { @@ -123,9 +123,9 @@ describe('BeachfrontAdapter', () => { const response = bidmanager.addBidResponse.firstCall.args[1]; expect(response).to.have.property( - 'statusMessage', - 'Bid returned empty or error response' - ); + 'statusMessage', + 'Bid returned empty or error response' + ); }); }); }); diff --git a/test/spec/modules/centroBidAdapter_spec.js b/test/spec/modules/centroBidAdapter_spec.js index 53283a92afe..d508c2c355d 100644 --- a/test/spec/modules/centroBidAdapter_spec.js +++ b/test/spec/modules/centroBidAdapter_spec.js @@ -150,9 +150,9 @@ describe('centro adapter tests', function () { adapter().callBids(params); expect(window['adCentroHandler_28136300x250%2F19968336%2Fheader-bid-tag-0']) - .to.exist.and.to.be.a('function'); + .to.exist.and.to.be.a('function'); expect(window['adCentroHandler_111111728x90%2F19968336%2Fheader-bid-tag-1']) - .to.exist.and.to.be.a('function'); + .to.exist.and.to.be.a('function'); }); it('bidmanager.addBidResponse should be called with correct arguments', function () { diff --git a/test/spec/modules/huddledmassesBidAdapter_spec.js b/test/spec/modules/huddledmassesBidAdapter_spec.js index 34218ed8e83..f4cc12dde1b 100644 --- a/test/spec/modules/huddledmassesBidAdapter_spec.js +++ b/test/spec/modules/huddledmassesBidAdapter_spec.js @@ -61,26 +61,26 @@ describe('HuddledMasses adapter tests', function () { let bidderRequest = adapter.callBids.getCall(0).args[0]; expect(bidderRequest).to.have.property('bids') - .that.is.an('array') - .with.lengthOf(1); + .that.is.an('array') + .with.lengthOf(1); expect(bidderRequest).to.have.deep.property('bids[0]') - .to.have.property('bidder', 'huddledmasses'); + .to.have.property('bidder', 'huddledmasses'); expect(bidderRequest).to.have.deep.property('bids[0]') - .with.property('sizes') - .that.is.an('array') - .with.lengthOf(2) - .that.deep.equals(adUnit.sizes); + .with.property('sizes') + .that.is.an('array') + .with.lengthOf(2) + .that.deep.equals(adUnit.sizes); expect(bidderRequest).to.have.deep.property('bids[0]') - .with.property('params') - .to.have.property('placement_id', 0); + .with.property('params') + .to.have.property('placement_id', 0); }); it('Valid bid-response', () => { server.respondWith(JSON.stringify( - response - )); + response + )); adapterManager.callBids({ adUnits: [clone(adUnit)] }); diff --git a/test/spec/modules/indexExchangeBidAdapter_request_spec.js b/test/spec/modules/indexExchangeBidAdapter_request_spec.js index 3a20b6a6d22..ef01e053a5c 100644 --- a/test/spec/modules/indexExchangeBidAdapter_request_spec.js +++ b/test/spec/modules/indexExchangeBidAdapter_request_spec.js @@ -282,7 +282,7 @@ describe('indexExchange adapter - Request', function () { var unsupportedSizeCount = 1; var requestSlotNumber = SlotThreshold; var configuredBids = IndexUtils.createBidSlots(requestSlotNumber); - // add additional unsupported sized slot + // add additional unsupported sized slot var invalidSlotPlacement = IndexUtils.DefaultPlacementCodePrefix + 'invalid'; var invalidSlotID = 'slot-invalid'; configuredBids.push(IndexUtils.createBidSlot(invalidSlotPlacement, invalidSlotID, [ IndexUtils.unsupportedSizes[0] ])); diff --git a/test/spec/modules/indexExchangeBidAdapter_response_spec.js b/test/spec/modules/indexExchangeBidAdapter_response_spec.js index 86a73a25c81..9285c6653be 100644 --- a/test/spec/modules/indexExchangeBidAdapter_response_spec.js +++ b/test/spec/modules/indexExchangeBidAdapter_response_spec.js @@ -156,7 +156,7 @@ describe('indexExchange adapter - Response', function () { var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); - // pass on bid on second size + // pass on bid on second size var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, undefined, undefined, [ [ false, true ] ]); cygnus_index_parse_res(asResponse); @@ -197,7 +197,7 @@ describe('indexExchange adapter - Response', function () { var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); - // pass on bid on all bids + // pass on bid on all bids var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, undefined, undefined, [ [ true, true ] ]); cygnus_index_parse_res(asResponse); @@ -270,8 +270,8 @@ describe('indexExchange adapter - Response', function () { var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); var passOnBid = [ - [ false ], // bids back on first slot - [ true ], // pass on bid on second slot + [ false ], // bids back on first slot + [ true ], // pass on bid on second slot ]; var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, undefined, undefined, passOnBid); cygnus_index_parse_res(asResponse); @@ -316,8 +316,8 @@ describe('indexExchange adapter - Response', function () { var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); var passOnBid = [ - [ true ], // pass on bid on the first slot - [ true ], // pass on bid on the second slot + [ true ], // pass on bid on the first slot + [ true ], // pass on bid on the second slot ]; var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, undefined, undefined, passOnBid); cygnus_index_parse_res(asResponse); @@ -354,7 +354,7 @@ describe('indexExchange adapter - Response', function () { adapter.callBids({ bids: configuredBids }); var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); - // first ix call + // first ix call var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, [ [requestParams.price] ], requestParams.request); cygnus_index_parse_res(asResponse); var expectedAdapterResponse = IndexUtils.getExpectedAdaptorResponse(configuredBids, asResponse); @@ -405,7 +405,7 @@ describe('indexExchange adapter - Response', function () { adapter.callBids({ bids: configuredBids }); var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); - // first ix call + // first ix call var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, [ [requestParams.price] ], requestParams.request); cygnus_index_parse_res(asResponse); @@ -456,7 +456,7 @@ describe('indexExchange adapter - Response', function () { adapter.callBids({ bids: configuredBids }); var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); - // first ix call + // first ix call var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, [ [requestParams.price] ], requestParams.request); cygnus_index_parse_res(asResponse); @@ -507,7 +507,7 @@ describe('indexExchange adapter - Response', function () { adapter.callBids({ bids: configuredBids }); var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); - // first ix call + // first ix call var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, [ [requestParams.price] ], requestParams.request, [ [ requestParams.passOnBid ] ]); cygnus_index_parse_res(asResponse); var expectedAdapterResponse = IndexUtils.getExpectedAdaptorResponse(configuredBids, asResponse); @@ -572,7 +572,7 @@ describe('indexExchange adapter - Response', function () { var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); var optionalResponseParam = [ [ - { ext: { dealid: 'ixDeal' } } // first slot first size + { ext: { dealid: 'ixDeal' } } // first slot first size ] ]; var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, undefined, undefined, undefined, optionalResponseParam); @@ -616,7 +616,7 @@ describe('indexExchange adapter - Response', function () { var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); var optionalResponseParam = [ [ - { ext: { dealid: '239' } } // first slot first size + { ext: { dealid: '239' } } // first slot first size ] ]; var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, undefined, undefined, undefined, optionalResponseParam); @@ -660,7 +660,7 @@ describe('indexExchange adapter - Response', function () { var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); var optionalResponseParam = [ [ - { ext: { dealid: '1234Deal' } } // first slot first size + { ext: { dealid: '1234Deal' } } // first slot first size ] ]; var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, undefined, undefined, undefined, optionalResponseParam); @@ -704,7 +704,7 @@ describe('indexExchange adapter - Response', function () { var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); var optionalResponseParam = [ [ - { ext: { dealid: 'deal1234' } } // first slot first size + { ext: { dealid: 'deal1234' } } // first slot first size ] ]; var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, undefined, undefined, undefined, optionalResponseParam); // Alpha numeric starting with non-numeric @@ -749,8 +749,8 @@ describe('indexExchange adapter - Response', function () { var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); var optionalResponseParam = [ [ - { ext: { deal: 'deal1', dealid: 'ixDealID1', dealname: 'deal name 1' } }, // first slot first size - { ext: { deal: 'deal2', dealid: 'ixDealID2', dealname: 'deal name 2' } }, // first slot second size + { ext: { deal: 'deal1', dealid: 'ixDealID1', dealname: 'deal name 1' } }, // first slot first size + { ext: { deal: 'deal2', dealid: 'ixDealID2', dealname: 'deal name 2' } }, // first slot second size ] ]; var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, undefined, undefined, undefined, optionalResponseParam); @@ -795,8 +795,8 @@ describe('indexExchange adapter - Response', function () { var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); var optionalResponseParam = [ [ - { ext: { deal: 'deal1', dealid: 'ixDealID1', dealname: 'deal name 1' } } // first slot first size - // No deal on first slot second size + { ext: { deal: 'deal1', dealid: 'ixDealID1', dealname: 'deal name 1' } } // first slot first size + // No deal on first slot second size ] ]; var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, undefined, undefined, undefined, optionalResponseParam); @@ -847,10 +847,10 @@ describe('indexExchange adapter - Response', function () { var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); var optionalResponseParam = [ [ - {}, - {} - // No deal on first slot first size - // No deal on first slot second size + {}, + {} + // No deal on first slot first size + // No deal on first slot second size ] ]; var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, undefined, undefined, undefined, optionalResponseParam); @@ -896,10 +896,10 @@ describe('indexExchange adapter - Response', function () { var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); var optionalResponseParam = [ [ - { ext: { dealid: 'ixDeal1' } } // first slot first size + { ext: { dealid: 'ixDeal1' } } // first slot first size ], [ - { ext: { dealid: 'ixDeal2' } } // second slot first size + { ext: { dealid: 'ixDeal2' } } // second slot first size ] ]; var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, undefined, undefined, undefined, optionalResponseParam); @@ -943,11 +943,11 @@ describe('indexExchange adapter - Response', function () { var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); var optionalResponseParam = [ [ - { ext: { dealid: 'ixDeal1' } } // first slot first size + { ext: { dealid: 'ixDeal1' } } // first slot first size ], [ - {} - // no deal on second slot first size + {} + // no deal on second slot first size ] ]; var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, undefined, undefined, undefined, optionalResponseParam); @@ -996,12 +996,12 @@ describe('indexExchange adapter - Response', function () { var requestJSON = IndexUtils.parseIndexRequest(adLoader.loadScript.firstCall.args[0]); var optionalResponseParam = [ [ - {} - // no deal on first slot first size + {} + // no deal on first slot first size ], [ - {} - // no deal on second slot first size + {} + // no deal on second slot first size ] ]; var asResponse = IndexUtils.getBidResponse(configuredBids, requestJSON, undefined, undefined, undefined, optionalResponseParam); @@ -1058,7 +1058,7 @@ describe('indexExchange adapter - Response', function () { var sidMatched = IndexUtils.matchBidsOnSID(expandedBids, impressionObj); assert.equal(sidMatched.matched.length, 3, 'Three slots are configured and sent to AS'); - // check normal site id + // check normal site id var normalSitePair = sidMatched.matched[0]; var expectedSlotID = normalSitePair.configured.params.id + '_1'; @@ -1069,7 +1069,7 @@ describe('indexExchange adapter - Response', function () { assert.equal(normalSitePair.sent.ext.siteID, expectedSiteID, 'request ' + normalSitePair.name + ' site ID is set to ' + expectedSiteID); assert.isNumber(normalSitePair.sent.ext.siteID, 'site ID is integer'); - // check tier 1 site id + // check tier 1 site id var tier2SitePair = sidMatched.matched[1]; var expectedTierSlotID = 'T1_' + tier2SitePair.configured.params.id + '_1'; assert.equal(tier2SitePair.sent.ext.sid, expectedTierSlotID, 'request ' + tier2SitePair.name + ' site ID is set to ' + expectedTierSlotID); @@ -1079,7 +1079,7 @@ describe('indexExchange adapter - Response', function () { assert.equal(tier2SitePair.sent.ext.siteID, expectedTierSiteID, 'request ' + normalSitePair.name + ' site ID is set to ' + expectedTierSiteID); assert.isNumber(tier2SitePair.sent.ext.siteID, 'site ID is integer'); - // check tier 2 site id + // check tier 2 site id var tier3SitePair = sidMatched.matched[2]; var expectedTierSlotID = 'T2_' + tier3SitePair.configured.params.id + '_1'; assert.equal(tier3SitePair.sent.ext.sid, expectedTierSlotID, 'request ' + tier3SitePair.name + ' site ID is set to ' + expectedTierSlotID); @@ -1089,7 +1089,7 @@ describe('indexExchange adapter - Response', function () { assert.equal(tier3SitePair.sent.ext.siteID, expectedTier3SiteID, 'request ' + normalSitePair.name + ' site ID is set to ' + expectedTier3SiteID); assert.isNumber(tier3SitePair.sent.ext.siteID, 'site ID is integer'); - // check unsent bids + // check unsent bids assert.equal(sidMatched.unmatched.configured.length, 0, 'All configured bids are in impression Obj'); assert.equal(sidMatched.unmatched.sent.length, 0, 'All bids in impression object are from configured bids'); }); diff --git a/test/spec/modules/indexExchangeBidAdapter_validadtion_spec.js b/test/spec/modules/indexExchangeBidAdapter_validadtion_spec.js index da0907cbf48..004a808e6c4 100644 --- a/test/spec/modules/indexExchangeBidAdapter_validadtion_spec.js +++ b/test/spec/modules/indexExchangeBidAdapter_validadtion_spec.js @@ -27,7 +27,7 @@ describe('indexExchange adapter - Validation', function () { }); it('test_prebid_indexAdapter_sizeValidation_1: request slot has supported and unsupported size -> unsupported size ignored in IX demand request', function () { - // create 2 sizes for 1 slot, 1 for supported size, the other is not supported + // create 2 sizes for 1 slot, 1 for supported size, the other is not supported var unsupportedSize = IndexUtils.unsupportedSizes[0]; var configuredBids = [ IndexUtils.createBidSlot(IndexUtils.DefaultPlacementCodePrefix, 'slot_1', [ IndexUtils.supportedSizes[0], unsupportedSize ]) @@ -60,7 +60,7 @@ describe('indexExchange adapter - Validation', function () { }); it('test_prebid_indexAdapter_sizeValidation_2_1: some slot has unsupported size -> unsupported slot ignored in IX demand request', function () { - // create 2 slot, 1 for supported size, the other is not supported + // create 2 slot, 1 for supported size, the other is not supported var unsupportedSize = IndexUtils.unsupportedSizes[0]; var configuredBids = [ IndexUtils.createBidSlot(IndexUtils.DefaultPlacementCodePrefix + 'supported', 'slot_1', [ IndexUtils.supportedSizes[0], ], { siteID: IndexUtils.DefaultSiteID }), @@ -96,7 +96,7 @@ describe('indexExchange adapter - Validation', function () { }); it('test_prebid_indexAdapter_sizeValidation_2_2: multiple slots with sinle size, all slot has supported size -> all slots are sent to IX demand', function () { - // create 2 slot, 1 for supported size, the other is not supported + // create 2 slot, 1 for supported size, the other is not supported var unsupportedSize = IndexUtils.unsupportedSizes[0]; var configuredBids = [ IndexUtils.createBidSlot(IndexUtils.DefaultPlacementCodePrefix + 'supported1', 'slot_1', [ IndexUtils.supportedSizes[0] ], { siteID: IndexUtils.DefaultSiteID }), @@ -128,7 +128,7 @@ describe('indexExchange adapter - Validation', function () { }); it('test_prebid_indexAdapter_sizeValidation_2_3: multiple slots with sinle size, all slot has unsupported size -> all slots are ignored', function () { - // create 2 slot, 1 for supported size, the other is not supported + // create 2 slot, 1 for supported size, the other is not supported var unsupportedSize = IndexUtils.unsupportedSizes[0]; var configuredBids = [ IndexUtils.createBidSlot(IndexUtils.DefaultPlacementCodePrefix + 'unsupported1', 'slot_1', [ IndexUtils.unsupportedSizes[0] ], { siteID: IndexUtils.DefaultSiteID }), @@ -140,7 +140,7 @@ describe('indexExchange adapter - Validation', function () { }); it('test_prebid_indexAdapter_sizeValidation_3_1: one slot has supported, unsupported, supported size -> unsupported slot ignored in IX demand request', function () { - // create 2 slot, 1 for supported size, the other is not supported + // create 2 slot, 1 for supported size, the other is not supported var unsupportedSize = IndexUtils.unsupportedSizes[0]; var configuredBids = [ IndexUtils.createBidSlot(IndexUtils.DefaultPlacementCodePrefix + 'somesupported', 'slot_1', [ IndexUtils.supportedSizes[0], unsupportedSize, IndexUtils.supportedSizes[1] ], { siteID: IndexUtils.DefaultSiteID }), @@ -176,7 +176,7 @@ describe('indexExchange adapter - Validation', function () { }); it('test_prebid_indexAdapter_sizeValidation_3_2: one slot has unsupported, supported, unsupported size -> unsupported slot ignored in IX demand request', function () { - // create 2 slot, 1 for supported size, the other is not supported + // create 2 slot, 1 for supported size, the other is not supported var unsupportedSize1 = IndexUtils.unsupportedSizes[0]; var unsupportedSize2 = IndexUtils.unsupportedSizes[1]; var configuredBids = [ @@ -507,7 +507,7 @@ describe('indexExchange adapter - Validation', function () { assert.equal(sidMatched.unmatched.configured.length, 0, 'All configured bids are in impression Obj'); assert.equal(sidMatched.unmatched.sent.length, 0, 'All bids in impression object are from configured bids'); } else if (expected == 'invalid') { - // case where callBids throws out request due to missing params + // case where callBids throws out request due to missing params assert.isFalse(adLoader.loadScript.called, 'No request to AS') } else { assert.strictEqual(typeof indexBidRequest, 'undefined', 'No request to AS'); @@ -672,7 +672,7 @@ describe('indexExchange adapter - Validation', function () { assert.equal(sidMatched.unmatched.configured.length, 0, 'All configured bids are in impression Obj'); assert.equal(sidMatched.unmatched.sent.length, 0, 'All bids in impression object are from configured bids'); } else if (expected == 'invalid') { - // case where callBids throws out request due to missing params + // case where callBids throws out request due to missing params assert.isFalse(adLoader.loadScript.called, 'No request to AS'); } else { assert.isUndefined(adLoader.loadScript.firstCall.args[0], 'No request to AS'); @@ -685,7 +685,7 @@ describe('indexExchange adapter - Validation', function () { base_prebid_indexAdapter_siteid(test.testname, test.param, test.expected); } - // TS: case created by PBA-12 + // TS: case created by PBA-12 it('test_prebid_indexAdapter_second_siteid_float: site ID is float -> slot is ignored', function() { var configuredBids = [ IndexUtils.createBidSlot(IndexUtils.DefaultPlacementCodePrefix + '1', 'slot_1', [ IndexUtils.supportedSizes[0] ]), @@ -786,7 +786,7 @@ describe('indexExchange adapter - Validation', function () { if (expected == 'pass') { assert.equal(sidMatched.matched.length, 2, 'Two slots are configured and sent to AS'); - // check normal site id + // check normal site id var normalSitePair = sidMatched.matched[0]; var expectedSlotID = normalSitePair.configured.params.id + '_1'; @@ -797,7 +797,7 @@ describe('indexExchange adapter - Validation', function () { assert.equal(normalSitePair.sent.ext.siteID, expectedSiteID, 'request ' + normalSitePair.name + ' site ID is set to ' + expectedSiteID); assert.isNumber(normalSitePair.sent.ext.siteID, 'site ID is integer'); - // check tier site id + // check tier site id var tier2SitePair = sidMatched.matched[1]; var expectedTierSlotID = 'T1_' + tier2SitePair.configured.params.id + '_1'; assert.equal(tier2SitePair.sent.ext.sid, expectedTierSlotID, 'request ' + tier2SitePair.name + ' site ID is set to ' + expectedTierSlotID); @@ -807,13 +807,13 @@ describe('indexExchange adapter - Validation', function () { assert.equal(tier2SitePair.sent.ext.siteID, expectedTierSiteID, 'request ' + normalSitePair.name + ' site ID is set to ' + expectedTierSiteID); assert.isNumber(tier2SitePair.sent.ext.siteID, 'site ID is integer'); - // check unsent bids + // check unsent bids assert.equal(sidMatched.unmatched.configured.length, 0, 'All configured bids are in impression Obj'); assert.equal(sidMatched.unmatched.sent.length, 0, 'All bids in impression object are from configured bids'); } else { assert.equal(sidMatched.matched.length, 1, 'one slot is configured and sent to AS'); - // check normal site id + // check normal site id var normalSitePair = sidMatched.matched[0]; var expectedSlotID = normalSitePair.configured.params.id + '_1'; @@ -824,7 +824,7 @@ describe('indexExchange adapter - Validation', function () { assert.equal(normalSitePair.sent.ext.siteID, expectedSiteID, 'request ' + normalSitePair.name + ' site ID is set to ' + expectedSiteID); assert.isNumber(normalSitePair.sent.ext.siteID, 'site ID is integer'); - // check unsent bids + // check unsent bids if (param.missingtier2SiteID) { assert.equal(sidMatched.unmatched.configured.length, 0, 'one configured bid is missing in impression Obj'); } else { @@ -907,7 +907,7 @@ describe('indexExchange adapter - Validation', function () { if (expected == 'pass') { assert.equal(sidMatched.matched.length, 2, 'Two slots are configured and sent to AS'); - // check normal site id + // check normal site id var normalSitePair = sidMatched.matched[0]; var expectedSlotID = normalSitePair.configured.params.id + '_1'; @@ -918,7 +918,7 @@ describe('indexExchange adapter - Validation', function () { assert.equal(normalSitePair.sent.ext.siteID, expectedSiteID, 'request ' + normalSitePair.name + ' site ID is set to ' + expectedSiteID); assert.isNumber(normalSitePair.sent.ext.siteID, 'site ID is integer'); - // check tier site id + // check tier site id var tier3SitePair = sidMatched.matched[1]; var expectedTierSlotID = 'T2_' + tier3SitePair.configured.params.id + '_1'; assert.equal(tier3SitePair.sent.ext.sid, expectedTierSlotID, 'request ' + tier3SitePair.name + ' site ID is set to ' + expectedTierSlotID); @@ -928,13 +928,13 @@ describe('indexExchange adapter - Validation', function () { assert.equal(tier3SitePair.sent.ext.siteID, expectedTierSiteID, 'request ' + normalSitePair.name + ' site ID is set to ' + expectedTierSiteID); assert.isNumber(tier3SitePair.sent.ext.siteID, 'site ID is integer'); - // check unsent bids + // check unsent bids assert.equal(sidMatched.unmatched.configured.length, 0, 'All configured bids are in impression Obj'); assert.equal(sidMatched.unmatched.sent.length, 0, 'All bids in impression object are from configured bids'); } else { assert.equal(sidMatched.matched.length, 1, 'one slot is configured and sent to AS'); - // check normal site id + // check normal site id var normalSitePair = sidMatched.matched[0]; var expectedSlotID = normalSitePair.configured.params.id + '_1'; @@ -945,7 +945,7 @@ describe('indexExchange adapter - Validation', function () { assert.equal(normalSitePair.sent.ext.siteID, expectedSiteID, 'request ' + normalSitePair.name + ' site ID is set to ' + expectedSiteID); assert.isNumber(normalSitePair.sent.ext.siteID, 'site ID is integer'); - // check unsent bids + // check unsent bids if (param.missingtier3SiteID) { assert.equal(sidMatched.unmatched.configured.length, 0, 'one configured bid is missing in impression Obj'); } else { diff --git a/test/spec/modules/inneractiveBidAdapter_spec.js b/test/spec/modules/inneractiveBidAdapter_spec.js index b92c173d78b..8c543c5dba7 100644 --- a/test/spec/modules/inneractiveBidAdapter_spec.js +++ b/test/spec/modules/inneractiveBidAdapter_spec.js @@ -88,9 +88,9 @@ describe('InneractiveAdapter', function () { describe('.createNew()', function () { it('should return an instance of this adapter having a "callBids" method', function () { expect(adapter) - .to.be.instanceOf(InneractiveAdapter).and - .to.have.property('callBids').and - .to.be.a('function'); + .to.be.instanceOf(InneractiveAdapter).and + .to.have.property('callBids').and + .to.be.a('function'); }); }); @@ -212,7 +212,7 @@ describe('InneractiveAdapter', function () { let firstRegisteredBidResponse = bidmanager.addBidResponse.firstCall.args[BID_DETAILS_ARG_INDEX]; expect(firstRegisteredBidResponse) - .to.have.property('statusMessage', 'Bid available'); + .to.have.property('statusMessage', 'Bid available'); }); it('should use the first element inside the bid request size array when no (width,height) is returned within the headers', function () { @@ -264,7 +264,7 @@ describe('InneractiveAdapter', function () { let firstRegisteredBidResponse = bidmanager.addBidResponse.firstCall.args[BID_DETAILS_ARG_INDEX]; expect(firstRegisteredBidResponse) - .to.have.property('statusMessage', 'Bid returned empty or error response'); + .to.have.property('statusMessage', 'Bid returned empty or error response'); }); it('should handle responses from our server in case we had no ad to offer', function () { @@ -276,7 +276,7 @@ describe('InneractiveAdapter', function () { let secondRegisteredBidResponse = bidmanager.addBidResponse.secondCall.args[BID_DETAILS_ARG_INDEX]; expect(secondRegisteredBidResponse) - .to.have.property('statusMessage', 'Bid returned empty or error response'); + .to.have.property('statusMessage', 'Bid returned empty or error response'); }); it('should handle JSON.parse errors', function () { @@ -286,7 +286,7 @@ describe('InneractiveAdapter', function () { const firstRegisteredBidResponse = bidmanager.addBidResponse.firstCall.args[BID_DETAILS_ARG_INDEX]; expect(firstRegisteredBidResponse) - .to.have.property('statusMessage', 'Bid returned empty or error response'); + .to.have.property('statusMessage', 'Bid returned empty or error response'); }); }); }); diff --git a/test/spec/modules/jcmBidAdapter_spec.js b/test/spec/modules/jcmBidAdapter_spec.js index 59f95dfe6e6..399746a6de3 100644 --- a/test/spec/modules/jcmBidAdapter_spec.js +++ b/test/spec/modules/jcmBidAdapter_spec.js @@ -2,7 +2,7 @@ describe('jcm adapter tests', function () { var expect = require('chai').expect; var urlParse = require('url-parse'); - // FYI: querystringify will perform encoding/decoding + // FYI: querystringify will perform encoding/decoding var querystringify = require('querystringify'); var adapter = require('modules/jcmBidAdapter'); diff --git a/test/spec/modules/komoonaBidAdapter_spec.js b/test/spec/modules/komoonaBidAdapter_spec.js index f0e4a7086d3..05623388db5 100644 --- a/test/spec/modules/komoonaBidAdapter_spec.js +++ b/test/spec/modules/komoonaBidAdapter_spec.js @@ -17,7 +17,7 @@ const REQUEST = { }, 'placementCode': 'div-gpt-ad-1438287399331-0', 'sizes': [ - [300, 250] + [300, 250] ], 'bidId': '30e5e911c00703', 'bidderRequestId': '25392d757fad47', diff --git a/test/spec/modules/mantisBidAdapter_spec.js b/test/spec/modules/mantisBidAdapter_spec.js index 7803bf947e2..e417ea51c04 100644 --- a/test/spec/modules/mantisBidAdapter_spec.js +++ b/test/spec/modules/mantisBidAdapter_spec.js @@ -114,7 +114,7 @@ describe('mantis adapter tests', function () { expect(serverCall).to.string('version=1'); }); - /* tests below are to just adhere to code coverage requirements, but it is already tested in our own libraries/deployment process */ + /* tests below are to just adhere to code coverage requirements, but it is already tested in our own libraries/deployment process */ it('should send uuid from window if set', () => { sandbox.stub(adloader, 'loadScript'); @@ -162,7 +162,7 @@ describe('mantis adapter tests', function () { var serverCall = adloader.loadScript.firstCall.args[0]; expect(serverCall).to.string('mobile=true&'); - // expect(serverCall).to.string('url=bar&'); + // expect(serverCall).to.string('url=bar&'); }); }); }); diff --git a/test/spec/modules/memeglobalBidAdapter_spec.js b/test/spec/modules/memeglobalBidAdapter_spec.js index 6f770c290d0..0dc2d6f1541 100644 --- a/test/spec/modules/memeglobalBidAdapter_spec.js +++ b/test/spec/modules/memeglobalBidAdapter_spec.js @@ -104,12 +104,12 @@ describe('memeglobal adapter tests', function () { $$PREBID_GLOBAL$$.mgres(response); expect(stubAddBidResponse.getCall(0)).to.equal(null); -// var bidPlacementCode = stubAddBidResponse.getCall(0).args[0]; -// expect(bidPlacementCode).to.equal('test-1'); -// -// var bidObject1 = stubAddBidResponse.getCall(0).args[1]; -// expect(bidObject1.getStatusCode()).to.equal(2); -// expect(bidObject1.bidderCode).to.equal('memeglobal'); + // var bidPlacementCode = stubAddBidResponse.getCall(0).args[0]; + // expect(bidPlacementCode).to.equal('test-1'); + // + // var bidObject1 = stubAddBidResponse.getCall(0).args[1]; + // expect(bidObject1.getStatusCode()).to.equal(2); + // expect(bidObject1.bidderCode).to.equal('memeglobal'); stubAddBidResponse.calledThrice; stubAddBidResponse.restore(); diff --git a/test/spec/modules/piximediaBidAdapter_spec.js b/test/spec/modules/piximediaBidAdapter_spec.js index 76e4ded1b1b..a3b01202102 100644 --- a/test/spec/modules/piximediaBidAdapter_spec.js +++ b/test/spec/modules/piximediaBidAdapter_spec.js @@ -2,7 +2,7 @@ describe('Piximedia adapter tests', function () { var expect = require('chai').expect; var urlParse = require('url-parse'); - // var querystringify = require('querystringify'); + // var querystringify = require('querystringify'); var adapter = require('modules/piximediaBidAdapter'); var adLoader = require('src/adloader'); @@ -268,7 +268,7 @@ describe('Piximedia adapter tests', function () { var stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); var stubGetUniqueIdentifierStr = sinon.spy(utils, 'getUniqueIdentifierStr'); - // this time, we do not provide dealId + // this time, we do not provide dealId var response = { foundbypm: true, cpm: 1.23, diff --git a/test/spec/modules/pubgearsBidAdapter_spec.js b/test/spec/modules/pubgearsBidAdapter_spec.js index c0179bc0d83..81f890e0dfd 100644 --- a/test/spec/modules/pubgearsBidAdapter_spec.js +++ b/test/spec/modules/pubgearsBidAdapter_spec.js @@ -5,8 +5,8 @@ import bidmanager from 'src/bidmanager' describe('PubGearsAdapter', () => { var adapter, mockScript, params = { - bids: [] - } + bids: [] + } beforeEach(() => { adapter = new Adapter() diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js index 254ab205439..2785082083d 100644 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -844,7 +844,7 @@ describe('the rubicon adapter', () => { expect(bids[0].cpm).to.equal(1); expect(bids[0].descriptionUrl).to.equal('a40fe16e-d08d-46a9-869d-2e1573599e0c'); expect(bids[0].vastUrl).to.equal( - 'https://fastlane-adv.rubiconproject.com/v1/creative/a40fe16e-d08d-46a9-869d-2e1573599e0c.xml' + 'https://fastlane-adv.rubiconproject.com/v1/creative/a40fe16e-d08d-46a9-869d-2e1573599e0c.xml' ); expect(bids[0].impression_id).to.equal('a40fe16e-d08d-46a9-869d-2e1573599e0c'); }); diff --git a/test/spec/modules/smartyadsBidAdapter_spec.js b/test/spec/modules/smartyadsBidAdapter_spec.js index 88213504a7d..d7c723604a6 100644 --- a/test/spec/modules/smartyadsBidAdapter_spec.js +++ b/test/spec/modules/smartyadsBidAdapter_spec.js @@ -62,26 +62,26 @@ describe('Smartyads adapter tests', function () { let bidderRequest = adapter.callBids.getCall(0).args[0]; expect(bidderRequest).to.have.property('bids') - .that.is.an('array') - .with.lengthOf(1); + .that.is.an('array') + .with.lengthOf(1); expect(bidderRequest).to.have.deep.property('bids[0]') - .to.have.property('bidder', 'smartyads'); + .to.have.property('bidder', 'smartyads'); expect(bidderRequest).to.have.deep.property('bids[0]') - .with.property('sizes') - .that.is.an('array') - .with.lengthOf(3) - .that.deep.equals(adUnit.sizes); + .with.property('sizes') + .that.is.an('array') + .with.lengthOf(3) + .that.deep.equals(adUnit.sizes); expect(bidderRequest).to.have.deep.property('bids[0]') - .with.property('params') - .to.have.property('banner_id', 0); + .with.property('params') + .to.have.property('banner_id', 0); }); it('Valid bid-response', () => { server.respondWith(JSON.stringify( - response - )); + response + )); adapterManager.callBids({ adUnits: [clone(adUnit)] }); diff --git a/test/spec/modules/stickyadstvBidAdapter_spec.js b/test/spec/modules/stickyadstvBidAdapter_spec.js index 276b8d4fb96..f9d98ce3ae2 100644 --- a/test/spec/modules/stickyadstvBidAdapter_spec.js +++ b/test/spec/modules/stickyadstvBidAdapter_spec.js @@ -84,7 +84,7 @@ describe('StickyAdsTV Adapter', function () { let getPricingCalled; beforeEach(function () { - // Mock VastLoader for test purpose + // Mock VastLoader for test purpose window.com = { stickyadstv: { vast: { diff --git a/test/spec/modules/twengaBidAdapter_spec.js b/test/spec/modules/twengaBidAdapter_spec.js index d5dd92fd0a6..feaa44ca438 100644 --- a/test/spec/modules/twengaBidAdapter_spec.js +++ b/test/spec/modules/twengaBidAdapter_spec.js @@ -94,9 +94,9 @@ describe('twenga adapter tests', function () { var parsedBidUrlQueryString = querystringify.parse(parsedBidUrl.query); $$PREBID_GLOBAL$$._bidsRequested - .push({ bidderCode: DEFAULT_PARAMS.bidderCode, - bids: [{ bidId: parsedBidUrlQueryString.callback_uid, - placementCode: DEFAULT_PARAMS.bids[0].placementCode }]}); + .push({ bidderCode: DEFAULT_PARAMS.bidderCode, + bids: [{ bidId: parsedBidUrlQueryString.callback_uid, + placementCode: DEFAULT_PARAMS.bids[0].placementCode }]}); var callback = stringToFunction(parsedBidUrlQueryString.callback); expect(callback).to.exist.and.to.be.a('function'); diff --git a/test/spec/modules/underdogmediaBidAdapter_spec.js b/test/spec/modules/underdogmediaBidAdapter_spec.js index c93246eab4c..249111be6ea 100644 --- a/test/spec/modules/underdogmediaBidAdapter_spec.js +++ b/test/spec/modules/underdogmediaBidAdapter_spec.js @@ -18,7 +18,7 @@ describe('underdogmedia adapter test', () => { bidder: 'underdogmedia', adUnitCode: 'foo', sizes: [ - [728, 90] + [728, 90] ], params: { siteId: '10272' @@ -28,7 +28,7 @@ describe('underdogmedia adapter test', () => { bidder: 'underdogmedia', adUnitCode: 'bar', sizes: [ - [300, 250] + [300, 250] ], params: { siteId: '10272', diff --git a/test/spec/modules/vertamediaBidAdapter_spec.js b/test/spec/modules/vertamediaBidAdapter_spec.js index ebcd439a124..3afe75790a5 100644 --- a/test/spec/modules/vertamediaBidAdapter_spec.js +++ b/test/spec/modules/vertamediaBidAdapter_spec.js @@ -120,9 +120,9 @@ describe('VertamediaAdater', () => { const response = bidmanager.addBidResponse.firstCall.args[1]; expect(response).to.have.property( - 'statusMessage', - 'Bid returned empty or error response' - ); + 'statusMessage', + 'Bid returned empty or error response' + ); }); it('handles JSON.parse errors', () => { @@ -133,9 +133,9 @@ describe('VertamediaAdater', () => { sinon.assert.calledOnce(bidmanager.addBidResponse); expect(bidmanager.addBidResponse.firstCall.args[1]).to.have.property( - 'statusMessage', - 'Bid returned empty or error response' - ); + 'statusMessage', + 'Bid returned empty or error response' + ); }); }); }); diff --git a/test/spec/modules/vertozBidAdapter_spec.js b/test/spec/modules/vertozBidAdapter_spec.js index e882c901c75..87d0ec8c842 100755 --- a/test/spec/modules/vertozBidAdapter_spec.js +++ b/test/spec/modules/vertozBidAdapter_spec.js @@ -15,7 +15,7 @@ describe('Vertoz Adapter', () => { bidder: 'vertoz', placementCode: 'foo', sizes: [ - [300, 250] + [300, 250] ], params: { placementId: 'VZ-HB-123' @@ -25,7 +25,7 @@ describe('Vertoz Adapter', () => { bidder: 'vertoz', placementCode: 'bar', sizes: [ - [728, 90] + [728, 90] ], params: { placementId: 'VZ-HB-456' @@ -35,7 +35,7 @@ describe('Vertoz Adapter', () => { bidder: 'vertoz', placementCode: 'coo', sizes: [ - [300, 600] + [300, 600] ], params: { placementId: '' diff --git a/test/spec/modules/wideorbitBidAdapter_spec.js b/test/spec/modules/wideorbitBidAdapter_spec.js index b524632597b..9ace04883e6 100644 --- a/test/spec/modules/wideorbitBidAdapter_spec.js +++ b/test/spec/modules/wideorbitBidAdapter_spec.js @@ -2,7 +2,7 @@ describe('wideorbit adapter tests', function () { var expect = require('chai').expect; var urlParse = require('url-parse'); - // FYI: querystringify will perform encoding/decoding + // FYI: querystringify will perform encoding/decoding var querystringify = require('querystringify'); var adapter = require('modules/wideorbitBidAdapter'); @@ -270,228 +270,228 @@ describe('wideorbit adapter tests', function () { }); }); - // describe('handling of the callback response', function () { - // - // var placements = [ - // { - // ExtPlacementId: 'div-gpt-ad-12345-1', - // Type: 'DirectHTML', - // Bid: 1.3, - // Width: 50, - // Height: 100, - // Source: '
The AD 1 itself...
', - // TrackingCodes: [ - // 'https://www.admeta.com/1.gif' - // ] - // }, - // { - // ExtPlacementId: 'div-gpt-ad-12345-2', - // Type: 'DirectHTML', - // Bid: 1.5, - // Width: 100, - // Height: 200, - // Source: '
The AD 2 itself...
', - // TrackingCodes: [ - // 'http://www.admeta.com/2a.gif', - // '' - // ] - // }, - // { - // ExtPlacementId: 'div-gpt-ad-12345-3', - // Type: 'Other', - // Bid: 1.7, - // Width: 150, - // Height: 250, - // Source: '
The AD 3 itself...
', - // TrackingCodes: [ - // 'http://www.admeta.com/3.gif' - // ] - // } - // ]; - // - // it('callback function should exist', function () { - // expect($$PREBID_GLOBAL$$.handleWideOrbitCallback).to.exist.and.to.be.a('function'); - // }); - // - // it('bidmanager.addBidResponse should be called thrice with correct arguments', function () { - // - // var stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); - // - // var params = { - // bidderCode: 'wideorbit', - // bids: [ - // { - // bidder: 'wideorbit', - // params: { - // pbId: 1, - // pId: 101 - // }, - // placementCode: 'div-gpt-ad-12345-1' - // }, - // { - // bidder: 'wideorbit', - // params: { - // pbId: 1, - // site: 'Site 1', - // page: 'Page 1', - // width: 100, - // height: 200, - // subPublisher: 'Sub Publisher 1' - // }, - // placementCode: 'div-gpt-ad-12345-2' - // }, - // { - // bidder: 'wideorbit', - // params: { - // pbId: 1, - // pId: 102 - // }, - // placementCode: 'div-gpt-ad-12345-3' - // }, - // ] - // }; - // - // var response = { - // UserMatchings: [ - // { - // Type: 'redirect', - // Url: 'http%3A%2F%2Fwww.admeta.com%2F1.gif' - // } - // ], - // Placements: placements - // }; - // - // adapter().callBids(params); - // $$PREBID_GLOBAL$$.handleWideOrbitCallback(response); - // - // var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; - // var bidObject1 = stubAddBidResponse.getCall(0).args[1]; - // var bidPlacementCode2 = stubAddBidResponse.getCall(1).args[0]; - // var bidObject2 = stubAddBidResponse.getCall(1).args[1]; - // var bidPlacementCode3 = stubAddBidResponse.getCall(2).args[0]; - // var bidObject3 = stubAddBidResponse.getCall(2).args[1]; - // - // expect(bidPlacementCode1).to.equal('div-gpt-ad-12345-1'); - // expect(bidObject1.cpm).to.equal(1.3); - // expect(bidObject1.ad).to.equal('
The AD 1 itself...
'); - // expect(bidObject1.width).to.equal(50); - // expect(bidObject1.height).to.equal(100); - // expect(bidObject1.getStatusCode()).to.equal(1); - // expect(bidObject1.bidderCode).to.equal('wideorbit'); - // - // expect(bidPlacementCode2).to.equal('div-gpt-ad-12345-2'); - // expect(bidObject2.cpm).to.equal(1.50); - // expect(bidObject2.ad).to.equal('
The AD 2 itself...
'); - // expect(bidObject2.width).to.equal(100); - // expect(bidObject2.height).to.equal(200); - // expect(bidObject2.getStatusCode()).to.equal(1); - // expect(bidObject2.bidderCode).to.equal('wideorbit'); - // - // expect(bidPlacementCode3).to.equal('div-gpt-ad-12345-3'); - // expect(bidObject3.getStatusCode()).to.equal(2); - // expect(bidObject3.bidderCode).to.equal('wideorbit'); - // - // sinon.assert.calledWith(stubAddBidResponse, bidPlacementCode1, bidObject1); - // sinon.assert.calledWith(stubAddBidResponse, bidPlacementCode2, bidObject2); - // sinon.assert.calledWith(stubAddBidResponse, bidPlacementCode3, bidObject3); - // - // sinon.assert.calledThrice(stubAddBidResponse); - // - // stubAddBidResponse.restore(); - // - // }); - // - // it('should append an image to the head when type is set to redirect', function () { - // - // var stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); - // - // var response = { - // UserMatchings: [ - // { - // Type: 'redirect', - // Url: 'http%3A%2F%2Fwww.admeta.com%2F1.gif' - // } - // ], - // Placements: placements - // }; - // - // $$PREBID_GLOBAL$$.handleWideOrbitCallback(response); - // - // var imgElement = document.querySelectorAll("head img")[0]; - // - // expect(imgElement).to.exist; - // expect(imgElement.src).to.equal('http://www.admeta.com/1.gif'); - // - // stubAddBidResponse.restore(); - // }); - // - // it('should append an iframe to the head when type is set to iframe', function () { - // - // var stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); - // - // var response = { - // UserMatchings: [ - // { - // Type: 'iframe', - // Url: 'http%3A%2F%2Fwww.admeta.com%2F1.ashx' - // } - // ], - // Placements: placements - // }; - // - // $$PREBID_GLOBAL$$.handleWideOrbitCallback(response); - // - // var iframeElement = document.querySelectorAll("head iframe")[0]; - // - // expect(iframeElement).to.exist; - // expect(iframeElement.src).to.equal('http://www.admeta.com/1.ashx'); - // - // stubAddBidResponse.restore(); - // - // }); - // - // it('should append an script to the head when type is set to js', function () { - // - // var stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); - // - // var response = { - // UserMatchings: [ - // { - // Type: 'js', - // Url: 'http%3A%2F%2Fwww.admeta.com%2F1.js' - // } - // ], - // Placements: placements - // }; - // - // $$PREBID_GLOBAL$$.handleWideOrbitCallback(response); - // - // var scriptElement = document.querySelectorAll("head script")[0]; - // - // expect(scriptElement).to.exist; - // expect(scriptElement.src).to.equal('http://www.admeta.com/1.js'); - // - // stubAddBidResponse.restore(); - // }); - // - // it('should do nothing when type is set to unrecognized type', function () { - // - // var stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); - // - // var response = { - // UserMatchings: [ - // { - // Type: 'unrecognized', - // Url: 'http%3A%2F%2Fwww.admeta.com%2F1.js' - // } - // ], - // Placements: placements - // }; - // - // $$PREBID_GLOBAL$$.handleWideOrbitCallback(response); - // - // stubAddBidResponse.restore(); - // }); - // - // }); + // describe('handling of the callback response', function () { + // + // var placements = [ + // { + // ExtPlacementId: 'div-gpt-ad-12345-1', + // Type: 'DirectHTML', + // Bid: 1.3, + // Width: 50, + // Height: 100, + // Source: '
The AD 1 itself...
', + // TrackingCodes: [ + // 'https://www.admeta.com/1.gif' + // ] + // }, + // { + // ExtPlacementId: 'div-gpt-ad-12345-2', + // Type: 'DirectHTML', + // Bid: 1.5, + // Width: 100, + // Height: 200, + // Source: '
The AD 2 itself...
', + // TrackingCodes: [ + // 'http://www.admeta.com/2a.gif', + // '' + // ] + // }, + // { + // ExtPlacementId: 'div-gpt-ad-12345-3', + // Type: 'Other', + // Bid: 1.7, + // Width: 150, + // Height: 250, + // Source: '
The AD 3 itself...
', + // TrackingCodes: [ + // 'http://www.admeta.com/3.gif' + // ] + // } + // ]; + // + // it('callback function should exist', function () { + // expect($$PREBID_GLOBAL$$.handleWideOrbitCallback).to.exist.and.to.be.a('function'); + // }); + // + // it('bidmanager.addBidResponse should be called thrice with correct arguments', function () { + // + // var stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); + // + // var params = { + // bidderCode: 'wideorbit', + // bids: [ + // { + // bidder: 'wideorbit', + // params: { + // pbId: 1, + // pId: 101 + // }, + // placementCode: 'div-gpt-ad-12345-1' + // }, + // { + // bidder: 'wideorbit', + // params: { + // pbId: 1, + // site: 'Site 1', + // page: 'Page 1', + // width: 100, + // height: 200, + // subPublisher: 'Sub Publisher 1' + // }, + // placementCode: 'div-gpt-ad-12345-2' + // }, + // { + // bidder: 'wideorbit', + // params: { + // pbId: 1, + // pId: 102 + // }, + // placementCode: 'div-gpt-ad-12345-3' + // }, + // ] + // }; + // + // var response = { + // UserMatchings: [ + // { + // Type: 'redirect', + // Url: 'http%3A%2F%2Fwww.admeta.com%2F1.gif' + // } + // ], + // Placements: placements + // }; + // + // adapter().callBids(params); + // $$PREBID_GLOBAL$$.handleWideOrbitCallback(response); + // + // var bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; + // var bidObject1 = stubAddBidResponse.getCall(0).args[1]; + // var bidPlacementCode2 = stubAddBidResponse.getCall(1).args[0]; + // var bidObject2 = stubAddBidResponse.getCall(1).args[1]; + // var bidPlacementCode3 = stubAddBidResponse.getCall(2).args[0]; + // var bidObject3 = stubAddBidResponse.getCall(2).args[1]; + // + // expect(bidPlacementCode1).to.equal('div-gpt-ad-12345-1'); + // expect(bidObject1.cpm).to.equal(1.3); + // expect(bidObject1.ad).to.equal('
The AD 1 itself...
'); + // expect(bidObject1.width).to.equal(50); + // expect(bidObject1.height).to.equal(100); + // expect(bidObject1.getStatusCode()).to.equal(1); + // expect(bidObject1.bidderCode).to.equal('wideorbit'); + // + // expect(bidPlacementCode2).to.equal('div-gpt-ad-12345-2'); + // expect(bidObject2.cpm).to.equal(1.50); + // expect(bidObject2.ad).to.equal('
The AD 2 itself...
'); + // expect(bidObject2.width).to.equal(100); + // expect(bidObject2.height).to.equal(200); + // expect(bidObject2.getStatusCode()).to.equal(1); + // expect(bidObject2.bidderCode).to.equal('wideorbit'); + // + // expect(bidPlacementCode3).to.equal('div-gpt-ad-12345-3'); + // expect(bidObject3.getStatusCode()).to.equal(2); + // expect(bidObject3.bidderCode).to.equal('wideorbit'); + // + // sinon.assert.calledWith(stubAddBidResponse, bidPlacementCode1, bidObject1); + // sinon.assert.calledWith(stubAddBidResponse, bidPlacementCode2, bidObject2); + // sinon.assert.calledWith(stubAddBidResponse, bidPlacementCode3, bidObject3); + // + // sinon.assert.calledThrice(stubAddBidResponse); + // + // stubAddBidResponse.restore(); + // + // }); + // + // it('should append an image to the head when type is set to redirect', function () { + // + // var stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); + // + // var response = { + // UserMatchings: [ + // { + // Type: 'redirect', + // Url: 'http%3A%2F%2Fwww.admeta.com%2F1.gif' + // } + // ], + // Placements: placements + // }; + // + // $$PREBID_GLOBAL$$.handleWideOrbitCallback(response); + // + // var imgElement = document.querySelectorAll("head img")[0]; + // + // expect(imgElement).to.exist; + // expect(imgElement.src).to.equal('http://www.admeta.com/1.gif'); + // + // stubAddBidResponse.restore(); + // }); + // + // it('should append an iframe to the head when type is set to iframe', function () { + // + // var stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); + // + // var response = { + // UserMatchings: [ + // { + // Type: 'iframe', + // Url: 'http%3A%2F%2Fwww.admeta.com%2F1.ashx' + // } + // ], + // Placements: placements + // }; + // + // $$PREBID_GLOBAL$$.handleWideOrbitCallback(response); + // + // var iframeElement = document.querySelectorAll("head iframe")[0]; + // + // expect(iframeElement).to.exist; + // expect(iframeElement.src).to.equal('http://www.admeta.com/1.ashx'); + // + // stubAddBidResponse.restore(); + // + // }); + // + // it('should append an script to the head when type is set to js', function () { + // + // var stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); + // + // var response = { + // UserMatchings: [ + // { + // Type: 'js', + // Url: 'http%3A%2F%2Fwww.admeta.com%2F1.js' + // } + // ], + // Placements: placements + // }; + // + // $$PREBID_GLOBAL$$.handleWideOrbitCallback(response); + // + // var scriptElement = document.querySelectorAll("head script")[0]; + // + // expect(scriptElement).to.exist; + // expect(scriptElement.src).to.equal('http://www.admeta.com/1.js'); + // + // stubAddBidResponse.restore(); + // }); + // + // it('should do nothing when type is set to unrecognized type', function () { + // + // var stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); + // + // var response = { + // UserMatchings: [ + // { + // Type: 'unrecognized', + // Url: 'http%3A%2F%2Fwww.admeta.com%2F1.js' + // } + // ], + // Placements: placements + // }; + // + // $$PREBID_GLOBAL$$.handleWideOrbitCallback(response); + // + // stubAddBidResponse.restore(); + // }); + // + // }); }); diff --git a/test/spec/modules/widespaceBidAdapter_spec.js b/test/spec/modules/widespaceBidAdapter_spec.js index 651d22b4606..8b9d89a914c 100644 --- a/test/spec/modules/widespaceBidAdapter_spec.js +++ b/test/spec/modules/widespaceBidAdapter_spec.js @@ -26,8 +26,8 @@ const BID_REQUEST = { }, 'placementCode': TEST.PLACEMENT_CODE, 'sizes': [ - [320, 320], - [320, 250] + [320, 320], + [320, 250] ], 'bidId': '45c7f5afb996c1', 'bidderRequestId': '7101db09af0db3', diff --git a/test/spec/sizeMapping_spec.js b/test/spec/sizeMapping_spec.js index a69e0bbde4d..53d4196349f 100644 --- a/test/spec/sizeMapping_spec.js +++ b/test/spec/sizeMapping_spec.js @@ -27,7 +27,7 @@ var invalidAdUnit = { var invalidAdUnit2 = { 'sizes': [300, 250], 'sizeMapping': [{ - foo: 'bar' // bad + foo: 'bar' // bad }] }; diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index d4a0f5a5fa0..d2ae3c7d892 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -1280,7 +1280,7 @@ describe('Unit: Prebid Module', function () { 'increment': 0.01, }, { - // missing min prop + // missing min prop 'max': 18, 'increment': 0.05, 'cap': true diff --git a/yarn.lock b/yarn.lock index 2ea12377d1d..a6aad494024 100644 --- a/yarn.lock +++ b/yarn.lock @@ -56,8 +56,8 @@ acorn@^3.0.0, acorn@^3.0.4, acorn@^3.3.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" acorn@^5.0.1, acorn@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d" + version "5.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.1.tgz#53fe161111f912ab999ee887a90a0bc52822fd75" adm-zip@~0.4.3: version "0.4.7" @@ -116,9 +116,9 @@ ansi-escape-sequences@^3.0.0: dependencies: array-back "^1.0.3" -ansi-escapes@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" +ansi-escapes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" ansi-regex@^0.2.0, ansi-regex@^0.2.1: version "0.2.1" @@ -132,6 +132,10 @@ ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + ansi-styles@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de" @@ -203,8 +207,8 @@ arr-diff@^2.0.0: arr-flatten "^1.0.1" arr-flatten@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.3.tgz#a274ed85ac08849b6bd7847c4580745dc51adfb1" + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" array-back@^1.0.2, array-back@^1.0.3, array-back@^1.0.4: version "1.0.4" @@ -216,6 +220,10 @@ array-differ@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" +array-each@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" + array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" @@ -224,6 +232,10 @@ array-slice@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" +array-slice@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.0.0.tgz#e73034f00dcc1f40876008fd20feae77bd4b7c2f" + array-tools@^1.0.6, array-tools@^1.1.0, array-tools@^1.1.4, array-tools@^1.8.4: version "1.8.6" resolved "https://registry.yarnpkg.com/array-tools/-/array-tools-1.8.6.tgz#145771f7f9c94e98cc5ea4196a99b8323aee18ae" @@ -319,6 +331,10 @@ ast-types@0.8.12: version "0.8.12" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.12.tgz#a0d90e4351bb887716c83fd637ebf818af4adfcc" +ast-types@0.8.15: + version "0.8.15" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.15.tgz#8eef0827f04dff0ec8857ba925abe3fea6194e52" + ast-types@0.9.6, ast-types@0.x.x: version "0.9.6" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9" @@ -344,8 +360,8 @@ async@^0.9.0, async@~0.9.0: resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" async@^2.0.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/async/-/async-2.4.1.tgz#62a56b279c98a11d0987096a01cc3eeb8eb7bbd7" + version "2.5.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" dependencies: lodash "^4.14.0" @@ -373,7 +389,7 @@ aws4@^1.2.1: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" -babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: +babel-code-frame@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" dependencies: @@ -406,19 +422,19 @@ babel-core@6.22.0, babel-core@^6.0.0, babel-core@^6.0.2: source-map "^0.5.0" babel-core@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.1.tgz#8c428564dce1e1f41fb337ec34f4c3b022b5ad83" + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729" dependencies: babel-code-frame "^6.22.0" - babel-generator "^6.24.1" + babel-generator "^6.25.0" babel-helpers "^6.24.1" babel-messages "^6.23.0" babel-register "^6.24.1" babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babylon "^6.11.0" + babel-template "^6.25.0" + babel-traverse "^6.25.0" + babel-types "^6.25.0" + babylon "^6.17.2" convert-source-map "^1.1.0" debug "^2.1.1" json5 "^0.5.0" @@ -480,13 +496,13 @@ babel-core@~5.8.3: trim-right "^1.0.0" try-resolve "^1.0.0" -babel-generator@^6.22.0, babel-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.1.tgz#e715f486c58ded25649d888944d52aa07c5d9497" +babel-generator@^6.22.0, babel-generator@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.25.0.tgz#33a1af70d5f2890aeb465a4a7793c1df6a9ea9fc" dependencies: babel-messages "^6.23.0" babel-runtime "^6.22.0" - babel-types "^6.24.1" + babel-types "^6.25.0" detect-indent "^4.0.0" jsesc "^1.3.0" lodash "^4.2.0" @@ -915,33 +931,33 @@ babel-runtime@^6.18.0, babel-runtime@^6.22.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-template@^6.22.0, babel-template@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333" +babel-template@^6.22.0, babel-template@^6.24.1, babel-template@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071" dependencies: babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babylon "^6.11.0" + babel-traverse "^6.25.0" + babel-types "^6.25.0" + babylon "^6.17.2" lodash "^4.2.0" -babel-traverse@^6.22.0, babel-traverse@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.24.1.tgz#ab36673fd356f9a0948659e7b338d5feadb31695" +babel-traverse@^6.22.0, babel-traverse@^6.24.1, babel-traverse@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1" dependencies: babel-code-frame "^6.22.0" babel-messages "^6.23.0" babel-runtime "^6.22.0" - babel-types "^6.24.1" - babylon "^6.15.0" + babel-types "^6.25.0" + babylon "^6.17.2" debug "^2.2.0" globals "^9.0.0" invariant "^2.2.0" lodash "^4.2.0" -babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.24.1.tgz#a136879dc15b3606bda0d90c1fc74304c2ff0975" +babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.24.1, babel-types@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e" dependencies: babel-runtime "^6.22.0" esutils "^2.0.2" @@ -952,25 +968,25 @@ babylon@^5.8.38: version "5.8.38" resolved "https://registry.yarnpkg.com/babylon/-/babylon-5.8.38.tgz#ec9b120b11bf6ccd4173a18bf217e60b79859ffd" -babylon@^6.11.0, babylon@^6.15.0: - version "6.17.2" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.2.tgz#201d25ef5f892c41bae49488b08db0dd476e9f5c" +babylon@^6.11.0, babylon@^6.17.2: + version "6.17.4" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a" backo2@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" -balanced-match@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" base64-arraybuffer@0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" base64-js@^1.0.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1" + version "1.2.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" base64-url@1.2.1: version "1.2.1" @@ -1119,10 +1135,10 @@ boom@2.x.x: hoek "2.x.x" brace-expansion@^1.0.0, brace-expansion@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.7.tgz#3effc3c50e000531fb720eaff80f0ae8ef23cf59" + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" dependencies: - balanced-match "^0.4.1" + balanced-match "^1.0.0" concat-map "0.0.1" braces@^0.1.2: @@ -1165,13 +1181,14 @@ browserstack@1.5.0: dependencies: https-proxy-agent "1.0.0" -browserstacktunnel-wrapper@~1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/browserstacktunnel-wrapper/-/browserstacktunnel-wrapper-1.4.2.tgz#6598fb7d784b6ff348e3df7c104b0d9c27ea5275" +browserstacktunnel-wrapper@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/browserstacktunnel-wrapper/-/browserstacktunnel-wrapper-2.0.1.tgz#ffe1910d6e39fe86618183e826690041af53edae" dependencies: + https-proxy-agent "^1.0.0" unzip "~0.1.9" -buffer-crc32@~0.2.1, buffer-crc32@~0.2.3: +buffer-crc32@~0.2.1: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" @@ -1187,12 +1204,6 @@ buffers@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" -bufferstreams@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/bufferstreams/-/bufferstreams-1.1.1.tgz#0161373060ac5988eff99058731114f6e195d51e" - dependencies: - readable-stream "^2.0.2" - builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -1362,11 +1373,11 @@ cli-commands@0.1.0: command-line-commands "^1.0.4" command-line-usage "^3.0.5" -cli-cursor@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" dependencies: - restore-cursor "^1.0.1" + restore-cursor "^2.0.0" cli-table@~0.3.1: version "0.3.1" @@ -1418,6 +1429,10 @@ clone@^1.0.0, clone@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" +clone@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" + cloneable-readable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.0.0.tgz#a6290d413f217a61232f95e458ff38418cfb0117" @@ -1445,11 +1460,11 @@ coffee-script@~1.8.0: mkdirp "~0.3.5" collect-all@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/collect-all/-/collect-all-1.0.2.tgz#39450f1e7aa6086570a006bce93ccf1218a77ea1" + version "1.0.3" + resolved "https://registry.yarnpkg.com/collect-all/-/collect-all-1.0.3.tgz#1abcc20448b58a1447487fcf34130e9512b0acf8" dependencies: stream-connect "^1.0.2" - stream-via "^1.0.3" + stream-via "^1.0.4" collect-all@~0.2.1: version "0.2.1" @@ -1668,7 +1683,7 @@ concat-stream@1.5.0: readable-stream "~2.0.0" typedarray "~0.0.5" -concat-stream@^1.4.7, concat-stream@^1.5.1, concat-stream@^1.5.2: +concat-stream@^1.5.1, concat-stream@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -1919,7 +1934,7 @@ d@1: dependencies: es5-ext "^0.10.9" -dargs@christian-bromann/dargs: +"dargs@github:christian-bromann/dargs": version "4.0.1" resolved "https://codeload.github.com/christian-bromann/dargs/tar.gz/7d6d4164a7c4106dbd14ef39ed8d95b7b5e9b770" dependencies: @@ -1974,7 +1989,7 @@ debug@0.7.4: version "0.7.4" resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" -debug@2, debug@2.6.8, debug@2.X, debug@^2.1.1, debug@^2.2.0: +debug@2, debug@2.6.8, debug@2.X, debug@^2.1.1, debug@^2.2.0, debug@^2.6.8: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: @@ -2059,7 +2074,7 @@ defs@~1.1.0: tryor "~0.1.2" yargs "~3.27.0" -degenerator@~1.0.0: +degenerator@~1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095" dependencies: @@ -2425,11 +2440,11 @@ escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" -escape-string-regexp@1.0.2, escape-string-regexp@^1.0.2: +escape-string-regexp@1.0.2, escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.5, escape-string-regexp@~1.0.5: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5, escape-string-regexp@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -2444,7 +2459,7 @@ escodegen@1.7.x, escodegen@1.x.x: optionalDependencies: source-map "~0.2.0" -escope@^3.2.0, escope@^3.6.0: +escope@^3.2.0: version "3.6.0" resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" dependencies: @@ -2453,48 +2468,46 @@ escope@^3.2.0, escope@^3.6.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-config-standard@^10.2.0: +eslint-config-standard@^10.2.1: version "10.2.1" resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz#c061e4d066f379dc17cd562c64e819b4dd454591" -eslint-import-resolver-node@^0.2.0: - version "0.2.3" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz#5add8106e8c928db2cba232bcd9efa846e3da16c" +eslint-import-resolver-node@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz#4422574cde66a9a7b099938ee4d508a199e0e3cc" dependencies: - debug "^2.2.0" - object-assign "^4.0.1" - resolve "^1.1.6" + debug "^2.6.8" + resolve "^1.2.0" -eslint-module-utils@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.0.0.tgz#a6f8c21d901358759cdc35dbac1982ae1ee58bce" +eslint-module-utils@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" dependencies: - debug "2.2.0" + debug "^2.6.8" pkg-dir "^1.0.0" eslint-plugin-import@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.3.0.tgz#37c801e0ada0e296cbdf20c3f393acb5b52af36b" + version "2.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz#21de33380b9efb55f5ef6d2e210ec0e07e7fa69f" dependencies: builtin-modules "^1.1.1" contains-path "^0.1.0" - debug "^2.2.0" + debug "^2.6.8" doctrine "1.5.0" - eslint-import-resolver-node "^0.2.0" - eslint-module-utils "^2.0.0" + eslint-import-resolver-node "^0.3.1" + eslint-module-utils "^2.1.1" has "^1.0.1" lodash.cond "^4.3.0" minimatch "^3.0.3" read-pkg-up "^2.0.0" -eslint-plugin-node@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-4.2.2.tgz#82959ca9aed79fcbd28bb1b188d05cac04fb3363" +eslint-plugin-node@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-5.1.0.tgz#bc8cdb85180d0b4d946a2531640e2a4dd7a4e6d4" dependencies: - ignore "^3.0.11" - minimatch "^3.0.2" - object-assign "^4.0.1" - resolve "^1.1.7" + ignore "^3.3.3" + minimatch "^3.0.4" + resolve "^1.3.3" semver "5.3.0" eslint-plugin-promise@^3.5.0: @@ -2505,47 +2518,52 @@ eslint-plugin-standard@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz#34d0c915b45edc6f010393c7eef3823b08565cf2" -eslint@^3.0.0: - version "3.19.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" +eslint-scope@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.1.1.tgz#facbdfcfe3e0facd3a8b80dc98c4e6c13ae582df" dependencies: - babel-code-frame "^6.16.0" + babel-code-frame "^6.22.0" chalk "^1.1.3" - concat-stream "^1.5.2" - debug "^2.1.1" + concat-stream "^1.6.0" + debug "^2.6.8" doctrine "^2.0.0" - escope "^3.6.0" - espree "^3.4.0" + eslint-scope "^3.7.1" + espree "^3.4.3" esquery "^1.0.0" estraverse "^4.2.0" esutils "^2.0.2" file-entry-cache "^2.0.0" - glob "^7.0.3" - globals "^9.14.0" - ignore "^3.2.0" + glob "^7.1.2" + globals "^9.17.0" + ignore "^3.3.3" imurmurhash "^0.1.4" - inquirer "^0.12.0" - is-my-json-valid "^2.10.0" + inquirer "^3.0.6" + is-my-json-valid "^2.16.0" is-resolvable "^1.0.0" - js-yaml "^3.5.1" - json-stable-stringify "^1.0.0" + js-yaml "^3.8.4" + json-stable-stringify "^1.0.1" levn "^0.3.0" - lodash "^4.0.0" - mkdirp "^0.5.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" natural-compare "^1.4.0" optionator "^0.8.2" - path-is-inside "^1.0.1" - pluralize "^1.2.1" - progress "^1.1.8" - require-uncached "^1.0.2" - shelljs "^0.7.5" - strip-bom "^3.0.0" + path-is-inside "^1.0.2" + pluralize "^4.0.0" + progress "^2.0.0" + require-uncached "^1.0.3" strip-json-comments "~2.0.1" - table "^3.7.8" + table "^4.0.1" text-table "~0.2.0" - user-home "^2.0.0" -espree@^3.4.0: +espree@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.3.tgz#2910b5ccd49ce893c2ffffaab4fd8b3a31b82374" dependencies: @@ -2571,7 +2589,7 @@ esprima@2.5.x: version "2.5.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.5.0.tgz#f387a46fd344c1b1a39baf8c20bfb43b6d0058cc" -esprima@3.x.x, esprima@~3.1.0: +esprima@3.x.x, esprima@^3.1.1, esprima@~3.1.0: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" @@ -2586,10 +2604,10 @@ esquery@^1.0.0: estraverse "^4.0.0" esrecurse@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.1.0.tgz#4713b6536adf7f2ac4f327d559e7756bff648220" + version "4.2.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" dependencies: - estraverse "~4.1.0" + estraverse "^4.1.0" object-assign "^4.0.1" estraverse@^1.9.1: @@ -2604,10 +2622,6 @@ estraverse@~1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.8.0.tgz#3f1264fb62c8500dbae5e4f73705cd576d6af428" -estraverse@~4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.1.1.tgz#f6caca728933a850ef90661d0e17982ba47111a2" - estree-walker@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.3.1.tgz#e6b1a51cf7292524e7237c312e5fe6660c1ce1aa" @@ -2659,10 +2673,6 @@ events@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" -exit-hook@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" - exit@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -2694,12 +2704,18 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" -expand-tilde@^1.2.1, expand-tilde@^1.2.2: +expand-tilde@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449" dependencies: os-homedir "^1.0.1" +expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + dependencies: + homedir-polyfill "^1.0.1" + expect.js@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/expect.js/-/expect.js-0.3.1.tgz#b0a59a0d2eff5437544ebf0ceaa6015841d09b5b" @@ -2722,6 +2738,14 @@ extend@3, extend@^3.0.0, extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" +external-editor@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.4.tgz#1ed9199da9cbfe2ef2f7a31b2fde8b0d12368972" + dependencies: + iconv-lite "^0.4.17" + jschardet "^1.4.2" + tmp "^0.0.31" + extglob@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" @@ -2789,6 +2813,12 @@ figures@^1.3.5: escape-string-regexp "^1.0.5" object-assign "^4.1.0" +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + file-entry-cache@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" @@ -2924,15 +2954,13 @@ findup-sync@^0.4.2: resolve-dir "^0.1.0" fined@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/fined/-/fined-1.0.2.tgz#5b28424b760d7598960b7ef8480dff8ad3660e97" + version "1.1.0" + resolved "https://registry.yarnpkg.com/fined/-/fined-1.1.0.tgz#b37dc844b76a2f5e7081e884f7c0ae344f153476" dependencies: - expand-tilde "^1.2.1" - lodash.assignwith "^4.0.7" - lodash.isempty "^4.2.1" - lodash.isplainobject "^4.0.4" - lodash.isstring "^4.0.1" - lodash.pick "^4.2.1" + expand-tilde "^2.0.2" + is-plain-object "^2.0.3" + object.defaults "^1.1.0" + object.pick "^1.2.0" parse-filepath "^1.0.1" first-chunk-stream@^1.0.0: @@ -2962,6 +2990,12 @@ for-own@^0.1.4: dependencies: for-in "^1.0.1" +for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + dependencies: + for-in "^1.0.1" + foreachasync@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/foreachasync/-/foreachasync-3.0.0.tgz#5502987dc8714be3392097f32e0071c9dee07cf6" @@ -3076,11 +3110,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" fsevents@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.1.tgz#f19fd28f43eeaf761680e519a203c4d0b3d31aff" + version "1.1.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.2.tgz#3282b713fb3ad80ede0e9fcf4611b5aa6fc033f4" dependencies: nan "^2.3.0" - node-pre-gyp "^0.6.29" + node-pre-gyp "^0.6.36" fstream-ignore@^1.0.5: version "1.0.5" @@ -3156,9 +3190,9 @@ get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" -get-uri@1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-1.1.0.tgz#7375d04daf7fcb584b3632679cbdf339b51bb149" +get-uri@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-2.0.0.tgz#713e47cbcbaeab38f88af1cdfc85fa7f09b00738" dependencies: data-uri-to-buffer "0" debug "2" @@ -3247,7 +3281,7 @@ glob@^4, glob@^4.3.1: minimatch "^2.0.1" once "^1.3.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.0: +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.0, glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: @@ -3295,7 +3329,7 @@ globals@^6.4.0: version "6.4.1" resolved "https://registry.yarnpkg.com/globals/-/globals-6.4.1.tgz#8498032b3b6d1cc81eebc5f79690d8fe29fabf4f" -globals@^9.0.0, globals@^9.14.0: +globals@^9.0.0, globals@^9.17.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -3391,13 +3425,12 @@ gulp-connect@^2.0.6: gulp-util "^3.0.6" tiny-lr "^0.2.1" -gulp-eslint@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/gulp-eslint/-/gulp-eslint-3.0.1.tgz#04e57e3e18c6974267c12cf6855dc717d4a313bd" +gulp-eslint@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/gulp-eslint/-/gulp-eslint-4.0.0.tgz#16d9ea4d696e7b7a9d65eeb1aa5bc4ba0a22c7f7" dependencies: - bufferstreams "^1.1.1" - eslint "^3.0.0" - gulp-util "^3.0.6" + eslint "^4.0.0" + gulp-util "^3.0.8" gulp-footer@^1.0.5: version "1.0.5" @@ -3512,7 +3545,7 @@ gulp-uglify@^0.3.1: through2 ">=0.6.1 <1.0.0-0" uglify-js "2.4.6" -gulp-util@*, "gulp-util@>=3.0.0 <4.0.0-0", gulp-util@^3.0.0, gulp-util@^3.0.4, gulp-util@^3.0.6, gulp-util@^3.0.7: +gulp-util@*, "gulp-util@>=3.0.0 <4.0.0-0", gulp-util@^3.0.0, gulp-util@^3.0.4, gulp-util@^3.0.6, gulp-util@^3.0.7, gulp-util@^3.0.8: version "3.0.8" resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" dependencies: @@ -3558,16 +3591,6 @@ gulp-webdriver@^1.0.1: through2 "^0.6.5" webdriverio "^3.4.0" -gulp-zip@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/gulp-zip/-/gulp-zip-3.2.0.tgz#ebd198dae6dc2d5f44d814569c8ec42118a93ef9" - dependencies: - chalk "^1.0.0" - concat-stream "^1.4.7" - gulp-util "^3.0.0" - through2 "^2.0.1" - yazl "^2.1.0" - gulp@^3.8.7: version "3.9.1" resolved "https://registry.yarnpkg.com/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4" @@ -3773,15 +3796,15 @@ home-path@^1.0.3, home-path@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/home-path/-/home-path-1.0.5.tgz#788b29815b12d53bacf575648476e6f9041d133f" -homedir-polyfill@^1.0.0: +homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" dependencies: parse-passwd "^1.0.0" hosted-git-info@^2.1.4: - version "2.4.2" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67" + version "2.5.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" htmlparser2@3.8.3: version "3.8.3" @@ -3844,7 +3867,7 @@ https-browserify@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82" -https-proxy-agent@1, https-proxy-agent@1.0.0: +https-proxy-agent@1, https-proxy-agent@1.0.0, https-proxy-agent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6" dependencies: @@ -3878,15 +3901,19 @@ iconv-lite@0.4.13: version "0.4.13" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" -iconv-lite@0.4.15, iconv-lite@^0.4.5: +iconv-lite@0.4.15: version "0.4.15" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" +iconv-lite@^0.4.17, iconv-lite@^0.4.5: + version "0.4.18" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2" + ieee754@^1.1.4: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" -ignore@^3.0.11, ignore@^3.2.0: +ignore@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" @@ -3919,7 +3946,7 @@ inherits@1: version "1.0.2" resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" -inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1: +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -3931,24 +3958,6 @@ ini@^1.3.4, ini@~1.3.0: version "1.3.4" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" -inquirer@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" - dependencies: - ansi-escapes "^1.1.0" - ansi-regex "^2.0.0" - chalk "^1.0.0" - cli-cursor "^1.0.1" - cli-width "^2.0.0" - figures "^1.3.5" - lodash "^4.3.0" - readline2 "^1.0.1" - run-async "^0.1.0" - rx-lite "^3.1.2" - string-width "^1.0.1" - strip-ansi "^3.0.0" - through "^2.3.6" - inquirer@^0.8.5: version "0.8.5" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.8.5.tgz#dbd740cf6ca3b731296a63ce6f6d961851f336df" @@ -3962,6 +3971,25 @@ inquirer@^0.8.5: rx "^2.4.3" through "^2.3.6" +inquirer@^3.0.6: + version "3.1.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.1.1.tgz#87621c4fba4072f48a8dd71c9f9df6f100b2d534" + dependencies: + ansi-escapes "^2.0.0" + chalk "^1.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.0.0" + strip-ansi "^3.0.0" + through "^2.3.6" + interpret@^0.6.4: version "0.6.6" resolved "https://registry.yarnpkg.com/interpret/-/interpret-0.6.6.tgz#fecd7a18e7ce5ca6abfb953e1f86213a49f1625b" @@ -3980,6 +4008,10 @@ invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" +ip@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.0.1.tgz#c7e356cdea225ae71b36d70f2e71a92ba4e42590" + ip@^1.1.4: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" @@ -4061,7 +4093,7 @@ is-integer@^1.0.4: dependencies: is-finite "^1.0.0" -is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.0, is-my-json-valid@^2.12.4: +is-my-json-valid@^2.12.0, is-my-json-valid@^2.12.4, is-my-json-valid@^2.16.0: version "2.16.0" resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" dependencies: @@ -4074,12 +4106,18 @@ is-number@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-number/-/is-number-0.1.1.tgz#69a7af116963d47206ec9bd9b48a14216f1e3806" -is-number@^2.0.2, is-number@^2.1.0: +is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" dependencies: kind-of "^3.0.2" +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + is-object@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" @@ -4100,6 +4138,12 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" +is-plain-object@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.3.tgz#c15bf3e4b66b62d72efaf2925848663ecbc619b6" + dependencies: + isobject "^3.0.0" + is-posix-bracket@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" @@ -4108,6 +4152,10 @@ is-primitive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + is-property@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" @@ -4124,7 +4172,7 @@ is-resolvable@^1.0.0: dependencies: tryit "^1.0.1" -is-stream@^1.0.1, is-stream@^1.1.0: +is-stream@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -4162,12 +4210,16 @@ isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" -isobject@^2.0.0: +isobject@^2.0.0, isobject@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" dependencies: isarray "1.0.0" +isobject@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + isstream@0.1.x, isstream@~0.1.1, isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -4216,16 +4268,23 @@ js-tokens@1.0.1: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-1.0.1.tgz#cc435a5c8b94ad15acb7983140fc80182c89aeae" js-tokens@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@3.6.1, js-yaml@3.x, js-yaml@^3.5.1: +js-yaml@3.6.1, js-yaml@3.x: version "3.6.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30" dependencies: argparse "^1.0.7" esprima "^2.6.0" +js-yaml@^3.8.4: + version "3.8.4" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.4.tgz#520b4564f86573ba96662af85a8cafa7b4b5a6f6" + dependencies: + argparse "^1.0.7" + esprima "^3.1.1" + js-yaml@~3.4.0: version "3.4.6" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.4.6.tgz#6be1b23f6249f53d293370fd4d1aaa63ce1b4eb0" @@ -4242,6 +4301,10 @@ jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" +jschardet@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.4.2.tgz#2aa107f142af4121d145659d44f50830961e699a" + jscs-jsdoc@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/jscs-jsdoc/-/jscs-jsdoc-1.3.2.tgz#1f2c82b6ab4b97524da958f46b4e562e0305f9a7" @@ -4380,7 +4443,7 @@ json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" -json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: +json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" dependencies: @@ -4443,12 +4506,12 @@ karma-babel-preprocessor@^6.0.1: babel-core "^6.0.0" karma-browserstack-launcher@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/karma-browserstack-launcher/-/karma-browserstack-launcher-1.2.0.tgz#acfa534835ba590041eef009c1169a219120bb5b" + version "1.3.0" + resolved "https://registry.yarnpkg.com/karma-browserstack-launcher/-/karma-browserstack-launcher-1.3.0.tgz#61fe3d36b1cf10681e40f9d874bf37271fb1c674" dependencies: browserstack "1.5.0" - browserstacktunnel-wrapper "~1.4.2" - q "~1.4.1" + browserstacktunnel-wrapper "~2.0.1" + q "~1.5.0" karma-chai@^0.1.0: version "0.1.0" @@ -4590,6 +4653,12 @@ kind-of@^3.0.2: dependencies: is-buffer "^1.1.5" +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + klaw@^1.0.0, klaw@~1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" @@ -4681,12 +4750,12 @@ loader-utils@^0.2.11, loader-utils@^0.2.16, loader-utils@^0.2.5, loader-utils@~0 object-assign "^4.0.1" localtunnel@^1.3.0: - version "1.8.2" - resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-1.8.2.tgz#913051e8328b51f75ad8a22ad1f5c5b8c599a359" + version "1.8.3" + resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-1.8.3.tgz#dcc5922fd85651037d4bde24fd93248d0b24eb05" dependencies: - debug "2.2.0" - openurl "1.1.0" - request "2.78.0" + debug "2.6.8" + openurl "1.1.1" + request "2.81.0" yargs "3.29.0" locate-path@^2.0.0: @@ -4837,10 +4906,6 @@ lodash.assign@^3.2.0: lodash._createassigner "^3.0.0" lodash.keys "^3.0.0" -lodash.assignwith@^4.0.7: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz#127a97f02adc41751a954d24b0de17e100e038eb" - lodash.clone@3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-3.0.3.tgz#84688c73d32b5a90ca25616963f189252a997043" @@ -4905,10 +4970,6 @@ lodash.isarray@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" -lodash.isempty@^4.2.1: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" - lodash.isobject@~2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-2.4.1.tgz#5a2e47fe69953f1ee631a7eba1fe64d2d06558f5" @@ -4951,7 +5012,7 @@ lodash.mergewith@^4.0.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55" -lodash.pick@^4.2.1, lodash.pick@^4.4.0: +lodash.pick@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" @@ -5077,7 +5138,11 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" -lru-cache@2, lru-cache@2.2.x: +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + +lru-cache@2.2.x: version "2.2.4" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d" @@ -5232,6 +5297,10 @@ mime@~1.2.11: version "1.2.11" resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10" +mimic-fn@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + minimatch@0.x, minimatch@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" @@ -5391,9 +5460,9 @@ mute-stream@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.4.tgz#a9219960a6d5d5d046597aee51252c6655f7177e" -mute-stream@0.0.5, mute-stream@~0.0.4: - version "0.0.5" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" +mute-stream@0.0.7, mute-stream@~0.0.4: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" nan@^2.3.0: version "2.6.2" @@ -5428,8 +5497,8 @@ netmask@~1.0.4: resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35" nightwatch@^0.9.5: - version "0.9.15" - resolved "https://registry.yarnpkg.com/nightwatch/-/nightwatch-0.9.15.tgz#71a62aa16368e9da09fae800ccb9fb34d036164d" + version "0.9.16" + resolved "https://registry.yarnpkg.com/nightwatch/-/nightwatch-0.9.16.tgz#c4ac3ec711b0ff047c3dca9c6557365ee236519f" dependencies: chai-nightwatch "~0.1.x" ejs "0.8.3" @@ -5474,7 +5543,7 @@ node-libs-browser@^0.7.0: util "^0.10.3" vm-browserify "0.0.4" -node-pre-gyp@^0.6.29: +node-pre-gyp@^0.6.36: version "0.6.36" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786" dependencies: @@ -5513,8 +5582,8 @@ nopt@^4.0.1: osenv "^0.1.4" normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: - version "2.3.8" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb" + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" dependencies: hosted-git-info "^2.1.4" is-builtin-module "^1.0.0" @@ -5528,8 +5597,8 @@ normalize-path@^2.0.1, normalize-path@^2.1.1: remove-trailing-separator "^1.0.1" npmlog@^4.0.2: - version "4.1.0" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.0.tgz#dc59bee85f64f00ed424efb2af0783df25d1c0b5" + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" dependencies: are-we-there-yet "~1.1.2" console-control-strings "~1.1.0" @@ -5601,6 +5670,15 @@ object-tools@^2, object-tools@^2.0.6: test-value "^1.1.0" typical "^2.4.2" +object.defaults@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" + dependencies: + array-each "^1.0.1" + array-slice "^1.0.0" + for-own "^1.0.0" + isobject "^3.0.0" + object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -5608,6 +5686,12 @@ object.omit@^2.0.0: for-own "^0.1.4" is-extendable "^0.1.1" +object.pick@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.2.0.tgz#b5392bee9782da6d9fb7d6afaf539779f1234c2b" + dependencies: + isobject "^2.1.0" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -5630,17 +5714,19 @@ once@~1.3.0: dependencies: wrappy "1" -onetime@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" open@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/open/-/open-0.0.5.tgz#42c3e18ec95466b6bf0dc42f3a2945c3f0cad8fc" -openurl@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/openurl/-/openurl-1.1.0.tgz#e2f2189d999c04823201f083f0f1a7cd8903187a" +openurl@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/openurl/-/openurl-1.1.1.tgz#3875b4b0ef7a52c156f0db41d4609dbb0f94b387" optimist@0.6.1, optimist@^0.6.1, optimist@~0.6.0, optimist@~0.6.1: version "0.6.1" @@ -5751,27 +5837,27 @@ p-locate@^2.0.0: p-limit "^1.1.0" pac-proxy-agent@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-1.0.0.tgz#dcd5b746581367430a236e88eacfd4e5b8d068a5" + version "1.1.0" + resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-1.1.0.tgz#34a385dfdf61d2f0ecace08858c745d3e791fd4d" dependencies: agent-base "2" debug "2" extend "3" - get-uri "1" + get-uri "2" http-proxy-agent "1" https-proxy-agent "1" - pac-resolver "~1.2.1" + pac-resolver "~2.0.0" + raw-body "2" socks-proxy-agent "2" - stream-to-buffer "0.1.0" -pac-resolver@~1.2.1: - version "1.2.6" - resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-1.2.6.tgz#ed03af0c5b5933505bdd3f07f75175466d5e7cfb" +pac-resolver@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-2.0.0.tgz#99b88d2f193fbdeefc1c9a529c1f3260ab5277cd" dependencies: co "~3.0.6" - degenerator "~1.0.0" + degenerator "~1.0.2" + ip "1.0.1" netmask "~1.0.4" - regenerator "~0.8.13" thunkify "~2.1.1" pako@~0.2.0: @@ -5849,7 +5935,7 @@ path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -path-is-inside@^1.0.1: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" @@ -5948,9 +6034,9 @@ pkginfo@0.x.x: version "0.4.0" resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.0.tgz#349dbb7ffd38081fcadc0853df687f0c7744cd65" -pluralize@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" +pluralize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-4.0.0.tgz#59b708c1c0190a2f692f1c7618c446b052fd1762" prelude-ls@~1.1.0, prelude-ls@~1.1.1, prelude-ls@~1.1.2: version "1.1.2" @@ -5976,7 +6062,11 @@ process@^0.11.0: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" -progress@^1.1.8, progress@~1.1.8: +progress@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + +progress@~1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" @@ -5985,8 +6075,8 @@ promise.prototype.finally@^1.0.1: resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-1.0.1.tgz#91182f91c92486995740fa05e0da942ac986befa" "promise@>=3.2 <8": - version "7.1.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf" + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" dependencies: asap "~2.0.3" @@ -6042,10 +6132,14 @@ punycode@^1.2.4, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" -q@1.4.1, q@^1.1.2, q@~1.4.1: +q@1.4.1, q@~1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" +q@^1.1.2, q@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" + q@~0.9.6: version "0.9.7" resolved "https://registry.yarnpkg.com/q/-/q-0.9.7.tgz#4de2e6cb3b29088c9e4cbc03bf9d42fb96ce2f75" @@ -6107,11 +6201,11 @@ random-bytes@~1.0.0: resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" randomatic@^1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" dependencies: - is-number "^2.0.2" - kind-of "^3.0.2" + is-number "^3.0.0" + kind-of "^4.0.0" range-parser@^1.0.3: version "1.2.0" @@ -6121,20 +6215,20 @@ range-parser@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.0.3.tgz#6872823535c692e2c2a0103826afd82c2e0ff175" -raw-body@~2.1.2, raw-body@~2.1.5: - version "2.1.7" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.1.7.tgz#adfeace2e4fb3098058014d08c072dcc59758774" +raw-body@2, raw-body@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.2.0.tgz#994976cf6a5096a41162840492f0bdc5d6e7fb96" dependencies: bytes "2.4.0" - iconv-lite "0.4.13" + iconv-lite "0.4.15" unpipe "1.0.0" -raw-body@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.2.0.tgz#994976cf6a5096a41162840492f0bdc5d6e7fb96" +raw-body@~2.1.2, raw-body@~2.1.5: + version "2.1.7" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.1.7.tgz#adfeace2e4fb3098058014d08c072dcc59758774" dependencies: bytes "2.4.0" - iconv-lite "0.4.15" + iconv-lite "0.4.13" unpipe "1.0.0" rc@^1.1.7: @@ -6183,8 +6277,8 @@ read@1.0.x: mute-stream "~0.0.4" readable-stream@1.1, readable-stream@1.1.x, readable-stream@~1.1.8, readable-stream@~1.1.9: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + version "1.1.13" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e" dependencies: core-util-is "~1.0.0" inherits "~2.0.1" @@ -6192,15 +6286,15 @@ readable-stream@1.1, readable-stream@1.1.x, readable-stream@~1.1.8, readable-str string_decoder "~0.10.x" readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6: - version "2.2.11" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.11.tgz#0796b31f8d7688007ff0b93a8088d34aa17c0f72" + version "2.3.3" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" dependencies: core-util-is "~1.0.0" - inherits "~2.0.1" + inherits "~2.0.3" isarray "~1.0.0" process-nextick-args "~1.0.6" - safe-buffer "~5.0.1" - string_decoder "~1.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.0.3" util-deprecate "~1.0.1" "readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.0, readable-stream@~1.0.17, readable-stream@~1.0.2, readable-stream@~1.0.24, readable-stream@~1.0.26, readable-stream@~1.0.31, readable-stream@~1.0.33: @@ -6239,15 +6333,7 @@ readline2@^0.1.1: mute-stream "0.0.4" strip-ansi "^2.0.1" -readline2@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - mute-stream "0.0.5" - -recast@0.10.33, recast@^0.10.10: +recast@0.10.33: version "0.10.33" resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.33.tgz#942808f7aa016f1fa7142c461d7e5704aaa8d697" dependencies: @@ -6256,6 +6342,15 @@ recast@0.10.33, recast@^0.10.10: private "~0.1.5" source-map "~0.5.0" +recast@^0.10.10: + version "0.10.43" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.43.tgz#b95d50f6d60761a5f6252e15d80678168491ce7f" + dependencies: + ast-types "0.8.15" + esprima-fb "~15001.1001.0-dev-harmony-fb" + private "~0.1.5" + source-map "~0.5.0" + recast@^0.11.17: version "0.11.23" resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3" @@ -6314,7 +6409,7 @@ regenerator-transform@0.9.11: babel-types "^6.19.0" private "^0.1.6" -regenerator@0.8.40, regenerator@~0.8.13: +regenerator@0.8.40: version "0.8.40" resolved "https://registry.yarnpkg.com/regenerator/-/regenerator-0.8.40.tgz#a0e457c58ebdbae575c9f8cd75127e93756435d8" dependencies: @@ -6439,31 +6534,6 @@ request@2.49.0: tough-cookie ">=0.12.0" tunnel-agent "~0.4.0" -request@2.78.0: - version "2.78.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.78.0.tgz#e1c8dec346e1c81923b24acdb337f11decabe9cc" - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.11.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~2.0.6" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - node-uuid "~1.4.7" - oauth-sign "~0.8.1" - qs "~6.3.0" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "~0.4.1" - request@2.79.0: version "2.79.0" resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" @@ -6489,7 +6559,7 @@ request@2.79.0: tunnel-agent "~0.4.1" uuid "^3.0.0" -request@^2.81.0: +request@2.81.0, request@^2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" dependencies: @@ -6572,7 +6642,7 @@ require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" -require-uncached@^1.0.2: +require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" dependencies: @@ -6616,7 +6686,7 @@ resolve@1.1.x, resolve@~1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" -resolve@^1.1.6, resolve@^1.1.7: +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.2.0, resolve@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" dependencies: @@ -6629,12 +6699,12 @@ response-time@~2.3.1: depd "~1.1.0" on-headers "~1.0.1" -restore-cursor@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" dependencies: - exit-hook "^1.0.0" - onetime "^1.0.0" + onetime "^2.0.0" + signal-exit "^3.0.2" revalidator@0.1.x: version "0.1.8" @@ -6676,23 +6746,29 @@ rndm@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/rndm/-/rndm-1.2.0.tgz#f33fe9cfb52bbfd520aa18323bc65db110a1b76c" -run-async@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" dependencies: - once "^1.3.0" + is-promise "^2.1.0" -rx-lite@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" rx@^2.4.3: version "2.5.3" resolved "https://registry.yarnpkg.com/rx/-/rx-2.5.3.tgz#21adc7d80f02002af50dae97fd9dbf248755f566" -safe-buffer@^5.0.1, safe-buffer@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" +safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" samsam@1.1.2, samsam@~1.1: version "1.1.2" @@ -6797,19 +6873,11 @@ shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" -shelljs@^0.7.5: - version "0.7.8" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - sigmund@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" -signal-exit@^3.0.0: +signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -6905,8 +6973,8 @@ socket.io@^1.4.5: socket.io-parser "2.3.1" socks-proxy-agent@2: - version "2.1.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-2.1.0.tgz#ddfb01b5dbea5fc879490ca38a25fe87d3d15912" + version "2.1.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-2.1.1.tgz#86ebb07193258637870e13b7bd99f26c663df3d3" dependencies: agent-base "2" extend "3" @@ -7085,8 +7153,8 @@ stream-handlebars@~0.1.6: object-tools "^1.2.1" stream-http@^2.3.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.1.tgz#546a51741ad5a6b07e9e31b0b10441a917df528a" + version "2.7.2" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad" dependencies: builtin-status-codes "^3.0.0" inherits "^2.0.1" @@ -7098,17 +7166,7 @@ stream-shift@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" -stream-to-buffer@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/stream-to-buffer/-/stream-to-buffer-0.1.0.tgz#26799d903ab2025c9bd550ac47171b00f8dd80a9" - dependencies: - stream-to "~0.2.0" - -stream-to@~0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/stream-to/-/stream-to-0.2.2.tgz#84306098d85fdb990b9fa300b1b3ccf55e8ef01d" - -stream-via@^1.0.3: +stream-via@^1.0.3, stream-via@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/stream-via/-/stream-via-1.0.4.tgz#8dccbb0ac909328eb8bc8e2a4bd3934afdaf606c" @@ -7143,21 +7201,21 @@ string-width@^1.0.1, string-width@^1.0.2: strip-ansi "^3.0.0" string-width@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e" + version "2.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.0.tgz#030664561fc146c9423ec7d978fe2457437fe6d0" dependencies: is-fullwidth-code-point "^2.0.0" - strip-ansi "^3.0.0" + strip-ansi "^4.0.0" string_decoder@^0.10.25, string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" -string_decoder@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.2.tgz#b29e1f4e1125fa97a10382b8a533737b7491e179" +string_decoder@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" dependencies: - safe-buffer "~5.0.1" + safe-buffer "~5.1.0" stringmap@~0.2.2: version "0.2.2" @@ -7189,6 +7247,12 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + strip-ansi@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" @@ -7269,9 +7333,9 @@ table-layout@^0.3.0: typical "^2.6.0" wordwrapjs "^2.0.0-0" -table@^3.7.8: - version "3.8.3" - resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" +table@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.1.tgz#a8116c133fac2c61f4a420ab6cdf5c4d61f0e435" dependencies: ajv "^4.7.0" ajv-keywords "^1.0.0" @@ -7426,7 +7490,7 @@ tiny-lr@^0.2.1: parseurl "~1.3.0" qs "~5.1.0" -tmp@0.0.x: +tmp@0.0.x, tmp@^0.0.31: version "0.0.31" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" dependencies: @@ -7547,8 +7611,8 @@ uglify-js@2.4.6: uglify-to-browserify "~1.0.0" uglify-js@^2.6, uglify-js@^2.8.10: - version "2.8.28" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.28.tgz#e335032df9bb20dcb918f164589d5af47f38834a" + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" dependencies: source-map "~0.5.1" yargs "~3.10.0" @@ -7680,15 +7744,9 @@ user-home@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" -user-home@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" - dependencies: - os-homedir "^1.0.0" - useragent@^2.1.6: - version "2.1.13" - resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.1.13.tgz#bba43e8aa24d5ceb83c2937473e102e21df74c10" + version "2.2.0" + resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.2.0.tgz#ef85f41903cfd05e2ba8c11ae61249c7a6bbf663" dependencies: lru-cache "2.2.x" tmp "0.0.x" @@ -7723,8 +7781,8 @@ uuid@^2.0.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" uuid@^3.0.0, uuid@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" v8flags@^2.0.2: version "2.1.1" @@ -7810,14 +7868,13 @@ vinyl@^0.5.0: replace-ext "0.0.1" vinyl@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.0.2.tgz#0a3713d8d4e9221c58f10ca16c0116c9e25eda7c" + version "2.1.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.1.0.tgz#021f9c2cf951d6b939943c89eb5ee5add4fd924c" dependencies: - clone "^1.0.0" + clone "^2.1.1" clone-buffer "^1.0.0" clone-stats "^1.0.0" cloneable-readable "^1.0.0" - is-stream "^1.1.0" remove-trailing-separator "^1.0.1" replace-ext "^1.0.0" @@ -7914,8 +7971,8 @@ webpack-core@~0.6.9: source-map "~0.4.1" webpack-dev-middleware@^1.0.11: - version "1.10.2" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.10.2.tgz#2e252ce1dfb020dbda1ccb37df26f30ab014dbd1" + version "1.11.0" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.11.0.tgz#09691d0973a30ad1f82ac73a12e2087f0a4754f9" dependencies: memory-fs "~0.4.1" mime "^1.3.4" @@ -8174,12 +8231,6 @@ yauzl@2.4.1: dependencies: fd-slicer "~1.0.1" -yazl@^2.1.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.4.2.tgz#14cb19083e1e25a70092c1588aabe0f4e4dd4d88" - dependencies: - buffer-crc32 "~0.2.3" - yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" From 852a933abd39c77c992c04aca8ee55c12337ef36 Mon Sep 17 00:00:00 2001 From: John Ellis Date: Mon, 10 Jul 2017 09:52:23 -0400 Subject: [PATCH 51/95] Yieldbot refresh - nextPageview with specific refresh slots (#1281) * Yieldbot refresh - nextPageview with argument for specific refresh slots to bid on * Yieldbot refresh - nextPageview with argument. slots own property --- modules/yieldbotBidAdapter.js | 27 ++++-- test/spec/modules/yieldbotBidAdapter_spec.js | 98 +++++++++++++++----- 2 files changed, 97 insertions(+), 28 deletions(-) diff --git a/modules/yieldbotBidAdapter.js b/modules/yieldbotBidAdapter.js index 1d52d6b181a..bef37e41321 100644 --- a/modules/yieldbotBidAdapter.js +++ b/modules/yieldbotBidAdapter.js @@ -84,24 +84,37 @@ function YieldbotAdapter() { ybotq.push(function () { var yieldbot = window.yieldbot; - + // Empty defined slots bidId array ybotlib.definedSlots = []; + // Iterate through bids to obtain Yieldbot slot config + // - Slot config can be different between initial and refresh requests + var psn = 'ERROR_PREBID_DEFINE_YB_PSN'; + var slots = {}; utils._each(bids, function (v) { var bid = v; - var psn = bid.params && bid.params.psn || 'ERROR_DEFINE_YB_PSN'; - var slot = bid.params && bid.params.slot || 'ERROR_DEFINE_YB_SLOT'; + // bidder params config: http://prebid.org/dev-docs/bidders/yieldbot.html + // - last psn wins + psn = bid.params && bid.params.psn || psn; + var slotName = bid.params && bid.params.slot || 'ERROR_PREBID_DEFINE_YB_SLOT'; - yieldbot.pub(psn); - yieldbot.defineSlot(slot, { sizes: bid.sizes || [] }); + slots[slotName] = bid.sizes || []; ybotlib.definedSlots.push(bid.bidId); }); - yieldbot.enableAsync(); + if (yieldbot._initialized !== true) { + yieldbot.pub(psn); + for (var slotName in slots) { + if (slots.hasOwnProperty(slotName)) { + yieldbot.defineSlot(slotName, { sizes: slots[slotName] || [] }); + } + } + yieldbot.enableAsync(); yieldbot.go(); } else { - yieldbot.nextPageview(); + yieldbot.nextPageview(slots); } }); + ybotq.push(function () { ybotlib.handleUpdateState(); }); diff --git a/test/spec/modules/yieldbotBidAdapter_spec.js b/test/spec/modules/yieldbotBidAdapter_spec.js index 400aa409a4a..006eb4bbf98 100644 --- a/test/spec/modules/yieldbotBidAdapter_spec.js +++ b/test/spec/modules/yieldbotBidAdapter_spec.js @@ -59,7 +59,7 @@ function restoreYieldbotMockLib() { window.yieldbot = null; } -function mockYieldbotInitBidRequest() { +function mockYieldbotBidRequest() { window.ybotq = window.ybotq || []; window.ybotq.forEach(fn => { fn.apply(window.yieldbot); @@ -75,27 +75,35 @@ beforeEach(function() { window.$$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); }); -describe('Yieldbot adapter tests', function() { - describe('callBids', function() { - beforeEach(function () { - sandbox = sinon.sandbox.create(); +function setupTest() { + sandbox = sinon.sandbox.create(); - createYieldbotMockLib(); + createYieldbotMockLib(); - sandbox.stub(adLoader, 'loadScript'); - yieldbotLibStub = sandbox.stub(window.yieldbot); - yieldbotLibStub.getSlotCriteria.restore(); + sandbox.stub(adLoader, 'loadScript'); + yieldbotLibStub = sandbox.stub(window.yieldbot); + yieldbotLibStub.getSlotCriteria.restore(); - bidManagerStub = sandbox.stub(bidManager, 'addBidResponse'); + bidManagerStub = sandbox.stub(bidManager, 'addBidResponse'); - const adapter = new YieldbotAdapter(); - adapter.callBids(bidderRequest); - mockYieldbotInitBidRequest(); + const adapter = new YieldbotAdapter(); + adapter.callBids(bidderRequest); + mockYieldbotBidRequest(); +} + +function restoreTest() { + sandbox.restore(); + restoreYieldbotMockLib(); +} + +describe('Yieldbot adapter tests', function() { + describe('callBids', function() { + beforeEach(function () { + setupTest(); }); afterEach(function() { - sandbox.restore(); - restoreYieldbotMockLib(); + restoreTest(); }); it('should request the yieldbot library', function() { @@ -114,6 +122,23 @@ describe('Yieldbot adapter tests', function() { sinon.assert.calledWith(yieldbotLibStub.defineSlot, 'leaderboard', {sizes: [[728, 90], [970, 90]]}); }); + it('should not use inherited Object properties', function() { + restoreTest(); + + let oProto = Object.prototype; + oProto.superProp = [300, 250]; + + expect(Object.prototype.superProp).to.be.an('array'); + setupTest(); + + sinon.assert.neverCalledWith(yieldbotLibStub.defineSlot, 'superProp', {sizes: [300, 250]}); + sinon.assert.calledWith(yieldbotLibStub.defineSlot, 'medrec', {sizes: [[300, 250], [300, 600]]}); + sinon.assert.calledWith(yieldbotLibStub.defineSlot, 'leaderboard', {sizes: [[728, 90], [970, 90]]}); + + delete oProto.superProp; + expect(Object.prototype.superProp).to.be.an('undefined'); + }); + it('should enable yieldbot async mode', function() { sinon.assert.called(yieldbotLibStub.enableAsync); }); @@ -168,19 +193,50 @@ describe('Yieldbot adapter tests', function() { it('should use yieldbot.nextPageview after first callBids', function() { const adapter = new YieldbotAdapter(); adapter.callBids(bidderRequest); - mockYieldbotInitBidRequest(); + mockYieldbotBidRequest(); expect(window.yieldbot._initialized).to.equal(true); adapter.callBids(bidderRequest); - mockYieldbotInitBidRequest(); + mockYieldbotBidRequest(); sinon.assert.calledOnce(yieldbotLibStub.nextPageview); }); + it('should call yieldbot.nextPageview with slot config of requested bids', function() { + window.pbjs._bidsRequested = window.pbjs._bidsRequested.filter(o => { + return o.bidderCode !== 'yieldbot'; + }); + + const adapter = new YieldbotAdapter(); + adapter.callBids(bidderRequest); + mockYieldbotBidRequest(); + + expect(window.yieldbot._initialized).to.equal(true); + sinon.assert.calledWith(yieldbotLibStub.defineSlot, 'medrec'); + sinon.assert.calledWith(yieldbotLibStub.defineSlot, 'leaderboard'); + + window.pbjs._bidsRequested = window.pbjs._bidsRequested.filter(o => { + return o.bidderCode !== 'yieldbot'; + }); + + const refreshBids = bidderRequest.bids.filter((object) => { return object.placementCode === '/4294967296/adunit1'; }); + let refreshRequest = Object.assign({}, bidderRequest); + refreshRequest.bids = refreshBids; + expect(refreshRequest.bids.length).to.equal(1); + + adapter.callBids(refreshRequest); + mockYieldbotBidRequest(); + + const bid = refreshBids[0]; + const expectedSlots = { 'leaderboard': [[728, 90], [970, 90]] }; + + sinon.assert.calledWithExactly(yieldbotLibStub.nextPageview, expectedSlots); + }); + it('should not throw on callBids without bidsRequested', function() { const adapter = new YieldbotAdapter(); adapter.callBids(bidderRequest); - mockYieldbotInitBidRequest(); + mockYieldbotBidRequest(); expect(window.yieldbot._initialized).to.equal(true); @@ -189,7 +245,7 @@ describe('Yieldbot adapter tests', function() { }); adapter.callBids(bidderRequest); - mockYieldbotInitBidRequest(); + mockYieldbotBidRequest(); sinon.assert.calledOnce(yieldbotLibStub.nextPageview); }); @@ -200,7 +256,7 @@ describe('Yieldbot adapter tests', function() { const adapter = new YieldbotAdapter(); adapter.callBids(bidderRequest); - mockYieldbotInitBidRequest(); + mockYieldbotBidRequest(); let bidResponses = window.$$PREBID_GLOBAL$$._bidsReceived.filter(o => { return o.bidderCode === 'yieldbot'; @@ -209,7 +265,7 @@ describe('Yieldbot adapter tests', function() { expect(bidResponses.length).to.equal(0); adapter.callBids(bidderRequest); - mockYieldbotInitBidRequest(); + mockYieldbotBidRequest(); sinon.assert.calledOnce(yieldbotLibStub.nextPageview); }); }); From 0f066b076be56367adf2bf94a46f9c041d1f6765 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Mon, 10 Jul 2017 16:12:50 +0100 Subject: [PATCH 52/95] Audience Network: Add support for video format (#1292) --- modules/audienceNetworkBidAdapter.js | 72 ++++++-- src/polyfill.js | 1 + .../modules/audienceNetworkBidAdapter_spec.js | 164 ++++++++++++++++++ 3 files changed, 223 insertions(+), 14 deletions(-) diff --git a/modules/audienceNetworkBidAdapter.js b/modules/audienceNetworkBidAdapter.js index 7e054fe7d54..d19bf4d9278 100644 --- a/modules/audienceNetworkBidAdapter.js +++ b/modules/audienceNetworkBidAdapter.js @@ -21,7 +21,8 @@ const validateBidRequest = bid => typeof bid.params === 'object' && typeof bid.params.placementId === 'string' && bid.params.placementId.length > 0 && - Array.isArray(bid.sizes) && bid.sizes.length > 0; + Array.isArray(bid.sizes) && bid.sizes.length > 0 && + (isVideo(bid.params.format) || bid.sizes.map(flattenSize).some(isValidSize)); /** * Flattens a 2-element [W, H] array as a 'WxH' string, @@ -32,6 +33,13 @@ const validateBidRequest = bid => const flattenSize = size => (Array.isArray(size) && size.length === 2) ? `${size[0]}x${size[1]}` : size; +/** + * Expands a 'WxH' string as a 2-element [W, H] array + * @param {String} size + * @returns {Array} + */ +const expandSize = size => size.split('x').map(Number); + /** * Is this a valid slot size? * @param {String} size @@ -39,6 +47,20 @@ const flattenSize = size => */ const isValidSize = size => ['300x250', '320x50'].includes(size); +/** + * Is this a video format? + * @param {String} format + * @returns {Boolean} + */ +const isVideo = format => format === 'video'; + +/** + * Which SDK version should be used for this format? + * @param {String} format + * @returns {String} + */ +const sdkVersion = format => isVideo(format) ? '' : '5.5.web'; + /** * Does the search part of the URL contain "anhb_testmode" * and therefore indicate testmode should be used? @@ -83,24 +105,33 @@ ${nativeContainer}

`; /** * Creates a "good" Bid object with the given bid ID and CPM. * @param {String} placementId - * @param {String} bidId * @param {String} size + * @param {String} format + * @param {String} bidId * @param {Number} cpmCents + * @param {String} pageurl * @returns {Object} Bid */ -const createSuccessBidResponse = (placementId, size, format, bidId, cpmCents) => { +const createSuccessBidResponse = (placementId, size, format, bidId, cpmCents, pageurl) => { const bid = createBid(STATUS.GOOD, { bidId }); // Prebid attributes bid.bidderCode = getBidderCode(); bid.cpm = cpmCents / 100; bid.ad = createAdHtml(placementId, format, bidId); - [bid.width, bid.height] = size.split('x').map(Number); + [bid.width, bid.height] = expandSize(size); // Audience Network attributes bid.hb_bidder = 'fan'; bid.fb_bidid = bidId; bid.fb_format = format; bid.fb_placementid = placementId; + // Video attributes + if (isVideo(format)) { + const vast = `https://an.facebook.com/v1/instream/vast.xml?placementid=${placementId}&pageurl=${encodeURIComponent(pageurl)}&playerwidth=${bid.width}&playerheight=${bid.height}&bidid=${bidId}`; + bid.mediaType = 'video'; + bid.vastUrl = vast; + bid.descriptionUrl = vast; + } return bid; }; @@ -121,7 +152,7 @@ const createFailureBidResponse = () => { * @param {String} params.bids[].placementCode - Prebid placement identifier * @param {Object} params.bids[].params * @param {String} params.bids[].params.placementId - Audience Network placement identifier - * @param {String} params.bids[].params.format - Optional format, one of 'native' or 'fullwidth' if set + * @param {String} params.bids[].params.format - Optional format, one of 'video', 'native' or 'fullwidth' if set * @param {Array} params.bids[].sizes - list of desired advert sizes * @param {Array} params.bids[].sizes[] - Size arrays [h,w]: should include one of [300, 250], [320, 50]: first matched size is used * @returns {void} @@ -132,33 +163,43 @@ const callBids = bidRequest => { const placementids = []; const adformats = []; const sizes = []; + const sdk = []; + bidRequest.bids .filter(validateBidRequest) .forEach(bid => bid.sizes .map(flattenSize) - .filter(isValidSize) + .filter(size => isValidSize(size) || isVideo(bid.params.format)) .slice(0, 1) .forEach(size => { adUnitCodes.push(bid.placementCode); placementids.push(bid.params.placementId); adformats.push(bid.params.format || size); sizes.push(size); + sdk.push(sdkVersion(bid.params.format)); }) ); if (placementids.length) { // Build URL const testmode = isTestmode(); + const pageurl = location.href; + const search = { + placementids, + adformats, + testmode, + pageurl, + sdk + }; + const video = adformats.findIndex(isVideo); + if (video !== -1) { + [search.playerwidth, search.playerheight] = expandSize(sizes[video]); + } const url = format({ protocol: 'https', host: 'an.facebook.com', pathname: '/v2/placementbid.json', - search: { - sdk: '5.5.web', - testmode, - placementids, - adformats - } + search }); // Request ajax(url, res => { @@ -182,7 +223,8 @@ const callBids = bidRequest => { sizes[i], adformats[i], bid.bid_id, - bid.bid_price_cents + bid.bid_price_cents, + pageurl )) ); } @@ -202,6 +244,8 @@ const callBids = bidRequest => { */ const AudienceNetwork = () => ({ callBids, setBidderCode, getBidderCode }); -adaptermanager.registerBidAdapter(new AudienceNetwork, 'audienceNetwork'); +adaptermanager.registerBidAdapter(new AudienceNetwork, 'audienceNetwork', { + supportedMediaTypes: ['video'] +}); module.exports = AudienceNetwork; diff --git a/src/polyfill.js b/src/polyfill.js index 31c3607ece3..1c8913824ae 100644 --- a/src/polyfill.js +++ b/src/polyfill.js @@ -2,6 +2,7 @@ Misc polyfills */ require('core-js/fn/array/find'); +require('core-js/fn/array/find-index'); require('core-js/fn/array/includes'); require('core-js/fn/object/assign'); diff --git a/test/spec/modules/audienceNetworkBidAdapter_spec.js b/test/spec/modules/audienceNetworkBidAdapter_spec.js index 0ed80086802..5cd064f169c 100644 --- a/test/spec/modules/audienceNetworkBidAdapter_spec.js +++ b/test/spec/modules/audienceNetworkBidAdapter_spec.js @@ -12,6 +12,8 @@ import AudienceNetwork from 'modules/audienceNetworkBidAdapter'; const bidderCode = 'audienceNetwork'; const placementId = 'test-placement-id'; const placementCode = '/test/placement/code'; +const playerwidth = 320; +const playerheight = 180; /** * Expect haystack string to contain needle n times. @@ -198,6 +200,33 @@ describe('AudienceNetwork adapter', () => { // Verify no attempt to log error expect(logError.called).to.equal(false); }); + + it('video', () => { + // Valid parameters + const params = { + bidderCode, + bids: [{ + bidder: bidderCode, + params: { + placementId, + format: 'video' + }, + sizes: [[playerwidth, playerheight]] + }] + }; + // Request bids + AudienceNetwork().callBids(params); + // Verify attempt to fetch response + expect(requests).to.have.lengthOf(1); + expect(requests[0].method).to.equal('GET'); + expect(requests[0].url) + .to.contain('https://an.facebook.com/v2/placementbid.json?') + .and.to.contain('placementids[]=test-placement-id') + .and.to.contain('adformats[]=video') + .and.to.contain('sdk[]='); + // Verify no attempt to log error + expect(logError.called).to.equal(false); + }); }); describe('callBids response handling', () => { @@ -453,5 +482,140 @@ describe('AudienceNetwork adapter', () => { // Verify no attempt to log error expect(logError.called).to.equal(false, 'logError called'); }); + + it('valid video bid in response', () => { + const bidId = 'test-bid-id-video'; + // Valid response + server.respondWith(JSON.stringify({ + errors: [], + bids: { + [placementId]: [{ + placement_id: placementId, + bid_id: bidId, + bid_price_cents: 123, + bid_price_currency: 'usd', + bid_price_model: 'cpm' + }] + } + })); + // Request bids + AudienceNetwork().callBids({ + bidderCode, + bids: [{ + bidder: bidderCode, + placementCode, + params: { + placementId, + format: 'video' + }, + sizes: [[playerwidth, playerheight]] + }] + }); + server.respond(); + // Verify addBidResponse call + expect(addBidResponse.calledOnce).to.equal(true); + const addBidResponseArgs = addBidResponse.args[0]; + expect(addBidResponseArgs).to.have.lengthOf(2); + expect(addBidResponseArgs[0]).to.equal(placementCode); + expect(addBidResponseArgs[1].getStatusCode()).to.equal(STATUS.GOOD); + expect(addBidResponseArgs[1].cpm).to.equal(1.23); + expect(addBidResponseArgs[1].bidderCode).to.equal(bidderCode); + // Video-specific properties + expect(addBidResponseArgs[1].mediaType).to.equal('video'); + expect(addBidResponseArgs[1].vastUrl) + .to.equal(addBidResponseArgs[1].descriptionUrl) + .and.to.contain('https://an.facebook.com/v1/instream/vast.xml?') + .and.to.contain(`placementid=${placementId}`) + .and.to.contain('pageurl=http%3A%2F%2F') + .and.to.contain(`playerwidth=${playerwidth}`) + .and.to.contain(`playerheight=${playerheight}`) + .and.to.contain(`bidid=${bidId}`); + expect(addBidResponseArgs[1].width).to.equal(playerwidth); + expect(addBidResponseArgs[1].height).to.equal(playerheight); + // Verify no attempt to log error + expect(logError.called).to.equal(false, 'logError called'); + }); + + it('mixed video and native bids', () => { + const videoPlacementId = 'test-video-placement-id'; + const videoBidId = 'test-video-bid-id'; + const nativePlacementId = 'test-native-placement-id'; + const nativeBidId = 'test-native-bid-id'; + // Valid response + server.respondWith(JSON.stringify({ + errors: [], + bids: { + [videoPlacementId]: [{ + placement_id: videoPlacementId, + bid_id: videoBidId, + bid_price_cents: 123, + bid_price_currency: 'usd', + bid_price_model: 'cpm' + }], + [nativePlacementId]: [{ + placement_id: nativePlacementId, + bid_id: nativeBidId, + bid_price_cents: 456, + bid_price_currency: 'usd', + bid_price_model: 'cpm' + }] + } + })); + // Request bids + AudienceNetwork().callBids({ + bidderCode, + bids: [{ + bidder: bidderCode, + placementCode, + params: { + placementId: videoPlacementId, + format: 'video' + }, + sizes: [[playerwidth, playerheight]] + }, { + bidder: bidderCode, + placementCode, + params: { + placementId: nativePlacementId, + format: 'native' + }, + sizes: [[300, 250]] + }] + }); + server.respond(); + // Verify multiple attempts to call addBidResponse + expect(addBidResponse.calledTwice).to.equal(true); + // Verify video + const addBidResponseVideoCall = addBidResponse.args[0]; + expect(addBidResponseVideoCall).to.have.lengthOf(2); + expect(addBidResponseVideoCall[0]).to.equal(placementCode); + expect(addBidResponseVideoCall[1].getStatusCode()).to.equal(STATUS.GOOD); + expect(addBidResponseVideoCall[1].cpm).to.equal(1.23); + expect(addBidResponseVideoCall[1].bidderCode).to.equal(bidderCode); + // Video-specific properties + expect(addBidResponseVideoCall[1].mediaType).to.equal('video'); + expect(addBidResponseVideoCall[1].vastUrl) + .to.equal(addBidResponseVideoCall[1].descriptionUrl) + .and.to.contain('https://an.facebook.com/v1/instream/vast.xml?') + .and.to.contain(`placementid=${videoPlacementId}`) + .and.to.contain('pageurl=http%3A%2F%2F') + .and.to.contain(`playerwidth=${playerwidth}`) + .and.to.contain(`playerheight=${playerheight}`) + .and.to.contain(`bidid=${videoBidId}`); + expect(addBidResponseVideoCall[1].width).to.equal(playerwidth); + expect(addBidResponseVideoCall[1].height).to.equal(playerheight); + // Verify native + const addBidResponseNativeCall = addBidResponse.args[1]; + expect(addBidResponseNativeCall).to.have.lengthOf(2); + expect(addBidResponseNativeCall[0]).to.equal(placementCode); + expect(addBidResponseNativeCall[1].getStatusCode()).to.equal(STATUS.GOOD); + expect(addBidResponseNativeCall[1].cpm).to.equal(4.56); + expect(addBidResponseNativeCall[1].bidderCode).to.equal(bidderCode); + expect(addBidResponseNativeCall[1].width).to.equal(300); + expect(addBidResponseNativeCall[1].height).to.equal(250); + expect(addBidResponseNativeCall[1].ad).to.contain(`placementid:'${nativePlacementId}',format:'native',bidid:'${nativeBidId}'`); + // Verify no attempt to log error + expect(logError.called).to.equal(false, 'logError called'); + }); }); }); From 579cf9ad25b0821ca193efe040d228db01c8a2c2 Mon Sep 17 00:00:00 2001 From: npeceniak Date: Mon, 10 Jul 2017 09:22:46 -0600 Subject: [PATCH 53/95] Spotx video Adapter (#1326) * Add Spotx bidder adapter. * Addressing code review comments for spotx adapter. * Add spotx_spec.js file for unit tests. * Increase test coverage * Add check for directSDK slot and video_slot - If passed an id set the slot and video_slot element when initializing the directsdk * Undo bracket notation change * Add Spotx bidder adapter. Addressing code review comments for spotx adapter. Add spotx_spec.js file for unit tests. Increase test coverage Add check for directSDK slot and video_slot - If passed an id set the slot and video_slot element when initializing the directsdk Undo bracket notation change * Update spotx adapter and spec file to use new module system * Address comments from pull request - Added parameter validation function - removed descriptionUrl --- modules/spotxBidAdapter.js | 141 ++++++++++++++++ test/spec/modules/spotxBidAdapter_spec.js | 186 ++++++++++++++++++++++ 2 files changed, 327 insertions(+) create mode 100644 modules/spotxBidAdapter.js create mode 100644 test/spec/modules/spotxBidAdapter_spec.js diff --git a/modules/spotxBidAdapter.js b/modules/spotxBidAdapter.js new file mode 100644 index 00000000000..ada3957fb19 --- /dev/null +++ b/modules/spotxBidAdapter.js @@ -0,0 +1,141 @@ +import Adapter from 'src/adapter'; +import bidfactory from 'src/bidfactory'; +import bidmanager from 'src/bidmanager'; +import adLoader from 'src/adloader'; +import * as utils from 'src/utils'; +import { STATUS } from 'src/constants'; +import adaptermanager from 'src/adaptermanager'; + +function Spotx() { + let baseAdapter = Adapter.createNew('Spotx'); + let bidReq; + let KVP_Object; + + baseAdapter.callBids = function(bidRequest) { + if (!bidRequest || !bidRequest.bids || bidRequest.bids.length === 0) { + return; + } + bidReq = bidRequest.bids[0] || []; + + if(!validateParams(bidReq)) + { + console.log("Bid Request does not contain valid parameters."); + return; + } + + loadDSDK(); + }; + + // Load the SpotX Direct AdOS SDK onto the page + function loadDSDK() + { + var channelId = bidReq.params.video.channel_id; + adLoader.loadScript('//js.spotx.tv/directsdk/v1/' + channelId + '.js', initDSDK, true); + } + + // We have a Direct AdOS SDK! Set options and initialize it! + function initDSDK() + { + var options = bidReq.params.video; + + // If we are passed a id string set the slot and video slot to the element using that id. + if (typeof options.slot === 'string') + { + options.slot = document.getElementById(bidReq.params.video.slot); + } + if (typeof options.video_slot === 'string') + { + options.video_slot = document.getElementById(bidReq.params.video.video_slot); + } + + var directAdOS = new SpotX.DirectAdOS(options); + + directAdOS.getAdServerKVPs().then(function(adServerKVPs) { + // Got an ad back. Build a successful response. + var resp = { + bids: [] + }; + var bid = {}; + + bid.cmpID = bidReq.params.video.channel_id; + bid.cpm = adServerKVPs.spotx_bid; + bid.url = adServerKVPs.spotx_ad_key; + bid.cur = 'USD'; + bid.bidderCode = 'spotx'; + bid.height = bidReq.sizes[0][1]; + bid.width = bidReq.sizes[0][0]; + resp.bids.push(bid); + KVP_Object = adServerKVPs; + handleResponse(resp); + }, function() { + // No ad... + handleResponse() + }); + } + + function createBid(status) + { + var bid = bidfactory.createBid(status, utils.getBidRequest(bidReq.bidId)); + + // Stuff we have no matter what + bid.bidderCode = bidReq.bidder; + bid.placementCode = bidReq.placementCode; + bid.requestId = bidReq.requestId; + bid.code = bidReq.bidder; + + // Stuff we only get with a successful response + if (status === STATUS.GOOD && KVP_Object) { + let url = '//search.spotxchange.com/ad/vast.html?key=' + KVP_Object.spotx_ad_key; + bid.mediaType = 'video'; + + bid.cpm = KVP_Object.spotx_bid; + bid.vastUrl = url; + bid.ad = url; + + bid.width = bidReq.sizes[0][0]; + bid.height = bidReq.sizes[0][1]; + } + + return bid; + } + + /* Notify Prebid of bid responses so bids can get in the auction */ + function handleResponse(response) { + if (!response || !response.bids || !response.bids.length) { + bidmanager.addBidResponse(bidReq.placementCode, createBid(STATUS.NO_BID)); + } + else { + bidmanager.addBidResponse(bidReq.placementCode, createBid(STATUS.GOOD, response.bids[0])); + } + } + + function validateParams(request){ + if(typeof request.params !== "object" && typeof request.params.video !== "object") + { + return false; + } + + // Check that all of our required parameters are defined. + if(bidReq.params.video.channel_id === undefined || bidReq.params.video.slot === undefined || bidReq.params.video.video_slot === undefined) + { + return false; + } + return true; + } + + return { + createNew: Spotx.createNew, + callBids: baseAdapter.callBids, + setBidderCode: baseAdapter.setBidderCode + }; +} + +Spotx.createNew = function() { + return new Spotx(); +}; + +adaptermanager.registerBidAdapter(new Spotx, 'spotx', { + supportedMediaTypes: ['video'] +}); + +module.exports = Spotx; diff --git a/test/spec/modules/spotxBidAdapter_spec.js b/test/spec/modules/spotxBidAdapter_spec.js new file mode 100644 index 00000000000..b8974def619 --- /dev/null +++ b/test/spec/modules/spotxBidAdapter_spec.js @@ -0,0 +1,186 @@ +import {expect} from 'chai'; +import {assert} from 'chai'; +import Adapter from 'modules/spotxBidAdapter'; +import bidManager from 'src/bidmanager'; +import adLoader from 'src/adloader'; + +const CHANNEL_ID = 85394; +const CACHE_KEY = 'eyJob3N0IjoiZmUwMDEuc3BvdHguZ2FkZ2V0cy5sb2QiLCJja'; + +let bidRequest = { + 'bidderCode': 'spotx', + 'requestId': '4b8bb067-fca9-478b-9207-d24b87fce85c', + 'bidderRequestId': '1bfc89fa86fd1d', + 'timeout': 1000, + 'bids': [ + { + 'bidId': '2626663210bd26', + 'bidder': 'spotx', + 'bidderRequestId': '145a190a61161e', + 'mediaType': 'video', + 'params': { + 'placementId': '123456789', + 'video': { + 'ad_mute': false, + 'autoplay': true, + 'channel_id': CHANNEL_ID, + 'hide_skin': false, + 'slot': null, + 'video_slot': null + } + }, + 'placementCode': 'video1', + 'requestId': '5e1e93aa-55cf-4f73-a56a-8a74d0584c5f', + 'sizes': [[640, 480]], + 'transactionId': 'df629792-c9ae-481e-9ce1-eaa83bde4cdb' + } + ] +}; + +let badBidRequest = { + 'bidderCode': 'spotx', + 'bids': [ + { + 'bidId': '2626663210bd26', + 'bidder': 'spotx', + 'mediaType': 'video', + 'params': { + 'placementId': '123456789', + 'video': { + 'slot': 'contentSpotx', + 'video_slot': 'contentElementSpotx' + } + }, + 'placementCode': 'video1', + } + ] +}; + +var xhrResponse = JSON.stringify({ + 'id': CHANNEL_ID.toString(), + 'cur': 'USD', + 'seatbid': [ + { + 'bid': [ + { + 'id': '47e.fc9b5.90ede6', + 'impid': '1497549328279', + 'impression_guid': 'e2514a4651f311e7b50f113c04e90000', + 'price': '20', + 'adm': '<\/VASTAdTagURI><\/Wrapper><\/Ad><\/VAST>', + 'adomain': 'null', + 'crid': '47e.fc9b5.90ede6', + 'cid': 'null', + 'ext': { + 'cache_key': CACHE_KEY + } + } + ] + } + ] +}); + +describe('spotx adapter tests', () => { + describe('callBids', () => { + let server; + let adapter; + + beforeEach(() => { + adapter = Adapter.createNew(); + + var slot = document.createElement('div'); + slot.setAttribute('id', 'contentSpotx'); + document.body.appendChild(slot); + + var videoSlot = document.createElement('video'); + videoSlot.setAttribute('id', 'contentElementSpotx'); + slot.appendChild(videoSlot); + + var source1 = document.createElement('source'); + source1.setAttribute('src', 'http://rmcdn.2mdn.net/Demo/vast_inspector/android.mp4'); + videoSlot.appendChild(source1); + + bidRequest.bids[0].params.video.slot = slot; + bidRequest.bids[0].params.video.video_slot = videoSlot; + + server = sinon.fakeServer.create(); + server.respondImmediately = true; + }); + + afterEach(() => { + var slot = document.getElementById('contentSpotx'); + while (slot.firstChild) { + slot.removeChild(slot.firstChild); + } + var body = slot.parentElement; + body.removeChild(slot); + + server.restore(); + }); + + it('should load Direct AdOS onto page', () => { + sinon.spy(adLoader, 'loadScript'); + + adapter.callBids(bidRequest); + + sinon.assert.calledOnce(adLoader.loadScript); + expect(adLoader.loadScript.firstCall.args[0]).to.equal('//js.spotx.tv/directsdk/v1/' + CHANNEL_ID + '.js'); + expect(adLoader.loadScript.firstCall.args[1]).to.be.a('function'); + + adLoader.loadScript.restore(); + }); + + it('should not load Direct AdOS onto page if no bid is provided', () => { + sinon.spy(adLoader, 'loadScript'); + + adapter.callBids(); + sinon.assert.notCalled(adLoader.loadScript); + adLoader.loadScript.restore(); + }); + + it('should add bid response on success', (done) => { + sinon.stub(bidManager, 'addBidResponse', (placementCode, bid) => { + expect(placementCode).to.equal('video1'); + expect(bid.bidderCode).to.equal('spotx'); + expect(bid.cpm).to.equal(20); + expect(bid.mediaType).to.equal('video'); + expect(bid.statusMessage).to.equal('Bid available'); + expect(bid.vastUrl).to.equal('//search.spotxchange.com/ad/vast.html?key=' + CACHE_KEY); + + bidManager.addBidResponse.restore(); + done(); + }); + + server.respondWith((request) => { + if (request.url.match(/openrtb\/2.3\/dados/) && request.method === 'POST') { + request.respond(200, {}, xhrResponse); + } + }); + + adapter.callBids(bidRequest); + }); + + it('should add failed bid response on error', (done) => { + sinon.stub(bidManager, 'addBidResponse', (placementCode, bid) => { + expect(placementCode).to.equal('video1'); + expect(bid.bidderCode).to.equal('spotx'); + expect(bid.statusMessage).to.equal('Bid returned empty or error response'); + expect(bid.cpm).to.be.undefined; + expect(bid.mediaType).to.be.undefined; + expect(bid.vastUrl).to.be.undefined; + + bidManager.addBidResponse.restore(); + done(); + }); + + server.respondWith((request) => { + if (request.url.match(/openrtb\/2.3\/dados/) && request.method === 'POST') { + request.respond(204, {}, ''); + } + }); + + adapter.callBids(bidRequest); + }); + }); +}); From b54004d251c9e50563156b0eb55b316a7bc0a9cd Mon Sep 17 00:00:00 2001 From: sergey-roxot Date: Mon, 10 Jul 2017 20:06:02 +0300 Subject: [PATCH 54/95] Add s2s and user sync features to roxot analytics adapter (#1337) * add roxot adapter * update roxot analytics system * remove unused test * remove unused import * update code after review * Added s2s tracking * Add user sync * Empty s2sConfig case handling added * Removed s2s * Add s2s bidder code setters * Revert "Add s2s bidder code setters" This reverts commit 89a44e35e2d72a36c55315a9ea19a2fcbfca8562. * Revert "Removed s2s" This reverts commit 929707fcb845016936ebb1346fbf1d99d3cd6416. * Revert "Empty s2sConfig case handling added" This reverts commit 2f55e24e6be33b5b2a3343a8b8080a538de54b9f. * Revert s2s * Removed user sync feature via iframe * Add ajax withCredentials option * Add xhr withCredentials --- modules/roxotAnalyticsAdapter.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/modules/roxotAnalyticsAdapter.js b/modules/roxotAnalyticsAdapter.js index 905da96df6a..99ea6bc9977 100644 --- a/modules/roxotAnalyticsAdapter.js +++ b/modules/roxotAnalyticsAdapter.js @@ -37,12 +37,16 @@ function buildEventStack() { function send(eventType, data, sendDataType) { let fullUrl = url + '?publisherIds[]=' + initOptions.publisherIds.join('&publisherIds[]=') + '&host=' + window.location.hostname; - - ajax( - fullUrl, - (result) => utils.logInfo('Event ' + eventType + ' sent ' + sendDataType + ' to roxot prebid analytic with result' + result), - JSON.stringify(data) - ); + let xhr = new XMLHttpRequest(); + xhr.open('POST', fullUrl, true); + xhr.setRequestHeader('Content-Type', 'text/plain'); + xhr.withCredentials = true; + xhr.onreadystatechange = function(result) { + if (this.readyState != 4) return; + + utils.logInfo('Event ' + eventType + ' sent ' + sendDataType + ' to roxot prebid analytic with result' + result); + } + xhr.send(JSON.stringify(data)); } function pushEvent(eventType, args) { From 56bdd2791af7213bc3828f4964aadecc7ad1672f Mon Sep 17 00:00:00 2001 From: dbemiller Date: Tue, 11 Jul 2017 14:13:02 -0400 Subject: [PATCH 55/95] Implementing prebid-cache to support Video ads (#1277) * Added code to cache video content, and made the cache key accessible through the bid. * Renamed the method we add to the bid. * Removed an extraneous function. * Removed some accidental console.log messages * Added unit tests for the video cache, and fixed a bug or two. * Refactored the bidmanager a bit to help wrap my head around it, and changed video support so that only bids which have been cached are valid. * Implemented video end-to-end. Waiting on the modules PR so that it can be transformed into a module. * Better fix to the utils bug. Modernized the imports. * Updated documentation. * Added a few unit tests, and added fixtures for shared data structures. * Added more thorough tests, and refactored a bit for better code reuse. * Renamed a function. * Added tests for adding video bids when the cache fails. * Removed an unused import. * Added tests for the adServerManager, and renamed some files for consistency with the normal conventions. * Renamed the dfpVideo module, and added unit tests for it. * Moved dfpAdServerVideo into the modules directory. * Fixed a bug, and added a regression test to catch it in the future. * Added a bare-bones example page. * Made some cosmetic changes to names and documentation. * Removed the shifty API. Updated unit tests. Renamed a property because Ive messed it up multiple times myself already during testing, expecting it to have a different name. * Most code review comments. Still need to look into the details of VAST. * Deleted some unused code, and upped the vast version to use 3.0 everywhere. * Made the cache use the new endpoints * Fixed style. * Moved the test page into the tests directory. * include the bid that ended the auction --- modules/dfpAdServerVideo.js | 88 ++++++++++++ src/adServerManager.js | 54 ++++++++ src/bidmanager.js | 90 +++++++++--- src/prebid.js | 5 + src/utils.js | 10 +- src/videoCache.js | 114 +++++++++++++++ test/fixtures/video/adUnit.json | 17 +++ test/fixtures/video/bidRequest.json | 26 ++++ test/fixtures/video/bidResponse.json | 13 ++ test/mocks/videoCacheStub.js | 34 +++++ test/pages/video.html | 134 ++++++++++++++++++ test/spec/modules/dfpAdServerVideo_spec.js | 94 +++++++++++++ test/spec/unit/adServerManager_spec.js | 30 ++++ test/spec/unit/bidmanager_spec.js | 154 +++++++++++++++++++++ test/spec/videoCache_spec.js | 94 +++++++++++++ 15 files changed, 929 insertions(+), 28 deletions(-) create mode 100644 modules/dfpAdServerVideo.js create mode 100644 src/adServerManager.js create mode 100644 src/videoCache.js create mode 100644 test/fixtures/video/adUnit.json create mode 100644 test/fixtures/video/bidRequest.json create mode 100644 test/fixtures/video/bidResponse.json create mode 100644 test/mocks/videoCacheStub.js create mode 100644 test/pages/video.html create mode 100644 test/spec/modules/dfpAdServerVideo_spec.js create mode 100644 test/spec/unit/adServerManager_spec.js create mode 100644 test/spec/unit/bidmanager_spec.js create mode 100644 test/spec/videoCache_spec.js diff --git a/modules/dfpAdServerVideo.js b/modules/dfpAdServerVideo.js new file mode 100644 index 00000000000..d73fa53802f --- /dev/null +++ b/modules/dfpAdServerVideo.js @@ -0,0 +1,88 @@ +/** + * This module adds [DFP support]{@link https://www.doubleclickbygoogle.com/} for Video to Prebid. + */ + +import { registerVideoSupport } from '../src/adServerManager'; +import { getWinningBids } from '../src/targeting'; +import { formatQS, format as buildUrl } from '../src/url'; +import { parseSizesInput } from '../src/utils'; + +/** + * @typedef {Object} DfpVideoParams + * + * This object contains the params needed to form a URL which hits the + * [DFP API]{@link https://support.google.com/dfp_premium/answer/1068325?hl=en}. + * + * All params (except iu, mentioned below) should be considered optional. This module will choose reasonable + * defaults for all of the other required params. + * + * The cust_params property, if present, must be an object. It will be merged with the rest of the + * standard Prebid targeting params (hb_adid, hb_bidder, etc). + * + * @param {string} iu This param *must* be included, in order for us to create a valid request. + * @param [string] description_url This field is required if you want Ad Exchange to bid on our ad unit... + * but otherwise optional + */ + +/** + * @typedef {Object} DfpVideoOptions + * + * @param {Object} adUnit The adUnit which this bid is supposed to help fill. + * @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. + * These will override this module's defaults whenever they conflict. + */ + +/** Safe defaults which work on pretty much all video calls. */ +const defaultParamConstants = { + env: 'vp', + gdfp_req: 1, + output: 'xml_vast3', + unviewed_position_start: 1, +}; + +/** + * Merge all the bid data and publisher-supplied options into a single URL, and then return it. + * + * @see [The DFP API]{@link https://support.google.com/dfp_premium/answer/1068325?hl=en#env} for details. + * + * @param {DfpVideoOptions} options Options which should be used to construct the URL. + * + * @return {string} A URL which calls DFP, letting options.bid + * (or the auction's winning bid for this adUnit, if undefined) compete alongside the rest of the + * demand in DFP. + */ +export default function buildDfpVideoUrl(options) { + const adUnit = options.adUnit; + const bid = options.bid || getWinningBids(adUnit.code)[0]; + + const derivedParams = { + correlator: Date.now(), + sz: parseSizesInput(adUnit.sizes).join('|'), + url: location.href, + }; + + const customParams = Object.assign({}, + bid.adserverTargeting, + { hb_uuid: bid.videoCacheKey }, + options.params.cust_params); + + const queryParams = Object.assign({}, + defaultParamConstants, + derivedParams, + options.params, + { cust_params: encodeURIComponent(formatQS(customParams))}); + + return buildUrl({ + protocol: 'https', + host: 'pubads.g.doubleclick.net', + pathname: '/gampad/ads', + search: queryParams + }); +} + +registerVideoSupport('dfp', { + buildVideoUrl: buildDfpVideoUrl +}); diff --git a/src/adServerManager.js b/src/adServerManager.js new file mode 100644 index 00000000000..0775b50a72f --- /dev/null +++ b/src/adServerManager.js @@ -0,0 +1,54 @@ +import { getGlobal } from 'src/prebidGlobal'; +import { logWarn } from 'src/utils'; + +const prebid = getGlobal(); + +/** + * This file defines the plugin points in prebid-core for AdServer-specific functionality. + * + * Its main job is to expose functions for AdServer modules to append functionality to the Prebid public API. + * For a given Ad Server with name "adServerName", these functions will only change the API in the + * $$PREBID_GLOBAL$$.adServers[adServerName] namespace. + */ + +/** + * @typedef {Object} CachedVideoBid + * + * @property {string} videoCacheId The ID which can be used to retrieve this video from prebid-server. + * This is the same ID given to the callback in the videoCache's store function. + */ + +/** + * @function VideoAdUrlBuilder + * + * @param {CachedVideoBid} bid The winning Bid which the ad server should show, assuming it beats out + * the competition. + * + * @param {Object} options Options required by the Ad Server to make a valid AdServer URL. + * This object will have different properties depending on the specific ad server supported. + * For more information, see the docs inside the ad server module you're supporting. + * + * @return {string} A URL which can be passed into the Video player to play an ad. + */ + +/** + * @typedef {Object} VideoSupport + * + * @function {VideoAdUrlBuilder} buildVideoAdUrl + */ + +/** + * Enable video support for the Ad Server. + * + * @property {string} name The identifying name for this adserver. + * @property {VideoSupport} videoSupport An object with the functions needed to support video in Prebid. + */ +export function registerVideoSupport(name, videoSupport) { + prebid.adServers = prebid.adServers || { }; + prebid.adServers[name] = prebid.adServers[name] || { }; + if (prebid.adServers[name].buildVideoUrl) { + logWarn(`Multiple calls to registerVideoSupport for AdServer ${name}. Expect surprising behavior.`); + return; + } + prebid.adServers[name].buildVideoUrl = videoSupport.buildVideoUrl; +} diff --git a/src/bidmanager.js b/src/bidmanager.js index 2f1cad4dbf0..8bbd52c612f 100644 --- a/src/bidmanager.js +++ b/src/bidmanager.js @@ -1,6 +1,7 @@ import { uniques, flatten, adUnitsFilter, getBidderRequest } from './utils'; import {getPriceBucketString} from './cpmBucketManager'; import {NATIVE_KEYS, nativeBidIsValid} from './native'; +import { store } from './videoCache'; var CONSTANTS = require('./constants.json'); var AUCTION_END = CONSTANTS.EVENTS.AUCTION_END; @@ -87,17 +88,43 @@ exports.bidsBackAll = function () { * This function should be called to by the bidder adapter to register a bid response */ exports.addBidResponse = function (adUnitCode, bid) { - if (!adUnitCode) { - utils.logWarn('No adUnitCode supplied to addBidResponse, response discarded'); - return; + if (isValid()) { + prepareBidForAuction(); + + if (bid.mediaType === 'video') { + tryAddVideoBid(bid); + } else { + doCallbacksIfNeeded(); + addBidToAuction(bid); + } } - if (bid) { + // Actual method logic is above. Everything below is helper functions. + + // Validate the arguments sent to us by the adapter. If this returns false, the bid should be totally ignored. + function isValid() { + function errorMessage(msg) { + return `Invalid bid from ${bid.bidderCode}. Ignoring bid: ${msg}`; + } + + if (!adUnitCode) { + utils.logWarn(errorMessage('No adUnitCode was supplied to addBidResponse.')); + return false; + } if (bid.mediaType === 'native' && !nativeBidIsValid(bid)) { - utils.logError(`Native bid response does not contain all required assets. This bid won't be addeed to the auction`); - return; + utils.logError(errorMessage('Native bid missing some required properties.')); + return false; } + if (bid.mediaType === 'video' && !bid.vastUrl) { + utils.logError(errorMessage(`Video bid does not have required vastUrl property.`)); + return false; + } + return true; + } + // Postprocess the bids so that all the universal properties exist, no matter which bidder they came from. + // This should be called before addBidToAuction(). + function prepareBidForAuction() { const { requestId, start } = getBidderRequest(bid.bidderCode, adUnitCode); Object.assign(bid, { requestId: requestId, @@ -110,18 +137,6 @@ exports.addBidResponse = function (adUnitCode, bid) { bid.timeToRespond = bid.responseTimestamp - bid.requestTimestamp; - if (bid.timeToRespond > $$PREBID_GLOBAL$$.cbTimeout + $$PREBID_GLOBAL$$.timeoutBuffer) { - const timedOut = true; - - exports.executeCallback(timedOut); - } - - // emit the bidAdjustment event before bidResponse, so bid response has the adjusted bid value - events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, bid); - - // emit the bidResponse event - events.emit(CONSTANTS.EVENTS.BID_RESPONSE, bid); - // append price strings const priceStringsObj = getPriceBucketString(bid.cpm, _customPriceBucket); bid.pbLg = priceStringsObj.low; @@ -138,15 +153,44 @@ exports.addBidResponse = function (adUnitCode, bid) { } bid.adserverTargeting = keyValues; - $$PREBID_GLOBAL$$._bidsReceived.push(bid); } - if (bid && bid.adUnitCode && bidsBackAdUnit(bid.adUnitCode)) { - triggerAdUnitCallbacks(bid.adUnitCode); + function doCallbacksIfNeeded() { + if (bid.timeToRespond > $$PREBID_GLOBAL$$.cbTimeout + $$PREBID_GLOBAL$$.timeoutBuffer) { + const timedOut = true; + exports.executeCallback(timedOut); + } + } + + // Add a bid to the auction. + function addBidToAuction() { + // Make sure that the bidAdjustment event fires before bidResponse, so that the bid response + // has the adjusted bid value + events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, bid); + events.emit(CONSTANTS.EVENTS.BID_RESPONSE, bid); + + $$PREBID_GLOBAL$$._bidsReceived.push(bid); + + if (bid.adUnitCode && bidsBackAdUnit(bid.adUnitCode)) { + triggerAdUnitCallbacks(bid.adUnitCode); + } + + if (bidsBackAll()) { + exports.executeCallback(); + } } - if (bidsBackAll()) { - exports.executeCallback(); + // Video bids may fail if the cache is down, or there's trouble on the network. + function tryAddVideoBid(bid) { + store([bid], function(error, cacheIds) { + if (error) { + utils.logWarn(`Failed to save to the video cache: ${error}. Video bid must be discarded.`); + } else { + bid.videoCacheKey = cacheIds[0].uuid; + addBidToAuction(bid); + } + doCallbacksIfNeeded(); + }); } }; diff --git a/src/prebid.js b/src/prebid.js index e211c447a1b..1de2cee60dc 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -657,6 +657,11 @@ $$PREBID_GLOBAL$$.getAllWinningBids = function () { * Build master video tag from publishers adserver tag * @param {string} adserverTag default url * @param {object} options options for video tag + * + * @deprecated Include the dfpVideoSupport module in your build, and use the + * $$PREBID_GLOBAL$$.adserver.buildVideoAdUrl (if DFP is your only Ad Server) or + * $$PREBID_GLOBAL$$.adservers.dfp.buildVideoAdUrl (if you use other Ad Servers too) + * function instead. This function will be removed in Prebid 1.0. */ $$PREBID_GLOBAL$$.buildMasterVideoTagFromAdserverTag = function (adserverTag, options) { utils.logInfo('Invoking $$PREBID_GLOBAL$$.buildMasterVideoTagFromAdserverTag', arguments); diff --git a/src/utils.js b/src/utils.js index ba608a1f1b7..4963adb1ae8 100644 --- a/src/utils.js +++ b/src/utils.js @@ -112,7 +112,7 @@ exports.transformAdServerTargetingObj = function (targeting) { * @param {array[array|number]} sizeObj Input array or double array [300,250] or [[300,250], [728,90]] * @return {array[string]} Array of strings like `["300x250"]` or `["300x250", "728x90"]` */ -exports.parseSizesInput = function (sizeObj) { +export function parseSizesInput(sizeObj) { var parsedSizes = []; // if a string for now we can assume it is a single size, like "300x250" @@ -137,11 +137,11 @@ exports.parseSizesInput = function (sizeObj) { if (sizeArrayLength > 0) { // if we are a 2 item array of 2 numbers, we must be a SingleSize array if (sizeArrayLength === 2 && typeof sizeObj[0] === objectType_number && typeof sizeObj[1] === objectType_number) { - parsedSizes.push(this.parseGPTSingleSizeArray(sizeObj)); + parsedSizes.push(parseGPTSingleSizeArray(sizeObj)); } else { // otherwise, we must be a MultiSize array for (var i = 0; i < sizeArrayLength; i++) { - parsedSizes.push(this.parseGPTSingleSizeArray(sizeObj[i])); + parsedSizes.push(parseGPTSingleSizeArray(sizeObj[i])); } } } @@ -152,9 +152,9 @@ exports.parseSizesInput = function (sizeObj) { // parse a GPT style sigle size array, (i.e [300,250]) // into an AppNexus style string, (i.e. 300x250) -exports.parseGPTSingleSizeArray = function (singleSize) { +export function parseGPTSingleSizeArray(singleSize) { // if we aren't exactly 2 items in this array, it is invalid - if (this.isArray(singleSize) && singleSize.length === 2 && (!isNaN(singleSize[0]) && !isNaN(singleSize[1]))) { + if (exports.isArray(singleSize) && singleSize.length === 2 && (!isNaN(singleSize[0]) && !isNaN(singleSize[1]))) { return singleSize[0] + 'x' + singleSize[1]; } }; diff --git a/src/videoCache.js b/src/videoCache.js new file mode 100644 index 00000000000..a3b7f66e4fe --- /dev/null +++ b/src/videoCache.js @@ -0,0 +1,114 @@ +/** + * This module interacts with the server used to cache video ad content to be restored later. + * At a high level, the expected workflow goes like this: + * + * - Request video ads from Bidders + * - Generate IDs for each valid bid, and cache the key/value pair on the server. + * - Return these IDs so that publishers can use them to fetch the bids later. + * + * This trickery helps integrate with ad servers, which set character limits on request params. + */ + +import { ajax } from './ajax'; + +const PUT_URL = 'https://prebid.adnxs.com/pbc/v1/cache' + +/** + * These are the properties required on a Bid in order to cache and retrieve it. + * + * @typedef {object} CacheableBid + * @property {string} vastUrl A URL which loads some valid VAST XML. + */ + +/** + * Function which wraps a URI that serves VAST XML, so that it can be loaded. + * + * @param {string} uri The URI where the VAST content can be found. + * @return A VAST URL which loads XML from the given URI. + */ +function wrapURI(uri) { + // Technically, this is vulnerable to cross-script injection by sketchy vastUrl bids. + // We could make sure it's a valid URI... but since we're loading VAST XML from the + // URL they provide anyway, that's probably not a big deal. + return ` + + + prebid.org wrapper + + + + + + `; +} + +/** + * Wraps a bid in the format expected by the prebid-server endpoints, or returns null if + * the bid can't be converted cleanly. + * + * @param {CacheableBid} bid + */ +function toStorageRequest(bid) { + return { + type: 'xml', + value: wrapURI(bid.vastUrl) + }; +} + + +/** + * A function which should be called with the results of the storage operation. + * + * @callback videoCacheStoreCallback + * + * @param {Error} [error] The error, if one occurred. + * @param {?string[]} uuids An array of unique IDs. The array will have one element for each bid we were asked + * to store. It may include null elements if some of the bids were malformed, or an error occurred. + * Each non-null element in this array is a valid input into the retrieve function, which will fetch + * some VAST XML which can be used to render this bid's ad. + */ + +/** + * A function which bridges the APIs between the videoCacheStoreCallback and our ajax function's API. + * + * @param {videoCacheStoreCallback} done A callback to the "store" function. + * @return {Function} A callback which interprets the cache server's responses, and makes up the right + * arguments for our callback. + */ +function shimStorageCallback(done) { + return { + success: function(responseBody) { + let ids; + try { + ids = JSON.parse(responseBody).responses + } + catch (e) { + done(e, []); + return; + } + + done(null, ids); + }, + error: function(statusText, responseBody) { + done(new Error(`Error storing video ad in the cache: ${statusText}: ${JSON.stringify(responseBody)}`), []); + } + } +} + +/** + * If the given bid is for a Video ad, generate a unique ID and cache it somewhere server-side. + * + * @param {CacheableBid[]} bids A list of bid objects which should be cached. + * @param {videoCacheStoreCallback} [done] An optional callback which should be executed after + * the data has been stored in the cache. + */ +export function store(bids, done) { + const requestData = { + puts: bids.map(toStorageRequest) + }; + + ajax(PUT_URL, shimStorageCallback(done), JSON.stringify(requestData), { + contentType: 'text/plain', + withCredentials: true + }); +} diff --git a/test/fixtures/video/adUnit.json b/test/fixtures/video/adUnit.json new file mode 100644 index 00000000000..6d2b7c385ad --- /dev/null +++ b/test/fixtures/video/adUnit.json @@ -0,0 +1,17 @@ +{ + "code": "video1", + "sizes": [640,480], + "mediaType": "video", + "bids": [ + { + "bidder": "appnexusAst", + "params": { + "placementId": "9333431", + "video": { + "skipppable": false, + "playback_methods": ["auto_play_sound_off"] + } + } + } + ] +} diff --git a/test/fixtures/video/bidRequest.json b/test/fixtures/video/bidRequest.json new file mode 100644 index 00000000000..75f054611c4 --- /dev/null +++ b/test/fixtures/video/bidRequest.json @@ -0,0 +1,26 @@ +{ + "auctionStart": 1462918897459, + "bidderCode": "appnexusAst", + "bidderRequestId": "2946b569352ef2", + "bids": [ + { + "bidder": "appnexusAst", + "params": { + "placementId": "9333431", + "video": { + "skipppable": false, + "playback_methods": ["auto_play_sound_off"] + } + }, + "placementCode": "video1", + "sizes": [640,480], + "bidId": "392b5a6b05d648", + "bidderRequestId": "2946b569352ef2", + "requestId": "6172477f-987f-4523-a967-fa6d7a434ddf", + "startTime": 1462918897462 + } + ], + "requestId": "6172477f-987f-4523-a967-fa6d7a434ddf", + "start": 1462918897460, + "timeout": 5000 +} diff --git a/test/fixtures/video/bidResponse.json b/test/fixtures/video/bidResponse.json new file mode 100644 index 00000000000..cba0798251d --- /dev/null +++ b/test/fixtures/video/bidResponse.json @@ -0,0 +1,13 @@ +{ + "adUnitCode": "video1", + "bidder": "appnexusAst", + "bidderCode": "appnexusAst", + "code": "appnexusAst", + "dealId": "foo", + "cpm": 0.1, + "height": 480, + "mediaType": "video", + "requestId": "6172477f-987f-4523-a967-fa6d7a434ddf", + "vastUrl": "www.myVastUrl.com", + "width": 640 +} diff --git a/test/mocks/videoCacheStub.js b/test/mocks/videoCacheStub.js new file mode 100644 index 00000000000..4a1d8bca343 --- /dev/null +++ b/test/mocks/videoCacheStub.js @@ -0,0 +1,34 @@ +import * as videoCache from 'src/videoCache'; + +/** + * Function which can be called from unit tests to stub out the video cache. + * + * @param {Object} responses + * @param {} responses.store If this is an Error, we'll stub out the store function so that it fails. + * If it's anything else, the store function will succeed, sending that value into the callback. + * + * @return {function} A function which returns the current stubs for the mocked functions. + */ +export default function useVideoCacheStub(responses) { + let storeStub; + + beforeEach(() => { + storeStub = sinon.stub(videoCache, 'store'); + + if (responses.store instanceof Error) { + storeStub.callsArgWith(1, responses.store); + } else { + storeStub.callsArgWith(1, null, responses.store); + } + }); + + afterEach(() => { + videoCache.store.restore(); + }); + + return function() { + return { + store: storeStub + }; + } +} diff --git a/test/pages/video.html b/test/pages/video.html new file mode 100644 index 00000000000..755815111d1 --- /dev/null +++ b/test/pages/video.html @@ -0,0 +1,134 @@ + + + + + + Prebid.js video adUnit example + + + + + + + + + + + + + + + + + + +

Prebid Video -- video.js

+ +
+ + +
+ + + + diff --git a/test/spec/modules/dfpAdServerVideo_spec.js b/test/spec/modules/dfpAdServerVideo_spec.js new file mode 100644 index 00000000000..81c83baa65c --- /dev/null +++ b/test/spec/modules/dfpAdServerVideo_spec.js @@ -0,0 +1,94 @@ +import { expect } from 'chai'; + +import parse from 'url-parse'; +import buildDfpVideoUrl from 'modules/dfpAdServerVideo'; +import { parseQS } from 'src/url'; +import adUnit from 'test/fixtures/video/adUnit'; + +const bid = { + videoCacheKey: 'abc', + adserverTargeting: { }, +}; + +describe('The DFP video support module', () => { + it('should make a legal request URL when given the required params', () => { + const url = parse(buildDfpVideoUrl({ + adUnit: adUnit, + bid: bid, + params: { + 'iu': 'my/adUnit', + 'description_url': 'someUrl.com', + } + })); + + expect(url.protocol).to.equal('https:'); + expect(url.host).to.equal('pubads.g.doubleclick.net'); + + const queryParams = parseQS(url.query); + expect(queryParams).to.have.property('correlator'); + expect(queryParams).to.have.property('description_url', 'someUrl.com'); + expect(queryParams).to.have.property('env', 'vp'); + expect(queryParams).to.have.property('gdfp_req', '1'); + expect(queryParams).to.have.property('iu', 'my/adUnit'); + expect(queryParams).to.have.property('output', 'xml_vast3'); + expect(queryParams).to.have.property('sz', '640x480'); + expect(queryParams).to.have.property('unviewed_position_start', '1'); + expect(queryParams).to.have.property('url'); + }); + + it('should override param defaults with user-provided ones', () => { + const url = parse(buildDfpVideoUrl({ + adUnit: adUnit, + bid: bid, + params: { + 'iu': 'my/adUnit', + 'output': 'vast', + } + })); + + expect(parseQS(url.query)).to.have.property('output', 'vast'); + }); + + it('should include the cache key and adserver targeting in cust_params', () => { + const bidCopy = Object.assign({ }, bid); + bidCopy.adserverTargeting = { + hb_adid: 'ad_id', + }; + + const url = parse(buildDfpVideoUrl({ + adUnit: adUnit, + bid: bidCopy, + params: { + 'iu': 'my/adUnit' + } + })); + const queryObject = parseQS(url.query); + const customParams = parseQS('?' + decodeURIComponent(queryObject.cust_params)); + + expect(customParams).to.have.property('hb_adid', 'ad_id'); + expect(customParams).to.have.property('hb_uuid', bid.videoCacheKey); + }); + + it('should merge the user-provided cust_params with the default ones', () => { + const bidCopy = Object.assign({ }, bid); + bidCopy.adserverTargeting = { + hb_adid: 'ad_id', + }; + + const url = parse(buildDfpVideoUrl({ + adUnit: adUnit, + bid: bidCopy, + params: { + 'iu': 'my/adUnit', + cust_params: { + 'my_targeting': 'foo', + }, + }, + })); + const queryObject = parseQS(url.query); + const customParams = parseQS('?' + decodeURIComponent(queryObject.cust_params)); + + expect(customParams).to.have.property('hb_adid', 'ad_id'); + expect(customParams).to.have.property('my_targeting', 'foo'); + }); +}); diff --git a/test/spec/unit/adServerManager_spec.js b/test/spec/unit/adServerManager_spec.js new file mode 100644 index 00000000000..72a3b61ce41 --- /dev/null +++ b/test/spec/unit/adServerManager_spec.js @@ -0,0 +1,30 @@ +import { expect } from 'chai'; +import { getGlobal } from 'src/prebidGlobal'; +import { registerVideoSupport } from 'src/adServerManager'; + +const prebid = getGlobal(); + +describe('The ad server manager', () => { + beforeEach(() => { + delete prebid.adServers; + }); + + it('should register video support to the proper place on the API', () => { + function videoSupport() { } + registerVideoSupport('dfp', { buildVideoUrl: videoSupport }); + + expect(prebid).to.have.property('adServers'); + expect(prebid.adServers).to.have.property('dfp'); + expect(prebid.adServers.dfp).to.have.property('buildVideoUrl', videoSupport); + }); + + it('should keep the first function when we try to add a second', () => { + function videoSupport() { } + registerVideoSupport('dfp', { buildVideoUrl: videoSupport }); + registerVideoSupport('dfp', { buildVideoUrl: function noop() { } }); + + expect(prebid).to.have.property('adServers'); + expect(prebid.adServers).to.have.property('dfp'); + expect(prebid.adServers.dfp).to.have.property('buildVideoUrl', videoSupport); + }); +}); diff --git a/test/spec/unit/bidmanager_spec.js b/test/spec/unit/bidmanager_spec.js new file mode 100644 index 00000000000..f7e12555378 --- /dev/null +++ b/test/spec/unit/bidmanager_spec.js @@ -0,0 +1,154 @@ +import { expect } from 'chai'; +import * as bidManager from 'src/bidmanager'; +import useVideoCacheStubs from 'test/mocks/videoCacheStub'; +import adUnit from 'test/fixtures/video/adUnit'; +import bidRequest from 'test/fixtures/video/bidRequest'; +import bidResponse from 'test/fixtures/video/bidResponse'; + +describe('The Bid Manager', () => { + before(() => { + $$PREBID_GLOBAL$$.cbTimeout = 5000; + $$PREBID_GLOBAL$$.timeoutBuffer = 50; + }); + + describe('addBidResponse() function,', () => { + /** + * Add the bidResponse fixture as a bid into the auction, and run some assertions + * to verify: + * + * 1. Whether or not that bid got added. + * 2. Whether or not the "end of auction" callbacks got called. + */ + function testAddVideoBid(expectBidAdded, expectCallbackCalled, videoCacheStubProvider) { + return function() { + const mockResponse = Object.assign({}, bidResponse); + const callback = sinon.spy(); + bidManager.addOneTimeCallback(callback); + + mockResponse.getSize = function() { + return `${this.height}x${this.width}`; + }; + bidManager.addBidResponse(adUnit.code, mockResponse); + + const expectedBidsReceived = expectBidAdded ? 1 : 0; + expect($$PREBID_GLOBAL$$._bidsReceived.length).to.equal(expectedBidsReceived); + + const storeStub = videoCacheStubProvider().store; + expect(storeStub.calledOnce).to.equal(true); + expect(storeStub.getCall(0).args[0][0]).to.equal(mockResponse); + + if (expectedBidsReceived === 1) { + const bid = $$PREBID_GLOBAL$$._bidsReceived[0]; + expect(bid.vastUrl).to.equal('www.myVastUrl.com'); + expect(bid.videoCacheKey).to.equal('FAKE_UUID'); + } + if (expectCallbackCalled) { + expect(callback.calledOnce).to.equal(true); + } else { + expect(callback.called).to.equal(false); + } + }; + } + + /** + * Initialize the global state so that the auction-space looks like we want it to. + * + * @param {Array} adUnits The array of ad units which should appear in this auction. + * @param {function} bidRequestTweaker A function which accepts a basic bidRequest, and + * transforms it to prepare it for auction. + */ + function prepAuction(adUnits, bidRequestTweaker) { + beforeEach(() => { + let thisBidRequest = bidRequest; + if (bidRequestTweaker) { + thisBidRequest = JSON.parse(JSON.stringify(bidRequest)); + bidRequestTweaker(thisBidRequest); + } + + $$PREBID_GLOBAL$$.adUnits = adUnits; + $$PREBID_GLOBAL$$._bidsRequested = [thisBidRequest]; + $$PREBID_GLOBAL$$._bidsReceived = []; + $$PREBID_GLOBAL$$._adUnitCodes = $$PREBID_GLOBAL$$.adUnits.map(unit => unit.code); + }); + } + + function auctionStart(timedOut) { + return timedOut + ? new Date().getTime() - $$PREBID_GLOBAL$$.cbTimeout - $$PREBID_GLOBAL$$.timeoutBuffer - 1 + : new Date().getTime(); + } + + describe('when the cache is functioning properly', () => { + let stubProvider = useVideoCacheStubs({ + store: [{ uuid: 'FAKE_UUID' }], + }); + + describe('when more bids are expected after this one', () => { + // Set up the global state so that we expect two bids, and the auction started just now + // (so as to reduce the chance of timeout. This assumes that the unit test runs run in < 5000 ms). + prepAuction( + [adUnit, Object.assign({}, adUnit, { code: 'video2' })], + (bidRequest) => { + const tweakedBidRequestBid = Object.assign({}, bidRequest.bids[0], { placementCode: 'video2' }); + bidRequest.bids.push(tweakedBidRequestBid); + bidRequest.start = auctionStart(false); + }); + + it("should add video bids, but shouldn't call the end-of-auction callbacks yet", + testAddVideoBid(true, false, stubProvider)); + }); + + describe('when this is the last bid expected in the auction', () => { + // Set up the global state so that we expect only one bid, and the auction started just now + // (so as to reduce the chance of timeout. This assumes that the unit test runs run in < 5000 ms). + prepAuction([adUnit], (bidRequest) => bidRequest.start = auctionStart(false)); + + it("shouldn't add invalid bids", () => { + bidManager.addBidResponse('', { }); + bidManager.addBidResponse('testCode', { mediaType: 'video' }); + bidManager.addBidResponse('testCode', { mediaType: 'native' }); + expect($$PREBID_GLOBAL$$._bidsReceived.length).to.equal(0); + }); + + it('should add valid video bids and then execute the callbacks signaling the end of the auction', + testAddVideoBid(true, true, stubProvider)); + }); + + describe('when the auction has timed out', () => { + // Set up the global state to expect two bids, and mock an auction which happened long enough + // in the past that it will *seem* like this bid is arriving after the timeouts. + prepAuction( + [adUnit, Object.assign({}, adUnit, { code: 'video2' })], + (bidRequest) => { + const tweakedBidRequestBid = Object.assign({}, bidRequest.bids[0], { placementCode: 'video2' }); + bidRequest.bids.push(tweakedBidRequestBid); + bidRequest.start = auctionStart(true); + }); + + // Because of the preconditions, this makes sure that the end-of-auction callbacks get called when + // the auction hits the timeout. + it('should add the bid, but also execute the callbacks signaling the end of the auction', + testAddVideoBid(true, true, stubProvider)); + }); + }); + + describe('when the cache is failing for some reason,', () => { + let stubProvider = useVideoCacheStubs({ + store: new Error('Unable to save to the cache'), + }); + + describe('when the auction still has time left', () => { + prepAuction([adUnit], (bidRequest) => bidRequest.start = auctionStart(false)); + + it("shouldn't add the bid to the auction, and shouldn't execute the end-of-auction callbacks", + testAddVideoBid(false, false, stubProvider)); + }); + + describe('when the auction has timed out', () => { + prepAuction([adUnit], (bidRequest) => bidRequest.start = auctionStart(true)); + it("shouldn't add the bid to the auction, but should execute the end-of-auction callbacks", + testAddVideoBid(false, true, stubProvider)); + }) + }); + }); +}); diff --git a/test/spec/videoCache_spec.js b/test/spec/videoCache_spec.js new file mode 100644 index 00000000000..935841d2208 --- /dev/null +++ b/test/spec/videoCache_spec.js @@ -0,0 +1,94 @@ +import 'mocha'; +import chai from 'chai'; +import { store } from 'src/videoCache'; + +const should = chai.should(); + +describe('The video cache', () => { + function assertError(callbackSpy) { + callbackSpy.calledOnce.should.equal(true); + callbackSpy.firstCall.args[0].should.be.an('error'); + } + + function assertSuccess(callbackSpy) { + callbackSpy.calledOnce.should.equal(true); + should.not.exist(callbackSpy.firstCall.args[0]); + } + + describe('when the cache server is unreachable', () => { + let xhr; + let requests; + + beforeEach(() => { + xhr = sinon.useFakeXMLHttpRequest(); + requests = []; + xhr.onCreate = (request) => requests.push(request); + }); + + afterEach(() => xhr.restore()); + + it('should execute the callback with an error when store() is called', () => { + const callback = sinon.spy(); + store([ { vastUrl: 'my-mock-url.com' } ], callback); + + requests[0].respond(503, { + 'Content-Type': 'plain/text', + }, 'The server could not save anything at the moment.'); + + assertError(callback); + callback.firstCall.args[1].should.deep.equal([]); + }); + }); + + describe('when the cache server is available', () => { + let xhr; + let requests; + + beforeEach(() => { + xhr = sinon.useFakeXMLHttpRequest(); + requests = []; + xhr.onCreate = (request) => requests.push(request); + }); + + afterEach(() => xhr.restore()); + + it('should make the expected request when store() is called', () => { + store([ { vastUrl: 'my-mock-url.com' } ], function() { }); + + const request = requests[0]; + request.method.should.equal('POST'); + request.url.should.equal('https://prebid.adnxs.com/pbc/v1/cache'); + request.requestHeaders['Content-Type'].should.equal('text/plain;charset=utf-8'); + + JSON.parse(request.requestBody).should.deep.equal({ + puts: [{ + type: 'xml', + value: ` + + + prebid.org wrapper + + + + + + `, + }], + }); + }); + + it('should execute the callback with a successful result when store() is called', () => { + const callback = sinon.spy(); + store([ { vastUrl: 'my-mock-url.com' } ], callback); + requests[0].respond( + 200, + { + 'Content-Type': 'application/json', + }, + '{"responses":[{"uuid":"c488b101-af3e-4a99-b538-00423e5a3371"}]}'); + + assertSuccess(callback); + callback.firstCall.args[1].should.deep.equal([{ uuid: 'c488b101-af3e-4a99-b538-00423e5a3371' }]); + }); + }); +}); From 0e72b548d30984da9e505a634d3b7b5cab17c3ab Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Tue, 11 Jul 2017 15:48:49 -0400 Subject: [PATCH 56/95] postbid setup files (#1189) * posted setup files * moved conf object * Code refactor * updated adunitcode value * Added IIFE and version * Renamed file * Update postbid html path * removed ES6 syntax * Updated code with friendly iframe postbid.js and added new oas creative * Update postbid.js path * Added gulp task to build postbid --- gulpfile.js | 6 + integrationExamples/postbid/oas/creative.html | 69 ++++++++++ integrationExamples/postbid/oas/postbid.js | 118 ++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 integrationExamples/postbid/oas/creative.html create mode 100644 integrationExamples/postbid/oas/postbid.js diff --git a/gulpfile.js b/gulpfile.js index d0da499048a..cc0a49e1cfd 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -287,3 +287,9 @@ gulp.task('e2etest-report', function() { }, 5000); }); + +gulp.task('build-postbid', function() { + return gulp.src('./integrationExamples/postbid/oas/postbid.js') + .pipe(uglify()) + .pipe(gulp.dest('build/dist')); +}); diff --git a/integrationExamples/postbid/oas/creative.html b/integrationExamples/postbid/oas/creative.html new file mode 100644 index 00000000000..76b16b0fa57 --- /dev/null +++ b/integrationExamples/postbid/oas/creative.html @@ -0,0 +1,69 @@ + +
+ diff --git a/integrationExamples/postbid/oas/postbid.js b/integrationExamples/postbid/oas/postbid.js new file mode 100644 index 00000000000..a4aeb588b26 --- /dev/null +++ b/integrationExamples/postbid/oas/postbid.js @@ -0,0 +1,118 @@ +(function(window){ + var postbid = {}; + postbid.que = []; + + var processQue = function(conf) { + for (var i = 0; i < postbid.que.length; i++) { + if (typeof postbid.que[i].called === 'undefined') { + try { + postbid.que[i].call(null, conf); + postbid.que[i].called = true; + } + catch (e) { + + } + } + } + } + + function getIframeContentDoc(iframe) { + var doc; + try { + if (iframe.contentWindow) { + doc = iframe.contentWindow.document; + } else if (iframe.contentDocument.document) { + doc = iframe.contentDocument.document; + } else { + doc = iframe.contentDocument; + } + } catch (e) { + } + return doc; + } + + function createIframe(id) { + var iframe = document.createElement('iframe'); + iframe.id = id; + iframe.width = '100%'; + iframe.height = '100%'; + iframe.frameBorder = "0"; + iframe.marginWidth = "0"; + iframe.marginHeight = "0"; + iframe.scrolling = "no"; + iframe.setAttribute('border', '0'); + iframe.setAttribute('allowtransparency', "true"); + + return iframe; + } + + function loadIframe(iframe, content) { + var iframeDoc = getIframeContentDoc(iframe); + iframeDoc.open('text/html', 'replace'); + iframeDoc.write(content); + iframeDoc.close(); + } + + function loadIeIframe(iframe, content) { + iframe.contentWindow.contents = content; + var base = document.getElementsByTagName('base'); + if(base.length) base[0].target = '_self'; + iframe.src = 'javascript:window["contents"];'; + if(base.length) base[0].target = '_blank'; + } + + function getBrowserType() { + var ua = navigator.userAgent.toLowerCase(); + + var match = /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + /(trident)(\/\d.0);/.exec(ua) || + (/trident\/7.0;/.test(ua)) ? ['msie'] : false || + ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; + + return match[1]; + } + + if (!Array.prototype.find) { + Object.defineProperty(Array.prototype, 'find', { + value: function(predicate) { + if (this == null) { + throw new TypeError('"this" is null or not defined'); + } + var o = Object(this); + var len = o.length >>> 0; + if (typeof predicate !== 'function') { + throw new TypeError('predicate must be a function'); + } + var thisArg = arguments[1]; + var k = 0; + while (k < len) { + var kValue = o[k]; + if (predicate.call(thisArg, kValue, k, o)) { + return kValue; + } + k++; + } + return undefined; + } + }); + } + + postbid.que.push(function(conf) { + var content = "\n + + + + + + + + + + + + + + +

Prebid.js Test

+
Div-1
+ + +
+ +
+ + + diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js new file mode 100644 index 00000000000..245c9592ded --- /dev/null +++ b/modules/ucfunnelBidAdapter.js @@ -0,0 +1,98 @@ +import * as Adapter from 'src/adapter.js'; +import bidfactory from 'src/bidfactory'; +import bidmanager from 'src/bidmanager'; +import * as utils from 'src/utils'; +import {ajax} from 'src/ajax'; +import {STATUS} from 'src/constants'; +import adaptermanager from 'src/adaptermanager'; + +const VER = 'ADGENT_PREBID-2017051801'; +const UCFUNNEL_BIDDER_CODE = 'ucfunnel'; + +function ucfunnelAdapter() { + function _callBids(params) { + let bids = params.bids || []; + + bids.forEach((bid) => { + try { + ajax(buildOptimizedCall(bid), bidCallback, undefined, { withCredentials: true }); + } catch (err) { + utils.logError('Error sending ucfunnel request for placement code ' + bid.placementCode, null, err); + } + + function bidCallback(responseText) { + try { + utils.logMessage('XHR callback function called for placement code: ' + bid.placementCode); + handleRpCB(responseText, bid); + } catch (err) { + if (typeof err === 'string') { + utils.logWarn(`${err} when processing ucfunnel response for placement code ${bid.placementCode}`); + } else { + utils.logError('Error processing ucfunnel response for placement code ' + bid.placementCode, null, err); + } + + // indicate that there is no bid for this placement + let badBid = bidfactory.createBid(STATUS.NO_BID, bid); + badBid.bidderCode = bid.bidder; + badBid.error = err; + bidmanager.addBidResponse(bid.placementCode, badBid); + } + } + }); + } + + function buildOptimizedCall(bid) { + bid.startTime = new Date().getTime(); + + let host = utils.getTopWindowLocation().host, + page = utils.getTopWindowLocation().pathname, + refer = document.referrer, + language = navigator.language, + dnt = (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0; + + let queryString = [ + 'ifr', 0, + 'bl', language, + 'je', 1, + 'dnt', dnt, + 'host', host, + 'u', page, + 'ru', refer, + 'adid', bid.params.adid, + 'w', bid.params.width, + 'h', bid.params.height, + 'ver', VER + ]; + + return queryString.reduce( + (memo, curr, index) => + index % 2 === 0 && queryString[index + 1] !== undefined + ? memo + curr + '=' + encodeURIComponent(queryString[index + 1]) + '&' + : memo, + '//agent.aralego.com/header?' + ).slice(0, -1); + } + + function handleRpCB(responseText, bidRequest) { + let ad = JSON.parse(responseText); // can throw + + let bid = bidfactory.createBid(STATUS.GOOD, bidRequest); + bid.creative_id = ad.ad_id; + bid.bidderCode = UCFUNNEL_BIDDER_CODE; + bid.cpm = ad.cpm || 0; + bid.ad = ad.adm; + bid.width = ad.width; + bid.height = ad.height; + bid.dealId = ad.deal; + + bidmanager.addBidResponse(bidRequest.placementCode, bid); + } + + return { + callBids: _callBids + }; +}; + +adaptermanager.registerBidAdapter(new ucfunnelAdapter, UCFUNNEL_BIDDER_CODE); + +module.exports = ucfunnelAdapter; diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js new file mode 100644 index 00000000000..7700b30e8e3 --- /dev/null +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -0,0 +1,110 @@ +import { expect } from 'chai'; +import Adapter from 'modules/ucfunnelBidAdapter'; +import adapterManager from 'src/adaptermanager'; +import bidManager from 'src/bidmanager'; +import CONSTANTS from 'src/constants.json'; + +describe('ucfunnel adapter tests', function () { + let sandbox; + const adUnit = { // TODO CHANGE + code: 'ucfunnel', + sizes: [[300, 250]], + bids: [{ + bidder: 'ucfunnel', + params: { + adid: 'test-ad-83444226E44368D1E32E49EEBE6D29', + width: 300, + height: 250 + } + }] + }; + + const response = { + ad_id: 'ad-83444226E44368D1E32E49EEBE6D29', + adm: '
', + cpm: 0.01, + height: 250, + width: 300 + }; + + beforeEach(() => { + sandbox = sinon.sandbox.create(); + }); + + afterEach(() => { + sandbox.restore(); + }); + + describe('ucfunnel callBids validation', () => { + let bids, + server; + + beforeEach(() => { + bids = []; + server = sinon.fakeServer.create(); + + sandbox.stub(bidManager, 'addBidResponse', (elemId, bid) => { + bids.push(bid); + }); + }); + + afterEach(() => { + server.restore(); + }); + + let adapter = adapterManager.bidderRegistry['ucfunnel']; + + it('Valid bid-request', () => { + sandbox.stub(adapter, 'callBids'); + adapterManager.callBids({ + adUnits: [clone(adUnit)] + }); + + let bidderRequest = adapter.callBids.getCall(0).args[0]; + + expect(bidderRequest).to.have.property('bids') + .that.is.an('array') + .with.lengthOf(1); + + expect(bidderRequest).to.have.deep.property('bids[0]') + .to.have.property('bidder', 'ucfunnel'); + + expect(bidderRequest).to.have.deep.property('bids[0]') + .with.property('sizes') + .that.is.an('array') + .with.lengthOf(1) + .that.deep.equals(adUnit.sizes); + expect(bidderRequest).to.have.deep.property('bids[0]') + .with.property('params') + .to.have.property('adid', 'test-ad-83444226E44368D1E32E49EEBE6D29'); + expect(bidderRequest).to.have.deep.property('bids[0]') + .with.property('params') + .to.have.property('width', 300); + }); + + it('Valid bid-response', () => { + server.respondWith(JSON.stringify( + response + )); + adapterManager.callBids({ + adUnits: [clone(adUnit)] + }); + server.respond(); + + expect(bids).to.be.lengthOf(1); + expect(bids[0].getStatusCode()).to.equal(CONSTANTS.STATUS.GOOD); + expect(bids[0].bidderCode).to.equal('ucfunnel'); + expect(bids[0].width).to.equal(300); + expect(bids[0].height).to.equal(250); + expect(bids[0].cpm).to.equal(0.01); + }); + }); +}); + +function clone(obj) { + try { + return JSON.parse(JSON.stringify(obj)); + } catch (e) { + return {}; + } +} From 356b0493f632ae459ed8f1e1754e09b93cca2c8c Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Tue, 11 Jul 2017 16:17:59 -0400 Subject: [PATCH 58/95] Fixing unit tests - added stubs for external server calls (#1362) --- test/spec/modules/spotxBidAdapter_spec.js | 109 +++++++++++++++------- 1 file changed, 75 insertions(+), 34 deletions(-) diff --git a/test/spec/modules/spotxBidAdapter_spec.js b/test/spec/modules/spotxBidAdapter_spec.js index b8974def619..e78e4c7c6ee 100644 --- a/test/spec/modules/spotxBidAdapter_spec.js +++ b/test/spec/modules/spotxBidAdapter_spec.js @@ -139,48 +139,89 @@ describe('spotx adapter tests', () => { adLoader.loadScript.restore(); }); - it('should add bid response on success', (done) => { - sinon.stub(bidManager, 'addBidResponse', (placementCode, bid) => { - expect(placementCode).to.equal('video1'); - expect(bid.bidderCode).to.equal('spotx'); - expect(bid.cpm).to.equal(20); - expect(bid.mediaType).to.equal('video'); - expect(bid.statusMessage).to.equal('Bid available'); - expect(bid.vastUrl).to.equal('//search.spotxchange.com/ad/vast.html?key=' + CACHE_KEY); - - bidManager.addBidResponse.restore(); - done(); + describe('bid response tests', () => { + let loadScriptStub; + let getAdServerKVPsStub; + + before(() => { + let response = { + spotx_bid: 20, + spotx_ad_key: CACHE_KEY + }; + + getAdServerKVPsStub = sinon.stub(); + getAdServerKVPsStub.onCall(0).returns({ + then: function (successCb) { + return successCb(response); + } + }); + + getAdServerKVPsStub.onCall(1).returns({ + then: function (successCb, failureCb) { + return failureCb(); + } + }); + + window.SpotX = { + DirectAdOS: function(options) { + return { + getAdServerKVPs: getAdServerKVPsStub + } + } + }; + + loadScriptStub = sinon.stub(adLoader, 'loadScript', function(url, callback) { + callback(); + }); }); - server.respondWith((request) => { - if (request.url.match(/openrtb\/2.3\/dados/) && request.method === 'POST') { - request.respond(200, {}, xhrResponse); - } + after(() => { + loadScriptStub.restore(); }); - adapter.callBids(bidRequest); - }); + it('should add bid response on success', (done) => { + sinon.stub(bidManager, 'addBidResponse', (placementCode, bid) => { + expect(placementCode).to.equal('video1'); + expect(bid.bidderCode).to.equal('spotx'); + expect(bid.cpm).to.equal(20); + expect(bid.mediaType).to.equal('video'); + expect(bid.statusMessage).to.equal('Bid available'); + expect(bid.vastUrl).to.equal('//search.spotxchange.com/ad/vast.html?key=' + CACHE_KEY); + + bidManager.addBidResponse.restore(); + done(); + }); + + server.respondWith((request) => { + if (request.url.match(/openrtb\/2.3\/dados/) && request.method === 'POST') { + request.respond(200, {}, xhrResponse); + } + }); - it('should add failed bid response on error', (done) => { - sinon.stub(bidManager, 'addBidResponse', (placementCode, bid) => { - expect(placementCode).to.equal('video1'); - expect(bid.bidderCode).to.equal('spotx'); - expect(bid.statusMessage).to.equal('Bid returned empty or error response'); - expect(bid.cpm).to.be.undefined; - expect(bid.mediaType).to.be.undefined; - expect(bid.vastUrl).to.be.undefined; - - bidManager.addBidResponse.restore(); - done(); + adapter.callBids(bidRequest); }); - server.respondWith((request) => { - if (request.url.match(/openrtb\/2.3\/dados/) && request.method === 'POST') { - request.respond(204, {}, ''); - } - }); + it('should add failed bid response on error', (done) => { + sinon.stub(bidManager, 'addBidResponse', (placementCode, bid) => { + expect(placementCode).to.equal('video1'); + expect(bid.bidderCode).to.equal('spotx'); + expect(bid.statusMessage).to.equal('Bid returned empty or error response'); + expect(bid.cpm).to.be.undefined; + expect(bid.mediaType).to.be.undefined; + expect(bid.vastUrl).to.be.undefined; + + bidManager.addBidResponse.restore(); + done(); + }); + + server.respondWith((request) => { + if (request.url.match(/openrtb\/2.3\/dados/) && request.method === 'POST') { + request.respond(204, {}, ''); + } + }); - adapter.callBids(bidRequest); + adapter.callBids(bidRequest); + }); }); }); }); From 3b8b29d237eb4ffa33b1e8458e7539a38eccf948 Mon Sep 17 00:00:00 2001 From: Matt Lane Date: Tue, 11 Jul 2017 13:29:08 -0700 Subject: [PATCH 59/95] Fix spacing for lint rules (#1366) --- test/spec/modules/ucfunnelBidAdapter_spec.js | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js index 7700b30e8e3..d8ddfc041b6 100644 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -63,23 +63,23 @@ describe('ucfunnel adapter tests', function () { let bidderRequest = adapter.callBids.getCall(0).args[0]; expect(bidderRequest).to.have.property('bids') - .that.is.an('array') - .with.lengthOf(1); + .that.is.an('array') + .with.lengthOf(1); expect(bidderRequest).to.have.deep.property('bids[0]') - .to.have.property('bidder', 'ucfunnel'); + .to.have.property('bidder', 'ucfunnel'); expect(bidderRequest).to.have.deep.property('bids[0]') - .with.property('sizes') - .that.is.an('array') - .with.lengthOf(1) - .that.deep.equals(adUnit.sizes); + .with.property('sizes') + .that.is.an('array') + .with.lengthOf(1) + .that.deep.equals(adUnit.sizes); expect(bidderRequest).to.have.deep.property('bids[0]') - .with.property('params') - .to.have.property('adid', 'test-ad-83444226E44368D1E32E49EEBE6D29'); + .with.property('params') + .to.have.property('adid', 'test-ad-83444226E44368D1E32E49EEBE6D29'); expect(bidderRequest).to.have.deep.property('bids[0]') - .with.property('params') - .to.have.property('width', 300); + .with.property('params') + .to.have.property('width', 300); }); it('Valid bid-response', () => { From 9884176cd712b96de23dc2c6554231261ccb8710 Mon Sep 17 00:00:00 2001 From: Matt Kendall Date: Tue, 11 Jul 2017 21:22:44 -0400 Subject: [PATCH 60/95] Updates for cookie sync for pbs (#1361) * Updates for cookie sync * fix conflict * fix unit test --- modules/prebidServerBidAdapter.js | 34 +++++++++++++++++-- src/adaptermanager.js | 15 ++++++-- src/constants.json | 4 ++- src/prebid.js | 15 ++++++-- test/spec/core/adapterManager_spec.js | 3 +- .../modules/prebidServerBidAdapter_spec.js | 14 +++++++- 6 files changed, 74 insertions(+), 11 deletions(-) diff --git a/modules/prebidServerBidAdapter.js b/modules/prebidServerBidAdapter.js index 67348059f5f..0f99345cfc0 100644 --- a/modules/prebidServerBidAdapter.js +++ b/modules/prebidServerBidAdapter.js @@ -9,7 +9,7 @@ import adaptermanager from 'src/adaptermanager'; const TYPE = S2S.SRC; const cookiePersistMessage = `Your browser may be blocking 3rd party cookies. By clicking on this page you allow Prebid Server and other advertising partners to place cookies to help us advertise. You can opt out of their cookies here.`; -const cookiePersistUrl = '//ib.adnxs.com/seg?add=1&redir='; +const cookiePersistUrl = 'https://ib.adnxs.com/seg?add=1&redir='; const paramTypes = { 'appnexus': { @@ -34,6 +34,8 @@ const paramTypes = { } }; +let _cookiesQueued = false; + /** * Bidder adapter for Prebid Server */ @@ -109,7 +111,7 @@ function PrebidServer() { if (result.status === 'OK' || result.status === 'no_cookie') { if (result.bidder_status) { result.bidder_status.forEach(bidder => { - if (bidder.no_cookie) { + if (bidder.no_cookie && !_cookiesQueued) { queueSync({bidder: bidder.bidder, url: bidder.usersync.url, type: bidder.usersync.type}); } }); @@ -159,7 +161,7 @@ function PrebidServer() { }); }); } - if (result.status === 'no_cookie') { + if (result.status === 'no_cookie' && config.cookieSet) { // cookie sync persist(cookiePersistUrl, cookiePersistMessage); } @@ -171,8 +173,34 @@ function PrebidServer() { utils.logError('error parsing response: ', result.status); } } + /** + * @param {} {bidders} list of bidders to request user syncs for. + */ + baseAdapter.queueSync = function({bidderCodes}) { + if (!_cookiesQueued) { + _cookiesQueued = true; + const payload = JSON.stringify({ + uuid: utils.generateUUID(), + bidders: bidderCodes + }); + ajax(config.syncEndpoint, (response) => { + try { + response = JSON.parse(response); + response.bidder_status.forEach(bidder => queueSync({bidder: bidder.bidder, url: bidder.usersync.url, type: bidder.usersync.type})); + } + catch (e) { + utils.logError(e); + } + }, + payload, { + contentType: 'text/plain', + withCredentials: true + }); + } + } return { + queueSync: baseAdapter.queueSync, setConfig: baseAdapter.setConfig, createNew: PrebidServer.createNew, callBids: baseAdapter.callBids, diff --git a/src/adaptermanager.js b/src/adaptermanager.js index 08b637e7712..579aa7d9510 100644 --- a/src/adaptermanager.js +++ b/src/adaptermanager.js @@ -12,7 +12,11 @@ var _bidderRegistry = {}; exports.bidderRegistry = _bidderRegistry; // create s2s settings objectType_function -let _s2sConfig = {}; +let _s2sConfig = { + endpoint: CONSTANTS.S2S.DEFAULT_ENDPOINT, + adapter: CONSTANTS.S2S.ADAPTER, + syncEndpoint: CONSTANTS.S2S.SYNC_ENDPOINT +}; var _analyticsRegistry = {}; let _bidderSequence = null; @@ -65,6 +69,13 @@ exports.callBids = ({adUnits, cbTimeout}) => { bidderCodes = shuffle(bidderCodes); } + const s2sAdapter = _bidderRegistry[_s2sConfig.adapter]; + if (s2sAdapter) { + s2sAdapter.setConfig(_s2sConfig); + s2sAdapter.queueSync({bidderCodes}); + } + + if (_s2sConfig.enabled) { // these are called on the s2s adapter let adaptersServerSide = _s2sConfig.bidders; @@ -115,9 +126,7 @@ exports.callBids = ({adUnits, cbTimeout}) => { }); let s2sBidRequest = {tid, 'ad_units': adUnitsCopy}; - let s2sAdapter = _bidderRegistry[_s2sConfig.adapter]; utils.logMessage(`CALLING S2S HEADER BIDDERS ==== ${adaptersServerSide.join(',')}`); - s2sAdapter.setConfig(_s2sConfig); s2sAdapter.callBids(s2sBidRequest); } diff --git a/src/constants.json b/src/constants.json index e64828d4474..4abb08b46d9 100644 --- a/src/constants.json +++ b/src/constants.json @@ -62,6 +62,8 @@ ], "S2S" : { "DEFAULT_ENDPOINT" : "https://prebid.adnxs.com/pbs/v1/auction", - "SRC" : "s2s" + "SRC" : "s2s", + "ADAPTER" : "prebidServer", + "SYNC_ENDPOINT" : "https://prebid.adnxs.com/pbs/v1/cookie_sync" } } diff --git a/src/prebid.js b/src/prebid.js index 1de2cee60dc..10d714d3831 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -711,7 +711,15 @@ $$PREBID_GLOBAL$$.getHighestCpmBids = function (adUnitCode) { /** * Set config for server to server header bidding - * @param {object} options - config object for s2s + * @typedef {Object} options - required + * @property {boolean} enabled enables S2S bidding + * @property {string[]} bidders bidders to request S2S + * === optional params below === + * @property {string} [endpoint] endpoint to contact + * @property {number} [timeout] timeout for S2S bidders - should be lower than `pbjs.requestBids({timeout})` + * @property {string} [adapter] adapter code to use for S2S + * @property {string} [syncEndpoint] endpoint URL for syncing cookies + * @property {boolean} [cookieSet] enables cookieSet functionality */ $$PREBID_GLOBAL$$.setS2SConfig = function(options) { if (!utils.contains(Object.keys(options), 'accountId')) { @@ -729,7 +737,10 @@ $$PREBID_GLOBAL$$.setS2SConfig = function(options) { endpoint: CONSTANTS.S2S.DEFAULT_ENDPOINT, timeout: 1000, maxBids: 1, - adapter: 'prebidServer' + adapter: CONSTANTS.S2S.ADAPTER, + syncEndpoint: CONSTANTS.S2S.SYNC_ENDPOINT, + cookieSet: false, + bidders: [] }, options); adaptermanager.setS2SConfig(config); }; diff --git a/test/spec/core/adapterManager_spec.js b/test/spec/core/adapterManager_spec.js index 45c37cc2267..55557f1e342 100644 --- a/test/spec/core/adapterManager_spec.js +++ b/test/spec/core/adapterManager_spec.js @@ -14,7 +14,8 @@ const CONFIG = { var prebidServerAdapterMock = { bidder: 'prebidServer', callBids: sinon.stub(), - setConfig: sinon.stub() + setConfig: sinon.stub(), + queueSync: sinon.stub() }; describe('adapterManager tests', () => { diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js index 4e5e70e44da..54b9c9bc034 100644 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -342,12 +342,24 @@ describe('S2S Adapter', () => { sinon.assert.calledTwice(cookie.queueSync); }); - it('persist cookie sync when no_cookie response', () => { + it('does not call persist cookie sync when no_cookie response && not opted in', () => { server.respondWith(JSON.stringify(RESPONSE_NO_PBS_COOKIE)); adapter.setConfig(CONFIG); adapter.callBids(REQUEST); server.respond(); + sinon.assert.notCalled(cookie.persist); + }); + + it('calls persist cookie sync when no_cookie response && opted in', () => { + server.respondWith(JSON.stringify(RESPONSE_NO_PBS_COOKIE)); + let config = Object.assign({ + cookieSet: true + }, CONFIG); + + adapter.setConfig(config); + adapter.callBids(REQUEST); + server.respond(); sinon.assert.calledOnce(cookie.persist); }); }); From aa93b82dcced67d4278179f36c1cf674dcf785e1 Mon Sep 17 00:00:00 2001 From: Seba Perez Date: Wed, 12 Jul 2017 10:44:48 -0300 Subject: [PATCH 61/95] Replaced pbjs variable for PREBID_GLOBAL macro (#1343) --- modules/eplanningBidAdapter.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/eplanningBidAdapter.js b/modules/eplanningBidAdapter.js index b08c6ad1a81..b0d610d1676 100644 --- a/modules/eplanningBidAdapter.js +++ b/modules/eplanningBidAdapter.js @@ -4,7 +4,7 @@ var adaptermanager = require('src/adaptermanager'); function EPlanningAdapter() { (function() { - var win = window, doc = win.document, pbjs = win.pbjs, _global = {}, _default = { 'sv': 'ads.us.e-planning.net', 't': 0 }, rnd, FILE = 'file', CALLBACK_FUNCTION = 'hbpb.rH', NULL_SIZE = '1x1', _csRequested = [], PROTO = location.protocol === 'https:' ? 'https:' : 'http:', ISV = 'aklc.img.e-planning.net'; + var win = window, doc = win.document, pbjsVar = win.$$PREBID_GLOBAL$$, _global = {}, _default = { 'sv': 'ads.us.e-planning.net', 't': 0 }, rnd, FILE = 'file', CALLBACK_FUNCTION = 'hbpb.rH', NULL_SIZE = '1x1', _csRequested = [], PROTO = location.protocol === 'https:' ? 'https:' : 'http:', ISV = 'aklc.img.e-planning.net'; function Hbpb() { var slots = (function() { var _data = []; @@ -168,8 +168,8 @@ function EPlanningAdapter() { doc.body.appendChild(script); } function callback(response) { - if (pbjs && pbjs.processEPlanningResponse && typeof pbjs.processEPlanningResponse === 'function') { - pbjs.processEPlanningResponse(response); + if (pbjsVar && pbjsVar.processEPlanningResponse && typeof pbjsVar.processEPlanningResponse === 'function') { + pbjsVar.processEPlanningResponse(response); } } function syncUsers(cs) { @@ -238,8 +238,8 @@ function EPlanningAdapter() { win.hbpb = win.hbpb || new Hbpb(); })(); - window.pbjs = window.pbjs || {}; - window.pbjs.processEPlanningResponse = function(response) { + window.$$PREBID_GLOBAL$$ = window.$$PREBID_GLOBAL$$ || {}; + window.$$PREBID_GLOBAL$$.processEPlanningResponse = function(response) { var bids, bidObject, i; if (response) { bids = response.bids; From 776682fe050a7b101d8cb91618528072fe0cfb2c Mon Sep 17 00:00:00 2001 From: Matt Lane Date: Wed, 12 Jul 2017 14:20:21 -0700 Subject: [PATCH 62/95] Fix import and module reference (#1368) * Use 'exports' for other insertElement reference --- src/secureCreatives.js | 2 +- src/utils.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/secureCreatives.js b/src/secureCreatives.js index 4e84ddc685b..2402ba755f4 100644 --- a/src/secureCreatives.js +++ b/src/secureCreatives.js @@ -4,7 +4,7 @@ */ import events from './events'; -import fireNativeImpressions from './native'; +import { fireNativeImpressions } from './native'; import { EVENTS } from './constants'; const BID_WON = EVENTS.BID_WON; diff --git a/src/utils.js b/src/utils.js index 4963adb1ae8..d67228a4a1a 100644 --- a/src/utils.js +++ b/src/utils.js @@ -455,7 +455,7 @@ exports.insertElement = function(elm, doc, target) { exports.insertPixel = function (url) { const img = new Image(); - img.id = this.getUniqueIdentifierStr(); + img.id = _getUniqueIdentifierStr(); img.src = url; img.height = 0; img.width = 0; @@ -466,7 +466,7 @@ exports.insertPixel = function (url) { } catch (e) { } }; - this.insertElement(img); + exports.insertElement(img); }; /** @@ -479,7 +479,7 @@ exports.insertCookieSyncIframe = function(url, encodeUri) { let div = document.createElement('div'); div.innerHTML = iframeHtml; let iframe = div.firstChild; - this.insertElement(iframe); + exports.insertElement(iframe); }; /** From f90e58b16b19b8beb5c89581065183d9ff5d9834 Mon Sep 17 00:00:00 2001 From: Matt Lane Date: Wed, 12 Jul 2017 14:20:35 -0700 Subject: [PATCH 63/95] Map native icon parameter and validate returned asset values (#1352) * Add sizes field to native icon requests A 'sizes' field is required by /ut when requesting 'icon' native assets * Validate returned asset has set value * Add required param to icon --- modules/appnexusAstBidAdapter.js | 9 +++++---- src/native.js | 2 +- test/spec/bidmanager_spec.js | 23 +++++++++++++---------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/modules/appnexusAstBidAdapter.js b/modules/appnexusAstBidAdapter.js index c7434680349..e8441d9a003 100644 --- a/modules/appnexusAstBidAdapter.js +++ b/modules/appnexusAstBidAdapter.js @@ -16,10 +16,11 @@ const NATIVE_MAPPING = { body: 'description', image: { serverName: 'main_image', - serverParams: { - required: true, - sizes: [{}] - } + serverParams: { required: true, sizes: [{}] } + }, + icon: { + serverName: 'icon', + serverParams: { required: true, sizes: [{}] } }, sponsoredBy: 'sponsored_by' }; diff --git a/src/native.js b/src/native.js index 537296305d4..28016354ba8 100644 --- a/src/native.js +++ b/src/native.js @@ -77,7 +77,7 @@ export function nativeBidIsValid(bid) { const requiredAssets = Object.keys(requestedAssets).filter( key => requestedAssets[key].required ); - const returnedAssets = Object.keys(bid.native); + const returnedAssets = Object.keys(bid.native).filter(key => bid.native[key]); return requiredAssets.every(asset => returnedAssets.includes(asset)); } diff --git a/test/spec/bidmanager_spec.js b/test/spec/bidmanager_spec.js index ff1dcc9b986..ae83a8d106f 100644 --- a/test/spec/bidmanager_spec.js +++ b/test/spec/bidmanager_spec.js @@ -485,25 +485,28 @@ describe('bidmanager.js', function () { }); it('should not add native bids that do not have required assets', () => { - const adUnit = { - code: 'adUnit-code', - mediaType: 'native', + sinon.stub(utils, 'getBidRequest', () => ({ + bidder: 'appnexusAst', nativeParams: { - title: {required: true}, + title: {'required': true}, }, - bids: [ - {bidder: 'appnexusAst', params: {placementId: 'id'}} - ] - }; + mediaType: 'native', + })); const bid = Object.assign({}, bidfactory.createBid(1), - {mediaType: 'native'} + { + bidderCode: 'appnexusAst', + mediaType: 'native', + native: {title: undefined} + } ); const bidsRecCount = $$PREBID_GLOBAL$$._bidsReceived.length; - bidmanager.addBidResponse(adUnit.code, bid); + bidmanager.addBidResponse('adUnit-code', bid); assert.equal(bidsRecCount, $$PREBID_GLOBAL$$._bidsReceived.length); + + utils.getBidRequest.restore(); }); it('should add native bids that do have required assets', () => { From 5cf6ad8776454385bb45e3bfb55751bb9481a566 Mon Sep 17 00:00:00 2001 From: Matt Kendall Date: Wed, 12 Jul 2017 17:21:15 -0400 Subject: [PATCH 64/95] Feature/update cookieset style (#1375) * Update cookieset style * update endpoint to https --- modules/prebidServerBidAdapter.js | 7 ++- src/cookie.js | 44 ++----------------- src/prebid.js | 2 +- .../modules/prebidServerBidAdapter_spec.js | 12 ++--- 4 files changed, 13 insertions(+), 52 deletions(-) diff --git a/modules/prebidServerBidAdapter.js b/modules/prebidServerBidAdapter.js index 0f99345cfc0..775a81b0d6e 100644 --- a/modules/prebidServerBidAdapter.js +++ b/modules/prebidServerBidAdapter.js @@ -4,12 +4,11 @@ import bidmanager from 'src/bidmanager'; import * as utils from 'src/utils'; import { ajax } from 'src/ajax'; import { STATUS, S2S } from 'src/constants'; -import { queueSync, persist } from 'src/cookie'; +import { queueSync, cookieSet } from 'src/cookie'; import adaptermanager from 'src/adaptermanager'; const TYPE = S2S.SRC; -const cookiePersistMessage = `Your browser may be blocking 3rd party cookies. By clicking on this page you allow Prebid Server and other advertising partners to place cookies to help us advertise. You can opt out of their cookies here.`; -const cookiePersistUrl = 'https://ib.adnxs.com/seg?add=1&redir='; +const cookieSetUrl = 'https://acdn.adnxs.com/cookieset/cs.js'; const paramTypes = { 'appnexus': { @@ -163,7 +162,7 @@ function PrebidServer() { } if (result.status === 'no_cookie' && config.cookieSet) { // cookie sync - persist(cookiePersistUrl, cookiePersistMessage); + cookieSet(cookieSetUrl); } } catch (error) { utils.logError(error); diff --git a/src/cookie.js b/src/cookie.js index 912b0763a05..a0636a415fb 100644 --- a/src/cookie.js +++ b/src/cookie.js @@ -1,5 +1,6 @@ const cookie = exports; import * as utils from 'utils'; +import adLoader from 'adloader'; const queue = []; @@ -38,48 +39,9 @@ cookie.syncCookies = function(timeout) { } }; -cookie.persist = function(url, msgHtml) { +cookie.cookieSet = function(cookieSetUrl) { if (!utils.isSafariBrowser()) { return; } - linkOverride(url); - displayFooter(msgHtml); + adLoader.loadScript(cookieSetUrl, null, true); }; - -function linkOverride(url) { - for (var i = 0; i < document.links.length; i++) { - var link = document.links[i]; - link.href = url + encodeURIComponent(link.href); - } -} - -function displayFooter(msgHtml) { - // https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie#Example_3_Do_something_only_once - if (document.cookie.replace(/(?:(?:^|.*;\s*)pbsCookiePersistFooter\s*\=\s*([^;]*).*$)|^.*$/, '$1') !== 'true') { - document.body.appendChild(createFooter(msgHtml)); - document.cookie = 'pbsCookiePersistFooter=true; expires=Fri, 31 Dec 9999 23:59:59 GMT'; - } -} - -function createFooter(msgHtml) { - const footer = document.createElement('div'); - footer.style.background = '#D3D3D3'; - footer.style.color = '#555'; - footer.style.boxShadow = '0 -1px 2px rgba(0, 0, 0, 0.2)'; - footer.style.fontFamily = 'sans-serif'; - footer.style.lineHeight = '1.5'; - footer.style.position = 'fixed'; - footer.style.bottom = '0'; - footer.style.left = '0'; - footer.style.right = '0'; - footer.style.width = '100%'; - footer.style.padding = '1em 0'; - footer.style.zindex = '1000'; - - const footerText = document.createElement('p'); - footerText.style.margin = '0 2em'; - footerText.innerHTML = msgHtml; - footer.appendChild(footerText); - - return footer; -} diff --git a/src/prebid.js b/src/prebid.js index 10d714d3831..be0477f640f 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -739,7 +739,7 @@ $$PREBID_GLOBAL$$.setS2SConfig = function(options) { maxBids: 1, adapter: CONSTANTS.S2S.ADAPTER, syncEndpoint: CONSTANTS.S2S.SYNC_ENDPOINT, - cookieSet: false, + cookieSet: true, bidders: [] }, options); adaptermanager.setS2SConfig(config); diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js index 54b9c9bc034..391d787772e 100644 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -184,7 +184,7 @@ describe('S2S Adapter', () => { beforeEach(() => { server = sinon.fakeServer.create(); sinon.stub(cookie, 'queueSync'); - sinon.stub(cookie, 'persist'); + sinon.stub(cookie, 'cookieSet'); sinon.stub(bidmanager, 'addBidResponse'); sinon.stub(utils, 'getBidderRequestAllAdUnits').returns({ bids: [{ @@ -203,7 +203,7 @@ describe('S2S Adapter', () => { utils.getBidderRequestAllAdUnits.restore(); utils.getBidRequest.restore(); cookie.queueSync.restore(); - cookie.persist.restore(); + cookie.cookieSet.restore(); }); // TODO: test dependent on pbjs_api_spec. Needs to be isolated @@ -342,16 +342,16 @@ describe('S2S Adapter', () => { sinon.assert.calledTwice(cookie.queueSync); }); - it('does not call persist cookie sync when no_cookie response && not opted in', () => { + it('does not call cookieSet cookie sync when no_cookie response && not opted in', () => { server.respondWith(JSON.stringify(RESPONSE_NO_PBS_COOKIE)); adapter.setConfig(CONFIG); adapter.callBids(REQUEST); server.respond(); - sinon.assert.notCalled(cookie.persist); + sinon.assert.notCalled(cookie.cookieSet); }); - it('calls persist cookie sync when no_cookie response && opted in', () => { + it('calls cookieSet cookie sync when no_cookie response && opted in', () => { server.respondWith(JSON.stringify(RESPONSE_NO_PBS_COOKIE)); let config = Object.assign({ cookieSet: true @@ -360,7 +360,7 @@ describe('S2S Adapter', () => { adapter.setConfig(config); adapter.callBids(REQUEST); server.respond(); - sinon.assert.calledOnce(cookie.persist); + sinon.assert.calledOnce(cookie.cookieSet); }); }); }); From 4b9136ce1c1f8e40cbbd14df1281763465488073 Mon Sep 17 00:00:00 2001 From: Samuel Horwitz Date: Wed, 12 Jul 2017 16:38:07 -0600 Subject: [PATCH 65/95] Add Kargo adapter (#1316) --- modules/kargoBidAdapter.js | 169 +++++++++++ test/spec/modules/kargoBidAdapter_spec.js | 350 ++++++++++++++++++++++ 2 files changed, 519 insertions(+) create mode 100644 modules/kargoBidAdapter.js create mode 100644 test/spec/modules/kargoBidAdapter_spec.js diff --git a/modules/kargoBidAdapter.js b/modules/kargoBidAdapter.js new file mode 100644 index 00000000000..cae77e93d69 --- /dev/null +++ b/modules/kargoBidAdapter.js @@ -0,0 +1,169 @@ +const bidfactory = require('src/bidfactory.js'); +const bidmanager = require('src/bidmanager.js'); +const adloader = require('src/adloader.js'); +const utils = require('src/utils.js'); +const adaptermanager = require('src/adaptermanager'); +const CONSTANTS = require('src/constants.json'); +const HOST = $$PREBID_GLOBAL$$.kargo_kraken_host || 'https://krk.kargo.com'; + +const KargoAdapter = function KargoAdapter() { + function _handleBid(bids) { + return function wrappedHandleBid(adUnits) { + utils._map(bids, bid => { + let adUnit = adUnits[bid.params.placementId]; + + if (adUnit) { + bidmanager.addBidResponse(bid.placementCode, _createBid(adUnit)); + + if (adUnit.receivedTracker) { + var el = document.createElement('img'); + el.src = adUnit.receivedTracker; + document.body.appendChild(el); + } + } + }); + }; + } + + function _createBid(adUnit) { + let bidObject = bidfactory.createBid(CONSTANTS.STATUS.GOOD); + bidObject.bidderCode = 'kargo'; + bidObject.cpm = Number(adUnit.cpm); + bidObject.ad = adUnit.adm; + bidObject.width = adUnit.width; + bidObject.height = adUnit.height; + return bidObject; + } + + function _callBids(params) { + let transformedParams = Object.assign({}, { + timeout: params.timeout, + currency: 'USD', + cpmGranularity: 1, + cpmRange: { + floor: 0, + ceil: 20 + }, + adSlotIds: utils._map(params.bids, bid => bid.params.placementId) + }, _getAllMetadata()), + encodedParams = encodeURIComponent(JSON.stringify(transformedParams)), + callbackName = `kargo_prebid_${params.requestId.replace(/-/g, '_')}`; + + window.$$PREBID_GLOBAL$$[callbackName] = _handleBid(params.bids); + + adloader.loadScript(`${HOST}/api/v1/bid?json=${encodedParams}&cb=window.$$PREBID_GLOBAL$$.${callbackName}`); + } + + function _readCookie(name) { + let nameEquals = `${name}=`; + + for (let cookie of document.cookie.split(';')) { + while (cookie.charAt(0) === ' ') { + cookie = cookie.substring(1, cookie.length); + } + + if (cookie.indexOf(nameEquals) === 0) { + return cookie.substring(nameEquals.length, cookie.length); + } + } + + return null; + } + + function _getCrbIds() { + try { + var crb = JSON.parse(decodeURIComponent(_readCookie('krg_crb'))), + syncIds = {}; + + if (crb && crb.v) { + var vParsed = JSON.parse(atob(crb.v)); + + if (vParsed && vParsed.syncIds) { + syncIds = vParsed.syncIds; + } + } + + return syncIds; + } + catch (e) { + return {}; + } + } + + function _getUid() { + try { + var uid = JSON.parse(decodeURIComponent(_readCookie('krg_uid'))), + vData = {}; + + if (uid && uid.v) { + vData = uid.v; + } + + return vData; + } + catch (e) { + return {}; + } + } + + function _getKruxUserId() { + return _getLocalStorageSafely('kxkar_user'); + } + + function _getKruxSegments() { + return _getLocalStorageSafely('kxkar_segs'); + } + + function _getKrux() { + var segmentsStr = _getKruxSegments(), + segments = []; + + if (segmentsStr) { + segments = segmentsStr.split(','); + } + + return { + userID: _getKruxUserId(), + segments: segments + }; + } + + function _getLocalStorageSafely(key) { + try { + return localStorage.getItem(key); + } + catch (e) { + return null; + } + } + + function _getUserIds() { + var uid = _getUid(), + crbIds = _getCrbIds(); + + return { + kargoID: uid.userId, + clientID: uid.clientId, + crbIDs: crbIds, + optOut: uid.optOut + }; + } + + function _getAllMetadata() { + return { + userIDs: _getUserIds(), + krux: _getKrux(), + pageURL: window.location.href + }; + } + + // Export the callBids function, so that prebid.js can execute + // this function when the page asks to send out bid requests. + return { + callBids: _callBids + }; +}; + +adaptermanager.registerBidAdapter(new KargoAdapter, 'kargo'); + +module.exports = KargoAdapter; diff --git a/test/spec/modules/kargoBidAdapter_spec.js b/test/spec/modules/kargoBidAdapter_spec.js new file mode 100644 index 00000000000..eaa4fa093b1 --- /dev/null +++ b/test/spec/modules/kargoBidAdapter_spec.js @@ -0,0 +1,350 @@ +describe('kargo adapter tests', function () { + const expect = require('chai').expect; + const assert = require('chai').assert; + const adapter = require('modules/kargoBidAdapter'); + const bidmanager = require('src/bidmanager'); + const bidfactory = require('src/bidfactory'); + const adloader = require('src/adloader'); + const CONSTANTS = require('src/constants.json'); + + var sandbox, params, krakenParams, adUnits, bidFactorySpy, addBidResponseSpy, bodyAppendSpy, cookies = [], localStorageItems = []; + + beforeEach(() => { + sandbox = sinon.sandbox.create(); + addBidResponseSpy = sandbox.stub(bidmanager, 'addBidResponse'); + bodyAppendSpy = sandbox.stub(document.body, 'appendChild'); + simulateBidFactory(); + simulateAdLoader(); + + params = { + timeout: 200, + requestId: 'f4cf851b-665a-43d7-b22c-33c8fdebe577', + bids: [ + { + params: { + placementId: 'foo' + }, + placementCode: 1 + }, + { + params: { + placementId: 'bar' + }, + placementCode: 2 + } + ] + }; + + adUnits = { + foo: { + receivedTracker: 'fake-tracker-1', + cpm: 3, + adm: '
', + width: 320, + height: 50 + }, + bar: { + cpm: 2.5, + adm: '
', + width: 300, + height: 250 + } + } + }); + + afterEach(() => { + sandbox.restore(); + + for (let cookie of cookies) { + removeCookie(cookie); + } + + for (let localStorageItem of localStorageItems) { + localStorage.removeItem(localStorageItem); + } + + cookies.length = 0; + localStorageItems.length = 0; + }); + + function setCookie(cname, cvalue, exdays = 1) { + _setCookie(cname, cvalue, exdays); + cookies.push(cname); + } + + function removeCookie(cname) { + _setCookie(cname, '', -1); + } + + function _setCookie(cname, cvalue, exdays = 1) { + var d = new Date(), + expires; + + d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); + expires = `expires=${d.toUTCString()}`; + document.cookie = `${cname}=${cvalue};${expires};path=/`; + } + + function setLocalStorageItem(name, val) { + localStorage.setItem(name, val); + localStorageItems.push(name); + } + + function simulateAdLoader() { + sandbox.stub(adloader, 'loadScript', (url) => { + window.pbjs.kargo_prebid_f4cf851b_665a_43d7_b22c_33c8fdebe577(adUnits); + krakenParams = JSON.parse(decodeURIComponent(url.match(/\?json=(.*)&cb=/)[1])); + }); + } + + function simulateNoLocalStorage() { + return sandbox.stub(localStorage, 'getItem').throws(); + } + + function simulateBidFactory() { + bidFactorySpy = sandbox.stub(bidfactory, 'createBid').withArgs(CONSTANTS.STATUS.GOOD); + + bidFactorySpy.onCall(0).returns({ + statusMessage: 'Bid available', + adId: '12dd646671a959' + }); + + bidFactorySpy.onCall(1).returns({ + statusMessage: 'Bid available', + adId: '33f07659bdaf94' + }); + } + + function initializeKruxUser() { + setLocalStorageItem('kxkar_user', 'rsgr9pnij'); + } + + function initializeKruxSegments() { + setLocalStorageItem('kxkar_segs', 'qv9v984dy,rpx2gy365,qrd5u4axv,rnub9nmtd,reha00jnu'); + } + + function initializeKrgUid() { + setCookie('krg_uid', '%7B%22v%22%3A%7B%22userId%22%3A%225f108831-302d-11e7-bf6b-4595acd3bf6c%22%2C%22clientId%22%3A%222410d8f2-c111-4811-88a5-7b5e190e475f%22%2C%22optOut%22%3Afalse%7D%7D'); + } + + function initializeKrgCrb() { + setCookie('krg_crb', '%7B%22v%22%3A%22eyJzeW5jSWRzIjp7IjIiOiI4MmZhMjU1NS01OTY5LTQ2MTQtYjRjZS00ZGNmMTA4MGU5ZjkiLCIxNiI6IlZveElrOEFvSnowQUFFZENleUFBQUFDMiY1MDIiLCIyMyI6ImQyYTg1NWE1LTFiMWMtNDMwMC05NDBlLWE3MDhmYTFmMWJkZSIsIjI0IjoiVm94SWs4QW9KejBBQUVkQ2V5QUFBQUMyJjUwMiIsIjI1IjoiNWVlMjQxMzgtNWUwMy00YjlkLWE5NTMtMzhlODMzZjI4NDlmIiwiMl84MCI6ImQyYTg1NWE1LTFiMWMtNDMwMC05NDBlLWE3MDhmYTFmMWJkZSIsIjJfOTMiOiI1ZWUyNDEzOC01ZTAzLTRiOWQtYTk1My0zOGU4MzNmMjg0OWYifSwiZXhwaXJlVGltZSI6MTQ5NzQ0OTM4MjY2OCwibGFzdFN5bmNlZEF0IjoxNDk3MzYyOTc5MDEyfQ%3D%3D%22%7D'); + } + + function initializeInvalidKrgUid() { + setCookie('krg_uid', 'invalid-krg-uid'); + } + + function initializeInvalidKrgCrbType1() { + setCookie('krg_crb', 'invalid-krg-crb'); + } + + function initializeInvalidKrgCrbType2() { + setCookie('krg_crb', '%7B%22v%22%3A%22%26%26%26%26%26%26%22%7D'); + } + + function initializeInvalidKrgCrbType3() { + setCookie('krg_crb', '%7B%22v%22%3A%22Ly8v%22%7D'); + } + + function initializeEmptyKrgUid() { + setCookie('krg_uid', '%7B%7D'); + } + + function initializeEmptyKrgCrb() { + setCookie('krg_crb', '%7B%22v%22%3A%22eyJleHBpcmVUaW1lIjoxNDk3NDQ5MzgyNjY4LCJsYXN0U3luY2VkQXQiOjE0OTczNjI5NzkwMTJ9%22%7D'); + } + + function getExpectedKrakenParams(excludeUserIds, excludeKrux) { + var base = { + timeout: 200, + currency: 'USD', + cpmGranularity: 1, + cpmRange: { + floor: 0, + ceil: 20 + }, + adSlotIds: [ + 'foo', + 'bar' + ], + userIDs: { + kargoID: '5f108831-302d-11e7-bf6b-4595acd3bf6c', + clientID: '2410d8f2-c111-4811-88a5-7b5e190e475f', + crbIDs: { + 2: '82fa2555-5969-4614-b4ce-4dcf1080e9f9', + 16: 'VoxIk8AoJz0AAEdCeyAAAAC2&502', + 23: 'd2a855a5-1b1c-4300-940e-a708fa1f1bde', + 24: 'VoxIk8AoJz0AAEdCeyAAAAC2&502', + 25: '5ee24138-5e03-4b9d-a953-38e833f2849f', + '2_80': 'd2a855a5-1b1c-4300-940e-a708fa1f1bde', + '2_93': '5ee24138-5e03-4b9d-a953-38e833f2849f' + }, + optOut: false + }, + krux: { + userID: 'rsgr9pnij', + segments: [ + 'qv9v984dy', + 'rpx2gy365', + 'qrd5u4axv', + 'rnub9nmtd', + 'reha00jnu' + ] + }, + pageURL: window.location.href + }; + + if (excludeUserIds === true) { + base.userIDs = { + crbIDs: {} + }; + } else if (excludeUserIds) { + if (excludeUserIds.uid) { + delete base.userIDs.kargoID; + delete base.userIDs.clientID; + delete base.userIDs.optOut; + } + + if (excludeUserIds.crb) { + base.userIDs.crbIDs = {}; + } + } + + if (excludeKrux) { + base.krux = { + userID: null, + segments: [] + }; + } + + return base; + } + + function getExpectedFirstBid() { + return { + 'bidderCode': 'kargo', + 'width': 320, + 'height': 50, + 'statusMessage': 'Bid available', + 'adId': '12dd646671a959', + 'cpm': 3, + 'ad': '
' + }; + } + + function getExpectedSecondBid() { + return { + 'bidderCode': 'kargo', + 'width': 300, + 'height': 250, + 'statusMessage': 'Bid available', + 'adId': '33f07659bdaf94', + 'cpm': 2.5, + 'ad': '
' + }; + } + + function generalAssertions() { + assert(bidFactorySpy.calledTwice); + + assert(addBidResponseSpy.getCall(0).calledWithExactly(1, sinon.match(getExpectedFirstBid()))); + assert(addBidResponseSpy.getCall(1).calledWithExactly(2, sinon.match(getExpectedSecondBid()))); + assert(addBidResponseSpy.calledTwice); + + var trackerEl = bodyAppendSpy.getCall(0).args[0]; + assert(trackerEl instanceof HTMLImageElement); + assert(trackerEl.src === `${window.location.origin}/fake-tracker-1`); + assert(bodyAppendSpy.calledOnce); + } + + it('works when all params and cookies are correctly set', function() { + initializeKruxUser(); + initializeKruxSegments(); + initializeKrgUid(); + initializeKrgCrb(); + + adapter().callBids(params); + + generalAssertions(); + expect(krakenParams).to.deep.equal(getExpectedKrakenParams()); + }); + + it('gracefully handles nothing being set', function() { + adapter().callBids(params); + + generalAssertions(); + expect(krakenParams).to.deep.equal(getExpectedKrakenParams(true, true)); + }); + + it('gracefully handles browsers without localStorage', function() { + simulateNoLocalStorage(); + initializeKrgUid(); + initializeKrgCrb(); + + adapter().callBids(params); + + generalAssertions(); + expect(krakenParams).to.deep.equal(getExpectedKrakenParams(false, true)); + }); + + it('handles empty yet valid Kargo CRBs and UIDs', function() { + initializeKruxUser(); + initializeKruxSegments(); + initializeEmptyKrgUid(); + initializeEmptyKrgCrb(); + + adapter().callBids(params); + + generalAssertions(); + expect(krakenParams).to.deep.equal(getExpectedKrakenParams(true)); + }); + + it('handles broken Kargo UIDs', function() { + initializeKruxUser(); + initializeKruxSegments(); + initializeInvalidKrgUid(); + initializeKrgCrb(); + + adapter().callBids(params); + + generalAssertions(); + expect(krakenParams).to.deep.equal(getExpectedKrakenParams({uid: true})); + }); + + it('handles broken Kargo CRBs where top level JSON is invalid', function() { + initializeKruxUser(); + initializeKruxSegments(); + initializeKrgUid(); + initializeInvalidKrgCrbType1(); + + adapter().callBids(params); + + generalAssertions(); + expect(krakenParams).to.deep.equal(getExpectedKrakenParams({crb: true})); + }); + + it('handles broken Kargo CRBs where inner base 64 is invalid', function() { + initializeKruxUser(); + initializeKruxSegments(); + initializeKrgUid(); + initializeInvalidKrgCrbType2(); + + adapter().callBids(params); + + generalAssertions(); + expect(krakenParams).to.deep.equal(getExpectedKrakenParams({crb: true})); + }); + + it('handles broken Kargo CRBs where inner JSON is invalid', function() { + initializeKruxUser(); + initializeKruxSegments(); + initializeKrgUid(); + initializeInvalidKrgCrbType3(); + + adapter().callBids(params); + + generalAssertions(); + expect(krakenParams).to.deep.equal(getExpectedKrakenParams({crb: true})); + }); +}); From 910f28fad141ee47e90765f9cc97011471162c3e Mon Sep 17 00:00:00 2001 From: Daniel Hoffmann Date: Thu, 13 Jul 2017 14:31:49 +0100 Subject: [PATCH 66/95] Xhb Adapter: adding alias support (#1290) * xhb adapter added - use AppNexus test ad unit * adjusted adapter to set responseCPM to 0 and add in dealId * implemented suggested changes * implemented suggested changes * ran jscs fixer for xhb.js and added it to adapters.json * Xhb adapter: adding alias support * minor changes as per request * re-added default bidder settings --- modules/xhbBidAdapter.js | 109 +++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 51 deletions(-) diff --git a/modules/xhbBidAdapter.js b/modules/xhbBidAdapter.js index 79c53b7d53c..95c4e88b84c 100644 --- a/modules/xhbBidAdapter.js +++ b/modules/xhbBidAdapter.js @@ -1,18 +1,22 @@ -const CONSTANTS = require('src/constants.json'); -const utils = require('src/utils.js'); -const adloader = require('src/adloader.js'); -const bidmanager = require('src/bidmanager.js'); -const bidfactory = require('src/bidfactory.js'); -const adaptermanager = require('src/adaptermanager'); - -function XhbAdapter() { +import * as Adapter from 'src/adapter'; +import bidfactory from 'src/bidfactory'; +import bidmanager from 'src/bidmanager'; +import * as utils from 'src/utils'; +import { STATUS } from 'src/constants'; +import adaptermanager from 'src/adaptermanager'; +import { loadScript } from 'src/adloader'; + +const XhbAdapter = function XhbAdapter() { + const baseAdapter = Adapter.createNew('xhb'); + let usersync = false; + const _defaultBidderSettings = { alwaysUseBid: true, adserverTargeting: [ { key: 'hb_xhb_deal', val: function (bidResponse) { - return bidResponse.dealId; + return bidResponse.adId; } }, { @@ -25,20 +29,33 @@ function XhbAdapter() { }; bidmanager.registerDefaultBidderSetting('xhb', _defaultBidderSettings); + baseAdapter.callBids = function (params) { + const anArr = params.bids; + for (let i = 0; i < anArr.length; i++) { + let bidRequest = anArr[i]; + let callbackId = bidRequest.bidId; + loadScript(buildJPTCall(bidRequest, callbackId)); + } + }; + function buildJPTCall(bid, callbackId) { // determine tag params const placementId = utils.getBidIdParameter('placementId', bid.params); + const member = utils.getBidIdParameter('member', bid.params); const inventoryCode = utils.getBidIdParameter('invCode', bid.params); let referrer = utils.getBidIdParameter('referrer', bid.params); const altReferrer = utils.getBidIdParameter('alt_referrer', bid.params); - // Always use https + // Build tag, always use https let jptCall = 'https://ib.adnxs.com/jpt?'; jptCall = utils.tryAppendQueryString(jptCall, 'callback', '$$PREBID_GLOBAL$$.handleXhbCB'); jptCall = utils.tryAppendQueryString(jptCall, 'callback_uid', callbackId); jptCall = utils.tryAppendQueryString(jptCall, 'id', placementId); + jptCall = utils.tryAppendQueryString(jptCall, 'psa', '0'); + jptCall = utils.tryAppendQueryString(jptCall, 'member', member); jptCall = utils.tryAppendQueryString(jptCall, 'code', inventoryCode); + jptCall = utils.tryAppendQueryString(jptCall, 'traffic_source_code', (utils.getBidIdParameter('trafficSourceCode', bid.params))); // sizes takes a bit more logic let sizeQueryString = ''; @@ -66,24 +83,6 @@ function XhbAdapter() { jptCall += sizeQueryString + '&'; } - // append custom attributes: - let paramsCopy = Object.assign({}, bid.params); - - // delete attributes already used - delete paramsCopy.placementId; - delete paramsCopy.invCode; - delete paramsCopy.query; - delete paramsCopy.referrer; - delete paramsCopy.alt_referrer; - - // get the reminder - let queryParams = utils.parseQueryStringParameters(paramsCopy); - - // append - if (queryParams) { - jptCall += queryParams; - } - // append referrer if (referrer === '') { referrer = utils.getTopWindowUrl(); @@ -106,24 +105,25 @@ function XhbAdapter() { if (jptResponseObj && jptResponseObj.callback_uid) { let responseCPM; - let id = jptResponseObj.callback_uid; + const id = jptResponseObj.callback_uid; let placementCode = ''; - let bidObj = utils.getBidRequest(id); + const bidObj = getBidRequest(id); if (bidObj) { bidCode = bidObj.bidder; placementCode = bidObj.placementCode; - // set the status - bidObj.status = CONSTANTS.STATUS.GOOD; + + // set the status + bidObj.status = STATUS.GOOD; } let bid = []; if (jptResponseObj.result && jptResponseObj.result.ad && jptResponseObj.result.ad !== '') { responseCPM = 0.00; - // store bid response - // bid status is good (indicating 1) + // store bid response + // bid status is good (indicating 1) let adId = jptResponseObj.result.creative_id; - bid = bidfactory.createBid(CONSTANTS.STATUS.GOOD, bidObj); + bid = bidfactory.createBid(STATUS.GOOD, bidObj); bid.creative_id = adId; bid.bidderCode = bidCode; bid.cpm = responseCPM; @@ -134,30 +134,37 @@ function XhbAdapter() { bidmanager.addBidResponse(placementCode, bid); } else { - // no response data - // indicate that there is no bid for this placement - bid = bidfactory.createBid(2); + // no response data + // indicate that there is no bid for this placement + bid = bidfactory.createBid(STATUS.NO_BID, bidObj); bid.bidderCode = bidCode; bidmanager.addBidResponse(placementCode, bid); } - } - }; - function _callBids(params) { - let bids = params.bids || []; - for (let i = 0; i < bids.length; i++) { - let bid = bids[i]; - let callbackId = bid.bidId; - adloader.loadScript(buildJPTCall(bid, callbackId)); + if (!usersync) { + let iframe = utils.createInvisibleIframe(); + iframe.src = '//acdn.adnxs.com/ib/static/usersync/v3/async_usersync.html'; + try { + document.body.appendChild(iframe); + } catch (error) { + utils.logError(error); + } + usersync = true; + } } - } + }; - // Export the callBids function, so that prebid.js can execute - // this function when the page asks to send out bid requests. return { - callBids: _callBids + callBids: baseAdapter.callBids, + setBidderCode: baseAdapter.setBidderCode, + createNew: XhbAdapter.createNew, + buildJPTCall: buildJPTCall }; -} +}; + +XhbAdapter.createNew = function () { + return new XhbAdapter(); +}; adaptermanager.registerBidAdapter(new XhbAdapter, 'xhb'); From 9de31b3c4b73c30c836f556882808ca285a5f76c Mon Sep 17 00:00:00 2001 From: dbemiller Date: Thu, 13 Jul 2017 10:21:56 -0400 Subject: [PATCH 67/95] Fixing some recent bugs in addBidResponse (#1372) * Added back the guard against undefined bids... for now. * Added back the guard to allow undefined bids, because we have no idea which adapters are doing this. * Made sure that the bid adjustment event fired before we use any of the bid properties. --- src/bidmanager.js | 16 +++++++++++----- test/spec/unit/bidmanager_spec.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/bidmanager.js b/src/bidmanager.js index 8bbd52c612f..0c18f9fe27c 100644 --- a/src/bidmanager.js +++ b/src/bidmanager.js @@ -108,7 +108,11 @@ exports.addBidResponse = function (adUnitCode, bid) { } if (!adUnitCode) { - utils.logWarn(errorMessage('No adUnitCode was supplied to addBidResponse.')); + utils.logWarn('No adUnitCode was supplied to addBidResponse.'); + return false; + } + if (!bid) { + utils.logWarn(`Some adapter tried to add an undefined bid for ${adUnitCode}.`); return false; } if (bid.mediaType === 'native' && !nativeBidIsValid(bid)) { @@ -125,7 +129,13 @@ exports.addBidResponse = function (adUnitCode, bid) { // Postprocess the bids so that all the universal properties exist, no matter which bidder they came from. // This should be called before addBidToAuction(). function prepareBidForAuction() { + // Let listeners know that now is the time to adjust the bid, if they want to. + // + // This must be fired first, so that we calculate derived values from the updates + events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, bid); + const { requestId, start } = getBidderRequest(bid.bidderCode, adUnitCode); + Object.assign(bid, { requestId: requestId, responseTimestamp: timestamp(), @@ -137,7 +147,6 @@ exports.addBidResponse = function (adUnitCode, bid) { bid.timeToRespond = bid.responseTimestamp - bid.requestTimestamp; - // append price strings const priceStringsObj = getPriceBucketString(bid.cpm, _customPriceBucket); bid.pbLg = priceStringsObj.low; bid.pbMg = priceStringsObj.med; @@ -164,9 +173,6 @@ exports.addBidResponse = function (adUnitCode, bid) { // Add a bid to the auction. function addBidToAuction() { - // Make sure that the bidAdjustment event fires before bidResponse, so that the bid response - // has the adjusted bid value - events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, bid); events.emit(CONSTANTS.EVENTS.BID_RESPONSE, bid); $$PREBID_GLOBAL$$._bidsReceived.push(bid); diff --git a/test/spec/unit/bidmanager_spec.js b/test/spec/unit/bidmanager_spec.js index f7e12555378..d5b8c77c167 100644 --- a/test/spec/unit/bidmanager_spec.js +++ b/test/spec/unit/bidmanager_spec.js @@ -1,10 +1,17 @@ import { expect } from 'chai'; +import constants from 'src/constants'; +import events from 'src/events'; + import * as bidManager from 'src/bidmanager'; import useVideoCacheStubs from 'test/mocks/videoCacheStub'; import adUnit from 'test/fixtures/video/adUnit'; import bidRequest from 'test/fixtures/video/bidRequest'; import bidResponse from 'test/fixtures/video/bidResponse'; +function adjustCpm(cpm) { + return cpm + 1; +} + describe('The Bid Manager', () => { before(() => { $$PREBID_GLOBAL$$.cbTimeout = 5000; @@ -39,6 +46,10 @@ describe('The Bid Manager', () => { if (expectedBidsReceived === 1) { const bid = $$PREBID_GLOBAL$$._bidsReceived[0]; + + // Ensures that the BidAdjustment listeners execute before the bid goes into the auction. + expect(bid.cpm).to.equal(adjustCpm(0.1)); + expect(bid.vastUrl).to.equal('www.myVastUrl.com'); expect(bid.videoCacheKey).to.equal('FAKE_UUID'); } @@ -58,6 +69,9 @@ describe('The Bid Manager', () => { * transforms it to prepare it for auction. */ function prepAuction(adUnits, bidRequestTweaker) { + function bidAdjuster(bid) { + bid.cpm = adjustCpm(bid.cpm); + } beforeEach(() => { let thisBidRequest = bidRequest; if (bidRequestTweaker) { @@ -65,11 +79,17 @@ describe('The Bid Manager', () => { bidRequestTweaker(thisBidRequest); } + events.on(constants.EVENTS.BID_ADJUSTMENT, bidAdjuster); + $$PREBID_GLOBAL$$.adUnits = adUnits; $$PREBID_GLOBAL$$._bidsRequested = [thisBidRequest]; $$PREBID_GLOBAL$$._bidsReceived = []; $$PREBID_GLOBAL$$._adUnitCodes = $$PREBID_GLOBAL$$.adUnits.map(unit => unit.code); }); + + afterEach(() => { + events.off(constants.EVENTS.BID_ADJUSTMENT, bidAdjuster); + }); } function auctionStart(timedOut) { @@ -112,6 +132,16 @@ describe('The Bid Manager', () => { it('should add valid video bids and then execute the callbacks signaling the end of the auction', testAddVideoBid(true, true, stubProvider)); + + it('should gracefully do nothing when adUnitCode is undefined', () => { + bidManager.addBidResponse(undefined, {}); + expect($$PREBID_GLOBAL$$._bidsReceived.length).to.equal(0); + }); + + it('should gracefully do nothing when bid is undefined', () => { + bidManager.addBidResponse('mock/code'); + expect($$PREBID_GLOBAL$$._bidsReceived.length).to.equal(0); + }); }); describe('when the auction has timed out', () => { From a44004032be835a739e4ea09f34d911c9c1862e8 Mon Sep 17 00:00:00 2001 From: Hugo Duthil Date: Thu, 13 Jul 2017 16:26:07 +0200 Subject: [PATCH 68/95] Add network zone matching to criteo adapter (#1342) --- modules/criteoBidAdapter.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/criteoBidAdapter.js b/modules/criteoBidAdapter.js index c380a2885f9..7a83ad9ff29 100644 --- a/modules/criteoBidAdapter.js +++ b/modules/criteoBidAdapter.js @@ -16,7 +16,7 @@ var CriteoAdapter = function CriteoAdapter() { _pushBidRequestEvent(params); adloader.loadScript( _publisherTagUrl, - function () {}, + function () { }, true ); } else { @@ -42,15 +42,22 @@ var CriteoAdapter = function CriteoAdapter() { // build slots before sending one multi-slots bid request for (var i = 0; i < bids.length; i++) { var bid = bids[i]; + var sizes = bid.sizes || []; slots.push( new Criteo.PubTag.DirectBidding.DirectBiddingSlot( bid.placementCode, bid.params.zoneId, undefined, - bid.transactionId + bid.transactionId, + sizes.map((size) => { + return { width: size[0], height: size[1] } + } + ) ) ); + var networkid = bid.params.networkId; + isAudit |= bid.params.audit !== undefined; } @@ -60,7 +67,9 @@ var CriteoAdapter = function CriteoAdapter() { slots, _callbackSuccess(slots), _callbackError(slots), - _callbackError(slots) // timeout handled as error + _callbackError(slots), // timeout handled as error + undefined, + networkid ); // process the event as soon as possible From 7d53893a8002b23e3534ccdd3385a3db4fd0187e Mon Sep 17 00:00:00 2001 From: Denis Logachev Date: Thu, 13 Jul 2017 17:44:53 +0300 Subject: [PATCH 69/95] video support for adkernel adapter (#1270) --- modules/adkernelBidAdapter.js | 73 +++++++++--- test/spec/modules/adkernelBidAdapter_spec.js | 114 +++++++++++++++---- 2 files changed, 151 insertions(+), 36 deletions(-) diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js index cd0ec8eb3cd..a9c5796b07e 100644 --- a/modules/adkernelBidAdapter.js +++ b/modules/adkernelBidAdapter.js @@ -17,6 +17,9 @@ const AdKernelAdapter = function AdKernelAdapter() { }; const EMPTY_BID_RESPONSE = {'seatbid': [{'bid': []}]}; + const VIDEO_TARGETING = ['mimes', 'minduration', 'maxduration', 'protocols', 'startdelay', 'linearity', 'sequence', + 'boxingallowed', 'playbackmethod', 'delivery', 'pos', 'api', 'ext']; + let baseAdapter = Adapter.createNew('adkernel'); /** @@ -26,15 +29,13 @@ const AdKernelAdapter = function AdKernelAdapter() { function RtbRequestDispatcher() { const _dispatch = {}; const originalBids = {}; - const site = createSite(); const syncedHostZones = {}; + const site = createSite(); // translate adunit info into rtb impression dispatched by host/zone this.addImp = function (bid) { let host = bid.params.host; let zone = bid.params.zoneId; - let size = bid.sizes[0]; - let bidId = bid.bidId; if (!(host in _dispatch)) { _dispatch[host] = {}; @@ -43,17 +44,10 @@ const AdKernelAdapter = function AdKernelAdapter() { if (!(zone in _dispatch[host])) { _dispatch[host][zone] = []; } - let imp = { - 'id': bidId, - 'tagid': bid.placementCode, - 'banner': {'w': size[0], 'h': size[1]} - }; - if (utils.getTopWindowLocation().protocol === 'https:') { - imp.secure = 1; - } + let imp = buildImp(bid); // save rtb impression for specified ad-network host and zone _dispatch[host][zone].push(imp); - originalBids[bidId] = bid; + originalBids[bid.bidId] = bid; // perform user-sync if (!(host in syncedHostZones)) { syncedHostZones[host] = []; @@ -63,6 +57,33 @@ const AdKernelAdapter = function AdKernelAdapter() { } }; + function buildImp(bid) { + const size = getBidSize(bid); + const imp = { 'id': bid.bidId, 'tagid': bid.placementCode}; + + if (bid.mediaType === 'video') { + imp.video = {w: size[0], h: size[1]}; + if (bid.params.video) { + Object.keys(bid.params.video) + .filter(param => VIDEO_TARGETING.includes(param)) + .forEach(param => imp.video[param] = bid.params.video[param]); + } + } else { + imp.banner = {w: size[0], h: size[1]}; + } + if (utils.getTopWindowLocation().protocol === 'https:') { + imp.secure = 1; + } + return imp; + } + + function getBidSize(bid) { + if (bid.mediaType === 'video') { + return bid.sizes; + } + return bid.sizes[0]; + } + /** * Main function to get bid requests */ @@ -171,7 +192,8 @@ const AdKernelAdapter = function AdKernelAdapter() { let adUnitId = bid.placementCode; if (bidResp) { utils.logMessage(`got response for ${adUnitId}`); - bidmanager.addBidResponse(adUnitId, createBidObject(bidResp, bid, imp.banner.w, imp.banner.h)); + let dimensions = getCreativeSize(imp, bidResp); + bidmanager.addBidResponse(adUnitId, createBidObject(bidResp, bid, dimensions.w, dimensions.h)); } else { utils.logMessage(`got empty response for ${adUnitId}`); bidmanager.addBidResponse(adUnitId, createEmptyBidObject(bid)); @@ -179,17 +201,34 @@ const AdKernelAdapter = function AdKernelAdapter() { }); } + /** + * Evaluate creative size from response or from request + */ + function getCreativeSize(imp, bid) { + let dimensions = (bid.h && bid.w) ? bid : (imp.banner || imp.video); + return { + w: dimensions.w, + h: dimensions.h + }; + } + /** * Create bid object for the bid manager */ function createBidObject(resp, bid, width, height) { - return Object.assign(bidfactory.createBid(1, bid), { + let bidObj = Object.assign(bidfactory.createBid(1, bid), { bidderCode: bid.bidder, - ad: formatAdMarkup(resp), width: width, height: height, cpm: parseFloat(resp.price) }); + if (bid.mediaType === 'video') { + bidObj.vastUrl = resp.nurl; + bidObj.mediaType = 'video'; + } else { + bidObj.ad = formatAdMarkup(resp); + } + return bidObj; } /** @@ -268,7 +307,9 @@ AdKernelAdapter.createNew = function() { return new AdKernelAdapter(); }; -adaptermanager.registerBidAdapter(new AdKernelAdapter, 'adkernel'); +adaptermanager.registerBidAdapter(new AdKernelAdapter, 'adkernel', { + supportedMediaTypes: ['video'] +}); adaptermanager.aliasBidAdapter('adkernel', 'headbidding'); module.exports = AdKernelAdapter; diff --git a/test/spec/modules/adkernelBidAdapter_spec.js b/test/spec/modules/adkernelBidAdapter_spec.js index 031caa6996a..87bf3430d5d 100644 --- a/test/spec/modules/adkernelBidAdapter_spec.js +++ b/test/spec/modules/adkernelBidAdapter_spec.js @@ -36,31 +36,60 @@ describe('Adkernel adapter', () => { params: {zoneId: 1}, placementCode: 'ad-unit-1', sizes: [[728, 90]] + }, bid_video = { + bidder: 'adkernel', + bidId: 'Bid_Video', + sizes: [640, 480], + mediaType: 'video', + params: { + zoneId: 1, + host: 'rtb.adkernel.com', + video: { + mimes: ['video/mp4', 'video/webm', 'video/x-flv'] + } + }, + placementCode: 'ad-unit-1' }; const bidResponse1 = { - 'id': 'bid1', - 'seatbid': [{ - 'bid': [{ - 'id': '1', - 'impid': 'Bid_01', - 'price': 3.01, - 'nurl': 'https://rtb.com/win?i=ZjKoPYSFI3Y_0', - 'adm': '' + id: 'bid1', + seatbid: [{ + bid: [{ + id: '1', + impid: 'Bid_01', + price: 3.01, + nurl: 'https://rtb.com/win?i=ZjKoPYSFI3Y_0', + adm: '' }] }], - 'cur': 'USD' + cur: 'USD' }, bidResponse2 = { - 'id': 'bid2', - 'seatbid': [{ - 'bid': [{ - 'id': '2', - 'impid': 'Bid_02', - 'price': 1.31, - 'adm': '' + id: 'bid2', + seatbid: [{ + bid: [{ + id: '2', + impid: 'Bid_02', + price: 1.31, + adm: '' + }] + }], + cur: 'USD' + }, videoBidResponse = { + id: '47ce4badcf7482', + seatbid: [{ + bid: [{ + id: 'sZSYq5zYMxo_0', + impid: 'Bid_Video', + price: 0.00145, + adid: '158801', + nurl: 'https://rtb.com/win?i=sZSYq5zYMxo_0&f=nurl', + cid: '16855', + crid: '158801', + w: 600, + h: 400 }] }], - 'cur': 'USD' + cur: 'USD' }; let adapter, @@ -113,7 +142,7 @@ describe('Adkernel adapter', () => { }); }); - describe('request building', () => { + describe('banner request building', () => { let bidRequest; beforeEach(() => { @@ -150,7 +179,6 @@ describe('Adkernel adapter', () => { }); it('should have tagid', () => { - // console.warn(bidRequest.imp[0]); expect(bidRequest.imp[0]).to.have.property('tagid', 'ad-unit-1'); }); @@ -166,6 +194,38 @@ describe('Adkernel adapter', () => { }) }); + describe('video request building', () => { + let bidRequest; + + beforeEach(() => { + sandbox.stub(utils, 'getTopWindowLocation', () => { + return { + protocol: 'https:', + hostname: 'example.com', + host: 'example.com', + pathname: '/index.html', + href: 'http://example.com/index.html' + }; + }); + ajaxStub.onCall(0).callsArgWith(1, JSON.stringify(videoBidResponse)); + doRequest([bid_video]); + bidRequest = JSON.parse(decodeURIComponent(ajaxStub.getCall(0).args[2].r)); + }); + + it('should have video object', () => { + expect(bidRequest.imp[0]).to.have.property('video'); + }); + + it('should have h/w', () => { + expect(bidRequest.imp[0].video).to.have.property('w', 640); + expect(bidRequest.imp[0].video).to.have.property('h', 480); + }); + + it('should have tagid', () => { + expect(bidRequest.imp[0]).to.have.property('tagid', 'ad-unit-1'); + }); + }); + describe('requests routing', () => { it('should issue a request for each network', () => { ajaxStub.onFirstCall().callsArgWith(1, '') @@ -210,6 +270,20 @@ describe('Adkernel adapter', () => { expect(bidResponse.height).to.equal(250); }); + it('should return fully-initialized video bid-response', () => { + ajaxStub.onCall(0).callsArgWith(1, JSON.stringify(videoBidResponse)); + doRequest([bid_video]); + let bidResponse = bidmanager.addBidResponse.firstCall.args[1]; + expect(bidmanager.addBidResponse.firstCall.args[0]).to.equal('ad-unit-1'); + expect(bidResponse.getStatusCode()).to.equal(CONSTANTS.STATUS.GOOD); + expect(bidResponse.mediaType).to.equal('video'); + expect(bidResponse.bidderCode).to.equal('adkernel'); + expect(bidResponse.cpm).to.equal(0.00145); + expect(bidResponse.vastUrl).to.equal('https://rtb.com/win?i=sZSYq5zYMxo_0&f=nurl'); + expect(bidResponse.width).to.equal(600); + expect(bidResponse.height).to.equal(400); + }); + it('should map responses to proper ad units', () => { ajaxStub.onCall(0).callsArgWith(1, JSON.stringify(bidResponse1)); ajaxStub.onCall(1).callsArgWith(1, JSON.stringify(bidResponse2)); @@ -234,7 +308,7 @@ describe('Adkernel adapter', () => { expect(bidmanager.addBidResponse.secondCall.args[0]).to.equal('ad-unit-2'); }); - it('should add nurl as pixel', () => { + it('should add nurl as pixel for banner response', () => { sandbox.spy(utils, 'createTrackPixelHtml'); ajaxStub.onCall(0).callsArgWith(1, JSON.stringify(bidResponse1)); doRequest([bid1_zone1]); From 81f3877fe0a35c2f46b6426665655d8acdfc1f04 Mon Sep 17 00:00:00 2001 From: Matt Kendall Date: Thu, 13 Jul 2017 11:35:24 -0400 Subject: [PATCH 70/95] add dbemiller to core team. --- governance.md | 1 + 1 file changed, 1 insertion(+) diff --git a/governance.md b/governance.md index faaece83079..9f8a1fe1e13 100644 --- a/governance.md +++ b/governance.md @@ -20,3 +20,4 @@ This document describes the governance model for the Prebid project. The Prebid - @jaiminpanchal27 - @snapwich - @harpere +- @dbemiller From 1f0c570e47bd0d1f37c9c7c5f06b1583f0e43727 Mon Sep 17 00:00:00 2001 From: Rich Snapp Date: Thu, 13 Jul 2017 11:38:00 -0600 Subject: [PATCH 71/95] add dt.pref for DigiTrust in rubiconBidAdapter (#1376) --- modules/rubiconBidAdapter.js | 3 ++- test/spec/modules/rubiconBidAdapter_spec.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index c9d91a11430..76c555855c0 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -150,7 +150,8 @@ function RubiconAdapter() { } return [ 'dt.id', digiTrustId.id, - 'dt.keyv', digiTrustId.keyv + 'dt.keyv', digiTrustId.keyv, + 'dt.pref', 0 ]; } diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js index 2785082083d..d2092d9a1eb 100644 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -329,7 +329,8 @@ describe('the rubicon adapter', () => { let expectedQuery = { 'dt.id': 'testId', - 'dt.keyv': 'testKeyV' + 'dt.keyv': 'testKeyV', + 'dt.pref': '0' }; // test that all values above are both present and correct From fe00cc963ba9c64571598e31b13c046c0cd9987c Mon Sep 17 00:00:00 2001 From: Anand Venkatraman Date: Thu, 13 Jul 2017 18:30:20 -0400 Subject: [PATCH 72/95] PulsePoint Lite adapter changes (#1338) * ET-1691: Pulsepoint Analytics adapter for Prebid. (#1) * ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter * ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter * ET-1691: cleanup * ET-1691: minor * ET-1691: revert package.json change * Adding bidRequest to bidFactory.createBid method as per https://github.com/prebid/Prebid.js/issues/509 * ET-1765: Adding support for additional params in PulsePoint adapter (#2) * ET-1850: Fixing https://github.com/prebid/Prebid.js/issues/866 * Minor fix * Adding multi imp ORTB support * replacing existing lite adapter code * interim commit * pulseLite - native tests * pulseLite - native tests * registering new adapter name via alias --- modules/pulsepointLiteBidAdapter.js | 304 +++++++++++++++--- .../modules/pulsepointLiteBidAdapter_spec.js | 171 ++++++++-- 2 files changed, 404 insertions(+), 71 deletions(-) diff --git a/modules/pulsepointLiteBidAdapter.js b/modules/pulsepointLiteBidAdapter.js index 807477f729d..b9ce3aacb56 100644 --- a/modules/pulsepointLiteBidAdapter.js +++ b/modules/pulsepointLiteBidAdapter.js @@ -5,45 +5,203 @@ import {ajax} from 'src/ajax'; import {STATUS} from 'src/constants'; import adaptermanager from 'src/adaptermanager'; +/** + * PulsePoint "Lite" Adapter. This adapter implementation is lighter than the + * alternative/original PulsePointAdapter because it has no external + * dependencies and relies on a single OpenRTB request to the PulsePoint + * bidder instead of separate requests per slot. + */ function PulsePointLiteAdapter() { - const bidUrl = window.location.protocol + '//bid.contextweb.com/header/tag?'; + const bidUrl = window.location.protocol + '//bid.contextweb.com/header/ortb'; const ajaxOptions = { - method: 'GET', + method: 'POST', withCredentials: true, contentType: 'text/plain' }; + const NATIVE_DEFAULTS = { + TITLE_LEN: 100, + DESCR_LEN: 200, + SPONSORED_BY_LEN: 50, + IMG_MIN: 150, + ICON_MIN: 50, + }; + + /** + * Makes the call to PulsePoint endpoint and registers bids. + */ + function _callBids(bidRequest) { + try { + // construct the openrtb bid request from slots + const request = { + imp: bidRequest.bids.map(slot => impression(slot)), + site: site(bidRequest), + device: device(), + }; + ajax(bidUrl, (rawResponse) => { + bidResponseAvailable(bidRequest, rawResponse); + }, JSON.stringify(request), ajaxOptions); + } catch (e) { + // register passback on any exceptions while attempting to fetch response. + logError('pulsepoint.requestBid', 'ERROR', e); + bidResponseAvailable(bidRequest); + } + } - function _callBids(bidderRequest) { - bidderRequest.bids.forEach(bidRequest => { - try { - var params = Object.assign({}, environment(), bidRequest.params); - var url = bidUrl + Object.keys(params).map(k => k + '=' + encodeURIComponent(params[k])).join('&'); - ajax(url, (bidResponse) => { - bidResponseAvailable(bidRequest, bidResponse); - }, null, ajaxOptions); - } catch (e) { - // register passback on any exceptions while attempting to fetch response. - logError('pulsepoint.requestBid', 'ERROR', e); - bidResponseAvailable(bidRequest); + /** + * Callback for bids, after the call to PulsePoint completes. + */ + function bidResponseAvailable(bidRequest, rawResponse) { + const idToSlotMap = {}; + const idToBidMap = {}; + // extract the request bids and the response bids, keyed by impr-id + bidRequest.bids.forEach((slot) => { + idToSlotMap[slot.bidId] = slot; + }); + const bidResponse = parse(rawResponse); + if (bidResponse) { + bidResponse.seatbid.forEach(seatBid => seatBid.bid.forEach((bid) => { + idToBidMap[bid.impid] = bid; + })); + } + // register the responses + Object.keys(idToSlotMap).forEach((id) => { + if (idToBidMap[id]) { + const size = adSize(idToSlotMap[id]); + const bid = createBid(STATUS.GOOD, bidRequest); + bid.bidderCode = bidRequest.bidderCode; + bid.cpm = idToBidMap[id].price; + bid.adId = id; + if(isNative(idToSlotMap[id])) { + bid.native = nativeResponse(idToSlotMap[id], idToBidMap[id]); + bid.mediaType = 'native'; + } else { + bid.ad = idToBidMap[id].adm; + bid.width = size[0]; + bid.height = size[1]; + } + addBidResponse(idToSlotMap[id].placementCode, bid); + } else { + const passback = createBid(STATUS.NO_BID, bidRequest); + passback.bidderCode = bidRequest.bidderCode; + passback.adId = id; + addBidResponse(idToSlotMap[id].placementCode, passback); } }); } - function environment() { + /** + * Produces an OpenRTBImpression from a slot config. + */ + function impression(slot) { + return { + id: slot.bidId, + banner: banner(slot), + native: native(slot), + tagid: slot.params.ct.toString(), + }; + } + + /** + * Produces an OpenRTB Banner object for the slot given. + */ + function banner(slot) { + const size = adSize(slot); + return slot.nativeParams ? null : { + w: size[0], + h: size[1], + }; + } + + /** + * Produces an OpenRTB Native object for the slot given. + */ + function native(slot) { + if (slot.nativeParams) { + const assets = []; + addAsset(assets, titleAsset(assets.length + 1, slot.nativeParams.title, NATIVE_DEFAULTS.TITLE_LEN)); + addAsset(assets, dataAsset(assets.length + 1, slot.nativeParams.body, 2, NATIVE_DEFAULTS.DESCR_LEN)); + addAsset(assets, dataAsset(assets.length + 1, slot.nativeParams.sponsoredBy, 1, NATIVE_DEFAULTS.SPONSORED_BY_LEN)); + addAsset(assets, imageAsset(assets.length + 1, slot.nativeParams.icon, 1, NATIVE_DEFAULTS.ICON_MIN, NATIVE_DEFAULTS.ICON_MIN)); + addAsset(assets, imageAsset(assets.length + 1, slot.nativeParams.image, 3, NATIVE_DEFAULTS.IMG_MIN, NATIVE_DEFAULTS.IMG_MIN)); + return { + request: JSON.stringify({ assets }), + ver: '1.1', + }; + } + return null; + } + + /** + * Helper method to add an asset to the assets list. + */ + function addAsset(assets, asset) { + if(asset) { + assets.push(asset); + } + } + + /** + * Produces a Native Title asset for the configuration given. + */ + function titleAsset(id, params, defaultLen) { + if (params) { + return { + id: id, + required: params.required ? 1 : 0, + title: { + len: params.len || defaultLen, + }, + }; + } + return null; + } + + /** + * Produces a Native Image asset for the configuration given. + */ + function imageAsset(id, params, type, defaultMinWidth, defaultMinHeight) { + return params ? { + id: id, + required: params.required ? 1 : 0, + img: { + type, + wmin: params.wmin || defaultMinWidth, + hmin: params.hmin || defaultMinHeight, + } + } : null; + } + + /** + * Produces a Native Data asset for the configuration given. + */ + function dataAsset(id, params, type, defaultLen) { + return params ? { + id: id, + required: params.required ? 1 : 0, + data: { + type, + len: params.len || defaultLen, + } + } : null; + } + + /** + * Produces an OpenRTB site object. + */ + function site(bidderRequest) { + const pubId = bidderRequest.bids.length > 0 ? bidderRequest.bids[0].params.cp : '0'; return { - cn: 1, - ca: 'BID', - tl: 1, - 'if': 0, - cwu: getTopWindowLocation().href, - cwr: referrer(), - dw: document.documentElement.clientWidth, - cxy: document.documentElement.clientWidth + ',' + document.documentElement.clientHeight, - tz: new Date().getTimezoneOffset(), - ln: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage) + publisher: { + id: pubId.toString(), + }, + ref: referrer(), + page: getTopWindowLocation().href, }; } + /** + * Attempts to capture the referrer url. + */ function referrer() { try { return window.top.document.referrer; @@ -52,33 +210,74 @@ function PulsePointLiteAdapter() { } } - function bidResponseAvailable(bidRequest, rawResponse) { - if (rawResponse) { - var bidResponse = parse(rawResponse); - if (bidResponse) { - var adSize = bidRequest.params.cf.toUpperCase().split('X'); - var bid = createBid(STATUS.GOOD, bidRequest); - bid.bidderCode = bidRequest.bidder; - bid.cpm = bidResponse.bidCpm; - bid.ad = bidResponse.html; - bid.width = adSize[0]; - bid.height = adSize[1]; - addBidResponse(bidRequest.placementCode, bid); - return; - } - } - var passback = createBid(STATUS.NO_BID, bidRequest); - passback.bidderCode = bidRequest.bidder; - addBidResponse(bidRequest.placementCode, passback); + /** + * Produces an OpenRTB Device object. + */ + function device() { + return { + ua: navigator.userAgent, + language: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage), + }; } + /** + * Safely parses the input given. Returns null on + * parsing failure. + */ function parse(rawResponse) { try { - return JSON.parse(rawResponse); + if(rawResponse) { + return JSON.parse(rawResponse); + } } catch (ex) { - logError('pulsepoint.safeParse', 'ERROR', ex); - return null; + logError('pulsepointLite.safeParse', 'ERROR', ex); + } + return null; + } + + /** + * Determines the AdSize for the slot. + */ + function adSize(slot) { + if(slot.params.cf) { + const size = slot.params.cf.toUpperCase().split('X'); + const width = parseInt(slot.params.cw || size[0], 10); + const height = parseInt(slot.params.ch || size[1], 10); + return [width, height]; } + return [1, 1]; + } + + /** + * Parses the native response from the Bid given. + */ + function nativeResponse(slot, bid) { + if(slot.nativeParams) { + const nativeAd = parse(bid.adm); + const keys = {}; + if(nativeAd && nativeAd.native && nativeAd.native.assets) { + nativeAd.native.assets.forEach((asset) => { + keys.title = asset.title ? asset.title.text : keys.title; + keys.body = asset.data && asset.data.type === 2 ? asset.data.value : keys.body; + keys.sponsoredBy = asset.data && asset.data.type === 1 ? asset.data.value : keys.sponsoredBy; + keys.image = asset.img && asset.img.type === 3 ? asset.img.url : keys.image; + keys.icon = asset.img && asset.img.type === 1 ? asset.img.url : keys.icon; + }); + if (nativeAd.native.link) { + keys.clickUrl = encodeURIComponent(nativeAd.native.link.url); + } + keys.impressionTrackers = nativeAd.native.imptrackers; + return keys; + } + } + return null; + } + + /** + * Parses the native response from the Bid given. + */ + function isNative(slot) { + return slot.nativeParams ? true : false; } return { @@ -86,6 +285,17 @@ function PulsePointLiteAdapter() { }; } -adaptermanager.registerBidAdapter(new PulsePointLiteAdapter, 'pulsepointLite'); +/** + * "pulseLite" will be the adapter name going forward. "pulsepointLite" to be + * deprecated, but kept here for backwards compatibility. + * Reason is key truncation. When the Publisher opts for sending all bids to DFP, then + * the keys get truncated due to the limit in key-size (20 characters, detailed + * here https://support.google.com/dfp_premium/answer/1628457?hl=en). Here is an + * example, where keys got truncated when using the "pulsepointLite" alias - "hb_adid_pulsepointLi=1300bd87d59c4c2" +*/ +adaptermanager.registerBidAdapter(new PulsePointLiteAdapter, 'pulseLite', { + supportedMediaTypes: [ 'native' ] +}); +adaptermanager.aliasBidAdapter('pulseLite', 'pulsepointLite'); module.exports = PulsePointLiteAdapter; diff --git a/test/spec/modules/pulsepointLiteBidAdapter_spec.js b/test/spec/modules/pulsepointLiteBidAdapter_spec.js index f48d361d4cd..9532685a037 100644 --- a/test/spec/modules/pulsepointLiteBidAdapter_spec.js +++ b/test/spec/modules/pulsepointLiteBidAdapter_spec.js @@ -1,12 +1,13 @@ import {expect} from 'chai'; import PulsePointAdapter from 'modules/pulsepointLiteBidAdapter'; import bidManager from 'src/bidmanager'; +import {getTopWindowLocation} from 'src/utils'; import * as ajax from 'src/ajax'; -import {parse as parseURL} from 'src/url'; describe('PulsePoint Lite Adapter Tests', () => { let pulsepointAdapter = new PulsePointAdapter(); let slotConfigs; + let nativeSlotConfig; let ajaxStub; beforeEach(() => { @@ -14,10 +15,10 @@ describe('PulsePoint Lite Adapter Tests', () => { ajaxStub = sinon.stub(ajax, 'ajax'); slotConfigs = { + bidderCode: 'pulseLite', bids: [ { placementCode: '/DfpAccount1/slot1', - bidder: 'pulsepoint', bidId: 'bid12345', params: { cp: 'p10000', @@ -26,16 +27,33 @@ describe('PulsePoint Lite Adapter Tests', () => { } }, { placementCode: '/DfpAccount2/slot2', - bidder: 'pulsepoint', bidId: 'bid23456', params: { - cp: 'p20000', + cp: 'p10000', ct: 't20000', cf: '728x90' } } ] }; + nativeSlotConfig = { + bidderCode: 'pulseLite', + bids: [ + { + placementCode: '/DfpAccount1/slot3', + bidId: 'bid12345', + nativeParams: { + title: { required: true, len: 200 }, + image: { wmin: 100 }, + sponsoredBy: { } + }, + params: { + cp: 'p10000', + ct: 't10000' + } + } + ] + }; }); afterEach(() => { @@ -45,48 +63,72 @@ describe('PulsePoint Lite Adapter Tests', () => { it('Verify requests sent to PulsePoint', () => { pulsepointAdapter.callBids(slotConfigs); - var call = parseURL(ajaxStub.firstCall.args[0]).search; + expect(ajaxStub.callCount).to.equal(1); + expect(ajaxStub.firstCall.args[0]).to.equal('http://bid.contextweb.com/header/ortb'); + const ortbRequest = JSON.parse(ajaxStub.firstCall.args[2]); + // site object + expect(ortbRequest.site).to.not.equal(null); + expect(ortbRequest.site.publisher).to.not.equal(null); + expect(ortbRequest.site.publisher.id).to.equal('p10000'); + expect(ortbRequest.site.ref).to.equal(window.top.document.referrer); + expect(ortbRequest.site.page).to.equal(getTopWindowLocation().href); + expect(ortbRequest.imp).to.have.lengthOf(2); + // device object + expect(ortbRequest.device).to.not.equal(null); + expect(ortbRequest.device.ua).to.equal(navigator.userAgent); // slot 1 - // expect(call.cp).to.equal('p10000'); - // expect(call.ct).to.equal('t10000'); - // expect(call.cf).to.equal('300x250'); - expect(call.ca).to.equal('BID'); - expect(call.cn).to.equal('1'); + expect(ortbRequest.imp[0].tagid).to.equal('t10000'); + expect(ortbRequest.imp[0].banner).to.not.equal(null); + expect(ortbRequest.imp[0].banner.w).to.equal(300); + expect(ortbRequest.imp[0].banner.h).to.equal(250); // slot 2 - call = parseURL(ajaxStub.secondCall.args[0]).search; - // expect(call.cp).to.equal('p20000'); - // expect(call.ct).to.equal('t20000'); - // expect(call.cf).to.equal('728x90'); - expect(call.ca).to.equal('BID'); - expect(call.cn).to.equal('1'); + expect(ortbRequest.imp[1].tagid).to.equal('t20000'); + expect(ortbRequest.imp[1].banner).to.not.equal(null); + expect(ortbRequest.imp[1].banner.w).to.equal(728); + expect(ortbRequest.imp[1].banner.h).to.equal(90); }); it('Verify bid', () => { pulsepointAdapter.callBids(slotConfigs); // trigger a mock ajax callback with bid. + const ortbRequest = JSON.parse(ajaxStub.firstCall.args[2]); ajaxStub.firstCall.args[1](JSON.stringify({ - html: 'This is an Ad', - bidCpm: 1.25 + seatbid: [{ + bid: [{ + impid: ortbRequest.imp[0].id, + price: 1.25, + adm: 'This is an Ad' + }] + }] })); + expect(bidManager.addBidResponse.callCount).to.equal(2); + // verify first bid let placement = bidManager.addBidResponse.firstCall.args[0]; let bid = bidManager.addBidResponse.firstCall.args[1]; expect(placement).to.equal('/DfpAccount1/slot1'); - expect(bid.bidderCode).to.equal('pulsepoint'); + expect(bid.bidderCode).to.equal('pulseLite'); expect(bid.cpm).to.equal(1.25); expect(bid.ad).to.equal('This is an Ad'); - expect(bid.width).to.equal('300'); - expect(bid.height).to.equal('250'); + expect(bid.width).to.equal(300); + expect(bid.height).to.equal(250); expect(bid.adId).to.equal('bid12345'); + // verify passback on 2nd impression. + placement = bidManager.addBidResponse.secondCall.args[0]; + bid = bidManager.addBidResponse.secondCall.args[1]; + expect(placement).to.equal('/DfpAccount2/slot2'); + expect(bid.adId).to.equal('bid23456'); + expect(bid.bidderCode).to.equal('pulseLite'); + expect(bid.cpm).to.be.undefined; }); - it('Verify passback', () => { + it('Verify full passback', () => { pulsepointAdapter.callBids(slotConfigs); // trigger a mock ajax callback with no bid. ajaxStub.firstCall.args[1](null); let placement = bidManager.addBidResponse.firstCall.args[0]; let bid = bidManager.addBidResponse.firstCall.args[1]; expect(placement).to.equal('/DfpAccount1/slot1'); - expect(bid.bidderCode).to.equal('pulsepoint'); + expect(bid.bidderCode).to.equal('pulseLite'); expect(bid).to.not.have.property('ad'); expect(bid).to.not.have.property('cpm'); expect(bid.adId).to.equal('bid12345'); @@ -98,9 +140,90 @@ describe('PulsePoint Lite Adapter Tests', () => { let placement = bidManager.addBidResponse.firstCall.args[0]; let bid = bidManager.addBidResponse.firstCall.args[1]; expect(placement).to.equal('/DfpAccount1/slot1'); - expect(bid.bidderCode).to.equal('pulsepoint'); + expect(bid.bidderCode).to.equal('pulseLite'); expect(bid).to.not.have.property('ad'); expect(bid).to.not.have.property('cpm'); expect(bid.adId).to.equal('bid12345'); }); + + it('Verify Native request', () => { + pulsepointAdapter.callBids(nativeSlotConfig); + expect(ajaxStub.callCount).to.equal(1); + expect(ajaxStub.firstCall.args[0]).to.equal('http://bid.contextweb.com/header/ortb'); + const ortbRequest = JSON.parse(ajaxStub.firstCall.args[2]); + // native impression + expect(ortbRequest.imp[0].tagid).to.equal('t10000'); + expect(ortbRequest.imp[0].banner).to.equal(null); + expect(ortbRequest.imp[0].native).to.not.equal(null); + expect(ortbRequest.imp[0].native.ver).to.equal('1.1'); + expect(ortbRequest.imp[0].native.request).to.not.equal(null); + // native request assets + const nativeRequest = JSON.parse(ortbRequest.imp[0].native.request); + expect(nativeRequest).to.not.equal(null); + expect(nativeRequest.assets).to.have.lengthOf(3); + // title asset + expect(nativeRequest.assets[0].id).to.equal(1); + expect(nativeRequest.assets[0].required).to.equal(1); + expect(nativeRequest.assets[0].title).to.not.equal(null); + expect(nativeRequest.assets[0].title.len).to.equal(200); + // data asset + expect(nativeRequest.assets[1].id).to.equal(2); + expect(nativeRequest.assets[1].required).to.equal(0); + expect(nativeRequest.assets[1].title).to.be.undefined; + expect(nativeRequest.assets[1].data).to.not.equal(null); + expect(nativeRequest.assets[1].data.type).to.equal(1); + expect(nativeRequest.assets[1].data.len).to.equal(50); + // image asset + expect(nativeRequest.assets[2].id).to.equal(3); + expect(nativeRequest.assets[2].required).to.equal(0); + expect(nativeRequest.assets[2].title).to.be.undefined; + expect(nativeRequest.assets[2].img).to.not.equal(null); + expect(nativeRequest.assets[2].img.wmin).to.equal(100); + expect(nativeRequest.assets[2].img.hmin).to.equal(150); + expect(nativeRequest.assets[2].img.type).to.equal(3); + }); + + it('Verify Native response', () => { + pulsepointAdapter.callBids(nativeSlotConfig); + expect(ajaxStub.callCount).to.equal(1); + expect(ajaxStub.firstCall.args[0]).to.equal('http://bid.contextweb.com/header/ortb'); + const ortbRequest = JSON.parse(ajaxStub.firstCall.args[2]); + const nativeResponse = { + native: { + assets: [ + { title: { text: 'Ad Title'} }, + { data: { type: 1, value: 'Sponsored By: Brand' }}, + { img: { type: 3, url: 'http://images.cdn.brand.com/123' } } + ], + link: { url: 'http://brand.clickme.com/' }, + imptrackers: [ 'http://imp1.trackme.com/', 'http://imp1.contextweb.com/' ] + } + }; + ajaxStub.firstCall.args[1](JSON.stringify({ + seatbid: [{ + bid: [{ + impid: ortbRequest.imp[0].id, + price: 1.25, + adm: JSON.stringify(nativeResponse) + }] + }] + })); + // verify bid + let placement = bidManager.addBidResponse.firstCall.args[0]; + let bid = bidManager.addBidResponse.firstCall.args[1]; + expect(placement).to.equal('/DfpAccount1/slot3'); + expect(bid.bidderCode).to.equal('pulseLite'); + expect(bid.cpm).to.equal(1.25); + expect(bid.adId).to.equal('bid12345'); + expect(bid.ad).to.be.undefined; + expect(bid.mediaType).to.equal('native'); + expect(bid.native).to.not.equal(null); + expect(bid.native.title).to.equal('Ad Title'); + expect(bid.native.sponsoredBy).to.equal('Sponsored By: Brand'); + expect(bid.native.image).to.equal('http://images.cdn.brand.com/123'); + expect(bid.native.clickUrl).to.equal(encodeURIComponent('http://brand.clickme.com/')); + expect(bid.native.impressionTrackers).to.have.lengthOf(2); + expect(bid.native.impressionTrackers[0]).to.equal('http://imp1.trackme.com/'); + expect(bid.native.impressionTrackers[1]).to.equal('http://imp1.contextweb.com/'); + }); }); From 17a0b7919da94d5e7adec23be0b975cff509014e Mon Sep 17 00:00:00 2001 From: Niksok Date: Fri, 14 Jul 2017 19:05:42 +0300 Subject: [PATCH 73/95] Centro adapter fix: do not call logError if 'No Bid' was received (#1265) * Add centro adapter and tests for it. * fix bug with different types of bid.sectionID and bid.unit from config * add query parameter adapter=prebid * update tests for centro adapter * fixed bug with call of JSONP callback with name, that contain invalid characters * Centro adapter fix: do not call logError if 'No Bid' was received * Centro adapter: pass the bid request object to bidfactory.createBid * Centro adapter: fix ESLintError --- modules/centroBidAdapter.js | 38 ++++++++++++---------- test/spec/modules/centroBidAdapter_spec.js | 7 ++-- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/modules/centroBidAdapter.js b/modules/centroBidAdapter.js index 5a04f330820..0a218b57f64 100644 --- a/modules/centroBidAdapter.js +++ b/modules/centroBidAdapter.js @@ -19,22 +19,21 @@ var CentroAdapter = function CentroAdapter() { unitNum: 'Requested unit is ' }; - function _makeHandler(handlerName, unit, placementCode) { + function _makeHandler(handlerName, unit, requestedBid) { return function(response) { try { delete window[handlerName]; } catch (err) { // catching for old IE window[handlerName] = undefined; } - _responseProcessing(response, unit, placementCode); + _responseProcessing(response, unit, requestedBid); }; } - function _sendBidRequest(bid) { - var placementCode = bid.placementCode, - size = bid.sizes && bid.sizes[0]; + function _sendBidRequest(requestedBid) { + var bid, size = requestedBid.sizes && requestedBid.sizes[0]; - bid = bid.params; + bid = requestedBid.params; if (!bid.unit) { // throw exception, or call utils.logError utils.logError(LOG_ERROR_MESS.noUnit, bidderCode); @@ -54,13 +53,13 @@ var CentroAdapter = function CentroAdapter() { query.push('sz=' + size.join('x')); } // make handler name for JSONP request - var handlerName = handlerPrefix + bid.unit + size.join('x') + encodeURIComponent(placementCode); + var handlerName = handlerPrefix + bid.unit + size.join('x') + encodeURIComponent(requestedBid.placementCode); query.push('callback=' + encodeURIComponent('window["' + handlerName + '"]')); // maybe is needed add some random parameter to disable cache // query.push('r='+Math.round(Math.random() * 1e5)); - window[handlerName] = _makeHandler(handlerName, bid.unit, placementCode); + window[handlerName] = _makeHandler(handlerName, bid.unit, requestedBid); adloader.loadScript((document.location.protocol === 'https:' ? 'https:' : 'http:') + (isDev ? devUrl : baseUrl) + '?' + query.join('&')); } @@ -72,23 +71,26 @@ var CentroAdapter = function CentroAdapter() { "value": 3.2, "adTag":'' */ - function _responseProcessing(resp, unit, placementCode) { + function _responseProcessing(resp, unit, requestedBid) { var bidObject; var bid = resp && resp.bid || resp; - if (bid && bid.adTag && bid.sectionID && bid.sectionID.toString() === unit.toString()) { - bidObject = bidfactory.createBid(1); - bidObject.cpm = bid.value; - bidObject.ad = bid.adTag; - bidObject.width = bid.width; - bidObject.height = bid.height; + if (bid && (bid.adTag || bid.statusMessage === 'No bid') && bid.sectionID && bid.sectionID.toString() === unit.toString()) { + if (bid.adTag) { + bidObject = bidfactory.createBid(1, requestedBid); + bidObject.cpm = bid.value; + bidObject.ad = bid.adTag; + bidObject.width = bid.width; + bidObject.height = bid.height; + } else { + bidObject = bidfactory.createBid(2, requestedBid); + } } else { // throw exception, or call utils.logError with resp.statusMessage utils.logError(LOG_ERROR_MESS.unitNum + unit + '. ' + (bid ? bid.statusMessage || LOG_ERROR_MESS.noAdTag : LOG_ERROR_MESS.noBid), bidderCode); - bidObject = bidfactory.createBid(2); + bidObject = bidfactory.createBid(2, requestedBid); } - bidObject.bidderCode = bidderCode; - bidmanager.addBidResponse(placementCode, bidObject); + bidmanager.addBidResponse(requestedBid.placementCode, bidObject); } /* diff --git a/test/spec/modules/centroBidAdapter_spec.js b/test/spec/modules/centroBidAdapter_spec.js index d508c2c355d..9f354e1ba56 100644 --- a/test/spec/modules/centroBidAdapter_spec.js +++ b/test/spec/modules/centroBidAdapter_spec.js @@ -176,7 +176,7 @@ describe('centro adapter tests', function () { $$PREBID_GLOBAL$$.adUnits = adUnits; var response = {'adTag': '
test content
', 'statusMessage': 'Bid available', 'height': 250, '_comment': '', 'value': 0.2, 'width': 300, 'sectionID': 28136}; - var response2 = {'adTag': '', 'statusMessage': 'No bid.', 'height': 0, 'value': 0, 'width': 0, 'sectionID': 111111}; + var response2 = {'adTag': '', 'statusMessage': 'No bid', 'height': 0, 'value': 0, 'width': 0, 'sectionID': 111111}; var response3 = {'adTag': '', 'height': 0, 'value': 0, 'width': 0, 'sectionID': 222222}; var response4 = ''; @@ -194,9 +194,8 @@ describe('centro adapter tests', function () { var bidPlacementCode4 = stubAddBidResponse.getCall(3).args[0]; var bidObject4 = stubAddBidResponse.getCall(3).args[1]; - expect(logErrorSpy.getCall(0).args[0]).to.equal('Requested unit is 111111. No bid.'); - expect(logErrorSpy.getCall(1).args[0]).to.equal('Requested unit is 222222. Bid has missmatch format.'); - expect(logErrorSpy.getCall(2).args[0]).to.equal('Requested unit is 333333. Response has no bid.'); + expect(logErrorSpy.getCall(0).args[0]).to.equal('Requested unit is 222222. Bid has missmatch format.'); + expect(logErrorSpy.getCall(1).args[0]).to.equal('Requested unit is 333333. Response has no bid.'); expect(bidPlacementCode1).to.equal('/19968336/header-bid-tag-0'); expect(bidObject1.cpm).to.equal(0.2); From 48be7306428d94afa89ac6f39b7cfdb58e5bb1da Mon Sep 17 00:00:00 2001 From: Rich Snapp Date: Fri, 14 Jul 2017 13:52:54 -0600 Subject: [PATCH 74/95] register google analytics after methods attached (#1382) --- modules/googleAnalyticsAdapter.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/googleAnalyticsAdapter.js b/modules/googleAnalyticsAdapter.js index 816fa9e5952..2993697c09d 100644 --- a/modules/googleAnalyticsAdapter.js +++ b/modules/googleAnalyticsAdapter.js @@ -22,11 +22,6 @@ var _enableDistribution = false; var _trackerSend = null; var _sampled = true; -adaptermanager.registerAnalyticsAdapter({ - adapter: exports, - code: 'ga' -}); - /** * This will enable sending data to google analytics. Only call once, or duplicate data will be sent! * @param {object} provider use to set GA global (if renamed); @@ -256,3 +251,8 @@ function sendBidWonToGa(bid) { checkAnalytics(); } + +adaptermanager.registerAnalyticsAdapter({ + adapter: exports, + code: 'ga' +}); From 55ae941fab2209ef665737335df172f8fc7e9441 Mon Sep 17 00:00:00 2001 From: Matt Lane Date: Mon, 17 Jul 2017 06:46:24 -0700 Subject: [PATCH 75/95] Add support for publisher-defined outstream renderers (#1357) --- src/adaptermanager.js | 1 + src/bidmanager.js | 16 +++++++++++++--- test/spec/bidmanager_spec.js | 22 ++++++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/adaptermanager.js b/src/adaptermanager.js index 579aa7d9510..004c8d6fac6 100644 --- a/src/adaptermanager.js +++ b/src/adaptermanager.js @@ -42,6 +42,7 @@ function getBids({bidderCode, requestId, bidderRequestId, adUnits}) { return Object.assign({}, bid, { placementCode: adUnit.code, mediaType: adUnit.mediaType, + renderer: adUnit.renderer, transactionId: adUnit.transactionId, sizes: sizes, bidId: bid.bid_id || utils.getUniqueIdentifierStr(), diff --git a/src/bidmanager.js b/src/bidmanager.js index 0c18f9fe27c..cd910c54524 100644 --- a/src/bidmanager.js +++ b/src/bidmanager.js @@ -2,6 +2,7 @@ import { uniques, flatten, adUnitsFilter, getBidderRequest } from './utils'; import {getPriceBucketString} from './cpmBucketManager'; import {NATIVE_KEYS, nativeBidIsValid} from './native'; import { store } from './videoCache'; +import { Renderer } from 'src/Renderer'; var CONSTANTS = require('./constants.json'); var AUCTION_END = CONSTANTS.EVENTS.AUCTION_END; @@ -134,12 +135,12 @@ exports.addBidResponse = function (adUnitCode, bid) { // This must be fired first, so that we calculate derived values from the updates events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, bid); - const { requestId, start } = getBidderRequest(bid.bidderCode, adUnitCode); + const bidRequest = getBidderRequest(bid.bidderCode, adUnitCode); Object.assign(bid, { - requestId: requestId, + requestId: bidRequest.requestId, responseTimestamp: timestamp(), - requestTimestamp: start, + requestTimestamp: bidRequest.start, cpm: parseFloat(bid.cpm) || 0, bidder: bid.bidderCode, adUnitCode @@ -147,6 +148,15 @@ exports.addBidResponse = function (adUnitCode, bid) { bid.timeToRespond = bid.responseTimestamp - bid.requestTimestamp; + // a publisher-defined renderer can be used to render bids + const adUnitRenderer = + bidRequest.bids && bidRequest.bids[0] && bidRequest.bids[0].renderer; + + if (adUnitRenderer) { + bid.renderer = Renderer.install({ url: adUnitRenderer.url }); + bid.renderer.setRender(adUnitRenderer.render); + } + const priceStringsObj = getPriceBucketString(bid.cpm, _customPriceBucket); bid.pbLg = priceStringsObj.low; bid.pbMg = priceStringsObj.med; diff --git a/test/spec/bidmanager_spec.js b/test/spec/bidmanager_spec.js index ae83a8d106f..d47d207c4d5 100644 --- a/test/spec/bidmanager_spec.js +++ b/test/spec/bidmanager_spec.js @@ -533,5 +533,27 @@ describe('bidmanager.js', function () { utils.getBidRequest.restore(); }); + + it('installs publisher-defined renderers on bids', () => { + sinon.stub(utils, 'getBidderRequest', () => ({ + bids: [{ + renderer: { + url: 'renderer.js', + render: (bid) => bid + } + }] + })); + + const bid = Object.assign({}, bidfactory.createBid(1), { + bidderCode: 'appnexusAst', + mediaType: 'video-outstream', + }); + + bidmanager.addBidResponse('adUnit-code', bid); + const addedBid = $$PREBID_GLOBAL$$._bidsReceived.pop(); + assert.equal(addedBid.renderer.url, 'renderer.js'); + + utils.getBidderRequest.restore(); + }); }); }); From 2c8ec162f086322597a9c34165c1d342cd3f869a Mon Sep 17 00:00:00 2001 From: Prebid-Team Date: Mon, 17 Jul 2017 16:19:17 +0000 Subject: [PATCH 76/95] Added CPM value as parameter for Vertoz Adapter (#1306) * Added CPM for user input * changed variable name from cpm to cpmFloor --- modules/vertozBidAdapter.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/vertozBidAdapter.js b/modules/vertozBidAdapter.js index 77731cbc2fa..35c92b40ad1 100755 --- a/modules/vertozBidAdapter.js +++ b/modules/vertozBidAdapter.js @@ -20,6 +20,7 @@ function VertozAdapter() { let vzEndPoint = BASE_URI; let reqParams = bid.params || {}; let placementId = utils.getValue(reqParams, 'placementId'); + let cpm = utils.getValue(reqParams, 'cpmFloor'); if (utils.isEmptyStr(placementId)) { utils.logError('missing params:', BIDDER_NAME, 'Enter valid vzPlacementId'); @@ -31,8 +32,10 @@ function VertozAdapter() { _vzPlacementId: placementId, _rqsrc: reqSrc, _cb: cb, - _slotBidId: slotBidId + _slotBidId: slotBidId, + _cpm: cpm }; + let queryParamValue = JSON.stringify(vzReq); vzEndPoint = utils.tryAppendQueryString(vzEndPoint, QUERY_PARAM_KEY, queryParamValue); adloader.loadScript(vzEndPoint); From e748bef965a8550b203bdf8f9c3929966f251d3d Mon Sep 17 00:00:00 2001 From: guillaume-sticky Date: Mon, 17 Jul 2017 18:54:20 +0200 Subject: [PATCH 77/95] StickyAdsTV bidder adapter update (#1311) * add stickyadsTV bidder adapter * init unit test file * ad some unit tests * fix unit test on ad format with parameters * add some unit tests * add unit tests on getBid method * add some test cases in unit tests * minor fix on component id tag. * remove adapters-sticky.json test file * use top most accessible window instead of window.top * Pass in the bid request in the createBid call. * use top most accessible window instead of window.top * add unit tests * update unit tests * fix unit test. * fix CI build * add alias freewheel-ssp * update unit tests on bidderCode value * fix component id values and add unit tests * allws to use any outstream format. * fix ASLoader on futur outstream format versions * minor: fix code format. * update unit tests * minor fix code format * minor: add missing new line at eof --- modules/stickyadstvBidAdapter.js | 90 +++++++++---------- .../modules/stickyadstvBidAdapter_spec.js | 31 +++++-- 2 files changed, 67 insertions(+), 54 deletions(-) diff --git a/modules/stickyadstvBidAdapter.js b/modules/stickyadstvBidAdapter.js index 27ebb4ef31a..c8936e11601 100644 --- a/modules/stickyadstvBidAdapter.js +++ b/modules/stickyadstvBidAdapter.js @@ -8,8 +8,7 @@ var adaptermanager = require('src/adaptermanager'); var StickyAdsTVAdapter = function StickyAdsTVAdapter() { var STICKYADS_BIDDERCODE = 'stickyadstv'; var MUSTANG_URL = '//cdn.stickyadstv.com/mustang/mustang.min.js'; - var INTEXTROLL_URL = '//cdn.stickyadstv.com/prime-time/intext-roll.min.js'; - var SCREENROLL_URL = '//cdn.stickyadstv.com/prime-time/screen-roll.min.js'; + var OUTSTREAM_URL = '//cdn.stickyadstv.com/prime-time/[COMP-ID].min.js'; var topMostWindow = getTopMostWindow(); topMostWindow.stickyadstv_cache = {}; @@ -34,11 +33,9 @@ var StickyAdsTVAdapter = function StickyAdsTVAdapter() { var integrationType = bid.params.format ? bid.params.format : 'inbanner'; var urltoLoad = MUSTANG_URL; - if (integrationType === 'intext-roll') { - urltoLoad = INTEXTROLL_URL; - } - if (integrationType === 'screen-roll') { - urltoLoad = SCREENROLL_URL; + if (integrationType !== 'inbanner') { + // integration types are equals to component ids + urltoLoad = OUTSTREAM_URL.replace('[COMP-ID]', integrationType); } var bidRegistered = false; @@ -56,6 +53,12 @@ var StickyAdsTVAdapter = function StickyAdsTVAdapter() { var zoneId = bid.params.zoneId || bid.params.zone; // accept both var size = getBiggerSize(bid.sizes); + // some of our formats doesn't have tools API exposed + var toolsAPI = window.com.stickyadstv.tools; + if (toolsAPI && toolsAPI.ASLoader) { + topMostWindow.stickyadstv_asLoader = new toolsAPI.ASLoader(zoneId, getComponentId(bid.params.format)); + } + var vastLoader = new window.com.stickyadstv.vast.VastLoader(); bid.vast = topMostWindow.stickyadstv_cache[bid.placementCode] = vastLoader.getVast(); @@ -79,17 +82,36 @@ var StickyAdsTVAdapter = function StickyAdsTVAdapter() { zoneId: zoneId, playerSize: size[0] + 'x' + size[1], vastUrlParams: bid.params.vastUrlParams, - componentId: 'prebid-sticky' + (bid.params.format ? '-' + bid.params.format : '') + componentId: getComponentId(bid.params.format) }; - if (bid.params.format === 'screen-roll') { - // in screenroll case we never use the original div size. - config.playerSize = window.com.stickyadstv.screenroll.getPlayerSize(); + var api = window.com.stickyadstv[getAPIName(bid.params.format)]; + if (api && typeof api.getPlayerSize === 'function') { + // in screenroll and similar cases we don't use the original div size. + config.playerSize = api.getPlayerSize(); } vastLoader.load(config, vastCallback); } + function getComponentId(inputFormat) { + var component = 'mustang'; // default component id + + if (inputFormat && inputFormat !== 'inbanner') { + // format identifiers are equals to their component ids. + component = inputFormat; + } + + return component; + } + + function getAPIName(componentId) { + componentId = componentId || ''; + + // remove dash in componentId to get API name + return componentId.replace('-', ''); + } + function getBiggerSize(array) { var result = [1, 1]; for (var i = 0; i < array.length; i++) { @@ -114,6 +136,7 @@ var StickyAdsTVAdapter = function StickyAdsTVAdapter() { ' autoPlay:true' + '};' + 'var ad = new topWindow.com.stickyadstv.vpaid.Ad(document.getElementById("stickyadstv_prebid_target"),config);' + + 'if(topWindow.stickyadstv_asLoader) topWindow.stickyadstv_asLoader.registerEvents(ad);' + 'ad.initAd(' + size[0] + ',' + size[1] + ',"",0,"","");' + ''; @@ -121,7 +144,7 @@ var StickyAdsTVAdapter = function StickyAdsTVAdapter() { return divHtml + script; }; - var formatIntextHTML = function(bid) { + var formatOutstreamHTML = function(bid) { var placementCode = bid.placementCode; var config = bid.params; @@ -136,7 +159,8 @@ var StickyAdsTVAdapter = function StickyAdsTVAdapter() { 'var topWindow = (function(){var res=window; try{while(top != res){if(res.parent.location.href.length)res=res.parent;}}catch(e){}return res;})();' + 'var vast = topWindow.stickyadstv_cache["' + placementCode + '"];' + 'var config = {' + - ' preloadedVast:vast'; + ' preloadedVast:vast,' + + ' ASLoader:topWindow.stickyadstv_asLoader'; for (var key in config) { // dont' send format parameter @@ -147,50 +171,20 @@ var StickyAdsTVAdapter = function StickyAdsTVAdapter() { } script += '};' + - 'topWindow.com.stickyadstv.intextroll.start(config);' + + 'topWindow.com.stickyadstv.' + getAPIName(bid.params.format) + '.start(config);' + ''; return script; }; - var formatScreenRollHTML = function(bid) { - var placementCode = bid.placementCode; - - var config = bid.params; - - var script = "'; - - return script; - }; function formatAdHTML(bid, size) { var integrationType = bid.params.format; var html = ''; - if (integrationType === 'intext-roll') { - html = formatIntextHTML(bid); - } else if (integrationType === 'screen-roll') { - html = formatScreenRollHTML(bid); + if (integrationType && integrationType !== 'inbanner') { + html = formatOutstreamHTML(bid); } else { html = formatInBannerHTML(bid, size); } @@ -202,7 +196,7 @@ var StickyAdsTVAdapter = function StickyAdsTVAdapter() { var priceData = vast.getPricing(); if (!priceData) { - utils.logWarn("StickyAdsTV: Bid pricing Can't be retreived. You may need to enable pricing on you're zone. Please get in touch with your sticky contact."); + console.warn("freewheel-ssp: Bid pricing Can't be retreived. You may need to enable pricing on you're zone. Please get in touch with your Freewheel contact."); } return priceData; @@ -265,6 +259,8 @@ var StickyAdsTVAdapter = function StickyAdsTVAdapter() { getBiggerSize: getBiggerSize, getBid: getBid, getTopMostWindow: getTopMostWindow, + getComponentId: getComponentId, + getAPIName: getAPIName, createNew: StickyAdsTVAdapter.createNew // enable alias feature (to be used for freewheel-ssp alias) }); }; diff --git a/test/spec/modules/stickyadstvBidAdapter_spec.js b/test/spec/modules/stickyadstvBidAdapter_spec.js index f9d98ce3ae2..c0f35b1c406 100644 --- a/test/spec/modules/stickyadstvBidAdapter_spec.js +++ b/test/spec/modules/stickyadstvBidAdapter_spec.js @@ -124,9 +124,9 @@ describe('StickyAdsTV Adapter', function () { delete window.com.stickyadstv; }); - it('should have returned a valid bidObject', function () { + it('should return a valid bidObject', function () { expect(bidResponse).to.have.property('cpm', 4.000); - expect(bidResponse).to.have.property('ad', ""); + expect(bidResponse).to.have.property('ad', ""); expect(bidResponse).to.have.property('bidderCode', 'stickyadstv'); expect(bidResponse).to.have.property('currencyCode', 'USD'); expect(bidResponse).to.have.property('width', 300); @@ -173,24 +173,24 @@ describe('StickyAdsTV Adapter', function () { it('should create an inBanner ad format', function () { let result = adapter.formatAdHTML({placementCode: 'placementCodeValue', params: {}}, [200, 300]); - expect(result).to.equal('
'); + expect(result).to.equal('
'); }); it('should create an intext ad format', function () { let result = adapter.formatAdHTML({placementCode: 'placementCodeValue', params: {format: 'intext-roll', auto: 'v2', smartPlay: 'true'}}, [200, 300]); - expect(result).to.equal(''); + expect(result).to.equal(''); }); it('should create a screenroll ad format', function () { let result = adapter.formatAdHTML({placementCode: 'placementCodeValue', params: {format: 'screen-roll', smartPlay: 'true'}}, [200, 300]); - expect(result).to.equal(''); + expect(result).to.equal(''); }); }); describe('getBiggerSize', function () { - it('should returns the bigger size', function () { + it('should return the bigger size', function () { let result = adapter.getBiggerSize([[1, 4000], [4000, 1], [200, 300], [0, 0]]); expect(result[0]).to.equal(200); @@ -199,10 +199,27 @@ describe('StickyAdsTV Adapter', function () { }); describe('top most window', function () { - it('should returns the top most window', function () { + it('should return the top most window', function () { let result = adapter.getTopMostWindow(); expect(result).to.equal(window.top); }); }); + + describe('get component id', function() { + it('should return valid component ids', function() { + expect(adapter.getComponentId('inbanner')).to.equal('mustang'); + expect(adapter.getComponentId('intext-roll')).to.equal('intext-roll'); + expect(adapter.getComponentId('screen-roll')).to.equal('screen-roll'); + }); + }); + + describe('get API name', function() { + it('should return valid API names', function() { + expect(adapter.getAPIName()).to.equal(''); + expect(adapter.getAPIName('intext-roll')).to.equal('intextroll'); + expect(adapter.getAPIName('screen-roll')).to.equal('screenroll'); + expect(adapter.getAPIName('floorad')).to.equal('floorad'); + }); + }); }); From 4b04890723aeb280b84a37175ab0015aa82e912e Mon Sep 17 00:00:00 2001 From: dbemiller Date: Mon, 17 Jul 2017 13:23:42 -0400 Subject: [PATCH 78/95] Modernizing build dependencies (#1355) * Upgraded webpack, as well as some minor other build dependencies. * Updated the yarn.lock file * Migrated the module loaders to the 3.0 syntax. * Ran yarn install. Moved the loader order around a bit. * Made the unit tests and code coverage reports work with the new versions. * Removed some unused lines, and fixed the coveralls task file location. * Fixed the gulp coverage task so that it points to the right folder. * Removed the JUnit reporter, which nobody seems to have reason to keep anymore. * Removed the CI_MODE flag, and removed progress. This should help clean up the browserstack logs. * Fixed gulp serve. * Updated some more dependencies. * Upgraded node to use version 7. * Split gulp test and gulp test-coverage, so we can run tests without instrumnetation. * Updated the yarn.lock * Removed ie9 from the test browsers, since we dont support it anymore. * Updated more dev dependency versions. * Made travis use HeadlessChrome. Removed some extraneous code that nobody needs anymore. * Better code reuse for launching browser tests. * updated the yarn.lock file. * Fixed a bug in the karma server callbacks, and made the logs from browserstack look good again. * Added source maps, so that the line numbers on failed unit tests are right. * Fixed a bug in the reporters code which causes Travis to fail. * Updated README and some code style fixes. * Fixed --watch, as well as a concurrency bug where several files mutate the webpack.conf file. * Removed another unused dependency. * Fixed the imports. * Replaced all the src/file imports with ./file imports, to make things consistent --- .nvmrc | 2 +- .travis.yml | 14 +- README.md | 37 +- browsers.json | 4 - gulpfile.js | 117 +- karma.conf.js | 136 --- karma.conf.maker.js | 154 +++ package.json | 48 +- src/AnalyticsAdapter.js | 10 +- src/Renderer.js | 4 +- src/adServerManager.js | 4 +- src/cookie.js | 4 +- src/prebid.js | 2 +- src/targeting.js | 6 +- src/utils.js | 2 +- webpack.conf.js | 66 +- yarn.lock | 2324 +++++++++++++++++---------------------- 17 files changed, 1298 insertions(+), 1636 deletions(-) delete mode 100644 karma.conf.js create mode 100644 karma.conf.maker.js diff --git a/.nvmrc b/.nvmrc index a75b92f1ed7..4fedf1d20e1 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -5.1 +7.0 diff --git a/.travis.yml b/.travis.yml index 8addbe93b94..73b5de5ae4a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,23 +1,17 @@ -sudo: required dist: trusty language: node_js node_js: - - "5.1" + - "7.0" +# See https://docs.travis-ci.com/user/gui-and-headless-browsers/#Using-the-Chrome-addon-in-the-headless-mode addons: - apt: - sources: - - google-chrome - packages: - - google-chrome-stable + chrome: stable before_install: - npm install -g gulp - - export CHROME_BIN=google-chrome - - export DISPLAY=:99.0 - - sh -e /etc/init.d/xvfb start + - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost & script: - gulp run-tests diff --git a/README.md b/README.md index ce51b04515f..023d08cd2a3 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,26 @@ Having said that, you are probably safe to check your custom bundle into your pr ## Test locally -To configure Prebid.js to run locally, edit the example file `./integrationExamples/gpt/pbjs_example_gpt.html`: +To lint the code: + +```bash +gulp lint +``` + +To run the unit tests: + +```bash +gulp test +``` + +To generate and view the code coverage reports: + +```bash +gulp test-coverage +gulp view-coverage +``` + +For end-to-end testing, edit the example file `./integrationExamples/gpt/pbjs_example_gpt.html`: 1. Change `{id}` values appropriately to set up ad units and bidders 2. Set the path to Prebid.js in your example file as shown below (see `pbs.src`). @@ -131,21 +150,21 @@ For deployment: })(); ``` -To run the project locally, use: +Build and run the project locally with: - $ gulp serve +```bash +gulp serve +``` -This runs code quality checks, generates all the necessary files and starts a web server at `http://localhost:9999` serving from the project root. Navigate to your example implementation to test, and if your `prebid.js` file is sourced from the `./build/dev` directory you will have sourcemaps available in your browser's developer tools. +This runs `lint` and `test`, then starts a web server at `http://localhost:9999` serving from the project root. +Navigate to your example implementation to test, and if your `prebid.js` file is sourced from the `./build/dev` +directory you will have sourcemaps available in your browser's developer tools. To run the example file, go to: + `http://localhost:9999/integrationExamples/gpt/pbjs_example_gpt.html` -To view a test coverage report, go to: - -+ `http://localhost:9999/build/coverage/karma_html/report` - -A watch is also in place that will run continuous tests in the terminal as you edit code and tests. +As you make code changes, the bundles will be rebuilt and the page reloaded automatically. diff --git a/browsers.json b/browsers.json index 4c753fe7072..2dc6f1ddf90 100644 --- a/browsers.json +++ b/browsers.json @@ -214,9 +214,5 @@ "browser": "iphone", "device": "iPhone 6S", "browser_version": null - }, - "Chrome_travis_ci": { - "base": "Chrome", - "flags": ["--no-sandbox"] } } diff --git a/gulpfile.js b/gulpfile.js index cc0a49e1cfd..9b5742cb180 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -3,15 +3,17 @@ var _ = require('lodash'); var argv = require('yargs').argv; var gulp = require('gulp'); -var argv = require('yargs').argv; var gutil = require('gulp-util'); var connect = require('gulp-connect'); -var webpack = require('webpack-stream'); +var path = require('path'); +var webpack = require('webpack'); +var webpackStream = require('webpack-stream'); var uglify = require('gulp-uglify'); var clean = require('gulp-clean'); -var karma = require('gulp-karma'); +var KarmaServer = require('karma').Server; +var karmaConfMaker = require('./karma.conf.maker'); var opens = require('open'); -var webpackConfig = require('./webpack.conf.js'); +var webpackConfig = require('./webpack.conf'); var helpers = require('./gulpHelpers'); var del = require('del'); var gulpJsdoc2md = require('gulp-jsdoc-to-markdown'); @@ -26,10 +28,8 @@ var gulpif = require('gulp-if'); var sourcemaps = require('gulp-sourcemaps'); var fs = require('fs'); -var CI_MODE = process.env.NODE_ENV === 'ci'; var prebid = require('./package.json'); var dateString = 'Updated : ' + (new Date()).toISOString().substring(0, 10); -var packageNameVersion = prebid.name + '_' + prebid.version; var banner = '/* <%= prebid.name %> v<%= prebid.version %>\n' + dateString + ' */\n'; var analyticsDirectory = '../analytics'; var port = 9999; @@ -41,7 +41,7 @@ gulp.task('serve', ['lint', 'build-bundle-dev', 'watch', 'test']); gulp.task('serve-nw', ['lint', 'watch', 'e2etest']); -gulp.task('run-tests', ['lint', 'test']); +gulp.task('run-tests', ['lint', 'test-coverage']); gulp.task('build', ['build-bundle-prod']); @@ -86,12 +86,25 @@ function bundle(dev) { .pipe(gulp.dest('build/' + (dev ? 'dev' : 'dist'))); } +// Workaround for incompatibility between Karma & gulp callbacks. +// See https://github.com/karma-runner/gulp-karma/issues/18 for some related discussion. +function newKarmaCallback(done) { + return function (exitCode) { + if (exitCode) { + done(new Error('Karma tests failed with exit code ' + exitCode)); + } else { + done(); + } + } +} + gulp.task('build-bundle-dev', ['devpack'], bundle.bind(null, true)); gulp.task('build-bundle-prod', ['webpack'], bundle.bind(null, false)); gulp.task('bundle', bundle.bind(null, false)); // used for just concatenating pre-built files with no build step gulp.task('devpack', ['clean'], function () { - webpackConfig.devtool = 'source-map'; + var cloned = _.cloneDeep(webpackConfig); + cloned.devtool = 'source-map'; var externalModules = helpers.getArgModules(); const analyticsSources = helpers.getAnalyticsSources(analyticsDirectory); @@ -99,20 +112,21 @@ gulp.task('devpack', ['clean'], function () { return gulp.src([].concat(moduleSources, analyticsSources, 'src/prebid.js')) .pipe(helpers.nameModules(externalModules)) - .pipe(webpack(webpackConfig)) + .pipe(webpackStream(cloned, webpack)) .pipe(replace('$prebid.version$', prebid.version)) .pipe(gulp.dest('build/dev')) .pipe(connect.reload()); }); gulp.task('webpack', ['clean'], function () { + var cloned = _.cloneDeep(webpackConfig); // change output filename if argument --tag given if (argv.tag && argv.tag.length) { - webpackConfig.output.filename = 'prebid.' + argv.tag + '.js'; + cloned.output.filename = 'prebid.' + argv.tag + '.js'; } - webpackConfig.devtool = null; + delete cloned.devtool; var externalModules = helpers.getArgModules(); @@ -121,7 +135,7 @@ gulp.task('webpack', ['clean'], function () { return gulp.src([].concat(moduleSources, analyticsSources, 'src/prebid.js')) .pipe(helpers.nameModules(externalModules)) - .pipe(webpack(webpackConfig)) + .pipe(webpackStream(cloned, webpack)) .pipe(replace('$prebid.version$', prebid.version)) .pipe(uglify()) .pipe(gulpif(file => file.basename === 'prebid.js', header(banner, { prebid: prebid }))) @@ -130,80 +144,50 @@ gulp.task('webpack', ['clean'], function () { .pipe(connect.reload()); }); -// Karma Continuous Testing -// Pass your browsers by using --browsers=chrome,firefox,ie9 -// Run CI by passing --watch -gulp.task('test', ['clean'], function () { - var defaultBrowsers = CI_MODE ? ['PhantomJS'] : ['Chrome']; - var browserArgs = helpers.parseBrowserArgs(argv).map(helpers.toCapitalCase); - - if (process.env.TRAVIS) { - browserArgs = ['Chrome_travis_ci']; +// Run the unit tests. +// +// By default, this runs in headless chrome. +// +// If --watch is given, the task will re-run unit tests whenever the source code changes +// If --browserstack is given, it will run the full suite of currently supported browsers. +// If --browsers is given, browsers can be chosen explicitly. e.g. --browsers=chrome,firefox,ie9 +gulp.task('test', ['clean'], function (done) { + var karmaConf = karmaConfMaker(false, argv.browserstack, argv.watch); + + var browserOverride = helpers.parseBrowserArgs(argv).map(helpers.toCapitalCase); + if (browserOverride.length > 0) { + karmaConf.browsers = browserOverride; } - if (argv.browserstack) { - browserArgs = [ - 'bs_ie_13_windows_10', - 'bs_ie_11_windows_10', - 'bs_firefox_46_windows_10', - 'bs_chrome_51_windows_10', - 'bs_ie_11_windows_8.1', - 'bs_firefox_46_windows_8.1', - 'bs_chrome_51_windows_8.1', - 'bs_ie_10_windows_8', - 'bs_firefox_46_windows_8', - 'bs_chrome_51_windows_8', - 'bs_ie_11_windows_7', - 'bs_ie_10_windows_7', - 'bs_ie_9_windows_7', - 'bs_firefox_46_windows_7', - 'bs_chrome_51_windows_7', - 'bs_safari_9.1_mac_elcapitan', - 'bs_firefox_46_mac_elcapitan', - 'bs_chrome_51_mac_elcapitan', - 'bs_safari_8_mac_yosemite', - 'bs_firefox_46_mac_yosemite', - 'bs_chrome_51_mac_yosemite', - 'bs_safari_7.1_mac_mavericks', - 'bs_firefox_46_mac_mavericks', - 'bs_chrome_49_mac_mavericks', - 'bs_ios_7', - 'bs_ios_8', - 'bs_ios_9', - ]; - } + new KarmaServer(karmaConf, newKarmaCallback(done)).start(); +}); - return gulp.src('lookAtKarmaConfJS') - .pipe(karma({ - browsers: (browserArgs.length > 0) ? browserArgs : defaultBrowsers, - configFile: 'karma.conf.js', - action: (argv.watch) ? 'watch' : 'run' - })); +gulp.task('test-coverage', ['clean'], function(done) { + new KarmaServer(karmaConfMaker(true, false), newKarmaCallback(done)).start(); }); -// Small task to load coverage reports in the browser -gulp.task('coverage', function (done) { +// View the code coverage report in the browser. +gulp.task('view-coverage', function (done) { var coveragePort = 1999; connect.server({ - port: 1999, - root: 'build/coverage', + port: coveragePort, + root: 'build/coverage/karma_html', livereload: false }); - opens('http://localhost:' + coveragePort + '/coverage/'); + opens('http://localhost:' + coveragePort); done(); }); -gulp.task('coveralls', ['test'], function() { // 2nd arg is a dependency: 'test' must be finished +gulp.task('coveralls', ['test-coverage'], function() { // 2nd arg is a dependency: 'test' must be finished // first send results of istanbul's test coverage to coveralls.io. return gulp.src('gulpfile.js', { read: false }) // You have to give it a file, but you don't // have to read it. - .pipe(shell('cat build/coverage/lcov/lcov.info | node_modules/coveralls/bin/coveralls.js')); + .pipe(shell('cat build/coverage/lcov.info | node_modules/coveralls/bin/coveralls.js')); }); // Watch Task with Live Reload gulp.task('watch', function () { - gulp.watch([ 'src/**/*.js', 'modules/**/*.js', @@ -285,7 +269,6 @@ gulp.task('e2etest-report', function() { setTimeout(function() { opens('http://localhost:' + reportPort + '/' + targetDestinationDir.slice(2) + '/results.html'); }, 5000); - }); gulp.task('build-postbid', function() { diff --git a/karma.conf.js b/karma.conf.js deleted file mode 100644 index 97a40d8430e..00000000000 --- a/karma.conf.js +++ /dev/null @@ -1,136 +0,0 @@ -// Karma configuration -// Generated on Thu Aug 07 2014 09:45:28 GMT-0700 (PDT) -var webpackConfig = require('./webpack.conf'); -webpackConfig.module.postLoaders = [ - { - test: /\.js$/, - exclude: /(node_modules)|(test)|(integrationExamples)|(build)|polyfill.js|(src\/adapters\/analytics\/ga.js)/, - loader: 'istanbul-instrumenter' - } -]; - -// remove optimize plugin for tests -webpackConfig.plugins.pop(); - -var CI_MODE = process.env.NODE_ENV === 'ci'; - -module.exports = function (config) { - config.set({ - - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: './', - - // BrowserStack Config - browserStack: { - username: process.env.BROWSERSTACK_USERNAME, - accessKey: process.env.BROWSERSTACK_KEY - }, - - // define browsers - customLaunchers: require('./browsers.json'), - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['es5-shim', 'mocha', 'expect', 'sinon'], - - client: { - mocha: { - reporter: 'html' - } - }, - - // list of files / patterns to load in the browser - files: [ - 'test/helpers/prebidGlobal.js', - 'test/**/*_spec.js', - 'test/helpers/karma-init.js' - ], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - 'test/**/*_spec.js': ['webpack'], - 'test/helpers/prebidGlobal.js': ['webpack'], - '!test/**/*_spec.js': 'coverage', - 'src/**/*.js': ['webpack', 'coverage'] - }, - - // WebPack Related - webpack: webpackConfig, - webpackMiddleware: { - noInfo: true - }, - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: CI_MODE ? ['junit', 'coverage'] : ['progress', 'html', 'coverage'], - - // junit reporter config - junitReporter: { - outputDir: 'test' - }, - - // optionally, configure the reporter - coverageReporter: { - reporters: [ - { type: 'html', dir: './build/coverage/' }, - { type: 'text', dir: './build/coverage/' }, - { type: 'lcov', dir: './build/coverage/lcov', subdir: '.' } - ] - }, - - htmlReporter: { - outputDir: 'build/coverage/karma_html', // where to put the reports - urlFriendlyName: true, // simply replaces spaces with _ for files/dirs - reportName: 'report' // report summary filename; browser info by default - }, - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: true, - - // start these browsers - // NOTE: these get defined again in gulpfile.js for the gulp tasks - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: ['Chrome'], - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: false, - browserDisconnectTimeout : 10000, // default 2000 - browserDisconnectTolerance : 1, // default 0 - browserNoActivityTimeout : 4*60*1000, //default 10000 - captureTimeout : 4*60*1000, //default 60000 - - plugins: [ - 'karma-browserstack-launcher', - 'karma-phantomjs-launcher', - 'karma-coverage', - 'karma-es5-shim', - 'karma-mocha', - 'karma-expect', - 'karma-sinon-ie', - 'karma-webpack', - 'karma-junit-reporter', - 'karma-html-reporter', - 'karma-chrome-launcher', - 'karma-sauce-launcher', - 'karma-firefox-launcher', - 'karma-opera-launcher', - 'karma-safari-launcher', - 'karma-script-launcher', - 'karma-requirejs', - 'karma-ie-launcher' - ] - }); -}; diff --git a/karma.conf.maker.js b/karma.conf.maker.js new file mode 100644 index 00000000000..89993235bb7 --- /dev/null +++ b/karma.conf.maker.js @@ -0,0 +1,154 @@ +// This configures Karma, describing how to run the tests and where to output code coverage reports. +// +// For more information, see http://karma-runner.github.io/1.0/config/configuration-file.html + +var _ = require('lodash'); +var webpackConf = require('./webpack.conf'); +var path = require('path') +var karmaConstants = require('karma').constants; + +function newWebpackConfig(codeCoverage) { + // Make a clone here because we plan on mutating this object, and don't want parallel tasks to trample each other. + var webpackConfig = _.cloneDeep(webpackConf); + + // remove optimize plugin for tests + webpackConfig.plugins.pop() + + webpackConfig.devtool = 'inline-source-map'; + + if (codeCoverage) { + webpackConfig.module.rules.push({ + enforce: 'post', + exclude: /(node_modules)|(test)|(integrationExamples)|(build)|polyfill.js|(src\/adapters\/analytics\/ga.js)/, + loader: 'istanbul-instrumenter-loader', + test: /\.js$/ + }) + } + return webpackConfig; +} + +function newPluginsArray(browserstack) { + var plugins = [ + 'karma-chrome-launcher', + 'karma-coverage-istanbul-reporter', + 'karma-es5-shim', + 'karma-expect', + 'karma-mocha', + 'karma-requirejs', + 'karma-sinon-ie', + 'karma-sourcemap-loader', + 'karma-spec-reporter', + 'karma-webpack', + ]; + if (browserstack) { + plugins.push('karma-browserstack-launcher'); + plugins.push('karma-sauce-launcher'); + plugins.push('karma-firefox-launcher'); + plugins.push('karma-opera-launcher'); + plugins.push('karma-safari-launcher'); + plugins.push('karma-script-launcher'); + plugins.push('karma-ie-launcher'); + } + return plugins; +} + +function setReporters(karmaConf, codeCoverage, browserstack) { + // In browserstack, the default 'progress' reporter floods the logs. + // The karma-spec-reporter reports failures more concisely + if (browserstack) { + karmaConf.reporters = ['spec']; + karmaConf.specReporter = { + suppressSkipped: false, + suppressPassed: true + }; + } else { + karmaConf.reporters = ['progress']; + } + if (codeCoverage) { + karmaConf.reporters.push('coverage-istanbul'); + karmaConf.coverageIstanbulReporter = { + reports: ['html', 'lcovonly', 'text-summary'], + dir: path.join(__dirname, 'build', 'coverage'), + 'report-config': { + html: { + subdir: 'karma_html', + urlFriendlyName: true, // simply replaces spaces with _ for files/dirs + } + } + } + } +} + +function setBrowsers(karmaConf, browserstack) { + if (browserstack) { + karmaConf.browserStack = { + username: process.env.BROWSERSTACK_USERNAME, + accessKey: process.env.BROWSERSTACK_KEY + } + karmaConf.customLaunchers = require('./browsers.json') + karmaConf.browsers = Object.keys(karmaConf.customLaunchers); + } else { + karmaConf.browsers = ['ChromeHeadless']; + } +} + +module.exports = function(codeCoverage, browserstack, watchMode) { + var webpackConfig = newWebpackConfig(codeCoverage); + var plugins = newPluginsArray(browserstack); + + var config = { + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: './', + + webpack: webpackConfig, + webpackMiddleware: { + noInfo: true + }, + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['es5-shim', 'mocha', 'expect', 'sinon'], + + // list of files / patterns to load in the browser + files: [ + 'test/helpers/prebidGlobal.js', + 'test/**/*_spec.js', + 'test/helpers/karma-init.js' + ], + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + 'test/**/*_spec.js': ['webpack', 'sourcemap'], + 'test/helpers/prebidGlobal.js': ['webpack', 'sourcemap'] + }, + + // web server port + port: 9876, + + // enable / disable colors in the output (reporters and logs) + colors: true, + + // level of logging + // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG + logLevel: karmaConstants.LOG_INFO, + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: true, + + reporters: ['progress'], + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: !watchMode, + browserDisconnectTimeout: 10000, // default 2000 + browserDisconnectTolerance: 1, // default 0 + browserNoActivityTimeout: 4 * 60 * 1000, // default 10000 + captureTimeout: 4 * 60 * 1000, // default 60000 + + plugins: plugins + } + setReporters(config, codeCoverage, browserstack); + setBrowsers(config, browserstack); + return config; +} diff --git a/package.json b/package.json index 8fdfec1f680..b8640716ac8 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "license": "Apache-2.0", "devDependencies": { "babel-core": "6.22.0", - "babel-loader": "6.4.1", + "babel-loader": "^7.1.1", "babel-plugin-transform-es3-member-expression-literals": "6.22.0", "babel-plugin-transform-es3-property-literals": "6.22.0", "babel-preset-es2015": "6.22.0", @@ -43,45 +43,42 @@ "gulp-babel": "^6.1.2", "gulp-clean": "^0.3.2", "gulp-concat": "^2.6.0", - "gulp-connect": "^2.0.6", + "gulp-connect": "^5.0.0", "gulp-eslint": "^4.0.0", "gulp-footer": "^1.0.5", "gulp-header": "^1.7.1", "gulp-if": "^2.0.2", - "gulp-jscs": "^3.0.2", "gulp-jsdoc-to-markdown": "^1.2.1", - "gulp-karma": "0.0.4", "gulp-optimize-js": "^1.1.0", "gulp-rename": "^1.2.0", "gulp-replace": "^0.4.0", "gulp-shell": "^0.5.2", - "gulp-uglify": "^0.3.1", + "gulp-uglify": "^3.0.0", "gulp-util": "^3.0.0", "gulp-webdriver": "^1.0.1", - "istanbul": "^0.3.2", - "istanbul-instrumenter-loader": "^0.1.2", + "istanbul": "^0.4.5", + "istanbul-instrumenter-loader": "^2.0.0", "json-loader": "^0.5.1", - "karma": "^0.13.2", + "karma": "^1.7.0", "karma-babel-preprocessor": "^6.0.1", "karma-browserstack-launcher": "^1.0.1", "karma-chai": "^0.1.0", - "karma-chrome-launcher": "^0.2.0", - "karma-coverage": "^0.2.7", + "karma-chrome-launcher": "^2.2.0", + "karma-coverage-istanbul-reporter": "^1.3.0", "karma-es5-shim": "^0.0.4", "karma-expect": "^1.1.0", - "karma-firefox-launcher": "^0.1.3", - "karma-html-reporter": "^0.2.7", - "karma-ie-launcher": "^0.1.5", - "karma-junit-reporter": "^0.3.8", + "karma-firefox-launcher": "^1.0.1", + "karma-ie-launcher": "^1.0.0", "karma-mocha": "^0.2.0", - "karma-opera-launcher": "^0.1.0", - "karma-phantomjs-launcher": "^0.2.1", - "karma-requirejs": "^0.2.2", - "karma-safari-launcher": "^0.1.1", - "karma-sauce-launcher": "^0.2.10", - "karma-script-launcher": "^0.1.0", - "karma-sinon-ie": "^2.0.0-rc10", - "karma-webpack": "^1.5.1", + "karma-opera-launcher": "^1.0.0", + "karma-requirejs": "^1.1.0", + "karma-safari-launcher": "^1.0.0", + "karma-sauce-launcher": "^1.1.0", + "karma-script-launcher": "^1.0.0", + "karma-sinon-ie": "^2.0.0", + "karma-sourcemap-loader": "^0.3.7", + "karma-spec-reporter": "^0.0.31", + "karma-webpack": "^2.0.3", "localtunnel": "^1.3.0", "lodash": "^4.17.4", "mkpath": "^1.0.0", @@ -89,17 +86,16 @@ "mock-fs": "^3.11.0", "nightwatch": "^0.9.5", "open": "0.0.5", - "phantomjs": "^1.9.18", "proxyquire": "^1.7.10", "querystringify": "0.0.3", "requirejs": "^2.1.20", "sinon": "^1.12.1", - "string-replace-webpack-plugin": "0.0.3", + "string-replace-webpack-plugin": "^0.1.3", "through2": "^2.0.3", "uglify-js": "^2.8.10", "url-parse": "^1.0.5", - "webpack": "^1.12.3", - "webpack-stream": "^3.1.0", + "webpack": "^3.0.0", + "webpack-stream": "^3.2.0", "yargs": "^1.3.1" }, "dependencies": { diff --git a/src/AnalyticsAdapter.js b/src/AnalyticsAdapter.js index badc764d5cf..8f8a4b12551 100644 --- a/src/AnalyticsAdapter.js +++ b/src/AnalyticsAdapter.js @@ -1,9 +1,9 @@ -import CONSTANTS from 'src/constants.json'; -import { loadScript } from 'src/adloader'; -import { ajax } from 'src/ajax'; +import CONSTANTS from './constants'; +import { loadScript } from './adloader'; +import { ajax } from './ajax'; -const events = require('src/events'); -const utils = require('src/utils'); +const events = require('./events'); +const utils = require('./utils'); const AUCTION_INIT = CONSTANTS.EVENTS.AUCTION_INIT; const AUCTION_END = CONSTANTS.EVENTS.AUCTION_END; diff --git a/src/Renderer.js b/src/Renderer.js index c81049fa1f6..c532b164fea 100644 --- a/src/Renderer.js +++ b/src/Renderer.js @@ -1,5 +1,5 @@ -import { loadScript } from 'src/adloader'; -import * as utils from 'src/utils'; +import { loadScript } from './adloader'; +import * as utils from './utils'; export function Renderer(options) { const { url, config, id, callback, loaded } = options; diff --git a/src/adServerManager.js b/src/adServerManager.js index 0775b50a72f..a8340431000 100644 --- a/src/adServerManager.js +++ b/src/adServerManager.js @@ -1,5 +1,5 @@ -import { getGlobal } from 'src/prebidGlobal'; -import { logWarn } from 'src/utils'; +import { getGlobal } from './prebidGlobal'; +import { logWarn } from './utils'; const prebid = getGlobal(); diff --git a/src/cookie.js b/src/cookie.js index a0636a415fb..e552232b132 100644 --- a/src/cookie.js +++ b/src/cookie.js @@ -1,6 +1,6 @@ const cookie = exports; -import * as utils from 'utils'; -import adLoader from 'adloader'; +import * as utils from './utils'; +import adLoader from './adloader'; const queue = []; diff --git a/src/prebid.js b/src/prebid.js index be0477f640f..9c3be0d5cf3 100644 --- a/src/prebid.js +++ b/src/prebid.js @@ -8,7 +8,7 @@ import './polyfill'; import { parse as parseURL, format as formatURL } from './url'; import { isValidePriceConfig } from './cpmBucketManager'; import { listenMessagesFromCreative } from './secureCreatives'; -import { syncCookies } from 'src/cookie.js'; +import { syncCookies } from './cookie'; import { loadScript } from './adloader'; import { setAjaxTimeout } from './ajax'; diff --git a/src/targeting.js b/src/targeting.js index 90b93ce191e..1dcbd583089 100644 --- a/src/targeting.js +++ b/src/targeting.js @@ -1,8 +1,8 @@ import { uniques, isGptPubadsDefined, getHighestCpm, adUnitsFilter } from './utils'; import { NATIVE_TARGETING_KEYS } from './native'; -const bidmanager = require('./bidmanager.js'); -const utils = require('./utils.js'); -var CONSTANTS = require('./constants.json'); +const bidmanager = require('./bidmanager'); +const utils = require('./utils'); +var CONSTANTS = require('./constants'); var targeting = exports; var pbTargetingKeys = []; diff --git a/src/utils.js b/src/utils.js index d67228a4a1a..14f9c58f3dd 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,4 +1,4 @@ -var CONSTANTS = require('./constants.json'); +var CONSTANTS = require('./constants'); var objectType_object = 'object'; var objectType_string = 'string'; diff --git a/webpack.conf.js b/webpack.conf.js index 52fc3ff923c..59d03790a4b 100644 --- a/webpack.conf.js +++ b/webpack.conf.js @@ -13,41 +13,43 @@ var neverBundle = [ module.exports = { devtool: 'source-map', resolve: { - root: [ - path.resolve('.') + modules: [ + path.resolve('.'), + 'node_modules' ], - modulesDirectories: ['', 'node_modules'] - }, - resolveLoader: { - root: [ - path.resolve('./loaders'), - path.resolve('./node_modules') - ] }, output: { jsonpFunction: 'pbjsChunk' }, module: { - loaders: [ + rules: [ { test: /\.js$/, exclude: path.resolve('./node_modules'), // required to prevent loader from choking non-Prebid.js node_modules - loader: 'babel', - query: { - presets: ['es2015'] - } + use: [ + { + loader: 'babel-loader', + options: { + presets: ['es2015'] + } + } + ] }, { // This makes sure babel-loader is ran on our intended Prebid.js modules that happen to be in node_modules test: /\.js$/, include: helpers.getArgModules().map(module => new RegExp('node_modules/' + module + '/')), - loader: 'babel', - query: { - presets: ['es2015'] - } + use: [ + { + loader: 'babel-loader', + options: { + presets: ['es2015'] + } + } + ], }, { test: /\.json$/, - loader: 'json' + loader: 'json-loader' }, { test: /constants.json$/, @@ -63,20 +65,20 @@ module.exports = { ] }) }, - { - test: /\.js$/, - include: /(src|test|modules|integrationExamples)/, - loader: StringReplacePlugin.replace({ - replacements: [ - { - pattern: /\$\$PREBID_GLOBAL\$\$/g, - replacement: function (match, p1, offset, string) { - return prebid.globalVarName; - } + { + test: /\.js$/, + include: /(src|test|modules|integrationExamples)/, + loader: StringReplacePlugin.replace({ + replacements: [ + { + pattern: /\$\$PREBID_GLOBAL\$\$/g, + replacement: function (match, p1, offset, string) { + return prebid.globalVarName; } - ] - }) - } + } + ] + }) + } ] }, plugins: [ diff --git a/yarn.lock b/yarn.lock index a6aad494024..ec49039d1d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19,10 +19,6 @@ normalize-path "^2.0.1" through2 "^2.0.3" -"JSV@>= 4.0.x": - version "4.0.2" - resolved "https://registry.yarnpkg.com/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57" - abbrev@1, abbrev@1.0.x: version "1.0.9" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" @@ -41,6 +37,12 @@ accepts@~1.2.12, accepts@~1.2.13: mime-types "~2.1.6" negotiator "0.5.3" +acorn-dynamic-import@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" + dependencies: + acorn "^4.0.3" + acorn-jsx@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" @@ -55,7 +57,7 @@ acorn@^3.0.0, acorn@^3.0.4, acorn@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" -acorn@^5.0.1, acorn@^5.0.3: +acorn@^5.0.0, acorn@^5.0.1, acorn@^5.0.3: version "5.1.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.1.tgz#53fe161111f912ab999ee887a90a0bc52822fd75" @@ -78,6 +80,10 @@ ajv-keywords@^1.0.0: version "1.5.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" +ajv-keywords@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.0.tgz#a296e17f7bfae7c1ce4f7e0de53d29cb32162df0" + ajv@^4.7.0, ajv@^4.9.1: version "4.11.8" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" @@ -85,6 +91,15 @@ ajv@^4.7.0, ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" +ajv@^5.1.5, ajv@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.2.tgz#47c68d69e86f5d953103b0074a9430dc63da5e39" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + json-schema-traverse "^0.3.0" + json-stable-stringify "^1.0.1" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -93,12 +108,6 @@ align-text@^0.1.1, align-text@^0.1.3: longest "^1.0.1" repeat-string "^1.5.2" -alter@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/alter/-/alter-0.2.0.tgz#c7588808617572034aae62480af26b1d4d1cb3cd" - dependencies: - stable "~0.1.3" - amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" @@ -144,9 +153,11 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" -ansi-styles@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" +ansi-styles@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.1.0.tgz#09c202d5c917ec23188caa5c9cb9179cd9547750" + dependencies: + color-convert "^1.0.0" anymatch@^1.3.0: version "1.3.0" @@ -166,11 +177,42 @@ app-usage-stats@^0.4.0: test-value "^2.1.0" usage-stats "^0.8.2" +append-transform@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + dependencies: + default-require-extensions "^1.0.0" + aproba@^1.0.3: version "1.1.2" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.2.tgz#45c6629094de4e96f693ef7eab74ae079c240fc1" -archiver@~0.14.0, archiver@~0.14.3: +archiver-utils@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-1.3.0.tgz#e50b4c09c70bf3d680e32ff1b7994e9f9d895174" + dependencies: + glob "^7.0.0" + graceful-fs "^4.1.0" + lazystream "^1.0.0" + lodash "^4.8.0" + normalize-path "^2.0.0" + readable-stream "^2.0.0" + +archiver@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/archiver/-/archiver-1.3.0.tgz#4f2194d6d8f99df3f531e6881f14f15d55faaf22" + dependencies: + archiver-utils "^1.3.0" + async "^2.0.0" + buffer-crc32 "^0.2.1" + glob "^7.0.0" + lodash "^4.8.0" + readable-stream "^2.0.0" + tar-stream "^1.5.0" + walkdir "^0.0.11" + zip-stream "^1.1.0" + +archiver@~0.14.3: version "0.14.4" resolved "https://registry.yarnpkg.com/archiver/-/archiver-0.14.4.tgz#5b9ddb9f5ee1ceef21cb8f3b020e6240ecb4315c" dependencies: @@ -194,7 +236,7 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" -argparse@^1.0.2, argparse@^1.0.7: +argparse@^1.0.7: version "1.0.9" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" dependencies: @@ -286,8 +328,16 @@ arrify@^1.0.0: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" asap@~2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f" + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + +asn1.js@^4.0.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.1.tgz#48ba240b45a9280e94748990ba597d216617fd40" + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" asn1@0.1.11: version "0.1.11" @@ -323,51 +373,41 @@ assertion-error@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" -ast-traverse@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ast-traverse/-/ast-traverse-0.1.1.tgz#69cf2b8386f19dcda1bb1e05d68fe359d8897de6" - -ast-types@0.8.12: - version "0.8.12" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.12.tgz#a0d90e4351bb887716c83fd637ebf818af4adfcc" - -ast-types@0.8.15: - version "0.8.15" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.15.tgz#8eef0827f04dff0ec8857ba925abe3fea6194e52" - -ast-types@0.9.6, ast-types@0.x.x: - version "0.9.6" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9" +ast-types@0.x.x: + version "0.9.12" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.12.tgz#b136300d67026625ae15326982ca9918e5db73c9" async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" -async@0.2.x, async@~0.2.10, async@~0.2.6, async@~0.2.9: - version "0.2.10" - resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" - -async@0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.0.tgz#ac3613b1da9bed1b47510bb4651b8931e47146c7" +async@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/async/-/async-1.4.0.tgz#35f86f83c59e0421d099cd9a91d8278fb578c00d" async@1.x, async@^1.3.0, async@^1.4.0, async@^1.5.0: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" +async@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.0.1.tgz#b709cc0280a9c36f09f4536be823c838a9049e25" + dependencies: + lodash "^4.8.0" + async@^0.9.0, async@~0.9.0: version "0.9.2" resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" -async@^2.0.1: +async@^2.0.0, async@^2.1.2, async@^2.1.4: version "2.5.0" resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" dependencies: lodash "^4.14.0" -async@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" +async@~0.2.10, async@~0.2.6: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" asynckit@^0.4.0: version "0.4.0" @@ -445,58 +485,7 @@ babel-core@^6.24.1: slash "^1.0.0" source-map "^0.5.0" -babel-core@~5.8.3: - version "5.8.38" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-5.8.38.tgz#1fcaee79d7e61b750b00b8e54f6dfc9d0af86558" - dependencies: - babel-plugin-constant-folding "^1.0.1" - babel-plugin-dead-code-elimination "^1.0.2" - babel-plugin-eval "^1.0.1" - babel-plugin-inline-environment-variables "^1.0.1" - babel-plugin-jscript "^1.0.4" - babel-plugin-member-expression-literals "^1.0.1" - babel-plugin-property-literals "^1.0.1" - babel-plugin-proto-to-assign "^1.0.3" - babel-plugin-react-constant-elements "^1.0.3" - babel-plugin-react-display-name "^1.0.3" - babel-plugin-remove-console "^1.0.1" - babel-plugin-remove-debugger "^1.0.1" - babel-plugin-runtime "^1.0.7" - babel-plugin-undeclared-variables-check "^1.0.2" - babel-plugin-undefined-to-void "^1.1.6" - babylon "^5.8.38" - bluebird "^2.9.33" - chalk "^1.0.0" - convert-source-map "^1.1.0" - core-js "^1.0.0" - debug "^2.1.1" - detect-indent "^3.0.0" - esutils "^2.0.0" - fs-readdir-recursive "^0.1.0" - globals "^6.4.0" - home-or-tmp "^1.0.0" - is-integer "^1.0.4" - js-tokens "1.0.1" - json5 "^0.4.0" - lodash "^3.10.0" - minimatch "^2.0.3" - output-file-sync "^1.1.0" - path-exists "^1.0.0" - path-is-absolute "^1.0.0" - private "^0.1.6" - regenerator "0.8.40" - regexpu "^1.3.0" - repeating "^1.1.2" - resolve "^1.1.6" - shebang-regex "^1.0.0" - slash "^1.0.0" - source-map "^0.5.0" - source-map-support "^0.2.10" - to-fast-properties "^1.0.0" - trim-right "^1.0.0" - try-resolve "^1.0.0" - -babel-generator@^6.22.0, babel-generator@^6.25.0: +babel-generator@^6.18.0, babel-generator@^6.22.0, babel-generator@^6.25.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.25.0.tgz#33a1af70d5f2890aeb465a4a7793c1df6a9ea9fc" dependencies: @@ -584,21 +573,13 @@ babel-helpers@^6.22.0, babel-helpers@^6.24.1: babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-jscs@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/babel-jscs/-/babel-jscs-2.0.5.tgz#0a347046b48145acbca56e8c8ed5f736bc54f9d0" - dependencies: - babel-core "~5.8.3" - lodash.assign "^3.2.0" - -babel-loader@6.4.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.4.1.tgz#0b34112d5b0748a8dcdbf51acf6f9bd42d50b8ca" +babel-loader@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.1.tgz#b87134c8b12e3e4c2a94e0546085bc680a2b8488" dependencies: - find-cache-dir "^0.1.1" - loader-utils "^0.2.16" + find-cache-dir "^1.0.0" + loader-utils "^1.0.2" mkdirp "^0.5.1" - object-assign "^4.0.1" babel-messages@^6.22.0, babel-messages@^6.23.0: version "6.23.0" @@ -612,60 +593,6 @@ babel-plugin-check-es2015-constants@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-constant-folding@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-constant-folding/-/babel-plugin-constant-folding-1.0.1.tgz#8361d364c98e449c3692bdba51eff0844290aa8e" - -babel-plugin-dead-code-elimination@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/babel-plugin-dead-code-elimination/-/babel-plugin-dead-code-elimination-1.0.2.tgz#5f7c451274dcd7cccdbfbb3e0b85dd28121f0f65" - -babel-plugin-eval@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-eval/-/babel-plugin-eval-1.0.1.tgz#a2faed25ce6be69ade4bfec263f70169195950da" - -babel-plugin-inline-environment-variables@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-inline-environment-variables/-/babel-plugin-inline-environment-variables-1.0.1.tgz#1f58ce91207ad6a826a8bf645fafe68ff5fe3ffe" - -babel-plugin-jscript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/babel-plugin-jscript/-/babel-plugin-jscript-1.0.4.tgz#8f342c38276e87a47d5fa0a8bd3d5eb6ccad8fcc" - -babel-plugin-member-expression-literals@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-member-expression-literals/-/babel-plugin-member-expression-literals-1.0.1.tgz#cc5edb0faa8dc927170e74d6d1c02440021624d3" - -babel-plugin-property-literals@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-property-literals/-/babel-plugin-property-literals-1.0.1.tgz#0252301900192980b1c118efea48ce93aab83336" - -babel-plugin-proto-to-assign@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/babel-plugin-proto-to-assign/-/babel-plugin-proto-to-assign-1.0.4.tgz#c49e7afd02f577bc4da05ea2df002250cf7cd123" - dependencies: - lodash "^3.9.3" - -babel-plugin-react-constant-elements@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/babel-plugin-react-constant-elements/-/babel-plugin-react-constant-elements-1.0.3.tgz#946736e8378429cbc349dcff62f51c143b34e35a" - -babel-plugin-react-display-name@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/babel-plugin-react-display-name/-/babel-plugin-react-display-name-1.0.3.tgz#754fe38926e8424a4e7b15ab6ea6139dee0514fc" - -babel-plugin-remove-console@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-remove-console/-/babel-plugin-remove-console-1.0.1.tgz#d8f24556c3a05005d42aaaafd27787f53ff013a7" - -babel-plugin-remove-debugger@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-remove-debugger/-/babel-plugin-remove-debugger-1.0.1.tgz#fd2ea3cd61a428ad1f3b9c89882ff4293e8c14c7" - -babel-plugin-runtime@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/babel-plugin-runtime/-/babel-plugin-runtime-1.0.7.tgz#bf7c7d966dd56ecd5c17fa1cb253c9acb7e54aaf" - babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" @@ -865,16 +792,6 @@ babel-plugin-transform-strict-mode@^6.24.1: babel-runtime "^6.22.0" babel-types "^6.24.1" -babel-plugin-undeclared-variables-check@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/babel-plugin-undeclared-variables-check/-/babel-plugin-undeclared-variables-check-1.0.2.tgz#5cf1aa539d813ff64e99641290af620965f65dee" - dependencies: - leven "^1.0.2" - -babel-plugin-undefined-to-void@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/babel-plugin-undefined-to-void/-/babel-plugin-undefined-to-void-1.1.6.tgz#7f578ef8b78dfae6003385d8417a61eda06e2f81" - babel-polyfill@^6.13.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" @@ -931,7 +848,7 @@ babel-runtime@^6.18.0, babel-runtime@^6.22.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-template@^6.22.0, babel-template@^6.24.1, babel-template@^6.25.0: +babel-template@^6.16.0, babel-template@^6.22.0, babel-template@^6.24.1, babel-template@^6.25.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071" dependencies: @@ -941,7 +858,7 @@ babel-template@^6.22.0, babel-template@^6.24.1, babel-template@^6.25.0: babylon "^6.17.2" lodash "^4.2.0" -babel-traverse@^6.22.0, babel-traverse@^6.24.1, babel-traverse@^6.25.0: +babel-traverse@^6.18.0, babel-traverse@^6.22.0, babel-traverse@^6.24.1, babel-traverse@^6.25.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1" dependencies: @@ -955,7 +872,7 @@ babel-traverse@^6.22.0, babel-traverse@^6.24.1, babel-traverse@^6.25.0: invariant "^2.2.0" lodash "^4.2.0" -babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.24.1, babel-types@^6.25.0: +babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.24.1, babel-types@^6.25.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e" dependencies: @@ -964,11 +881,7 @@ babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.24.1, babel-types@^6.25 lodash "^4.2.0" to-fast-properties "^1.0.1" -babylon@^5.8.38: - version "5.8.38" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-5.8.38.tgz#ec9b120b11bf6ccd4173a18bf217e60b79859ffd" - -babylon@^6.11.0, babylon@^6.17.2: +babylon@^6.11.0, babylon@^6.17.2, babylon@^6.17.4: version "6.17.4" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a" @@ -1004,7 +917,7 @@ basic-auth@~1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-1.0.4.tgz#030935b01de7c9b94a824b29f3fccb750d3a5290" -batch@0.5.3, batch@^0.5.3: +batch@0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/batch/-/batch-0.5.3.tgz#3f3414f380321743bfc1042f9a83ff1d5824d464" @@ -1049,11 +962,11 @@ bl@^0.9.0, bl@~0.9.0: dependencies: readable-stream "~1.0.26" -bl@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.0.3.tgz#fc5421a28fd4226036c3b3891a66a25bc64d226e" +bl@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.1.tgz#cac328f7bee45730d404b692203fcb590e172d5e" dependencies: - readable-stream "~2.0.5" + readable-stream "^2.0.5" blob@0.0.4: version "0.0.4" @@ -1069,15 +982,19 @@ block-stream@*: dependencies: inherits "~2.0.0" -bluebird@^2.9.27, bluebird@^2.9.30, bluebird@^2.9.33: - version "2.11.0" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" +bluebird@^3.3.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" bluebird@~3.4.6: version "3.4.7" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" -body-parser@^1.12.4: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.7" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.7.tgz#ddb048e50d9482790094c13eb3fcfc833ce7ab46" + +body-parser@^1.16.1: version "1.17.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.2.tgz#f8892abc8f9e627d42aedafbca66bf5ab99104ee" dependencies: @@ -1155,9 +1072,9 @@ braces@^1.8.2: preserve "^0.2.0" repeat-element "^1.1.2" -breakable@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/breakable/-/breakable-1.0.0.tgz#784a797915a38ead27bad456b5572cb4bbaa78c1" +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" browser-stdout@1.3.0: version "1.3.0" @@ -1169,6 +1086,51 @@ browserify-aes@0.4.0: dependencies: inherits "^2.0.1" +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.0.6.tgz#5e7725dbdef1fd5930d4ebab48567ce451c48a0a" + dependencies: + buffer-xor "^1.0.2" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + inherits "^2.0.1" + +browserify-cipher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.0.tgz#9988244874bf5ed4e28da95666dcd66ac8fc363a" + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.0.tgz#daa277717470922ed2fe18594118a175439721dd" + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + browserify-zlib@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" @@ -1188,11 +1150,15 @@ browserstacktunnel-wrapper@~2.0.1: https-proxy-agent "^1.0.0" unzip "~0.1.9" -buffer-crc32@~0.2.1: +buffer-crc32@^0.2.1, buffer-crc32@~0.2.1: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" -buffer@^4.9.0: +buffer-xor@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + +buffer@^4.3.0, buffer@^4.9.0: version "4.9.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" dependencies: @@ -1279,13 +1245,9 @@ caseless@~0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.8.0.tgz#5bca2881d41437f54b2407ebe34888c7b9ad4f7d" -caseless@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.9.0.tgz#b7b65ce6bf1413886539cfd533f0b30effa9cf88" - catharsis@~0.8.8: - version "0.8.8" - resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.8.8.tgz#693479f43aac549d806bd73e924cd0d944951a06" + version "0.8.9" + resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.8.9.tgz#98cc890ca652dd2ef0e70b37925310ff9e90fc8b" dependencies: underscore-contrib "~0.3.0" @@ -1327,7 +1289,7 @@ chalk@^0.5.0: strip-ansi "^0.3.0" supports-color "^0.2.0" -chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3, chalk@~1.1.0: +chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -1337,15 +1299,15 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3, chalk@~1.1.0: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" +chalk@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.0.1.tgz#dbec49436d2ae15f536114e76d14656cdbc0f44d" dependencies: - ansi-styles "~1.0.0" - has-color "~0.1.0" - strip-ansi "~0.1.0" + ansi-styles "^3.1.0" + escape-string-regexp "^1.0.5" + supports-color "^4.0.0" -chokidar@^1.0.0, chokidar@^1.4.1: +chokidar@^1.0.0, chokidar@^1.4.1, chokidar@^1.4.3: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" dependencies: @@ -1360,6 +1322,13 @@ chokidar@^1.0.0, chokidar@^1.4.1: optionalDependencies: fsevents "^1.0.0" +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + circular-json@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" @@ -1379,12 +1348,6 @@ cli-cursor@^2.1.0: dependencies: restore-cursor "^2.0.0" -cli-table@~0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" - dependencies: - colors "1.0.3" - cli-width@^1.0.1: version "1.1.1" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-1.1.1.tgz#a4d293ef67ebb7b88d4a4d42c0ccf00c4d1e366d" @@ -1453,12 +1416,6 @@ code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" -coffee-script@~1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.8.0.tgz#9c9f1d2b4a52a000ded15b659791703648263c1d" - dependencies: - mkdirp "~0.3.5" - collect-all@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/collect-all/-/collect-all-1.0.3.tgz#1abcc20448b58a1447487fcf34130e9512b0acf8" @@ -1482,15 +1439,17 @@ collect-json@^1.0.1, collect-json@^1.0.7, collect-json@^1.0.8: stream-connect "^1.0.2" stream-via "^1.0.3" -colors@0.6.x: - version "0.6.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc" +color-convert@^1.0.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" + dependencies: + color-name "^1.1.1" -colors@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" +color-name@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.2.tgz#5c8ab72b64bd2215d617ae9559ebb148475cf98d" -colors@^1.1.0: +colors@^1.1.0, colors@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" @@ -1509,6 +1468,12 @@ column-layout@^2.1.1: typical "^2.4.2" wordwrapjs "^1.2.0" +combine-lists@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/combine-lists/-/combine-lists-1.0.1.tgz#458c07e09e0d900fc28b70a3fec2dacd1d2cb7f6" + dependencies: + lodash "^4.5.0" + combined-stream@^1.0.5, combined-stream@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" @@ -1595,18 +1560,12 @@ commander@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" -commander@2.9.0, commander@^2.5.0, commander@^2.8.1, commander@^2.9.0, commander@~2.9.0: +commander@2.9.0, commander@^2.9.0, commander@~2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" dependencies: graceful-readlink ">= 1.0.0" -comment-parser@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-0.3.1.tgz#fd657aac8c1492d308c9a6100fc9b49d2435aba1" - dependencies: - readable-stream "^2.0.4" - common-sequence@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/common-sequence/-/common-sequence-1.0.2.tgz#30e07f3f8f6f7f9b3dee854f20b2d39eee086de8" @@ -1615,20 +1574,6 @@ commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" -commoner@~0.10.3: - version "0.10.8" - resolved "https://registry.yarnpkg.com/commoner/-/commoner-0.10.8.tgz#34fc3672cd24393e8bb47e70caa0293811f4f2c5" - dependencies: - commander "^2.5.0" - detective "^4.3.1" - glob "^5.0.15" - graceful-fs "^4.1.2" - iconv-lite "^0.4.5" - mkdirp "^0.5.0" - private "^0.1.6" - q "^1.1.2" - recast "^0.11.17" - component-bind@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" @@ -1645,6 +1590,15 @@ component-inherit@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" +compress-commons@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-1.2.0.tgz#58587092ef20d37cb58baf000112c9278ff73b9f" + dependencies: + buffer-crc32 "^0.2.1" + crc32-stream "^2.0.0" + normalize-path "^2.0.0" + readable-stream "^2.0.0" + compress-commons@~0.2.0: version "0.2.9" resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-0.2.9.tgz#422d927430c01abd06cd455b6dfc04cb4cf8003c" @@ -1675,14 +1629,6 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.0.tgz#53f7d43c51c5e43f81c8fdd03321c631be68d611" - dependencies: - inherits "~2.0.1" - readable-stream "~2.0.0" - typedarray "~0.0.5" - concat-stream@^1.5.1, concat-stream@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" @@ -1754,7 +1700,7 @@ connect@^2.30.0: utils-merge "1.0.0" vhost "~3.0.1" -connect@^3.3.5: +connect@^3.6.0: version "3.6.2" resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.2.tgz#694e8d20681bfe490282c8ab886be98f09f42fe7" dependencies: @@ -1785,7 +1731,7 @@ content-type@~1.0.1, content-type@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" -convert-source-map@1.X, convert-source-map@^1.1.0: +convert-source-map@1.X, convert-source-map@^1.1.0, convert-source-map@^1.3.0: version "1.5.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" @@ -1808,11 +1754,7 @@ cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" -core-js@^1.0.0: - version "1.2.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" - -core-js@^2.0.1, core-js@^2.1.0, core-js@^2.4.0, core-js@^2.4.1: +core-js@^2.0.1, core-js@^2.2.0, core-js@^2.4.0, core-js@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" @@ -1830,6 +1772,13 @@ coveralls@^2.11.11: minimist "1.2.0" request "2.79.0" +crc32-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-2.0.0.tgz#e3cdd3b4df3168dd74e3de3fbbcb7b297fe908f4" + dependencies: + crc "^3.4.4" + readable-stream "^2.0.0" + crc32-stream@~0.3.1: version "0.3.4" resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-0.3.4.tgz#73bc25b45fac1db6632231a7bfce8927e9f06552" @@ -1841,6 +1790,37 @@ crc@3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/crc/-/crc-3.3.0.tgz#fa622e1bc388bf257309082d6b65200ce67090ba" +crc@^3.4.4: + version "3.4.4" + resolved "https://registry.yarnpkg.com/crc/-/crc-3.4.4.tgz#9da1e980e3bd44fc5c93bf5ab3da3378d85e466b" + +create-ecdh@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.0.tgz#888c723596cdf7612f6498233eebd7a35301737d" + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd" + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + ripemd160 "^2.0.0" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.6" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.6.tgz#acb9e221a4e17bdb076e90657c42b93e3726cf06" + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + cryptiles@0.2.x: version "0.2.2" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-0.2.2.tgz#ed91ff1f17ad13d3748288594f8a48a0d26f325c" @@ -1862,6 +1842,21 @@ crypto-browserify@3.3.0: ripemd160 "0.2.0" sha.js "2.2.6" +crypto-browserify@^3.11.0: + version "3.11.1" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.1.tgz#948945efc6757a400d6e5e5af47194d10064279f" + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + csrf@~3.0.0: version "3.0.6" resolved "https://registry.yarnpkg.com/csrf/-/csrf-3.0.6.tgz#b61120ddceeafc91e76ed5313bb5c0b2667b710a" @@ -1924,10 +1919,6 @@ custom-event@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" -cycle@1.0.x: - version "1.0.3" - resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" - d@1: version "1.0.0" resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" @@ -1946,15 +1937,15 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -data-uri-to-buffer@0: - version "0.0.4" - resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-0.0.4.tgz#46e13ab9da8e309745c8d01ce547213ebdb2fe3f" +data-uri-to-buffer@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-1.0.0.tgz#af963806bc2bb6253f75442f13dfbee68a2a5897" date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" -dateformat@^1.0.7-1.2.3, dateformat@~1.0.6: +dateformat@^1.0.7-1.2.3: version "1.0.12" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" dependencies: @@ -1979,17 +1970,14 @@ ddata@~0.1.25: test-value "^2.0.0" debug-fabulous@0.1.X: - version "0.1.0" - resolved "https://registry.yarnpkg.com/debug-fabulous/-/debug-fabulous-0.1.0.tgz#ad0ea07a5d519324fb55842a8f34ee59c7f8ff6c" + version "0.1.1" + resolved "https://registry.yarnpkg.com/debug-fabulous/-/debug-fabulous-0.1.1.tgz#1b970878c9fa4fbd1c88306eab323c830c58f1d6" dependencies: - debug "2.X" + debug "2.3.0" + memoizee "^0.4.5" object-assign "4.1.0" -debug@0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" - -debug@2, debug@2.6.8, debug@2.X, debug@^2.1.1, debug@^2.2.0, debug@^2.6.8: +debug@2, debug@2.6.8, debug@^2.1.1, debug@^2.2.0, debug@^2.6.3, debug@^2.6.8: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: @@ -2007,6 +1995,12 @@ debug@2.2.0, debug@~2.2.0: dependencies: ms "0.7.1" +debug@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.0.tgz#3912dc55d7167fc3af17d2b85c13f93deaedaa43" + dependencies: + ms "0.7.2" + debug@2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c" @@ -2029,22 +2023,24 @@ deep-eql@0.1.3, deep-eql@^0.1.3: dependencies: type-detect "0.1.1" -deep-equal@*: - version "1.0.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" - deep-extend@~0.4.0, deep-extend@~0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" -deep-is@~0.1.2, deep-is@~0.1.3: +deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" -"deepmerge@>=0.2.7 <0.3.0-0", deepmerge@^0.2.7, deepmerge@~0.2.7: +deepmerge@^0.2.7, deepmerge@~0.2.7: version "0.2.10" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-0.2.10.tgz#8906bf9e525a4fbf1b203b2afcb4640249821219" +default-require-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + dependencies: + strip-bom "^2.0.0" + defaults@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" @@ -2055,25 +2051,6 @@ defer-promise@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/defer-promise/-/defer-promise-1.0.1.tgz#1ca6ffeddbcef1715dd7aae25c7616f9ae22932f" -defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - -defs@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/defs/-/defs-1.1.1.tgz#b22609f2c7a11ba7a3db116805c139b1caffa9d2" - dependencies: - alter "~0.2.0" - ast-traverse "~0.1.1" - breakable "~1.0.0" - esprima-fb "~15001.1001.0-dev-harmony-fb" - simple-fmt "~0.1.0" - simple-is "~0.2.0" - stringmap "~0.2.2" - stringset "~0.2.1" - tryor "~0.1.2" - yargs "~3.27.0" - degenerator@~1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095" @@ -2118,6 +2095,13 @@ deprecated@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19" +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" @@ -2128,14 +2112,6 @@ detect-file@^0.1.0: dependencies: fs-exists-sync "^0.1.0" -detect-indent@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-3.0.1.tgz#9dc5e5ddbceef8325764b9451b02bc6d54084f75" - dependencies: - get-stdin "^4.0.1" - minimist "^1.1.0" - repeating "^1.1.0" - detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" @@ -2146,13 +2122,6 @@ detect-newline@2.X: version "2.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" -detective@^4.3.1: - version "4.5.0" - resolved "https://registry.yarnpkg.com/detective/-/detective-4.5.0.tgz#6e5a8c6b26e6c7a254b1c6b6d7490d98ec91edd1" - dependencies: - acorn "^4.0.3" - defined "^1.0.0" - di@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" @@ -2165,6 +2134,14 @@ diff@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" +diffie-hellman@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e" + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + dmd@^1.4.1: version "1.4.2" resolved "https://registry.yarnpkg.com/dmd/-/dmd-1.4.2.tgz#b1304b98a5700a6bfe5dcf91be657c981700a4bc" @@ -2209,38 +2186,10 @@ dom-serialize@^2.2.0: extend "^3.0.0" void-elements "^2.0.0" -dom-serializer@0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" - dependencies: - domelementtype "~1.1.1" - entities "~1.1.1" - domain-browser@^1.1.1: version "1.1.7" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" -domelementtype@1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" - -domelementtype@~1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" - -domhandler@2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738" - dependencies: - domelementtype "1" - -domutils@1.5: - version "1.5.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - dependencies: - dom-serializer "0" - domelementtype "1" - duplexer2@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" @@ -2278,6 +2227,18 @@ ejs@^2.3.1, ejs@^2.5.1: version "2.5.6" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.6.tgz#479636bfa3fe3b1debd52087f0acb204b4f19c88" +elliptic@^6.0.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -2298,9 +2259,9 @@ end-of-stream@~0.1.5: dependencies: once "~1.3.0" -engine.io-client@~1.8.4: - version "1.8.4" - resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-1.8.4.tgz#9fe85dee25853ca6babe25bd2ad68710863e91c2" +engine.io-client@1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-1.8.3.tgz#1798ed93451246453d4c6f635d7a201fe940d5ab" dependencies: component-emitter "1.2.1" component-inherit "0.0.3" @@ -2326,16 +2287,25 @@ engine.io-parser@1.3.2: has-binary "0.1.7" wtf-8 "1.0.0" -engine.io@~1.8.4: - version "1.8.4" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.4.tgz#77bce12b80e5d60429337fec3b0daf691ebc9003" +engine.io@1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.3.tgz#8de7f97895d20d39b85f88eeee777b2bd42b13d4" dependencies: accepts "1.3.3" base64id "1.0.0" cookie "0.3.1" debug "2.3.3" engine.io-parser "1.3.2" - ws "1.1.4" + ws "1.1.2" + +enhanced-resolve@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.3.0.tgz#950964ecc7f0332a42321b673b38dc8ff15535b3" + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + object-assign "^4.0.1" + tapable "^0.2.5" enhanced-resolve@~0.9.0: version "0.9.1" @@ -2349,14 +2319,6 @@ ent@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" -entities@1.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26" - -entities@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" - errno@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" @@ -2376,9 +2338,9 @@ errorhandler@~1.4.2: accepts "~1.3.0" escape-html "~1.0.3" -es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: - version "0.10.23" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.23.tgz#7578b51be974207a5487821b56538c224e4e7b38" +es5-ext@^0.10.13, es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2: + version "0.10.24" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.24.tgz#a55877c9924bc0c8d9bd3c2cbe17495ac1709b14" dependencies: es6-iterator "2" es6-symbol "~3.1" @@ -2448,18 +2410,18 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5, escape-string-regexp@~1 version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" -escodegen@1.7.x, escodegen@1.x.x: - version "1.7.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.7.1.tgz#30ecfcf66ca98dc67cd2fd162abeb6eafa8ce6fc" +escodegen@1.8.x, escodegen@1.x.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" dependencies: - esprima "^1.2.2" + esprima "^2.7.1" estraverse "^1.9.1" esutils "^2.0.2" - optionator "^0.5.0" + optionator "^0.8.1" optionalDependencies: source-map "~0.2.0" -escope@^3.2.0: +escope@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" dependencies: @@ -2526,9 +2488,10 @@ eslint-scope@^3.7.1: estraverse "^4.1.1" eslint@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.1.1.tgz#facbdfcfe3e0facd3a8b80dc98c4e6c13ae582df" + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.2.0.tgz#a2b3184111b198e02e9c7f3cca625a5e01c56b3d" dependencies: + ajv "^5.2.0" babel-code-frame "^6.22.0" chalk "^1.1.3" concat-stream "^1.6.0" @@ -2545,7 +2508,6 @@ eslint@^4.0.0: ignore "^3.3.3" imurmurhash "^0.1.4" inquirer "^3.0.6" - is-my-json-valid "^2.16.0" is-resolvable "^1.0.0" js-yaml "^3.8.4" json-stable-stringify "^1.0.1" @@ -2577,25 +2539,17 @@ espree@~3.1.7: acorn "^3.3.0" acorn-jsx "^3.0.0" -esprima-fb@~15001.1001.0-dev-harmony-fb: - version "15001.1001.0-dev-harmony-fb" - resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz#43beb57ec26e8cf237d3dd8b33e42533577f2659" +esprima@2.7.x, esprima@^2.6.0, esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" -esprima@1.2.x, esprima@^1.2.2: - version "1.2.5" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.2.5.tgz#0993502feaf668138325756f30f9a51feeec11e9" - -esprima@2.5.x: - version "2.5.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.5.0.tgz#f387a46fd344c1b1a39baf8c20bfb43b6d0058cc" - -esprima@3.x.x, esprima@^3.1.1, esprima@~3.1.0: +esprima@3.x.x: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" -esprima@^2.6.0, esprima@~2.7.0: - version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" +esprima@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" esquery@^1.0.0: version "1.0.0" @@ -2618,15 +2572,11 @@ estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" -estraverse@~1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.8.0.tgz#3f1264fb62c8500dbae5e4f73705cd576d6af428" - estree-walker@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.3.1.tgz#e6b1a51cf7292524e7237c312e5fe6660c1ce1aa" -esutils@^2.0.0, esutils@^2.0.2: +esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -2634,7 +2584,7 @@ etag@~1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/etag/-/etag-1.7.0.tgz#03d30b5f67dd6e632d2945d30d6652731a34d5d8" -event-emitter@~0.3.5: +event-emitter@^0.3.4, event-emitter@~0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" dependencies: @@ -2653,7 +2603,7 @@ event-stream@*, event-stream@^3.3.2: stream-combiner "~0.0.4" through "~2.3.1" -event-stream@~3.0.18, event-stream@~3.0.20: +event-stream@~3.0.18: version "3.0.20" resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.0.20.tgz#038bbb2ea9ea90385b26fbc1854d0b539f2abea3" dependencies: @@ -2673,9 +2623,11 @@ events@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" -exit@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" +evp_bytestokey@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz#497b66ad9fef65cd7c08a6180824ba1476b66e53" + dependencies: + create-hash "^1.1.1" expand-braces@^0.1.1: version "0.1.2" @@ -2752,23 +2704,10 @@ extglob@^0.3.1: dependencies: is-extglob "^1.0.0" -extract-zip@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.5.0.tgz#92ccf6d81ef70a9fa4c1747114ccef6d8688a6c4" - dependencies: - concat-stream "1.5.0" - debug "0.7.4" - mkdirp "0.5.0" - yauzl "2.4.1" - extsprintf@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" -eyes@0.1.x: - version "0.1.8" - resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" - faker@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/faker/-/faker-3.1.0.tgz#0f908faf4e6ec02524e54a57e432c5c013e08c9f" @@ -2780,9 +2719,9 @@ fancy-log@^1.1.0: chalk "^1.1.1" time-stamp "^1.0.0" -fast-levenshtein@~1.0.0: - version "1.0.7" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz#0178dcdee023b92905193af0959e8a7639cfdcb9" +fast-deep-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" fast-levenshtein@~2.0.4: version "2.0.6" @@ -2794,12 +2733,6 @@ faye-websocket@~0.10.0: dependencies: websocket-driver ">=0.5.1" -fd-slicer@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" - dependencies: - pend "~1.2.0" - feature-detect-es6@^1.2.0, feature-detect-es6@^1.3.0, feature-detect-es6@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/feature-detect-es6/-/feature-detect-es6-1.3.1.tgz#f888736af9cb0c91f55663bfa4762eb96ee7047f" @@ -2846,27 +2779,20 @@ file-set@~0.2.1: array-tools "^2" glob "^4" -file-uri-to-path@0: - version "0.0.2" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-0.0.2.tgz#37cdd1b5b905404b3f05e1b23645be694ff70f82" +file-uri-to-path@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" -fileset@0.1.x: - version "0.1.8" - resolved "https://registry.yarnpkg.com/fileset/-/fileset-0.1.8.tgz#506b91a9396eaa7e32fb42a84077c7a0c736b741" - dependencies: - glob "3.x" - minimatch "0.x" - -fileset@0.2.x: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fileset/-/fileset-0.2.1.tgz#588ef8973c6623b2a76df465105696b96aac8067" +fileset@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" dependencies: - glob "5.x" - minimatch "2.x" + glob "^7.0.3" + minimatch "^3.0.3" fill-keys@^1.0.2: version "1.0.2" @@ -2912,13 +2838,13 @@ finalhandler@1.0.3: statuses "~1.3.1" unpipe "~1.0.0" -find-cache-dir@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" +find-cache-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" dependencies: commondir "^1.0.1" - mkdirp "^0.5.1" - pkg-dir "^1.0.0" + make-dir "^1.0.0" + pkg-dir "^2.0.0" find-index@^0.1.1: version "0.1.1" @@ -2938,7 +2864,7 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" -find-up@^2.0.0: +find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" dependencies: @@ -3004,7 +2930,7 @@ forever-agent@~0.5.0: version "0.5.2" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.5.2.tgz#6d0e09c4921f94a27f63d3b49c5feff1ea4c5130" -forever-agent@~0.6.0, forever-agent@~0.6.1: +forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -3020,22 +2946,6 @@ form-data@~0.1.0: combined-stream "~0.0.4" mime "~1.2.11" -form-data@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-0.2.0.tgz#26f8bc26da6440e299cbdcfb69035c4f77a6e466" - dependencies: - async "~0.9.0" - combined-stream "~0.0.4" - mime-types "~2.0.3" - -form-data@~1.0.0-rc3: - version "1.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.1.tgz#ae315db9a4907fa065502304a66d7733475ee37c" - dependencies: - async "^2.0.1" - combined-stream "^1.0.5" - mime-types "^2.1.11" - form-data@~2.1.1: version "2.1.4" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" @@ -3068,16 +2978,6 @@ fs-exists-sync@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" -fs-extra@~0.26.4: - version "0.26.7" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.26.7.tgz#9ae1fdd94897798edab76d0918cf42d0c3184fa9" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - fs-extra@~0.6.1: version "0.6.4" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.6.4.tgz#f46f0c75b7841f8d200b3348cd4d691d5a099d15" @@ -3087,10 +2987,6 @@ fs-extra@~0.6.1: ncp "~0.4.2" rimraf "~2.2.0" -fs-readdir-recursive@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz#315b4fb8c1ca5b8c47defef319d073dad3568059" - fs-then-native@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/fs-then-native/-/fs-then-native-1.0.2.tgz#ac8d3807c9f1bbd1279607fb228e0ab649bb41fe" @@ -3142,7 +3038,7 @@ fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: mkdirp ">=0.5 0" rimraf "2" -ftp@~0.3.5: +ftp@~0.3.10: version "0.3.10" resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d" dependencies: @@ -3191,14 +3087,14 @@ get-stdin@^4.0.1: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" get-uri@2: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-2.0.0.tgz#713e47cbcbaeab38f88af1cdfc85fa7f09b00738" + version "2.0.1" + resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-2.0.1.tgz#dbdcacacd8c608a38316869368117697a1631c59" dependencies: - data-uri-to-buffer "0" + data-uri-to-buffer "1" debug "2" extend "3" - file-uri-to-path "0" - ftp "~0.3.5" + file-uri-to-path "1" + ftp "~0.3.10" readable-stream "2" getpass@^0.1.1: @@ -3243,7 +3139,7 @@ glob2base@^0.0.12: dependencies: find-index "^0.1.1" -glob@3.2.3, glob@3.x: +glob@3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.3.tgz#e313eeb249c7affaa5c475286b0e115b59839467" dependencies: @@ -3251,16 +3147,6 @@ glob@3.2.3, glob@3.x: inherits "2" minimatch "~0.2.11" -glob@5.x, glob@^5.0.1, glob@^5.0.10, glob@^5.0.15: - version "5.0.15" - resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@7.0.5: version "7.0.5" resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" @@ -3281,7 +3167,17 @@ glob@^4, glob@^4.3.1: minimatch "^2.0.1" once "^1.3.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.0, glob@^7.1.2: +glob@^5.0.10, glob@^5.0.14, glob@^5.0.15: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: @@ -3325,10 +3221,6 @@ global-prefix@^0.1.4: is-windows "^0.2.0" which "^1.2.12" -globals@^6.4.0: - version "6.4.1" - resolved "https://registry.yarnpkg.com/globals/-/globals-6.4.1.tgz#8498032b3b6d1cc81eebc5f79690d8fe29fabf4f" - globals@^9.0.0, globals@^9.17.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -3358,7 +3250,7 @@ glogg@^1.0.0: dependencies: sparkles "^1.0.0" -graceful-fs@4.X, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9: +graceful-fs@4.X, graceful-fs@^4.1.0, graceful-fs@^4.1.2, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -3415,9 +3307,9 @@ gulp-concat@^2.6.0: through2 "^2.0.0" vinyl "^2.0.0" -gulp-connect@^2.0.6: - version "2.3.1" - resolved "https://registry.yarnpkg.com/gulp-connect/-/gulp-connect-2.3.1.tgz#14ae7173328b691252b01fc1930a39cbb24fb33c" +gulp-connect@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/gulp-connect/-/gulp-connect-5.0.0.tgz#f2fdf306ae911468368c2285f2d782f13eddaf4e" dependencies: connect "^2.30.0" connect-livereload "^0.5.4" @@ -3457,15 +3349,6 @@ gulp-if@^2.0.2: ternary-stream "^2.0.1" through2 "^2.0.1" -gulp-jscs@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/gulp-jscs/-/gulp-jscs-3.0.2.tgz#dc7fbb01ce2bfc8325bba7cbbf95d65e43530478" - dependencies: - gulp-util "^3.0.4" - jscs "^2.1.1" - through2 "^2.0.0" - tildify "^1.0.0" - gulp-jsdoc-to-markdown@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/gulp-jsdoc-to-markdown/-/gulp-jsdoc-to-markdown-1.2.2.tgz#bd0e267e3972bc169e7bdb992f967823b023fefd" @@ -3474,15 +3357,6 @@ gulp-jsdoc-to-markdown@^1.2.1: jsdoc-to-markdown "^1.3.4" through2 "^2.0.1" -gulp-karma@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/gulp-karma/-/gulp-karma-0.0.4.tgz#65cc202483f25369966ed60ff5dba1f6476131bd" - dependencies: - event-stream "~3.0.20" - gulp-util "~2.2.14" - optimist "~0.6.0" - xtend "~2.1.1" - gulp-match@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/gulp-match/-/gulp-match-1.0.3.tgz#91c7c0d7f29becd6606d57d80a7f8776a87aba8e" @@ -3536,16 +3410,19 @@ gulp-sourcemaps@^2.6.0: through2 "2.X" vinyl "1.X" -gulp-uglify@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/gulp-uglify/-/gulp-uglify-0.3.2.tgz#fa37bf6d4ad9a29a349c6cba862abb22eba67aac" +gulp-uglify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/gulp-uglify/-/gulp-uglify-3.0.0.tgz#0df0331d72a0d302e3e37e109485dddf33c6d1ca" dependencies: - deepmerge ">=0.2.7 <0.3.0-0" - gulp-util ">=3.0.0 <4.0.0-0" - through2 ">=0.6.1 <1.0.0-0" - uglify-js "2.4.6" + gulplog "^1.0.0" + has-gulplog "^0.1.0" + lodash "^4.13.1" + make-error-cause "^1.1.1" + through2 "^2.0.0" + uglify-js "^3.0.5" + vinyl-sourcemaps-apply "^0.2.0" -gulp-util@*, "gulp-util@>=3.0.0 <4.0.0-0", gulp-util@^3.0.0, gulp-util@^3.0.4, gulp-util@^3.0.6, gulp-util@^3.0.7, gulp-util@^3.0.8: +gulp-util@*, gulp-util@^3.0.0, gulp-util@^3.0.4, gulp-util@^3.0.6, gulp-util@^3.0.7, gulp-util@^3.0.8: version "3.0.8" resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" dependencies: @@ -3568,7 +3445,7 @@ gulp-util@*, "gulp-util@>=3.0.0 <4.0.0-0", gulp-util@^3.0.0, gulp-util@^3.0.4, g through2 "^2.0.0" vinyl "^0.5.0" -gulp-util@^2.2.14, gulp-util@~2.2.14: +gulp-util@^2.2.14: version "2.2.20" resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-2.2.20.tgz#d7146e5728910bd8f047a6b0b1e549bc22dbd64c" dependencies: @@ -3651,7 +3528,7 @@ handlebars@^3.0.0, handlebars@^3.0.3: optionalDependencies: uglify-js "~2.3" -handlebars@^4.0.1: +handlebars@^4.0.1, handlebars@^4.0.3: version "4.0.10" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f" dependencies: @@ -3665,16 +3542,7 @@ har-schema@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" -har-validator@^1.4.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-1.8.0.tgz#d83842b0eb4c435960aeb108a067a3aa94c0eeb2" - dependencies: - bluebird "^2.9.30" - chalk "^1.0.0" - commander "^2.8.1" - is-my-json-valid "^2.12.0" - -har-validator@~2.0.2, har-validator@~2.0.6: +har-validator@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" dependencies: @@ -3708,10 +3576,6 @@ has-binary@0.1.7: dependencies: isarray "0.0.1" -has-color@~0.1.0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" - has-cors@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" @@ -3720,6 +3584,10 @@ has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + has-gulplog@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" @@ -3736,12 +3604,18 @@ has@^1.0.1: dependencies: function-bind "^1.0.2" -hasha@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/hasha/-/hasha-2.2.0.tgz#78d7cbfc1e6d66303fe79837365984517b2f6ee1" +hash-base@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1" dependencies: - is-stream "^1.0.1" - pinkie-promise "^2.0.0" + inherits "^2.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.0" hawk@1.1.1: version "1.1.1" @@ -3752,16 +3626,7 @@ hawk@1.1.1: hoek "0.9.x" sntp "0.2.x" -hawk@~2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-2.3.1.tgz#1e731ce39447fa1d0f6d707f7bceebec0fd1ec1f" - dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" - -hawk@~3.1.0, hawk@~3.1.3: +hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" dependencies: @@ -3770,6 +3635,14 @@ hawk@~3.1.0, hawk@~3.1.3: hoek "2.x.x" sntp "1.x.x" +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + hoek@0.9.x: version "0.9.1" resolved "https://registry.yarnpkg.com/hoek/-/hoek-0.9.1.tgz#3d322462badf07716ea7eb85baf88079cddce505" @@ -3778,13 +3651,6 @@ hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" -home-or-tmp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-1.0.0.tgz#4b9f1e40800c3e50c6c27f781676afcce71f3985" - dependencies: - os-tmpdir "^1.0.1" - user-home "^1.1.1" - home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" @@ -3806,16 +3672,6 @@ hosted-git-info@^2.1.4: version "2.5.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" -htmlparser2@3.8.3: - version "3.8.3" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068" - dependencies: - domelementtype "1" - domhandler "2.3" - domutils "1.5" - entities "1.0" - readable-stream "1.1" - http-errors@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.3.1.tgz#197e22cdebd4198585e8694ef6786197b91ed942" @@ -3867,7 +3723,7 @@ https-browserify@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82" -https-proxy-agent@1, https-proxy-agent@1.0.0, https-proxy-agent@^1.0.0: +https-proxy-agent@1, https-proxy-agent@1.0.0, https-proxy-agent@^1.0.0, https-proxy-agent@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6" dependencies: @@ -3875,24 +3731,6 @@ https-proxy-agent@1, https-proxy-agent@1.0.0, https-proxy-agent@^1.0.0: debug "2" extend "3" -i@0.3.x: - version "0.3.5" - resolved "https://registry.yarnpkg.com/i/-/i-0.3.5.tgz#1d2b854158ec8169113c6cb7f6b6801e99e211d5" - -ibrik@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ibrik/-/ibrik-2.0.0.tgz#89a2434f2a5c82b92166c3d97de3b5636eea2e9c" - dependencies: - coffee-script "~1.8.0" - esprima "1.2.x" - estraverse "~1.8.0" - fileset "0.1.x" - istanbul "~0.3.2" - lodash "~2.4.1" - mkdirp "~0.5.0" - optimist "~0.6.1" - which "~1.0.5" - iconv-lite@0.4.11: version "0.4.11" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.11.tgz#2ecb42fd294744922209a2e7c404dac8793d8ade" @@ -3905,7 +3743,7 @@ iconv-lite@0.4.15: version "0.4.15" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" -iconv-lite@^0.4.17, iconv-lite@^0.4.5: +iconv-lite@^0.4.17: version "0.4.18" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2" @@ -3938,10 +3776,6 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherit@^2.2.2: - version "2.2.6" - resolved "https://registry.yarnpkg.com/inherit/-/inherit-2.2.6.tgz#f1614b06c8544e8128e4229c86347db73ad9788d" - inherits@1: version "1.0.2" resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" @@ -3972,11 +3806,11 @@ inquirer@^0.8.5: through "^2.3.6" inquirer@^3.0.6: - version "3.1.1" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.1.1.tgz#87621c4fba4072f48a8dd71c9f9df6f100b2d534" + version "3.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.2.0.tgz#45b44c2160c729d7578c54060b3eed94487bb42b" dependencies: ansi-escapes "^2.0.0" - chalk "^1.0.0" + chalk "^2.0.0" cli-cursor "^2.1.0" cli-width "^2.0.0" external-editor "^2.0.4" @@ -3986,8 +3820,8 @@ inquirer@^3.0.6: run-async "^2.2.0" rx-lite "^4.0.8" rx-lite-aggregates "^4.0.8" - string-width "^2.0.0" - strip-ansi "^3.0.0" + string-width "^2.1.0" + strip-ansi "^4.0.0" through "^2.3.6" interpret@^0.6.4: @@ -4087,13 +3921,7 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" -is-integer@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-integer/-/is-integer-1.0.7.tgz#6bde81aacddf78b659b6629d629cadc51a886d5c" - dependencies: - is-finite "^1.0.0" - -is-my-json-valid@^2.12.0, is-my-json-valid@^2.12.4, is-my-json-valid@^2.16.0: +is-my-json-valid@^2.12.4: version "2.16.0" resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" dependencies: @@ -4139,10 +3967,10 @@ is-path-inside@^1.0.0: path-is-inside "^1.0.1" is-plain-object@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.3.tgz#c15bf3e4b66b62d72efaf2925848663ecbc619b6" + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" dependencies: - isobject "^3.0.0" + isobject "^3.0.1" is-posix-bracket@^0.1.0: version "0.1.1" @@ -4152,7 +3980,7 @@ is-primitive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" -is-promise@^2.1.0: +is-promise@^2.1, is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" @@ -4172,10 +4000,6 @@ is-resolvable@^1.0.0: dependencies: tryit "^1.0.1" -is-stream@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -4216,29 +4040,95 @@ isobject@^2.0.0, isobject@^2.1.0: dependencies: isarray "1.0.0" -isobject@^3.0.0: +isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" -isstream@0.1.x, isstream@~0.1.1, isstream@~0.1.2: +isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" -istanbul-instrumenter-loader@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-0.1.3.tgz#71394c509594ed707ef280a7c7145207de7e2a50" +istanbul-api@^1.1.8: + version "1.1.10" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.10.tgz#f27e5e7125c8de13f6a80661af78f512e5439b2b" + dependencies: + async "^2.1.4" + fileset "^2.0.2" + istanbul-lib-coverage "^1.1.1" + istanbul-lib-hook "^1.0.7" + istanbul-lib-instrument "^1.7.3" + istanbul-lib-report "^1.1.1" + istanbul-lib-source-maps "^1.2.1" + istanbul-reports "^1.1.1" + js-yaml "^3.7.0" + mkdirp "^0.5.1" + once "^1.4.0" + +istanbul-instrumenter-loader@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-2.0.0.tgz#e5492900ab0bba835efa8024cb00be9b3eea2700" + dependencies: + convert-source-map "^1.3.0" + istanbul-lib-instrument "^1.1.3" + loader-utils "^0.2.16" + object-assign "^4.1.0" + +istanbul-lib-coverage@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da" + +istanbul-lib-hook@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz#dd6607f03076578fe7d6f2a630cf143b49bacddc" + dependencies: + append-transform "^0.4.0" + +istanbul-lib-instrument@^1.1.3, istanbul-lib-instrument@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.3.tgz#925b239163eabdd68cc4048f52c2fa4f899ecfa7" + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.17.4" + istanbul-lib-coverage "^1.1.1" + semver "^5.3.0" + +istanbul-lib-report@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#f0e55f56655ffa34222080b7a0cd4760e1405fc9" + dependencies: + istanbul-lib-coverage "^1.1.1" + mkdirp "^0.5.1" + path-parse "^1.0.5" + supports-color "^3.1.2" + +istanbul-lib-source-maps@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz#a6fe1acba8ce08eebc638e572e294d267008aa0c" dependencies: - istanbul "0.x.x" + debug "^2.6.3" + istanbul-lib-coverage "^1.1.1" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + +istanbul-reports@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.1.tgz#042be5c89e175bc3f86523caab29c014e77fee4e" + dependencies: + handlebars "^4.0.3" -istanbul@0.x.x, istanbul@^0.3.2, istanbul@~0.3.0, istanbul@~0.3.2: - version "0.3.22" - resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.3.22.tgz#3e164d85021fe19c985d1f0e7ef0c3e22d012eb6" +istanbul@^0.4.5: + version "0.4.5" + resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" dependencies: abbrev "1.0.x" async "1.x" - escodegen "1.7.x" - esprima "2.5.x" - fileset "0.2.x" + escodegen "1.8.x" + esprima "2.7.x" + glob "^5.0.15" handlebars "^4.0.1" js-yaml "3.x" mkdirp "0.5.x" @@ -4263,10 +4153,6 @@ jade@0.26.3: commander "0.6.1" mkdirp "0.3.0" -js-tokens@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-1.0.1.tgz#cc435a5c8b94ad15acb7983140fc80182c89aeae" - js-tokens@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" @@ -4278,20 +4164,12 @@ js-yaml@3.6.1, js-yaml@3.x: argparse "^1.0.7" esprima "^2.6.0" -js-yaml@^3.8.4: - version "3.8.4" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.4.tgz#520b4564f86573ba96662af85a8cafa7b4b5a6f6" +js-yaml@^3.7.0, js-yaml@^3.8.4: + version "3.9.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.0.tgz#4ffbbf25c2ac963b8299dc74da7e3740de1c18ce" dependencies: argparse "^1.0.7" - esprima "^3.1.1" - -js-yaml@~3.4.0: - version "3.4.6" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.4.6.tgz#6be1b23f6249f53d293370fd4d1aaa63ce1b4eb0" - dependencies: - argparse "^1.0.2" - esprima "^2.6.0" - inherit "^2.2.2" + esprima "^4.0.0" js2xmlparser@~1.0.0: version "1.0.0" @@ -4305,50 +4183,6 @@ jschardet@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.4.2.tgz#2aa107f142af4121d145659d44f50830961e699a" -jscs-jsdoc@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/jscs-jsdoc/-/jscs-jsdoc-1.3.2.tgz#1f2c82b6ab4b97524da958f46b4e562e0305f9a7" - dependencies: - comment-parser "^0.3.1" - jsdoctypeparser "~1.2.0" - -jscs-preset-wikimedia@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jscs-preset-wikimedia/-/jscs-preset-wikimedia-1.0.0.tgz#fff563342038fc2e8826b7bb7309c3ae3406fc7e" - -jscs@^2.1.1: - version "2.11.0" - resolved "https://registry.yarnpkg.com/jscs/-/jscs-2.11.0.tgz#6e11ef0caaa07731f9dcc2b2b27d8ecee1ddbcb6" - dependencies: - babel-jscs "^2.0.0" - chalk "~1.1.0" - cli-table "~0.3.1" - commander "~2.9.0" - escope "^3.2.0" - esprima "~2.7.0" - estraverse "^4.1.0" - exit "~0.1.2" - glob "^5.0.1" - htmlparser2 "3.8.3" - js-yaml "~3.4.0" - jscs-jsdoc "^1.3.1" - jscs-preset-wikimedia "~1.0.0" - jsonlint "~1.6.2" - lodash "~3.10.0" - minimatch "~3.0.0" - natural-compare "~1.2.2" - pathval "~0.1.1" - prompt "~0.2.14" - reserved-words "^0.1.1" - resolve "^1.1.6" - strip-bom "^2.0.0" - strip-json-comments "~1.0.2" - to-double-quotes "^2.0.0" - to-single-quotes "^2.0.0" - vow "~0.4.8" - vow-fs "~0.3.4" - xmlbuilder "^3.1.0" - jsdoc-75lb@^3.5.6: version "3.6.0" resolved "https://registry.yarnpkg.com/jsdoc-75lb/-/jsdoc-75lb-3.6.0.tgz#a807119528b4009ccbcab49b7522f63fec6cd0bd" @@ -4421,12 +4255,6 @@ jsdoc2md-stats@^1.0.3: app-usage-stats "^0.4.0" feature-detect-es6 "^1.3.1" -jsdoctypeparser@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/jsdoctypeparser/-/jsdoctypeparser-1.2.0.tgz#e7dedc153a11849ffc5141144ae86a7ef0c25392" - dependencies: - lodash "^3.7.0" - jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" @@ -4435,10 +4263,14 @@ jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" -json-loader@^0.5.1: +json-loader@^0.5.1, json-loader@^0.5.4: version "0.5.4" resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.4.tgz#8baa1365a632f58a3c46d20175fc6002c96e37de" +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -4457,20 +4289,10 @@ json3@3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" -json5@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.4.0.tgz#054352e4c4c80c86c0923877d449de176a732c8d" - -json5@^0.5.0: +json5@^0.5.0, json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - optionalDependencies: - graceful-fs "^4.1.6" - jsonfile@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-1.0.1.tgz#ea5efe40b83690b98667614a7392fc60e842c0dd" @@ -4479,13 +4301,6 @@ jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" -jsonlint@~1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/jsonlint/-/jsonlint-1.6.2.tgz#5737045085f55eb455c68b1ff4ebc01bd50e8830" - dependencies: - JSV ">= 4.0.x" - nomnom ">= 1.5.x" - jsonpointer@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" @@ -4517,21 +4332,19 @@ karma-chai@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/karma-chai/-/karma-chai-0.1.0.tgz#bee5ad40400517811ae34bb945f762909108b79a" -karma-chrome-launcher@^0.2.0: - version "0.2.3" - resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-0.2.3.tgz#4c6d700d163a9d34c618efd87918be49e7a4a8c9" +karma-chrome-launcher@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz#cf1b9d07136cc18fe239327d24654c3dbc368acf" dependencies: fs-access "^1.0.0" which "^1.2.1" -karma-coverage@^0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/karma-coverage/-/karma-coverage-0.2.7.tgz#f76740b275bbf30a0ab9f41d8cf56843a0994576" +karma-coverage-istanbul-reporter@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-1.3.0.tgz#d142cd9c55731c9e363ef7374e8ef1a31bebfadb" dependencies: - dateformat "~1.0.6" - ibrik "~2.0.0" - istanbul "~0.3.0" - minimatch "~0.3.0" + istanbul-api "^1.1.8" + minimatch "^3.0.4" karma-es5-shim@^0.0.4: version "0.0.4" @@ -4545,69 +4358,64 @@ karma-expect@^1.1.0: dependencies: expect.js "^0.3.1" -karma-firefox-launcher@^0.1.3: - version "0.1.7" - resolved "https://registry.yarnpkg.com/karma-firefox-launcher/-/karma-firefox-launcher-0.1.7.tgz#c05dd86533691e62f31952595098e8bd357d39f3" - -karma-html-reporter@^0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/karma-html-reporter/-/karma-html-reporter-0.2.7.tgz#fd73da9f1ac99fd5bafb309cf070942188e7ba63" - dependencies: - lodash "~2.2.0" - mu2 "~0.5.19" - -karma-ie-launcher@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/karma-ie-launcher/-/karma-ie-launcher-0.1.5.tgz#ee43bd238f61c45dd8fbc1694b13a50dfb5a3e1b" +karma-firefox-launcher@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/karma-firefox-launcher/-/karma-firefox-launcher-1.0.1.tgz#ce58f47c2013a88156d55a5d61337c099cf5bb51" -karma-junit-reporter@^0.3.8: - version "0.3.8" - resolved "https://registry.yarnpkg.com/karma-junit-reporter/-/karma-junit-reporter-0.3.8.tgz#d24b85b8507b7ddb2c8ced0d1f4f2b1ac700d3fe" +karma-ie-launcher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/karma-ie-launcher/-/karma-ie-launcher-1.0.0.tgz#497986842c490190346cd89f5494ca9830c6d59c" dependencies: - xmlbuilder "3.1.0" + lodash "^4.6.1" karma-mocha@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-0.2.2.tgz#388ed917da15dcb196d1b915c1934ef803193f8e" -karma-opera-launcher@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/karma-opera-launcher/-/karma-opera-launcher-0.1.0.tgz#751c89db4e686a8327d291f19a58b34f00dbd078" - -karma-phantomjs-launcher@^0.2.1: - version "0.2.3" - resolved "https://registry.yarnpkg.com/karma-phantomjs-launcher/-/karma-phantomjs-launcher-0.2.3.tgz#77f68243fad7852c5b321bcf9d691f1223cc0809" - dependencies: - lodash "^3.10.1" +karma-opera-launcher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/karma-opera-launcher/-/karma-opera-launcher-1.0.0.tgz#fa51628531a1d0be84b2d8dc0d7ee209fc8ff91a" -karma-requirejs@^0.2.2: - version "0.2.6" - resolved "https://registry.yarnpkg.com/karma-requirejs/-/karma-requirejs-0.2.6.tgz#1a770c64f901320a389c65b4944746326372def8" +karma-requirejs@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/karma-requirejs/-/karma-requirejs-1.1.0.tgz#fddae2cb87d7ebc16fb0222893564d7fee578798" -karma-safari-launcher@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/karma-safari-launcher/-/karma-safari-launcher-0.1.1.tgz#a6380accab60a583fdd624f41b9a3f10fdf41008" +karma-safari-launcher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/karma-safari-launcher/-/karma-safari-launcher-1.0.0.tgz#96982a2cc47d066aae71c553babb28319115a2ce" -karma-sauce-launcher@^0.2.10: - version "0.2.14" - resolved "https://registry.yarnpkg.com/karma-sauce-launcher/-/karma-sauce-launcher-0.2.14.tgz#e42e412517c5f40534c8bba7d14bb4f10727b6a7" +karma-sauce-launcher@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/karma-sauce-launcher/-/karma-sauce-launcher-1.1.0.tgz#3d083cf5659d6736ab97bcee5d8acd86ad522212" dependencies: - q "~0.9.6" - sauce-connect-launcher "~0.11.1" - saucelabs "~0.1.0" - wd "~0.3.4" + q "^1.4.1" + sauce-connect-launcher "^0.17.0" + saucelabs "^1.3.0" + wd "^1.0.0" -karma-script-launcher@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/karma-script-launcher/-/karma-script-launcher-0.1.0.tgz#b643e7c2faead1a52cdb2eeaadcf7a245f0d772a" +karma-script-launcher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/karma-script-launcher/-/karma-script-launcher-1.0.0.tgz#cd017c4de5ef09e5a9da793276176108dd4b542d" -karma-sinon-ie@^2.0.0-rc10: +karma-sinon-ie@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/karma-sinon-ie/-/karma-sinon-ie-2.0.0.tgz#d07f05ac911baea5f6dbc95e1404fd9c93f6cc65" -karma-webpack@^1.5.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-1.8.1.tgz#39d5fd2edeea3cc3ef5b405989b37d5b0e6a3b4e" +karma-sourcemap-loader@^0.3.7: + version "0.3.7" + resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz#91322c77f8f13d46fed062b042e1009d4c4505d8" + dependencies: + graceful-fs "^4.1.2" + +karma-spec-reporter@^0.0.31: + version "0.0.31" + resolved "https://registry.yarnpkg.com/karma-spec-reporter/-/karma-spec-reporter-0.0.31.tgz#4830dc7148a155c7d7a186e632339a0d80fadec3" + dependencies: + colors "^1.1.2" + +karma-webpack@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-2.0.4.tgz#3e2d4f48ba94a878e1c66bb8e1ae6128987a175b" dependencies: async "~0.9.0" loader-utils "^0.2.5" @@ -4615,37 +4423,37 @@ karma-webpack@^1.5.1: source-map "^0.1.41" webpack-dev-middleware "^1.0.11" -karma@^0.13.2: - version "0.13.22" - resolved "https://registry.yarnpkg.com/karma/-/karma-0.13.22.tgz#07750b1bd063d7e7e7b91bcd2e6354d8f2aa8744" +karma@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/karma/-/karma-1.7.0.tgz#6f7a1a406446fa2e187ec95398698f4cee476269" dependencies: - batch "^0.5.3" - bluebird "^2.9.27" - body-parser "^1.12.4" + bluebird "^3.3.0" + body-parser "^1.16.1" chokidar "^1.4.1" colors "^1.1.0" - connect "^3.3.5" - core-js "^2.1.0" + combine-lists "^1.0.0" + connect "^3.6.0" + core-js "^2.2.0" di "^0.0.1" dom-serialize "^2.2.0" expand-braces "^0.1.1" - glob "^7.0.0" + glob "^7.1.1" graceful-fs "^4.1.2" http-proxy "^1.13.0" isbinaryfile "^3.0.0" lodash "^3.8.0" log4js "^0.6.31" mime "^1.3.4" - minimatch "^3.0.0" + minimatch "^3.0.2" optimist "^0.6.1" - rimraf "^2.3.3" - socket.io "^1.4.5" + qjobs "^1.1.4" + range-parser "^1.2.0" + rimraf "^2.6.0" + safe-buffer "^5.0.1" + socket.io "1.7.3" source-map "^0.5.3" - useragent "^2.1.6" - -kew@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b" + tmp "0.0.31" + useragent "^2.1.12" kind-of@^3.0.2: version "3.2.2" @@ -4659,7 +4467,7 @@ kind-of@^4.0.0: dependencies: is-buffer "^1.1.5" -klaw@^1.0.0, klaw@~1.3.0: +klaw@~1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" optionalDependencies: @@ -4669,6 +4477,12 @@ lazy-cache@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" +lazystream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" + dependencies: + readable-stream "^2.0.5" + lazystream@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-0.1.0.tgz#1b25d63c772a4c20f0a5ed0a9d77f484b6e16920" @@ -4685,10 +4499,6 @@ lcov-parse@0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" -leven@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/leven/-/leven-1.0.2.tgz#9144b6eebca5f1d0680169f1a6770dcea60b75c3" - levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -4696,13 +4506,6 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -levn@~0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.2.5.tgz#ba8d339d0ca4a610e3a3f145b9caf48807155054" - dependencies: - prelude-ls "~1.1.0" - type-check "~0.3.1" - liftoff@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.3.0.tgz#a98f2ff67183d8ba7cfaca10548bd7ff0550b385" @@ -4740,6 +4543,10 @@ load-json-file@^2.0.0: pify "^2.0.0" strip-bom "^3.0.0" +loader-runner@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" + loader-utils@^0.2.11, loader-utils@^0.2.16, loader-utils@^0.2.5, loader-utils@~0.2.2, loader-utils@~0.2.3, loader-utils@~0.2.5: version "0.2.17" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" @@ -4749,6 +4556,14 @@ loader-utils@^0.2.11, loader-utils@^0.2.16, loader-utils@^0.2.5, loader-utils@~0 json5 "^0.5.0" object-assign "^4.0.1" +loader-utils@^1.0.2, loader-utils@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + localtunnel@^1.3.0: version "1.8.3" resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-1.8.3.tgz#dcc5922fd85651037d4bde24fd93248d0b24eb05" @@ -4819,14 +4634,6 @@ lodash._bindcallback@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" -lodash._createassigner@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" - dependencies: - lodash._bindcallback "^3.0.0" - lodash._isiterateecall "^3.0.0" - lodash.restparam "^3.0.0" - lodash._escapehtmlchar@~2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz#df67c3bb6b7e8e1e831ab48bfa0795b92afe899d" @@ -4898,14 +4705,6 @@ lodash.assign@*, lodash.assign@^4.0.3, lodash.assign@^4.0.6: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" -lodash.assign@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa" - dependencies: - lodash._baseassign "^3.0.0" - lodash._createassigner "^3.0.0" - lodash.keys "^3.0.0" - lodash.clone@3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-3.0.3.tgz#84688c73d32b5a90ca25616963f189252a997043" @@ -5074,15 +4873,15 @@ lodash.values@~2.4.1: dependencies: lodash.keys "~2.4.1" -lodash@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.5.0.tgz#19bb3f4d51278f0b8c818ed145c74ecf9fe40e6d" - -lodash@^3.10.0, lodash@^3.10.1, lodash@^3.3.1, lodash@^3.5.0, lodash@^3.7.0, lodash@^3.8.0, lodash@^3.9.3, lodash@~3.10.0: +lodash@3.10.1, lodash@^3.3.1, lodash@^3.8.0: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -lodash@^4.0.0, lodash@^4.14.0, lodash@^4.16.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0: +lodash@4.16.2: + version "4.16.2" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.16.2.tgz#3e626db827048a699281a8a125226326cfc0e652" + +lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.16.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.5.0, lodash@^4.6.1, lodash@^4.8.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -5090,22 +4889,10 @@ lodash@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" -lodash@~2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.2.1.tgz#ca935fd14ab3c0c872abacf198b9cda501440867" - -lodash@~2.4.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e" - lodash@~3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.2.0.tgz#4bf50a3243f9aeb0bac41a55d3d5990675a462fb" -lodash@~3.9.3: - version "3.9.3" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.9.3.tgz#0159e86832feffc6d61d852b12a953b99496bd32" - log-driver@1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056" @@ -5150,12 +4937,34 @@ lru-cache@~2.6.5: version "2.6.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.6.5.tgz#e56d6354148ede8d7707b58d143220fd08df0fd5" +lru-queue@0.1: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" + dependencies: + es5-ext "~0.10.2" + magic-string@^0.16.0: version "0.16.0" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.16.0.tgz#970ebb0da7193301285fb1aa650f39bdd81eb45a" dependencies: vlq "^0.2.1" +make-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.0.0.tgz#97a011751e91dd87cfadef58832ebb04936de978" + dependencies: + pify "^2.3.0" + +make-error-cause@^1.1.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/make-error-cause/-/make-error-cause-1.2.2.tgz#df0388fcd0b37816dff0a5fb8108939777dcbc9d" + dependencies: + make-error "^1.2.0" + +make-error@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.0.tgz#52ad3a339ccf10ce62b4040b708fe707244b8b96" + map-cache@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -5187,6 +4996,19 @@ media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" +memoizee@^0.4.5: + version "0.4.5" + resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.5.tgz#1bc3ea1e4be056dd475d521979d7be3d5e5b21c8" + dependencies: + d "1" + es5-ext "^0.10.13" + es6-weak-map "^2.0.1" + event-emitter "^0.3.4" + is-promise "^2.1" + lru-queue "0.1" + next-tick "1" + timers-ext "0.1" + memory-fs@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.2.0.tgz#f2bb25368bc121e391c2520de92969caee0a0290" @@ -5198,7 +5020,7 @@ memory-fs@^0.3.0, memory-fs@~0.3.0: errno "^0.1.3" readable-stream "^2.0.1" -memory-fs@~0.4.1: +memory-fs@^0.4.0, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" dependencies: @@ -5261,15 +5083,18 @@ micromatch@^2.1.5, micromatch@^2.3.7: parse-glob "^3.0.4" regex-cache "^0.4.2" +miller-rabin@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.0.tgz#4a62fb1d42933c05583982f4c716f6fb9e6c6d3d" + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + "mime-db@>= 1.27.0 < 2", mime-db@~1.27.0: version "1.27.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" -mime-db@~1.12.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.12.0.tgz#3d0c63180f458eb10d325aaa37d7c58ae312e9d7" - -mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.6, mime-types@~2.1.7, mime-types@~2.1.9: +mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.6, mime-types@~2.1.7, mime-types@~2.1.9: version "2.1.15" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed" dependencies: @@ -5279,12 +5104,6 @@ mime-types@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-1.0.2.tgz#995ae1392ab8affcbfcb2641dd054e943c0d5dce" -mime-types@~2.0.1, mime-types@~2.0.3: - version "2.0.14" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.0.14.tgz#310e159db23e077f8bb22b748dabfa4957140aa6" - dependencies: - mime-db "~1.12.0" - mime@1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" @@ -5301,31 +5120,32 @@ mimic-fn@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" -minimatch@0.x, minimatch@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" - dependencies: - lru-cache "2" - sigmund "~1.0.0" +minimalistic-assert@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3" + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.0: +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: brace-expansion "^1.1.7" -minimatch@2.x, minimatch@^2.0.1, minimatch@^2.0.3: - version "2.0.10" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" - dependencies: - brace-expansion "^1.0.0" - minimatch@3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" dependencies: brace-expansion "^1.0.0" +minimatch@^2.0.1: + version "2.0.10" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" + dependencies: + brace-expansion "^1.0.0" + minimatch@~0.2.11: version "0.2.14" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" @@ -5357,7 +5177,7 @@ mkdirp@0.3.x, mkdirp@~0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7" -mkdirp@0.5, mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@0.x.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@0.5, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -5439,10 +5259,6 @@ ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -mu2@~0.5.19: - version "0.5.21" - resolved "https://registry.yarnpkg.com/mu2/-/mu2-0.5.21.tgz#888a8f0fd90eb1cfda9db81476f6e199cc9e58d3" - multiparty@3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/multiparty/-/multiparty-3.3.2.tgz#35de6804dc19643e5249f3d3e3bdc6c8ce301d3f" @@ -5460,7 +5276,7 @@ mute-stream@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.4.tgz#a9219960a6d5d5d046597aee51252c6655f7177e" -mute-stream@0.0.7, mute-stream@~0.0.4: +mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" @@ -5476,11 +5292,7 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" -natural-compare@~1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.2.2.tgz#1f96d60e3141cac1b6d05653ce0daeac763af6aa" - -ncp@0.4.x, ncp@~0.4.2: +ncp@~0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/ncp/-/ncp-0.4.2.tgz#abcc6cbd3ec2ed2a729ff6e7c1fa8f01784a8574" @@ -5496,6 +5308,10 @@ netmask@~1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35" +next-tick@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + nightwatch@^0.9.5: version "0.9.16" resolved "https://registry.yarnpkg.com/nightwatch/-/nightwatch-0.9.16.tgz#c4ac3ec711b0ff047c3dca9c6557365ee236519f" @@ -5543,6 +5359,34 @@ node-libs-browser@^0.7.0: util "^0.10.3" vm-browserify "0.0.4" +node-libs-browser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.0.0.tgz#a3a59ec97024985b46e958379646f96c4b616646" + dependencies: + assert "^1.1.1" + browserify-zlib "^0.1.4" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^1.0.0" + https-browserify "0.0.1" + os-browserify "^0.2.0" + path-browserify "0.0.0" + process "^0.11.0" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.0.5" + stream-browserify "^2.0.1" + stream-http "^2.3.1" + string_decoder "^0.10.25" + timers-browserify "^2.0.2" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.10.3" + vm-browserify "0.0.4" + node-pre-gyp@^0.6.36: version "0.6.36" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786" @@ -5557,17 +5401,10 @@ node-pre-gyp@^0.6.36: tar "^2.2.1" tar-pack "^3.4.0" -node-uuid@~1.4.0, node-uuid@~1.4.7: +node-uuid@~1.4.0: version "1.4.8" resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" -"nomnom@>= 1.5.x": - version "1.8.1" - resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" - dependencies: - chalk "~0.4.0" - underscore "~1.6.0" - nopt@3.x: version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" @@ -5590,7 +5427,7 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.0.1, normalize-path@^2.1.1: +normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" dependencies: @@ -5617,11 +5454,7 @@ oauth-sign@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.5.0.tgz#d767f5169325620eab2e087ef0c472e773db6461" -oauth-sign@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.6.0.tgz#7dbeae44f6ca454e1f168451d630746735813ce3" - -oauth-sign@~0.8.0, oauth-sign@~0.8.1: +oauth-sign@~0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" @@ -5702,7 +5535,7 @@ on-headers@~1.0.0, on-headers@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" -once@1.x, once@^1.3.0, once@^1.3.3: +once@1.x, once@^1.3.0, once@^1.3.3, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: @@ -5728,7 +5561,7 @@ openurl@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/openurl/-/openurl-1.1.1.tgz#3875b4b0ef7a52c156f0db41d4609dbb0f94b387" -optimist@0.6.1, optimist@^0.6.1, optimist@~0.6.0, optimist@~0.6.1: +optimist@0.6.1, optimist@^0.6.1, optimist@~0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" dependencies: @@ -5751,18 +5584,7 @@ optimize-js@^1.0.0: magic-string "^0.16.0" yargs "^4.8.1" -optionator@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.5.0.tgz#b75a8995a2d417df25b6e4e3862f50aa88651368" - dependencies: - deep-is "~0.1.2" - fast-levenshtein "~1.0.0" - levn "~0.2.5" - prelude-ls "~1.1.1" - type-check "~0.3.1" - wordwrap "~0.0.2" - -optionator@^0.8.2: +optionator@^0.8.1, optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" dependencies: @@ -5814,14 +5636,6 @@ osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" -output-file-sync@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" - dependencies: - graceful-fs "^4.1.4" - mkdirp "^0.5.1" - object-assign "^4.1.0" - "over@>= 0.0.5 < 1": version "0.0.5" resolved "https://registry.yarnpkg.com/over/-/over-0.0.5.tgz#f29852e70fd7e25f360e013a8ec44c82aedb5708" @@ -5864,6 +5678,16 @@ pako@~0.2.0: version "0.2.9" resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" +parse-asn1@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712" + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + parse-filepath@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.1.tgz#159d6155d43904d16c10ef698911da1e91969b73" @@ -5917,10 +5741,6 @@ path-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" -path-exists@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-1.0.0.tgz#d5a8998eb71ef37a74c34eb0d9eba6e878eea081" - path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" @@ -5967,10 +5787,6 @@ path-type@^2.0.0: dependencies: pify "^2.0.0" -pathval@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-0.1.1.tgz#08f911cdca9cce5942880da7817bc0b723b66d82" - pause-stream@0.0.11: version "0.0.11" resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" @@ -5985,28 +5801,21 @@ pbkdf2-compat@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/pbkdf2-compat/-/pbkdf2-compat-2.0.1.tgz#b6e0c8fa99494d94e0511575802a59a5c142f288" -pend@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" +pbkdf2@^3.0.3: + version "3.0.12" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.12.tgz#be36785c5067ea48d806ff923288c5f750b6b8a2" + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" -phantomjs@^1.9.18: - version "1.9.20" - resolved "https://registry.yarnpkg.com/phantomjs/-/phantomjs-1.9.20.tgz#4424aca20e14d255c0b0889af6f6b8973da10e0d" - dependencies: - extract-zip "~1.5.0" - fs-extra "~0.26.4" - hasha "^2.2.0" - kew "~0.7.0" - progress "~1.1.8" - request "~2.67.0" - request-progress "~2.0.1" - which "~1.2.2" - -pify@^2.0.0: +pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -6026,19 +5835,17 @@ pkg-dir@^1.0.0: dependencies: find-up "^1.0.0" -pkginfo@0.3.x: - version "0.3.1" - resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21" - -pkginfo@0.x.x: - version "0.4.0" - resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.0.tgz#349dbb7ffd38081fcadc0853df687f0c7744cd65" +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + dependencies: + find-up "^2.1.0" pluralize@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-4.0.0.tgz#59b708c1c0190a2f692f1c7618c446b052fd1762" -prelude-ls@~1.1.0, prelude-ls@~1.1.1, prelude-ls@~1.1.2: +prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -6050,7 +5857,7 @@ pretty-hrtime@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" -private@^0.1.6, private@~0.1.5: +private@^0.1.6: version "0.1.7" resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1" @@ -6066,29 +5873,15 @@ progress@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" -progress@~1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" - promise.prototype.finally@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-1.0.1.tgz#91182f91c92486995740fa05e0da942ac986befa" "promise@>=3.2 <8": version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - dependencies: - asap "~2.0.3" - -prompt@~0.2.14: - version "0.2.14" - resolved "https://registry.yarnpkg.com/prompt/-/prompt-0.2.14.tgz#57754f64f543fd7b0845707c818ece618f05ffdc" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" dependencies: - pkginfo "0.x.x" - read "1.0.x" - revalidator "0.1.x" - utile "0.2.x" - winston "0.8.x" + asap "~2.0.3" proxy-agent@2.0.0: version "2.0.0" @@ -6115,6 +5908,16 @@ prr@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" +public-encrypt@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6" + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + "pullstream@>= 0.4.1 < 1": version "0.4.1" resolved "https://registry.yarnpkg.com/pullstream/-/pullstream-0.4.1.tgz#d6fb3bf5aed697e831150eb1002c25a3f8ae1314" @@ -6132,22 +5935,22 @@ punycode@^1.2.4, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" -q@1.4.1, q@~1.4.1: +q@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" -q@^1.1.2, q@~1.5.0: +q@^1.4.1, q@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" -q@~0.9.6: - version "0.9.7" - resolved "https://registry.yarnpkg.com/q/-/q-0.9.7.tgz#4de2e6cb3b29088c9e4cbc03bf9d42fb96ce2f75" - q@~1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/q/-/q-1.3.0.tgz#850d79f8cb831d92e103b46483e4e35d34640050" +qjobs@^1.1.4: + version "1.1.5" + resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.1.5.tgz#659de9f2cf8dcc27a1481276f205377272382e73" + qs@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/qs/-/qs-4.0.0.tgz#c31d9b74ec27df75e543a86c78728ed8d4623607" @@ -6164,18 +5967,10 @@ qs@~2.3.1: version "2.3.3" resolved "https://registry.yarnpkg.com/qs/-/qs-2.3.3.tgz#e9e85adbe75da0bbe4c8e0476a086290f863b404" -qs@~2.4.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-2.4.2.tgz#f7ce788e5777df0b5010da7f7c4e73ba32470f5a" - qs@~5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/qs/-/qs-5.1.0.tgz#4d932e5c7ea411cca76a312d39a606200fd50cd9" -qs@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.1.tgz#801fee030e0b9450d6385adc48a4cc55b44aedfc" - qs@~6.3.0: version "6.3.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" @@ -6207,7 +6002,13 @@ randomatic@^1.1.3: is-number "^3.0.0" kind-of "^4.0.0" -range-parser@^1.0.3: +randombytes@^2.0.0, randombytes@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79" + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.0.3, range-parser@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" @@ -6270,22 +6071,16 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" -read@1.0.x: - version "1.0.7" - resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" - dependencies: - mute-stream "~0.0.4" - -readable-stream@1.1, readable-stream@1.1.x, readable-stream@~1.1.8, readable-stream@~1.1.9: - version "1.1.13" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e" +readable-stream@1.1.x, readable-stream@~1.1.8, readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" dependencies: core-util-is "~1.0.0" inherits "~2.0.1" isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6: +readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6: version "2.3.3" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" dependencies: @@ -6306,17 +6101,6 @@ readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stre isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@~2.0.0, readable-stream@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~0.10.x" - util-deprecate "~1.0.1" - readdirp@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" @@ -6333,33 +6117,6 @@ readline2@^0.1.1: mute-stream "0.0.4" strip-ansi "^2.0.1" -recast@0.10.33: - version "0.10.33" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.33.tgz#942808f7aa016f1fa7142c461d7e5704aaa8d697" - dependencies: - ast-types "0.8.12" - esprima-fb "~15001.1001.0-dev-harmony-fb" - private "~0.1.5" - source-map "~0.5.0" - -recast@^0.10.10: - version "0.10.43" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.43.tgz#b95d50f6d60761a5f6252e15d80678168491ce7f" - dependencies: - ast-types "0.8.15" - esprima-fb "~15001.1001.0-dev-harmony-fb" - private "~0.1.5" - source-map "~0.5.0" - -recast@^0.11.17: - version "0.11.23" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3" - dependencies: - ast-types "0.9.6" - esprima "~3.1.0" - private "~0.1.5" - source-map "~0.5.0" - rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -6409,17 +6166,6 @@ regenerator-transform@0.9.11: babel-types "^6.19.0" private "^0.1.6" -regenerator@0.8.40: - version "0.8.40" - resolved "https://registry.yarnpkg.com/regenerator/-/regenerator-0.8.40.tgz#a0e457c58ebdbae575c9f8cd75127e93756435d8" - dependencies: - commoner "~0.10.3" - defs "~1.1.0" - esprima-fb "~15001.1001.0-dev-harmony-fb" - private "~0.1.5" - recast "0.10.33" - through "~2.3.8" - regex-cache@^0.4.2: version "0.4.3" resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" @@ -6435,16 +6181,6 @@ regexpu-core@^2.0.0: regjsgen "^0.2.0" regjsparser "^0.1.4" -regexpu@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexpu/-/regexpu-1.3.0.tgz#e534dc991a9e5846050c98de6d7dd4a55c9ea16d" - dependencies: - esprima "^2.6.0" - recast "^0.10.10" - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - regjsgen@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" @@ -6471,12 +6207,6 @@ repeat-string@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" -repeating@^1.1.0, repeating@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-1.1.3.tgz#3d4114218877537494f97f77f9785fab810fa4ac" - dependencies: - is-finite "^1.0.0" - repeating@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" @@ -6507,12 +6237,6 @@ req-then@0.5.1: lodash.pick "^4.4.0" typical "^2.6.0" -request-progress@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-2.0.1.tgz#5d36bb57961c673aa5b788dbc8141fdf23b44e08" - dependencies: - throttleit "^1.0.0" - request@2.49.0: version "2.49.0" resolved "https://registry.yarnpkg.com/request/-/request-2.49.0.tgz#0d4f6348dc3348059b553e4db60fd2478de662a7" @@ -6586,54 +6310,6 @@ request@2.81.0, request@^2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" -request@~2.55.0: - version "2.55.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.55.0.tgz#d75c1cdf679d76bb100f9bffe1fe551b5c24e93d" - dependencies: - aws-sign2 "~0.5.0" - bl "~0.9.0" - caseless "~0.9.0" - combined-stream "~0.0.5" - forever-agent "~0.6.0" - form-data "~0.2.0" - har-validator "^1.4.0" - hawk "~2.3.0" - http-signature "~0.10.0" - isstream "~0.1.1" - json-stringify-safe "~5.0.0" - mime-types "~2.0.1" - node-uuid "~1.4.0" - oauth-sign "~0.6.0" - qs "~2.4.0" - stringstream "~0.0.4" - tough-cookie ">=0.12.0" - tunnel-agent "~0.4.0" - -request@~2.67.0: - version "2.67.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.67.0.tgz#8af74780e2bf11ea0ae9aa965c11f11afd272742" - dependencies: - aws-sign2 "~0.6.0" - bl "~1.0.0" - caseless "~0.11.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~1.0.0-rc3" - har-validator "~2.0.2" - hawk "~3.1.0" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - node-uuid "~1.4.7" - oauth-sign "~0.8.0" - qs "~5.2.0" - stringstream "~0.0.4" - tough-cookie "~2.2.0" - tunnel-agent "~0.4.1" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -6663,10 +6339,6 @@ requizzle@~0.2.1: dependencies: underscore "~1.6.0" -reserved-words@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/reserved-words/-/reserved-words-0.1.1.tgz#6f7c15e5e5614c50da961630da46addc87c0cef2" - resolve-dir@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e" @@ -6706,10 +6378,6 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" -revalidator@0.1.x: - version "0.1.8" - resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b" - rewire@2.5.2: version "2.5.2" resolved "https://registry.yarnpkg.com/rewire/-/rewire-2.5.2.tgz#6427de7b7feefa7d36401507eb64a5385bc58dc7" @@ -6724,15 +6392,17 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.5.1, rimraf@^2.6.1: +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.0, rimraf@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" dependencies: glob "^7.0.5" -rimraf@2.2.6: - version "2.2.6" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.6.tgz#c59597569b14d956ad29cacc42bdddf5f0ea4f4c" +rimraf@2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.3.tgz#e5b51c9437a4c582adb955e9f28cf8d945e272af" + dependencies: + glob "^5.0.14" rimraf@~2.2.0: version "2.2.8" @@ -6742,6 +6412,13 @@ ripemd160@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-0.2.0.tgz#2bf198bde167cacfa51c0a928e84b68bbe171fce" +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7" + dependencies: + hash-base "^2.0.0" + inherits "^2.0.1" + rndm@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/rndm/-/rndm-1.2.0.tgz#f33fe9cfb52bbfd520aa18323bc65db110a1b76c" @@ -6766,7 +6443,7 @@ rx@^2.4.3: version "2.5.3" resolved "https://registry.yarnpkg.com/rx/-/rx-2.5.3.tgz#21adc7d80f02002af50dae97fd9dbf248755f566" -safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" @@ -6774,18 +6451,21 @@ samsam@1.1.2, samsam@~1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567" -sauce-connect-launcher@~0.11.1: - version "0.11.1" - resolved "https://registry.yarnpkg.com/sauce-connect-launcher/-/sauce-connect-launcher-0.11.1.tgz#65f51d8891249fdabaaf17599734de1902476129" +sauce-connect-launcher@^0.17.0: + version "0.17.0" + resolved "https://registry.yarnpkg.com/sauce-connect-launcher/-/sauce-connect-launcher-0.17.0.tgz#908d9311ecaf17dd9b4647a1435fd4a2072e80ce" dependencies: adm-zip "~0.4.3" - async "0.9.0" - lodash "3.5.0" - rimraf "2.2.6" + async "1.4.0" + https-proxy-agent "~1.0.0" + lodash "3.10.1" + rimraf "2.4.3" -saucelabs@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/saucelabs/-/saucelabs-0.1.1.tgz#5e0ea1cf3d735d6ea15fde94b5bda6bc15d2c06d" +saucelabs@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/saucelabs/-/saucelabs-1.4.0.tgz#b934a9af9da2874b3f40aae1fcde50a4466f5f38" + dependencies: + https-proxy-agent "^1.0.0" "semver@2 || 3 || 4 || 5", semver@5.3.0, semver@^5.3.0: version "5.3.0" @@ -6869,9 +6549,11 @@ sha.js@2.2.6: version "2.2.6" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.2.6.tgz#17ddeddc5f722fb66501658895461977867315ba" -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.8" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.8.tgz#37068c2c476b6baf402d14a49c67f597921f634f" + dependencies: + inherits "^2.0.1" sigmund@~1.0.0: version "1.0.1" @@ -6881,14 +6563,6 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" -simple-fmt@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/simple-fmt/-/simple-fmt-0.1.0.tgz#191bf566a59e6530482cb25ab53b4a8dc85c3a6b" - -simple-is@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/simple-is/-/simple-is-0.2.0.tgz#2abb75aade39deb5cc815ce10e6191164850baf0" - sinon@^1.12.1: version "1.17.7" resolved "https://registry.yarnpkg.com/sinon/-/sinon-1.17.7.tgz#4542a4f49ba0c45c05eb2e9dd9d203e2b8efe0bf" @@ -6935,15 +6609,15 @@ socket.io-adapter@0.5.0: debug "2.3.3" socket.io-parser "2.3.1" -socket.io-client@1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-1.7.4.tgz#ec9f820356ed99ef6d357f0756d648717bdd4281" +socket.io-client@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-1.7.3.tgz#b30e86aa10d5ef3546601c09cde4765e381da377" dependencies: backo2 "1.0.2" component-bind "1.0.0" component-emitter "1.2.1" debug "2.3.3" - engine.io-client "~1.8.4" + engine.io-client "1.8.3" has-binary "0.1.7" indexof "0.0.1" object-component "0.0.3" @@ -6960,16 +6634,16 @@ socket.io-parser@2.3.1: isarray "0.0.1" json3 "3.3.2" -socket.io@^1.4.5: - version "1.7.4" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.7.4.tgz#2f7ecedc3391bf2d5c73e291fe233e6e34d4dd00" +socket.io@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.7.3.tgz#b8af9caba00949e568e369f1327ea9be9ea2461b" dependencies: debug "2.3.3" - engine.io "~1.8.4" + engine.io "1.8.3" has-binary "0.1.7" object-assign "4.1.0" socket.io-adapter "0.5.0" - socket.io-client "1.7.4" + socket.io-client "1.7.3" socket.io-parser "2.3.1" socks-proxy-agent@2: @@ -6995,6 +6669,10 @@ sort-array@^1.0.0: object-get "^2.1.0" typical "^2.6.0" +source-list-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" + source-list-map@~0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" @@ -7008,12 +6686,6 @@ source-map-resolve@^0.3.0: source-map-url "~0.3.0" urix "~0.1.0" -source-map-support@^0.2.10: - version "0.2.10" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.2.10.tgz#ea5a3900a1c1cb25096a0ae8cc5c2b4b10ded3dc" - dependencies: - source-map "0.1.32" - source-map-support@^0.4.2: version "0.4.15" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1" @@ -7024,13 +6696,7 @@ source-map-url@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9" -source-map@0.1.32: - version "0.1.32" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.32.tgz#c8b6c167797ba4740a8ea33252162ff08591b266" - dependencies: - amdefine ">=0.0.4" - -source-map@0.X, source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.1: +source-map@0.X, source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" @@ -7082,7 +6748,7 @@ split@0.3: dependencies: through "2" -sprintf-js@~1.0.2: +sprintf-js@^1.0.3, sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -7100,14 +6766,6 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" -stable@~0.1.3: - version "0.1.6" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.6.tgz#910f5d2aed7b520c6e777499c1f32e139fdecb10" - -stack-trace@0.0.x: - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - statuses@1, "statuses@>= 1.3.1 < 2", statuses@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" @@ -7174,14 +6832,15 @@ stream-via@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/stream-via/-/stream-via-0.1.1.tgz#0cee5df9c959fb1d3f4eda4819f289d5f9205afc" -string-replace-webpack-plugin@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/string-replace-webpack-plugin/-/string-replace-webpack-plugin-0.0.3.tgz#82c67448cea95ec002a1bfcfd2fb0195cd12bd24" +string-replace-webpack-plugin@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/string-replace-webpack-plugin/-/string-replace-webpack-plugin-0.1.3.tgz#73c657e759d66cfe80ae1e0cf091aa256d0e715c" dependencies: async "~0.2.10" + loader-utils "~0.2.3" + optionalDependencies: css-loader "^0.9.1" file-loader "^0.8.1" - loader-utils "~0.2.3" style-loader "^0.8.3" string-tools@^0.1.4: @@ -7200,7 +6859,7 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.0.0: +string-width@^2.0.0, string-width@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.0.tgz#030664561fc146c9423ec7d978fe2457437fe6d0" dependencies: @@ -7217,14 +6876,6 @@ string_decoder@~1.0.3: dependencies: safe-buffer "~5.1.0" -stringmap@~0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/stringmap/-/stringmap-0.2.2.tgz#556c137b258f942b8776f5b2ef582aa069d7d1b1" - -stringset@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/stringset/-/stringset-0.2.1.tgz#ef259c4e349344377fcd1c913dd2e848c9c042b5" - stringstream@~0.0.4: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" @@ -7253,10 +6904,6 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" - strip-bom-string@1.X: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" @@ -7284,10 +6931,6 @@ strip-indent@^1.0.1: dependencies: get-stdin "^4.0.1" -strip-json-comments@~1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" - strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -7316,12 +6959,18 @@ supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -supports-color@^3.1.0: +supports-color@^3.1.0, supports-color@^3.1.2: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" dependencies: has-flag "^1.0.0" +supports-color@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.2.0.tgz#ad986dc7eb2315d009b4d77c8169c2231a684037" + dependencies: + has-flag "^2.0.0" + table-layout@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-0.3.0.tgz#6ee20dc483db371b3e5c87f704ed2f7c799d2c9a" @@ -7352,6 +7001,10 @@ tapable@^0.1.8, tapable@~0.1.8: version "0.1.10" resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4" +tapable@^0.2.5, tapable@~0.2.5: + version "0.2.6" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.6.tgz#206be8e188860b514425375e6f1ae89bfb01fd8d" + tar-pack@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984" @@ -7365,6 +7018,15 @@ tar-pack@^3.4.0: tar "^2.2.1" uid-number "^0.0.6" +tar-stream@^1.5.0: + version "1.5.4" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.4.tgz#36549cf04ed1aee9b2a30c0143252238daf94016" + dependencies: + bl "^1.0.0" + end-of-stream "^1.0.0" + readable-stream "^2.0.0" + xtend "^4.0.0" + tar-stream@~1.1.0: version "1.1.5" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.1.5.tgz#be9218c130c20029e107b0f967fb23de0579d13c" @@ -7423,10 +7085,6 @@ then-fs@^2.0.0: dependencies: promise ">=3.2 <8" -throttleit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" - through2@2.X, through2@^2.0.0, through2@^2.0.1, through2@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" @@ -7434,13 +7092,6 @@ through2@2.X, through2@^2.0.0, through2@^2.0.1, through2@^2.0.3: readable-stream "^2.1.5" xtend "~4.0.1" -"through2@>=0.6.1 <1.0.0-0", through2@^0.6.1, through2@^0.6.5: - version "0.6.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" - dependencies: - readable-stream ">=1.0.33-1 <1.1.0-0" - xtend ">=4.0.0 <4.1.0-0" - through2@^0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/through2/-/through2-0.4.2.tgz#dbf5866031151ec8352bb6c4db64a2292a840b9b" @@ -7455,7 +7106,14 @@ through2@^0.5.0: readable-stream "~1.0.17" xtend "~3.0.0" -through@2, through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.1, through@~2.3.4, through@~2.3.8: +through2@^0.6.1, through2@^0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through@2, through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.1, through@~2.3.4: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -7479,6 +7137,13 @@ timers-browserify@^2.0.2: dependencies: setimmediate "^1.0.4" +timers-ext@0.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.2.tgz#61cc47a76c1abd3195f14527f978d58ae94c5204" + dependencies: + es5-ext "~0.10.14" + next-tick "1" + tiny-lr@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-0.2.1.tgz#b3fdba802e5d56a33c2f6f10794b32e477ac729d" @@ -7490,7 +7155,7 @@ tiny-lr@^0.2.1: parseurl "~1.3.0" qs "~5.1.0" -tmp@0.0.x, tmp@^0.0.31: +tmp@0.0.31, tmp@0.0.x, tmp@^0.0.31: version "0.0.31" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" dependencies: @@ -7504,28 +7169,16 @@ to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" -to-double-quotes@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-double-quotes/-/to-double-quotes-2.0.0.tgz#aaf231d6fa948949f819301bbab4484d8588e4a7" - -to-fast-properties@^1.0.0, to-fast-properties@^1.0.1: +to-fast-properties@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" -to-single-quotes@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/to-single-quotes/-/to-single-quotes-2.0.1.tgz#7cc29151f0f5f2c41946f119f5932fe554170125" - tough-cookie@>=0.12.0, tough-cookie@~2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" dependencies: punycode "^1.4.1" -tough-cookie@~2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.2.2.tgz#c83a1830f4e5ef0b93ef2a3488e724f8de016ac7" - "traverse@>=0.3.0 <0.4": version "0.3.9" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" @@ -7534,22 +7187,14 @@ trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" -trim-right@^1.0.0, trim-right@^1.0.1: +trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" -try-resolve@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/try-resolve/-/try-resolve-1.0.1.tgz#cfde6fabd72d63e5797cfaab873abbe8e700e912" - tryit@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" -tryor@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/tryor/-/tryor-0.1.2.tgz#8145e4ca7caff40acde3ccf946e8b8bb75b4172b" - tsscmp@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.5.tgz#7dc4a33af71581ab4337da91d85ca5427ebd9a97" @@ -7572,7 +7217,7 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" -type-check@~0.3.1, type-check@~0.3.2: +type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" dependencies: @@ -7593,7 +7238,7 @@ type-is@~1.6.10, type-is@~1.6.15, type-is@~1.6.6: media-typer "0.3.0" mime-types "~2.1.15" -typedarray@^0.0.6, typedarray@~0.0.5: +typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -7601,16 +7246,7 @@ typical@^2.1, typical@^2.2, typical@^2.3.0, typical@^2.4.2, typical@^2.5.0, typi version "2.6.1" resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" -uglify-js@2.4.6: - version "2.4.6" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.4.6.tgz#31766a4d822babf5f32c14096251ed9259298ad3" - dependencies: - async "~0.2.6" - optimist "~0.3.5" - source-map "~0.1.7" - uglify-to-browserify "~1.0.0" - -uglify-js@^2.6, uglify-js@^2.8.10: +uglify-js@^2.6, uglify-js@^2.8.10, uglify-js@^2.8.29: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" dependencies: @@ -7619,6 +7255,13 @@ uglify-js@^2.6, uglify-js@^2.8.10: optionalDependencies: uglify-to-browserify "~1.0.0" +uglify-js@^3.0.5: + version "3.0.24" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.0.24.tgz#ee93400ad9857fb7a1671778db83f6a23f033121" + dependencies: + commander "~2.9.0" + source-map "~0.5.1" + uglify-js@~2.3: version "2.3.6" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.3.6.tgz#fa0984770b428b7a9b2a8058f46355d14fef211a" @@ -7640,6 +7283,14 @@ uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" +uglifyjs-webpack-plugin@^0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309" + dependencies: + source-map "^0.5.6" + uglify-js "^2.8.29" + webpack-sources "^1.0.1" + uid-number@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" @@ -7670,9 +7321,12 @@ underscore-contrib@~0.3.0: dependencies: underscore "1.6.0" -underscore.string@~3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.0.3.tgz#4617b8c1a250cf6e5064fbbb363d0fa96cf14552" +underscore.string@3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.3.4.tgz#2c2a3f9f83e64762fdc45e6ceac65142864213db" + dependencies: + sprintf-js "^1.0.3" + util-deprecate "^1.0.2" underscore@1.6.0, underscore@~1.6.0: version "1.6.0" @@ -7744,14 +7398,14 @@ user-home@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" -useragent@^2.1.6: - version "2.2.0" - resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.2.0.tgz#ef85f41903cfd05e2ba8c11ae61249c7a6bbf663" +useragent@^2.1.12: + version "2.2.1" + resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.2.1.tgz#cf593ef4f2d175875e8bb658ea92e18a4fd06d8e" dependencies: lru-cache "2.2.x" tmp "0.0.x" -util-deprecate@~1.0.1: +util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -7761,25 +7415,10 @@ util@0.10.3, "util@>=0.10.3 <1", util@^0.10.3: dependencies: inherits "2.0.1" -utile@0.2.x: - version "0.2.1" - resolved "https://registry.yarnpkg.com/utile/-/utile-0.2.1.tgz#930c88e99098d6220834c356cbd9a770522d90d7" - dependencies: - async "~0.2.9" - deep-equal "*" - i "0.3.x" - mkdirp "0.x.x" - ncp "0.4.x" - rimraf "2.x.x" - utils-merge@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" -uuid@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" - uuid@^3.0.0, uuid@^3.0.1: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" @@ -7797,7 +7436,7 @@ validate-npm-package-license@^3.0.1: spdx-correct "~1.0.0" spdx-expression-parse "~1.0.0" -vargs@~0.1.0: +vargs@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/vargs/-/vargs-0.1.0.tgz#6b6184da6520cc3204ce1b407cac26d92609ebff" @@ -7892,25 +7531,6 @@ void-elements@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" -vow-fs@~0.3.4: - version "0.3.6" - resolved "https://registry.yarnpkg.com/vow-fs/-/vow-fs-0.3.6.tgz#2d4c59be22e2bf2618ddf597ab4baa923be7200d" - dependencies: - glob "^7.0.5" - uuid "^2.0.2" - vow "^0.4.7" - vow-queue "^0.4.1" - -vow-queue@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/vow-queue/-/vow-queue-0.4.2.tgz#e7fe17160e15c7c4184d1b666a9bc64e18e30184" - dependencies: - vow "~0.4.0" - -vow@^0.4.7, vow@~0.4.0, vow@~0.4.8: - version "0.4.16" - resolved "https://registry.yarnpkg.com/vow/-/vow-0.4.16.tgz#bb9d54d938d5f80520d658a740e7a895e30feeeb" - walk-back@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/walk-back/-/walk-back-2.0.1.tgz#554e2a9d874fac47a8cb006bf44c2f0c4998a0a4" @@ -7921,6 +7541,10 @@ walk@^2.3.9: dependencies: foreachasync "^3.0.0" +walkdir@^0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.0.11.tgz#a16d025eb931bd03b52f308caed0f40fcebe9532" + watchpack@^0.2.1: version "0.2.9" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-0.2.9.tgz#62eaa4ab5e5ba35fdfc018275626e3c0f5e3fb0b" @@ -7929,17 +7553,26 @@ watchpack@^0.2.1: chokidar "^1.0.0" graceful-fs "^4.1.2" -wd@~0.3.4: - version "0.3.12" - resolved "https://registry.yarnpkg.com/wd/-/wd-0.3.12.tgz#3fb4f1d759f8c85dde5393d17334ffe03e9bb329" +watchpack@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.3.1.tgz#7d8693907b28ce6013e7f3610aa2a1acf07dad87" + dependencies: + async "^2.1.2" + chokidar "^1.4.3" + graceful-fs "^4.1.2" + +wd@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/wd/-/wd-1.3.0.tgz#fdbdfbe192805b1cbd7943375642f06d990bccef" dependencies: - archiver "~0.14.0" - async "~1.0.0" - lodash "~3.9.3" - q "~1.4.1" - request "~2.55.0" - underscore.string "~3.0.3" - vargs "~0.1.0" + archiver "1.3.0" + async "2.0.1" + lodash "4.16.2" + mkdirp "^0.5.1" + q "1.4.1" + request "2.79.0" + underscore.string "3.3.4" + vargs "0.1.0" webdriverio@^3.4.0: version "3.4.0" @@ -7979,7 +7612,14 @@ webpack-dev-middleware@^1.0.11: path-is-absolute "^1.0.0" range-parser "^1.0.3" -webpack-stream@^3.1.0: +webpack-sources@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.0.1.tgz#c7356436a4d13123be2e2426a05d1dad9cbe65cf" + dependencies: + source-list-map "^2.0.0" + source-map "~0.5.3" + +webpack-stream@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/webpack-stream/-/webpack-stream-3.2.0.tgz#3a1d160fb11d41727b7ce6f32f722464f98b2186" dependencies: @@ -7991,7 +7631,7 @@ webpack-stream@^3.1.0: vinyl "^1.1.0" webpack "^1.12.9" -webpack@^1.12.3, webpack@^1.12.9: +webpack@^1.12.9: version "1.15.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-1.15.0.tgz#4ff31f53db03339e55164a9d468ee0324968fe98" dependencies: @@ -8011,6 +7651,33 @@ webpack@^1.12.3, webpack@^1.12.9: watchpack "^0.2.1" webpack-core "~0.6.9" +webpack@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.2.0.tgz#8b0cae0e1a9fd76bfbf0eab61a8c2ada848c312f" + dependencies: + acorn "^5.0.0" + acorn-dynamic-import "^2.0.0" + ajv "^5.1.5" + ajv-keywords "^2.0.0" + async "^2.1.2" + enhanced-resolve "^3.3.0" + escope "^3.6.0" + interpret "^1.0.0" + json-loader "^0.5.4" + json5 "^0.5.1" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + mkdirp "~0.5.0" + node-libs-browser "^2.0.0" + source-map "^0.5.3" + supports-color "^3.1.0" + tapable "~0.2.5" + uglifyjs-webpack-plugin "^0.4.6" + watchpack "^1.3.1" + webpack-sources "^1.0.1" + yargs "^6.0.0" + websocket-driver@>=0.5.1: version "0.6.5" resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36" @@ -8029,16 +7696,12 @@ which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" -which@^1.1.1, which@^1.2.1, which@^1.2.12, which@~1.2.2: +which@^1.1.1, which@^1.2.1, which@^1.2.12: version "1.2.14" resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" dependencies: isexe "^2.0.0" -which@~1.0.5: - version "1.0.9" - resolved "https://registry.yarnpkg.com/which/-/which-1.0.9.tgz#460c1da0f810103d0321a9b633af9e575e64486f" - wide-align@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" @@ -8057,18 +7720,6 @@ window-size@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" -winston@0.8.x: - version "0.8.3" - resolved "https://registry.yarnpkg.com/winston/-/winston-0.8.3.tgz#64b6abf4cd01adcaefd5009393b1d8e8bec19db0" - dependencies: - async "0.2.x" - colors "0.6.x" - cycle "1.0.x" - eyes "0.1.x" - isstream "0.1.x" - pkginfo "0.3.x" - stack-trace "0.0.x" - wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" @@ -8121,23 +7772,10 @@ ws@1.1.2: options ">=0.0.5" ultron "1.0.x" -ws@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.4.tgz#57f40d036832e5f5055662a397c4de76ed66bf61" - dependencies: - options ">=0.0.5" - ultron "1.0.x" - wtf-8@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a" -xmlbuilder@3.1.0, xmlbuilder@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-3.1.0.tgz#2c86888f2d4eade850fa38ca7f7223f7209516e1" - dependencies: - lodash "^3.5.0" - xmlhttprequest-ssl@1.5.3: version "1.5.3" resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz#185a888c04eca46c3e4070d99f7b49de3528992d" @@ -8171,6 +7809,12 @@ yargs-parser@^2.4.1: camelcase "^3.0.0" lodash.assign "^4.0.6" +yargs-parser@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" + dependencies: + camelcase "^3.0.0" + yargs@3.29.0: version "3.29.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.29.0.tgz#1aab9660eae79d8b8f675bcaeeab6ee34c2cf69c" @@ -8205,6 +7849,24 @@ yargs@^4.8.1: y18n "^3.2.1" yargs-parser "^2.4.1" +yargs@^6.0.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^4.2.0" + yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" @@ -8214,27 +7876,19 @@ yargs@~3.10.0: decamelize "^1.0.0" window-size "0.1.0" -yargs@~3.27.0: - version "3.27.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.27.0.tgz#21205469316e939131d59f2da0c6d7f98221ea40" - dependencies: - camelcase "^1.2.1" - cliui "^2.1.0" - decamelize "^1.0.0" - os-locale "^1.4.0" - window-size "^0.1.2" - y18n "^3.2.0" - -yauzl@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" - dependencies: - fd-slicer "~1.0.1" - yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" +zip-stream@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-1.2.0.tgz#a8bc45f4c1b49699c6b90198baacaacdbcd4ba04" + dependencies: + archiver-utils "^1.3.0" + compress-commons "^1.2.0" + lodash "^4.8.0" + readable-stream "^2.0.0" + zip-stream@~0.5.0: version "0.5.2" resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-0.5.2.tgz#32dcbc506d0dab4d21372625bd7ebaac3c2fff56" From d468f33af7fb918910bcdef54b3c01f3e24d5ac2 Mon Sep 17 00:00:00 2001 From: Anand Venkatraman Date: Mon, 17 Jul 2017 23:10:39 +0530 Subject: [PATCH 79/95] PulsePoint Lite adapter - adding createNew method for aliasing. (#1383) * ET-1691: Pulsepoint Analytics adapter for Prebid. (#1) * ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter * ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter * ET-1691: cleanup * ET-1691: minor * ET-1691: revert package.json change * Adding bidRequest to bidFactory.createBid method as per https://github.com/prebid/Prebid.js/issues/509 * ET-1765: Adding support for additional params in PulsePoint adapter (#2) * ET-1850: Fixing https://github.com/prebid/Prebid.js/issues/866 * Minor fix * Adding createNew method on the adapter for aliasing --- modules/pulsepointLiteBidAdapter.js | 3 +++ test/spec/modules/pulsepointLiteBidAdapter_spec.js | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/modules/pulsepointLiteBidAdapter.js b/modules/pulsepointLiteBidAdapter.js index b9ce3aacb56..dd04c982e0f 100644 --- a/modules/pulsepointLiteBidAdapter.js +++ b/modules/pulsepointLiteBidAdapter.js @@ -285,6 +285,9 @@ function PulsePointLiteAdapter() { }; } +PulsePointLiteAdapter.createNew = function() { + return new PulsePointLiteAdapter(); +} /** * "pulseLite" will be the adapter name going forward. "pulsepointLite" to be * deprecated, but kept here for backwards compatibility. diff --git a/test/spec/modules/pulsepointLiteBidAdapter_spec.js b/test/spec/modules/pulsepointLiteBidAdapter_spec.js index 9532685a037..2a8b09245a2 100644 --- a/test/spec/modules/pulsepointLiteBidAdapter_spec.js +++ b/test/spec/modules/pulsepointLiteBidAdapter_spec.js @@ -226,4 +226,9 @@ describe('PulsePoint Lite Adapter Tests', () => { expect(bid.native.impressionTrackers[0]).to.equal('http://imp1.trackme.com/'); expect(bid.native.impressionTrackers[1]).to.equal('http://imp1.contextweb.com/'); }); + + it('Verify createNew', function () { + const adapter = PulsePointAdapter.createNew(); + expect(adapter).to.have.property('callBids'); + }); }); From b566fca220127aea73e65e1d51a6611da7581b76 Mon Sep 17 00:00:00 2001 From: Matt Lane Date: Mon, 17 Jul 2017 12:26:07 -0700 Subject: [PATCH 80/95] Prebid 0.26.0 Release (#1384) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b8640716ac8..161c6065aae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "0.26.0-pre", + "version": "0.26.0", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From f0ba1fc79705dde6e8cceaa31cc13ea059c41b64 Mon Sep 17 00:00:00 2001 From: Matt Lane Date: Mon, 17 Jul 2017 13:14:50 -0700 Subject: [PATCH 81/95] Increment pre version (#1385) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 161c6065aae..9eb05e2c523 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "0.26.0", + "version": "0.27.0-pre", "description": "Header Bidding Management Library", "main": "src/prebid.js", "scripts": { From 58a8c35b5bd5d6e425537eda14ec3405c583ecb8 Mon Sep 17 00:00:00 2001 From: Bart van Bragt Date: Tue, 18 Jul 2017 21:36:45 +0200 Subject: [PATCH 82/95] Mention NodeJS 4.0 dependency in the README (#1386) * Mention NodeJS 4.0 dependency in the README This caused me some trouble on a Debian Jessie machine (which ships with NodeJS 0.10). * Require NodeJS => 4.0 * (re)move note about NodeJS --- README.md | 6 +++--- package.json | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 023d08cd2a3..26e3f27d16a 100644 --- a/README.md +++ b/README.md @@ -28,10 +28,12 @@ Working examples can be found in [the developer docs](http://prebid.org/dev-docs $ cd Prebid.js $ yarn install -Prebid also supports the `yarn` npm client. This is an alternative to using `npm` for package management, though `npm` will continue to work as before. +Prebid supports the `yarn` npm client. This is an alternative to using `npm` for package management, though `npm install` will continue to work as before. For more info, see [the Yarn documentation](https://yarnpkg.com). +*Note:* You need to have `NodeJS` 4.x or greater installed. + ## Build for Development @@ -47,8 +49,6 @@ This runs some code quality checks, starts a web server at `http://localhost:999 + `./build/dist/prebid.js` - Minified production code + `./prebid.js_.zip` - Distributable zip archive -*Note:* You need to have `node.js` 4.x or greater installed to be able to run the `gulp build` commands. - ### Build Optimization The standard build output contains all the available modules from within the `modules` folder. diff --git a/package.json b/package.json index 9eb05e2c523..feb3857e8f9 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,9 @@ "globalVarName": "pbjs", "author": "the prebid.js contributors", "license": "Apache-2.0", + "engines": { + "node": ">=4.0" + }, "devDependencies": { "babel-core": "6.22.0", "babel-loader": "^7.1.1", From 1eea8f2f40889d432fb4d553b7a127ad1dd5f1c2 Mon Sep 17 00:00:00 2001 From: Rich Snapp Date: Tue, 18 Jul 2017 15:15:22 -0600 Subject: [PATCH 83/95] Fix banner showing up in prebid-core.js (#1388) --- gulpfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index 9b5742cb180..2572420904d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -138,7 +138,7 @@ gulp.task('webpack', ['clean'], function () { .pipe(webpackStream(cloned, webpack)) .pipe(replace('$prebid.version$', prebid.version)) .pipe(uglify()) - .pipe(gulpif(file => file.basename === 'prebid.js', header(banner, { prebid: prebid }))) + .pipe(gulpif(file => file.basename === 'prebid-core.js', header(banner, { prebid: prebid }))) .pipe(optimizejs()) .pipe(gulp.dest('build/dist')) .pipe(connect.reload()); From a9887520648803f4b7503c44929256bb3f40a2cf Mon Sep 17 00:00:00 2001 From: dbemiller Date: Fri, 21 Jul 2017 11:34:45 -0400 Subject: [PATCH 84/95] Fixing the BidAdjustmentEvent fire time (#1399) * Fired the bid adjustment event at (what I think is) the appropriate time. * More thorough tests. * Better test description. * Removed a stray console.log --- src/bidmanager.js | 11 ++++++----- test/spec/unit/bidmanager_spec.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/bidmanager.js b/src/bidmanager.js index cd910c54524..ff32aa3e905 100644 --- a/src/bidmanager.js +++ b/src/bidmanager.js @@ -130,11 +130,6 @@ exports.addBidResponse = function (adUnitCode, bid) { // Postprocess the bids so that all the universal properties exist, no matter which bidder they came from. // This should be called before addBidToAuction(). function prepareBidForAuction() { - // Let listeners know that now is the time to adjust the bid, if they want to. - // - // This must be fired first, so that we calculate derived values from the updates - events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, bid); - const bidRequest = getBidderRequest(bid.bidderCode, adUnitCode); Object.assign(bid, { @@ -148,6 +143,12 @@ exports.addBidResponse = function (adUnitCode, bid) { bid.timeToRespond = bid.responseTimestamp - bid.requestTimestamp; + // Let listeners know that now is the time to adjust the bid, if they want to. + // + // CAREFUL: Publishers rely on certain bid properties to be available (like cpm), + // but others to not be set yet (like priceStrings). See #1372 and #1389. + events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, bid); + // a publisher-defined renderer can be used to render bids const adUnitRenderer = bidRequest.bids && bidRequest.bids[0] && bidRequest.bids[0].renderer; diff --git a/test/spec/unit/bidmanager_spec.js b/test/spec/unit/bidmanager_spec.js index d5b8c77c167..c55a2ae5a2f 100644 --- a/test/spec/unit/bidmanager_spec.js +++ b/test/spec/unit/bidmanager_spec.js @@ -70,6 +70,21 @@ describe('The Bid Manager', () => { */ function prepAuction(adUnits, bidRequestTweaker) { function bidAdjuster(bid) { + if (bid.hasOwnProperty('cpm')) { + bid.hadCpmDuringBidAdjustment = true; + } + if (bid.hasOwnProperty('adUnitCode')) { + bid.hadAdUnitCodeDuringBidAdjustment = true; + } + if (bid.hasOwnProperty('timeToRespond')) { + bid.hadTimeToRespondDuringBidAdjustment = true; + } + if (bid.hasOwnProperty('requestTimestamp')) { + bid.hadRequestTimestampDuringBidAdjustment = true; + } + if (bid.hasOwnProperty('responseTimestamp')) { + bid.hadResponseTimestampDuringBidAdjustment = true; + } bid.cpm = adjustCpm(bid.cpm); } beforeEach(() => { @@ -142,6 +157,20 @@ describe('The Bid Manager', () => { bidManager.addBidResponse('mock/code'); expect($$PREBID_GLOBAL$$._bidsReceived.length).to.equal(0); }); + + it('should attach properties for analytics *before* the BID_ADJUSTMENT event listeners are called', () => { + const copy = Object.assign({}, bidResponse); + copy.getSize = function() { + return `${this.height}x${this.width}`; + }; + delete copy.cpm; + bidManager.addBidResponse('mock/code', copy); + expect(copy).to.have.property('hadCpmDuringBidAdjustment', true); + expect(copy).to.have.property('hadAdUnitCodeDuringBidAdjustment', true); + expect(copy).to.have.property('hadTimeToRespondDuringBidAdjustment', true); + expect(copy).to.have.property('hadRequestTimestampDuringBidAdjustment', true); + expect(copy).to.have.property('hadResponseTimestampDuringBidAdjustment', true); + }); }); describe('when the auction has timed out', () => { From 74b0dc327b4ac9c59caef2e06c0201ad89fcd2ef Mon Sep 17 00:00:00 2001 From: Matt Lane Date: Fri, 21 Jul 2017 09:31:18 -0700 Subject: [PATCH 85/95] Set outstream mediaType based on renderer in response (#1391) --- modules/appnexusAstBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/appnexusAstBidAdapter.js b/modules/appnexusAstBidAdapter.js index e8441d9a003..0cb372bcc55 100644 --- a/modules/appnexusAstBidAdapter.js +++ b/modules/appnexusAstBidAdapter.js @@ -197,7 +197,7 @@ function AppnexusAstAdapter() { const bid = createBid(status, tag); if (type === 'native') bid.mediaType = 'native'; if (type === 'video') bid.mediaType = 'video'; - if (type === 'video-outstream') bid.mediaType = 'video-outstream'; + if (ad && ad.renderer_url) bid.mediaType = 'video-outstream'; if (bid.adId in bidRequests) { const placement = bidRequests[bid.adId].placementCode; From 19705b360bdff24b48104b3fa7b0d537099ecc55 Mon Sep 17 00:00:00 2001 From: Matt Lane Date: Mon, 24 Jul 2017 10:46:22 -0700 Subject: [PATCH 86/95] Lint modules directory (#1404) * Lint modules directory * Run --fix * Add indentation exception for adapter * Push lint error to test CI * Fix forced error --- .eslintrc.js | 1 + gulpfile.js | 2 +- modules/aardvarkBidAdapter.js | 4 +- modules/adbladeBidAdapter.js | 2 +- modules/adbundBidAdapter.js | 2 +- modules/adbutlerBidAdapter.js | 2 +- modules/adequantBidAdapter.js | 2 +- modules/adformBidAdapter.js | 2 +- modules/adkernelBidAdapter.js | 2 +- modules/admediaBidAdapter.js | 2 +- modules/admixerBidAdapter.js | 2 +- modules/adsupplyBidAdapter.js | 2 +- modules/adyoulikeBidAdapter.js | 2 +- modules/aolBidAdapter.js | 2 +- modules/appnexusAstBidAdapter.js | 4 +- modules/appnexusBidAdapter.js | 2 +- modules/atomxBidAdapter.js | 2 +- modules/audienceNetworkBidAdapter.js | 2 +- modules/beachfrontBidAdapter.js | 2 +- modules/bidfluenceBidAdapter.js | 2 +- modules/brightcomBidAdapter.js | 4 +- modules/carambolaBidAdapter.js | 2 +- modules/centroBidAdapter.js | 2 +- modules/conversantBidAdapter.js | 2 +- modules/coxBidAdapter.js | 2 +- modules/criteoBidAdapter.js | 4 +- modules/districtmDMXBidAdapter.js | 2 +- modules/eplanningBidAdapter.js | 2 +- modules/express.js | 11 ++-- modules/fidelityBidAdapter.js | 2 +- modules/getintentBidAdapter.js | 2 +- modules/gumgumBidAdapter.js | 18 +++--- modules/hiromediaBidAdapter.js | 2 +- modules/huddledmassesBidAdapter.js | 58 ++++++++--------- modules/indexExchangeBidAdapter.js | 2 +- modules/inneractiveBidAdapter.js | 2 +- modules/innityBidAdapter.js | 2 +- modules/jcmBidAdapter.js | 2 +- modules/kargoBidAdapter.js | 2 +- modules/komoonaBidAdapter.js | 4 +- modules/kruxlinkBidAdapter.js | 2 +- modules/lifestreetBidAdapter.js | 2 +- modules/mantisBidAdapter.js | 2 +- modules/memeglobalBidAdapter.js | 2 +- modules/nginadBidAdapter.js | 2 +- modules/openxBidAdapter.js | 4 +- modules/piximediaBidAdapter.js | 2 +- modules/pubgearsBidAdapter.js | 8 +-- modules/pubmaticBidAdapter.js | 2 +- modules/pubwiseAnalyticsAdapter.js | 38 ++++++------ modules/pulsepointBidAdapter.js | 2 +- modules/pulsepointLiteBidAdapter.js | 16 ++--- modules/quantcastBidAdapter.js | 2 +- modules/rhythmoneBidAdapter.js | 3 +- modules/roxotBidAdapter.js | 6 +- modules/rubiconBidAdapter.js | 6 +- modules/sekindoUMBidAdapter.js | 2 +- modules/serverbidBidAdapter.js | 2 +- modules/sharethroughAnalyticsAdapter.js | 82 ++++++++++++------------- modules/sharethroughBidAdapter.js | 2 +- modules/smartadserverBidAdapter.js | 2 +- modules/smartyadsBidAdapter.js | 6 +- modules/sonobiBidAdapter.js | 6 +- modules/sovrnBidAdapter.js | 4 +- modules/spotxBidAdapter.js | 14 ++--- modules/springserveBidAdapter.js | 2 +- modules/stickyadstvBidAdapter.js | 2 +- modules/tapsenseBidAdapter.js | 2 +- modules/thoughtleadrBidAdapter.js | 2 +- modules/trionBidAdapter.js | 2 +- modules/tripleliftBidAdapter.js | 2 +- modules/twengaBidAdapter.js | 2 +- modules/ucfunnelBidAdapter.js | 4 +- modules/underdogmediaBidAdapter.js | 2 +- modules/unrulyBidAdapter.js | 2 +- modules/vertamediaBidAdapter.js | 2 +- modules/vertozBidAdapter.js | 2 +- modules/wideorbitBidAdapter.js | 2 +- modules/widespaceBidAdapter.js | 2 +- modules/xhbBidAdapter.js | 2 +- modules/yieldbotBidAdapter.js | 4 +- 81 files changed, 212 insertions(+), 213 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 706768d6a45..8cdd5c498c1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -23,6 +23,7 @@ module.exports = { "camelcase": "off", "eqeqeq": "off", "import/first": "off", + "new-cap": "off", "no-control-regex": "off", "no-mixed-operators": "off", "no-multiple-empty-lines": "off", diff --git a/gulpfile.js b/gulpfile.js index 2572420904d..ed7cc4a5a8f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -207,7 +207,7 @@ gulp.task('watch', function () { }); gulp.task('lint', () => { - return gulp.src(['src/**/*.js', 'test/**/*.js']) + return gulp.src(['src/**/*.js', 'modules/**/*.js', 'test/**/*.js']) .pipe(eslint()) .pipe(eslint.format('stylish')) .pipe(eslint.failAfterError()); diff --git a/modules/aardvarkBidAdapter.js b/modules/aardvarkBidAdapter.js index 65c90b3be47..a058c90fa9b 100644 --- a/modules/aardvarkBidAdapter.js +++ b/modules/aardvarkBidAdapter.js @@ -42,7 +42,7 @@ var AARDVARK_CALLBACK_NAME = 'aardvarkResponse', bidIds.push(_sc + '=' + bid.bidId); - // Create the bidIdsMap for easier mapping back later + // Create the bidIdsMap for easier mapping back later $$PREBID_GLOBAL$$[AARDVARK_REQUESTS_MAP][bidderCode][bid.bidId] = bid; } @@ -124,6 +124,6 @@ exports.createNew = function() { return new AardvarkAdapter(); }; -adaptermanager.registerBidAdapter(new AardvarkAdapter, 'aardvark'); +adaptermanager.registerBidAdapter(new AardvarkAdapter(), 'aardvark'); module.exports = AardvarkAdapter; diff --git a/modules/adbladeBidAdapter.js b/modules/adbladeBidAdapter.js index ab0a7a83cb3..ee1fcca86f7 100644 --- a/modules/adbladeBidAdapter.js +++ b/modules/adbladeBidAdapter.js @@ -130,6 +130,6 @@ var AdbladeAdapter = function AdbladeAdapter() { }; }; -adaptermanager.registerBidAdapter(new AdbladeAdapter, 'adblade'); +adaptermanager.registerBidAdapter(new AdbladeAdapter(), 'adblade'); module.exports = AdbladeAdapter; diff --git a/modules/adbundBidAdapter.js b/modules/adbundBidAdapter.js index a7c2bd45257..2971d881f7b 100644 --- a/modules/adbundBidAdapter.js +++ b/modules/adbundBidAdapter.js @@ -64,6 +64,6 @@ var adBundAdapter = function adBundAdapter() { }; }; -adaptermanager.registerBidAdapter(new adBundAdapter, 'adbund'); +adaptermanager.registerBidAdapter(new adBundAdapter(), 'adbund'); module.exports = adBundAdapter; diff --git a/modules/adbutlerBidAdapter.js b/modules/adbutlerBidAdapter.js index 8fbbba305ac..a253c494d6c 100644 --- a/modules/adbutlerBidAdapter.js +++ b/modules/adbutlerBidAdapter.js @@ -139,6 +139,6 @@ var AdButlerAdapter = function AdButlerAdapter() { }; }; -adaptermanager.registerBidAdapter(new AdButlerAdapter, 'adbutler'); +adaptermanager.registerBidAdapter(new AdButlerAdapter(), 'adbutler'); module.exports = AdButlerAdapter; diff --git a/modules/adequantBidAdapter.js b/modules/adequantBidAdapter.js index b45b976ac28..982ea4adbde 100644 --- a/modules/adequantBidAdapter.js +++ b/modules/adequantBidAdapter.js @@ -73,6 +73,6 @@ function AdequantAdapter() { }; } -adaptermanager.registerBidAdapter(new AdequantAdapter, 'adequant'); +adaptermanager.registerBidAdapter(new AdequantAdapter(), 'adequant'); module.exports = AdequantAdapter; diff --git a/modules/adformBidAdapter.js b/modules/adformBidAdapter.js index 7f7cc13d059..5d1bb98b4ec 100644 --- a/modules/adformBidAdapter.js +++ b/modules/adformBidAdapter.js @@ -162,6 +162,6 @@ function AdformAdapter() { } } -adaptermanager.registerBidAdapter(new AdformAdapter, 'adform'); +adaptermanager.registerBidAdapter(new AdformAdapter(), 'adform'); module.exports = AdformAdapter; diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js index a9c5796b07e..ad3cbeb334b 100644 --- a/modules/adkernelBidAdapter.js +++ b/modules/adkernelBidAdapter.js @@ -307,7 +307,7 @@ AdKernelAdapter.createNew = function() { return new AdKernelAdapter(); }; -adaptermanager.registerBidAdapter(new AdKernelAdapter, 'adkernel', { +adaptermanager.registerBidAdapter(new AdKernelAdapter(), 'adkernel', { supportedMediaTypes: ['video'] }); adaptermanager.aliasBidAdapter('adkernel', 'headbidding'); diff --git a/modules/admediaBidAdapter.js b/modules/admediaBidAdapter.js index e933911d537..ff21fba3101 100644 --- a/modules/admediaBidAdapter.js +++ b/modules/admediaBidAdapter.js @@ -100,6 +100,6 @@ var AdmediaAdapter = function AdmediaAdapter() { }; }; -adaptermanager.registerBidAdapter(new AdmediaAdapter, 'admedia'); +adaptermanager.registerBidAdapter(new AdmediaAdapter(), 'admedia'); module.exports = AdmediaAdapter; diff --git a/modules/admixerBidAdapter.js b/modules/admixerBidAdapter.js index d0b4515133a..71220732540 100644 --- a/modules/admixerBidAdapter.js +++ b/modules/admixerBidAdapter.js @@ -81,7 +81,7 @@ var AdmixerAdapter = function AdmixerAdapter() { }; }; -adaptermanager.registerBidAdapter(new AdmixerAdapter, 'admixer', { +adaptermanager.registerBidAdapter(new AdmixerAdapter(), 'admixer', { supportedMediaTypes: ['video'] }); diff --git a/modules/adsupplyBidAdapter.js b/modules/adsupplyBidAdapter.js index 8d7aa1ef4a6..041437cce98 100644 --- a/modules/adsupplyBidAdapter.js +++ b/modules/adsupplyBidAdapter.js @@ -85,6 +85,6 @@ var AdSupplyAdapter = function AdSupplyAdapter() { }; }; -adaptermanager.registerBidAdapter(new AdSupplyAdapter, 'adsupply'); +adaptermanager.registerBidAdapter(new AdSupplyAdapter(), 'adsupply'); module.exports = AdSupplyAdapter; diff --git a/modules/adyoulikeBidAdapter.js b/modules/adyoulikeBidAdapter.js index b9e958ac16b..f58292b0fae 100644 --- a/modules/adyoulikeBidAdapter.js +++ b/modules/adyoulikeBidAdapter.js @@ -199,6 +199,6 @@ AdyoulikeAdapter.createNew = function () { return new AdyoulikeAdapter(); }; -adaptermanager.registerBidAdapter(new AdyoulikeAdapter, 'adyoulike'); +adaptermanager.registerBidAdapter(new AdyoulikeAdapter(), 'adyoulike'); module.exports = AdyoulikeAdapter; diff --git a/modules/aolBidAdapter.js b/modules/aolBidAdapter.js index 1f0b3a5bbb0..42aff892b75 100644 --- a/modules/aolBidAdapter.js +++ b/modules/aolBidAdapter.js @@ -303,6 +303,6 @@ const AolAdapter = function AolAdapter() { }; }; -adaptermanager.registerBidAdapter(new AolAdapter, 'aol'); +adaptermanager.registerBidAdapter(new AolAdapter(), 'aol'); module.exports = AolAdapter; diff --git a/modules/appnexusAstBidAdapter.js b/modules/appnexusAstBidAdapter.js index 0cb372bcc55..284d8eef10b 100644 --- a/modules/appnexusAstBidAdapter.js +++ b/modules/appnexusAstBidAdapter.js @@ -193,7 +193,7 @@ function AppnexusAstAdapter() { utils.logError(`${type} ad type not supported`); } - tag.bidId = tag.uuid; // bidfactory looks for bidId on requested bid + tag.bidId = tag.uuid; // bidfactory looks for bidId on requested bid const bid = createBid(status, tag); if (type === 'native') bid.mediaType = 'native'; if (type === 'video') bid.mediaType = 'video'; @@ -378,7 +378,7 @@ AppnexusAstAdapter.createNew = function() { return new AppnexusAstAdapter(); }; -adaptermanager.registerBidAdapter(new AppnexusAstAdapter, 'appnexusAst', { +adaptermanager.registerBidAdapter(new AppnexusAstAdapter(), 'appnexusAst', { supportedMediaTypes: ['video', 'native'] }); diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index 46b08314d7b..a20b7f29e47 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -226,7 +226,7 @@ AppNexusAdapter.createNew = function () { return new AppNexusAdapter(); }; -adaptermanager.registerBidAdapter(new AppNexusAdapter, 'appnexus'); +adaptermanager.registerBidAdapter(new AppNexusAdapter(), 'appnexus'); adaptermanager.aliasBidAdapter('appnexus', 'brealtime'); adaptermanager.aliasBidAdapter('appnexus', 'pagescience'); adaptermanager.aliasBidAdapter('appnexus', 'defymedia'); diff --git a/modules/atomxBidAdapter.js b/modules/atomxBidAdapter.js index 9acf2339af9..5b8652561eb 100644 --- a/modules/atomxBidAdapter.js +++ b/modules/atomxBidAdapter.js @@ -74,6 +74,6 @@ var AtomxAdapter = function AtomxAdapter() { }; -adaptermanager.registerBidAdapter(new AtomxAdapter, 'atomx'); +adaptermanager.registerBidAdapter(new AtomxAdapter(), 'atomx'); module.exports = AtomxAdapter; diff --git a/modules/audienceNetworkBidAdapter.js b/modules/audienceNetworkBidAdapter.js index d19bf4d9278..0a67020b86d 100644 --- a/modules/audienceNetworkBidAdapter.js +++ b/modules/audienceNetworkBidAdapter.js @@ -244,7 +244,7 @@ const callBids = bidRequest => { */ const AudienceNetwork = () => ({ callBids, setBidderCode, getBidderCode }); -adaptermanager.registerBidAdapter(new AudienceNetwork, 'audienceNetwork', { +adaptermanager.registerBidAdapter(new AudienceNetwork(), 'audienceNetwork', { supportedMediaTypes: ['video'] }); diff --git a/modules/beachfrontBidAdapter.js b/modules/beachfrontBidAdapter.js index 059d15ac79d..29434a35c0c 100644 --- a/modules/beachfrontBidAdapter.js +++ b/modules/beachfrontBidAdapter.js @@ -133,7 +133,7 @@ BeachfrontAdapter.createNew = function () { return new BeachfrontAdapter(); }; -adaptermanager.registerBidAdapter(new BeachfrontAdapter, 'beachfront', { +adaptermanager.registerBidAdapter(new BeachfrontAdapter(), 'beachfront', { supportedMediaTypes: ['video'] }); diff --git a/modules/bidfluenceBidAdapter.js b/modules/bidfluenceBidAdapter.js index da22096b7e6..73b548a4993 100644 --- a/modules/bidfluenceBidAdapter.js +++ b/modules/bidfluenceBidAdapter.js @@ -53,6 +53,6 @@ var BidfluenceAdapter = function BidfluenceAdapter() { }; }; -adaptermanager.registerBidAdapter(new BidfluenceAdapter, 'bidfluence'); +adaptermanager.registerBidAdapter(new BidfluenceAdapter(), 'bidfluence'); module.exports = BidfluenceAdapter; diff --git a/modules/brightcomBidAdapter.js b/modules/brightcomBidAdapter.js index 2f6d30275ea..c8945e58f91 100644 --- a/modules/brightcomBidAdapter.js +++ b/modules/brightcomBidAdapter.js @@ -122,7 +122,7 @@ var BrightcomAdapter = function BrightcomAdapter() { // Make sure response is valid if ( - (brightcomResponseObj) && (brightcomResponseObj.id) && + (brightcomResponseObj) && (brightcomResponseObj.id) && (brightcomResponseObj.seatbid) && (brightcomResponseObj.seatbid.length !== 0) && (brightcomResponseObj.seatbid[0].bid) && (brightcomResponseObj.seatbid[0].bid.length !== 0) ) { @@ -200,6 +200,6 @@ var BrightcomAdapter = function BrightcomAdapter() { }; }; -adaptermanager.registerBidAdapter(new BrightcomAdapter, 'brightcom'); +adaptermanager.registerBidAdapter(new BrightcomAdapter(), 'brightcom'); module.exports = BrightcomAdapter; diff --git a/modules/carambolaBidAdapter.js b/modules/carambolaBidAdapter.js index ae064e93ce1..3c65e7da77e 100644 --- a/modules/carambolaBidAdapter.js +++ b/modules/carambolaBidAdapter.js @@ -191,6 +191,6 @@ function CarambolaAdapter() { }; } -adaptermanager.registerBidAdapter(new CarambolaAdapter, 'carambola'); +adaptermanager.registerBidAdapter(new CarambolaAdapter(), 'carambola'); module.exports = CarambolaAdapter; diff --git a/modules/centroBidAdapter.js b/modules/centroBidAdapter.js index 0a218b57f64..59abe7cec15 100644 --- a/modules/centroBidAdapter.js +++ b/modules/centroBidAdapter.js @@ -117,6 +117,6 @@ var CentroAdapter = function CentroAdapter() { }; }; -adaptermanager.registerBidAdapter(new CentroAdapter, 'centro'); +adaptermanager.registerBidAdapter(new CentroAdapter(), 'centro'); module.exports = CentroAdapter; diff --git a/modules/conversantBidAdapter.js b/modules/conversantBidAdapter.js index 12984b521db..d51008559f2 100644 --- a/modules/conversantBidAdapter.js +++ b/modules/conversantBidAdapter.js @@ -271,7 +271,7 @@ var ConversantAdapter = function () { }; }; -adaptermanager.registerBidAdapter(new ConversantAdapter, 'conversant', { +adaptermanager.registerBidAdapter(new ConversantAdapter(), 'conversant', { supportedMediaTypes: ['video'] }); diff --git a/modules/coxBidAdapter.js b/modules/coxBidAdapter.js index 0d0f5047c06..432b82ebf88 100644 --- a/modules/coxBidAdapter.js +++ b/modules/coxBidAdapter.js @@ -253,6 +253,6 @@ function CoxAdapter() { }; } -adaptermanager.registerBidAdapter(new CoxAdapter, 'cox'); +adaptermanager.registerBidAdapter(new CoxAdapter(), 'cox'); module.exports = CoxAdapter; diff --git a/modules/criteoBidAdapter.js b/modules/criteoBidAdapter.js index 7a83ad9ff29..8fd74ff83fa 100644 --- a/modules/criteoBidAdapter.js +++ b/modules/criteoBidAdapter.js @@ -51,7 +51,7 @@ var CriteoAdapter = function CriteoAdapter() { bid.transactionId, sizes.map((size) => { return { width: size[0], height: size[1] } - } + } ) ) ); @@ -144,6 +144,6 @@ var CriteoAdapter = function CriteoAdapter() { }; }; -adaptermanager.registerBidAdapter(new CriteoAdapter, 'criteo'); +adaptermanager.registerBidAdapter(new CriteoAdapter(), 'criteo'); module.exports = CriteoAdapter; diff --git a/modules/districtmDMXBidAdapter.js b/modules/districtmDMXBidAdapter.js index d07985097ef..65a51ecc475 100644 --- a/modules/districtmDMXBidAdapter.js +++ b/modules/districtmDMXBidAdapter.js @@ -51,6 +51,6 @@ var DistrictmAdaptor = function districtmAdaptor() { }; }; -adaptermanager.registerBidAdapter(new DistrictmAdaptor, 'districtmDMX'); +adaptermanager.registerBidAdapter(new DistrictmAdaptor(), 'districtmDMX'); module.exports = DistrictmAdaptor; diff --git a/modules/eplanningBidAdapter.js b/modules/eplanningBidAdapter.js index b0d610d1676..aa2e0d8cea7 100644 --- a/modules/eplanningBidAdapter.js +++ b/modules/eplanningBidAdapter.js @@ -278,6 +278,6 @@ function EPlanningAdapter() { }; } -adaptermanager.registerBidAdapter(new EPlanningAdapter, 'eplanning'); +adaptermanager.registerBidAdapter(new EPlanningAdapter(), 'eplanning'); module.exports = EPlanningAdapter; diff --git a/modules/express.js b/modules/express.js index 8a855245e36..20921276cfe 100644 --- a/modules/express.js +++ b/modules/express.js @@ -14,14 +14,13 @@ const MODULE_NAME = 'express'; * @param {Object[]} [adUnits = pbjs.adUnits] - an array of adUnits for express to operate on. */ $$PREBID_GLOBAL$$.express = function(adUnits = $$PREBID_GLOBAL$$.adUnits) { - utils.logMessage('loading ' + MODULE_NAME); if (adUnits.length === 0) { utils.logWarn('no valid adUnits found, not loading ' + MODULE_NAME); } -// put adUnits in a more performant hash lookup by code. + // put adUnits in a more performant hash lookup by code. var adUnitsCache = adUnits.reduce(function (cache, adUnit) { if (adUnit.code && adUnit.bids) { cache[adUnit.code] = adUnit; @@ -59,9 +58,9 @@ $$PREBID_GLOBAL$$.express = function(adUnits = $$PREBID_GLOBAL$$.adUnits) { // a helper function to verify slots or get slots if not present function defaultSlots(slots) { - return Array.isArray(slots) ? - slots.slice() : - googletag.pubads().getSlots().slice(); + return Array.isArray(slots) + ? slots.slice() + : googletag.pubads().getSlots().slice(); } // maps gpt slots to adUnits, matches are copied to new array and removed from passed array. @@ -150,7 +149,6 @@ $$PREBID_GLOBAL$$.express = function(adUnits = $$PREBID_GLOBAL$$.adUnits) { }); } } - }; // override gpt refresh() function @@ -205,5 +203,4 @@ $$PREBID_GLOBAL$$.express = function(adUnits = $$PREBID_GLOBAL$$.adUnits) { return fGptEnableSingleRequest.apply(window.googletag.pubads(), arguments); }; }); - }; diff --git a/modules/fidelityBidAdapter.js b/modules/fidelityBidAdapter.js index 2bd585c15c1..73ee9d44ddd 100644 --- a/modules/fidelityBidAdapter.js +++ b/modules/fidelityBidAdapter.js @@ -97,6 +97,6 @@ var FidelityAdapter = function FidelityAdapter() { }; }; -adaptermanager.registerBidAdapter(new FidelityAdapter, 'fidelity'); +adaptermanager.registerBidAdapter(new FidelityAdapter(), 'fidelity'); module.exports = FidelityAdapter; diff --git a/modules/getintentBidAdapter.js b/modules/getintentBidAdapter.js index 909b767e508..6dc2cb9f4da 100644 --- a/modules/getintentBidAdapter.js +++ b/modules/getintentBidAdapter.js @@ -70,7 +70,7 @@ var GetIntentAdapter = function GetIntentAdapter() { }; }; -adaptermanager.registerBidAdapter(new GetIntentAdapter, 'getintent', { +adaptermanager.registerBidAdapter(new GetIntentAdapter(), 'getintent', { supportedMediaTypes: ['video'] }); diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index 7d99cfbff69..7aff53fbcc6 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -58,9 +58,9 @@ const GumgumAdapter = function GumgumAdapter() { utils._each(bids, bidRequest => { const { bidId - , params = {} - , placementCode - } = bidRequest; + , params = {} + , placementCode + } = bidRequest; const timestamp = _getTimeStamp(); const trackingId = params.inScreen; const nativeId = params.native; @@ -118,11 +118,11 @@ const GumgumAdapter = function GumgumAdapter() { const _handleGumGumResponse = cachedBidRequest => (bidResponse = {}) => { const { pi: productId - } = cachedBidRequest; + } = cachedBidRequest; const { ad = {} - , pag = {} - , thms: throttle - } = bidResponse; + , pag = {} + , thms: throttle + } = bidResponse; /* cache the pageViewId */ if (pag && pag.pvid) pageViewId = pag.pvid; if (ad && ad.id) { @@ -131,7 +131,7 @@ const GumgumAdapter = function GumgumAdapter() { /* create the bid */ const bid = bidfactory.createBid(1); const { t: trackingId - } = pag; + } = pag; bidResponse.request = cachedBidRequest; const encodedResponse = encodeURIComponent(JSON.stringify(bidResponse)); const gumgumAdLoader = ``; + } + } else { + // width and height are only relevant with non-native requests. + // native requests will always return a 2x2 zone size. + bidObject.width = bidResponse.width; + bidObject.height = bidResponse.height; + bidObject.ad = bidResponse.creative; + } + } + else { + bidObject = _invalidBidResponse(); + } + return bidObject; + } + return { callBids: _callBids }; diff --git a/test/spec/modules/criteoBidAdapter_spec.js b/test/spec/modules/criteoBidAdapter_spec.js index c686f284134..f9cff1c463a 100644 --- a/test/spec/modules/criteoBidAdapter_spec.js +++ b/test/spec/modules/criteoBidAdapter_spec.js @@ -1,7 +1,7 @@ import Adapter from '../../../modules/criteoBidAdapter'; import bidManager from '../../../src/bidmanager'; -import {ajax} from '../../../src/ajax' -import {expect} from 'chai'; +import { ajax } from '../../../src/ajax' +import { expect } from 'chai'; var CONSTANTS = require('../../../src/constants'); @@ -12,7 +12,8 @@ before(() => { DirectBidding: { DirectBiddingSlot: function DirectBiddingSlot(placementCode, zoneid, nativeCallback, transactionId, sizes) { return { - impId: placementCode + impId: placementCode, + nativeCallback: nativeCallback }; }, @@ -68,7 +69,7 @@ describe('criteo adapter test', () => { ] }; - let validResponse = {slots: [{impid: 'foo', cpm: 1.12, creative: ""}]}; + let validResponse = { slots: [{ impid: 'foo', cpm: 1.12, creative: "" }] }; let invalidResponse = { slots: [{ 'impid': 'unknownSlot' }] } let validMultiBid = { @@ -95,6 +96,23 @@ describe('criteo adapter test', () => { ] }; + let validNativeResponse = { slots: [{ impid: 'foo', cpm: 1.12, native: { productName: 'product0' } }] }; + let validNativeBid = { + bidderCode: 'criteo', + bids: [ + { + bidder: 'criteo', + placementCode: 'foo', + sizes: [[250, 350]], + params: { + zoneId: 32934, + audit: 'true', + nativeCallback: function (nativeJson) { console.log('Product name: ' + nativeJson.productName) } + } + } + ] + } + beforeEach(() => { adapter = new Adapter(); }); @@ -107,7 +125,7 @@ describe('criteo adapter test', () => { let server; beforeEach(() => { - server = sinon.fakeServer.create({autoRespond: true, respondImmediately: true}); + server = sinon.fakeServer.create({ autoRespond: true, respondImmediately: true }); server.respondWith(JSON.stringify(validResponse)); }); @@ -157,11 +175,42 @@ describe('criteo adapter test', () => { }); }); + describe('adding bids to the manager with native bids', () => { + let server; + + beforeEach(() => { + server = sinon.fakeServer.create({ autoRespond: true, respondImmediately: true }); + server.respondWith(JSON.stringify(validNativeResponse)); + }); + + it('adds creative to the response of a native valid request', (done) => { + stubAddBidResponse = sinon.stub( + bidManager, 'addBidResponse', + function (adUnitCode, bid) { + let expectedAdProperty = ``; + + expect(bid).to.have.property('ad', expectedAdProperty); + done(); + }); + adapter.callBids(validNativeBid); + }); + }); + describe('dealing with unexpected situations', () => { let server; beforeEach(() => { - server = sinon.fakeServer.create({autoRespond: true, respondImmediately: true}); + server = sinon.fakeServer.create({ autoRespond: true, respondImmediately: true }); }); it('no bid if cdb handler responds with no bid empty string response', (done) => { From 0d1bd5568e42942458069dffb9f7e60b6de9397b Mon Sep 17 00:00:00 2001 From: dbemiller Date: Wed, 26 Jul 2017 11:43:26 -0400 Subject: [PATCH 92/95] Fixed style error. (#1419) --- modules/admediaBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/admediaBidAdapter.js b/modules/admediaBidAdapter.js index e77d6841420..fe6e2aa260f 100644 --- a/modules/admediaBidAdapter.js +++ b/modules/admediaBidAdapter.js @@ -57,7 +57,7 @@ var AdmediaAdapter = function AdmediaAdapter() { request_obj.siteRef = document.referrer; request_obj.topUrl = utils.getTopWindowUrl(); - request_obj.callback = '$$PREBID_GLOBAL$$'; + request_obj.callback = '$$PREBID_GLOBAL$$'; request_obj.callbackId = bid.bidId; var endpoint = bidderUrl + utils.parseQueryStringParameters(request_obj); From 03d86a0ed90fe0ebfb2a8eb26b804ba226338cc1 Mon Sep 17 00:00:00 2001 From: francoroy Date: Wed, 26 Jul 2017 18:43:49 +0300 Subject: [PATCH 93/95] Added MobFox Adapter (#1312) * added matomy as an alias for appnexus * added mobfox adapter * added mobfox adapter * lint fixes in mobfox test * fixed mobfox adapter error handling on invalid json * fixed mobfox adapter error handling on no ad response --- modules/mobfoxBidAdapter.js | 185 +++++++++++++++++++++ test/spec/modules/mobfoxBidAdapter_spec.js | 162 ++++++++++++++++++ 2 files changed, 347 insertions(+) create mode 100644 modules/mobfoxBidAdapter.js create mode 100644 test/spec/modules/mobfoxBidAdapter_spec.js diff --git a/modules/mobfoxBidAdapter.js b/modules/mobfoxBidAdapter.js new file mode 100644 index 00000000000..aaf4328ac23 --- /dev/null +++ b/modules/mobfoxBidAdapter.js @@ -0,0 +1,185 @@ +const bidfactory = require('src/bidfactory.js'); +const bidmanager = require('src/bidmanager.js'); +const adloader = require('src/adloader'); +const ajax = require('src/ajax.js'); +const CONSTANTS = require('src/constants.json'); +const utils = require('src/utils.js'); +const adaptermanager = require('src/adaptermanager'); + +const mobfoxAdapter = function () { + const BIDDER_CODE = 'mobfox'; + const BID_REQUEST_BASE_URL = 'https://my.mobfox.com/request.php'; + + // request + function buildQueryStringFromParams(params) { + for (let key in params) { + if (params.hasOwnProperty(key)) { + if (params[key] === undefined) { + delete params[key]; + } else { + params[key] = encodeURIComponent(params[key]); + } + } + } + + return utils._map(Object.keys(params), key => `${key}=${params[key]}`) + .join('&'); + } + + function buildBidRequest(bid) { + let bidParams = bid.params; + + let requestParams = { + // -------------------- Mandatory Parameters ------------------ + rt: bidParams.rt || 'api-fetchip', + r_type: bidParams.r_type || 'banner', + r_resp: bidParams.r_resp || 'json', // string | vast20 + // i: bidParams.i || undefined , // string | 69.197.148.18 + s: bidParams.s, // string | 80187188f458cfde788d961b6882fd53 + u: bidParams.u || window.navigator.userAgent, // string + + // ------------------- Global Parameters ---------------------- + adspace_width: bidParams.adspace_width || bid.sizes[0][0], // integer | 320 + adspace_height: bidParams.adspace_height || bid.sizes[0][1], // integer | 48 + r_floor: bidParams.r_floor || undefined, // 0.8 + + o_andadvid: bidParams.o_andadvid || undefined, // 'c6292267-56ad-4326-965d-deef6fcd5er9' + longitude: bidParams.longitude || undefined, // 12.12 + latitude: bidParams.latitude || undefined, // 280.12 + demo_age: bidParams.demo_age || undefined, // 1978 + + // ------------------- banner / interstitial ---------------------- + adspace_strict: bidParams.adspace_strict || undefined, + + // ------------------- interstitial / video ---------------------- + imp_instl: bidParams.imp_instl || undefined, // integer | 1 + + // ------------------- mraid ---------------------- + c_mraid: bidParams.c_mraid || undefined, // integer | 1 + + // ------------------- video ---------------------- + v_dur_min: bidParams.v_dur_min || undefined, // integer | 0 + v_dur_max: bidParams.v_dur_max || undefined, // integer | 999 + v_autoplay: bidParams.v_autoplay || undefined, // integer | 1 + v_startmute: bidParams.v_startmute || undefined, // integer | 0 + v_rewarded: bidParams.v_rewarded || undefined, // integer | 0 + v_api: bidParams.v_api || undefined, // string | vpaid20 + n_ver: bidParams.n_ver || undefined, // + n_adunit: bidParams.n_adunit || undefined, // + n_layout: bidParams.n_layout || undefined, // + n_context: bidParams.n_context || undefined, // + n_plcmttype: bidParams.n_plcmttype || undefined, // + n_img_icon_req: bidParams.n_img_icon_req || undefined, // boolean0 + n_img_icon_size: bidParams.n_img_icon_size || undefined, // string80 + n_img_large_req: bidParams.n_img_large_req || undefined, // boolean0 + n_img_large_w: bidParams.n_img_large_w || undefined, // integer1200 + n_img_large_h: bidParams.n_img_large_h || undefined, // integer627 + n_title_req: bidParams.n_title_req || undefined, // boolean0 + n_title_len: bidParams.n_title_len || undefined, // string25 + n_desc_req: bidParams.n_desc_req || undefined, // boolean0 + n_desc_len: bidParams.n_desc_len || undefined, // string140 + n_rating_req: bidParams.n_rating_req || undefined + }; + + return requestParams; + } + + function sendBidRequest(bid) { + let requestParams = buildBidRequest(bid); + let queryString = buildQueryStringFromParams(requestParams); + + ajax.ajax(`${BID_REQUEST_BASE_URL}?${queryString}`, { + success(resp, xhr) { + if (xhr.getResponseHeader('Content-Type') == 'application/json') { + try { + resp = JSON.parse(resp) + } + catch (e) { + resp = {error: resp} + } + } + onBidResponse({ + data: resp, + xhr: xhr + }, bid); + }, + error(err) { + if (xhr.getResponseHeader('Content-Type') == 'application/json') { + try { + err = JSON.parse(err); + } + catch (e) { + } + ; + } + onBidResponseError(bid, [err]); + } + }); + } + + // response + function onBidResponseError(bid, err) { + utils.logError('Bid Response Error', bid, ...err); + let bidResponse = bidfactory.createBid(CONSTANTS.STATUS.NO_BID, bid); + bidResponse.bidderCode = BIDDER_CODE; + bidmanager.addBidResponse(bid.placementCode, bidResponse); + } + + function onBidResponse(bidderResponse, bid) { + // transform the response to a valid prebid response + try { + let bidResponse = transformResponse(bidderResponse, bid); + bidmanager.addBidResponse(bid.placementCode, bidResponse); + } catch (e) { + onBidResponseError(bid, [e]); + } + } + + function transformResponse(bidderResponse, bid) { + let responseBody = bidderResponse.data; + + // Validate Request + let err = responseBody.error; + if (err) { + throw err; + } + + let htmlString = responseBody.request && responseBody.request.htmlString; + if (!htmlString) { + throw [`htmlString is missing`, responseBody]; + } + + let cpm, cpmHeader = bidderResponse.xhr.getResponseHeader('X-Pricing-CPM'); + try { + cpm = Number(cpmHeader); + } catch (e) { + throw ['Invalid CPM value:', cpmHeader]; + } + + // Validations passed - Got bid + let bidResponse = bidfactory.createBid(CONSTANTS.STATUS.GOOD, bid); + bidResponse.bidderCode = BIDDER_CODE; + + bidResponse.ad = htmlString; + bidResponse.cpm = cpm; + + bidResponse.width = bid.sizes[0][0]; + bidResponse.height = bid.sizes[0][1]; + + return bidResponse; + } + + // prebid api + function callBids(params) { + let bids = params.bids || []; + bids.forEach(sendBidRequest); + } + + return { + callBids: callBids + }; +}; + + +adaptermanager.registerBidAdapter(new mobfoxAdapter(), 'mobfox'); +module.exports = mobfoxAdapter; diff --git a/test/spec/modules/mobfoxBidAdapter_spec.js b/test/spec/modules/mobfoxBidAdapter_spec.js new file mode 100644 index 00000000000..41d2569af47 --- /dev/null +++ b/test/spec/modules/mobfoxBidAdapter_spec.js @@ -0,0 +1,162 @@ +describe('mobfox adapter tests', function () { + const expect = require('chai').expect; + const utils = require('src/utils'); + const adapter = require('modules/mobfoxBidAdapter'); + const bidmanager = require('src/bidmanager'); + const adloader = require('src/adloader'); + const CONSTANTS = require('src/constants.json'); + const ajax = require('src/ajax.js'); + let mockResponses = { + banner: { + 'request': { + 'type': 'textAd', + 'htmlString': '<\/title><style>body{margin:0;padding:0}#mobfoxCover{background:0 0;margin:0;padding:0;border:none;position:absolute;left:0;top:0;z-index:100}<\/style><\/head><body><div id="mobfoxCover"><\/div><script type="text\/javascript">function checkRedirect(e){return function(){if(state===REDIRECT){state=REDUNDANT;var t=window.document.querySelector("iframe").contentDocument.querySelector("html").innerHTML.toLowerCase();if(!(t.indexOf("<script")<0&&t.indexOf("<iframe")<0)){var o=new XMLHttpRequest,d={creativeId:creativeId,advertiserId:advertiserId,hParam:hParam,dspId:dspId,networkId:networkId,autoPilotInventoryConfId:autoPilotInventoryConfId,stackItemId:stackItemId,adSpaceId:adSpaceId,cId:cId,adomain:adomain,geo:geo,event:e,ua:window.navigator.userAgent,adId:adId,site:window.location.href,md5Hash:md5Hash,snapshot:btoa(unescape(encodeURIComponent(t)))};o.open("POST","http:\/\/my.mobfox.com\/fraud-integration",!1),o.setRequestHeader("Content-type","application\/json"),o.send(JSON.stringify(d))}}}}function init(){window.onbeforeunload=checkRedirect("onbeforeunload"),window.addEventListener("beforeunload",checkRedirect("beforeunload")),window.addEventListener("unload",checkRedirect("unload")),document.addEventListener("visibilitychange",function(){"hidden"===document.visibilityState&&checkRedirect("visibilityState")});var e=document.createElement("iframe");document.body.appendChild(e),e.width="320",e.height="50";var t=document.querySelector("#mobfoxCover");t.style.width=e.width+"px",t.style.height=e.height+"px",e.style.margin="0px",e.style.padding="0px",e.style.border="none",e.scrolling="no",e.style.overflow="hidden",e.sandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox allow-top-navigation allow-same-origin";var o=atob(markupB64);setTimeout(function(){state=NORMAL},200),setTimeout(function(){var e=document.querySelector("#mobfoxCover");document.body.removeChild(e)},200);var d="srcdoc"in e,n=o;o.indexOf("<body>")<0&&(n="<html><body style="margin:0">"+o+"<\/body><\/html>"),d?e.srcdoc=n:(e.contentWindow.document.open(),e.contentWindow.document.write(n),e.contentWindow.document.close())}var markupB64="PGEgaHJlZj0iaHR0cDovL3Rva3lvLW15Lm1vYmZveC5jb20vZXhjaGFuZ2UuY2xpY2sucGhwP2g9ZGI1ZjZkOTJiMDk1OGI0ZDFlNjU4ZjZlNWRkNWY0MmUiIHRhcmdldD0iX2JsYW5rIj48aW1nIHNyYz0iaHR0cHM6Ly9jcmVhdGl2ZWNkbi5tb2Jmb3guY29tL2U4ZTkxNWYzMmJhOTVkM2JmMzY4YTM5N2EyMzQ4NzVmLmdpZiIgYm9yZGVyPSIwIi8+PC9hPjxicj48aW1nIHN0eWxlPSJwb3NpdGlvbjphYnNvbHV0ZTsgbGVmdDogLTEwMDAwcHg7IiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBzcmM9Imh0dHA6Ly90b2t5by1teS5tb2Jmb3guY29tL2V4Y2hhbmdlLnBpeGVsLnBocD9oPWRiNWY2ZDkyYjA5NThiNGQxZTY1OGY2ZTVkZDVmNDJlIi8+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPmRvY3VtZW50LndyaXRlKCc8aW1nIHN0eWxlPSJwb3NpdGlvbjphYnNvbHV0ZTsgbGVmdDogLTEwMDAwcHg7IiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBzcmM9Imh0dHA6Ly90b2t5by1teS5tb2Jmb3guY29tL2V4Y2hhbmdlLnBpeGVsLnBocD9oPWRiNWY2ZDkyYjA5NThiNGQxZTY1OGY2ZTVkZDVmNDJlJnRlc3Q9MSIvPicpOzwvc2NyaXB0Pg==",INITIAL=0,REDIRECT=1,REDUNDANT=2,NORMAL=3,state=INITIAL,creativeId="",advertiserId="",hParam="db5f6d92b0958b4d1e658f6e5dd5f42e",dspId="",networkId="",autoPilotInventoryConfId="",stackItemId="392746",serverHost="184.172.209.50",adSpaceId="",adId="",cId="",adomain="",geo="US",md5Hash="f3bd183c0b19faf12c76e75461cb8cac";document.addEventListener("DOMContentLoaded",function(e){state=REDIRECT}),setTimeout(init,1)<\/script><\/body><\/html>', + 'clicktype': 'safari', + 'clickurl': 'http://tokyo-my.mobfox.com/exchange.click.php?h=db5f6d92b0958b4d1e658f6e5dd5f42e', + 'urltype': 'link', + 'refresh': '30', + 'scale': 'no', + 'skippreflight': 'yes' + } + } + }; + + let mockRequestsParams = { + banner: { + rt: 'api', + r_type: 'banner', + i: '69.197.148.18', + s: 'fe96717d9875b9da4339ea5367eff1ec', + u: 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4', + adspace_strict: 0, + + // o_iosadvid: '1976F519-26D0-4428-9891-3133253A453F', + // r_floor: '0.2', + // longitude: '12.12', + // latitude: '280.12', + // demo_gender: 'male', + // demo_age: '1982', + // demo_keywords: 'sports', + // adspace_width: 320, + // adspace_height: 50 + } + }; + + before(() => sinon.stub(document.body, 'appendChild')); + after(() => document.body.appendChild.restore()); + + let xhrMock = { + getResponseHeader: getResponseHeaderMock + }; + function getResponseHeaderMock(header) { + switch (header) { + case 'Content-Type': + return 'application/json'; + case 'X-Pricing-CPM': + return '1'; + } + } + function createMobfoxErrorStub() { + return sinon.stub(ajax, 'ajax', (url, callbacks) => { + callbacks.success( + JSON.stringify({error: 'No Ad Available'}), + xhrMock + ); + }); + } + + function createMobfoxSuccessStub() { + return sinon.stub(ajax, 'ajax', (url, callbacks) => { + callbacks.success( + JSON.stringify(mockResponses.banner) + , xhrMock + ); + }); + } + + describe('test mobfox error response', function () { + let stubAddBidResponse, stubAjax; + before(function () { + stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); + stubAjax = createMobfoxErrorStub() + }); + + after(function () { + stubAddBidResponse.restore(); + stubAjax.restore(); + }); + + it('should add empty bid responses if no bids returned', function () { + let bidderRequest = { + bidderCode: 'mobfox', + bids: [ + { + bidId: 'bidId1', + bidder: 'mobfox', + params: {}, + sizes: [[300, 250]], + placementCode: 'test-gpt-div-1234' + } + ] + }; + + // empty ads in bidresponse + let requestParams = utils.cloneJson(mockRequestsParams.banner); + requestParams.adspace_width = 1231564; // should return an error + bidderRequest.bids[0].params = requestParams; + pbjs._bidsRequested.push(bidderRequest); + // adapter needs to be called, in order for the stub to register. + adapter().callBids(bidderRequest); + + let bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; + let bidResponse1 = stubAddBidResponse.getCall(0).args[1]; + expect(bidPlacementCode1).to.equal('test-gpt-div-1234'); + expect(bidResponse1.getStatusCode()).to.equal(CONSTANTS.STATUS.NO_BID); + expect(bidResponse1.bidderCode).to.equal('mobfox'); + }); + }); + + describe('test mobfox success response', function () { + let stubAddBidResponse, stubAjax; + before(function () { + stubAddBidResponse = sinon.stub(bidmanager, 'addBidResponse'); + stubAjax = createMobfoxSuccessStub() + }); + + after(function () { + stubAddBidResponse.restore(); + stubAjax.restore(); + }); + + it('should add a bid response', function () { + let bidderRequest = { + bidderCode: 'mobfox', + bids: [ + { + bidId: 'bidId1', + bidder: 'mobfox', + params: {}, + sizes: [[300, 250]], + placementCode: 'test-gpt-div-1234' + } + ] + }; + + let requestParams = utils.cloneJson(mockRequestsParams.banner); + bidderRequest.bids[0].params = requestParams; + pbjs._bidsRequested.push(bidderRequest); + // adapter needs to be called, in order for the stub to register. + adapter().callBids(bidderRequest); + + let bidPlacementCode1 = stubAddBidResponse.getCall(0).args[0]; + let bidResponse1 = stubAddBidResponse.getCall(0).args[1]; + expect(bidPlacementCode1).to.equal('test-gpt-div-1234'); + expect(bidResponse1.getStatusCode()).to.equal(CONSTANTS.STATUS.GOOD); + expect(bidResponse1.bidderCode).to.equal('mobfox'); + + expect(bidResponse1.cpm).to.equal(1); + expect(bidResponse1.width).to.equal(bidderRequest.bids[0].sizes[0][0]); + expect(bidResponse1.height).to.equal(bidderRequest.bids[0].sizes[0][1]); + }); + }); +}); From 1d827006701113ce2cb679c9cddaad8a3bf8c25c Mon Sep 17 00:00:00 2001 From: Valentin Zhukovsky <kventin_zhuk@outlook.com> Date: Wed, 26 Jul 2017 18:58:03 +0300 Subject: [PATCH 94/95] Added aliases for aol adapter. (#1371) --- modules/aolBidAdapter.js | 59 ++++++-- test/spec/modules/aolBidAdapter_spec.js | 177 ++++++++++++++++++------ 2 files changed, 178 insertions(+), 58 deletions(-) diff --git a/modules/aolBidAdapter.js b/modules/aolBidAdapter.js index 42aff892b75..5c3dd430693 100644 --- a/modules/aolBidAdapter.js +++ b/modules/aolBidAdapter.js @@ -4,6 +4,13 @@ const bidfactory = require('src/bidfactory.js'); const bidmanager = require('src/bidmanager.js'); const constants = require('src/constants.json'); const adaptermanager = require('src/adaptermanager'); +const BaseAdapter = require('src/adapter'); + +const AOL_BIDDERS_CODES = { + aol: 'aol', + onemobile: 'onemobile', + onedisplay: 'onedisplay' +}; $$PREBID_GLOBAL$$.aolGlobals = { pixelsDropped: false @@ -14,7 +21,6 @@ const AolAdapter = function AolAdapter() { const pubapiTemplate = template`${'protocol'}://${'host'}/pubapi/3.0/${'network'}/${'placement'}/${'pageid'}/${'sizeid'}/ADTECH;v=2;cmd=bid;cors=yes;alias=${'alias'}${'bidfloor'};misc=${'misc'}`; const nexageBaseApiTemplate = template`${'protocol'}://${'host'}/bidRequest?`; const nexageGetApiTemplate = template`dcn=${'dcn'}&pos=${'pos'}&cmd=bid${'ext'}`; - const BIDDER_CODE = 'aol'; const MP_SERVER_MAP = { us: 'adserver-us.adtech.advertising.com', eu: 'adserver-eu.adtech.advertising.com', @@ -175,7 +181,7 @@ const AolAdapter = function AolAdapter() { function _addErrorBidResponse(bid, response = {}) { const bidResponse = bidfactory.createBid(2, bid); - bidResponse.bidderCode = BIDDER_CODE; + bidResponse.bidderCode = bid.bidder; bidResponse.reason = response.nbr; bidResponse.raw = response; bidmanager.addBidResponse(bid.placementCode, bidResponse); @@ -199,7 +205,7 @@ const AolAdapter = function AolAdapter() { cpm = bidData.price; if (cpm === null || isNaN(cpm)) { - utils.logError('Invalid price in bid response', BIDDER_CODE, bid); + utils.logError('Invalid price in bid response', AOL_BIDDERS_CODES.aol, bid); _addErrorBidResponse(bid, response); return; } @@ -219,7 +225,7 @@ const AolAdapter = function AolAdapter() { } const bidResponse = bidfactory.createBid(1, bid); - bidResponse.bidderCode = BIDDER_CODE; + bidResponse.bidderCode = bid.bidder; bidResponse.ad = ad; bidResponse.cpm = cpm; bidResponse.width = bidData.w; @@ -234,8 +240,16 @@ const AolAdapter = function AolAdapter() { bidmanager.addBidResponse(bid.placementCode, bidResponse); } + function _isMarketplaceBidder(bidder) { + return bidder === AOL_BIDDERS_CODES.aol || bidder === AOL_BIDDERS_CODES.onedisplay; + } + + function _isNexageBidder(bidder) { + return bidder === AOL_BIDDERS_CODES.aol || bidder === AOL_BIDDERS_CODES.onemobile; + } + function _isNexageRequestPost(bid) { - if (bid.params.id && bid.params.imp && bid.params.imp[0]) { + if (_isNexageBidder(bid.bidder) && bid.params.id && bid.params.imp && bid.params.imp[0]) { let imp = bid.params.imp[0]; return imp.id && imp.tagid && ((imp.banner && imp.banner.w && imp.banner.h) || @@ -243,6 +257,14 @@ const AolAdapter = function AolAdapter() { } } + function _isNexageRequestGet(bid) { + return _isNexageBidder(bid.bidder) && bid.params.dcn && bid.params.pos; + } + + function _isMarketplaceRequest(bid) { + return _isMarketplaceBidder(bid.bidder) && bid.params.placement && bid.params.network; + } + function _callBids(params) { utils._each(params.bids, bid => { let apiUrl; @@ -251,9 +273,10 @@ const AolAdapter = function AolAdapter() { withCredentials: true }; let isNexageRequestPost = _isNexageRequestPost(bid); - if (bid.params.placement && bid.params.network) { - apiUrl = _buildMarketplaceUrl(bid); - } else if (bid.params.dcn && bid.params.pos || isNexageRequestPost) { + let isNexageRequestGet = _isNexageRequestGet(bid); + let isMarketplaceRequest = _isMarketplaceRequest(bid); + + if (isNexageRequestGet || isNexageRequestPost) { apiUrl = _buildNexageApiUrl(bid); if (isNexageRequestPost) { data = bid.params; @@ -263,7 +286,10 @@ const AolAdapter = function AolAdapter() { options.method = 'POST'; options.contentType = 'application/json'; } + } else if (isMarketplaceRequest) { + apiUrl = _buildMarketplaceUrl(bid); } + if (apiUrl) { ajax(apiUrl, response => { // Needs to be here in case bidderSettings are defined after requestBids() is called @@ -279,7 +305,7 @@ const AolAdapter = function AolAdapter() { showCpmAdjustmentWarning = false; // warning is shown at most once if (!response && response.length <= 0) { - utils.logError('Empty bid response', BIDDER_CODE, bid); + utils.logError('Empty bid response', AOL_BIDDERS_CODES.aol, bid); _addErrorBidResponse(bid, response); return; } @@ -287,7 +313,7 @@ const AolAdapter = function AolAdapter() { try { response = JSON.parse(response); } catch (e) { - utils.logError('Invalid JSON in bid response', BIDDER_CODE, bid); + utils.logError('Invalid JSON in bid response', AOL_BIDDERS_CODES.aol, bid); _addErrorBidResponse(bid, response); return; } @@ -298,11 +324,16 @@ const AolAdapter = function AolAdapter() { }); } - return { - callBids: _callBids - }; + return Object.assign(BaseAdapter.createNew(AOL_BIDDERS_CODES.aol), { + callBids: _callBids, + createNew: function () { + return new AolAdapter(); + } + }); }; -adaptermanager.registerBidAdapter(new AolAdapter(), 'aol'); +adaptermanager.registerBidAdapter(new AolAdapter(), AOL_BIDDERS_CODES.aol); +adaptermanager.aliasBidAdapter(AOL_BIDDERS_CODES.aol, AOL_BIDDERS_CODES.onedisplay); +adaptermanager.aliasBidAdapter(AOL_BIDDERS_CODES.aol, AOL_BIDDERS_CODES.onemobile); module.exports = AolAdapter; diff --git a/test/spec/modules/aolBidAdapter_spec.js b/test/spec/modules/aolBidAdapter_spec.js index d48de9eb37b..188c5375b89 100644 --- a/test/spec/modules/aolBidAdapter_spec.js +++ b/test/spec/modules/aolBidAdapter_spec.js @@ -22,6 +22,34 @@ let getDefaultBidResponse = () => { }; }; +let getMarketplaceBidParams = () => { + return { + placement: 1234567, + network: '9599.1' + }; +}; + +let getNexageGetBidParams = () => { + return { + dcn: '2c9d2b50015c5ce9db6aeeed8b9500d6', + pos: 'header' + }; +}; + +let getNexagePostBidParams = () => { + return { + id: 'id-1', + imp: [{ + id: 'id-2', + banner: { + w: '100', + h: '100' + }, + tagid: 'header1' + }] + }; +}; + let getDefaultBidRequest = () => { return { bidderCode: 'aol', @@ -34,15 +62,15 @@ let getDefaultBidRequest = () => { bidderRequestId: '7101db09af0db2', requestId: 'd3e07445-ab06-44c8-a9dd-5ef9af06d2a6', placementCode: 'foo', - params: { - placement: 1234567, - network: '9599.1' - } + params: getMarketplaceBidParams() }] }; }; describe('AolAdapter', () => { + const MARKETPLACE_URL = 'adserver-us.adtech.advertising.com/pubapi/3.0/'; + const NEXAGE_URL = 'hb.nexage.com/bidRequest?'; + let adapter; beforeEach(() => adapter = new AolAdapter()); @@ -83,7 +111,57 @@ describe('AolAdapter', () => { it('should hit the Marketplace api endpoint with the Marketplace config', () => { adapter.callBids(getDefaultBidRequest()); - expect(requests[0].url).to.contain('adserver-us.adtech.advertising.com/pubapi/3.0/'); + expect(requests[0].url).to.contain(MARKETPLACE_URL); + }); + + it('should hit the Marketplace via onedisplay bidder code', () => { + let bidRequest = createBidderRequest({ + bids: [{ + bidder: 'onedisplay' + }], + params: getMarketplaceBidParams() + }); + + adapter.callBids(bidRequest); + expect(requests[0].url).to.contain(MARKETPLACE_URL); + }); + + it('should hit the Marketplace via onedisplay bidder code when Marketplace and Nexage params are present', () => { + let bidParams = Object.assign(getMarketplaceBidParams(), getNexageGetBidParams()); + let bidRequest = createBidderRequest({ + bids: [{ + bidder: 'onedisplay' + }], + params: bidParams + }); + + adapter.callBids(bidRequest); + expect(requests[0].url).to.contain(MARKETPLACE_URL); + }); + + it('should hit the Marketplace via onedisplay bidder code when Nexage params are present', () => { + let bidParams = Object.assign(getMarketplaceBidParams(), getNexageGetBidParams(), getNexagePostBidParams()); + let bidRequest = createBidderRequest({ + bids: [{ + bidder: 'onedisplay' + }], + params: bidParams + }); + + adapter.callBids(bidRequest); + expect(requests[0].url).to.contain(MARKETPLACE_URL); + }); + + it('should not resolve endpoint for onedisplay bidder code when only Nexage params are present', () => { + let bidParams = Object.assign(getNexageGetBidParams(), getNexagePostBidParams()); + + adapter.callBids(createBidderRequest({ + bids: [{ + bidder: 'onedisplay' + }], + params: bidParams + })); + expect(requests.length).to.equal(0); }); it('should hit endpoint based on the region config option', () => { @@ -105,7 +183,7 @@ describe('AolAdapter', () => { region: 'an' } })); - expect(requests[0].url).to.contain('adserver-us.adtech.advertising.com/pubapi/3.0/'); + expect(requests[0].url).to.contain(MARKETPLACE_URL); }); it('should hit endpoint based on the server config option', () => { @@ -238,33 +316,61 @@ describe('AolAdapter', () => { it('should hit the nexage api endpoint with the nexage config', () => { adapter.callBids(createBidderRequest({ - params: { - dcn: '11223344', - pos: 'header-2324' - } + params: getNexageGetBidParams() })); - expect(requests[0].url).to.contain('hb.nexage.com/bidRequest?'); + + expect(requests[0].url).to.contain(NEXAGE_URL); }); it('should hit the nexage api custom endpoint if specified in the nexage config', () => { + let bidParams = Object.assign({ + host: 'qa-hb.nexage.com' + }, getNexageGetBidParams()); + adapter.callBids(createBidderRequest({ - params: { - host: 'qa-hb.nexage.com', - dcn: '11223344', - pos: 'header-2324' - } + params: bidParams })); expect(requests[0].url).to.contain('qa-hb.nexage.com/bidRequest?'); }); + it('should hit nexage api when nexage and marketplace params are present', () => { + let bidParams = Object.assign(getNexageGetBidParams(), getMarketplaceBidParams()); + + adapter.callBids(createBidderRequest({ + params: bidParams + })); + expect(requests[0].url).to.contain(NEXAGE_URL); + }); + + it('should hit nexage api via onemobile bidder code when nexage and marketplace params are present', () => { + let bidParams = Object.assign(getNexageGetBidParams(), getMarketplaceBidParams()); + + adapter.callBids(createBidderRequest({ + bids: [{ + bidder: 'onemobile' + }], + params: bidParams + })); + expect(requests[0].url).to.contain(NEXAGE_URL); + }); + + it('should not resolve endpoint for onemobile bidder code when only Marketplace params are present', () => { + adapter.callBids(createBidderRequest({ + bids: [{ + bidder: 'onemobile' + }], + params: getMarketplaceBidParams() + })); + + expect(requests.length).to.equal(0); + }); + it('should contain required params - dcn & pos', () => { adapter.callBids(createBidderRequest({ - params: { - dcn: '54321123', - pos: 'footer-2324' - } + params: getNexageGetBidParams() })); - expect(requests[0].url).to.contain('hb.nexage.com/bidRequest?dcn=54321123&pos=footer-2324'); + + expect(requests[0].url).to.contain(NEXAGE_URL + 'dcn=2c9d2b50015c5ce9db6aeeed8b9500d6&pos=header'); }); it('should contain cmd=bid by default', () => { @@ -295,38 +401,21 @@ describe('AolAdapter', () => { }); it('should hit the nexage api endpoint with post data with the openrtb config', () => { - let bidConfig = { - id: 'id-1', - imp: [{ - id: 'id-2', - banner: { - w: '100', - h: '100' - }, - tagid: 'header1' - }] - }; + let bidConfig = getNexagePostBidParams(); + adapter.callBids(createBidderRequest({ params: bidConfig })); - expect(requests[0].url).to.contain('hb.nexage.com/bidRequest?'); + expect(requests[0].url).to.contain(NEXAGE_URL); expect(requests[0].requestBody).to.deep.equal(bidConfig); expect(requests[0].requestHeaders).to.have.property('x-openrtb-version'); }); it('should not hit the nexage api endpoint with post data with the openrtb config' + ' if a required parameter is missing', () => { - let bidConfig = { - id: 'id-1', - imp: [{ - // id: 'id-2', - banner: { - w: '100', - h: '100' - }, - tagid: 'header1' - }] - }; + let bidConfig = getNexagePostBidParams(); + + bidConfig.imp[0].id = null; adapter.callBids(createBidderRequest({ params: bidConfig })); From 6069d9b1274c04dc59a739b89ce8439ea763ce6a Mon Sep 17 00:00:00 2001 From: Rich Snapp <rsnapp@rubiconproject.com> Date: Wed, 26 Jul 2017 13:57:01 -0600 Subject: [PATCH 95/95] Specify --browsers when using gulp test --watch (#1420) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 26e3f27d16a..ac15a991f0c 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,7 @@ If you are contributing code, you should [configure your editor](http://eslint.o ### Unit Testing with Karma - $ gulp test --watch + $ gulp test --watch --browsers=chrome This will run tests and keep the Karma test browser open. If your `prebid.js` file is sourced from the `./build/dev` directory you will also have sourcemaps available when using your browser's developer tools.