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

Commit

Permalink
feat(imaging): create basic imaging module (#2250)
Browse files Browse the repository at this point in the history
Co-authored-by: Jack Meyer <jackcmeyer@gmail.com>
Co-authored-by: Matteo Vivona <matteo.vivona@me.com>
  • Loading branch information
3 people committed Aug 5, 2020
1 parent a7b8441 commit f256129
Show file tree
Hide file tree
Showing 26 changed files with 1,591 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/HospitalRun.tsx
Expand Up @@ -4,6 +4,7 @@ import { useSelector } from 'react-redux'
import { Redirect, Route, Switch } from 'react-router-dom'

import Dashboard from './dashboard/Dashboard'
import Imagings from './imagings/Imagings'
import Incidents from './incidents/Incidents'
import Labs from './labs/Labs'
import Breadcrumbs from './page-header/breadcrumbs/Breadcrumbs'
Expand Down Expand Up @@ -53,6 +54,7 @@ const HospitalRun = () => {
<Route path="/labs" component={Labs} />
<Route path="/incidents" component={Incidents} />
<Route path="/settings" component={Settings} />
<Route path="/imaging" component={Imagings} />
</Switch>
</div>
<Toaster autoClose={5000} hideProgressBar draggable />
Expand Down
50 changes: 50 additions & 0 deletions src/__tests__/HospitalRun.test.tsx
Expand Up @@ -9,11 +9,13 @@ import thunk from 'redux-thunk'

import Dashboard from '../dashboard/Dashboard'
import HospitalRun from '../HospitalRun'
import ViewImagings from '../imagings/ViewImagings'
import Incidents from '../incidents/Incidents'
import ViewLabs from '../labs/ViewLabs'
import { addBreadcrumbs } from '../page-header/breadcrumbs/breadcrumbs-slice'
import Appointments from '../scheduling/appointments/Appointments'
import Settings from '../settings/Settings'
import ImagingRepository from '../shared/db/ImagingRepository'
import LabRepository from '../shared/db/LabRepository'
import Permissions from '../shared/model/Permissions'
import { RootState } from '../shared/store'
Expand Down Expand Up @@ -170,6 +172,54 @@ describe('HospitalRun', () => {
})
})

