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

Commit

Permalink
feat(patients): use patient typeahead to find related person
Browse files Browse the repository at this point in the history
  • Loading branch information
jackcmeyer committed Jan 23, 2020
1 parent bc6fd38 commit 7565b5a
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 237 deletions.
133 changes: 13 additions & 120 deletions src/__tests__/patients/related-persons/NewRelatedPersonModal.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import '../../../__mocks__/matchMediaMock'
import React from 'react'
import { ReactWrapper, mount } from 'enzyme'
import { Modal, Button, Alert } from '@hospitalrun/components'
import { Modal, Alert } from '@hospitalrun/components'
import { act } from '@testing-library/react'
import { Typeahead } from 'react-bootstrap-typeahead'
import NewRelatedPersonModal from '../../../patients/related-persons/NewRelatedPersonModal'
import TextInputWithLabelFormGroup from '../../../components/input/TextInputWithLabelFormGroup'
import TextFieldWithLabelFormGroup from '../../../components/input/TextFieldWithLabelFormGroup'

describe('New Related Person Modal', () => {
describe('layout', () => {
Expand All @@ -27,44 +27,11 @@ describe('New Related Person Modal', () => {
expect(modal.prop('show')).toBeTruthy()
})

it('should render a prefix name text input', () => {
const prefixTextInput = wrapper.findWhere((w) => w.prop('name') === 'prefix')
it('should render a patient search typeahead', () => {
const patientSearchTypeahead = wrapper.find(Typeahead)

expect(prefixTextInput).toHaveLength(1)
expect(prefixTextInput.type()).toBe(TextInputWithLabelFormGroup)
expect(prefixTextInput.prop('name')).toEqual('prefix')
expect(prefixTextInput.prop('isEditable')).toBeTruthy()
expect(prefixTextInput.prop('label')).toEqual('patient.prefix')
})

it('should render a given name text input', () => {
const givenNameTextInput = wrapper.findWhere((w) => w.prop('name') === 'givenName')

expect(givenNameTextInput).toHaveLength(1)
expect(givenNameTextInput.type()).toBe(TextInputWithLabelFormGroup)
expect(givenNameTextInput.prop('name')).toEqual('givenName')
expect(givenNameTextInput.prop('isEditable')).toBeTruthy()
expect(givenNameTextInput.prop('label')).toEqual('patient.givenName')
})

it('should render a family name text input', () => {
const familyNameTextInput = wrapper.findWhere((w) => w.prop('name') === 'familyName')

expect(familyNameTextInput).toHaveLength(1)
expect(familyNameTextInput.type()).toBe(TextInputWithLabelFormGroup)
expect(familyNameTextInput.prop('name')).toEqual('familyName')
expect(familyNameTextInput.prop('isEditable')).toBeTruthy()
expect(familyNameTextInput.prop('label')).toEqual('patient.familyName')
})

it('should render a suffix text input', () => {
const suffixTextInput = wrapper.findWhere((w) => w.prop('name') === 'suffix')

expect(suffixTextInput).toHaveLength(1)
expect(suffixTextInput.type()).toBe(TextInputWithLabelFormGroup)
expect(suffixTextInput.prop('name')).toEqual('suffix')
expect(suffixTextInput.prop('isEditable')).toBeTruthy()
expect(suffixTextInput.prop('label')).toEqual('patient.suffix')
expect(patientSearchTypeahead).toHaveLength(1)
expect(patientSearchTypeahead.prop('placeholder')).toEqual('patient.relatedPerson')
})

it('should render a relationship type text input', () => {
Expand All @@ -79,36 +46,6 @@ describe('New Related Person Modal', () => {
)
})

it('should render a phone number text input', () => {
const phoneNumberTextInput = wrapper.findWhere((w) => w.prop('name') === 'phoneNumber')

expect(phoneNumberTextInput).toHaveLength(1)
expect(phoneNumberTextInput.type()).toBe(TextInputWithLabelFormGroup)
expect(phoneNumberTextInput.prop('name')).toEqual('phoneNumber')
expect(phoneNumberTextInput.prop('isEditable')).toBeTruthy()
expect(phoneNumberTextInput.prop('label')).toEqual('patient.phoneNumber')
})

it('should render a email text input', () => {
const emailTextInput = wrapper.findWhere((w) => w.prop('name') === 'email')

expect(emailTextInput).toHaveLength(1)
expect(emailTextInput.type()).toBe(TextInputWithLabelFormGroup)
expect(emailTextInput.prop('name')).toEqual('email')
expect(emailTextInput.prop('isEditable')).toBeTruthy()
expect(emailTextInput.prop('label')).toEqual('patient.email')
})

it('should render a address text input', () => {
const addressTextField = wrapper.findWhere((w) => w.prop('name') === 'address')

expect(addressTextField).toHaveLength(1)
expect(addressTextField.type()).toBe(TextFieldWithLabelFormGroup)
expect(addressTextField.prop('name')).toEqual('address')
expect(addressTextField.prop('isEditable')).toBeTruthy()
expect(addressTextField.prop('label')).toEqual('patient.address')
})

it('should render a cancel button', () => {
const cancelButton = wrapper.findWhere((w) => w.text() === 'actions.cancel')

Expand Down Expand Up @@ -138,26 +75,8 @@ describe('New Related Person Modal', () => {

it('should call the save function with the correct data', () => {
act(() => {
const prefixTextInput = wrapper.findWhere((w) => w.prop('name') === 'prefix')
prefixTextInput.prop('onChange')({ target: { value: 'prefix' } })
})
wrapper.update()

act(() => {
const givenNameTextInput = wrapper.findWhere((w) => w.prop('name') === 'givenName')
givenNameTextInput.prop('onChange')({ target: { value: 'given' } })
})
wrapper.update()

act(() => {
const familyNameTextInput = wrapper.findWhere((w) => w.prop('name') === 'familyName')
familyNameTextInput.prop('onChange')({ target: { value: 'family' } })
})
wrapper.update()

act(() => {
const suffixTextInput = wrapper.findWhere((w) => w.prop('name') === 'suffix')
suffixTextInput.prop('onChange')({ target: { value: 'suffix' } })
const patientTypeahead = wrapper.find(Typeahead)
patientTypeahead.prop('onChange')([{ id: '123' }])
})
wrapper.update()

Expand All @@ -167,42 +86,16 @@ describe('New Related Person Modal', () => {
})
wrapper.update()

act(() => {
const phoneNumberTextInput = wrapper.findWhere((w) => w.prop('name') === 'phoneNumber')
phoneNumberTextInput.prop('onChange')({ target: { value: 'phone number' } })
})
wrapper.update()

act(() => {
const emailTextInput = wrapper.findWhere((w) => w.prop('name') === 'email')
emailTextInput.prop('onChange')({ target: { value: 'email' } })
})
wrapper.update()

act(() => {
const addressTextField = wrapper.findWhere((w) => w.prop('name') === 'address')
addressTextField.prop('onChange')({ currentTarget: { value: 'address' } })
})
wrapper.update()

const addNewButton = wrapper.findWhere((w) => w.text() === 'patient.relatedPersons.new')
act(() => {
wrapper
.find(Modal)
.prop('successButton')
.onClick({} as React.MouseEvent<HTMLButtonElement, MouseEvent>)
;(wrapper.find(Modal).prop('successButton') as any).onClick(
{} as React.MouseEvent<HTMLButtonElement, MouseEvent>,
)
})

expect(onSaveSpy).toHaveBeenCalledTimes(1)
expect(onSaveSpy).toHaveBeenCalledWith({
prefix: 'prefix',
givenName: 'given',
familyName: 'family',
suffix: 'suffix',
patientId: '123',
type: 'relationship',
phoneNumber: 'phone number',
email: 'email',
address: 'address',
})
})

Expand All @@ -220,7 +113,7 @@ describe('New Related Person Modal', () => {
expect(onSaveSpy).not.toHaveBeenCalled()
expect(errorAlert).toHaveLength(1)
expect(errorAlert.prop('message')).toEqual(
'patient.relatedPersons.error.givenNameRequired patient.relatedPersons.error.relationshipTypeRequired',
'patient.relatedPersons.error.relatedPersonRequired patient.relatedPersons.error.relationshipTypeRequired',
)
})
})
Expand Down
30 changes: 19 additions & 11 deletions src/__tests__/patients/related-persons/RelatedPersons.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import createMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import { Provider } from 'react-redux'
import Permissions from 'model/Permissions'
import { mocked } from 'ts-jest/utils'
import * as patientSlice from '../../../patients/patient-slice'

const mockStore = createMockStore([thunk])
Expand Down Expand Up @@ -80,7 +81,7 @@ describe('Related Persons Tab', () => {
it('should call update patient with the data from the modal', () => {
jest.spyOn(patientSlice, 'updatePatient')
jest.spyOn(PatientRepository, 'saveOrUpdate')
const expectedRelatedPerson = { givenName: 'test', fullName: 'test' }
const expectedRelatedPerson = { patientId: '123', type: 'type' }
const expectedPatient = {
...patient,
relatedPersons: [expectedRelatedPerson],
Expand All @@ -98,7 +99,7 @@ describe('Related Persons Tab', () => {
const newRelatedPersonModal = wrapper.find(NewRelatedPersonModal)

const onSave = newRelatedPersonModal.prop('onSave') as any
onSave({ givenName: 'test' })
onSave(expectedRelatedPerson)
})

wrapper.update()
Expand All @@ -119,7 +120,7 @@ describe('Related Persons Tab', () => {
act(() => {
const newRelatedPersonModal = wrapper.find(NewRelatedPersonModal)
const onSave = newRelatedPersonModal.prop('onSave') as any
onSave({ givenName: 'test' })
onSave({ patientId: '123', type: 'type' })
})

wrapper.update()
Expand All @@ -133,19 +134,26 @@ describe('Related Persons Tab', () => {
const patient = {
id: '123',
rev: '123',
relatedPersons: [{ fullName: 'test' }],
relatedPersons: [{ patientId: '123', type: 'type' }],
} as Patient

const user = {
permissions: [Permissions.WritePatients, Permissions.ReadPatients],
}

beforeEach(() => {
wrapper = mount(
<Provider store={mockStore({ patient, user })}>
<RelatedPersonTab patient={patient} />
</Provider>,
)
beforeEach(async () => {
jest.spyOn(PatientRepository, 'find')
mocked(PatientRepository.find).mockResolvedValue({ fullName: 'test test' } as Patient)

await act(async () => {
wrapper = await mount(
<Provider store={mockStore({ patient, user })}>
<RelatedPersonTab patient={patient} />
</Provider>,
)
})

wrapper.update()
})

it('should render a list of of related persons with their full name being displayed', () => {
Expand All @@ -154,7 +162,7 @@ describe('Related Persons Tab', () => {

expect(list).toHaveLength(1)
expect(listItems).toHaveLength(1)
expect(listItems.at(0).text()).toEqual(patient.relatedPersons[0].fullName)
expect(listItems.at(0).text()).toEqual('test test')
})
})
})
3 changes: 2 additions & 1 deletion src/locales/en-US/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@
"generalInformation": "General Information",
"contactInformation": "Contact Information",
"unknownDateOfBirth": "Unknown",
"relatedPerson": "Related Person",
"relatedPersons": {
"error": {
"givenNameRequired": "Given Name is required.",
"relatedPersonRequired": "Related Person is required.",
"relationshipTypeRequired": "Relationship Type is required."
},
"label": "Related Persons",
Expand Down
2 changes: 1 addition & 1 deletion src/model/Patient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ export default interface Patient extends AbstractDBModel, Name, ContactInformati
occupation?: string
type?: string
friendlyId: string
relatedPersons: RelatedPerson[]
relatedPersons?: RelatedPerson[]
}
6 changes: 2 additions & 4 deletions src/model/RelatedPerson.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import Name from './Name'
import ContactInformation from './ContactInformation'

export default interface RelatedPerson extends Name, ContactInformation {
export default interface RelatedPerson {
patientId: string
type: string
}
2 changes: 2 additions & 0 deletions src/patients/patient-slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ interface PatientState {
isLoading: boolean
isUpdatedSuccessfully: boolean
patient: Patient
relatedPersons: Patient[]
}

const initialState: PatientState = {
isLoading: false,
isUpdatedSuccessfully: false,
patient: {} as Patient,
relatedPersons: [],
}

function startLoading(state: PatientState) {
Expand Down
Loading

0 comments on commit 7565b5a

Please sign in to comment.