Skip to content

Commit

Permalink
Merge pull request #1504 from tidepool-org/WEB-3376-mobile-analytics
Browse files Browse the repository at this point in the history
[WEB-3376] - Mobile Usage Analytics
  • Loading branch information
henry-tp authored Jan 27, 2025
2 parents e6c685b + e3764e9 commit 739577d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 8 deletions.
25 changes: 21 additions & 4 deletions app/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import config from './config';
import api from './core/api';
import personUtils from './core/personutils';
import detectTouchScreen from './core/notouch';
import utils from './core/utils';

/* global __DEV_TOOLS__ */

Expand All @@ -46,10 +47,26 @@ export let appContext = {
};

appContext.trackMetric = (...args) => {
let selectedClinicId = appContext.store?.getState()?.blip?.selectedClinicId;
if (selectedClinicId) {
_.defaultsDeep(args, [, { clinicId: selectedClinicId }]);
}
const state = appContext.store?.getState();

const clinicId = state?.blip?.selectedClinicId;
const loggedInUserId = state?.blip?.loggedInUserId;
const user = state?.blip?.allUsersMap?.[loggedInUserId];

const clinician = personUtils.isClinicianAccount(user);
const mobile = utils.isMobile();

let eventMetadata = {
clinicId,
clinician,
mobile,
};

// Empty values should be omitted from the metadata object to prevent sending blank query params
const filteredEventMetadata = _.omitBy(eventMetadata, _.isNil);

_.defaultsDeep(args, [, filteredEventMetadata]);

return appContext.api.metrics.track.apply(appContext.api.metrics, args);
};

Expand Down
15 changes: 14 additions & 1 deletion app/redux/utils/trackingMiddleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,30 @@
import _ from 'lodash';

import { isClinicianAccount } from '../../core/personutils';
import utils from '../../core/utils';
import * as ActionTypes from '../constants/actionTypes';

const trackMetricMap = {
LOGIN_SUCCESS: 'Logged In',
UPDATE_PATIENT_SUCCESS: 'Updated Profile',
UPDATE_USER_SUCCESS: 'Updated Account',
LOGOUT_REQUEST: 'Logged Out',
VERIFY_CUSTODIAL_SUCCESS: 'VCA Home Verification - Verified',
};

const interpretMetricMap = {
LOGIN_SUCCESS: function(action) {
const user = _.get(action, 'payload.user');

const clinician = isClinicianAccount(user);
const mobile = utils.isMobile();

let eventMetadata = { clinician, mobile };

// Empty values should be omitted from the metadata object to prevent sending blank query params
const filteredEventMetadata = _.omitBy(eventMetadata, _.isNil);

return { eventName: 'Logged In', properties: filteredEventMetadata };
},
SETUP_DATA_STORAGE_SUCCESS: function(action) {
const diagnosisType = _.get(action, 'payload.patient.profile.patient.diagnosisType');
return { eventName: 'Created Profile', properties: diagnosisType ? { 'Diabetes Type': diagnosisType } : null };
Expand Down
18 changes: 17 additions & 1 deletion test/unit/bootstrap.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import appContext from '../../app/bootstrap';

describe('appContext', () => {
before(() => {
Object.defineProperty(window.navigator, 'userAgent', { value: 'Mozilla/5.0 .. truncated .. Chrome/131.0.0.0' });

appContext.api = {
metrics: {
track: sinon.stub(),
Expand All @@ -35,15 +37,27 @@ describe('appContext', () => {

it('should call appContext.api.metrics.track with clinicId defaulted to selectedClinicId when it is present', () => {
const selectedClinicId = 'clinic123';
const loggedInUserId = 'abcd-1234';
const allUsersMap = {
[loggedInUserId]: { username: '[email protected]', roles: ['clinician'] },
};

appContext.store.getState.returns({ blip: { selectedClinicId } });
appContext.store.getState.returns({
blip: {
selectedClinicId,
loggedInUserId,
allUsersMap,
},
});

appContext.trackMetric('someMetric2');

expect(appContext.api.metrics.track.calledOnce).to.be.true;
expect(
appContext.api.metrics.track.calledWith('someMetric2', {
clinicId: 'clinic123',
mobile: false,
clinician: true,
})
).to.be.true;

Expand All @@ -55,6 +69,8 @@ describe('appContext', () => {
expect(
appContext.api.metrics.track.calledWith('someMetric2', {
clinicId: 'anotherClinic',
mobile: false,
clinician: true,
})
).to.be.true;
});
Expand Down
8 changes: 6 additions & 2 deletions test/unit/redux/utils/trackingMiddleware.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ describe('trackingMiddleware', () => {
const next = sinon.stub();

beforeEach(() => {
Object.defineProperty(window.navigator, 'userAgent', { value: 'Mozilla/5.0 .. truncated .. Chrome/131.0.0.0' });
api.metrics.track.resetHistory();
});

Expand Down Expand Up @@ -80,12 +81,15 @@ describe('trackingMiddleware', () => {

it('should call the metrics api for LOGIN_SUCCESS', () => {
const loginSuccess = {
type: ActionTypes.LOGIN_SUCCESS
type: ActionTypes.LOGIN_SUCCESS,
payload: {
user: { roles: ['clinic'] },
},
};
expect(api.metrics.track.callCount).to.equal(0);
trackingMiddleware(api)(getStateObj)(next)(loginSuccess);
expect(api.metrics.track.callCount).to.equal(1);
expect(api.metrics.track.calledWith('Logged In')).to.be.true;
expect(api.metrics.track.calledWith('Logged In', { mobile: false, clinician: true })).to.be.true;
});

it('should call the metrics api for SETUP_DATA_STORAGE_SUCCESS', () => {
Expand Down

0 comments on commit 739577d

Please sign in to comment.