diff --git a/modules/33acrossBidAdapter.js b/modules/33acrossBidAdapter.js index 801a5d564a3..f53bf8b9d17 100644 --- a/modules/33acrossBidAdapter.js +++ b/modules/33acrossBidAdapter.js @@ -64,7 +64,7 @@ function _getAdSlotHTMLElement(adUnitCode) { // Infer the necessary data from valid bid for a minimal ttxRequest and create HTTP request // NOTE: At this point, TTX only accepts request for a single impression -function _createServerRequest(bidRequest, gdprConsent) { +function _createServerRequest(bidRequest, gdprConsent = {}) { const ttxRequest = {}; const params = bidRequest.params; const element = _getAdSlotHTMLElement(bidRequest.adUnitCode); @@ -143,14 +143,22 @@ function _createServerRequest(bidRequest, gdprConsent) { } // Sync object will always be of type iframe for TTX -function _createSync(siteId) { +function _createSync({siteId, gdprConsent = {}}) { const ttxSettings = config.getConfig('ttxSettings'); const syncUrl = (ttxSettings && ttxSettings.syncUrl) || SYNC_ENDPOINT; - return { + const {consentString, gdprApplies} = gdprConsent; + + const sync = { type: 'iframe', - url: `${syncUrl}&id=${siteId}` + url: `${syncUrl}&id=${siteId}&gdpr_consent=${encodeURIComponent(consentString)}` + }; + + if (typeof gdprApplies === 'boolean') { + sync.url += `&gdpr=${Number(gdprApplies)}`; } + + return sync; } function _getSize(size) { @@ -282,8 +290,6 @@ function isBidRequestValid(bid) { // NOTE: With regards to gdrp consent data, // - the server independently infers gdpr applicability therefore, setting the default value to false -// - the server, at this point, also doesn't need the consent string to handle gdpr compliance. So passing -// value whether set or not, for the sake of future dev. function buildRequests(bidRequests, bidderRequest) { const gdprConsent = Object.assign({ consentString: undefined, @@ -307,14 +313,12 @@ function interpretResponse(serverResponse, bidRequest) { return bidResponses; } -// Register one sync per unique guid -// NOTE: If gdpr applies do not sync +// Register one sync per unique guid so long as iframe is enable +// Else no syncs +// For logic on how we handle gdpr data see _createSyncs and module's unit tests +// '33acrossBidAdapter#getUserSyncs' function getUserSyncs(syncOptions, responses, gdprConsent) { - if (gdprConsent && gdprConsent.gdprApplies === true) { - return [] - } else { - return (syncOptions.iframeEnabled) ? adapterState.uniqueSiteIds.map(_createSync) : ([]); - } + return (syncOptions.iframeEnabled) ? adapterState.uniqueSiteIds.map((siteId) => _createSync({gdprConsent, siteId})) : ([]); } export const spec = { diff --git a/modules/33acrossBidAdapter.md b/modules/33acrossBidAdapter.md index 58e3b2b273a..c313f3b6e0b 100644 --- a/modules/33acrossBidAdapter.md +++ b/modules/33acrossBidAdapter.md @@ -24,7 +24,7 @@ var adUnits = [ bids: [{ bidder: '33across', params: { - siteId: 'examplePub1234', + siteId: 'cxBE0qjUir6iopaKkGJozW', productId: 'siab' } }] diff --git a/test/spec/modules/33acrossBidAdapter_spec.js b/test/spec/modules/33acrossBidAdapter_spec.js index 7e1a8619c63..08ea0a863ee 100644 --- a/test/spec/modules/33acrossBidAdapter_spec.js +++ b/test/spec/modules/33acrossBidAdapter_spec.js @@ -618,73 +618,140 @@ describe('33acrossBidAdapter:', function () { ]; }); - context('when gdpr does not apply', function() { - let gdprConsent; + context('when iframe is not enabled', function() { + it('returns empty sync array', function() { + const syncOptions = {}; + + spec.buildRequests(bidRequests); + + expect(spec.getUserSyncs(syncOptions)).to.deep.equal([]); + }); + }); + context('when iframe is enabled', function() { + let syncOptions; beforeEach(function() { - gdprConsent = { - gdprApplies: false + syncOptions = { + iframeEnabled: true }; }); - context('when iframe is not enabled', function() { - it('returns empty sync array', function() { - const syncOptions = {}; + context('when there is no gdpr consent data', function() { + it('returns sync urls with undefined consent string as param', function() { + spec.buildRequests(bidRequests); + + const syncResults = spec.getUserSyncs(syncOptions, {}, undefined); + const expectedSyncs = [ + { + type: 'iframe', + url: `${syncs[0].url}&gdpr_consent=undefined` + }, + { + type: 'iframe', + url: `${syncs[1].url}&gdpr_consent=undefined` + } + ] + + expect(syncResults).to.deep.equal(expectedSyncs); + }) + }); + context('when gdpr applies but there is no consent string', function() { + it('returns sync urls with undefined consent string as param and gdpr=1', function() { spec.buildRequests(bidRequests); - expect(spec.getUserSyncs(syncOptions, {}, gdprConsent)).to.deep.equal([]); + const syncResults = spec.getUserSyncs(syncOptions, {}, {gdprApplies: true}); + const expectedSyncs = [ + { + type: 'iframe', + url: `${syncs[0].url}&gdpr_consent=undefined&gdpr=1` + }, + { + type: 'iframe', + url: `${syncs[1].url}&gdpr_consent=undefined&gdpr=1` + } + ]; + + expect(syncResults).to.deep.equal(expectedSyncs); }); }); - context('when iframe is enabled', function() { - it('returns sync array equal to number of unique siteIDs', function() { - const syncOptions = { - iframeEnabled: true - }; - + context('when gdpr applies and there is consent string', function() { + it('returns sync urls with gdpr_consent=consent string as param and gdpr=1', function() { spec.buildRequests(bidRequests); - expect(spec.getUserSyncs(syncOptions, {}, gdprConsent)).to.deep.equal(syncs); + const syncResults = spec.getUserSyncs(syncOptions, {}, {gdprApplies: true, consentString: 'consent123A'}); + const expectedSyncs = [ + { + type: 'iframe', + url: `${syncs[0].url}&gdpr_consent=consent123A&gdpr=1` + }, + { + type: 'iframe', + url: `${syncs[1].url}&gdpr_consent=consent123A&gdpr=1` + } + ]; + + expect(syncResults).to.deep.equal(expectedSyncs); }); }); - }); - - context('when consent data is not defined', function() { - context('when iframe is not enabled', function() { - it('returns empty sync array', function() { - const syncOptions = {}; + context('when gdpr does not apply and there is no consent string', function() { + it('returns sync urls with undefined consent string as param and gdpr=0', function() { spec.buildRequests(bidRequests); - expect(spec.getUserSyncs(syncOptions)).to.deep.equal([]); + const syncResults = spec.getUserSyncs(syncOptions, {}, {gdprApplies: false}); + const expectedSyncs = [ + { + type: 'iframe', + url: `${syncs[0].url}&gdpr_consent=undefined&gdpr=0` + }, + { + type: 'iframe', + url: `${syncs[1].url}&gdpr_consent=undefined&gdpr=0` + } + ]; + expect(syncResults).to.deep.equal(expectedSyncs); }); }); - context('when iframe is enabled', function() { - it('returns sync array equal to number of unique siteIDs', function() { - const syncOptions = { - iframeEnabled: true - }; - + context('when gdpr is unknown and there is consent string', function() { + it('returns sync urls with only consent string as param', function() { spec.buildRequests(bidRequests); - expect(spec.getUserSyncs(syncOptions)).to.deep.equal(syncs); + const syncResults = spec.getUserSyncs(syncOptions, {}, {consentString: 'consent123A'}); + const expectedSyncs = [ + { + type: 'iframe', + url: `${syncs[0].url}&gdpr_consent=consent123A` + }, + { + type: 'iframe', + url: `${syncs[1].url}&gdpr_consent=consent123A` + } + ]; + expect(syncResults).to.deep.equal(expectedSyncs); }); }); - }); - context('when gdpr applies', function() { - it('returns empty sync array', function() { - const syncOptions = {}; - const gdprConsent = { - gdprApplies: true - }; - - spec.buildRequests(bidRequests); + context('when gdpr does not apply and there is consent string (yikes!)', function() { + it('returns sync urls with consent string as param and gdpr=0', function() { + spec.buildRequests(bidRequests); - expect(spec.getUserSyncs(syncOptions, {}, gdprConsent)).to.deep.equal([]); + const syncResults = spec.getUserSyncs(syncOptions, {}, {gdprApplies: false, consentString: 'consent123A'}); + const expectedSyncs = [ + { + type: 'iframe', + url: `${syncs[0].url}&gdpr_consent=consent123A&gdpr=0` + }, + { + type: 'iframe', + url: `${syncs[1].url}&gdpr_consent=consent123A&gdpr=0` + } + ]; + expect(syncResults).to.deep.equal(expectedSyncs); + }); }); - }) + }); }); });