diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index eb2ad8ccb03..ce0da73f751 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -1194,6 +1194,15 @@ export const spec = { deepSetValue(payload, 'regs.ext.us_privacy', bidderRequest.uspConsent); } + // Attaching GPP Consent Params + if (bidderRequest?.gppConsent?.gppString) { + deepSetValue(payload, 'regs.gpp', bidderRequest.gppConsent.gppString); + deepSetValue(payload, 'regs.gpp_sid', bidderRequest.gppConsent.applicableSections); + } else if (bidderRequest?.ortb2?.regs?.gpp) { + deepSetValue(payload, 'regs.gpp', bidderRequest.ortb2.regs.gpp); + deepSetValue(payload, 'regs.gpp_sid', bidderRequest.ortb2.regs.gpp_sid); + } + // coppa compliance if (config.getConfig('coppa') === true) { deepSetValue(payload, 'regs.coppa', 1); @@ -1352,7 +1361,7 @@ export const spec = { /** * Register User Sync. */ - getUserSyncs: (syncOptions, responses, gdprConsent, uspConsent) => { + getUserSyncs: (syncOptions, responses, gdprConsent, uspConsent, gppConsent) => { let syncurl = '' + publisherId; // Attaching GDPR Consent Params in UserSync url @@ -1366,6 +1375,12 @@ export const spec = { syncurl += '&us_privacy=' + encodeURIComponent(uspConsent); } + // GPP Consent + if (gppConsent?.gppString && gppConsent?.applicableSections?.length) { + syncurl += '&gpp=' + encodeURIComponent(gppConsent.gppString); + syncurl += '&gpp_sid=' + encodeURIComponent(gppConsent?.applicableSections?.join(',')); + } + // coppa compliance if (config.getConfig('coppa') === true) { syncurl += '&coppa=1'; diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 5d8d762e793..53f5e12aa6d 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -3057,6 +3057,76 @@ describe('PubMatic adapter', function () { }); } + describe('GPP', function() { + it('Request params check with GPP Consent', function () { + let bidRequest = { + gppConsent: { + 'gppString': 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN', + 'fullGppData': { + 'sectionId': 3, + 'gppVersion': 1, + 'sectionList': [ + 5, + 7 + ], + 'applicableSections': [ + 5 + ], + 'gppString': 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN', + 'pingData': { + 'cmpStatus': 'loaded', + 'gppVersion': '1.0', + 'cmpDisplayStatus': 'visible', + 'supportedAPIs': [ + 'tcfca', + 'usnat', + 'usca', + 'usva', + 'usco', + 'usut', + 'usct' + ], + 'cmpId': 31 + }, + 'eventName': 'sectionChange' + }, + 'applicableSections': [ + 5 + ], + 'apiVersion': 1 + } + }; + let request = spec.buildRequests(bidRequests, bidRequest); + let data = JSON.parse(request.data); + expect(data.regs.gpp).to.equal('DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN'); + expect(data.regs.gpp_sid[0]).to.equal(5); + }); + + it('Request params check without GPP Consent', function () { + let bidRequest = {}; + let request = spec.buildRequests(bidRequests, bidRequest); + let data = JSON.parse(request.data); + expect(data.regs).to.equal(undefined); + }); + + it('Request params check with GPP Consent read from ortb2', function () { + let bidRequest = { + ortb2: { + regs: { + 'gpp': 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN', + 'gpp_sid': [ + 5 + ] + } + } + }; + let request = spec.buildRequests(bidRequests, bidRequest); + let data = JSON.parse(request.data); + expect(data.regs.gpp).to.equal('DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN'); + expect(data.regs.gpp_sid[0]).to.equal(5); + }); + }); + describe('Fledge', function() { it('should not send imp.ext.ae when FLEDGE is disabled, ', function () { let bidRequest = Object.assign([], bidRequests); @@ -3991,6 +4061,55 @@ describe('PubMatic adapter', function () { type: 'image', url: `${syncurl_image}&gdpr=1&gdpr_consent=foo&us_privacy=1NYN&coppa=1` }]); }); + + describe('GPP', function() { + it('should return userSync url without Gpp consent if gppConsent is undefined', () => { + const result = spec.getUserSyncs({iframeEnabled: true}, undefined, undefined, undefined, undefined); + expect(result).to.deep.equal([{ + type: 'iframe', url: `${syncurl_iframe}` + }]); + }); + + it('should return userSync url without Gpp consent if gppConsent.gppString is undefined', () => { + const gppConsent = { applicableSections: ['5'] }; + const result = spec.getUserSyncs({iframeEnabled: true}, undefined, undefined, undefined, gppConsent); + expect(result).to.deep.equal([{ + type: 'iframe', url: `${syncurl_iframe}` + }]); + }); + + it('should return userSync url without Gpp consent if gppConsent.applicableSections is undefined', () => { + const gppConsent = { gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN' }; + const result = spec.getUserSyncs({iframeEnabled: true}, undefined, undefined, undefined, gppConsent); + expect(result).to.deep.equal([{ + type: 'iframe', url: `${syncurl_iframe}` + }]); + }); + + it('should return userSync url without Gpp consent if gppConsent.applicableSections is an empty array', () => { + const gppConsent = { gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN', applicableSections: [] }; + const result = spec.getUserSyncs({iframeEnabled: true}, undefined, undefined, undefined, gppConsent); + expect(result).to.deep.equal([{ + type: 'iframe', url: `${syncurl_iframe}` + }]); + }); + + it('should concatenate gppString and applicableSections values in the returned userSync iframe url', () => { + const gppConsent = { gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN', applicableSections: [5] }; + const result = spec.getUserSyncs({iframeEnabled: true}, undefined, undefined, undefined, gppConsent); + expect(result).to.deep.equal([{ + type: 'iframe', url: `${syncurl_iframe}&gpp=${encodeURIComponent(gppConsent.gppString)}&gpp_sid=${encodeURIComponent(gppConsent.applicableSections)}` + }]); + }); + + it('should concatenate gppString and applicableSections values in the returned userSync image url', () => { + const gppConsent = { gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN', applicableSections: [5] }; + const result = spec.getUserSyncs({iframeEnabled: false}, undefined, undefined, undefined, gppConsent); + expect(result).to.deep.equal([{ + type: 'image', url: `${syncurl_image}&gpp=${encodeURIComponent(gppConsent.gppString)}&gpp_sid=${encodeURIComponent(gppConsent.applicableSections)}` + }]); + }); + }); }); if (FEATURES.VIDEO) {