Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PubMatic bid adapter to support CCPA/USP #4533

Merged
merged 19 commits into from
Dec 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
33762d1
added support for pubcommon, digitrust, id5id
pm-harshad-mane Sep 12, 2019
0722354
added support for IdentityLink
pm-harshad-mane Sep 13, 2019
f2c32c0
changed the source for id5
pm-harshad-mane Sep 13, 2019
37163d1
Merge remote-tracking branch 'upstream/master'
pm-harshad-mane Sep 13, 2019
eaed987
added unit test cases
pm-harshad-mane Sep 13, 2019
602ee7e
changed source param for identityLink
pm-harshad-mane Sep 16, 2019
b6fcd36
Merge remote-tracking branch 'upstream/master'
pm-harshad-mane Sep 23, 2019
58381f3
Merge remote-tracking branch 'upstream/master'
pm-harshad-mane Sep 26, 2019
c9fb11b
Merge remote-tracking branch 'upstream/master'
pm-harshad-mane Oct 10, 2019
8ece7fd
Merge remote-tracking branch 'upstream/master'
pm-harshad-mane Oct 16, 2019
28d12a0
Merge remote-tracking branch 'upstream/master'
pm-harshad-mane Oct 16, 2019
05a55e1
Merge remote-tracking branch 'upstream/master'
pm-harshad-mane Oct 31, 2019
e8b10d5
Merge remote-tracking branch 'upstream/master'
pm-harshad-mane Nov 5, 2019
870085f
Merge remote-tracking branch 'upstream/master'
pm-harshad-mane Nov 12, 2019
844ce4e
Merge remote-tracking branch 'upstream/master'
pm-harshad-mane Nov 12, 2019
704eca3
Merge remote-tracking branch 'upstream/master'
pm-harshad-mane Nov 13, 2019
2565cb9
Merge remote-tracking branch 'upstream/master'
pm-harshad-mane Dec 4, 2019
1d75bd4
Merge remote-tracking branch 'upstream/master'
pm-harshad-mane Dec 4, 2019
3608ab0
added CCPA/USP support in PubMatic adapter
pm-harshad-mane Dec 4, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion modules/pubmaticBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,11 @@ export const spec = {
};
}

// CCPA
if (bidderRequest && bidderRequest.uspConsent) {
utils.deepSetValue(payload, 'regs.ext.us_privacy', bidderRequest.uspConsent);
}

