Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bike goal list view and routes #207

Merged
merged 11 commits into from
Oct 12, 2022
23 changes: 23 additions & 0 deletions src/components/Goals/BikeGoal/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import flag from 'cozy-flags'
import { countDays } from 'src/lib/timeseries'

export const getDaysToReach = () =>
flag('coachco2.bikegoal.settings').daysToReach
Copy link
Contributor

Choose a reason for hiding this comment

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

Dans l'état, on a une erreur si le flag n'est pas défini.
Peut-être qu'on aurait pu mettre une valeur par défaut ou émettre une erreur explicite dans ce cas ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

exact, je me suis posé la question, et je suis parti du principe que de toute façon l'app ne marcherait pas sans et que le flag serait présent sur les instances... un throw explicite serait bien dans ce genre de conclusion 👍


export const isGoalCompleted = timeseries => {
return countDays(timeseries) >= getDaysToReach()
}

export const countDaysOrDaysToReach = timeseries => {
const days = countDays(timeseries)
const daysToReach = getDaysToReach()

return days < daysToReach ? days : daysToReach
}

export const makeGoalAchievementPercentage = timeseries => {
const daysOrDaysToReach = countDaysOrDaysToReach(timeseries)
const daysToReach = getDaysToReach()

return Math.round((daysOrDaysToReach / daysToReach) * 100)
}
83 changes: 83 additions & 0 deletions src/components/Goals/BikeGoal/helpers.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import {
isGoalCompleted,
countDaysOrDaysToReach,
makeGoalAchievementPercentage
} from './helpers'

jest.mock('cozy-flags', () => name => {
if (name === 'coachco2.bikegoal.settings') {
return { daysToReach: 30 }
}
})

describe('isGoalCompleted', () => {
it('should return true', () => {
const timeseries = [
{ startDate: '2021-01-01T00:00:00', endDate: '2021-01-02T00:00:00' },
{ startDate: '2021-03-01T00:00:00', endDate: '2021-03-02T00:00:00' }
]

const res = isGoalCompleted(timeseries)

expect(res).toBe(true)
})

it('should return false', () => {
const timeseries = [
{ startDate: '2021-01-01T00:00:00', endDate: '2021-01-02T00:00:00' },
{ startDate: '2021-01-04T00:00:00', endDate: '2021-01-05T00:00:00' }
]

const res = isGoalCompleted(timeseries)

expect(res).toBe(false)
})
})

describe('countDaysOrDaysToReach', () => {
it('should return the number of timeseries days', () => {
const timeseries = [
{ startDate: '2021-01-01T00:00:00', endDate: '2021-01-01T00:00:00' },
{ startDate: '2021-01-05T00:00:00', endDate: '2021-01-05T00:00:00' }
]

const res = countDaysOrDaysToReach(timeseries)

expect(res).toBe(4)
})

it('should return the days to reach', () => {
const timeseries = [
{ startDate: '2021-01-01T00:00:00', endDate: '2021-01-02T00:00:00' },
{ startDate: '2021-06-01T00:00:00', endDate: '2021-06-01T00:00:00' }
]

const res = countDaysOrDaysToReach(timeseries)

expect(res).toBe(30)
})
})

describe('makeGoalAchievementPercentage', () => {
it('should return 30', () => {
const timeseries = [
{ startDate: '2021-01-01T00:00:00', endDate: '2021-01-01T00:00:00' },
{ startDate: '2021-01-05T00:00:00', endDate: '2021-01-05T00:00:00' }
]

const res = makeGoalAchievementPercentage(timeseries)

expect(res).toBe(13)
})

it('should return 100', () => {
const timeseries = [
{ startDate: '2021-01-01T00:00:00', endDate: '2021-01-02T00:00:00' },
{ startDate: '2021-06-01T00:00:00', endDate: '2021-06-01T00:00:00' }
]

const res = makeGoalAchievementPercentage(timeseries)

expect(res).toBe(100)
})
})
21 changes: 21 additions & 0 deletions src/lib/timeseries.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import uniq from 'lodash/uniq'
import subMonths from 'date-fns/subMonths'
import startOfMonth from 'date-fns/startOfMonth'
import dateFnsFormatDistance from 'date-fns/formatDistance'
import differenceInDays from 'date-fns/differenceInDays'

import { computeCO2Section, computeCaloriesSection } from 'src/lib/metrics'
import {
Expand Down Expand Up @@ -453,3 +454,23 @@ export const computeMonthsAndCO2s = (timeseries, f) => {

return { months: formatedMonths, CO2s }
}

export const computeFirstAndLastDay = timeseries => {
let firstDay = getStartDate(timeseries[0])
let lastDay = getEndDate(timeseries[0])

timeseries.forEach(timeserie => {
const startDate = getStartDate(timeserie)
const endDate = getEndDate(timeserie)

firstDay = startDate < firstDay ? startDate : firstDay
lastDay = endDate > lastDay ? endDate : lastDay
})

return { firstDay, lastDay }
}

export const countDays = timeseries => {
const { firstDay, lastDay } = computeFirstAndLastDay(timeseries)
return differenceInDays(lastDay, firstDay)
}
36 changes: 35 additions & 1 deletion src/lib/timeseries.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ import {
getFormattedTotalCalories,
setAggregationPurpose,
setAutomaticPurpose,
setManualPurpose
setManualPurpose,
computeFirstAndLastDay,
countDays
} from 'src/lib/timeseries'

describe('transformSerieToTrip', () => {
Expand Down Expand Up @@ -781,3 +783,35 @@ describe('set purpose', () => {
})
})
})

describe('computeFirstAndLastDay', () => {
it('should return first and last day', () => {
const timeseries = [
{ startDate: '2021-01-01T00:00:00', endDate: '2021-01-02T00:00:00' },
{ startDate: '2021-02-01T00:00:00', endDate: '2021-02-02T00:00:00' },
{ startDate: '2021-03-01T00:00:00', endDate: '2021-03-02T00:00:00' }
]

const res = computeFirstAndLastDay(timeseries)

expect(res).toStrictEqual({
firstDay: new Date('2021-01-01T00:00:00.000Z'),
lastDay: new Date('2021-03-02T00:00:00.000Z')
})
})
})

describe('countDays', () => {
it('should return the number of days covered by timeseries', () => {
const timeseries = [
{ startDate: '2021-01-01T00:00:00', endDate: '2021-01-02T00:00:00' },
{ startDate: '2021-02-01T00:00:00', endDate: '2021-02-02T00:00:00' },
{ startDate: '2021-02-01T10:00:00', endDate: '2021-02-02T10:00:00' },
{ startDate: '2021-03-01T00:00:00', endDate: '2021-03-02T00:00:00' }
]

const res = countDays(timeseries)

expect(res).toBe(60)
})
})