Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

Commit

Permalink
feat(edit patient): implement Edit Patient functionality
Browse files Browse the repository at this point in the history
1765
  • Loading branch information
MatthewDorner committed Feb 6, 2020
1 parent f15c238 commit 8e3355f
Show file tree
Hide file tree
Showing 18 changed files with 391 additions and 331 deletions.
10 changes: 10 additions & 0 deletions src/HospitalRun.tsx
Expand Up @@ -9,6 +9,7 @@ import Permissions from './model/Permissions'
import Dashboard from './dashboard/Dashboard'
import Patients from './patients/list/Patients'
import NewPatient from './patients/new/NewPatient'
import EditPatient from './patients/edit/EditPatient'
import ViewPatient from './patients/view/ViewPatient'
import { RootState } from './store'
import Navbar from './components/Navbar'
Expand Down Expand Up @@ -42,6 +43,15 @@ const HospitalRun = () => {
path="/patients/new"
component={NewPatient}
/>
<PrivateRoute
isAuthenticated={
permissions.includes(Permissions.WritePatients) &&
permissions.includes(Permissions.ReadPatients)
}
exact
path="/patients/edit/:id"
component={EditPatient}
/>
<PrivateRoute
isAuthenticated={permissions.includes(Permissions.ReadPatients)}
path="/patients/:id"
Expand Down
119 changes: 119 additions & 0 deletions src/__tests__/patients/GeneralInformation.test.tsx
@@ -0,0 +1,119 @@
import '../../__mocks__/matchMediaMock'
import React from 'react'
import { Router } from 'react-router'
import { mount, ReactWrapper } from 'enzyme'
import { act } from 'react-dom/test-utils'
import GeneralInformation from 'patients/GeneralInformation'
import { createMemoryHistory } from 'history'
import Patient from '../../model/Patient'

describe('General Information', () => {
const patient = {
id: '123',
prefix: 'prefix',
givenName: 'givenName',
familyName: 'familyName',
suffix: 'suffix',
sex: 'male',
type: 'charity',
occupation: 'occupation',
preferredLanguage: 'preferredLanguage',
phoneNumber: 'phoneNumber',
email: 'email@email.com',
address: 'address',
friendlyId: 'P00001',
dateOfBirth: new Date().toISOString(),
isApproximateDateOfBirth: false,
} as Patient

let wrapper: ReactWrapper
let history = createMemoryHistory()

beforeEach(() => {
history = createMemoryHistory()
wrapper = mount(
<Router history={history}>
<GeneralInformation patient={patient} />)
</Router>,
)
})

beforeEach(() => {
jest.restoreAllMocks()
})

it('should render the sex select', () => {
const sexSelect = wrapper.findWhere((w: any) => w.prop('name') === 'sex')
expect(sexSelect.prop('value')).toEqual(patient.sex)
expect(sexSelect.prop('label')).toEqual('patient.sex')
expect(sexSelect.prop('isEditable')).toBeFalsy()
})

it('should render the patient type select', () => {
const typeSelect = wrapper.findWhere((w: any) => w.prop('name') === 'type')
expect(typeSelect.prop('value')).toEqual(patient.type)
expect(typeSelect.prop('label')).toEqual('patient.type')
expect(typeSelect.prop('isEditable')).toBeFalsy()
})

it('should render the date of the birth of the patient', () => {
const dateOfBirthInput = wrapper.findWhere((w: any) => w.prop('name') === 'dateOfBirth')
expect(dateOfBirthInput.prop('value')).toEqual(new Date(patient.dateOfBirth))
expect(dateOfBirthInput.prop('label')).toEqual('patient.dateOfBirth')
expect(dateOfBirthInput.prop('isEditable')).toBeFalsy()
})

it('should render the occupation of the patient', () => {
const dateOfBirthInput = wrapper.findWhere((w: any) => w.prop('name') === 'occupation')
expect(dateOfBirthInput.prop('value')).toEqual(patient.occupation)
expect(dateOfBirthInput.prop('label')).toEqual('patient.occupation')
expect(dateOfBirthInput.prop('isEditable')).toBeFalsy()
})

it('should render the preferred language of the patient', () => {
const dateOfBirthInput = wrapper.findWhere((w: any) => w.prop('name') === 'preferredLanguage')
expect(dateOfBirthInput.prop('value')).toEqual(patient.preferredLanguage)
expect(dateOfBirthInput.prop('label')).toEqual('patient.preferredLanguage')
expect(dateOfBirthInput.prop('isEditable')).toBeFalsy()
})

it('should render the phone number of the patient', () => {
const dateOfBirthInput = wrapper.findWhere((w: any) => w.prop('name') === 'phoneNumber')
expect(dateOfBirthInput.prop('value')).toEqual(patient.phoneNumber)
expect(dateOfBirthInput.prop('label')).toEqual('patient.phoneNumber')
expect(dateOfBirthInput.prop('isEditable')).toBeFalsy()
})

it('should render the email of the patient', () => {
const dateOfBirthInput = wrapper.findWhere((w: any) => w.prop('name') === 'email')
expect(dateOfBirthInput.prop('value')).toEqual(patient.email)
expect(dateOfBirthInput.prop('label')).toEqual('patient.email')
expect(dateOfBirthInput.prop('isEditable')).toBeFalsy()
})

it('should render the address of the patient', () => {
const dateOfBirthInput = wrapper.findWhere((w: any) => w.prop('name') === 'address')
expect(dateOfBirthInput.prop('value')).toEqual(patient.address)
expect(dateOfBirthInput.prop('label')).toEqual('patient.address')
expect(dateOfBirthInput.prop('isEditable')).toBeFalsy()
})

it('should render the age and date of birth as approximate if patient.isApproximateDateOfBirth is true', async () => {
let wrapper: any
patient.isApproximateDateOfBirth = true
await act(async () => {
wrapper = await mount(
<Router history={history}>
<GeneralInformation patient={patient} />)
</Router>,
)
})

wrapper.update()

const ageInput = wrapper.findWhere((w: any) => w.prop('name') === 'approximateAge')
expect(ageInput.prop('value')).toEqual('0')
expect(ageInput.prop('label')).toEqual('patient.approximateAge')
expect(ageInput.prop('isEditable')).toBeFalsy()
})
})
13 changes: 6 additions & 7 deletions src/clients/db/Repository.ts
Expand Up @@ -39,11 +39,11 @@ export default class Repository<T extends AbstractDBModel> {
}

