Skip to content

Commit

Permalink
feat: 🎸 respects GDPR - purpose 1 (#58)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: 🧨 tracking is disabled by default, use purposeConsents in initConfig
object to set users consents
  • Loading branch information
Greld authored Dec 13, 2021
1 parent d5e5193 commit d792e91
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 13 deletions.
3 changes: 2 additions & 1 deletion packages/plugin-analytic-google/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"license": "MIT",
"dependencies": {
"@ima/plugin-analytic": "^4.0.2",
"@ima/plugin-script-loader": "^2.1.0"
"@ima/plugin-script-loader": "^2.1.0",
"easy-uid": "^1.0.2"
},
"peerDependencies": {
"@ima/plugin-script-loader": ">= 1.0.0"
Expand Down
51 changes: 40 additions & 11 deletions packages/plugin-analytic-google/src/GoogleAnalytic.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,20 +73,36 @@ export default class GoogleAnalytic extends AbstractAnalytic {

const clientWindow = this._window.getWindow();

if (customDimensions) {
if (typeof customDimensions === 'object') {
Object.entries(customDimensions).forEach(([key, value]) => {
clientWindow.ga('set', key, value);
});
}
if (customDimensions && typeof customDimensions === 'object') {
this._setSetter(customDimensions);
}

clientWindow.ga('set', 'page', pageData.path);
clientWindow.ga('set', 'location', this._window.getUrl());
clientWindow.ga('set', 'title', document.title || '');
this._setSetter({
page: pageData.path,
location: this._window.getUrl(),
title: document.title || ''
});

clientWindow.ga('send', 'pageview');
}

/**
* @override
* @inheritdoc
*/
_applyPurposeConsents(purposeConsents) {
if (purposeConsents && typeof purposeConsents === 'object') {
if (purposeConsents['1']) {
delete this._config.settings['clientId'];
delete this._config.settings['storage'];
}
// TODO: respect other purposes
// delete this._config.settingsSetter['allowAdFeatures'];
// delete this._config.settingsSetter['anonymizeIp'];
// delete this._config.settingsSetter['allowAdPersonalizationSignals'];
}
}

/**
* @override
* @inheritdoc
Expand All @@ -97,7 +113,7 @@ export default class GoogleAnalytic extends AbstractAnalytic {
if (
this.isEnabled() ||
!clientWindow.ga ||
typeof this._window.getWindow().ga !== 'function'
typeof clientWindow.ga !== 'function'
) {
return;
}
Expand All @@ -109,14 +125,27 @@ export default class GoogleAnalytic extends AbstractAnalytic {
'auto',
this._config.settings
);

this._setSetter(this._config.settingsSetter);
}

_setSetter(settings) {
const clientWindow = this._window.getWindow();

if (settings && typeof settings === 'object') {
Object.entries(settings).forEach(([key, value]) => {
clientWindow.ga('set', key, value);
});
}
}

/**
* @override
* @inheritdoc
*/
_createGlobalDefinition() {
let window = this._window.getWindow();
const window = this._window.getWindow();

window[GA_ROOT_VARIABLE] =
window[GA_ROOT_VARIABLE] ||
function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,75 @@ describe('GoogleAnalytic', () => {
expect(mockGa.ga).toHaveBeenCalledWith('set', 'dimension2', 'value2');
});
});

describe('_setSetter method', () => {
it('should do nothing when argument is null', () => {
spyOn(googleAnalytic, 'isEnabled').and.returnValue(true);
spyOn(mockGa, 'ga');

const setterObj = null;

googleAnalytic._setSetter(setterObj);

expect(mockGa.ga).not.toHaveBeenCalled();
});

it('should do nothing when argument is not an object', () => {
spyOn(googleAnalytic, 'isEnabled').and.returnValue(true);
spyOn(mockGa, 'ga');

const setterObj = () => {};

googleAnalytic._setSetter(setterObj);

expect(mockGa.ga).not.toHaveBeenCalled();
});

it('should set object properties into ga', () => {
spyOn(googleAnalytic, 'isEnabled').and.returnValue(true);
spyOn(mockGa, 'ga');

const setterObj = {
prop1: 'value1',
prop2: 'value2'
};

googleAnalytic._setSetter(setterObj);

expect(mockGa.ga).toHaveBeenCalledWith('set', 'prop1', 'value1');
expect(mockGa.ga).toHaveBeenCalledWith('set', 'prop2', 'value2');
});
});

describe('_applyPurposeConsents method', () => {
it('should remove clientId and storage from settings when purpose 1 is set', () => {
spyOn(googleAnalytic, 'isEnabled').and.returnValue(true);
spyOn(mockGa, 'ga');

settings.settings = {
clientId: 'abcde12345',
storage: 'none'
};

googleAnalytic._applyPurposeConsents({ 1: true });

expect(settings.settings).toEqual({});
});

it('should leave settings as it is when purpose 1 is not set', () => {
spyOn(googleAnalytic, 'isEnabled').and.returnValue(true);
spyOn(mockGa, 'ga');

settings.settings = {
clientId: 'abcde123445',
storage: 'none'
};

const expectedSettings = Object.assign({}, settings.settings);

googleAnalytic._applyPurposeConsents({ 1: false });

expect(settings.settings).toEqual(expectedSettings);
});
});
});
12 changes: 11 additions & 1 deletion packages/plugin-analytic-google/src/main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import uid from 'easy-uid';

import GoogleAnalytic from './GoogleAnalytic.js';

const defaultDependencies = GoogleAnalytic.$dependencies;
Expand All @@ -11,7 +13,15 @@ let initSettings = () => {
analytic: {
google: {
service: 'UA-XXXXXXX-X',
settings: {}
settings: {
clientId: uid(),
storage: 'none'
},
settingsSetter: {
allowAdFeatures: false,
anonymizeIp: true,
allowAdPersonalizationSignals: false
}
}
}
}
Expand Down

0 comments on commit d792e91

Please sign in to comment.