From f0973c405bf05a08d49dc54ac86e4f93ba473578 Mon Sep 17 00:00:00 2001 From: Ankit Prakash Date: Wed, 18 Dec 2019 08:17:48 -0700 Subject: [PATCH] Sovrn ccpa support (#4592) * sovrn ccpa support * use array map/join instead of object.entries --- modules/sovrnBidAdapter.js | 32 ++++++------ test/spec/modules/sovrnBidAdapter_spec.js | 64 ++++++++++++++++++++++- 2 files changed, 80 insertions(+), 16 deletions(-) diff --git a/modules/sovrnBidAdapter.js b/modules/sovrnBidAdapter.js index daaa3da3aaca..5cd76981e8d1 100644 --- a/modules/sovrnBidAdapter.js +++ b/modules/sovrnBidAdapter.js @@ -81,15 +81,12 @@ export const spec = { }; } - if (bidderRequest && bidderRequest.gdprConsent) { - sovrnBidReq.regs = { - ext: { - gdpr: +bidderRequest.gdprConsent.gdprApplies - }}; - sovrnBidReq.user = { - ext: { - consent: bidderRequest.gdprConsent.consentString - }}; + if (bidderRequest.gdprConsent) { + utils.deepSetValue(sovrnBidReq, 'regs.ext.gdpr', +bidderRequest.gdprConsent.gdprApplies); + utils.deepSetValue(sovrnBidReq, 'user.ext.consent', bidderRequest.gdprConsent.consentString) + } + if (bidderRequest.uspConsent) { + utils.deepSetValue(sovrnBidReq, 'regs.ext.us_privacy', bidderRequest.uspConsent); } if (digitrust) { @@ -151,21 +148,26 @@ export const spec = { } }, - getUserSyncs: function(syncOptions, serverResponses, gdprConsent) { + getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { try { - let tracks = [] + const tracks = [] if (serverResponses && serverResponses.length !== 0) { if (syncOptions.iframeEnabled) { - let iidArr = serverResponses.filter(resp => utils.deepAccess(resp, 'body.ext.iid')) + const iidArr = serverResponses.filter(resp => utils.deepAccess(resp, 'body.ext.iid')) .map(resp => resp.body.ext.iid); - let consentString = ''; + const params = []; if (gdprConsent && gdprConsent.gdprApplies && typeof gdprConsent.consentString === 'string') { - consentString = gdprConsent.consentString + params.push(['gdpr_consent', gdprConsent.consentString]); } + if (uspConsent) { + params.push(['us_privacy', uspConsent]); + } + if (iidArr[0]) { + params.push(['informer', iidArr[0]]); tracks.push({ type: 'iframe', - url: 'https://ap.lijit.com/beacon?informer=' + iidArr[0] + '&gdpr_consent=' + consentString, + url: 'https://ap.lijit.com/beacon?' + params.map(p => p.join('=')).join('&') }); } } diff --git a/test/spec/modules/sovrnBidAdapter_spec.js b/test/spec/modules/sovrnBidAdapter_spec.js index 44adb4d1cbd4..0778b6487c21 100644 --- a/test/spec/modules/sovrnBidAdapter_spec.js +++ b/test/spec/modules/sovrnBidAdapter_spec.js @@ -152,6 +152,25 @@ describe('sovrnBidAdapter', function() { expect(data.user.ext.consent).to.equal(consentString); }); + it('should send us_privacy if bidderRequest has a value for uspConsent', function () { + let uspString = '1NYN'; + let bidderRequest = { + 'bidderCode': 'sovrn', + 'auctionId': '1d1a030790a475', + 'bidderRequestId': '22edbae2733bf6', + 'timeout': 3000, + uspConsent: uspString, + refererInfo: { + referer: 'http://example.com/page.html', + } + }; + bidderRequest.bids = bidRequests; + + const data = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data); + + expect(data.regs.ext['us_privacy']).to.equal(uspString); + }); + it('converts tagid to string', function () { const ivBidRequests = [{ 'bidder': 'sovrn', @@ -399,13 +418,56 @@ describe('sovrnBidAdapter', function() { const expectedReturnStatement = [ { 'type': 'iframe', - 'url': 'https://ap.lijit.com/beacon?informer=13487408&gdpr_consent=', + 'url': 'https://ap.lijit.com/beacon?informer=13487408', } ]; const returnStatement = spec.getUserSyncs(syncOptions, serverResponse); expect(returnStatement[0]).to.deep.equal(expectedReturnStatement[0]); }); + it('should include gdpr consent string if present', function() { + const gdprConsent = { + gdprApplies: 1, + consentString: 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==' + } + const expectedReturnStatement = [ + { + 'type': 'iframe', + 'url': `https://ap.lijit.com/beacon?gdpr_consent=${gdprConsent.consentString}&informer=13487408`, + } + ]; + const returnStatement = spec.getUserSyncs(syncOptions, serverResponse, gdprConsent, ''); + expect(returnStatement[0]).to.deep.equal(expectedReturnStatement[0]); + }); + + it('should include us privacy string if present', function() { + const uspString = '1NYN'; + const expectedReturnStatement = [ + { + 'type': 'iframe', + 'url': `https://ap.lijit.com/beacon?us_privacy=${uspString}&informer=13487408`, + } + ]; + const returnStatement = spec.getUserSyncs(syncOptions, serverResponse, null, uspString); + expect(returnStatement[0]).to.deep.equal(expectedReturnStatement[0]); + }); + + it('should include all privacy strings if present', function() { + const gdprConsent = { + gdprApplies: 1, + consentString: 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==' + } + const uspString = '1NYN'; + const expectedReturnStatement = [ + { + 'type': 'iframe', + 'url': `https://ap.lijit.com/beacon?gdpr_consent=${gdprConsent.consentString}&us_privacy=${uspString}&informer=13487408`, + } + ]; + const returnStatement = spec.getUserSyncs(syncOptions, serverResponse, gdprConsent, uspString); + expect(returnStatement[0]).to.deep.equal(expectedReturnStatement[0]); + }); + it('should not return if iid missing on server response', function() { const returnStatement = spec.getUserSyncs(syncOptions, []); expect(returnStatement).to.be.empty;