Skip to content

Commit 1baa24a

Browse files
feat(core): add setDMAParamsForEEA public method (#993)
-feat(): adds new public method setDMAParamsForEEA
1 parent 15ea67e commit 1baa24a

File tree

11 files changed

+209
-8
lines changed

11 files changed

+209
-8
lines changed

.husky/prepare-commit-msg

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#!/bin/sh
22
. "$(dirname "$0")/_/husky.sh"
33

4-
exec < /dev/tty && node_modules/.bin/cz --hook || true
4+
if [ $2 == "template" ]; then
5+
exec < /dev/tty && npx cz --hook || true
6+
fi

.jshintrc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,7 @@
2626
"sub": true,
2727
"trailing": true,
2828
"undef": true,
29-
"unused": true
29+
"unused": true,
30+
"esversion": 6,
31+
"-W138": true
3032
}

example.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ <h4>QR Code</h4>
8282
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
8383
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
8484
<script type="text/javascript">
85-
(function(b,r,a,n,c,h,_,s,d,k){if(!b[n]||!b[n]._q){for(;s<_.length;)c(h,_[s++]);d=r.createElement(a);d.async=1;d.src="https://cdn.branch.io/branch-latest.min.js";k=r.getElementsByTagName(a)[0];k.parentNode.insertBefore(d,k);b[n]=h}})(window,document,"script","branch",function(b,r){b[r]=function(){b._q.push([r,arguments])}},{_q:[],_v:1},"addListener banner closeBanner closeJourney data deepview deepviewCta first init link logout removeListener setBranchViewData setIdentity track trackCommerceEvent logEvent disableTracking getBrowserFingerprintId crossPlatformIds lastAttributedTouchData setAPIResponseCallback qrCode setRequestMetaData".split(" "), 0);
85+
(function(b,r,a,n,c,h,_,s,d,k){if(!b[n]||!b[n]._q){for(;s<_.length;)c(h,_[s++]);d=r.createElement(a);d.async=1;d.src="https://cdn.branch.io/branch-latest.min.js";k=r.getElementsByTagName(a)[0];k.parentNode.insertBefore(d,k);b[n]=h}})(window,document,"script","branch",function(b,r){b[r]=function(){b._q.push([r,arguments])}},{_q:[],_v:1},"addListener banner closeBanner closeJourney data deepview deepviewCta first init link logout removeListener setBranchViewData setIdentity track trackCommerceEvent logEvent disableTracking getBrowserFingerprintId crossPlatformIds lastAttributedTouchData setAPIResponseCallback qrCode setRequestMetaData setDMAParamsForEEA".split(" "), 0);
8686

