diff --git a/modules/vuukleBidAdapter.js b/modules/vuukleBidAdapter.js index ddf96b3e940..f3ab2562ef4 100644 --- a/modules/vuukleBidAdapter.js +++ b/modules/vuukleBidAdapter.js @@ -1,18 +1,24 @@ -import { parseSizesInput } from '../src/utils.js'; +import { parseSizesInput, deepAccess } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'vuukle'; const URL = 'https://pb.vuukle.com/adapter'; const TIME_TO_LIVE = 360; +const VENDOR_ID = 1004; export const spec = { code: BIDDER_CODE, + gvlid: VENDOR_ID, + supportedMediaTypes: [ BANNER ], isBidRequestValid: function(bid) { return true }, - buildRequests: function(bidRequests) { + buildRequests: function(bidRequests, bidderRequest) { + bidderRequest = bidderRequest || {}; const requests = bidRequests.map(function (bid) { const parseSized = parseSizesInput(bid.sizes); const arrSize = parseSized[0].split('x'); @@ -25,10 +31,27 @@ export const spec = { rnd: Math.random(), bidId: bid.bidId, source: 'pbjs', + schain: JSON.stringify(bid.schain), + requestId: bid.bidderRequestId, + tmax: bidderRequest.timeout, + gdpr: (bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) ? 1 : 0, + consentGiven: vuukleGetConsentGiven(bidderRequest.gdprConsent), version: '$prebid.version$', - v: 1, + v: 2, }; + if (bidderRequest.uspConsent) { + params.uspConsent = bidderRequest.uspConsent; + } + + if (config.getConfig('coppa') === true) { + params.coppa = 1; + } + + if (bidderRequest.gdprConsent && bidderRequest.gdprConsent.consentString) { + params.consent = bidderRequest.gdprConsent.consentString; + } + return { method: 'GET', url: URL, @@ -65,3 +88,11 @@ export const spec = { }, } registerBidder(spec); + +function vuukleGetConsentGiven(gdprConsent) { + let consentGiven = 0; + if (typeof gdprConsent !== 'undefined') { + consentGiven = deepAccess(gdprConsent, `vendorData.vendor.consents.${VENDOR_ID}`) ? 1 : 0; + } + return consentGiven; +} diff --git a/test/spec/modules/vuukleBidAdapter_spec.js b/test/spec/modules/vuukleBidAdapter_spec.js index 17353a40b85..32ba74867bb 100644 --- a/test/spec/modules/vuukleBidAdapter_spec.js +++ b/test/spec/modules/vuukleBidAdapter_spec.js @@ -1,5 +1,6 @@ import { expect } from 'chai'; import { spec } from 'modules/vuukleBidAdapter.js'; +import { config } from '../../../src/config.js'; describe('vuukleBidAdapterTests', function() { let bidRequestData = { @@ -34,6 +35,13 @@ describe('vuukleBidAdapterTests', function() { expect(req_data.bidId).to.equal('testbid'); }); + it('validate_generated_params_tmax', function() { + request = spec.buildRequests(bidRequestData.bids, {timeout: 1234}); + let req_data = request[0].data; + + expect(req_data.tmax).to.equal(1234); + }); + it('validate_response_params', function() { let serverResponse = { body: { @@ -58,4 +66,83 @@ describe('vuukleBidAdapterTests', function() { expect(bid.creativeId).to.equal('12345'); expect(bid.meta.advertiserDomains).to.deep.equal(['example.com']); }); + + describe('consent handling', function() { + const bidderRequest = { + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + gdprApplies: 1, + vendorData: { + vendor: { + consents: { + 1004: 1 + } + } + } + } + } + + it('must handle consent 1/1', function() { + request = spec.buildRequests(bidRequestData.bids, bidderRequest); + let req_data = request[0].data; + + expect(req_data.gdpr).to.equal(1); + expect(req_data.consentGiven).to.equal(1); + expect(req_data.consent).to.equal('COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw'); + }) + + it('must handle consent 0/1', function() { + bidderRequest.gdprConsent.gdprApplies = 0; + request = spec.buildRequests(bidRequestData.bids, bidderRequest); + let req_data = request[0].data; + + expect(req_data.gdpr).to.equal(0); + expect(req_data.consentGiven).to.equal(1); + }) + + it('must handle consent 0/0', function() { + bidderRequest.gdprConsent.gdprApplies = 0; + bidderRequest.gdprConsent.vendorData = undefined; + request = spec.buildRequests(bidRequestData.bids, bidderRequest); + let req_data = request[0].data; + + expect(req_data.gdpr).to.equal(0); + expect(req_data.consentGiven).to.equal(0); + }) + + it('must handle consent undef', function() { + request = spec.buildRequests(bidRequestData.bids, {}); + let req_data = request[0].data; + + expect(req_data.gdpr).to.equal(0); + expect(req_data.consentGiven).to.equal(0); + }) + }) + + it('must handle usp consent', function() { + request = spec.buildRequests(bidRequestData.bids, {uspConsent: '1YNN'}); + let req_data = request[0].data; + + expect(req_data.uspConsent).to.equal('1YNN'); + }) + + it('must handle undefined usp consent', function() { + request = spec.buildRequests(bidRequestData.bids, {}); + let req_data = request[0].data; + + expect(req_data.uspConsent).to.equal(undefined); + }) + + it('must handle coppa flag', function() { + sinon.stub(config, 'getConfig') + .withArgs('coppa') + .returns(true); + + request = spec.buildRequests(bidRequestData.bids); + let req_data = request[0].data; + + expect(req_data.coppa).to.equal(1); + + config.getConfig.restore(); + }) });