From 62327f2e3a14e18c55b6876cfe4ee150ddd3deeb Mon Sep 17 00:00:00 2001 From: Susan Date: Wed, 11 Dec 2019 10:45:24 -0800 Subject: [PATCH 1/5] pass us privacy consent string to request --- modules/gumgumBidAdapter.js | 4 ++++ test/spec/modules/gumgumBidAdapter_spec.js | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index 2325e1bc448..4068e5ac5a4 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -158,6 +158,7 @@ function isBidRequestValid (bid) { function buildRequests (validBidRequests, bidderRequest) { const bids = []; const gdprConsent = bidderRequest && bidderRequest.gdprConsent; + const uspConsent = bidderRequest && bidderRequest.uspConsent; utils._each(validBidRequests, bidRequest => { const timeout = config.getConfig('bidderTimeout'); const { @@ -198,6 +199,9 @@ function buildRequests (validBidRequests, bidderRequest) { if (data.gdprApplies) { data.gdprConsent = gdprConsent.consentString; } + if (uspConsent) { + data.uspConsent = uspConsent; + } if (schain && schain.nodes) { data.schain = _serializeSupplyChainObj(schain); } diff --git a/test/spec/modules/gumgumBidAdapter_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js index cbd71cc82f0..4789a8f0523 100644 --- a/test/spec/modules/gumgumBidAdapter_spec.js +++ b/test/spec/modules/gumgumBidAdapter_spec.js @@ -146,7 +146,7 @@ describe('gumgumAdapter', function () { expect(request.data).to.not.include.any.keys('eAdBuyId'); expect(request.data).to.not.include.any.keys('adBuyId'); }); - it('should add consent parameters if gdprConsent is present', function () { + it('should add gdpr consent parameters if gdprConsent is present', function () { const gdprConsent = { consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', gdprApplies: true }; const fakeBidRequest = { gdprConsent: gdprConsent }; const bidRequest = spec.buildRequests(bidRequests, fakeBidRequest)[0]; @@ -159,6 +159,14 @@ describe('gumgumAdapter', function () { const bidRequest = spec.buildRequests(bidRequests, fakeBidRequest)[0]; expect(bidRequest.data).to.not.include.any.keys('gdprConsent') }); + it('should add uspConsent parameter if it is present in the bidderRequest', function () { + const noUspBidRequest = spec.buildRequests(bidRequests)[0]; + const uspConsentObj = { uspConsent: '1YYY' }; + const bidRequest = spec.buildRequests(bidRequests, uspConsentObj)[0]; + expect(noUspBidRequest.data).to.not.include.any.keys('uspConsent'); + expect(bidRequest.data).to.include.any.keys('uspConsent'); + expect(bidRequest.data.uspConsent).to.eq(uspConsentObj.uspConsent); + }); it('should add a tdid parameter if request contains unified id from TradeDesk', function () { const unifiedId = { 'userId': { From 6c8b2fa1317a35802c49ce45716967b4e6fd1778 Mon Sep 17 00:00:00 2001 From: Susan Date: Fri, 17 Jan 2020 11:57:26 -0800 Subject: [PATCH 2/5] passes bid response currency --- modules/gumgumBidAdapter.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index 4068e5ac5a4..894e3ac1b0c 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -244,7 +244,8 @@ function interpretResponse (serverResponse, bidRequest) { ad: { price: cpm, id: creativeId, - markup + markup, + cur }, cw: wrapper, pag: { @@ -273,7 +274,7 @@ function interpretResponse (serverResponse, bidRequest) { ad: wrapper ? getWrapperCode(wrapper, Object.assign({}, serverResponseBody, { bidRequest })) : markup, cpm: isTestUnit ? 0.1 : cpm, creativeId, - currency: 'USD', + currency: cur || 'USD', height, netRevenue: true, requestId: bidRequest.id, From b196605370a8d46e52551972ca2089baab045c27 Mon Sep 17 00:00:00 2001 From: Susan Date: Fri, 17 Jan 2020 14:25:59 -0800 Subject: [PATCH 3/5] adds test for passing bid response currency --- test/spec/modules/gumgumBidAdapter_spec.js | 35 ++++++++++++++-------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/test/spec/modules/gumgumBidAdapter_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js index 4789a8f0523..f98d8bf306e 100644 --- a/test/spec/modules/gumgumBidAdapter_spec.js +++ b/test/spec/modules/gumgumBidAdapter_spec.js @@ -230,24 +230,33 @@ describe('gumgumAdapter', function () { method: 'GET', pi: 3 } + let expectedResponse = { + 'ad': '

I am an ad

', + 'cpm': 0, + 'creativeId': 29593, + 'currency': 'USD', + 'height': '250', + 'netRevenue': true, + 'requestId': 12345, + 'width': '300', + // dealId: DEAL_ID, + // referrer: REFERER, + ttl: 60 + }; it('should get correct bid response', function () { - let expectedResponse = { - 'ad': '

I am an ad

', - 'cpm': 0, - 'creativeId': 29593, - 'currency': 'USD', - 'height': '250', - 'netRevenue': true, - 'requestId': 12345, - 'width': '300', - // dealId: DEAL_ID, - // referrer: REFERER, - ttl: 60 - }; expect(spec.interpretResponse({ body: serverResponse }, bidRequest)).to.deep.equal([expectedResponse]); }); + it('should pass correct currency if found in bid response', function () { + const cur = 'EURO'; + let response = Object.assign({}, serverResponse); + let expected = Object.assign({}, expectedResponse); + response.ad.cur = cur; + expected.currency = cur; + expect(spec.interpretResponse({ body: response }, bidRequest)).to.deep.equal([expected]); + }); + it('handles nobid responses', function () { let response = { 'ad': {}, From 102b26844fa6de60157d182e74f2303228183dc9 Mon Sep 17 00:00:00 2001 From: Susan Date: Wed, 12 Feb 2020 08:51:30 -0800 Subject: [PATCH 4/5] implements video support --- modules/gumgumBidAdapter.js | 64 +++++++++++++++++++--- test/spec/modules/gumgumBidAdapter_spec.js | 34 +++++++++++- 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index 894e3ac1b0c..208772f6834 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -1,6 +1,7 @@ import * as utils from '../src/utils' import { config } from '../src/config' +import { BANNER, VIDEO } from '../src/mediaTypes'; import includes from 'core-js/library/fn/array/includes'; import { registerBidder } from '../src/adapters/bidderFactory' @@ -8,6 +9,7 @@ const BIDDER_CODE = 'gumgum' const ALIAS_BIDDER_CODE = ['gg'] const BID_ENDPOINT = `https://g2.gumgum.com/hbid/imp` const DT_CREDENTIALS = { member: 'YcXr87z2lpbB' } +const SUPPORTED_MEDIA_TYPES = [BANNER, VIDEO] const TIME_TO_LIVE = 60 let browserParams = {}; @@ -23,7 +25,7 @@ function _getBrowserParams(topWindowUrl) { function getNetworkSpeed () { const connection = window.navigator && (window.navigator.connection || window.navigator.mozConnection || window.navigator.webkitConnection) const Mbps = connection && (connection.downlink || connection.bandwidth) - return Mbps ? Math.round(Mbps * 1024) : null // 1 megabit -> 1024 kilobits + return Mbps ? Math.round(Mbps * 1024) : null } function getOgURL () { let ogURL = '' @@ -136,6 +138,7 @@ function isBidRequestValid (bid) { case !!(params.inScreen): break; case !!(params.inSlot): break; case !!(params.ICV): break; + case !!(params.video): break; default: utils.logWarn(`[GumGum] No product selected for the placement ${adUnitCode}, please check your implementation.`); return false; @@ -149,6 +152,41 @@ function isBidRequestValid (bid) { return true; } +/** + * Renames vid params from mediatypes.video keys + * @param {Object} attributes + * @returns {Object} + */ +function _getVidParams (attributes) { + const { + minduration: mind, + maxduration: maxd, + linearity: li, + startdelay: sd, + placement: pt, + protocols = [], + playerSize = [] + } = attributes; + const sizes = utils.parseSizesInput(playerSize); + const [viw, vih] = sizes[0] && sizes[0].split('x'); + let pr = ''; + + if (protocols.length) { + pr = protocols.join(','); + } + + return { + mind, + maxd, + li, + sd, + pt, + pr, + viw, + vih + }; +} + /** * Make a server request from the list of BidRequests. * @@ -159,20 +197,22 @@ function buildRequests (validBidRequests, bidderRequest) { const bids = []; const gdprConsent = bidderRequest && bidderRequest.gdprConsent; const uspConsent = bidderRequest && bidderRequest.uspConsent; + const timeout = config.getConfig('bidderTimeout'); + const topWindowUrl = bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer; utils._each(validBidRequests, bidRequest => { - const timeout = config.getConfig('bidderTimeout'); const { bidId, + mediaTypes = {}, params = {}, schain, transactionId, userId = {} } = bidRequest; - const data = {}; - const sizes = bidRequest.mediaTypes && bidRequest.mediaTypes.banner && bidRequest.mediaTypes.banner.sizes; - const topWindowUrl = bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer; + const bannerSizes = mediaTypes.banner && mediaTypes.banner.sizes; + let data = {}; + if (pageViewId) { - data.pv = pageViewId + data.pv = pageViewId; } if (params.bidfloor) { data.fp = params.bidfloor; @@ -193,6 +233,12 @@ function buildRequests (validBidRequests, bidderRequest) { data.ni = parseInt(params.ICV, 10); data.pi = 5; } + if (params.video) { + data = Object.assign(data, _getVidParams(mediaTypes.video)); + data.t = params.video; + data.pi = 7; + } + if (gdprConsent) { data.gdprApplies = gdprConsent.gdprApplies ? 1 : 0; } @@ -212,7 +258,7 @@ function buildRequests (validBidRequests, bidderRequest) { tId: transactionId, pi: data.pi, selector: params.selector, - sizes: sizes || bidRequest.sizes, + sizes: bannerSizes || bidRequest.sizes, url: BID_ENDPOINT, method: 'GET', data: Object.assign(data, _getBrowserParams(topWindowUrl), _getDigiTrustQueryParams(userId), _getTradeDeskIDParam(userId)) @@ -271,6 +317,7 @@ function interpretResponse (serverResponse, bidRequest) { bidResponses.push({ // dealId: DEAL_ID, // referrer: REFERER, + ...(product === 7 && { vastXml: markup }), ad: wrapper ? getWrapperCode(wrapper, Object.assign({}, serverResponseBody, { bidRequest })) : markup, cpm: isTestUnit ? 0.1 : cpm, creativeId, @@ -314,6 +361,7 @@ export const spec = { isBidRequestValid, buildRequests, interpretResponse, - getUserSyncs + getUserSyncs, + supportedMediaTypes: SUPPORTED_MEDIA_TYPES } registerBidder(spec) diff --git a/test/spec/modules/gumgumBidAdapter_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js index f98d8bf306e..8f0968cf530 100644 --- a/test/spec/modules/gumgumBidAdapter_spec.js +++ b/test/spec/modules/gumgumBidAdapter_spec.js @@ -106,7 +106,7 @@ describe('gumgumAdapter', function () { expect(request.method).to.equal('GET'); expect(request.id).to.equal('30b31c1838de1e'); }); - it('should correctly set the request paramters depending on params field', function () { + it('should set t and fp parameters in bid request if inScreen request param is found', function () { const request = Object.assign({}, bidRequests[0]); delete request.params; request.params = { @@ -129,7 +129,7 @@ describe('gumgumAdapter', function () { expect(bidRequest.data.pubId).to.equal(request.params.inScreenPubID); expect(bidRequest.data).to.not.include.any.keys('t'); }); - it('should correctly set the request paramters depending on params field', function () { + it('should set a ni parameter in bid request if ICV request param is found', function () { const request = Object.assign({}, bidRequests[0]); delete request.params; request.params = { @@ -139,6 +139,36 @@ describe('gumgumAdapter', function () { expect(bidRequest.data.pi).to.equal(5); expect(bidRequest.data).to.include.any.keys('ni'); }); + it('should add parameters associated with video if video request param is found', function () { + const videoVals = { + playerSize: [640, 480], + context: 'instream', + minduration: 1, + maxduration: 2, + linearity: 1, + startdelay: 1, + placement: 123456, + protocols: [1,2] + }; + const request = Object.assign({}, bidRequests[0]); + delete request.params; + request.mediaTypes = { + video: videoVals + }; + request.params = { + 'video': '10433395' + }; + const bidRequest = spec.buildRequests([request])[0]; + expect(bidRequest.data.pi).to.eq(7); + expect(bidRequest.data.mind).to.eq(videoVals.minduration); + expect(bidRequest.data.maxd).to.eq(videoVals.maxduration); + expect(bidRequest.data.li).to.eq(videoVals.linearity); + expect(bidRequest.data.sd).to.eq(videoVals.startdelay); + expect(bidRequest.data.pt).to.eq(videoVals.placement); + expect(bidRequest.data.pr).to.eq(videoVals.protocols.join(',')); + expect(bidRequest.data.viw).to.eq(videoVals.playerSize[0].toString()); + expect(bidRequest.data.vih).to.eq(videoVals.playerSize[1].toString()); + }); it('should not add additional parameters depending on params field', function () { const request = spec.buildRequests(bidRequests)[0]; expect(request.data).to.not.include.any.keys('ni'); From 8d99b32830b3756c69172e138525b08a36021c10 Mon Sep 17 00:00:00 2001 From: Susan Date: Wed, 12 Feb 2020 09:05:09 -0800 Subject: [PATCH 5/5] fix linting --- test/spec/modules/gumgumBidAdapter_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spec/modules/gumgumBidAdapter_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js index 8f0968cf530..fb4c1bf7b30 100644 --- a/test/spec/modules/gumgumBidAdapter_spec.js +++ b/test/spec/modules/gumgumBidAdapter_spec.js @@ -148,7 +148,7 @@ describe('gumgumAdapter', function () { linearity: 1, startdelay: 1, placement: 123456, - protocols: [1,2] + protocols: [1, 2] }; const request = Object.assign({}, bidRequests[0]); delete request.params;