Skip to content

Commit

Permalink
Handle validation for YYYY-MM-DD format
Browse files Browse the repository at this point in the history
  • Loading branch information
lpsinger committed Sep 3, 2024
1 parent 5b9182c commit 821c09b
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 30 deletions.
12 changes: 10 additions & 2 deletions src/components/forms/DatePicker/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,12 @@ export const DatePicker = ({
const parsedRangeDate = rangeDate ? parseDateString(rangeDate) : undefined

const validateInput = (): void => {
const isInvalid = isDateInvalid(externalValue, parsedMinDate, parsedMaxDate)
const isInvalid = isDateInvalid(
externalValue,
dateFormat,
parsedMinDate,
parsedMaxDate
)

if (isInvalid && !externalInputEl?.current?.validationMessage) {
externalInputEl?.current?.setCustomValidity(VALIDATION_MESSAGE)
Expand Down Expand Up @@ -134,7 +139,10 @@ export const DatePicker = ({

const inputDate = parseDateString(value, dateFormat, true)
let newValue = ''
if (inputDate && !isDateInvalid(value, parsedMinDate, parsedMaxDate)) {
if (
inputDate &&
!isDateInvalid(value, dateFormat, parsedMinDate, parsedMaxDate)
) {
newValue = formatDate(inputDate)
}

Expand Down
79 changes: 54 additions & 25 deletions src/components/forms/DatePicker/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,34 +81,63 @@ describe('formatDate', () => {
})

describe('isDateInvalid', () => {
it('returns false if the date is within the min & max', () => {
const testMin = new Date('May 1, 1988')
const testMax = new Date('June 1, 1988')
expect(isDateInvalid('05/16/1988', testMin, testMax)).toEqual(false)
})

it('returns true if the date is not within the min & max', () => {
const testMin = new Date('May 1, 1988')
const testMax = new Date('June 1, 1988')
expect(isDateInvalid('08/16/1988', testMin, testMax)).toEqual(true)
})

it('returns true if the date is not valid', () => {
const testMin = new Date('May 1, 1988')
const testMax = new Date('June 1, 1988')
expect(isDateInvalid('not a date', testMin, testMax)).toEqual(true)
})
it.each([
['05/16/1988', DEFAULT_EXTERNAL_DATE_FORMAT],
['1988-05-16', INTERNAL_DATE_FORMAT],
] as const)(
'returns false if the date is within the min & max',
(date, format) => {
const testMin = new Date('May 1, 1988')
const testMax = new Date('June 1, 1988')
expect(isDateInvalid(date, format, testMin, testMax)).toEqual(false)
}
)

it.each([
['08/16/1988', DEFAULT_EXTERNAL_DATE_FORMAT],
['1988-08-16', INTERNAL_DATE_FORMAT],
] as const)(
'returns true if the date is not within the min & max',
(date, format) => {
const testMin = new Date('May 1, 1988')
const testMax = new Date('June 1, 1988')
expect(isDateInvalid(date, format, testMin, testMax)).toEqual(true)
}
)

it.each([DEFAULT_EXTERNAL_DATE_FORMAT, INTERNAL_DATE_FORMAT] as const)(
'returns true if the date is not valid',
(format) => {
const testMin = new Date('May 1, 1988')
const testMax = new Date('June 1, 1988')
expect(isDateInvalid('not a date', format, testMin, testMax)).toEqual(
true
)
}
)

describe('with no max date', () => {
it('returns false if the date is after the min', () => {
const testMin = new Date('May 1, 1988')
expect(isDateInvalid('05/16/1988', testMin)).toEqual(false)
})
it.each([
['05/16/1988', DEFAULT_EXTERNAL_DATE_FORMAT],
['1988-05-16', INTERNAL_DATE_FORMAT],
] as const)(
'returns false if the date is after the min',
(date, format) => {
const testMin = new Date('May 1, 1988')
expect(isDateInvalid(date, format, testMin)).toEqual(false)
}
)

it('returns true if the date is not after the min', () => {
const testMin = new Date('May 1, 1988')
expect(isDateInvalid('02/16/1988', testMin)).toEqual(true)
})
it.each([
['02/16/1988', DEFAULT_EXTERNAL_DATE_FORMAT],
['1988-02-16', INTERNAL_DATE_FORMAT],
] as const)(
'returns true if the date is not after the min',
(date, format) => {
const testMin = new Date('May 1, 1988')
expect(isDateInvalid(date, format, testMin)).toEqual(true)
}
)
})
})

Expand Down
18 changes: 15 additions & 3 deletions src/components/forms/DatePicker/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ export const formatDate = (

export const isDateInvalid = (
dateString: string,
dateFormat: DateFormat,
minDate: Date,
maxDate?: Date
): boolean => {
Expand All @@ -468,22 +469,33 @@ export const isDateInvalid = (
if (dateString) {
isInvalid = true

const dateStringParts = dateString.split('/')
const [month, day, year] = dateStringParts.map((str) => {
const dateStringParts = dateString.split(
dateFormat === DEFAULT_EXTERNAL_DATE_FORMAT ? '/' : '-'
)
const dateParts = dateStringParts.map((str) => {
let value
const parsed = parseInt(str, 10)
if (!Number.isNaN(parsed)) value = parsed
return value
})

let month, day, year, yearStringPart
if (dateFormat === DEFAULT_EXTERNAL_DATE_FORMAT) {
yearStringPart = dateStringParts[2]
;[month, day, year] = dateParts
} else {
yearStringPart = dateStringParts[0]
;[year, month, day] = dateParts
}

if (month && day && year != null) {
const checkDate = setDate(year, month - 1, day)

if (
checkDate.getMonth() === month - 1 &&
checkDate.getDate() === day &&
checkDate.getFullYear() === year &&
dateStringParts[2].length === 4 &&
yearStringPart.length === 4 &&
isDateWithinMinAndMax(checkDate, minDate, maxDate)
) {
isInvalid = false
Expand Down

0 comments on commit 821c09b

Please sign in to comment.