diff --git a/modules/33acrossBidAdapter.js b/modules/33acrossBidAdapter.js index 26fc0a11fd5..bdc80ade375 100644 --- a/modules/33acrossBidAdapter.js +++ b/modules/33acrossBidAdapter.js @@ -251,6 +251,7 @@ function _createServerRequest({ bidRequests, gdprConsent = {}, uspConsent, pageU const ttxRequest = {}; const firstBidRequest = bidRequests[0]; const { siteId, test } = firstBidRequest.params; + const coppaValue = config.getConfig('coppa'); /* * Infer data for the request payload @@ -296,6 +297,10 @@ function _createServerRequest({ bidRequests, gdprConsent = {}, uspConsent, pageU }); } + if (coppaValue !== undefined) { + ttxRequest.regs.coppa = Number(!!coppaValue); + } + ttxRequest.ext = { ttx: { prebidStartedAt: Date.now(), diff --git a/modules/33acrossIdSystem.js b/modules/33acrossIdSystem.js index be81b26b110..802c2651d29 100644 --- a/modules/33acrossIdSystem.js +++ b/modules/33acrossIdSystem.js @@ -8,7 +8,7 @@ import { logMessage, logError } from '../src/utils.js'; import { ajaxBuilder } from '../src/ajax.js'; import { submodule } from '../src/hook.js'; -import { uspDataHandler } from '../src/adapterManager.js'; +import { uspDataHandler, coppaDataHandler } from '../src/adapterManager.js'; const MODULE_NAME = '33acrossId'; const API_URL = 'https://lexicon.33across.com/v1/envelope'; @@ -37,11 +37,13 @@ function getEnvelope(response) { function calculateQueryStringParams(pid, gdprConsentData) { const uspString = uspDataHandler.getConsentData(); const gdprApplies = Boolean(gdprConsentData?.gdprApplies); + const coppaValue = coppaDataHandler.getCoppa(); const params = { pid, gdpr: Number(gdprApplies), src: CALLER_NAME, - ver: '$prebid.version$' + ver: '$prebid.version$', + coppa: Number(coppaValue) }; if (uspString) { diff --git a/test/spec/modules/33acrossBidAdapter_spec.js b/test/spec/modules/33acrossBidAdapter_spec.js index aa2621f1fa0..d0b590336b9 100644 --- a/test/spec/modules/33acrossBidAdapter_spec.js +++ b/test/spec/modules/33acrossBidAdapter_spec.js @@ -200,6 +200,14 @@ describe('33acrossBidAdapter:', function () { return this; }; + this.withCoppa = coppaValue => { + Object.assign(ttxRequest.regs, { + coppa: coppaValue + }); + + return this; + }; + this.withSite = site => { Object.assign(ttxRequest, { site }); return this; @@ -1059,6 +1067,7 @@ describe('33acrossBidAdapter:', function () { .withBanner() .withProduct() .withGdprConsent('foobarMyPreference', 1) + .withCoppa(1) .build(); const serverRequest = new ServerRequestBuilder() .withData(ttxRequest) @@ -1094,6 +1103,7 @@ describe('33acrossBidAdapter:', function () { const ttxRequest = new TtxRequestBuilder() .withBanner() .withProduct() + .withCoppa(1) .build(); const serverRequest = new ServerRequestBuilder() .withData(ttxRequest) @@ -1138,6 +1148,7 @@ describe('33acrossBidAdapter:', function () { .withBanner() .withProduct() .withUspConsent('foo') + .withCoppa(1) .build(); const serverRequest = new ServerRequestBuilder() .withData(ttxRequest) @@ -1173,6 +1184,7 @@ describe('33acrossBidAdapter:', function () { const ttxRequest = new TtxRequestBuilder() .withBanner() .withProduct() + .withCoppa(1) .build(); const serverRequest = new ServerRequestBuilder() .withData(ttxRequest) @@ -1184,6 +1196,42 @@ describe('33acrossBidAdapter:', function () { }); }); + context('when coppa is enabled', function() { + it('returns corresponding server requests with coppa: 1', function() { + sandbox.stub(config, 'getConfig').withArgs('coppa').returns(true); + + const ttxRequest = new TtxRequestBuilder() + .withBanner() + .withProduct() + .withCoppa(1) + .build(); + const serverRequest = new ServerRequestBuilder() + .withData(ttxRequest) + .build(); + const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + + validateBuiltServerRequest(builtServerRequest, serverRequest); + }); + }); + + context('when coppa is not enabled', function() { + it('returns corresponding server requests with coppa: 0', function() { + sandbox.stub(config, 'getConfig').withArgs('coppa').returns(false); + + const ttxRequest = new TtxRequestBuilder() + .withBanner() + .withProduct() + .withCoppa(0) + .build(); + const serverRequest = new ServerRequestBuilder() + .withData(ttxRequest) + .build(); + const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + + validateBuiltServerRequest(builtServerRequest, serverRequest); + }); + }); + context('when refererInfo values are available', function() { context('when refererInfo.page is defined', function() { it('returns corresponding server requests with site.page set', function() { @@ -1780,12 +1828,14 @@ describe('33acrossBidAdapter:', function () { .withProduct('siab') .withBanner() .withVideo() + .withCoppa(1) .build(); const req2 = new TtxRequestBuilder('sample33xGUID123456780') .withProduct('siab') .withBanner() .withVideo() + .withCoppa(1) .build(); req2.imp[0].id = 'b3'; @@ -1794,6 +1844,7 @@ describe('33acrossBidAdapter:', function () { .withProduct('inview') .withBanner() .withVideo() + .withCoppa(1) .build(); req3.imp[0].id = 'b4'; diff --git a/test/spec/modules/33acrossIdSystem_spec.js b/test/spec/modules/33acrossIdSystem_spec.js index 5070d2b8845..e41d6d90d81 100644 --- a/test/spec/modules/33acrossIdSystem_spec.js +++ b/test/spec/modules/33acrossIdSystem_spec.js @@ -2,7 +2,7 @@ import { thirthyThreeAcrossIdSubmodule } from 'modules/33acrossIdSystem.js'; import * as utils from 'src/utils.js'; import { server } from 'test/mocks/xhr.js'; -import { uspDataHandler } from 'src/adapterManager.js'; +import { uspDataHandler, coppaDataHandler } from 'src/adapterManager.js'; describe('33acrossIdSystem', () => { describe('name', () => { @@ -157,6 +157,48 @@ describe('33acrossIdSystem', () => { }); }); + context('when coppa is enabled', () => { + it('should call endpoint with an enabled coppa signal', () => { + const completeCallback = () => {}; + const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + params: { + pid: '12345' + } + }); + + sinon.stub(coppaDataHandler, 'getCoppa').returns(true); + + callback(completeCallback); + + const [request] = server.requests; + + expect(request.url).to.contain('coppa=1'); + + coppaDataHandler.getCoppa.restore(); + }); + }); + + context('when coppa is not enabled', () => { + it('should call endpoint with coppa signal not enabled', () => { + const completeCallback = () => {}; + const { callback } = thirthyThreeAcrossIdSubmodule.getId({ + params: { + pid: '12345' + } + }); + + sinon.stub(coppaDataHandler, 'getCoppa').returns(false); + + callback(completeCallback); + + const [request] = server.requests; + + expect(request.url).to.contain('coppa=0'); + + coppaDataHandler.getCoppa.restore(); + }); + }); + context('when the partner ID is not given', () => { it('should log an error', () => { const logErrorSpy = sinon.spy(utils, 'logError');