Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: #2067 Developer Settings profile tab validation #2075

Merged
merged 2 commits into from
Jul 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

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