Skip to content

Commit

Permalink
Rads Bid Adapter: add GDPR support & user sync support (#6455)
Browse files Browse the repository at this point in the history
  • Loading branch information
onlsol authored Mar 31, 2021
1 parent 7935df6 commit f316b20
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 2 deletions.
54 changes: 52 additions & 2 deletions modules/radsBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const spec = {
bid_id: bidId,
};
}
prepareExtraParams(params, payload);
prepareExtraParams(params, payload, bidderRequest);

return {
method: 'GET',
Expand Down Expand Up @@ -97,9 +97,46 @@ export const spec = {
bidResponses.push(bidResponse);
}
return bidResponses;
},
getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) {
if (!serverResponses || serverResponses.length === 0) {
return [];
}

const syncs = []

let gdprParams = '';
if (gdprConsent) {
if ('gdprApplies' in gdprConsent && typeof gdprConsent.gdprApplies === 'boolean') {
gdprParams = `gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`;
} else {
gdprParams = `gdpr_consent=${gdprConsent.consentString}`;
}
}

if (syncOptions.iframeEnabled) {
serverResponses[0].body.userSync.iframeUrl.forEach((url) => syncs.push({
type: 'iframe',
url: appendToUrl(url, gdprParams)
}));
}
if (syncOptions.pixelEnabled && serverResponses.length > 0) {
serverResponses[0].body.userSync.imageUrl.forEach((url) => syncs.push({
type: 'image',
url: appendToUrl(url, gdprParams)
}));
}
return syncs;
}
}

function appendToUrl(url, what) {
if (!what) {
return url;
}
return url + (url.indexOf('?') !== -1 ? '&' : '?') + what;
}

function objectToQueryString(obj, prefix) {
let str = [];
let p;
Expand All @@ -125,10 +162,23 @@ function isVideoRequest(bid) {
return bid.mediaType === 'video' || !!utils.deepAccess(bid, 'mediaTypes.video');
}

function prepareExtraParams(params, payload) {
function prepareExtraParams(params, payload, bidderRequest) {
if (params.pfilter !== undefined) {
payload.pfilter = params.pfilter;
}

if (bidderRequest && bidderRequest.gdprConsent) {
if (payload.pfilter !== undefined) {
payload.pfilter.gdpr_consent = bidderRequest.gdprConsent.consentString;
payload.pfilter.gdpr = bidderRequest.gdprConsent.gdprApplies;
} else {
payload.pfilter = {
'gdpr_consent': bidderRequest.gdprConsent.consentString,
'gdpr': bidderRequest.gdprConsent.gdprApplies
};
}
}

if (params.bcat !== undefined) {
payload.bcat = params.bcat;
}
Expand Down
83 changes: 83 additions & 0 deletions test/spec/modules/radsBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,25 @@ describe('radsAdapter', function () {
'auctionId': '1d1a030790a475'
}];

// Without gdprConsent
let bidderRequest = {
refererInfo: {
referer: 'some_referrer.net'
}
}
// With gdprConsent
var bidderRequestGdprConsent = {
refererInfo: {
referer: 'some_referrer.net'
},
gdprConsent: {
consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==',
vendorData: {someData: 'value'},
gdprApplies: true
}
};

// without gdprConsent
const request = spec.buildRequests(bidRequests, bidderRequest);
it('sends bid request to our endpoint via GET', function () {
expect(request[0].method).to.equal('GET');
Expand All @@ -105,6 +118,20 @@ describe('radsAdapter', function () {
let data = request[1].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid');
expect(data).to.equal('rt=vast2&_f=prebid_js&_ps=6682&srw=640&srh=480&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgeo%5D%5Bregion%5D=DE-BE&bcat=IAB2%2CIAB4&dvt=desktop');
});

// with gdprConsent
const request2 = spec.buildRequests(bidRequests, bidderRequestGdprConsent);
it('sends bid request to our endpoint via GET', function () {
expect(request2[0].method).to.equal('GET');
let data = request2[0].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid');
expect(data).to.equal('rt=bid-response&_f=prebid_js&_ps=6682&srw=300&srh=250&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&bcat=IAB2%2CIAB4&dvt=desktop&i=1.1.1.1');
});

it('sends bid video request to our rads endpoint via GET', function () {
expect(request2[1].method).to.equal('GET');
let data = request2[1].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid');
expect(data).to.equal('rt=vast2&_f=prebid_js&_ps=6682&srw=640&srh=480&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgeo%5D%5Bregion%5D=DE-BE&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&bcat=IAB2%2CIAB4&dvt=desktop');
});
});

describe('interpretResponse', function () {
Expand Down Expand Up @@ -203,4 +230,60 @@ describe('radsAdapter', function () {
expect(result.length).to.equal(0);
});
});

describe(`getUserSyncs test usage`, function () {
let serverResponses;

beforeEach(function () {
serverResponses = [{
body: {
requestId: '23beaa6af6cdde',
cpm: 0.5,
width: 0,
height: 0,
creativeId: 100500,
dealId: '',
currency: 'EUR',
netRevenue: true,
ttl: 300,
type: 'sspHTML',
ad: '<!-- test creative -->',
userSync: {
iframeUrl: ['anyIframeUrl?a=1'],
imageUrl: ['anyImageUrl', 'anyImageUrl2']
}
}
}];
});

it(`return value should be an array`, function () {
expect(spec.getUserSyncs({ iframeEnabled: true })).to.be.an('array');
});
it(`array should have only one object and it should have a property type = 'iframe'`, function () {
expect(spec.getUserSyncs({ iframeEnabled: true }, serverResponses).length).to.be.equal(1);
let [userSync] = spec.getUserSyncs({ iframeEnabled: true }, serverResponses);
expect(userSync).to.have.property('type');
expect(userSync.type).to.be.equal('iframe');
});
it(`we have valid sync url for iframe`, function () {
let [userSync] = spec.getUserSyncs({ iframeEnabled: true }, serverResponses, {consentString: 'anyString'});
expect(userSync.url).to.be.equal('anyIframeUrl?a=1&gdpr_consent=anyString')
expect(userSync.type).to.be.equal('iframe');
});
it(`we have valid sync url for image`, function () {
let [userSync] = spec.getUserSyncs({ pixelEnabled: true }, serverResponses, {gdprApplies: true, consentString: 'anyString'});
expect(userSync.url).to.be.equal('anyImageUrl?gdpr=1&gdpr_consent=anyString')
expect(userSync.type).to.be.equal('image');
});
it(`we have valid sync url for image and iframe`, function () {
let userSync = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses, {gdprApplies: true, consentString: 'anyString'});
expect(userSync.length).to.be.equal(3);
expect(userSync[0].url).to.be.equal('anyIframeUrl?a=1&gdpr=1&gdpr_consent=anyString')
expect(userSync[0].type).to.be.equal('iframe');
expect(userSync[1].url).to.be.equal('anyImageUrl?gdpr=1&gdpr_consent=anyString')
expect(userSync[1].type).to.be.equal('image');
expect(userSync[2].url).to.be.equal('anyImageUrl2?gdpr=1&gdpr_consent=anyString')
expect(userSync[2].type).to.be.equal('image');
});
});
});

0 comments on commit f316b20

Please sign in to comment.