From 70317f9a34493d07b7a4e889b1539cdd84230ed7 Mon Sep 17 00:00:00 2001 From: Mikael Lundin Date: Thu, 3 Jun 2021 16:45:29 +0200 Subject: [PATCH] adnuntias Bid Adapter: Added GDPR support and segment passing (#6796) * Master merge issues * Adnuntius Bid Adapter: Added tests for gdpr and segments * Moved segments to read from ortb2 instead of a custom value. * Changed bidder to read segments from ortb2. * fixing lgtm alert --- modules/adnuntiusBidAdapter.js | 39 +++++++++- test/spec/modules/adnuntiusBidAdapter_spec.js | 75 +++++++++++++++++++ 2 files changed, 110 insertions(+), 4 deletions(-) diff --git a/modules/adnuntiusBidAdapter.js b/modules/adnuntiusBidAdapter.js index 8752e37a96f..5e10219188d 100644 --- a/modules/adnuntiusBidAdapter.js +++ b/modules/adnuntiusBidAdapter.js @@ -1,30 +1,61 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'adnuntius'; const ENDPOINT_URL = 'https://delivery.adnuntius.com/i?tzo='; +const GVLID = 855; + +const checkSegment = function (segment) { + if (utils.isStr(segment)) return segment; + if (segment.id) return segment.id +} + +const getSegmentsFromOrtb = function (ortb2) { + const userData = utils.deepAccess(ortb2, 'user.data'); + let segments = []; + if (userData) { + userData.forEach(userdat => { + if (userdat.segment) { + segments.push(...userdat.segment.filter(checkSegment).map(checkSegment)); + } + }); + } + return segments +} export const spec = { code: BIDDER_CODE, - + gvlid: GVLID, + supportedMediaTypes: [BANNER], isBidRequestValid: function (bid) { return !!(bid.bidId || (bid.params.member && bid.params.invCode)); }, - buildRequests: function (validBidRequests) { + buildRequests: function (validBidRequests, bidderRequest) { const networks = {}; const bidRequests = {}; const requests = []; + const ortb2 = config.getConfig('ortb2'); + const segments = getSegmentsFromOrtb(ortb2); const tzo = new Date().getTimezoneOffset(); + const gdprApplies = utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies'); + const consentString = utils.deepAccess(bidderRequest, 'gdprConsent.consentString'); + const reqConsent = (gdprApplies !== undefined) ? '&consentString=' + consentString : ''; + const reqSegments = (segments.length > 0) ? '&segments=' + segments.join(',') : ''; for (var i = 0; i < validBidRequests.length; i++) { const bid = validBidRequests[i] const network = bid.params.network || 'network'; + const targeting = bid.params.targeting || {}; + bidRequests[network] = bidRequests[network] || []; bidRequests[network].push(bid); networks[network] = networks[network] || {}; networks[network].adUnits = networks[network].adUnits || []; - networks[network].adUnits.push({ ...bid.params.targeting, auId: bid.params.auId, targetId: bid.bidId }); + networks[network].adUnits.push({ ...targeting, auId: bid.params.auId, targetId: bid.bidId }); } const networkKeys = Object.keys(networks) @@ -32,7 +63,7 @@ export const spec = { const network = networkKeys[j]; requests.push({ method: 'POST', - url: ENDPOINT_URL + tzo + '&format=json', + url: ENDPOINT_URL + tzo + '&format=json' + reqSegments + reqConsent, data: JSON.stringify(networks[network]), bid: bidRequests[network] }); diff --git a/test/spec/modules/adnuntiusBidAdapter_spec.js b/test/spec/modules/adnuntiusBidAdapter_spec.js index 62073fc6aaa..9c9bf0e9914 100644 --- a/test/spec/modules/adnuntiusBidAdapter_spec.js +++ b/test/spec/modules/adnuntiusBidAdapter_spec.js @@ -2,10 +2,17 @@ import { expect } from 'chai'; // may prefer 'assert' in place of 'expect' import { spec } from 'modules/adnuntiusBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; +import { config } from 'src/config.js'; describe('adnuntiusBidAdapter', function () { + afterEach(function () { + config.resetConfig(); + }); const tzo = new Date().getTimezoneOffset(); const ENDPOINT_URL = `https://delivery.adnuntius.com/i?tzo=${tzo}&format=json`; + // const ENDPOINT_URL_SEGMENTS_ = `https://delivery.adnuntius.com/i?tzo=${tzo}&format=json`; + const ENDPOINT_URL_SEGMENTS = `https://delivery.adnuntius.com/i?tzo=${tzo}&format=json&segments=segment1,segment2,segment3`; + const ENDPOINT_URL_CONSENT = `https://delivery.adnuntius.com/i?tzo=${tzo}&format=json&consentString=consentString`; const adapter = newBidder(spec); const bidRequests = [ @@ -116,6 +123,74 @@ describe('adnuntiusBidAdapter', function () { expect(request[0]).to.have.property('data'); expect(request[0].data).to.equal('{\"adUnits\":[{\"auId\":\"8b6bc\",\"targetId\":\"123\"}]}'); }); + + it('should pass segments if available in config', function () { + config.setBidderConfig({ + bidders: ['adnuntius', 'other'], + config: { + ortb2: { + user: { + data: [{ + name: 'adnuntius', + segment: [{ id: 'segment1' }, { id: 'segment2' }] + }, + { + name: 'other', + segment: ['segment3'] + }], + } + } + } + }); + + const request = config.runWithBidder('adnuntius', () => spec.buildRequests(bidRequests)); + expect(request.length).to.equal(1); + expect(request[0]).to.have.property('url') + expect(request[0].url).to.equal(ENDPOINT_URL_SEGMENTS); + }); + + it('should skip segments in config if not either id or array of strings', function () { + config.setBidderConfig({ + bidders: ['adnuntius', 'other'], + config: { + ortb2: { + user: { + data: [{ + name: 'adnuntius', + segment: [{ id: 'segment1' }, { id: 'segment2' }, { id: 'segment3' }] + }, + { + name: 'other', + segment: [{ + notright: 'segment4' + }] + }], + } + } + } + }); + + const request = config.runWithBidder('adnuntius', () => spec.buildRequests(bidRequests)); + expect(request.length).to.equal(1); + expect(request[0]).to.have.property('url') + expect(request[0].url).to.equal(ENDPOINT_URL_SEGMENTS); + }); + }); + + describe('user privacy', function () { + it('should send GDPR Consent data if gdprApplies', function () { + let request = spec.buildRequests(bidRequests, { gdprConsent: { gdprApplies: true, consentString: 'consentString' } }); + expect(request.length).to.equal(1); + expect(request[0]).to.have.property('url') + expect(request[0].url).to.equal(ENDPOINT_URL_CONSENT); + }); + + it('should not send GDPR Consent data if gdprApplies equals undefined', function () { + let request = spec.buildRequests(bidRequests, { gdprConsent: { gdprApplies: undefined, consentString: 'consentString' } }); + expect(request.length).to.equal(1); + expect(request[0]).to.have.property('url') + expect(request[0].url).to.equal(ENDPOINT_URL); + }); }); describe('interpretResponse', function () {