Skip to content
This repository has been archived by the owner on Feb 1, 2024. It is now read-only.

Add Google Analytics tracking if and only if a user has clicked "Accept" on the notification #409

Merged
merged 2 commits into from Mar 27, 2019

Conversation

kellyi
Copy link
Contributor

@kellyi kellyi commented Mar 27, 2019

Overview

This PR configures the application to add Google Analytics tracking if -- and only if -- a user has clicked "Accept" on the Notification. To make this easier to prove & verify, I opted to initialize the GA tracking conditionally in a utility function around which I was able to set up some testing apparatus.

If a user clicks "Reject", we set a value for GA_TRACKING in localStorage to "HAS_REJECTED_GA_TRACKING" and then that sticks until the user clears localStorage.

If a user clicks "Accept", we set a value for GA_TRACKING in localStorage to
"HAS_ACCEPTED_GA_TRACKING" and then set up tracking for that visit. On subsequent visits, the application will check for the GA_TRACKING value and if it sees that there is a value AND that that value is "HAS_ACCEPTED_GA_TRACKING" then tracking starts.

For the following conditions, the application does not start GA Tracking at all:

  • window.localStorage is unavailable for whatever reason
  • GA_TRACKING has not been set at all in window.localStorage
  • GA_TRACKING is in window.localStorage but does not have a value of "HAS_ACCEPTED_GA_TRACKING".

As an additional guard, I set an initial global opt out value per https://developers.google.com/analytics/devguides/collection/analyticsjs/user-opt-out which is only deleted when all the acceptance conditions have been met.

Connects #265
Connects #267

Demo

Screen Shot 2019-03-27 at 12 40 56 PM

Notes

The second commit here is entirely for testing and I will drop it before merging this in. GA provides a helpful debug library which logs actions to the console so you can easily see when it is called.

Testing Instructions

  • serve this branch, then visit the application in Chrome
  • clear your cookies and your localStorage
  • refresh the page and verify that you see the new GDPR notification in the Snackbar
  • open the network tab

Rejection testing

  • click "Reject"
  • verify that you do not see any requests made to google analytics in the network tab
  • switch to the console and verify that you DO NOT see a message like the following logged amidst the Redux logger actions:

Screen Shot 2019-03-27 at 12 44 32 PM

  • look at the application cookies and verify that no Google Analytics cookies have been set
  • refresh the page and repeat these verification steps
  • refresh a couple more times and repeat these verification steps

At no point prior to "Accepting" or after "Rejecting" should you see:

  • requests made to Google Analytics in the Network tab
  • cookies set by Google Anayltics

Acceptance testing

  • clear cookies and localStorage
  • refresh the app and click Accept
  • verify that you do see a request made to GA in the network tab and that you also see something like this in the console with subequent info about settings:

Screen Shot 2019-03-27 at 12 44 32 PM

Screen Shot 2019-03-27 at 12 47 20 PM

  • refresh the page and verify that you see the Google Analytics stuff load again along with the "anonymizeIp" setting
  • refresh the page again and verify the same
No localStorage testing
  • open Firefox, then open about:config
  • Follow these instructions to disable localStorage:
In FireFox: Type “about:config” in your address bar and hit enter to view your internal browser settings. Scroll down to „dom.storage.enabled”, right click on it and hit „Toggle” to disable the DOM Storage.
  • visit the application in Firefox and verify that it doesn't crash and that Google Analytics tracking does not start

Checklist

  • fixup! commits have been squashed
  • CI passes after rebase
  • CHANGELOG.md updated with summary of features or fixes, following Keep a Changelog guidelines

Copy link
Contributor

@rajadain rajadain left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 tested, very detailed and well thought out. Works well too! Great job.

src/app/src/__tests__/util.ga.tests.js Show resolved Hide resolved
import Snackbar from '@material-ui/core/Snackbar';
import Button from './Button';
import ShowOnly from './ShowOnly';
import COLOURS from '../util/COLOURS';

class GDPRNotification extends PureComponent {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why change from PureComponent to Component? (I'm not familiar with the subtle differences)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding of PureComponent is that it has some characteristics which memoize it in certain circumstances, but I don't quite know whether that's true or what those circumstances are. In the interest of being able to reason about this a little more accurately I switched it out for a regular Component.

@rajadain rajadain removed their assignment Mar 27, 2019
};
acceptGDPRAlertAndDismissSnackbar = () => this.setState(
state => Object.assign({}, state, { open: false }),
acceptGATrackingAndStartTracking,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent function name

const gaKey = env(REACT_APP_GOOGLE_ANALYTICS_KEY);
const environment = env('ENVIRONMENT');

if (!environment || environment !== 'development') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite understand the environment !== 'development' clause here. Doesn't this mean that if we are in staging or production then we will always return null?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is part of the test commit that will be dropped before merging. It's supposed to be if (environment === development) return null;.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, sorry for not explaining well. I'll drop c68fabf before merging this, but it is essentially just to be able to test this in local development. For production and staging it will be set to === 'development' -> return null

Copy link
Contributor

@jwalgran jwalgran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a thoughtful implementation and is working well. I am not sure we need to be recording a consent action every time the page is loaded, but in the interest of getting this released I would rather get it deployed and remove it later if we decide we don't need it.

- add util.ga.js file with functions for getting and setting a value for
the user's choice to accept or reject cookies and starting tracking if
and only if a user has explicitly accepted the tracking code
- add util.ga.tests.js file with tests for localstorage
- update GDPRNotification component to use utility functions
- conditionally call tracking code in GDPRNotification's
componentDidMount method if and only if a user has already clicked the
Accept link in the GDPRNotification snackbar
- update cookie opt out Snackbar message with approved text
- set link to TOS & privacy policy

Connects #265

- send TRACKING_CONSENT event to Google Analytics prior to each pageview
- add moment library for date parsing and comparison
- store date user decided in localstorage
- expire date after one year
- don't track if date is expired
@kellyi kellyi force-pushed the ki/add-google-analytics-on-an-opt-in-basis branch from 2e7c0ec to 6a107e5 Compare March 27, 2019 19:27
@kellyi kellyi changed the base branch from develop to release/2.0.0 March 27, 2019 19:27
Copy link
Contributor

@jwalgran jwalgran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that this is still conditionally and correctly sending analyitcs events.

@kellyi kellyi merged commit dfbf928 into release/2.0.0 Mar 27, 2019
@kellyi kellyi deleted the ki/add-google-analytics-on-an-opt-in-basis branch March 27, 2019 19:45
@kellyi
Copy link
Contributor Author

kellyi commented Mar 27, 2019

Thanks for the feedback and help with this!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants