Skip to content

Commit

Permalink
fix: #2067 Developer Settings profile tab validation (#2075)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cuong Vu authored Jul 17, 2020
1 parent ca548ff commit e1ea44c
Show file tree
Hide file tree
Showing 9 changed files with 617 additions and 315 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,84 +1,72 @@
import React from 'react'
import { shallow } from 'enzyme'
import {
defaultInitialValues,
generateInitialValues,
ContactInformationForm,
ContactInformationFormProps,
mapPropsContactInformation,
EnhanceContactInformationProps,
ContactInformationValues,
handleSubmitContactInformation,
} from '../contact-information-form'
import { mockFormikAction } from '@/utils/mock-formik'
import { developerStub } from '@/sagas/__stubs__/developer'
import appState from '@/reducers/__stubs__/app-state'
import { DeveloperModel } from '@reapit/foundations-ts-definitions'

const developerInfo: DeveloperModel | null = appState.settings.developerInfomation

const valuesMock: ContactInformationValues = {
name: 'name',
jobTitle: 'jobTitle',
telephone: '12341234',
companyName: 'companyName',
}

describe('ContactInformationForm', () => {
it('should match snapshot', () => {
const mockProps = {
isSubmitting: false,
isValidating: false,
isValid: true,
} as ContactInformationFormProps
const wrapper = shallow(<ContactInformationForm {...mockProps} />)
const wrapper = shallow(
<ContactInformationForm developerInformation={developerInfo} updateDeveloperInformation={jest.fn()} />,
)
expect(wrapper).toMatchSnapshot()
})
it('should match snapshot', () => {
const mockProps = {
isSubmitting: true,
isValidating: true,
isValid: false,
} as ContactInformationFormProps
const wrapper = shallow(<ContactInformationForm {...mockProps} />)

it('should match snapshot with developerInfomation = null', () => {
const wrapper = shallow(
<ContactInformationForm developerInformation={null} updateDeveloperInformation={jest.fn()} />,
)
expect(wrapper).toMatchSnapshot()
})
describe('mapPropsContactInformation', () => {
it('should run correctly', () => {
const mockProps: EnhanceContactInformationProps = {
developerInformation: developerStub,
updateDeveloperInformation: jest.fn(),
}
const result = mapPropsContactInformation(mockProps)
const output = {
jobTitle: mockProps.developerInformation?.jobTitle || '',
telephone: mockProps.developerInformation?.telephone || '',
companyName: mockProps.developerInformation?.company || '',
name: mockProps.developerInformation?.name || '',
}
expect(result).toEqual(output)
})
})

it('should return to fall back', () => {
const mockProps: EnhanceContactInformationProps = {
developerInformation: developerStub,
updateDeveloperInformation: jest.fn(),
}
const result = mapPropsContactInformation(mockProps)
const output = {
jobTitle: mockProps.developerInformation?.jobTitle || '',
telephone: mockProps.developerInformation?.telephone || '',
companyName: mockProps.developerInformation?.company || '',
name: mockProps.developerInformation?.name || '',
}
expect(result).toEqual(output)
describe('handleSubmitContactInformation', () => {
it('should run correctly', () => {
const updateDeveloperInformation = jest.fn()
const setSubmitting = jest.fn()
const fn = handleSubmitContactInformation(updateDeveloperInformation)
fn(valuesMock, { setSubmitting } as any)
expect(setSubmitting).toHaveBeenCalledWith(true)
expect(updateDeveloperInformation).toHaveBeenCalledWith(valuesMock)
})
})

describe('generateInitialValues', () => {
it('should return correctly', () => {
const result = generateInitialValues({
developerInfo,
defaultInitialValues,
})
const { name, company: companyName, telephone, jobTitle } = developerInfo as DeveloperModel
const expectedResult = {
name,
companyName,
telephone,
jobTitle,
}
expect(result).toEqual(expectedResult)
})
describe('handleSubmitContactInformation', () => {
it('should call setSubmitting', () => {
const mockValues: ContactInformationValues = {
companyName: 'Reapit Ltd',
name: 'Reapit Ltd',
jobTitle: 'Head of Cloud',
telephone: '01234 567890',
}
const mockForm = {
...mockFormikAction,
}
const mockProps: EnhanceContactInformationProps = {
developerInformation: developerStub,
updateDeveloperInformation: jest.fn(),
}
handleSubmitContactInformation(mockValues, { ...mockForm, props: mockProps })
expect(mockForm.setSubmitting).toBeCalledWith(true)
expect(mockProps.updateDeveloperInformation).toBeCalled()

it('should return correctly with developerInfo null', () => {
const result = generateInitialValues({
developerInfo: null,
defaultInitialValues,
})
expect(result).toEqual(defaultInitialValues)
})
})
Original file line number Diff line number Diff line change
@@ -1,65 +1,22 @@
import React from 'react'
import { compose } from 'redux'
import {
FormSection,
FormHeading,
FormSubHeading,
Input,
Button,
Form,
withFormik,
FormikProps,
FormikBag,
LevelRight,
Grid,
GridItem,
Formik,
FormikHelpers,
} from '@reapit/elements'
import { DeveloperModel } from '@reapit/foundations-ts-definitions'
import { validate } from '@/utils/form/settings-contact-information'
import { validationSchema } from './form-schema/validation-schema'
import { formFieldsContactInfomation } from './form-schema/form-fields'

export type ContactInformationFormProps = FormikProps<ContactInformationValues>

export const ContactInformationForm: React.FC<ContactInformationFormProps> = ({
isSubmitting,
isValidating,
isValid,
}) => {
return (
<FormSection>
<Form>
<FormHeading>Contact Information</FormHeading>
<FormSubHeading>Please use the fields below to edit your contact information</FormSubHeading>
<Grid>
<GridItem>
<Input dataTest="company-name" type="text" labelText="Company Name" id="companyName" name="companyName" />
</GridItem>
<GridItem>
<Input dataTest="name" type="text" labelText="Full Name" id="name" name="name" />
</GridItem>
</Grid>
<Grid>
<GridItem>
<Input dataTest="job-title" type="text" labelText="Job Title" id="jobTitle" name="jobTitle" />
</GridItem>
<GridItem>
<Input dataTest="telephone" type="tel" labelText="Telephone" id="phone" name="telephone" />
</GridItem>
</Grid>
<LevelRight>
<Button
dataTest="save-changes"
disabled={!isValid}
loading={isSubmitting || isValidating}
variant="primary"
type="submit"
>
Save Changes
</Button>
</LevelRight>
</Form>
</FormSection>
)
}
const { nameField, jobTitleField, telephoneField, companyNameField } = formFieldsContactInfomation

export type ContactInformationValues = {
companyName: string
Expand All @@ -68,38 +25,121 @@ export type ContactInformationValues = {
telephone: string
}

export const mapPropsContactInformation = ({ developerInformation }: EnhanceContactInformationProps) => {
export type ContactInformationFormProps = {
developerInformation: DeveloperModel | null
updateDeveloperInformation: (values: ContactInformationValues) => void
}

export const defaultInitialValues: ContactInformationValues = {
name: '',
companyName: '',
telephone: '',
jobTitle: '',
}

export const generateInitialValues = ({
defaultInitialValues,
developerInfo,
}: {
defaultInitialValues: ContactInformationValues
developerInfo: DeveloperModel | null
}): ContactInformationValues => {
if (!developerInfo) {
return defaultInitialValues
}

const { name = '', company: companyName = '', telephone = '', jobTitle = '' } = developerInfo

return {
jobTitle: developerInformation?.jobTitle || '',
telephone: developerInformation?.telephone || '',
companyName: developerInformation?.company || '',
name: developerInformation?.name || '',
name,
companyName,
telephone,
jobTitle,
}
}

export type EnhanceContactInformationProps = {
developerInformation: DeveloperModel | null
updateDeveloperInformation: (values: ContactInformationValues) => void
export const ContactInformationForm: React.FC<ContactInformationFormProps> = ({
developerInformation,
updateDeveloperInformation,
}) => {
const initialValues = generateInitialValues({ defaultInitialValues, developerInfo: developerInformation })

return (
<Formik
validationSchema={validationSchema}
initialValues={initialValues}
onSubmit={handleSubmitContactInformation(updateDeveloperInformation)}
>
{({ isSubmitting, isValidating, isValid }) => {
return (
<FormSection>
<Form>
<FormHeading>Contact Information</FormHeading>
<FormSubHeading>Please use the fields below to edit your contact information</FormSubHeading>
<Grid>
<GridItem>
<Input
dataTest="company-name"
type="text"
labelText={companyNameField.label as string}
id={companyNameField.name}
name={companyNameField.name}
/>
</GridItem>
<GridItem>
<Input
dataTest="name"
type="text"
labelText={nameField.label as string}
id={nameField.name}
name={nameField.name}
/>
</GridItem>
</Grid>
<Grid>
<GridItem>
<Input
dataTest="job-title"
type="text"
labelText={jobTitleField.label as string}
id={jobTitleField.name}
name={jobTitleField.name}
/>
</GridItem>
<GridItem>
<Input
dataTest="telephone"
type="tel"
labelText={telephoneField.label as string}
id={telephoneField.name}
name={telephoneField.name}
/>
</GridItem>
</Grid>
<LevelRight>
<Button
dataTest="save-changes"
disabled={!isValid}
loading={isSubmitting || isValidating}
variant="primary"
type="submit"
>
Save Changes
</Button>
</LevelRight>
</Form>
</FormSection>
)
}}
</Formik>
)
}

export const handleSubmitContactInformation = async (
values: ContactInformationValues,
{ setSubmitting, props }: FormikBag<EnhanceContactInformationProps, ContactInformationValues>,
) => {
export const handleSubmitContactInformation = (
updateDeveloperInformation: (values: ContactInformationValues) => void,
) => (values: ContactInformationValues, { setSubmitting }: FormikHelpers<ContactInformationValues>) => {
setSubmitting(true)
props.updateDeveloperInformation(values)
updateDeveloperInformation(values)
}

export const withContactInformationForm = withFormik({
displayName: 'WithContactInformationForm',
mapPropsToValues: mapPropsContactInformation,
handleSubmit: handleSubmitContactInformation,
validate,
})

const EnhanceContactInformation = compose<React.FC<EnhanceContactInformationProps>>(withContactInformationForm)(
ContactInformationForm,
)
EnhanceContactInformation.displayName = 'EnhanceContactInformation'

export default EnhanceContactInformation
export default ContactInformationForm
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { FormFieldInfo } from '@reapit/elements'

type FieldContactInformation = 'companyNameField' | 'nameField' | 'jobTitleField' | 'telephoneField'

export const formFieldsContactInfomation: Record<FieldContactInformation, FormFieldInfo> = {
companyNameField: {
name: 'companyName',
label: 'Company Name',
errorMessage: 'Company name is not valid',
},
nameField: {
name: 'name',
label: 'Full Name',
errorMessage: 'Full name is not valid',
},
jobTitleField: {
name: 'jobTitle',
label: 'Job Title',
errorMessage: 'Job title is not valid',
},
telephoneField: {
name: 'telephone',
label: 'Telephone',
errorMessage: 'Telephone is not valid',
},
}
Loading

0 comments on commit e1ea44c

Please sign in to comment.