describe('/imaging', () => {
it('should render the Imagings component when /imaging is accessed', async () => {
jest.spyOn(ImagingRepository, 'findAll').mockResolvedValue([])
const store = mockStore({
title: 'test',
user: { user: { id: '123' }, permissions: [Permissions.ViewImagings] },
imagings: { imagings: [] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
} as any)

let wrapper: any
await act(async () => {
wrapper = await mount(
<Provider store={store}>
<MemoryRouter initialEntries={['/imaging']}>
<HospitalRun />
</MemoryRouter>
</Provider>,
)
})
wrapper.update()

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

it('should render the dashboard if the user does not have permissions to view imagings', () => {
jest.spyOn(LabRepository, 'findAll').mockResolvedValue([])
const store = mockStore({
title: 'test',
user: { user: { id: '123' }, permissions: [] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
} as any)

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

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

describe('/settings', () => {
it('should render the Settings component when /settings is accessed', async () => {
const store = mockStore({
Expand Down
74 changes: 74 additions & 0 deletions src/__tests__/imagings/Imagings.test.tsx
@@ -0,0 +1,74 @@
import { mount } from 'enzyme'
import React from 'react'
import { Provider } from 'react-redux'
import { MemoryRouter } from 'react-router-dom'
import createMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'

import Imagings from '../../imagings/Imagings'
import NewImagingRequest from '../../imagings/requests/NewImagingRequest'
import ImagingRepository from '../../shared/db/ImagingRepository'
import PatientRepository from '../../shared/db/PatientRepository'
import Imaging from '../../shared/model/Imaging'
import Patient from '../../shared/model/Patient'
import Permissions from '../../shared/model/Permissions'
import { RootState } from '../../shared/store'

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

describe('Imagings', () => {
jest.spyOn(ImagingRepository, 'findAll').mockResolvedValue([])
jest
.spyOn(ImagingRepository, 'find')
.mockResolvedValue({ id: '1234', requestedOn: new Date().toISOString() } as Imaging)
jest
.spyOn(PatientRepository, 'find')
.mockResolvedValue({ id: '12345', fullName: 'test test' } as Patient)

describe('routing', () => {
describe('/imaging/new', () => {
it('should render the new imaging request screen when /imaging/new is accessed', () => {
const store = mockStore({
title: 'test',
user: { permissions: [Permissions.RequestImaging] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
imaging: {
imaging: { id: 'imagingId', patient: 'patient' } as Imaging,
patient: { id: 'patientId', fullName: 'some name' },
error: {},
},
} as any)

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

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

it('should not navigate to /imagings/new if the user does not have RequestLab permissions', () => {
const store = mockStore({
title: 'test',
user: { permissions: [] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
} as any)

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

expect(wrapper.find(NewImagingRequest)).toHaveLength(0)
})
})
})
})
125 changes: 125 additions & 0 deletions src/__tests__/imagings/ViewImagings.test.tsx
@@ -0,0 +1,125 @@
import { Table } from '@hospitalrun/components'
import { act } from '@testing-library/react'
import { mount, ReactWrapper } 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 ViewImagings from '../../imagings/ViewImagings'
import * as breadcrumbUtil from '../../page-header/breadcrumbs/useAddBreadcrumbs'
import * as ButtonBarProvider from '../../page-header/button-toolbar/ButtonBarProvider'
import * as titleUtil from '../../page-header/title/useTitle'
import ImagingRepository from '../../shared/db/ImagingRepository'
import Imaging from '../../shared/model/Imaging'
import Permissions from '../../shared/model/Permissions'
import { RootState } from '../../shared/store'

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

describe('View Imagings', () => {
let history: any
let setButtonToolBarSpy: any
const expectedDate = new Date(2020, 5, 3, 19, 48)
const expectedImaging = {
code: 'I-1234',
id: '1234',
type: 'imaging type',
patient: 'patient',
status: 'requested',
requestedOn: expectedDate.toISOString(),
requestedBy: 'some user',
} as Imaging

const setup = async (permissions: Permissions[], mockImagings?: any) => {
jest.resetAllMocks()
jest.spyOn(breadcrumbUtil, 'default')
setButtonToolBarSpy = jest.fn()
jest.spyOn(titleUtil, 'default')
jest.spyOn(ImagingRepository, 'findAll').mockResolvedValue(mockImagings)
jest.spyOn(ButtonBarProvider, 'useButtonToolbarSetter').mockReturnValue(setButtonToolBarSpy)

history = createMemoryHistory()
history.push(`/imaging`)

const store = mockStore({
title: '',
user: { permissions },
imagings: { imagings: mockImagings },
} as any)

let wrapper: any
await act(async () => {
wrapper = await mount(
<ButtonBarProvider.ButtonBarProvider>
<Provider store={store}>
<Router history={history}>
<Route path="/imaging">
<ViewImagings />
</Route>
</Router>
</Provider>
</ButtonBarProvider.ButtonBarProvider>,
)
})

wrapper.update()
return wrapper as ReactWrapper
}

describe('title', () => {
it('should have the title', async () => {
await setup([Permissions.ViewImagings], [])
expect(titleUtil.default).toHaveBeenCalledWith('imagings.label')
})
})

describe('button bar', () => {
it('should display button to add new imaging request', async () => {
await setup([Permissions.ViewImagings, Permissions.RequestImaging], [])

const actualButtons: React.ReactNode[] = setButtonToolBarSpy.mock.calls[0][0]
expect((actualButtons[0] as any).props.children).toEqual('imagings.requests.new')
})

it('should not display button to add new imaging request if the user does not have permissions', async () => {
await setup([Permissions.ViewImagings], [])

const actualButtons: React.ReactNode[] = setButtonToolBarSpy.mock.calls[0][0]
expect(actualButtons).toEqual([])
})
})

describe('table', () => {
it('should render a table with data', async () => {
const wrapper = await setup(
[Permissions.ViewIncident, Permissions.RequestImaging],
[expectedImaging],
)
const table = wrapper.find(Table)
const columns = table.prop('columns')
expect(columns[0]).toEqual(
expect.objectContaining({ label: 'imagings.imaging.code', key: 'code' }),
)
expect(columns[1]).toEqual(
expect.objectContaining({ label: 'imagings.imaging.type', key: 'type' }),
)
expect(columns[2]).toEqual(
expect.objectContaining({ label: 'imagings.imaging.requestedOn', key: 'requestedOn' }),
)
expect(columns[3]).toEqual(
expect.objectContaining({ label: 'imagings.imaging.patient', key: 'patient' }),
)
expect(columns[4]).toEqual(
expect.objectContaining({ label: 'imagings.imaging.requestedBy', key: 'requestedBy' }),
)
expect(columns[5]).toEqual(
expect.objectContaining({ label: 'imagings.imaging.status', key: 'status' }),
)

expect(table.prop('data')).toEqual([expectedImaging])
})
})
})

0 comments on commit f256129

Please sign in to comment.