Skip to content

Commit

Permalink
Vuukle Bid Adapter: support gdpr/usp/coppa/schain/gvlid (#9023)
Browse files Browse the repository at this point in the history
* add gdpr/usp/coppa/schain/gvlid

* restore getConfig

* fix linting
  • Loading branch information
ChrisHuie authored Oct 6, 2022
1 parent 17b9b32 commit 5c21bdc
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 3 deletions.
37 changes: 34 additions & 3 deletions modules/vuukleBidAdapter.js
Original file line number Diff line number Diff line change
@@ -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');
Expand All @@ -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,
Expand Down Expand Up @@ -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;
}
87 changes: 87 additions & 0 deletions test/spec/modules/vuukleBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -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 = {
Expand Down Expand Up @@ -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: {
Expand All @@ -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();
})
});

0 comments on commit 5c21bdc

Please sign in to comment.