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

Commit

Permalink
feat(patients): add visit functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
morrme committed Aug 2, 2020
1 parent 9bff149 commit 5384632
Show file tree
Hide file tree
Showing 30 changed files with 1,349 additions and 5 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@
"eslint": "~6.8.0",
"eslint-config-airbnb": "~18.2.0",
"eslint-config-prettier": "~6.11.0",
"eslint-import-resolver-typescript": "~2.0.0",
"eslint-import-resolver-typescript": "~2.2.0",
"eslint-plugin-import": "~2.22.0",
"eslint-plugin-jest": "~23.18.0",
"eslint-plugin-jest": "~23.20.0",
"eslint-plugin-jsx-a11y": "~6.3.0",
"eslint-plugin-prettier": "~3.1.2",
"eslint-plugin-react": "~7.20.0",
Expand Down
90 changes: 90 additions & 0 deletions src/__tests__/patients/new/DuplicateNewPatientModal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { Modal } from '@hospitalrun/components'
import { act } from '@testing-library/react'
import { mount, ReactWrapper } from 'enzyme'
import React from 'react'
import { Provider } from 'react-redux'
import createMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'

import DuplicateNewPatientModal from '../../../patients/new/DuplicateNewPatientModal'
import { RootState } from '../../../shared/store'

const mockStore = createMockStore<RootState, any>([thunk])

const setupOnClick = (onClose: any, onContinue: any, prop: string) => {
const store = mockStore({
patient: {
patient: {
id: '1234',
},
},
} as any)

const wrapper = mount(
<Provider store={store}>
<DuplicateNewPatientModal
show
toggle={jest.fn()}
onCloseButtonClick={onClose}
onContinueButtonClick={onContinue}
/>
</Provider>,
)
wrapper.update()

act(() => {
const modal = wrapper.find(Modal)
const { onClick } = modal.prop(prop) as any
onClick()
})

return { wrapper: wrapper as ReactWrapper }
}

describe('Duplicate New Patient Modal', () => {
it('should render a modal with the correct labels', () => {
const store = mockStore({
patient: {
patient: {
id: '1234',
},
},
} as any)
const wrapper = mount(
<Provider store={store}>
<DuplicateNewPatientModal
show
toggle={jest.fn()}
onCloseButtonClick={jest.fn()}
onContinueButtonClick={jest.fn()}
/>
</Provider>,
)
wrapper.update()
const modal = wrapper.find(Modal)
expect(modal).toHaveLength(1)
expect(modal.prop('title')).toEqual('patients.newPatient')
expect(modal.prop('closeButton')?.children).toEqual('actions.cancel')
expect(modal.prop('closeButton')?.color).toEqual('danger')
expect(modal.prop('successButton')?.children).toEqual('actions.save')
expect(modal.prop('successButton')?.color).toEqual('success')
})

describe('cancel', () => {
it('should call the onCloseButtonClick function when the close button is clicked', () => {
const onCloseButtonClickSpy = jest.fn()
const closeButtonProp = 'closeButton'
setupOnClick(onCloseButtonClickSpy, jest.fn(), closeButtonProp)
expect(onCloseButtonClickSpy).toHaveBeenCalledTimes(1)
})
})

describe('on save', () => {
it('should call the onContinueButtonClick function when the continue button is clicked', () => {
const onContinueButtonClickSpy = jest.fn()
const continueButtonProp = 'successButton'
setupOnClick(jest.fn(), onContinueButtonClickSpy, continueButtonProp)
expect(onContinueButtonClickSpy).toHaveBeenCalledTimes(1)
})
})
})
18 changes: 18 additions & 0 deletions src/__tests__/patients/new/NewPatient.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,24 @@ describe('New Patient', () => {
expect(store.getActions()).toContainEqual(patientSlice.createPatientSuccess())
})

it('should reveal modal (return true) when save button is clicked if an existing patient has the same information', async () => {
let wrapper: any
await act(async () => {
wrapper = await setup()
})

const saveButton = wrapper.find('.btn-save').at(0)
const onClick = saveButton.prop('onClick') as any
expect(saveButton.text().trim()).toEqual('actions.save')

act(() => {
onClick()
})
wrapper.update()

expect(onClick()).toEqual(true)
})

