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

Commit

Permalink
refactor(appointment): Appointment slice redux refactor (#2051)
Browse files Browse the repository at this point in the history
  • Loading branch information
MatthewDorner committed May 6, 2020
1 parent e208ca6 commit adcad7b
Show file tree
Hide file tree
Showing 26 changed files with 697 additions and 613 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"private": false,
"license": "MIT",
"dependencies": {
"@hospitalrun/components": "^1.4.0",
"@hospitalrun/components": "^1.5.0",
"@reduxjs/toolkit": "~1.3.0",
"@types/escape-string-regexp": "~2.0.1",
"@types/pouchdb-find": "~6.3.4",
Expand Down
36 changes: 2 additions & 34 deletions src/HospitalRun.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,20 @@ import React from 'react'
import { Switch, Route } from 'react-router-dom'
import { useSelector } from 'react-redux'
import { Toaster } from '@hospitalrun/components'
import Appointments from 'scheduling/appointments/Appointments'
import NewAppointment from 'scheduling/appointments/new/NewAppointment'
import EditAppointment from 'scheduling/appointments/edit/EditAppointment'
import ViewAppointment from 'scheduling/appointments/view/ViewAppointment'
import Breadcrumbs from 'breadcrumbs/Breadcrumbs'
import { ButtonBarProvider } from 'page-header/ButtonBarProvider'
import ButtonToolBar from 'page-header/ButtonToolBar'
import Labs from 'labs/Labs'
import Sidebar from './components/Sidebar'
import Permissions from './model/Permissions'
import Dashboard from './dashboard/Dashboard'
import { RootState } from './store'
import Navbar from './components/Navbar'
import PrivateRoute from './components/PrivateRoute'
import Patients from './patients/Patients'
import Appointments from './scheduling/appointments/Appointments'

const HospitalRun = () => {
const { title } = useSelector((state: RootState) => state.title)
const { permissions } = useSelector((state: RootState) => state.user)
const { sidebarCollapsed } = useSelector((state: RootState) => state.components)

return (
Expand All @@ -44,34 +39,7 @@ const HospitalRun = () => {
<div>
<Switch>
<Route exact path="/" component={Dashboard} />

<PrivateRoute
isAuthenticated={permissions.includes(Permissions.ReadAppointments)}
exact
path="/appointments"
component={Appointments}
/>
<PrivateRoute
isAuthenticated={permissions.includes(Permissions.WriteAppointments)}
exact
path="/appointments/new"
component={NewAppointment}
/>
<PrivateRoute
isAuthenticated={
permissions.includes(Permissions.WriteAppointments) &&
permissions.includes(Permissions.ReadAppointments)
}
exact
path="/appointments/edit/:id"
component={EditAppointment}
/>
<PrivateRoute
isAuthenticated={permissions.includes(Permissions.ReadAppointments)}
exact
path="/appointments/:id"
component={ViewAppointment}
/>
<PrivateRoute isAuthenticated path="/appointments" component={Appointments} />
<PrivateRoute isAuthenticated path="/patients" component={Patients} />
<PrivateRoute isAuthenticated path="/labs" component={Labs} />
</Switch>
Expand Down
193 changes: 0 additions & 193 deletions src/__tests__/HospitalRun.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,208 +8,15 @@ import configureMockStore from 'redux-mock-store'
import { Toaster } from '@hospitalrun/components'
import { act } from 'react-dom/test-utils'
import Dashboard from 'dashboard/Dashboard'
import Appointments from 'scheduling/appointments/Appointments'
import NewAppointment from 'scheduling/appointments/new/NewAppointment'
import EditAppointment from 'scheduling/appointments/edit/EditAppointment'
import { addBreadcrumbs } from 'breadcrumbs/breadcrumbs-slice'
import ViewLabs from 'labs/ViewLabs'
import LabRepository from 'clients/db/LabRepository'
import PatientRepository from '../clients/db/PatientRepository'
import AppointmentRepository from '../clients/db/AppointmentRepository'
import Patient from '../model/Patient'
import Appointment from '../model/Appointment'
import HospitalRun from '../HospitalRun'
import Permissions from '../model/Permissions'

const mockStore = configureMockStore([thunk])

describe('HospitalRun', () => {
describe('routing', () => {
describe('/appointments', () => {
it('should render the appointments screen when /appointments is accessed', async () => {
const store = mockStore({
title: 'test',
user: { permissions: [Permissions.ReadAppointments] },
appointments: { appointments: [] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
})

const wrapper = mount(
<Provider store={store}>
<MemoryRouter initialEntries={['/appointments']}>
<HospitalRun />
</MemoryRouter>
</Provider>,
)

await act(async () => {
wrapper.update()
})

expect(wrapper.find(Appointments)).toHaveLength(1)

expect(store.getActions()).toContainEqual(
addBreadcrumbs([
{ i18nKey: 'scheduling.appointments.label', location: '/appointments' },
{ i18nKey: 'dashboard.label', location: '/' },
]),
)
})

it('should render the Dashboard when the user does not have read appointment privileges', () => {
const wrapper = mount(
<Provider
store={mockStore({
title: 'test',
user: { permissions: [] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
})}
>
<MemoryRouter initialEntries={['/appointments']}>
<HospitalRun />
</MemoryRouter>
</Provider>,
)

expect(wrapper.find(Dashboard)).toHaveLength(1)
})
})

describe('/appointments/new', () => {
it('should render the new appointment screen when /appointments/new is accessed', async () => {
const store = mockStore({
title: 'test',
user: { permissions: [Permissions.WriteAppointments] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
})

const wrapper = mount(
<Provider store={store}>
<MemoryRouter initialEntries={['/appointments/new']}>
<HospitalRun />
</MemoryRouter>
</Provider>,
)

wrapper.update()

expect(wrapper.find(NewAppointment)).toHaveLength(1)
expect(store.getActions()).toContainEqual(
addBreadcrumbs([
{ i18nKey: 'scheduling.appointments.label', location: '/appointments' },
{ i18nKey: 'scheduling.appointments.new', location: '/appointments/new' },
{ i18nKey: 'dashboard.label', location: '/' },
]),
)
})

it('should render the Dashboard when the user does not have read appointment privileges', () => {
const wrapper = mount(
<Provider
store={mockStore({
title: 'test',
user: { permissions: [] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
})}
>
<MemoryRouter initialEntries={['/appointments/new']}>
<HospitalRun />
</MemoryRouter>
</Provider>,
)

expect(wrapper.find(Dashboard)).toHaveLength(1)
})
})

describe('/appointments/edit/:id', () => {
it('should render the edit appointment screen when /appointments/edit/:id is accessed', () => {
const appointment = {
id: '123',
patientId: '456',
} as Appointment

const patient = {
id: '456',
} as Patient

jest.spyOn(AppointmentRepository, 'find').mockResolvedValue(appointment)
jest.spyOn(PatientRepository, 'find').mockResolvedValue(patient)

const store = mockStore({
title: 'test',
user: { permissions: [Permissions.WriteAppointments, Permissions.ReadAppointments] },
appointment: { appointment, patient: {} as Patient },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
})

const wrapper = mount(
<Provider store={store}>
<MemoryRouter initialEntries={['/appointments/edit/123']}>
<HospitalRun />
</MemoryRouter>
</Provider>,
)

expect(wrapper.find(EditAppointment)).toHaveLength(1)

expect(store.getActions()).toContainEqual(
addBreadcrumbs([
{ i18nKey: 'scheduling.appointments.label', location: '/appointments' },
{ text: '123', location: '/appointments/123' },
{
i18nKey: 'scheduling.appointments.editAppointment',
location: '/appointments/edit/123',
},
{ i18nKey: 'dashboard.label', location: '/' },
]),
)
})

it('should render the Dashboard when the user does not have read appointment privileges', () => {
const wrapper = mount(
<Provider
store={mockStore({
title: 'test',
user: { permissions: [Permissions.WriteAppointments] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
})}
>
<MemoryRouter initialEntries={['/appointments/edit/123']}>
<HospitalRun />
</MemoryRouter>
</Provider>,
)

expect(wrapper.find(Dashboard)).toHaveLength(1)
})

it('should render the Dashboard when the user does not have write appointment privileges', () => {
const wrapper = mount(
<Provider
store={mockStore({
title: 'test',
user: { permissions: [Permissions.ReadAppointments] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
})}
>
<MemoryRouter initialEntries={['/appointments/edit/123']}>
<HospitalRun />
</MemoryRouter>
</Provider>,
)

expect(wrapper.find(Dashboard)).toHaveLength(1)
})
})

describe('/labs', () => {
it('should render the Labs component when /labs is accessed', async () => {
jest.spyOn(LabRepository, 'findAll').mockResolvedValue([])
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/labs/ViewLab.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('View Labs', () => {
lab,
patient: mockPatient,
error,
status: Object.keys(error).length > 0 ? 'error' : 'success',
status: Object.keys(error).length > 0 ? 'error' : 'completed',
},
})

Expand Down
10 changes: 5 additions & 5 deletions src/__tests__/labs/lab-slice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe('lab slice', () => {
fetchLabSuccess({ lab: expectedLab, patient: expectedPatient }),
)

expect(labStore.status).toEqual('success')
expect(labStore.status).toEqual('completed')
expect(labStore.lab).toEqual(expectedLab)
expect(labStore.patient).toEqual(expectedPatient)
})
Expand All @@ -67,7 +67,7 @@ describe('lab slice', () => {

const labStore = labSlice(undefined, updateLabSuccess(expectedLab))

expect(labStore.status).toEqual('success')
expect(labStore.status).toEqual('completed')
expect(labStore.lab).toEqual(expectedLab)
})
})
Expand All @@ -86,7 +86,7 @@ describe('lab slice', () => {

const labStore = labSlice(undefined, requestLabSuccess(expectedLab))

expect(labStore.status).toEqual('success')
expect(labStore.status).toEqual('completed')
expect(labStore.lab).toEqual(expectedLab)
})
})
Expand Down Expand Up @@ -114,7 +114,7 @@ describe('lab slice', () => {

const labStore = labSlice(undefined, completeLabSuccess(expectedLab))

expect(labStore.status).toEqual('success')
expect(labStore.status).toEqual('completed')
expect(labStore.lab).toEqual(expectedLab)
})
})
Expand Down Expand Up @@ -142,7 +142,7 @@ describe('lab slice', () => {

const labStore = labSlice(undefined, cancelLabSuccess(expectedLab))

expect(labStore.status).toEqual('success')
expect(labStore.status).toEqual('completed')
expect(labStore.lab).toEqual(expectedLab)
})
})
Expand Down
8 changes: 2 additions & 6 deletions src/__tests__/patients/GeneralInformation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,8 @@ describe('Error handling', () => {
phoneNumber: 'phone number message',
email: 'email message',
}
const history = createMemoryHistory()
const wrapper = mount(
<Router history={history}>
<GeneralInformation patient={{} as Patient} isEditable error={error} />
</Router>,
)

const wrapper = mount(<GeneralInformation patient={{} as Patient} isEditable error={error} />)
wrapper.update()

const errorMessage = wrapper.find(Alert)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,42 @@ import { mount, ReactWrapper } from 'enzyme'
import AppointmentDetailForm from 'scheduling/appointments/AppointmentDetailForm'
import Appointment from 'model/Appointment'
import { roundToNearestMinutes, addMinutes } from 'date-fns'
import { Typeahead } from '@hospitalrun/components'
import { Typeahead, Alert } from '@hospitalrun/components'
import PatientRepository from 'clients/db/PatientRepository'
import Patient from 'model/Patient'
import { act } from '@testing-library/react'

describe('AppointmentDetailForm', () => {
describe('Error handling', () => {
it('should display errors', () => {
const error = {
message: 'some message',
patient: 'patient message',
startDateTime: 'start date time message',
}

const wrapper = mount(
<AppointmentDetailForm
appointment={{} as Appointment}
patient={{} as Patient}
isEditable
error={error}
/>,
)
wrapper.update()

const errorMessage = wrapper.find(Alert)
const patientTypeahead = wrapper.find(Typeahead)
const startDateInput = wrapper.findWhere((w: any) => w.prop('name') === 'startDate')
expect(errorMessage).toBeTruthy()
expect(errorMessage.prop('message')).toMatch(error.message)
expect(patientTypeahead.prop('isInvalid')).toBeTruthy()
expect(patientTypeahead.prop('feedback')).toEqual(error.patient)
expect(startDateInput.prop('isInvalid')).toBeTruthy()
expect(startDateInput.prop('feedback')).toEqual(error.startDateTime)
})
})

describe('layout - editable', () => {
let wrapper: ReactWrapper
const expectedAppointment = {
Expand Down
Loading

1 comment on commit adcad7b

@vercel
Copy link

@vercel vercel bot commented on adcad7b May 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.