Skip to content

Commit

Permalink
fix: Myinfo Child DOB (#6648)
Browse files Browse the repository at this point in the history
* ref: shift MYINFO_DATE_FORMAT const to DateField

* feat: parse and format myinfo DOB

* fix: change dateFormat of ChildDateOfBirth

* fix: add space to CHILD_PREFIX

* fix: undo date formatting

* fix: change date format

* fix: add validation to backend

* fix: move date constants to shared

* ref: use shared formatMyinfoDate function

* test: use correct import

* fix: remove unused imports

* docs: add explanation

* ref: use const for myInfoFormattedValue
  • Loading branch information
wanlingt committed Aug 29, 2023
1 parent 4d453b7 commit e34c951
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 33 deletions.
12 changes: 2 additions & 10 deletions frontend/src/features/myinfo/utils/extractPreviewValue.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import { format, parse } from 'date-fns'

import { BasicField, MyInfoPrefilledFormField } from '~shared/types'

import { DATE_PARSE_FORMAT } from '~templates/Field/Date/DateField'
import { formatMyinfoDate } from '~shared/utils/dates'

type PrefilledMyInfoValue = string | { value: string }

const MYINFO_DATE_FORMAT = 'yyyy-MM-dd'

export const extractPreviewValue = ({
fieldType,
fieldValue,
Expand All @@ -21,10 +16,7 @@ export const extractPreviewValue = ({
value: fieldValue,
}
case BasicField.Date:
return format(
parse(fieldValue, MYINFO_DATE_FORMAT, new Date()),
DATE_PARSE_FORMAT,
)
return formatMyinfoDate(fieldValue)
default:
return fieldValue
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { format, parse } from 'date-fns'
import { times } from 'lodash'

import { DATE_PARSE_FORMAT } from '~shared/constants/dates'
import { BasicField, FormFieldDto } from '~shared/types/field'
import {
AttachmentResponse,
Expand All @@ -15,7 +16,6 @@ import {
import { removeAt } from '~shared/utils/immutable-array-fns'

import { CHECKBOX_OTHERS_INPUT_VALUE } from '~templates/Field/Checkbox/CheckboxField'
import { DATE_PARSE_FORMAT } from '~templates/Field/Date/DateField'
import { RADIO_OTHERS_INPUT_VALUE } from '~templates/Field/Radio/RadioField'
import { createTableRow } from '~templates/Field/Table/utils/createRow'
import {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import {
} from '@chakra-ui/react'
import simplur from 'simplur'

import {
ChildrenCompoundFieldInputs,
ChildrenCompoundFieldSchema,
DATE_DISPLAY_FORMAT,
} from '~shared/constants/dates'
import { MYINFO_ATTRIBUTE_MAP } from '~shared/constants/field/myinfo'
import {
FormColorTheme,
Expand All @@ -30,6 +35,7 @@ import {
MyInfoChildData,
MyInfoChildVaxxStatus,
} from '~shared/types'
import { formatMyinfoDate } from '~shared/utils/dates'

import { createChildrenValidationRules } from '~utils/fieldValidation'
import { Button } from '~components/Button/Button'
Expand All @@ -39,10 +45,6 @@ import { FormLabel } from '~components/FormControl/FormLabel/FormLabel'
import { IconButton } from '~components/IconButton/IconButton'

import { BaseFieldProps, FieldContainer } from '../FieldContainer'
import {
ChildrenCompoundFieldInputs,
ChildrenCompoundFieldSchema,
} from '../types'

export interface ChildrenCompoundFieldProps extends BaseFieldProps {
schema: ChildrenCompoundFieldSchema
Expand Down Expand Up @@ -324,12 +326,20 @@ const ChildrenBody = ({
const key = `${field.id}+${index}`
const fieldPath = `${schema._id}.child.${currChildBodyIdx}.${index}`
const myInfoValue = getChildAttr(subField)

// We want to format the date by converting the value from a myinfo format to
// a format used by our date fields
const myInfoFormattedValue =
subField === MyInfoChildAttributes.ChildDateOfBirth && myInfoValue
? formatMyinfoDate(myInfoValue)
: myInfoValue

const value = watch(fieldPath) as unknown as string
if (myInfoValue && value !== myInfoValue) {
if (myInfoFormattedValue && value !== myInfoFormattedValue) {
// We need to do this as the underlying data is not updated
// by the field's value, but rather by onChange, which we did
// not trigger via prefill.
setValue(fieldPath, myInfoValue)
setValue(fieldPath, myInfoFormattedValue)
}
const isDisabled = isSubmitting || !!myInfoValue
switch (subField) {
Expand Down Expand Up @@ -379,9 +389,8 @@ const ChildrenBody = ({
</FormLabel>
<DatePicker
{...rest}
dateFormat="yyyy/MM/dd"
// Convert MyInfo YYYY-MM-DD to YYYY/MM/DD
inputValue={value?.replaceAll('-', '/')}
displayFormat={DATE_DISPLAY_FORMAT}
inputValue={value}
onInputValueChange={(date) => {
setValue(fieldPath, date)
}}
Expand Down
7 changes: 2 additions & 5 deletions frontend/src/templates/Field/Date/DateField.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Text } from '@chakra-ui/react'
import { Meta, Story } from '@storybook/react'
import { addDays, lightFormat, parse } from 'date-fns'

import { DATE_DISPLAY_FORMAT } from '~shared/constants/dates'
import {
BasicField,
DateSelectedValidation,
Expand All @@ -15,11 +16,7 @@ import Button from '~components/Button'

import { DateFieldSchema } from '../types'

import {
DATE_DISPLAY_FORMAT,
DateField as DateFieldComponent,
DateFieldProps,
} from './DateField'
import { DateField as DateFieldComponent, DateFieldProps } from './DateField'

const MOCKED_TODAY_DATE_STRING = '13/12/2021'
const MOCKED_TODAY_DATE = parse(
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/templates/Field/Date/DateField.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { act, render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { addDays, isBefore, lightFormat } from 'date-fns'

import { DATE_DISPLAY_FORMAT } from '~shared/constants/dates'

import { REQUIRED_ERROR } from '~constants/validation'

import { DATE_DISPLAY_FORMAT } from './DateField'
import * as stories from './DateField.stories'

const {
Expand Down
4 changes: 1 addition & 3 deletions frontend/src/templates/Field/Date/DateField.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useCallback, useMemo } from 'react'
import { Controller, useFormContext } from 'react-hook-form'

import { DATE_DISPLAY_FORMAT, DATE_PARSE_FORMAT } from '~shared/constants/dates'
import { FormColorTheme } from '~shared/types'
import { DateSelectedValidation } from '~shared/types/field'
import { isDateAnInvalidDay } from '~shared/utils/date-validation'
Expand All @@ -17,9 +18,6 @@ import { DatePicker } from '~components/DatePicker'
import { BaseFieldProps, FieldContainer } from '../FieldContainer'
import { DateFieldSchema, SingleAnswerFieldInput } from '../types'

export const DATE_DISPLAY_FORMAT = 'dd/MM/yyyy'
export const DATE_PARSE_FORMAT = 'dd/MM/yyyy'

export interface DateFieldProps extends BaseFieldProps {
schema: DateFieldSchema
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/utils/fieldValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { identity } from 'lodash'
import simplur from 'simplur'
import validator from 'validator'

import { DATE_PARSE_FORMAT } from '~shared/constants/dates'
import {
AttachmentFieldBase,
BasicField,
Expand Down Expand Up @@ -46,7 +47,6 @@ import {
INVALID_EMAIL_ERROR,
REQUIRED_ERROR,
} from '~constants/validation'
import { DATE_PARSE_FORMAT } from '~templates/Field/Date/DateField'
import {
CheckboxFieldValues,
SingleAnswerValue,
Expand Down
3 changes: 3 additions & 0 deletions shared/constants/dates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const DATE_DISPLAY_FORMAT = 'dd/MM/yyyy'
export const DATE_PARSE_FORMAT = 'dd/MM/yyyy'
export const MYINFO_DATE_FORMAT = 'yyyy-MM-dd'
1 change: 1 addition & 0 deletions shared/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './file'
export * from './form'
export * from './links'
export * from './feature-flags'
export * from './dates'
6 changes: 6 additions & 0 deletions shared/utils/dates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { format, parse } from 'date-fns'
import { MYINFO_DATE_FORMAT, DATE_PARSE_FORMAT } from '../constants'

export const formatMyinfoDate = (value: string) => {
return format(parse(value, MYINFO_DATE_FORMAT, new Date()), DATE_PARSE_FORMAT)
}
12 changes: 11 additions & 1 deletion src/app/modules/myinfo/myinfo.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
MyInfoChildData,
MyInfoChildVaxxStatus,
} from '../../../../shared/types'
import { formatMyinfoDate } from '../../../../shared/utils/dates'
import { hasProp } from '../../../../shared/utils/has-prop'
import {
IFieldSchema,
Expand Down Expand Up @@ -79,7 +80,9 @@ function hashChildrenFieldValues(
const subFields = getMyInfoAttr(field) as MyInfoChildAttributes[]
subFields.forEach((subField) => {
const fieldArr = childrenBirthRecords[subField]
let myInfoFormattedValue: string
fieldArr?.forEach((value, childIdx) => {
myInfoFormattedValue = value
const childName =
childrenBirthRecords?.[MyInfoChildAttributes.ChildName]?.[childIdx]
if (childName === undefined) {
Expand All @@ -95,9 +98,16 @@ function hashChildrenFieldValues(
if (!value) {
return
}
// Child's DOB is processed different from non-child Myinfo dates
// We have to return value in the the same date format as the frontend
// Hence we format it here
if (subField === MyInfoChildAttributes.ChildDateOfBirth) {
myInfoFormattedValue = formatMyinfoDate(value)
return
}
readOnlyHashPromises[
getMyInfoChildHashKey(field._id, subField, childIdx, childName)
] = bcrypt.hash(value, HASH_SALT_ROUNDS)
] = bcrypt.hash(myInfoFormattedValue, HASH_SALT_ROUNDS)
})
})
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Prefixes in response emails
// Prefixes in response emails, a space is included after the [field] for formatting
export const MYINFO_PREFIX = '[MyInfo] '
export const VERIFIED_PREFIX = '[verified] '
export const TABLE_PREFIX = '[table] '
export const ATTACHMENT_PREFIX = '[attachment] '
export const CHILD_PREFIX = '[child]'
export const CHILD_PREFIX = '[child] '

// Parameters for hashing submissions
export const SALT_LENGTH = 32
Expand Down

0 comments on commit e34c951

Please sign in to comment.