From cd66b75b46595053a8e53c283ed661231ad51367 Mon Sep 17 00:00:00 2001 From: Joshua Goldstein Date: Fri, 10 May 2019 19:54:05 -0700 Subject: [PATCH 1/9] Added CPMStar Bid Adapter --- modules/cpmstarBidAdapter.js | 118 +++++++++++++++ modules/cpmstarBidAdapter.md | 31 ++++ test/spec/modules/cpmstarBidAdapter_spec.js | 156 ++++++++++++++++++++ 3 files changed, 305 insertions(+) create mode 100755 modules/cpmstarBidAdapter.js create mode 100755 modules/cpmstarBidAdapter.md create mode 100755 test/spec/modules/cpmstarBidAdapter_spec.js diff --git a/modules/cpmstarBidAdapter.js b/modules/cpmstarBidAdapter.js new file mode 100755 index 00000000000..3b5951913c5 --- /dev/null +++ b/modules/cpmstarBidAdapter.js @@ -0,0 +1,118 @@ +import * as utils from 'src/utils'; +import { registerBidder } from 'src/adapters/bidderFactory'; +import {VIDEO, BANNER} from '../src/mediaTypes'; + +const BIDDER_CODE = 'cpmstar'; + +const ENDPOINT_DEV = '//dev.server.cpmstar.com/view.aspx'; +const ENDPOINT_STAGING = '//staging.server.cpmstar.com/view.aspx'; +const ENDPOINT_PRODUCTION = '//server.cpmstar.com/view.aspx'; + +const DEFAULT_TTL = 300; +const DEFAULT_CURRENCY = 'USD'; + +function getMediaType(bidRequest) { + if (bidRequest == null) return BANNER; + return !utils.deepAccess(bidRequest, 'mediaTypes.video') ? BANNER : VIDEO; +} + +function getPlayerSize(bidRequest) { + var playerSize = utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'); + if (playerSize == null || playerSize[0] == null || playerSize[1] == null) return [640, 440]; +} + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO], + pageID: Math.floor(Math.random() * 10e6), + + isBidRequestValid: function (bid) { + return ((typeof bid.params.placementId === 'string') && !!bid.params.placementId.length) || (typeof bid.params.placementId === 'number'); + }, + + buildRequests: function (validBidRequests, bidderRequest) { + var requests = []; + // This reference to window.top can cause issues when loaded in an iframe if not protected with a try/catch. + + for (var i = 0; i < validBidRequests.length; i++) { + var bidRequest = validBidRequests[i]; + var referer = encodeURIComponent(bidderRequest.refererInfo.referer); + var e = utils.getBidIdParameter('endpoint', bidRequest.params); + var ENDPOINT = e == 'dev' ? ENDPOINT_DEV : e == 'staging' ? ENDPOINT_STAGING : ENDPOINT_PRODUCTION; + var mediaType = getMediaType(bidRequest); + var playerSize = getPlayerSize(bidRequest); + var videoArgs = '&fv=0' + (playerSize ? ('&w=' + playerSize[0] + '&h=' + playerSize[1]) : ''); + requests.push({ + method: 'GET', + url: ENDPOINT + '?media=' + mediaType + (mediaType == VIDEO ? videoArgs : '') + '&json=c_b&mv=1&poolid=' + utils.getBidIdParameter('placementId', bidRequest.params) + '&reachedTop=' + encodeURIComponent(bidderRequest.refererInfo.reachedTop) + '&requestid=' + bidRequest.bidId + '&referer=' + referer, + bidRequest: bidRequest, + }); + } + + return requests; + }, + + onTimeout(timeout) { + }, + onBidWon(winningBid) { + }, + + interpretResponse: function (serverResponse, request) { + var bidRequest = request.bidRequest; + var mediaType = getMediaType(bidRequest); + + var bidResponses = []; + + if (!Array.isArray(serverResponse.body)) { + serverResponse.body = [serverResponse.body]; + } + + for (var i = 0; i < serverResponse.body.length; i++) { + var raw = serverResponse.body[i]; + var rawBid = raw.creatives[0]; + if (!rawBid) { + return; + } + var cpm = (parseFloat(rawBid.cpm) || 0); + + if (!cpm) { + return; + } + + var bidResponse = { + requestId: rawBid.requestid, + cpm: cpm, + width: rawBid.width || 0, + height: rawBid.height || 0, + currency: rawBid.currency ? rawBid.currency : DEFAULT_CURRENCY, + netRevenue: rawBid.netRevenue ? rawBid.netRevenue : true, + ttl: rawBid.ttl ? rawBid.ttl : DEFAULT_TTL, + creativeId: rawBid.creativeid || 0, + ad: '' + }; + + if (rawBid.hasOwnProperty('dealId')) { + bidResponse.dealId = rawBid.dealId + } + + if (mediaType == BANNER && rawBid.code) { + bidResponse.ad = rawBid.code + (rawBid.px_cr ? "\n" : ''); + } else if (mediaType == VIDEO && rawBid.creativemacros && rawBid.creativemacros.HTML5VID_VASTSTRING) { + var playerSize = getPlayerSize(bidRequest); + if (playerSize != null) { + bidResponse.width = playerSize[0]; + bidResponse.height = playerSize[1]; + } + bidResponse.mediaType = VIDEO; + bidResponse.vastXml = rawBid.creativemacros.HTML5VID_VASTSTRING; + } else { + return utils.logError('bad response', rawBid); + } + + bidResponses.push(bidResponse); + } + + return bidResponses; + } +}; +registerBidder(spec); diff --git a/modules/cpmstarBidAdapter.md b/modules/cpmstarBidAdapter.md new file mode 100755 index 00000000000..fe3c4e85a84 --- /dev/null +++ b/modules/cpmstarBidAdapter.md @@ -0,0 +1,31 @@ +# Overview + +``` +Module Name: Cpmstar Bidder Adapter +Module Type: Bidder Adapter +Maintainer: josh@cpmstar.com +``` + +# Description + +Module that connects to Cpmstar's demand sources + +# Test Parameters +``` +var adUnits = [ + { + code: 'banner-ad-div', + mediaTypes: { + banner: { + sizes: [[300, 250]], + } + }, + bids: [{ + bidder: 'cpmstar', + params: { + placementId: 81006 + } + }] + } +]; +``` \ No newline at end of file diff --git a/test/spec/modules/cpmstarBidAdapter_spec.js b/test/spec/modules/cpmstarBidAdapter_spec.js new file mode 100755 index 00000000000..c1f4560944b --- /dev/null +++ b/test/spec/modules/cpmstarBidAdapter_spec.js @@ -0,0 +1,156 @@ +import { expect } from 'chai'; +import { spec } from 'modules/cpmstarBidAdapter'; +import { deepClone } from 'src/utils'; + +describe('Cpmstar Bid Adapter', function () { + describe('isBidRequestValid', function () { + it('should return true since the bid is valid', + function () { + var bid = { params: { placementId: 123456 } }; + expect(spec.isBidRequestValid(bid)).to.equal(true); + }) + + it('should return false since the bid is invalid', function () { + var bid = { params: { placementId: '' } }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }) + }); + + describe('buildRequests', function () { + const valid_bid_requests = [{ + 'bidder': 'cpmstar', + 'params': { + 'placementId': '57' + }, + 'sizes': [[300, 250]], + 'bidId': 'bidId' + }]; + + const bidderRequest = { + refererInfo: { + referer: 'referer', + reachedTop: false, + } + + }; + + it('should produce a valid production request', function () { + var requests = spec.buildRequests(valid_bid_requests, bidderRequest); + expect(requests[0]).to.have.property('method'); + expect(requests[0]).to.have.property('url'); + expect(requests[0]).to.have.property('bidRequest'); + expect(requests[0].url.startsWith('//server.cpmstar.com/view.aspx')).to.equal(true); + }); + it('should produce a valid staging request', function () { + var stgReq = deepClone(valid_bid_requests); + stgReq[0].params.endpoint = 'staging'; + var requests = spec.buildRequests(stgReq, bidderRequest); + expect(requests[0]).to.have.property('method'); + expect(requests[0]).to.have.property('url'); + expect(requests[0]).to.have.property('bidRequest'); + expect(requests[0].url.startsWith('//staging.server.cpmstar.com/view.aspx')).to.equal(true); + }); + it('should produce a valid dev request', function () { + var devReq = deepClone(valid_bid_requests); + devReq[0].params.endpoint = 'dev'; + var requests = spec.buildRequests(devReq, bidderRequest); + expect(requests[0]).to.have.property('method'); + expect(requests[0]).to.have.property('url'); + expect(requests[0]).to.have.property('bidRequest'); + expect(requests[0].url.startsWith('//dev.server.cpmstar.com/view.aspx')).to.equal(true); + }); + }) + + describe('interpretResponse', function () { + const request = { + bidRequest: { + mediaType: 'BANNER' + } + }; + const serverResponse = { + body: [{ + creatives: [{ + cpm: 1, + width: 0, + height: 0, + currency: 'USD', + netRevenue: true, + ttl: 1, + creativeid: '1234', + requestid: '11123', + code: 'no idea', + media: 'banner', + } + ], + }] + }; + + it('should return a valid bidresponse array', function () { + var r = spec.interpretResponse(serverResponse, request) + var c = serverResponse.body[0].creatives[0]; + expect(r[0].length).to.not.equal(0); + expect(r[0].requestId).equal(c.requestid); + expect(r[0].creativeId).equal(c.creativeid); + expect(r[0].cpm).equal(c.cpm); + expect(r[0].width).equal(c.width); + expect(r[0].height).equal(c.height); + expect(r[0].currency).equal(c.currency); + expect(r[0].netRevenue).equal(c.netRevenue); + expect(r[0].ttl).equal(c.ttl); + expect(r[0].ad).equal(c.code); + }); + + it('should return a valid bidresponse array from a non-array-body', function () { + var r = spec.interpretResponse({ body: serverResponse.body[0] }, request) + var c = serverResponse.body[0].creatives[0]; + expect(r[0].length).to.not.equal(0); + expect(r[0].requestId).equal(c.requestid); + expect(r[0].creativeId).equal(c.creativeid); + expect(r[0].cpm).equal(c.cpm); + expect(r[0].width).equal(c.width); + expect(r[0].height).equal(c.height); + expect(r[0].currency).equal(c.currency); + expect(r[0].netRevenue).equal(c.netRevenue); + expect(r[0].ttl).equal(c.ttl); + expect(r[0].ad).equal(c.code); + }); + + it('should return undefined due to an invalid cpm value', function () { + var badServer = deepClone(serverResponse); + badServer.body[0].creatives[0].cpm = 0; + var c = spec.interpretResponse(badServer, request); + expect(c).to.be.undefined; + }); + + it('should return undefined due to a bad response', function () { + var badServer = deepClone(serverResponse); + badServer.body[0].creatives[0].code = null; + var c = spec.interpretResponse(badServer, request); + expect(c).to.be.undefined; + }); + + it('should return a valid response with a dealId', function () { + var dealServer = deepClone(serverResponse); + dealServer.body[0].creatives[0].dealId = 'deal'; + expect(spec.interpretResponse(dealServer, request)[0].dealId).to.equal('deal'); + }); + }); + + describe('onTimeout', function () { + it('should do and return nothing', function () { + var timeout = 'test'; + var r = spec.onTimeout('test'); + expect(r).to.be.undefined; + expect(timeout).to.equal(timeout); + }) + }); + + describe('onBidWon', function () { + it('should do and return nothing', function () { + var bid = 'test'; + var r = spec.onBidWon('test'); + expect(r).to.be.undefined; + expect(bid).to.equal('test'); + }); + }); +}); From 1f60e6c61ac8a0da41bc9c704d896f111b64edaf Mon Sep 17 00:00:00 2001 From: Joshua Goldstein Date: Fri, 10 May 2019 20:14:07 -0700 Subject: [PATCH 2/9] Updated getPlayerSize for cpmstarBidAdapter --- modules/cpmstarBidAdapter.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/cpmstarBidAdapter.js b/modules/cpmstarBidAdapter.js index 3b5951913c5..9e448e1bd1c 100755 --- a/modules/cpmstarBidAdapter.js +++ b/modules/cpmstarBidAdapter.js @@ -18,7 +18,9 @@ function getMediaType(bidRequest) { function getPlayerSize(bidRequest) { var playerSize = utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'); + if (playerSize[0] != null) playerSize = playerSize[0]; if (playerSize == null || playerSize[0] == null || playerSize[1] == null) return [640, 440]; + return playerSize; } export const spec = { From 80209231d9d605d646b6be80ad76e81ec44fda4f Mon Sep 17 00:00:00 2001 From: Joshua Goldstein Date: Fri, 10 May 2019 20:42:37 -0700 Subject: [PATCH 3/9] Improved cpmstarBidAdapter code coverage --- modules/cpmstarBidAdapter.js | 33 +++++++++++---------- test/spec/modules/cpmstarBidAdapter_spec.js | 20 +++++++++++++ 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/modules/cpmstarBidAdapter.js b/modules/cpmstarBidAdapter.js index 9e448e1bd1c..93416cca91f 100755 --- a/modules/cpmstarBidAdapter.js +++ b/modules/cpmstarBidAdapter.js @@ -11,23 +11,24 @@ const ENDPOINT_PRODUCTION = '//server.cpmstar.com/view.aspx'; const DEFAULT_TTL = 300; const DEFAULT_CURRENCY = 'USD'; -function getMediaType(bidRequest) { - if (bidRequest == null) return BANNER; - return !utils.deepAccess(bidRequest, 'mediaTypes.video') ? BANNER : VIDEO; -} - -function getPlayerSize(bidRequest) { - var playerSize = utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'); - if (playerSize[0] != null) playerSize = playerSize[0]; - if (playerSize == null || playerSize[0] == null || playerSize[1] == null) return [640, 440]; - return playerSize; -} - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO], pageID: Math.floor(Math.random() * 10e6), + getMediaType: function(bidRequest) { + if (bidRequest == null) return BANNER; + return !utils.deepAccess(bidRequest, 'mediaTypes.video') ? BANNER : VIDEO; + }, + + getPlayerSize: function(bidRequest) { + var playerSize = utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'); + if (playerSize == null) return [640, 440]; + if (playerSize[0] != null) playerSize = playerSize[0]; + if (playerSize == null || playerSize[0] == null || playerSize[1] == null) return [640, 440]; + return playerSize; + }, + isBidRequestValid: function (bid) { return ((typeof bid.params.placementId === 'string') && !!bid.params.placementId.length) || (typeof bid.params.placementId === 'number'); }, @@ -41,8 +42,8 @@ export const spec = { var referer = encodeURIComponent(bidderRequest.refererInfo.referer); var e = utils.getBidIdParameter('endpoint', bidRequest.params); var ENDPOINT = e == 'dev' ? ENDPOINT_DEV : e == 'staging' ? ENDPOINT_STAGING : ENDPOINT_PRODUCTION; - var mediaType = getMediaType(bidRequest); - var playerSize = getPlayerSize(bidRequest); + var mediaType = spec.getMediaType(bidRequest); + var playerSize = spec.getPlayerSize(bidRequest); var videoArgs = '&fv=0' + (playerSize ? ('&w=' + playerSize[0] + '&h=' + playerSize[1]) : ''); requests.push({ method: 'GET', @@ -61,7 +62,7 @@ export const spec = { interpretResponse: function (serverResponse, request) { var bidRequest = request.bidRequest; - var mediaType = getMediaType(bidRequest); + var mediaType = spec.getMediaType(bidRequest); var bidResponses = []; @@ -100,7 +101,7 @@ export const spec = { if (mediaType == BANNER && rawBid.code) { bidResponse.ad = rawBid.code + (rawBid.px_cr ? "\n" : ''); } else if (mediaType == VIDEO && rawBid.creativemacros && rawBid.creativemacros.HTML5VID_VASTSTRING) { - var playerSize = getPlayerSize(bidRequest); + var playerSize = spec.getPlayerSize(bidRequest); if (playerSize != null) { bidResponse.width = playerSize[0]; bidResponse.height = playerSize[1]; diff --git a/test/spec/modules/cpmstarBidAdapter_spec.js b/test/spec/modules/cpmstarBidAdapter_spec.js index c1f4560944b..758d408344a 100755 --- a/test/spec/modules/cpmstarBidAdapter_spec.js +++ b/test/spec/modules/cpmstarBidAdapter_spec.js @@ -14,6 +14,26 @@ describe('Cpmstar Bid Adapter', function () { var bid = { params: { placementId: '' } }; expect(spec.isBidRequestValid(bid)).to.equal(false); }) + + it('should return a valid player size', function() { + var bid = { mediaTypes: { + video: { + playerSize: [[960, 540]] + } + }} + expect(spec.getPlayerSize(bid)[0]).to.equal(960); + expect(spec.getPlayerSize(bid)[1]).to.equal(540); + }) + + it('should return a default player size', function() { + var bid = { mediaTypes: { + video: { + playerSize: null + } + }} + expect(spec.getPlayerSize(bid)[0]).to.equal(640); + expect(spec.getPlayerSize(bid)[1]).to.equal(440); + }) }); describe('buildRequests', function () { From 06911ae3fa1f8d39181240ddf2ea385fbdb656e9 Mon Sep 17 00:00:00 2001 From: Nicholas Elek Date: Tue, 14 May 2019 15:42:42 -0700 Subject: [PATCH 4/9] updated test spec, removed empty functions, made imports relative, added warnings to erroneous server responses, and removed the default value for ad in bid response. --- modules/cpmstarBidAdapter.js | 13 +++++------ test/spec/modules/cpmstarBidAdapter_spec.js | 24 +++------------------ 2 files changed, 8 insertions(+), 29 deletions(-) diff --git a/modules/cpmstarBidAdapter.js b/modules/cpmstarBidAdapter.js index 93416cca91f..84b76cbbc35 100755 --- a/modules/cpmstarBidAdapter.js +++ b/modules/cpmstarBidAdapter.js @@ -1,5 +1,6 @@ -import * as utils from 'src/utils'; -import { registerBidder } from 'src/adapters/bidderFactory'; + +import * as utils from '../src/utils'; +import { registerBidder } from '../src/adapters/bidderFactory'; import {VIDEO, BANNER} from '../src/mediaTypes'; const BIDDER_CODE = 'cpmstar'; @@ -55,11 +56,6 @@ export const spec = { return requests; }, - onTimeout(timeout) { - }, - onBidWon(winningBid) { - }, - interpretResponse: function (serverResponse, request) { var bidRequest = request.bidRequest; var mediaType = spec.getMediaType(bidRequest); @@ -74,11 +70,13 @@ export const spec = { var raw = serverResponse.body[i]; var rawBid = raw.creatives[0]; if (!rawBid) { + utils.logWarn('cpmstarBidAdapter: server response failed check'); return; } var cpm = (parseFloat(rawBid.cpm) || 0); if (!cpm) { + utils.logWarn('cpmstarBidAdapter: server response failed check. Missing cpm') return; } @@ -91,7 +89,6 @@ export const spec = { netRevenue: rawBid.netRevenue ? rawBid.netRevenue : true, ttl: rawBid.ttl ? rawBid.ttl : DEFAULT_TTL, creativeId: rawBid.creativeid || 0, - ad: '' }; if (rawBid.hasOwnProperty('dealId')) { diff --git a/test/spec/modules/cpmstarBidAdapter_spec.js b/test/spec/modules/cpmstarBidAdapter_spec.js index 758d408344a..3dd06a484d9 100755 --- a/test/spec/modules/cpmstarBidAdapter_spec.js +++ b/test/spec/modules/cpmstarBidAdapter_spec.js @@ -59,7 +59,7 @@ describe('Cpmstar Bid Adapter', function () { expect(requests[0]).to.have.property('method'); expect(requests[0]).to.have.property('url'); expect(requests[0]).to.have.property('bidRequest'); - expect(requests[0].url.startsWith('//server.cpmstar.com/view.aspx')).to.equal(true); + expect(requests[0].url).to.include('//server.cpmstar.com/view.aspx'); }); it('should produce a valid staging request', function () { var stgReq = deepClone(valid_bid_requests); @@ -68,7 +68,7 @@ describe('Cpmstar Bid Adapter', function () { expect(requests[0]).to.have.property('method'); expect(requests[0]).to.have.property('url'); expect(requests[0]).to.have.property('bidRequest'); - expect(requests[0].url.startsWith('//staging.server.cpmstar.com/view.aspx')).to.equal(true); + expect(requests[0].url).to.include('//staging.server.cpmstar.com/view.aspx'); }); it('should produce a valid dev request', function () { var devReq = deepClone(valid_bid_requests); @@ -77,7 +77,7 @@ describe('Cpmstar Bid Adapter', function () { expect(requests[0]).to.have.property('method'); expect(requests[0]).to.have.property('url'); expect(requests[0]).to.have.property('bidRequest'); - expect(requests[0].url.startsWith('//dev.server.cpmstar.com/view.aspx')).to.equal(true); + expect(requests[0].url).to.include('//dev.server.cpmstar.com/view.aspx'); }); }) @@ -155,22 +155,4 @@ describe('Cpmstar Bid Adapter', function () { expect(spec.interpretResponse(dealServer, request)[0].dealId).to.equal('deal'); }); }); - - describe('onTimeout', function () { - it('should do and return nothing', function () { - var timeout = 'test'; - var r = spec.onTimeout('test'); - expect(r).to.be.undefined; - expect(timeout).to.equal(timeout); - }) - }); - - describe('onBidWon', function () { - it('should do and return nothing', function () { - var bid = 'test'; - var r = spec.onBidWon('test'); - expect(r).to.be.undefined; - expect(bid).to.equal('test'); - }); - }); }); From c43d765311e098a0004c6dbe7b76c3cff2f8f5ab Mon Sep 17 00:00:00 2001 From: Nicholas Elek Date: Tue, 14 May 2019 17:45:31 -0700 Subject: [PATCH 5/9] added test video ad unit --- modules/cpmstarBidAdapter.md | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/modules/cpmstarBidAdapter.md b/modules/cpmstarBidAdapter.md index fe3c4e85a84..7dab435b0f0 100755 --- a/modules/cpmstarBidAdapter.md +++ b/modules/cpmstarBidAdapter.md @@ -20,12 +20,31 @@ var adUnits = [ sizes: [[300, 250]], } }, - bids: [{ - bidder: 'cpmstar', - params: { - placementId: 81006 + bids: [ + { + bidder: 'cpmstar', + params: { + placementId: 81006 + } + }, + ] + }, + { + code: 'video-ad-div', + mediaTypes: { + video: { + context: 'instream', + sizes: [[640, 480]] + } + }, + bids:[ + { + bidder: 'cpmstar', + params: { + placementId: 81007 + } } - }] + ] } ]; ``` \ No newline at end of file From 8e79f9e0fe1feb0ce7907f5854dd04ac13a98c05 Mon Sep 17 00:00:00 2001 From: Nicholas Elek Date: Thu, 7 May 2020 22:03:59 -0700 Subject: [PATCH 6/9] added support for gdpr and coppa --- modules/cpmstarBidAdapter.js | 33 +++++++++++++++++++++++++++++---- modules/cpmstarBidAdapter.md | 3 +++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/modules/cpmstarBidAdapter.js b/modules/cpmstarBidAdapter.js index 6146e704448..ff4c73fb5e0 100755 --- a/modules/cpmstarBidAdapter.js +++ b/modules/cpmstarBidAdapter.js @@ -1,7 +1,8 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; -import {VIDEO, BANNER} from '../src/mediaTypes.js'; +import { VIDEO, BANNER } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'cpmstar'; @@ -17,12 +18,12 @@ export const spec = { supportedMediaTypes: [BANNER, VIDEO], pageID: Math.floor(Math.random() * 10e6), - getMediaType: function(bidRequest) { + getMediaType: function (bidRequest) { if (bidRequest == null) return BANNER; return !utils.deepAccess(bidRequest, 'mediaTypes.video') ? BANNER : VIDEO; }, - getPlayerSize: function(bidRequest) { + getPlayerSize: function (bidRequest) { var playerSize = utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'); if (playerSize == null) return [640, 440]; if (playerSize[0] != null) playerSize = playerSize[0]; @@ -46,9 +47,33 @@ export const spec = { var mediaType = spec.getMediaType(bidRequest); var playerSize = spec.getPlayerSize(bidRequest); var videoArgs = '&fv=0' + (playerSize ? ('&w=' + playerSize[0] + '&h=' + playerSize[1]) : ''); + + let url = ENDPOINT + '?media=' + mediaType + (mediaType == VIDEO ? videoArgs : '') + + '&json=c_b&mv=1&poolid=' + utils.getBidIdParameter('placementId', bidRequest.params) + + '&reachedTop=' + encodeURIComponent(bidderRequest.refererInfo.reachedTop) + + '&requestid=' + bidRequest.bidId + + '&referer=' + encodeURIComponent(referer); + + if (bidderRequest.gdprConsent) { + if (bidderRequest.gdprConsent.consentString != undefined) { + url += '&gdpr_consent=' + bidderRequest.gdprConsent.consentString; + } + if (bidderRequest.gdprConsent.gdprApplies != undefined) { + url += '&gdpr=' + (bidderRequest.gdprConsent.gdprApplies ? 1 : 0); + } + } + + if (bidderRequest.uspConsent != undefined) { + url += '&us_privacy=' + bidderRequest.uspConsent; + } + + if (config.getConfig('coppa')) { + url += '&tfcd=' + (config.getConfig('coppa') ? 1 : 0); + } + requests.push({ method: 'GET', - url: ENDPOINT + '?media=' + mediaType + (mediaType == VIDEO ? videoArgs : '') + '&json=c_b&mv=1&poolid=' + utils.getBidIdParameter('placementId', bidRequest.params) + '&reachedTop=' + encodeURIComponent(bidderRequest.refererInfo.reachedTop) + '&requestid=' + bidRequest.bidId + '&referer=' + referer, + url: url, bidRequest: bidRequest, }); } diff --git a/modules/cpmstarBidAdapter.md b/modules/cpmstarBidAdapter.md index 7dab435b0f0..c227f19bfaf 100755 --- a/modules/cpmstarBidAdapter.md +++ b/modules/cpmstarBidAdapter.md @@ -4,6 +4,9 @@ Module Name: Cpmstar Bidder Adapter Module Type: Bidder Adapter Maintainer: josh@cpmstar.com +gdpr_supported: true +usp_supported: true +coppa_supported: true ``` # Description From abf72f0d3800505808d240f3b6bea6c4fb94b63f Mon Sep 17 00:00:00 2001 From: Nicholas Elek Date: Sun, 10 May 2020 00:41:31 -0700 Subject: [PATCH 7/9] changed != undefined to != null --- modules/cpmstarBidAdapter.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/cpmstarBidAdapter.js b/modules/cpmstarBidAdapter.js index ff4c73fb5e0..c0266afceb3 100755 --- a/modules/cpmstarBidAdapter.js +++ b/modules/cpmstarBidAdapter.js @@ -55,15 +55,15 @@ export const spec = { '&referer=' + encodeURIComponent(referer); if (bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.consentString != undefined) { + if (bidderRequest.gdprConsent.consentString != null) { url += '&gdpr_consent=' + bidderRequest.gdprConsent.consentString; } - if (bidderRequest.gdprConsent.gdprApplies != undefined) { + if (bidderRequest.gdprConsent.gdprApplies != null) { url += '&gdpr=' + (bidderRequest.gdprConsent.gdprApplies ? 1 : 0); } } - if (bidderRequest.uspConsent != undefined) { + if (bidderRequest.uspConsent != null) { url += '&us_privacy=' + bidderRequest.uspConsent; } From f47eb96e6f0818fffbf26e7f18993b279e5a4e2f Mon Sep 17 00:00:00 2001 From: Nicholas Elek Date: Sun, 10 May 2020 01:45:45 -0700 Subject: [PATCH 8/9] changed let to var --- modules/cpmstarBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cpmstarBidAdapter.js b/modules/cpmstarBidAdapter.js index c0266afceb3..b416c00c2d0 100755 --- a/modules/cpmstarBidAdapter.js +++ b/modules/cpmstarBidAdapter.js @@ -48,7 +48,7 @@ export const spec = { var playerSize = spec.getPlayerSize(bidRequest); var videoArgs = '&fv=0' + (playerSize ? ('&w=' + playerSize[0] + '&h=' + playerSize[1]) : ''); - let url = ENDPOINT + '?media=' + mediaType + (mediaType == VIDEO ? videoArgs : '') + + var url = ENDPOINT + '?media=' + mediaType + (mediaType == VIDEO ? videoArgs : '') + '&json=c_b&mv=1&poolid=' + utils.getBidIdParameter('placementId', bidRequest.params) + '&reachedTop=' + encodeURIComponent(bidderRequest.refererInfo.reachedTop) + '&requestid=' + bidRequest.bidId + From 2e2f648b01fee59981332b125f6142113f11f8dc Mon Sep 17 00:00:00 2001 From: Nicholas Elek Date: Sat, 16 May 2020 23:22:59 -0700 Subject: [PATCH 9/9] added unit for GDPR, COPPA, and USP. --- test/spec/modules/cpmstarBidAdapter_spec.js | 50 ++++++++++++++++----- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/test/spec/modules/cpmstarBidAdapter_spec.js b/test/spec/modules/cpmstarBidAdapter_spec.js index 9e794d3e098..1993f28e5d5 100755 --- a/test/spec/modules/cpmstarBidAdapter_spec.js +++ b/test/spec/modules/cpmstarBidAdapter_spec.js @@ -1,6 +1,7 @@ import { expect } from 'chai'; import { spec } from 'modules/cpmstarBidAdapter.js'; import { deepClone } from 'src/utils.js'; +import { config } from 'src/config.js'; describe('Cpmstar Bid Adapter', function () { describe('isBidRequestValid', function () { @@ -15,22 +16,26 @@ describe('Cpmstar Bid Adapter', function () { expect(spec.isBidRequestValid(bid)).to.equal(false); }) - it('should return a valid player size', function() { - var bid = { mediaTypes: { - video: { - playerSize: [[960, 540]] + it('should return a valid player size', function () { + var bid = { + mediaTypes: { + video: { + playerSize: [[960, 540]] + } } - }} + } expect(spec.getPlayerSize(bid)[0]).to.equal(960); expect(spec.getPlayerSize(bid)[1]).to.equal(540); }) - it('should return a default player size', function() { - var bid = { mediaTypes: { - video: { - playerSize: null + it('should return a default player size', function () { + var bid = { + mediaTypes: { + video: { + playerSize: null + } } - }} + } expect(spec.getPlayerSize(bid)[0]).to.equal(640); expect(spec.getPlayerSize(bid)[1]).to.equal(440); }) @@ -79,6 +84,31 @@ describe('Cpmstar Bid Adapter', function () { expect(requests[0]).to.have.property('bidRequest'); expect(requests[0].url).to.include('https://dev.server.cpmstar.com/view.aspx'); }); + it('should produce a request with support for GDPR', function () { + var gdpr_bidderRequest = deepClone(bidderRequest); + gdpr_bidderRequest.gdprConsent = { + consentString: 'consentString', + gdprApplies: true + }; + var requests = spec.buildRequests(valid_bid_requests, gdpr_bidderRequest); + expect(requests[0]).to.have.property('url'); + expect(requests[0].url).to.include('gdpr_consent=consentString'); + expect(requests[0].url).to.include('gdpr=1'); + }); + it('should produce a request with support for USP', function () { + var usp_bidderRequest = deepClone(bidderRequest); + usp_bidderRequest.uspConsent = '1YYY'; + var requests = spec.buildRequests(valid_bid_requests, usp_bidderRequest); + expect(requests[0]).to.have.property('url'); + expect(requests[0].url).to.include('us_privacy=1YYY'); + }); + it('should produce a request with support for COPPA', function () { + sinon.stub(config, 'getConfig').withArgs('coppa').returns(true); + var requests = spec.buildRequests(valid_bid_requests, bidderRequest); + config.getConfig.restore(); + expect(requests[0]).to.have.property('url'); + expect(requests[0].url).to.include('tfcd=1'); + }); }) describe('interpretResponse', function () {