async findAll(): Promise<T[]> {
const allPatients = await this.db.allDocs({
const allDocs = await this.db.allDocs({
include_docs: true,
})

return allPatients.rows.map(mapRow)
return allDocs.rows.map(mapRow)
}

async save(entity: T): Promise<T> {
Expand All @@ -57,16 +57,15 @@ export default class Repository<T extends AbstractDBModel> {
return this.save(entity)
}

const { id, rev, ...dataToSave } = entity

try {
await this.find(entity.id)
const existingEntity = await this.find(entity.id)
const { id, rev, ...restOfDoc } = existingEntity
const entityToUpdate = {
_id: id,
_rev: rev,
...dataToSave,
...restOfDoc,
...entity,
}

await this.db.put(entityToUpdate)
return this.find(entity.id)
} catch (error) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/input/DatePickerWithLabelFormGroup.tsx
Expand Up @@ -5,7 +5,7 @@ interface Props {
name: string
label: string
value: Date | undefined
isEditable: boolean
isEditable?: boolean
onChange?: (date: Date) => void
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/input/DateTimePickerWithLabelFormGroup.tsx
Expand Up @@ -5,7 +5,7 @@ interface Props {
name: string
label: string
value: Date | undefined
isEditable: boolean
isEditable?: boolean
onChange?: (date: Date) => void
}

Expand Down
3 changes: 1 addition & 2 deletions src/components/input/SelectWithLableFormGroup.tsx
Expand Up @@ -10,7 +10,7 @@ interface Props {
value: string
label: string
name: string
isEditable: boolean
isEditable?: boolean
options: Option[]
onChange?: (event: React.ChangeEvent<HTMLSelectElement>) => void
}
Expand All @@ -37,7 +37,6 @@ const SelectWithLabelFormGroup = (props: Props) => {

SelectWithLabelFormGroup.defaultProps = {
value: '',
isEditable: true,
}

export default SelectWithLabelFormGroup
6 changes: 1 addition & 5 deletions src/components/input/TextFieldWithLabelFormGroup.tsx
Expand Up @@ -5,7 +5,7 @@ interface Props {
value: string
label: string
name: string
isEditable: boolean
isEditable?: boolean
placeholder?: string
onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>) => void
}
Expand All @@ -21,10 +21,6 @@ const TextFieldWithLabelFormGroup = (props: Props) => {
)
}

TextFieldWithLabelFormGroup.defaultProps = {
isEditable: true,
}

TextFieldWithLabelFormGroup.defaultProps = {
value: '',
}
Expand Down
3 changes: 1 addition & 2 deletions src/components/input/TextInputWithLabelFormGroup.tsx
Expand Up @@ -5,7 +5,7 @@ interface Props {
value: string
label: string
name: string
isEditable: boolean
isEditable?: boolean
type: 'text' | 'email' | 'number'
placeholder?: string
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void
Expand All @@ -31,7 +31,6 @@ const TextInputWithLabelFormGroup = (props: Props) => {

TextInputWithLabelFormGroup.defaultProps = {
value: '',
isEditable: true,
type: 'text',
}

Expand Down
4 changes: 3 additions & 1 deletion src/locales/en-US/translation.json
Expand Up @@ -7,7 +7,9 @@
"viewPatients": "View Patients",
"viewPatient": "View Patient",
"newPatient": "New Patient",
"successfullyCreated": "Successfully created patient"
"editPatient": "Edit Patient",
"successfullyCreated": "Successfully created patient",
"successfullyUpdated": "Successfully updated patient"
},
"patient": {
"suffix": "Suffix",
Expand Down

0 comments on commit 8e3355f

Please sign in to comment.