From 58dae9fd4feaf612b4acdffc4988d3e7e6dabf56 Mon Sep 17 00:00:00 2001 From: Niels Baarsma Date: Wed, 20 Dec 2017 16:06:59 +0300 Subject: [PATCH 1/5] Make Bid Adapter for Dentsu Aegis Network Marketplace --- modules/danmarketplaceBidAdapter.js | 144 +++++++++ modules/danmarketplaceBidAdapter.md | 40 +++ .../modules/danmarketplaceBidAdapter_spec.js | 289 ++++++++++++++++++ 3 files changed, 473 insertions(+) create mode 100644 modules/danmarketplaceBidAdapter.js create mode 100755 modules/danmarketplaceBidAdapter.md create mode 100644 test/spec/modules/danmarketplaceBidAdapter_spec.js diff --git a/modules/danmarketplaceBidAdapter.js b/modules/danmarketplaceBidAdapter.js new file mode 100644 index 00000000000..2419292f79e --- /dev/null +++ b/modules/danmarketplaceBidAdapter.js @@ -0,0 +1,144 @@ +import * as utils from 'src/utils'; +import {registerBidder} from 'src/adapters/bidderFactory'; +const BIDDER_CODE = 'danmarketplace'; +const ENDPOINT_URL = '//ads.danmarketplace.com/hb'; +const TIME_TO_LIVE = 360; +const ADAPTER_SYNC_URL = '//ads.danmarketplace.com/push_sync'; +const LOG_ERROR_MESS = { + noAuid: 'Bid from response has no auid parameter - ', + noAdm: 'Bid from response has no adm parameter - ', + noBid: 'Array of bid objects is empty', + noPlacementCode: 'Can\'t find in requested bids the bid with auid - ', + emptyUids: 'Uids should be not empty', + emptySeatbid: 'Seatbid array from response has empty item', + emptyResponse: 'Response is empty', + hasEmptySeatbidArray: 'Response has empty seatbid array', + hasNoArrayOfBids: 'Seatbid from response has no array of bid objects - ' +}; + +/** + * Dentsu Aegis Network Marketplace Bid Adapter. + * Contact: niels@baarsma.net + * + */ +export const spec = { + code: BIDDER_CODE, + + aliases: ['DANMarketplace', 'DAN_Marketplace'], + + isBidRequestValid: function(bid) { + return !!bid.params.uid; + }, + + buildRequests: function(validBidRequests) { + const auids = []; + const bidsMap = {}; + const bids = validBidRequests || []; + let priceType = 'net'; + let reqId; + + bids.forEach(bid => { + if (bid.params.priceType === 'gross') { + priceType = 'gross'; + } + if (!bidsMap[bid.params.uid]) { + bidsMap[bid.params.uid] = [bid]; + auids.push(bid.params.uid); + } else { + bidsMap[bid.params.uid].push(bid); + } + reqId = bid.bidderRequestId; + }); + + const payload = { + u: utils.getTopWindowUrl(), + pt: priceType, + auids: auids.join(','), + r: reqId, + }; + + return { + method: 'GET', + url: ENDPOINT_URL, + data: payload, + bidsMap: bidsMap, + }; + }, + + interpretResponse: function(serverResponse, bidRequest) { + serverResponse = serverResponse && serverResponse.body + const bidResponses = []; + const bidsMap = bidRequest.bidsMap; + const priceType = bidRequest.data.pt; + + let errorMessage; + + if (!serverResponse) errorMessage = LOG_ERROR_MESS.emptyResponse; + else if (serverResponse.seatbid && !serverResponse.seatbid.length) { + errorMessage = LOG_ERROR_MESS.hasEmptySeatbidArray; + } + + if (!errorMessage && serverResponse.seatbid) { + serverResponse.seatbid.forEach(respItem => { + _addBidResponse(_getBidFromResponse(respItem), bidsMap, priceType, bidResponses); + }); + } + if (errorMessage) utils.logError(errorMessage); + return bidResponses; + }, + + getUserSyncs: function(syncOptions) { + if (syncOptions.pixelEnabled) { + return [{ + type: 'image', + url: ADAPTER_SYNC_URL + }]; + } + } +} + +function _getBidFromResponse(respItem) { + if (!respItem) { + utils.logError(LOG_ERROR_MESS.emptySeatbid); + } else if (!respItem.bid) { + utils.logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem)); + } else if (!respItem.bid[0]) { + utils.logError(LOG_ERROR_MESS.noBid); + } + return respItem && respItem.bid && respItem.bid[0]; +} + +function _addBidResponse(serverBid, bidsMap, priceType, bidResponses) { + if (!serverBid) return; + let errorMessage; + if (!serverBid.auid) errorMessage = LOG_ERROR_MESS.noAuid + JSON.stringify(serverBid); + if (!serverBid.adm) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid); + else { + const awaitingBids = bidsMap[serverBid.auid]; + if (awaitingBids) { + awaitingBids.forEach(bid => { + const bidResponse = { + requestId: bid.bidId, // bid.bidderRequestId, + bidderCode: spec.code, + cpm: serverBid.price, + width: serverBid.w, + height: serverBid.h, + creativeId: serverBid.auid, // bid.bidId, + currency: 'USD', + netRevenue: priceType !== 'gross', + ttl: TIME_TO_LIVE, + ad: serverBid.adm, + dealId: serverBid.dealid + }; + bidResponses.push(bidResponse); + }); + } else { + errorMessage = LOG_ERROR_MESS.noPlacementCode + serverBid.auid; + } + } + if (errorMessage) { + utils.logError(errorMessage); + } +} + +registerBidder(spec); diff --git a/modules/danmarketplaceBidAdapter.md b/modules/danmarketplaceBidAdapter.md new file mode 100755 index 00000000000..263385949bd --- /dev/null +++ b/modules/danmarketplaceBidAdapter.md @@ -0,0 +1,40 @@ +# Overview + +Module Name: Dentsu Aegis Network Marketplace Bidder Adapter +Module Type: Bidder Adapter +Maintainer: niels@baarsma.net + +# Description + +Module that connects to DAN Marketplace demand source to fetch bids. + +# Test Parameters +``` + var adUnits = [ + { + code: 'test-div', + sizes: [[300, 250]], + bids: [ + { + bidder: "danmarketplace", + params: { + uid: '4', + priceType: 'gross' // by default is 'net' + } + } + ] + },{ + code: 'test-div', + sizes: [[728, 90]], + bids: [ + { + bidder: "danmarketplace", + params: { + uid: 5, + priceType: 'gross' + } + } + ] + } + ]; +``` \ No newline at end of file diff --git a/test/spec/modules/danmarketplaceBidAdapter_spec.js b/test/spec/modules/danmarketplaceBidAdapter_spec.js new file mode 100644 index 00000000000..e3dfd9f37e8 --- /dev/null +++ b/test/spec/modules/danmarketplaceBidAdapter_spec.js @@ -0,0 +1,289 @@ +import { expect } from 'chai'; +import { spec } from 'modules/danmarketplaceBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory'; + +describe('DAN_Marketplace Adapter', function () { + const adapter = newBidder(spec); + + describe('inherited functions', () => { + it('exists and is a function', () => { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + }); + + describe('isBidRequestValid', () => { + let bid = { + 'bidder': 'danmarketplace', + 'params': { + 'uid': '4' + }, + 'adUnitCode': 'adunit-code', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }; + + it('should return true when required params found', () => { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + + it('should return false when required params are not passed', () => { + let bid = Object.assign({}, bid); + delete bid.params; + bid.params = { + 'uid': 0 + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', () => { + let bidRequests = [ + { + 'bidder': 'danmarketplace', + 'params': { + 'uid': '5' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }, + { + 'bidder': 'danmarketplace', + 'params': { + 'uid': '5' + }, + 'adUnitCode': 'adunit-code-2', + 'sizes': [[728, 90]], + 'bidId': '3150ccb55da321', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }, + { + 'bidder': 'danmarketplace', + 'params': { + 'uid': '6' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '42dbe3a7168a6a', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + } + ]; + + it('should attach valid params to the tag', () => { + const request = spec.buildRequests([bidRequests[0]]); + const payload = request.data; + expect(payload).to.be.an('object'); + expect(payload).to.have.property('u').that.is.a('string'); + expect(payload).to.have.property('pt', 'net'); + expect(payload).to.have.property('auids', '5'); + }); + + it('auids must not be duplicated', () => { + const request = spec.buildRequests(bidRequests); + const payload = request.data; + expect(payload).to.be.an('object'); + expect(payload).to.have.property('u').that.is.a('string'); + expect(payload).to.have.property('pt', 'net'); + expect(payload).to.have.property('auids', '5,6'); + }); + + it('pt parameter must be "gross" if params.priceType === "gross"', () => { + bidRequests[1].params.priceType = 'gross'; + const request = spec.buildRequests(bidRequests); + const payload = request.data; + expect(payload).to.be.an('object'); + expect(payload).to.have.property('u').that.is.a('string'); + expect(payload).to.have.property('pt', 'gross'); + expect(payload).to.have.property('auids', '5,6'); + delete bidRequests[1].params.priceType; + }); + + it('pt parameter must be "net" or "gross"', () => { + bidRequests[1].params.priceType = 'some'; + const request = spec.buildRequests(bidRequests); + const payload = request.data; + expect(payload).to.be.an('object'); + expect(payload).to.have.property('u').that.is.a('string'); + expect(payload).to.have.property('pt', 'net'); + expect(payload).to.have.property('auids', '5,6'); + delete bidRequests[1].params.priceType; + }); + }); + + describe('interpretResponse', () => { + const responses = [ + {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 4, 'h': 250, 'w': 300}], 'seat': '1'}, + {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 5, 'h': 90, 'w': 728}], 'seat': '1'}, + {'bid': [{'price': 0, 'auid': 6, 'h': 250, 'w': 300}], 'seat': '1'}, + {'bid': [{'price': 0, 'adm': '
test content 4
', 'h': 250, 'w': 300}], 'seat': '1'}, + undefined, + {'bid': [], 'seat': '1'}, + {'seat': '1'}, + ]; + + it('should get correct bid response', () => { + const bidRequests = [ + { + 'bidder': 'danmarketplace', + 'params': { + 'uid': '4' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '659423fff799cb', + 'bidderRequestId': '5f2009617a7c0a', + 'auctionId': '1cbd2feafe5e8b', + } + ]; + const request = spec.buildRequests(bidRequests); + const expectedResponse = [ + { + 'requestId': '659423fff799cb', + 'cpm': 1.15, + 'creativeId': 4, + 'dealId': undefined, + 'width': 300, + 'height': 250, + 'ad': '
test content 1
', + 'bidderCode': 'danmarketplace', + 'currency': 'USD', + 'netRevenue': true, + 'ttl': 360, + } + ]; + + const result = spec.interpretResponse({'body': {'seatbid': [responses[0]]}}, request); + expect(result).to.deep.equal(expectedResponse); + }); + + it('should get correct multi bid response', () => { + const bidRequests = [ + { + 'bidder': 'danmarketplace', + 'params': { + 'uid': '4' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '300bfeb0d71a5b', + 'bidderRequestId': '2c2bb1972df9a', + 'auctionId': '1fa09aee5c8c99', + }, + { + 'bidder': 'danmarketplace', + 'params': { + 'uid': '5' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '4dff80cc4ee346', + 'bidderRequestId': '2c2bb1972df9a', + 'auctionId': '1fa09aee5c8c99', + }, + { + 'bidder': 'danmarketplace', + 'params': { + 'uid': '4' + }, + 'adUnitCode': 'adunit-code-2', + 'sizes': [[728, 90]], + 'bidId': '5703af74d0472a', + 'bidderRequestId': '2c2bb1972df9a', + 'auctionId': '1fa09aee5c8c99', + } + ]; + const request = spec.buildRequests(bidRequests); + const expectedResponse = [ + { + 'requestId': '300bfeb0d71a5b', + 'cpm': 1.15, + 'creativeId': 4, + 'dealId': undefined, + 'width': 300, + 'height': 250, + 'ad': '
test content 1
', + 'bidderCode': 'danmarketplace', + 'currency': 'USD', + 'netRevenue': true, + 'ttl': 360, + }, + { + 'requestId': '5703af74d0472a', + 'cpm': 1.15, + 'creativeId': 4, + 'dealId': undefined, + 'width': 300, + 'height': 250, + 'ad': '
test content 1
', + 'bidderCode': 'danmarketplace', + 'currency': 'USD', + 'netRevenue': true, + 'ttl': 360, + }, + { + 'requestId': '4dff80cc4ee346', + 'cpm': 0.5, + 'creativeId': 5, + 'dealId': undefined, + 'width': 728, + 'height': 90, + 'ad': '
test content 2
', + 'bidderCode': 'danmarketplace', + 'currency': 'USD', + 'netRevenue': true, + 'ttl': 360, + } + ]; + + const result = spec.interpretResponse({'body': {'seatbid': [responses[0], responses[1]]}}, request); + expect(result).to.deep.equal(expectedResponse); + }); + + it('handles wrong and nobid responses', () => { + const bidRequests = [ + { + 'bidder': 'danmarketplace', + 'params': { + 'uid': '6' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '300bfeb0d7190gf', + 'bidderRequestId': '2c2bb1972d23af', + 'auctionId': '1fa09aee5c84d34', + }, + { + 'bidder': 'danmarketplace', + 'params': { + 'uid': '7' + }, + 'adUnitCode': 'adunit-code-1', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '300bfeb0d71321', + 'bidderRequestId': '2c2bb1972d23af', + 'auctionId': '1fa09aee5c84d34', + }, + { + 'bidder': 'danmarketplace', + 'params': { + 'uid': '8' + }, + 'adUnitCode': 'adunit-code-2', + 'sizes': [[728, 90]], + 'bidId': '300bfeb0d7183bb', + 'bidderRequestId': '2c2bb1972d23af', + 'auctionId': '1fa09aee5c84d34', + } + ]; + const request = spec.buildRequests(bidRequests); + const result = spec.interpretResponse({'body': {'seatbid': responses.slice(2)}}, request); + expect(result.length).to.equal(0); + }); + }); +}); From 2333886dc48d66f763783480787390e8afd3859d Mon Sep 17 00:00:00 2001 From: Niels Baarsma Date: Thu, 1 Feb 2018 19:50:04 +0300 Subject: [PATCH 2/5] Update DAN_Marketplace adapter --- modules/danmarketplaceBidAdapter.js | 1 - test/spec/modules/danmarketplaceBidAdapter_spec.js | 4 ---- 2 files changed, 5 deletions(-) diff --git a/modules/danmarketplaceBidAdapter.js b/modules/danmarketplaceBidAdapter.js index 2419292f79e..24b3682042e 100644 --- a/modules/danmarketplaceBidAdapter.js +++ b/modules/danmarketplaceBidAdapter.js @@ -119,7 +119,6 @@ function _addBidResponse(serverBid, bidsMap, priceType, bidResponses) { awaitingBids.forEach(bid => { const bidResponse = { requestId: bid.bidId, // bid.bidderRequestId, - bidderCode: spec.code, cpm: serverBid.price, width: serverBid.w, height: serverBid.h, diff --git a/test/spec/modules/danmarketplaceBidAdapter_spec.js b/test/spec/modules/danmarketplaceBidAdapter_spec.js index e3dfd9f37e8..ee7f844ae98 100644 --- a/test/spec/modules/danmarketplaceBidAdapter_spec.js +++ b/test/spec/modules/danmarketplaceBidAdapter_spec.js @@ -151,7 +151,6 @@ describe('DAN_Marketplace Adapter', function () { 'width': 300, 'height': 250, 'ad': '
test content 1
', - 'bidderCode': 'danmarketplace', 'currency': 'USD', 'netRevenue': true, 'ttl': 360, @@ -208,7 +207,6 @@ describe('DAN_Marketplace Adapter', function () { 'width': 300, 'height': 250, 'ad': '
test content 1
', - 'bidderCode': 'danmarketplace', 'currency': 'USD', 'netRevenue': true, 'ttl': 360, @@ -221,7 +219,6 @@ describe('DAN_Marketplace Adapter', function () { 'width': 300, 'height': 250, 'ad': '
test content 1
', - 'bidderCode': 'danmarketplace', 'currency': 'USD', 'netRevenue': true, 'ttl': 360, @@ -234,7 +231,6 @@ describe('DAN_Marketplace Adapter', function () { 'width': 728, 'height': 90, 'ad': '
test content 2
', - 'bidderCode': 'danmarketplace', 'currency': 'USD', 'netRevenue': true, 'ttl': 360, From 1579d46cd87a9e10c24a15cdcded98b1528dcfac Mon Sep 17 00:00:00 2001 From: Niels Baarsma Date: Thu, 22 Feb 2018 17:43:08 +0300 Subject: [PATCH 3/5] Rename danmarketplaceBidAdapter into danmarketBidAdapter --- ...ceBidAdapter.js => danmarketBidAdapter.js} | 4 ++-- ...ceBidAdapter.md => danmarketBidAdapter.md} | 4 ++-- ...er_spec.js => danmarketBidAdapter_spec.js} | 24 +++++++++---------- 3 files changed, 16 insertions(+), 16 deletions(-) rename modules/{danmarketplaceBidAdapter.js => danmarketBidAdapter.js} (97%) rename modules/{danmarketplaceBidAdapter.md => danmarketBidAdapter.md} (90%) rename test/spec/modules/{danmarketplaceBidAdapter_spec.js => danmarketBidAdapter_spec.js} (94%) diff --git a/modules/danmarketplaceBidAdapter.js b/modules/danmarketBidAdapter.js similarity index 97% rename from modules/danmarketplaceBidAdapter.js rename to modules/danmarketBidAdapter.js index 24b3682042e..619bd893ea2 100644 --- a/modules/danmarketplaceBidAdapter.js +++ b/modules/danmarketBidAdapter.js @@ -1,6 +1,6 @@ import * as utils from 'src/utils'; import {registerBidder} from 'src/adapters/bidderFactory'; -const BIDDER_CODE = 'danmarketplace'; +const BIDDER_CODE = 'danmarket'; const ENDPOINT_URL = '//ads.danmarketplace.com/hb'; const TIME_TO_LIVE = 360; const ADAPTER_SYNC_URL = '//ads.danmarketplace.com/push_sync'; @@ -24,7 +24,7 @@ const LOG_ERROR_MESS = { export const spec = { code: BIDDER_CODE, - aliases: ['DANMarketplace', 'DAN_Marketplace'], + aliases: ['DANMarketplace', 'DAN_Marketplace', 'danmarketplace'], isBidRequestValid: function(bid) { return !!bid.params.uid; diff --git a/modules/danmarketplaceBidAdapter.md b/modules/danmarketBidAdapter.md similarity index 90% rename from modules/danmarketplaceBidAdapter.md rename to modules/danmarketBidAdapter.md index 263385949bd..8ddc83d2cf6 100755 --- a/modules/danmarketplaceBidAdapter.md +++ b/modules/danmarketBidAdapter.md @@ -16,7 +16,7 @@ Module that connects to DAN Marketplace demand source to fetch bids. sizes: [[300, 250]], bids: [ { - bidder: "danmarketplace", + bidder: "danmarket", params: { uid: '4', priceType: 'gross' // by default is 'net' @@ -28,7 +28,7 @@ Module that connects to DAN Marketplace demand source to fetch bids. sizes: [[728, 90]], bids: [ { - bidder: "danmarketplace", + bidder: "danmarket", params: { uid: 5, priceType: 'gross' diff --git a/test/spec/modules/danmarketplaceBidAdapter_spec.js b/test/spec/modules/danmarketBidAdapter_spec.js similarity index 94% rename from test/spec/modules/danmarketplaceBidAdapter_spec.js rename to test/spec/modules/danmarketBidAdapter_spec.js index ee7f844ae98..d1b86d1bf53 100644 --- a/test/spec/modules/danmarketplaceBidAdapter_spec.js +++ b/test/spec/modules/danmarketBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { spec } from 'modules/danmarketplaceBidAdapter'; +import { spec } from 'modules/danmarketBidAdapter'; import { newBidder } from 'src/adapters/bidderFactory'; describe('DAN_Marketplace Adapter', function () { @@ -13,7 +13,7 @@ describe('DAN_Marketplace Adapter', function () { describe('isBidRequestValid', () => { let bid = { - 'bidder': 'danmarketplace', + 'bidder': 'danmarket', 'params': { 'uid': '4' }, @@ -41,7 +41,7 @@ describe('DAN_Marketplace Adapter', function () { describe('buildRequests', () => { let bidRequests = [ { - 'bidder': 'danmarketplace', + 'bidder': 'danmarket', 'params': { 'uid': '5' }, @@ -52,7 +52,7 @@ describe('DAN_Marketplace Adapter', function () { 'auctionId': '1d1a030790a475', }, { - 'bidder': 'danmarketplace', + 'bidder': 'danmarket', 'params': { 'uid': '5' }, @@ -63,7 +63,7 @@ describe('DAN_Marketplace Adapter', function () { 'auctionId': '1d1a030790a475', }, { - 'bidder': 'danmarketplace', + 'bidder': 'danmarket', 'params': { 'uid': '6' }, @@ -130,7 +130,7 @@ describe('DAN_Marketplace Adapter', function () { it('should get correct bid response', () => { const bidRequests = [ { - 'bidder': 'danmarketplace', + 'bidder': 'danmarket', 'params': { 'uid': '4' }, @@ -164,7 +164,7 @@ describe('DAN_Marketplace Adapter', function () { it('should get correct multi bid response', () => { const bidRequests = [ { - 'bidder': 'danmarketplace', + 'bidder': 'danmarket', 'params': { 'uid': '4' }, @@ -175,7 +175,7 @@ describe('DAN_Marketplace Adapter', function () { 'auctionId': '1fa09aee5c8c99', }, { - 'bidder': 'danmarketplace', + 'bidder': 'danmarket', 'params': { 'uid': '5' }, @@ -186,7 +186,7 @@ describe('DAN_Marketplace Adapter', function () { 'auctionId': '1fa09aee5c8c99', }, { - 'bidder': 'danmarketplace', + 'bidder': 'danmarket', 'params': { 'uid': '4' }, @@ -244,7 +244,7 @@ describe('DAN_Marketplace Adapter', function () { it('handles wrong and nobid responses', () => { const bidRequests = [ { - 'bidder': 'danmarketplace', + 'bidder': 'danmarket', 'params': { 'uid': '6' }, @@ -255,7 +255,7 @@ describe('DAN_Marketplace Adapter', function () { 'auctionId': '1fa09aee5c84d34', }, { - 'bidder': 'danmarketplace', + 'bidder': 'danmarket', 'params': { 'uid': '7' }, @@ -266,7 +266,7 @@ describe('DAN_Marketplace Adapter', function () { 'auctionId': '1fa09aee5c84d34', }, { - 'bidder': 'danmarketplace', + 'bidder': 'danmarket', 'params': { 'uid': '8' }, From 4b208d6bb47698ac6887d0d42317dce03212df58 Mon Sep 17 00:00:00 2001 From: Niels Baarsma Date: Wed, 23 May 2018 22:24:49 +0300 Subject: [PATCH 4/5] Add support of GDPR in DAN Marketplace Bid Adapter --- modules/danmarketBidAdapter.js | 11 ++++++++- test/spec/modules/danmarketBidAdapter_spec.js | 24 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/modules/danmarketBidAdapter.js b/modules/danmarketBidAdapter.js index 619bd893ea2..fe7c5b02f9c 100644 --- a/modules/danmarketBidAdapter.js +++ b/modules/danmarketBidAdapter.js @@ -30,7 +30,7 @@ export const spec = { return !!bid.params.uid; }, - buildRequests: function(validBidRequests) { + buildRequests: function(validBidRequests, bidderRequest) { const auids = []; const bidsMap = {}; const bids = validBidRequests || []; @@ -57,6 +57,15 @@ export const spec = { r: reqId, }; + if (bidderRequest && bidderRequest.gdprConsent) { + if (bidderRequest.gdprConsent.consentString) { + payload.gdpr_consent = bidderRequest.gdprConsent.consentString; + } + payload.gdpr_applies = + (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') + ? Number(bidderRequest.gdprConsent.gdprApplies) : 1; + } + return { method: 'GET', url: ENDPOINT_URL, diff --git a/test/spec/modules/danmarketBidAdapter_spec.js b/test/spec/modules/danmarketBidAdapter_spec.js index d1b86d1bf53..243e2fdfb66 100644 --- a/test/spec/modules/danmarketBidAdapter_spec.js +++ b/test/spec/modules/danmarketBidAdapter_spec.js @@ -114,6 +114,30 @@ describe('DAN_Marketplace Adapter', function () { expect(payload).to.have.property('auids', '5,6'); delete bidRequests[1].params.priceType; }); + + it('if gdprConsent is present payload must have gdpr params', () => { + const request = spec.buildRequests(bidRequests, {gdprConsent: {consentString: 'AAA', gdprApplies: true}}); + const payload = request.data; + expect(payload).to.be.an('object'); + expect(payload).to.have.property('gdpr_consent', 'AAA'); + expect(payload).to.have.property('gdpr_applies', 1); + }); + + it('if gdprApplies is false gdpr_applies must be 0', () => { + const request = spec.buildRequests(bidRequests, {gdprConsent: {consentString: 'AAA', gdprApplies: false}}); + const payload = request.data; + expect(payload).to.be.an('object'); + expect(payload).to.have.property('gdpr_consent', 'AAA'); + expect(payload).to.have.property('gdpr_applies', 0); + }); + + it('if gdprApplies is undefined gdpr_applies must be 1', () => { + const request = spec.buildRequests(bidRequests, {gdprConsent: {consentString: 'AAA'}}); + const payload = request.data; + expect(payload).to.be.an('object'); + expect(payload).to.have.property('gdpr_consent', 'AAA'); + expect(payload).to.have.property('gdpr_applies', 1); + }); }); describe('interpretResponse', () => { From db6f4afead19e5af66c69ae8cf668b5c0586768a Mon Sep 17 00:00:00 2001 From: Niels Baarsma Date: Thu, 24 May 2018 14:56:07 +0300 Subject: [PATCH 5/5] Add GDPR params in sync pixel --- modules/danmarketBidAdapter.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/modules/danmarketBidAdapter.js b/modules/danmarketBidAdapter.js index fe7c5b02f9c..d851af424ce 100644 --- a/modules/danmarketBidAdapter.js +++ b/modules/danmarketBidAdapter.js @@ -96,11 +96,20 @@ export const spec = { return bidResponses; }, - getUserSyncs: function(syncOptions) { + getUserSyncs: function(syncOptions, serverResponses, gdprConsent) { if (syncOptions.pixelEnabled) { + var query = []; + if (gdprConsent) { + if (gdprConsent.consentString) { + query.push('gdpr_consent=' + encodeURIComponent(gdprConsent.consentString)); + } + query.push('gdpr_applies=' + encodeURIComponent( + (typeof gdprConsent.gdprApplies === 'boolean') + ? Number(gdprConsent.gdprApplies) : 1)); + } return [{ type: 'image', - url: ADAPTER_SYNC_URL + url: ADAPTER_SYNC_URL + (query.length ? '?' + query.join('&') : '') }]; } }