// coppa compliance
if (config.getConfig('coppa') === true) {
utils.deepSetValue(payload, 'regs.coppa', 1);
Expand Down Expand Up @@ -1012,7 +1017,7 @@ export const spec = {
/**
* Register User Sync.
*/
getUserSyncs: (syncOptions, responses, gdprConsent) => {
getUserSyncs: (syncOptions, responses, gdprConsent, uspConsent) => {
let syncurl = USYNCURL + publisherId;

// Attaching GDPR Consent Params in UserSync url
Expand All @@ -1021,6 +1026,11 @@ export const spec = {
syncurl += '&gdpr_consent=' + encodeURIComponent(gdprConsent.consentString || '');
}

// CCPA
if (uspConsent) {
syncurl += '&us_privacy=' + encodeURIComponent(uspConsent);
}

// coppa compliance
if (config.getConfig('coppa') === true) {
syncurl += '&coppa=1';
Expand Down
109 changes: 109 additions & 0 deletions test/spec/modules/pubmaticBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,43 @@ describe('PubMatic adapter', function () {
expect(data.imp[0].ext.pmZoneId).to.equal(bidRequests[0].params.pmzoneid.split(',').slice(0, 50).map(id => id.trim()).join()); // pmzoneid
});

it('Request params check with USP/CCPA Consent', function () {
let bidRequest = {
uspConsent: '1NYN'
};
let request = spec.buildRequests(bidRequests, bidRequest);
let data = JSON.parse(request.data);
expect(data.regs.ext.us_privacy).to.equal('1NYN');// USP/CCPAs
expect(data.at).to.equal(1); // auction type
expect(data.cur[0]).to.equal('USD'); // currency
expect(data.site.domain).to.be.a('string'); // domain should be set
expect(data.site.page).to.equal(bidRequests[0].params.kadpageurl); // forced pageURL
expect(data.site.publisher.id).to.equal(bidRequests[0].params.publisherId); // publisher Id
expect(data.user.yob).to.equal(parseInt(bidRequests[0].params.yob)); // YOB
expect(data.user.gender).to.equal(bidRequests[0].params.gender); // Gender
expect(data.device.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude
expect(data.device.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude
expect(data.user.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude
expect(data.user.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude
expect(data.ext.wrapper.wv).to.equal($$REPO_AND_VERSION$$); // Wrapper Version
expect(data.ext.wrapper.transactionId).to.equal(bidRequests[0].transactionId); // Prebid TransactionId
expect(data.ext.wrapper.wiid).to.equal(bidRequests[0].params.wiid); // OpenWrap: Wrapper Impression ID
expect(data.ext.wrapper.profile).to.equal(parseInt(bidRequests[0].params.profId)); // OpenWrap: Wrapper Profile ID
expect(data.ext.wrapper.version).to.equal(parseInt(bidRequests[0].params.verId)); // OpenWrap: Wrapper Profile Version ID

expect(data.imp[0].id).to.equal(bidRequests[0].bidId); // Prebid bid id is passed as id
expect(data.imp[0].bidfloor).to.equal(parseFloat(bidRequests[0].params.kadfloor)); // kadfloor
expect(data.imp[0].tagid).to.equal('/15671365/DMDemo'); // tagid
expect(data.imp[0].banner.w).to.equal(300); // width
expect(data.imp[0].banner.h).to.equal(250); // height
expect(data.imp[0].ext.pmZoneId).to.equal(bidRequests[0].params.pmzoneid.split(',').slice(0, 50).map(id => id.trim()).join()); // pmzoneid

// second request without USP/CCPA
let request2 = spec.buildRequests(bidRequests, {});
let data2 = JSON.parse(request2.data);
expect(data2.regs).to.equal(undefined);// USP/CCPAs
});

it('Request should have digitrust params', function() {
window.DigiTrust = {
getUser: function () {
Expand Down Expand Up @@ -2444,5 +2481,77 @@ describe('PubMatic adapter', function () {
expect(response[0].mediaType).to.equal('native');
});
});

describe('getUserSyncs', function() {
const syncurl = 'https://ads.pubmatic.com/AdServer/js/showad.js#PIX&kdntuid=1&p=5670';
let sandbox;
beforeEach(function () {
sandbox = sinon.sandbox.create();
});
afterEach(function() {
sandbox.restore();
})

it('execute only if iframeEnabled', function() {
expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined, undefined)).to.deep.equal([{
type: 'iframe', url: syncurl
}]);
expect(spec.getUserSyncs({ iframeEnabled: false }, {}, undefined, undefined)).to.equal(undefined);
});

it('CCPA/USP', function() {
expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined, '1NYN')).to.deep.equal([{
type: 'iframe', url: `${syncurl}&us_privacy=1NYN`
}]);
});

it('GDPR', function() {
expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, undefined)).to.deep.equal([{
type: 'iframe', url: `${syncurl}&gdpr=1&gdpr_consent=foo`
}]);
expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: false, consentString: 'foo'}, undefined)).to.deep.equal([{
type: 'iframe', url: `${syncurl}&gdpr=0&gdpr_consent=foo`
}]);
expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: true, consentString: undefined}, undefined)).to.deep.equal([{
type: 'iframe', url: `${syncurl}&gdpr=1&gdpr_consent=`
}]);
});

it('COPPA: true', function() {
sandbox.stub(config, 'getConfig').callsFake(key => {
const config = {
'coppa': true
};
return config[key];
});
expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined, undefined)).to.deep.equal([{
type: 'iframe', url: `${syncurl}&coppa=1`
}]);
});

it('COPPA: false', function() {
sandbox.stub(config, 'getConfig').callsFake(key => {
const config = {
'coppa': false
};
return config[key];
});
expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined, undefined)).to.deep.equal([{
type: 'iframe', url: `${syncurl}`
}]);
});

it('GDPR + COPPA:true + CCPA/USP', function() {
sandbox.stub(config, 'getConfig').callsFake(key => {
const config = {
'coppa': true
};
return config[key];
});
expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, '1NYN')).to.deep.equal([{
type: 'iframe', url: `${syncurl}&gdpr=1&gdpr_consent=foo&us_privacy=1NYN&coppa=1`
}]);
});
});
});
});