Skip to content

Commit

Permalink
Merge pull request #966 from cozy/fix/ver-56
Browse files Browse the repository at this point in the history
feat: Make some fields mandatory for creation
  • Loading branch information
Merkur39 committed Mar 13, 2024
2 parents 7d84e92 + c4d7fe2 commit 504bcc6
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 49 deletions.
46 changes: 35 additions & 11 deletions src/components/ContactCard/ContactForm/index.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import arrayMutators from 'final-form-arrays'
import get from 'lodash/get'
import PropTypes from 'prop-types'
import React from 'react'
import { Form } from 'react-final-form'
Expand Down Expand Up @@ -27,16 +28,32 @@ export function getSubmitContactForm() {
return _submitContactForm
}

const oneOfMandatoryFields = [
'givenName',
'familyName',
'email[0].email',
'cozy'
]

const ContactForm = ({ contact, onSubmit }) => {
const { t } = useI18n()
return (
<Form
mutators={{ ...arrayMutators }}
validate={values => {
const errors = {}
if (oneOfMandatoryFields.every(field => !get(values, field))) {
oneOfMandatoryFields.forEach(field => {
errors[field] = t('fields.required')
})
}
return errors
}}
onSubmit={formValues =>
onSubmit(formValuesToContact({ formValues, oldContact: contact, t }))
}
initialValues={contactToFormValues(contact, t)}
render={({ handleSubmit }) => {
render={({ handleSubmit, valid, submitFailed, errors }) => {
setSubmitContactForm(handleSubmit)
return (
<div>
Expand All @@ -53,16 +70,23 @@ const ContactForm = ({ contact, onSubmit }) => {
name={name}
icon={icon}
isArray={isArray}
renderInput={(inputName, id) => (
<ContactFieldInput
attributes={attributes}
id={id}
name={inputName}
label={t(`fields.${name}`)}
withLabel={hasLabel}
labelPlaceholder={t('fields.label')}
/>
)}
renderInput={(inputName, id) => {
const isOneOfFields =
oneOfMandatoryFields.includes(inputName)
const isError = isOneOfFields && !valid && submitFailed
return (
<ContactFieldInput
attributes={attributes}
error={isError}
helperText={isError ? errors[inputName] : null}
id={id}
name={inputName}
label={t(`fields.${name}`)}
withLabel={hasLabel}
labelPlaceholder={t('fields.label')}
/>
)
}}
/>
)
)}
Expand Down
28 changes: 3 additions & 25 deletions src/components/ContactCard/ContactForm/index.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,30 +192,8 @@ describe('ContactForm', () => {
expect(screen.queryByDisplayValue(testFields['Notes'])).not.toBeNull()
})

it('should submit empty fields', () => {
const expected = {
address: [],
birthday: '',
birthplace: '',
gender: '',
company: '',
cozy: [],
displayName: '',
email: [],
fullname: '',
indexes: { byFamilyNameGivenNameEmailCozyUrl: null },
jobTitle: '',
metadata: { cozy: true, version: 1 },
name: { familyName: '', givenName: '' },
note: '',
phone: [],
relationships: { groups: { data: [] } }
}

let received = null
const onSubmit = contact => {
received = contact
}
it('should not submit empty fields', () => {
const onSubmit = jest.fn()

render(
<AppLike client={client}>
Expand All @@ -227,6 +205,6 @@ describe('ContactForm', () => {
fireEvent.submit(screen.getByRole('form'))
})

expect(received).toEqual(expected)
expect(onSubmit).not.toBeCalled()
})
})
50 changes: 39 additions & 11 deletions src/components/Modals/ContactFormModal.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,48 +57,76 @@ describe('ContactFormModal component', () => {
})
})

it('should pass a new contact to the creation function', async () => {
it('should not call the create function if any of the required fields are missing', async () => {
const formData = {
company: 'Cozy Cloud'
}
useQuery.mockReturnValue({
data: {}
})

useParams.mockReturnValue({
contactId: 'ID'
})

const jsx = (
render(
<AppLike>
<ContactFormModal />
</AppLike>
)

act(() => {
fireEvent.change(screen.getByLabelText('Company'), {
target: { value: formData.company }
})
})
expect(screen.getByLabelText('Company').value).toBe('Cozy Cloud')

act(() => {
fireEvent.click(screen.getByText('Save'))
})

expect(createOrUpdateContact).not.toBeCalled()
})

it('should pass a new contact to the creation function', async () => {
const formData = {
firstname: 'bob'
}
useQuery.mockReturnValue({
data: {}
})
useParams.mockReturnValue({
contactId: 'ID'
})

const expected = {
address: [],
birthday: '',
birthplace: '',
gender: '',
company: 'Cozy Cloud',
company: '',
cozy: [],
displayName: '',
displayName: 'bob',
email: [],
fullname: '',
indexes: { byFamilyNameGivenNameEmailCozyUrl: null },
fullname: 'bob',
indexes: { byFamilyNameGivenNameEmailCozyUrl: 'bob' },
jobTitle: '',
metadata: { cozy: true, version: 1 },
name: { familyName: '', givenName: '' },
name: { familyName: '', givenName: 'bob' },
note: '',
phone: [],
relationships: { groups: { data: [] } }
}

render(jsx)
render(
<AppLike>
<ContactFormModal />
</AppLike>
)

act(() => {
fireEvent.change(screen.getByLabelText('Company'), {
target: { value: formData.company }
fireEvent.change(screen.getByLabelText('Firstname'), {
target: { value: formData.firstname }
})
})

Expand Down
3 changes: 2 additions & 1 deletion src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@
"stairs": "Stairs",
"floor": "Floor",
"apartment": "Apartment",
"entrycode": "Entry code"
"entrycode": "Entry code",
"required": "One of these fields must be filled in"
},
"gender": {
"man": "Man",
Expand Down
3 changes: 2 additions & 1 deletion src/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@
"stairs": "Escalier",
"floor": "Etage",
"apartment": "Appartement",
"entrycode": "Code d'entrée"
"entrycode": "Code d'entrée",
"required": "Un de ces champs doit être renseigné"
},
"gender": {
"man": "Homme",
Expand Down

0 comments on commit 504bcc6

Please sign in to comment.