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

feat(imaging): create basic imaging module #2250

Merged
merged 15 commits into from
Aug 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/HospitalRun.tsx
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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])
})
})
})
Loading