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

Commit

Permalink
feat(incidents): add ability to view an incident
Browse files Browse the repository at this point in the history
  • Loading branch information
jackcmeyer committed May 4, 2020
1 parent f11d8e9 commit 5887859
Show file tree
Hide file tree
Showing 6 changed files with 276 additions and 24 deletions.
2 changes: 2 additions & 0 deletions src/__tests__/HospitalRun.test.tsx
Expand Up @@ -34,6 +34,7 @@ describe('HospitalRun', () => {
appointments: { appointments: [] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
incidents: { incidents: [] },
})

const wrapper = mount(
Expand Down Expand Up @@ -265,6 +266,7 @@ describe('HospitalRun', () => {
user: { permissions: [Permissions.ViewIncidents] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
incidents: { incidents: [] },
})

let wrapper: any
Expand Down
25 changes: 21 additions & 4 deletions src/__tests__/incidents/Incidents.test.tsx
Expand Up @@ -10,19 +10,28 @@ import Permissions from 'model/Permissions'
import ViewIncident from '../../incidents/view/ViewIncident'
import Incidents from '../../incidents/Incidents'
import ReportIncident from '../../incidents/report/ReportIncident'
import Incident from '../../model/Incident'
import IncidentRepository from '../../clients/db/IncidentRepository'

const mockStore = configureMockStore([thunk])

describe('Incidents', () => {
describe('routing', () => {
describe('/incidents/new', () => {
it('should render the new lab request screen when /incidents/new is accessed', () => {
it('should render the new incident screen when /incidents/new is accessed', () => {
const expectedIncident = {
id: '1234',
code: '1234',
} as Incident
jest.spyOn(IncidentRepository, 'find').mockResolvedValue(expectedIncident)
const store = mockStore({
title: 'test',
user: { permissions: [Permissions.ReportIncident] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
incident: {},
incident: {
incident: expectedIncident,
},
})

const wrapper = mount(
Expand All @@ -36,7 +45,7 @@ describe('Incidents', () => {
expect(wrapper.find(ReportIncident)).toHaveLength(1)
})

it('should not navigate to /incidents/new if the user does not have RequestLab permissions', () => {
it('should not navigate to /incidents/new if the user does not have ReportIncident permissions', () => {
const store = mockStore({
title: 'test',
user: { permissions: [] },
Expand All @@ -57,12 +66,20 @@ describe('Incidents', () => {
})

describe('/incidents/:id', () => {
it('should render the view lab screen when /incidents/:id is accessed', async () => {
it('should render the view incident screen when /incidents/:id is accessed', async () => {
const store = mockStore({
title: 'test',
user: { permissions: [Permissions.ViewIncident] },
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
incident: {
incident: {
id: '1234',
code: '1234 ',
date: new Date().toISOString(),
reportedOn: new Date().toISOString(),
},
},
})

let wrapper: any
Expand Down
71 changes: 64 additions & 7 deletions src/__tests__/incidents/incident-slice.test.ts
Expand Up @@ -8,10 +8,15 @@ import incident, {
reportIncidentSuccess,
reportIncidentError,
reportIncident,
fetchIncidentStart,
fetchIncidentSuccess,
fetchIncident,
} from '../../incidents/incident-slice'
import Incident from '../../model/Incident'
import { RootState } from '../../store'
import IncidentRepository from '../../clients/db/IncidentRepository'
import Permissions from '../../model/Permissions'
import User from '../../model/User'

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

Expand Down Expand Up @@ -58,6 +63,22 @@ describe('incident slice', () => {
expect(incidentStore.status).toEqual('error')
expect(incidentStore.error).toEqual(expectedError)
})

it('should handle fetch incident start', () => {
const incidentStore = incident(undefined, fetchIncidentStart())
expect(incidentStore.status).toEqual('loading')
})

it('should handle fetch incident success', () => {
const expectedIncident = {
id: '1234',
code: 'some code',
} as Incident

const incidentStore = incident(undefined, fetchIncidentSuccess(expectedIncident))
expect(incidentStore.status).toEqual('completed')
expect(incidentStore.incident).toEqual(expectedIncident)
})
})

describe('report incident', () => {
Expand All @@ -84,11 +105,17 @@ describe('incident slice', () => {
code: `I-${expectedShortId}`,
reportedOn: expectedDate.toISOString(),
reportedBy: 'some user id',
}
status: 'reported',
} as Incident

jest.spyOn(IncidentRepository, 'save').mockResolvedValue(expectedIncident)

const store = mockStore({ user: { user: { id: expectedIncident.reportedBy } } })
const store = mockStore({
user: {
user: { id: expectedIncident.reportedBy } as User,
permissions: [] as Permissions[],
},
} as any)

await store.dispatch(reportIncident(newIncident, onSuccessSpy))

Expand All @@ -110,8 +137,12 @@ describe('incident slice', () => {
description: 'incidents.reports.error.descriptionRequired',
}

const store = mockStore({ user: { user: { id: 'some id' } } })

const store = mockStore({
user: {
user: { id: 'some id' } as User,
permissions: [] as Permissions[],
},
} as any)
await store.dispatch(reportIncident(newIncident, onSuccessSpy))

expect(store.getActions()[0]).toEqual(reportIncidentStart())
Expand All @@ -124,7 +155,7 @@ describe('incident slice', () => {
const onSuccessSpy = jest.fn()
const newIncident = {
description: 'description',
date: addDays(new Date(), 4),
date: addDays(new Date(), 4).toISOString(),
department: 'some department',
category: 'category',
categoryItem: 'categoryItem',
Expand All @@ -134,8 +165,12 @@ describe('incident slice', () => {
date: 'incidents.reports.error.dateMustBeInThePast',
}

const store = mockStore({ user: { user: { id: 'some id' } } })

const store = mockStore({
user: {
user: { id: 'some id' } as User,
permissions: [] as Permissions[],
},
} as any)
await store.dispatch(reportIncident(newIncident, onSuccessSpy))

expect(store.getActions()[0]).toEqual(reportIncidentStart())
Expand All @@ -144,4 +179,26 @@ describe('incident slice', () => {
expect(onSuccessSpy).not.toHaveBeenCalled()
})
})

describe('fetch incident', () => {
it('should fetch the incident', async () => {
const expectedIncident = {
id: '123',
description: 'description',
date: addDays(new Date(), 4).toISOString(),
department: 'some department',
category: 'category',
categoryItem: 'categoryItem',
} as Incident
jest.spyOn(IncidentRepository, 'find').mockResolvedValue(expectedIncident)

const store = mockStore()

await store.dispatch(fetchIncident(expectedIncident.id))

expect(store.getActions()[0]).toEqual(fetchIncidentStart())
expect(IncidentRepository.find).toHaveBeenCalledWith(expectedIncident.id)
expect(store.getActions()[1]).toEqual(fetchIncidentSuccess(expectedIncident))
})
})
})
104 changes: 95 additions & 9 deletions src/__tests__/incidents/view/ViewIncident.test.tsx
Expand Up @@ -12,24 +12,44 @@ import * as titleUtil from '../../../page-header/useTitle'
import * as ButtonBarProvider from '../../../page-header/ButtonBarProvider'
import * as breadcrumbUtil from '../../../breadcrumbs/useAddBreadcrumbs'
import ViewIncident from '../../../incidents/view/ViewIncident'
import Incident from '../../../model/Incident'
import IncidentRepository from '../../../clients/db/IncidentRepository'

const mockStore = createMockStore([thunk])

describe('View Incident', () => {
const expectedDate = new Date(2020, 5, 1, 19, 48)
let history: any
const expectedIncident = {
id: '1234',
code: 'some code',
department: 'some department',
description: 'some description',
category: 'some category',
categoryItem: 'some category item',
status: 'reported',
reportedBy: 'some user id',
reportedOn: expectedDate.toISOString(),
date: expectedDate.toISOString(),
} as Incident

const setup = async (permissions: Permissions[]) => {
jest.resetAllMocks()
jest.spyOn(breadcrumbUtil, 'default')
jest.spyOn(titleUtil, 'default')
jest.spyOn(IncidentRepository, 'find').mockResolvedValue(expectedIncident)

history = createMemoryHistory()
history.push(`/incidents/1234`)

const store = mockStore({
title: '',
user: {
permissions,
},
incident: {
incident: expectedIncident,
},
})

let wrapper: any
Expand All @@ -50,17 +70,83 @@ describe('View Incident', () => {
return wrapper
}

it('should set the title', async () => {
await setup([Permissions.ViewIncident])
describe('layout', () => {
it('should set the title', async () => {
await setup([Permissions.ViewIncident])

expect(titleUtil.default).toHaveBeenCalledWith('incidents.reports.view')
})
expect(titleUtil.default).toHaveBeenCalledWith(expectedIncident.code)
})

it('should set the breadcrumbs properly', async () => {
await setup([Permissions.ViewIncident])

expect(breadcrumbUtil.default).toHaveBeenCalledWith([
{ i18nKey: expectedIncident.code, location: '/incidents/1234' },
])
})

it('should render the date of incident', async () => {
const wrapper = await setup([Permissions.ViewIncident])

it('should set the breadcrumbs properly', async () => {
await setup([Permissions.ViewIncident])
const dateOfIncidentFormGroup = wrapper.find('.incident-date')
expect(dateOfIncidentFormGroup.find('h4').text()).toEqual('incidents.reports.dateOfIncident')
expect(dateOfIncidentFormGroup.find('h5').text()).toEqual('2020-06-01 07:48 PM')
})

it('should render the status', async () => {
const wrapper = await setup([Permissions.ViewIncident])

const dateOfIncidentFormGroup = wrapper.find('.incident-status')
expect(dateOfIncidentFormGroup.find('h4').text()).toEqual('incidents.reports.status')
expect(dateOfIncidentFormGroup.find('h5').text()).toEqual(expectedIncident.status)
})

it('should render the reported by', async () => {
const wrapper = await setup([Permissions.ViewIncident])

const dateOfIncidentFormGroup = wrapper.find('.incident-reported-by')
expect(dateOfIncidentFormGroup.find('h4').text()).toEqual('incidents.reports.reportedBy')
expect(dateOfIncidentFormGroup.find('h5').text()).toEqual(expectedIncident.reportedBy)
})

expect(breadcrumbUtil.default).toHaveBeenCalledWith([
{ i18nKey: 'incidents.reports.view', location: '/incidents/1234' },
])
it('should render the reported on', async () => {
const wrapper = await setup([Permissions.ViewIncident])

const dateOfIncidentFormGroup = wrapper.find('.incident-reported-on')
expect(dateOfIncidentFormGroup.find('h4').text()).toEqual('incidents.reports.reportedOn')
expect(dateOfIncidentFormGroup.find('h5').text()).toEqual('2020-06-01 07:48 PM')
})

it('should render the department', async () => {
const wrapper = await setup([Permissions.ViewIncident])

const departmentInput = wrapper.findWhere((w: any) => w.prop('name') === 'department')
expect(departmentInput.prop('label')).toEqual('incidents.reports.department')
expect(departmentInput.prop('value')).toEqual(expectedIncident.department)
})

it('should render the category', async () => {
const wrapper = await setup([Permissions.ViewIncident])

const categoryInput = wrapper.findWhere((w: any) => w.prop('name') === 'category')
expect(categoryInput.prop('label')).toEqual('incidents.reports.category')
expect(categoryInput.prop('value')).toEqual(expectedIncident.category)
})

it('should render the category item', async () => {
const wrapper = await setup([Permissions.ViewIncident])

const categoryItemInput = wrapper.findWhere((w: any) => w.prop('name') === 'categoryItem')
expect(categoryItemInput.prop('label')).toEqual('incidents.reports.categoryItem')
expect(categoryItemInput.prop('value')).toEqual(expectedIncident.categoryItem)
})

it('should render the description', async () => {
const wrapper = await setup([Permissions.ViewIncident])

const descriptionTextInput = wrapper.findWhere((w: any) => w.prop('name') === 'description')
expect(descriptionTextInput.prop('label')).toEqual('incidents.reports.description')
expect(descriptionTextInput.prop('value')).toEqual(expectedIncident.description)
})
})
})
11 changes: 11 additions & 0 deletions src/incidents/incident-slice.ts
Expand Up @@ -45,18 +45,28 @@ const incidentSlice = createSlice({
name: 'incident',
initialState,
reducers: {
fetchIncidentStart: start,
fetchIncidentSuccess: finish,
reportIncidentStart: start,
reportIncidentSuccess: finish,
reportIncidentError: error,
},
})

export const {
fetchIncidentStart,
fetchIncidentSuccess,
reportIncidentStart,
reportIncidentSuccess,
reportIncidentError,
} = incidentSlice.actions

export const fetchIncident = (id: string): AppThunk => async (dispatch) => {
dispatch(fetchIncidentStart())
const incident = await IncidentRepository.find(id)
dispatch(fetchIncidentSuccess(incident))
}

function validateIncident(incident: Incident): Error {
const newError: Error = {}

Expand Down Expand Up @@ -98,6 +108,7 @@ export const reportIncident = (
incident.reportedOn = new Date(Date.now()).toISOString()
incident.code = getIncidentCode()
incident.reportedBy = getState().user.user.id
incident.status = 'reported'
const newIncident = await IncidentRepository.save(incident)
await dispatch(reportIncidentSuccess(newIncident))
if (onSuccess) {
Expand Down

0 comments on commit 5887859

Please sign in to comment.