From 1654784471b735e43cbcff9fee5766ac439a7a06 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 5 Dec 2022 17:18:00 +0100 Subject: [PATCH] Created now function and refactored intervalToDateRange --- src/utils/dates/DateRangeSelector.tsx | 3 +- src/utils/dates/Time.tsx | 4 +- src/utils/helpers/date.ts | 4 +- src/utils/helpers/dateIntervals.ts | 46 +++++++------------- test/utils/helpers/dateIntervals.test.ts | 11 +++-- test/visits/reducers/domainVisits.test.ts | 4 +- test/visits/reducers/nonOrphanVisits.test.ts | 4 +- test/visits/reducers/orphanVisits.test.ts | 4 +- test/visits/reducers/shortUrlVisits.test.ts | 4 +- test/visits/reducers/tagVisits.test.ts | 4 +- 10 files changed, 38 insertions(+), 50 deletions(-) diff --git a/src/utils/dates/DateRangeSelector.tsx b/src/utils/dates/DateRangeSelector.tsx index 652d3c11..3aaeaf9e 100644 --- a/src/utils/dates/DateRangeSelector.tsx +++ b/src/utils/dates/DateRangeSelector.tsx @@ -9,6 +9,7 @@ import { intervalToDateRange, rangeIsInterval, dateRangeIsEmpty, + ALL, } from '../helpers/dateIntervals'; import { DateRangeRow } from './DateRangeRow'; import { DateIntervalDropdownItems } from './DateIntervalDropdownItems'; @@ -31,7 +32,7 @@ export const DateRangeSelector = ( const [activeDateRange, setActiveDateRange] = useState(initialIntervalIsRange ? undefined : initialDateRange); const updateDateRange = (dateRange: DateRange) => { - setActiveInterval(dateRangeIsEmpty(dateRange) ? 'all' : undefined); + setActiveInterval(dateRangeIsEmpty(dateRange) ? ALL : undefined); setActiveDateRange(dateRange); onDatesChange(dateRange); }; diff --git a/src/utils/dates/Time.tsx b/src/utils/dates/Time.tsx index a06381df..e2418659 100644 --- a/src/utils/dates/Time.tsx +++ b/src/utils/dates/Time.tsx @@ -1,5 +1,5 @@ import { parseISO, format as formatDate, getUnixTime, formatDistance } from 'date-fns'; -import { isDateObject, STANDARD_DATE_AND_TIME_FORMAT } from '../helpers/date'; +import { isDateObject, now, STANDARD_DATE_AND_TIME_FORMAT } from '../helpers/date'; export interface TimeProps { date: Date | string; @@ -12,7 +12,7 @@ export const Time = ({ date, format = STANDARD_DATE_AND_TIME_FORMAT, relative = return ( ); }; diff --git a/src/utils/helpers/date.ts b/src/utils/helpers/date.ts index e9489193..ee74e992 100644 --- a/src/utils/helpers/date.ts +++ b/src/utils/helpers/date.ts @@ -9,6 +9,8 @@ export type DateOrString = Date | string; type NullableDate = DateOrString | null; +export const now = () => new Date(); + export const isDateObject = (date: DateOrString): date is Date => typeof date !== 'string'; const formatDateFromFormat = (date?: NullableDate, theFormat?: string): OptionalString => { @@ -28,7 +30,7 @@ export const formatIsoDate = (date?: NullableDate) => formatDateFromFormat(date, export const formatInternational = formatDate(); -export const parseDate = (date: string, theFormat: string) => parse(date, theFormat, new Date()); +export const parseDate = (date: string, theFormat: string) => parse(date, theFormat, now()); export const parseISO = (date: DateOrString): Date => (isDateObject(date) ? date : stdParseISO(date)); diff --git a/src/utils/helpers/dateIntervals.ts b/src/utils/helpers/dateIntervals.ts index f81addb8..eb37758a 100644 --- a/src/utils/helpers/dateIntervals.ts +++ b/src/utils/helpers/dateIntervals.ts @@ -1,13 +1,13 @@ import { subDays, startOfDay, endOfDay } from 'date-fns'; import { cond, filter, isEmpty, T } from 'ramda'; -import { dateOrNull, DateOrString, formatInternational, isBeforeOrEqual, parseISO } from './date'; +import { dateOrNull, DateOrString, formatInternational, isBeforeOrEqual, now, parseISO } from './date'; export interface DateRange { startDate?: Date | null; endDate?: Date | null; } -const ALL = 'all'; +export const ALL = 'all'; const INTERVAL_TO_STRING_MAP = { today: 'Today', yesterday: 'Yesterday', @@ -64,39 +64,25 @@ export const rangeOrIntervalToString = (range?: DateRange | DateInterval): strin return INTERVAL_TO_STRING_MAP[range]; }; -const startOfDaysAgo = (daysAgo: number) => startOfDay(subDays(new Date(), daysAgo)); -const endingToday = (startDate: Date): DateRange => ({ startDate, endDate: endOfDay(new Date()) }); +const startOfDaysAgo = (daysAgo: number) => startOfDay(subDays(now(), daysAgo)); +const endingToday = (startDate: Date): DateRange => ({ startDate, endDate: endOfDay(now()) }); -export const intervalToDateRange = (dateInterval?: DateInterval): DateRange => { - if (!dateInterval || dateInterval === ALL) { - return {}; - } - - switch (dateInterval) { - case 'today': - return endingToday(startOfDay(new Date())); - case 'yesterday': - return { startDate: startOfDaysAgo(1), endDate: endOfDay(subDays(new Date(), 1)) }; - case 'last7Days': - return endingToday(startOfDaysAgo(7)); - case 'last30Days': - return endingToday(startOfDaysAgo(30)); - case 'last90Days': - return endingToday(startOfDaysAgo(90)); - case 'last180Days': - return endingToday(startOfDaysAgo(180)); - case 'last365Days': - return endingToday(startOfDaysAgo(365)); - } - - return {}; -}; +export const intervalToDateRange = cond<[DateInterval | undefined], DateRange>([ + [(dateInterval) => dateInterval === 'today', () => endingToday(startOfDay(now()))], + [(dateInterval) => dateInterval === 'yesterday', () => ({ startDate: startOfDaysAgo(1), endDate: endOfDay(subDays(now(), 1)) })], + [(dateInterval) => dateInterval === 'last7Days', () => endingToday(startOfDaysAgo(7))], + [(dateInterval) => dateInterval === 'last30Days', () => endingToday(startOfDaysAgo(30))], + [(dateInterval) => dateInterval === 'last90Days', () => endingToday(startOfDaysAgo(90))], + [(dateInterval) => dateInterval === 'last180Days', () => endingToday(startOfDaysAgo(180))], + [(dateInterval) => dateInterval === 'last365Days', () => endingToday(startOfDaysAgo(365))], + [T, () => ({})], +]); export const dateToMatchingInterval = (date: DateOrString): DateInterval => { - const theDate: Date = parseISO(date); + const theDate = parseISO(date); return cond([ - [() => isBeforeOrEqual(startOfDay(new Date()), theDate), () => 'today'], + [() => isBeforeOrEqual(startOfDay(now()), theDate), () => 'today'], [() => isBeforeOrEqual(startOfDaysAgo(1), theDate), () => 'yesterday'], [() => isBeforeOrEqual(startOfDaysAgo(7), theDate), () => 'last7Days'], [() => isBeforeOrEqual(startOfDaysAgo(30), theDate), () => 'last30Days'], diff --git a/test/utils/helpers/dateIntervals.test.ts b/test/utils/helpers/dateIntervals.test.ts index 37ebe6ff..76f98392 100644 --- a/test/utils/helpers/dateIntervals.test.ts +++ b/test/utils/helpers/dateIntervals.test.ts @@ -8,11 +8,10 @@ import { rangeOrIntervalToString, toDateRange, } from '../../../src/utils/helpers/dateIntervals'; -import { parseDate } from '../../../src/utils/helpers/date'; +import { parseDate, now } from '../../../src/utils/helpers/date'; describe('date-types', () => { - const now = () => new Date(); - const daysBack = (days: number) => subDays(new Date(), days); + const daysBack = (days: number) => subDays(now(), days); describe('dateRangeIsEmpty', () => { it.each([ @@ -26,9 +25,9 @@ describe('date-types', () => { [{ startDate: undefined, endDate: undefined }, true], [{ startDate: undefined, endDate: null }, true], [{ startDate: null, endDate: undefined }, true], - [{ startDate: new Date() }, false], - [{ endDate: new Date() }, false], - [{ startDate: new Date(), endDate: new Date() }, false], + [{ startDate: now() }, false], + [{ endDate: now() }, false], + [{ startDate: now(), endDate: now() }, false], ])('returns proper result', (dateRange, expectedResult) => { expect(dateRangeIsEmpty(dateRange)).toEqual(expectedResult); }); diff --git a/test/visits/reducers/domainVisits.test.ts b/test/visits/reducers/domainVisits.test.ts index db52ba06..b7024e0d 100644 --- a/test/visits/reducers/domainVisits.test.ts +++ b/test/visits/reducers/domainVisits.test.ts @@ -197,12 +197,12 @@ describe('domainVisitsReducer', () => { it.each([ [ - [Mock.of({ date: formatISO(subDays(new Date(), 20)) })], + [Mock.of({ date: formatISO(subDays(now, 20)) })], { type: fallbackToIntervalAction.toString(), payload: 'last30Days' }, 3, ], [ - [Mock.of({ date: formatISO(subDays(new Date(), 100)) })], + [Mock.of({ date: formatISO(subDays(now, 100)) })], { type: fallbackToIntervalAction.toString(), payload: 'last180Days' }, 3, ], diff --git a/test/visits/reducers/nonOrphanVisits.test.ts b/test/visits/reducers/nonOrphanVisits.test.ts index e62a6d10..89dc2671 100644 --- a/test/visits/reducers/nonOrphanVisits.test.ts +++ b/test/visits/reducers/nonOrphanVisits.test.ts @@ -177,12 +177,12 @@ describe('nonOrphanVisitsReducer', () => { it.each([ [ - [Mock.of({ date: formatISO(subDays(new Date(), 5)) })], + [Mock.of({ date: formatISO(subDays(now, 5)) })], { type: fallbackToIntervalAction.toString(), payload: 'last7Days' }, 3, ], [ - [Mock.of({ date: formatISO(subDays(new Date(), 200)) })], + [Mock.of({ date: formatISO(subDays(now, 200)) })], { type: fallbackToIntervalAction.toString(), payload: 'last365Days' }, 3, ], diff --git a/test/visits/reducers/orphanVisits.test.ts b/test/visits/reducers/orphanVisits.test.ts index 0b728929..083b7fc4 100644 --- a/test/visits/reducers/orphanVisits.test.ts +++ b/test/visits/reducers/orphanVisits.test.ts @@ -175,12 +175,12 @@ describe('orphanVisitsReducer', () => { it.each([ [ - [Mock.of({ date: formatISO(subDays(new Date(), 5)) })], + [Mock.of({ date: formatISO(subDays(now, 5)) })], { type: fallbackToIntervalAction.toString(), payload: 'last7Days' }, 3, ], [ - [Mock.of({ date: formatISO(subDays(new Date(), 200)) })], + [Mock.of({ date: formatISO(subDays(now, 200)) })], { type: fallbackToIntervalAction.toString(), payload: 'last365Days' }, 3, ], diff --git a/test/visits/reducers/shortUrlVisits.test.ts b/test/visits/reducers/shortUrlVisits.test.ts index 4b65d351..6a2b7452 100644 --- a/test/visits/reducers/shortUrlVisits.test.ts +++ b/test/visits/reducers/shortUrlVisits.test.ts @@ -219,12 +219,12 @@ describe('shortUrlVisitsReducer', () => { it.each([ [ - [Mock.of({ date: formatISO(subDays(new Date(), 5)) })], + [Mock.of({ date: formatISO(subDays(now, 5)) })], { type: fallbackToIntervalAction.toString(), payload: 'last7Days' }, 3, ], [ - [Mock.of({ date: formatISO(subDays(new Date(), 200)) })], + [Mock.of({ date: formatISO(subDays(now, 200)) })], { type: fallbackToIntervalAction.toString(), payload: 'last365Days' }, 3, ], diff --git a/test/visits/reducers/tagVisits.test.ts b/test/visits/reducers/tagVisits.test.ts index fc94e980..c96eca44 100644 --- a/test/visits/reducers/tagVisits.test.ts +++ b/test/visits/reducers/tagVisits.test.ts @@ -193,12 +193,12 @@ describe('tagVisitsReducer', () => { it.each([ [ - [Mock.of({ date: formatISO(subDays(new Date(), 20)) })], + [Mock.of({ date: formatISO(subDays(now, 20)) })], { type: fallbackToIntervalAction.toString(), payload: 'last30Days' }, 3, ], [ - [Mock.of({ date: formatISO(subDays(new Date(), 100)) })], + [Mock.of({ date: formatISO(subDays(now, 100)) })], { type: fallbackToIntervalAction.toString(), payload: 'last180Days' }, 3, ],