8787
branch.setAPIResponseCallback(function(url, method, requestBody, error, status, responseBody) {
8888
console.log('Request: ' + method + ' ' + url + ' body=' + JSON.stringify(requestBody));

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/1_utils.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ utils.timeSinceNavigationStart = function() {
2929
return (Date.now() - window.performance.timing.navigationStart).toString();
3030
};
3131
utils.currentRequestBrttTag = "";
32+
utils.allowDMAParamURLMap = {
33+
"/v1/open": "",
34+
"/v1/pageview": "",
35+
"/v2/event": "user_data"
36+
};
3237
utils.calculateBrtt = function(startTime) {
3338
if (!startTime || typeof startTime !== "number") {
3439
return null;
@@ -1324,3 +1329,31 @@ utils.removeTrailingDotZeros = function(versionNumber) {
13241329
return versionNumber;
13251330
};
13261331

1332+
utils.shouldAddDMAParams = function(endPointURL) {
1333+
return utils.allowDMAParamURLMap.hasOwnProperty(endPointURL);
1334+
};
1335+
1336+
utils.setDMAParams = function(data, dmaObj = {}, endPoint) {
1337+
const DMA_EEA = "dma_eea";
1338+
const DMA_Ad_Personalization = "dma_ad_personalization";
1339+
const DMA_Ad_User_Data = "dma_ad_user_data";
1340+
1341+
const dmaParams = {
1342+
[DMA_EEA]: dmaObj.eeaRegion || false,
1343+
[DMA_Ad_Personalization]: dmaObj.adPersonalizationConsent || false,
1344+
[DMA_Ad_User_Data]: dmaObj.adUserDataUsageConsent || false
1345+
};
1346+
1347+
for (const [key, value] of Object.entries(utils.allowDMAParamURLMap)) {
1348+
if (endPoint.includes(key)) {
1349+
if (value === '') {
1350+
Object.assign(data, dmaParams);
1351+
}
1352+
else {
1353+
data[value] = Object.assign({}, data[value], dmaParams);
1354+
}
1355+
break;
1356+
}
1357+
}
1358+
};
1359+

src/3_api.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@
135135
if (data.hasOwnProperty("branch_requestMetadata") && data["branch_requestMetadata"] && !(resource.endpoint === '/v1/pageview' || resource.endpoint === '/v1/dismiss')) {
136136
d['metadata'] = safejson.stringify(data["branch_requestMetadata"]);
137137
}
138+
if (data['branch_dma_data']) {
139+
utils.setDMAParams(d, data['branch_dma_data'], resource.endpoint);
140+
if (d['branch_dma_data']) {
141+
delete d['branch_dma_data'];
142+
}
143+
}
138144

139145
if (resource.method === 'POST') {
140146
try {

src/6_branch.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,10 @@ Branch.prototype._api = function(resource, obj, callback) {
215215
}
216216

217217
}
218+
if (utils.shouldAddDMAParams(resource.endpoint)) {
219+
var dmaData = this._storage.get('branch_dma_data', true);
220+
obj["branch_dma_data"] = dmaData ? safejson.parse(dmaData) : {};
221+
}
218222
return this._server.request(resource, obj, this._storage, function(err, data) {
219223
callback(err, data);
220224
});
@@ -1941,6 +1945,26 @@ Branch.prototype['setAPIResponseCallback'] = wrap(callback_params.NO_CALLBACK, f
19411945
return this._referringLink(withExtendedJourneysAssist);
19421946
};
19431947

1948+
/***
1949+
* @function Branch.setDMAParamsForEEA
1950+
* @param {Boolean} eeaRegion - If European regulations, including the DMA, apply to this user and conversion.
1951+
* @param {Boolean} adPersonalizationConsent - If End user has granted/denied ads personalization consent.
1952+
* @param {Boolean} adUserDataUsageConsent - If User has granted/denied consent for 3P transmission of user level data for ads.
1953+
* Sets the value of parameters required by Google Conversion APIs for DMA Compliance in EEA region.
1954+
*/
1955+
Branch.prototype['setDMAParamsForEEA'] = function(eeaRegion, adPersonalizationConsent, adUserDataUsageConsent) {
1956+
try {
1957+
var dmaObj = {};
1958+
dmaObj.eeaRegion = eeaRegion || false;
1959+
dmaObj.adPersonalizationConsent = adPersonalizationConsent || false;
1960+
dmaObj.adUserDataUsageConsent = adUserDataUsageConsent || false;
1961+
this._storage.set('branch_dma_data', safejson.stringify(dmaObj), true);
1962+
}
1963+
catch (e) {
1964+
console.error("setDMAParamsForEEA::An error occured while setting DMA parameters for EEA", e);
1965+
}
1966+
};
1967+
19441968
/***
19451969
* @function Branch.setRequestMetaData
19461970
* @param {String} key - Request metadata key

src/onpage.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@
5656
'lastAttributedTouchData',
5757
'setAPIResponseCallback',
5858
'qrCode',
59-
'setRequestMetaData'
59+
'setRequestMetaData',
60+
'setDMAParamsForEEA'
6061
],
6162
0
6263
);

test/1_utils.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
22
/*jshint -W079 */
3+
/*jshint esversion: 6 */
34
var sinon = require('sinon');
45
goog.require('utils');
56

@@ -1324,6 +1325,75 @@ describe('utils', function() {
13241325
});
13251326
});
13261327

1328+
describe('shouldAddDMAParams', function() {
1329+
it('should return true for valid endpoints', function() {
1330+
assert.equal(utils.shouldAddDMAParams('/v1/open'), true);
1331+
assert.equal(utils.shouldAddDMAParams('/v1/pageview'), true);
1332+
assert.equal(utils.shouldAddDMAParams('/v2/event'), true);
1333+
});
1334+
1335+
it('should return false for invalid endpoints', function() {
1336+
assert.equal(utils.shouldAddDMAParams('/v3/invalid'), false);
1337+
assert.equal(utils.shouldAddDMAParams('/v2/others'), false);
1338+
});
1339+
});
1340+
1341+
describe('setDMAParams', function() {
1342+
it('should add DMA parameters for valid endpoints: v1/open', () => {
1343+
const data = {};
1344+
const dmaObj = {
1345+
eeaRegion: true,
1346+
adPersonalizationConsent: true,
1347+
adUserDataUsageConsent: false
1348+
};
1349+
utils.setDMAParams(data, dmaObj, '/v1/open');
1350+
assert.deepEqual(data, { dma_eea: true, dma_ad_personalization: true, dma_ad_user_data: false });
1351+
});
1352+
it('should add DMA parameters for valid endpoints: v2/event', () => {
1353+
const dmaObj = {
1354+
eeaRegion: true,
1355+
adPersonalizationConsent: true,
1356+
adUserDataUsageConsent: false
1357+
};
1358+
1359+
const data2 = {};
1360+
utils.setDMAParams(data2, dmaObj, '/v2/event');
1361+
assert.deepEqual(data2, { "user_data": { dma_eea: true, dma_ad_personalization: true, dma_ad_user_data: false } });
1362+
});
1363+
it('should add DMA parameters for valid endpoints: v1/pageview', () => {
1364+
const dmaObj = {
1365+
eeaRegion: true,
1366+
adPersonalizationConsent: true,
1367+
adUserDataUsageConsent: false
1368+
};
1369+
1370+
const data2 = {};
1371+
utils.setDMAParams(data2, dmaObj, '/v1/pageview');
1372+
assert.deepEqual(data2, { dma_eea: true, dma_ad_personalization: true, dma_ad_user_data: false });
1373+
});
1374+
it('should not add DMA parameters for invalid endpoints: v1/invalid', () => {
1375+
const data = {};
1376+
const dmaObj = {
1377+
eeaRegion: true,
1378+
adPersonalizationConsent: true,
1379+
adUserDataUsageConsent: false
1380+
};
1381+
1382+
utils.setDMAParams(data, dmaObj, '/v1/invalid');
1383+
assert.deepEqual(data, {});
1384+
});
1385+
it('should not add DMA parameters for invalid endpoints: v1/dismiss', () => {
1386+
const data = {};
1387+
const dmaObj = {
1388+
eeaRegion: true,
1389+
adPersonalizationConsent: true,
1390+
adUserDataUsageConsent: false
1391+
};
1392+
1393+
utils.setDMAParams(data, dmaObj, '/v1/dismiss');
1394+
assert.deepEqual(data, {});
1395+
});
1396+
});
13271397

13281398
/*
13291399
describe('journey_cta', function(done) {

test/6_branch_new.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
22
/*jshint -W079 */
3+
/*jshint esversion: 6 */
34
var sinon = require('sinon');
45

56
goog.require('Branch');
@@ -54,4 +55,66 @@ describe('Branch - new', function() {
5455
assert.deepEqual(requestMetadata, { "key": "value" });
5556
});
5657
});
58+
describe('setDMAParamsForEEA', function() {
59+
let sandbox;
60+
beforeEach(() => {
61+
sandbox = sinon.createSandbox();
62+
});
63+
afterEach(() => {
64+
sandbox.restore();
65+
});
66+
it('test method exists', function() {
67+
sinon.assert.match(typeof branch_instance.setDMAParamsForEEA, "function");
68+
});
69+
it('should store dma params inside branch_dma_data of storage', function() {
70+
const thisObj = {
71+
_storage: {
72+
set: () => {}
73+
}
74+
};
75+
const storageSetStub = sandbox.stub(thisObj._storage, 'set');
76+
const dmaObj = {};
77+
dmaObj.eeaRegion = true;
78+
dmaObj.adPersonalizationConsent = true;
79+
dmaObj.adUserDataUsageConsent = true;
80+
const stringifieddmaObj = JSON.stringify(dmaObj);
81+
branch_instance.setDMAParamsForEEA.call(thisObj, dmaObj.eeaRegion, dmaObj.adPersonalizationConsent, dmaObj.adUserDataUsageConsent);
82+
sinon.assert.calledWith(storageSetStub, 'branch_dma_data', stringifieddmaObj, true);
83+
});
84+
it('should store default dma params inside branch_dma_data of storage', function() {
85+
const thisObj = {
86+
_storage: {
87+
set: () => {}
88+
}
89+
};
90+
const storageSetStub = sandbox.stub(thisObj._storage, 'set');
91+
const dmaObj = {};
92+
dmaObj.eeaRegion = false;
93+
dmaObj.adPersonalizationConsent = false;
94+
dmaObj.adUserDataUsageConsent = false;
95+
const stringifieddmaObj = JSON.stringify(dmaObj);
96+
branch_instance.setDMAParamsForEEA.call(thisObj);
97+
sinon.assert.calledWith(storageSetStub, 'branch_dma_data', stringifieddmaObj, true);
98+
});
99+
it('should catch and log exception', function() {
100+
const thisObj = {
101+
_storage: {
102+
set: () => {}
103+
}
104+
};
105+
sandbox.stub(thisObj._storage, 'set').throws(new Error('Mock error'));
106+
const consoleErrorStub = sandbox.stub(console, 'error');
107+
try {
108+
const dmaObj = {};
109+
dmaObj.eeaRegion = false;
110+
dmaObj.adPersonalizationConsent = false;
111+
dmaObj.adUserDataUsageConsent = false;
112+
branch_instance.setDMAParamsForEEA.call(thisObj);
113+
114+
} catch (e) {
115+
116+
}
117+
sinon.assert.calledWith(consoleErrorStub, 'setDMAParamsForEEA::An error occured while setting DMA parameters for EEA', sinon.match.instanceOf(Error));
118+
});
119+
});
57120
});

0 commit comments

Comments
 (0)