Skip to content

Commit

Permalink
fix: make analytics opt-in (#981)
Browse files Browse the repository at this point in the history
- remove doNotTrack detection in favour of always opt-in

wip on: #980


License: MIT
Signed-off-by: Oli Evans <oli@tableflip.io>
  • Loading branch information
fsdiogo authored and olizilla committed Feb 27, 2019
1 parent aa7df07 commit 38743dc
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 60 deletions.
30 changes: 10 additions & 20 deletions src/bundles/analytics.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,7 @@ const IGNORE_ACTIONS = /^(FILES_FETCH_|FILES_WRITE_UPDATED)/
const USER_ACTIONS = /^(CONFIG_SAVE_|FILES_|DESKTOP_)/
const ASYNC_ACTIONS = /^(.+)_(STARTED|FINISHED|FAILED)$/

function getDoNotTrack () {
if (!root.navigator) return false
const value = root.doNotTrack || root.navigator.doNotTrack || root.navigator.msDoNotTrack
if (value === '1' || value === 'yes') {
return true
}
return false
}

const createAnalyticsBundle = ({
doNotTrack = getDoNotTrack(),
countlyUrl = 'https://countly.ipfs.io',
countlyAppKey,
appVersion,
Expand Down Expand Up @@ -99,7 +89,7 @@ const createAnalyticsBundle = ({
}
},

reducer: (state = { doNotTrack, lastEnabledAt: 0, lastDisabledAt: 0 }, action) => {
reducer: (state = { lastEnabledAt: 0, lastDisabledAt: 0 }, action) => {
if (action.type === 'ANALYTICS_ENABLED') {
return { ...state, lastEnabledAt: Date.now() }
}
Expand All @@ -112,27 +102,27 @@ const createAnalyticsBundle = ({
selectAnalytics: (state) => state.analytics,

/*
Use the users preference or their global doNotTrack setting.
Use the users preference.
*/
selectAnalyticsEnabled: (state) => {
const { lastEnabledAt, lastDisabledAt, doNotTrack } = state.analytics
// where never opted in or out, use their global tracking preference
const { lastEnabledAt, lastDisabledAt } = state.analytics
// where never opted in or out, analytics are disabled by default
if (!lastEnabledAt && !lastDisabledAt) {
return !doNotTrack
return false
}
// otherwise return their most recent choice.
return lastEnabledAt > lastDisabledAt
},

/*
Ask the user if we may enable analytics if they have doNotTrack set
Ask the user if we may enable analytics.
*/
selectAnalyticsAskToEnable: (state) => {
const { lastEnabledAt, lastDisabledAt, doNotTrack } = state.analytics
// user has not explicity chosen
const { lastEnabledAt, lastDisabledAt } = state.analytics
// user has not explicitly chosen
if (!lastEnabledAt && !lastDisabledAt) {
// ask to enable if doNotTrack is true.
return doNotTrack
// ask to enable.
return true
}
// user has already made an explicit choice; dont ask again.
return false
Expand Down
55 changes: 15 additions & 40 deletions src/bundles/analytics.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ beforeEach(() => {

afterEach(() => {
delete global.Countly
if (global.navigator && global.navigator.hasOwnProperty('doNotTrack')) {
delete global.navigator.doNotTrack
}
})

function createStore (analyticsOpts = {}) {
Expand All @@ -28,75 +25,53 @@ function createStore (analyticsOpts = {}) {
)()
}

it('should normalise the doNotTrack state from the navigator.doNotTrack value', () => {
let store = createStore()
// false if not set.
expect(store.selectAnalytics().doNotTrack).toBe(false)
global.navigator = { doNotTrack: '1' }
store = createStore()
expect(store.selectAnalytics().doNotTrack).toBe(true)

global.navigator.doNotTrack = '0'
store = createStore()
expect(store.selectAnalytics().doNotTrack).toBe(false)
})

it('should enable analytics if doNotTrack is falsey', () => {
it('should enable analytics if user has explicitly enabled it', () => {
const store = createStore()
expect(store.selectAnalyticsEnabled()).toBe(true)
})

it('should disable analytics if doNotTrack is true', () => {
const store = createStore({ doNotTrack: true })
expect(store.selectAnalyticsEnabled()).toBe(false)
})

it('should enable analytics if doNotTrack is true but user has explicitly enabled it', () => {
const store = createStore({ doNotTrack: true })
store.doEnableAnalytics()
expect(store.selectAnalyticsEnabled()).toBe(true)
})

it('should disable analytics if doNotTrack is falsey but user has explicitly disabled it', () => {
const store = createStore({ doNotTrack: false })
it('should disable analytics if user has explicitly disabled it', () => {
const store = createStore()
store.doDisableAnalytics()
expect(store.selectAnalyticsEnabled()).toBe(false)
})

it('should enable selectAnalyticsAskToEnable if doNotTrack is true and user has not explicity enabled or disabled it', () => {
const store = createStore({ doNotTrack: true })
it('should enable selectAnalyticsAskToEnable if user has not explicity enabled or disabled it', () => {
const store = createStore()
expect(store.selectAnalyticsAskToEnable()).toBe(true)
})

it('should disable selectAnalyticsAskToEnable if doNotTrack is true and user has explicity disabled it', () => {
const store = createStore({ doNotTrack: true })
it('should disable selectAnalyticsAskToEnable if user has explicity disabled it', () => {
const store = createStore()
store.doDisableAnalytics()
expect(store.selectAnalyticsAskToEnable()).toBe(false)
})

it('should disable selectAnalyticsAskToEnable if doNotTrack is true and user has explicity enabled it', () => {
const store = createStore({ doNotTrack: true })
it('should disable selectAnalyticsAskToEnable if user has explicity enabled it', () => {
const store = createStore()
store.doEnableAnalytics()
expect(store.selectAnalyticsAskToEnable()).toBe(false)
})

it('should disable selectAnalyticsAskToEnable if analytics are enabled', () => {
const store = createStore({ doNotTrack: false })
const store = createStore()
store.doEnableAnalytics()
expect(store.selectAnalyticsAskToEnable()).toBe(false)
})

it('should toggle analytics', async (done) => {
const store = createStore({ doNotTrack: false })
expect(store.selectAnalyticsEnabled()).toBe(true)
const store = createStore()
expect(store.selectAnalyticsEnabled()).toBe(false)

store.doToggleAnalytics()
expect(store.selectAnalyticsEnabled()).toBe(false)
expect(store.selectAnalyticsEnabled()).toBe(true)

// we calc enabled state from time diff between lastEnabledAt and lastDisabledAt, so need a pause
await sleep()

store.doToggleAnalytics()
expect(store.selectAnalyticsEnabled()).toBe(true)
expect(store.selectAnalyticsEnabled()).toBe(false)

done()
})

0 comments on commit 38743dc

Please sign in to comment.