fix(client): calculate streaks correctly (#59252)

This commit is contained in:
Oliver Eyton-Williams
2025-03-13 04:31:46 +01:00
committed by GitHub
parent bc69f62635
commit fa9f5a7ca6
2 changed files with 29 additions and 7 deletions

View File

@@ -46,11 +46,23 @@ const twoStreakCalendar = {
'1736946000': 1 // 2025-01-15 13:00:00 UTC
};
const multipleEntriesInOneDay = {
// Two on Jan 13, 2025
'1736755200': 1, // 2025-01-13 08:00:00 UTC
'1736755500': 1, // 2025-01-13 08:05:00 UTC
// Two on Jan 14, 2025
'1736845200': 1, // 2025-01-14 09:00:00 UTC
'1736845500': 1, // 2025-01-14 09:05:00 UTC
// Two on Jan 15, 2025
'1736946000': 1, // 2025-01-15 13:00:00 UTC
'1736946300': 1 // 2025-01-15 13:05:00 UTC
};
jest.useFakeTimers();
describe('calculateStreaks', () => {
test('Should return a longest streak of 5 days when the user has not completed a challenge in a while', () => {
jest.setSystemTime(new Date(2025, 0, 15));
beforeEach(() => jest.setSystemTime(new Date(2025, 0, 15)));
test('Should return 0 for the current streak if the user has not made progress today', () => {
const { longestStreak, currentStreak } =
calculateStreaks(oldStreakCalendar);
@@ -77,10 +89,8 @@ describe('calculateStreaks', () => {
});
test('Should return a longest and current streaks of 1 day when the user has recently completed their first challenge', () => {
const now = new Date(2025, 0, 15);
jest.setSystemTime(now);
const calendar = {
[now.valueOf() / 1000]: 1
[Date.now() / 1000]: 1
};
const { longestStreak, currentStreak } = calculateStreaks(calendar);
@@ -103,4 +113,13 @@ describe('calculateStreaks', () => {
expect(longestStreak).toBe(0);
expect(currentStreak).toBe(0);
});
test('Should handle multiple entries in one day', () => {
const { longestStreak, currentStreak } = calculateStreaks(
multipleEntriesInOneDay
);
expect(longestStreak).toBe(3);
expect(currentStreak).toBe(3);
});
});

View File

@@ -3,7 +3,7 @@ import { startOfDay, addDays, isEqual } from 'date-fns';
import { useTranslation } from 'react-i18next';
import { Spacer } from '@freecodecamp/ui';
import { last } from 'lodash-es';
import { uniq } from 'lodash';
import { uniqBy } from 'lodash';
import { FullWidthRow } from '../../helpers';
@@ -19,7 +19,10 @@ export const calculateStreaks = (calendar: Record<string, number>) => {
const timestamps = Object.keys(calendar).map(
stamp => Number.parseInt(stamp, 10) * 1000
);
const days = uniq(timestamps.map(stamp => startOfDay(stamp)));
const days = uniqBy(
timestamps.map(stamp => startOfDay(stamp)),
day => day.getTime()
);
const { longestStreak, currentStreak } = days.reduce(
(acc, day) => {