it('should navigate to /patients/:id and display a message after a new patient is successfully created', async () => {
jest.spyOn(components, 'Toast')
const mockedComponents = mocked(components, true)
Expand Down
24 changes: 24 additions & 0 deletions src/__tests__/patients/util/is-possible-duplicate-patient.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { isPossibleDuplicatePatient } from '../../../patients/util/is-possible-duplicate-patient'
import Patient from '../../../shared/model/Patient'

describe('is possible duplicate patient', () => {
describe('isPossibleDuplicatePatient', () => {
it('should return true when duplicate patients are passed', () => {
const newPatient = {
givenName: 'given',
familyName: 'family',
suffix: 'suffix',
} as Patient

const existingPatient = {
givenName: 'given',
familyName: 'family',
suffix: 'suffix',
} as Patient

const isDuplicatePatient = isPossibleDuplicatePatient(newPatient, existingPatient)

expect(isDuplicatePatient).toEqual(true)
})
})
})
3 changes: 2 additions & 1 deletion src/__tests__/patients/view/ViewPatient.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ describe('ViewPatient', () => {
const tabs = tabsHeader.find(Tab)
expect(tabsHeader).toHaveLength(1)

expect(tabs).toHaveLength(8)
expect(tabs).toHaveLength(9)
expect(tabs.at(0).prop('label')).toEqual('patient.generalInformation')
expect(tabs.at(1).prop('label')).toEqual('patient.relatedPersons.label')
expect(tabs.at(2).prop('label')).toEqual('scheduling.appointments.label')
Expand All @@ -139,6 +139,7 @@ describe('ViewPatient', () => {
expect(tabs.at(5).prop('label')).toEqual('patient.notes.label')
expect(tabs.at(6).prop('label')).toEqual('patient.labs.label')
expect(tabs.at(7).prop('label')).toEqual('patient.carePlan.label')
expect(tabs.at(8).prop('label')).toEqual('patient.visits.label')
})

it('should mark the general information tab as active and render the general information component when route is /patients/:id', async () => {
Expand Down
119 changes: 119 additions & 0 deletions src/__tests__/patients/visits/AddVisitModal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { Modal } from '@hospitalrun/components'
import { mount } from 'enzyme'
import { createMemoryHistory } from 'history'
import React from 'react'
import { act } from 'react-dom/test-utils'
import { Provider } from 'react-redux'
import { Router } from 'react-router-dom'
import createMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'

import * as patientSlice from '../../../patients/patient-slice'
import AddVisitModal from '../../../patients/visits/AddVisitModal'
import VisitForm from '../../../patients/visits/VisitForm'
import PatientRepository from '../../../shared/db/PatientRepository'
import Patient from '../../../shared/model/Patient'
import { VisitStatus } from '../../../shared/model/Visit'
import { RootState } from '../../../shared/store'

const mockStore = createMockStore<RootState, any>([thunk])

describe('Add Visit Modal', () => {
const patient = {
id: 'patientId',
visits: [
{
id: '123',
startDateTime: new Date().toISOString(),
endDateTime: new Date().toISOString(),
type: 'standard type',
status: VisitStatus.Arrived,
reason: 'routine',
location: 'main',
},
],
} as Patient

const visitError = {
title: 'visit error',
}

const onCloseSpy = jest.fn()
const setup = () => {
jest.spyOn(PatientRepository, 'find').mockResolvedValue(patient)
jest.spyOn(PatientRepository, 'saveOrUpdate')
const store = mockStore({ patient: { patient, visitError } } as any)
const history = createMemoryHistory()
const wrapper = mount(
<Provider store={store}>
<Router history={history}>
<AddVisitModal show onCloseButtonClick={onCloseSpy} />
</Router>
</Provider>,
)

wrapper.update()
return { wrapper }
}

it('should render a modal', () => {
const { wrapper } = setup()

const modal = wrapper.find(Modal)

expect(modal).toHaveLength(1)

const successButton = modal.prop('successButton')
const cancelButton = modal.prop('closeButton')
expect(modal.prop('title')).toEqual('patient.visits.new')
expect(successButton?.children).toEqual('patient.visits.new')
expect(successButton?.icon).toEqual('add')
expect(cancelButton?.children).toEqual('actions.cancel')
})

it('should render the visit form', () => {
const { wrapper } = setup()

const visitForm = wrapper.find(VisitForm)
expect(visitForm).toHaveLength(1)
expect(visitForm.prop('visitError')).toEqual(visitError)
})

it('should dispatch add visit when the save button is clicked', async () => {
const { wrapper } = setup()
jest.spyOn(patientSlice, 'addVisit')

act(() => {
const visitForm = wrapper.find(VisitForm)
const onChange = visitForm.prop('onChange') as any
onChange(patient.visits[0])
})
wrapper.update()

await act(async () => {
const modal = wrapper.find(Modal)
const successButton = modal.prop('successButton')
const onClick = successButton?.onClick as any
await onClick()
})

expect(patientSlice.addVisit).toHaveBeenCalledTimes(1)
expect(patientSlice.addVisit).toHaveBeenCalledWith(patient.id, patient.visits[0])
})

it('should call the on close function when the cancel button is clicked', () => {
const { wrapper } = setup()

const modal = wrapper.find(Modal)

expect(modal).toHaveLength(1)

act(() => {
const cancelButton = modal.prop('closeButton')
const onClick = cancelButton?.onClick as any
onClick()
})

expect(onCloseSpy).toHaveBeenCalledTimes(1)
})
})
52 changes: 52 additions & 0 deletions src/__tests__/patients/visits/ViewVisit.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { mount } from 'enzyme'
import { createMemoryHistory } from 'history'
import React from 'react'
import { Provider } from 'react-redux'
import { Route, Router } from 'react-router-dom'
import createMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'

import ViewVisit from '../../../patients/visits/ViewVisit'
import VisitForm from '../../../patients/visits/VisitForm'
import Patient from '../../../shared/model/Patient'
import { RootState } from '../../../shared/store'

const mockStore = createMockStore<RootState, any>([thunk])

describe('View Visit', () => {
const patient = {
id: 'patientId',
visits: [{ id: '123', reason: 'reason for visit' }],
} as Patient

const setup = () => {
const store = mockStore({ patient: { patient }, user: { user: { id: '123' } } } as any)
const history = createMemoryHistory()
history.push(`/patients/${patient.id}/visits/${patient.visits[0].id}`)
const wrapper = mount(
<Provider store={store}>
<Router history={history}>
<Route path="/patients/:id/visits/:visitId">
<ViewVisit />
</Route>
</Router>
</Provider>,
)

return { wrapper }
}

it('should render the visit reason', () => {
const { wrapper } = setup()

expect(wrapper.find('h2').text()).toEqual(patient.visits[0].reason)
})

it('should render a visit form with the correct data', () => {
const { wrapper } = setup()

const visitForm = wrapper.find(VisitForm)
expect(visitForm).toHaveLength(1)
expect(visitForm.prop('visit')).toEqual(patient.visits[0])
})
})
Loading

0 comments on commit 5384632

Please sign in to comment.