diff --git a/src/__tests__/scheduling/appointments/AppointmentDetailForm.test.tsx b/src/__tests__/scheduling/appointments/AppointmentDetailForm.test.tsx
new file mode 100644
index 0000000000..a3b7881831
--- /dev/null
+++ b/src/__tests__/scheduling/appointments/AppointmentDetailForm.test.tsx
@@ -0,0 +1,239 @@
+import '../../../__mocks__/matchMediaMock'
+import React from 'react'
+import { mount, ReactWrapper } from 'enzyme'
+import AppointmentDetailForm from 'scheduling/appointments/AppointmentDetailForm'
+import Appointment from 'model/Appointment'
+import { roundToNearestMinutes, addMinutes } from 'date-fns'
+import { Typeahead, Button } from '@hospitalrun/components'
+import PatientRepository from 'clients/db/PatientRepository'
+import Patient from 'model/Patient'
+import { act } from '@testing-library/react'
+
+describe('AppointmentDetailForm', () => {
+ describe('layout', () => {
+ let wrapper: ReactWrapper
+
+ beforeEach(() => {
+ wrapper = mount(
+ ,
+ )
+ })
+
+ it('should render a typeahead for patients', () => {
+ const patientTypeahead = wrapper.find(Typeahead)
+
+ expect(patientTypeahead).toHaveLength(1)
+ expect(patientTypeahead.prop('placeholder')).toEqual('scheduling.appointment.patient')
+ })
+
+ it('should render as start date date time picker', () => {
+ const startDateTimePicker = wrapper.findWhere((w) => w.prop('name') === 'startDate')
+
+ expect(startDateTimePicker).toHaveLength(1)
+ expect(startDateTimePicker.prop('label')).toEqual('scheduling.appointment.startDate')
+ expect(startDateTimePicker.prop('value')).toEqual(
+ roundToNearestMinutes(new Date(), { nearestTo: 15 }),
+ )
+ })
+
+ it('should render an end date time picker', () => {
+ const endDateTimePicker = wrapper.findWhere((w) => w.prop('name') === 'endDate')
+
+ expect(endDateTimePicker).toHaveLength(1)
+ expect(endDateTimePicker.prop('label')).toEqual('scheduling.appointment.endDate')
+ expect(endDateTimePicker.prop('value')).toEqual(
+ addMinutes(roundToNearestMinutes(new Date(), { nearestTo: 15 }), 60),
+ )
+ })
+
+ it('should render a location text input box', () => {
+ const locationTextInputBox = wrapper.findWhere((w) => w.prop('name') === 'location')
+
+ expect(locationTextInputBox).toHaveLength(1)
+ expect(locationTextInputBox.prop('label')).toEqual('scheduling.appointment.location')
+ })
+
+ it('should render a type select box', () => {
+ const typeSelect = wrapper.findWhere((w) => w.prop('name') === 'type')
+
+ expect(typeSelect).toHaveLength(1)
+ expect(typeSelect.prop('label')).toEqual('scheduling.appointment.type')
+ expect(typeSelect.prop('options')[0].label).toEqual('scheduling.appointment.types.checkup')
+ expect(typeSelect.prop('options')[0].value).toEqual('checkup')
+ expect(typeSelect.prop('options')[1].label).toEqual('scheduling.appointment.types.emergency')
+ expect(typeSelect.prop('options')[1].value).toEqual('emergency')
+ expect(typeSelect.prop('options')[2].label).toEqual('scheduling.appointment.types.followUp')
+ expect(typeSelect.prop('options')[2].value).toEqual('follow up')
+ expect(typeSelect.prop('options')[3].label).toEqual('scheduling.appointment.types.routine')
+ expect(typeSelect.prop('options')[3].value).toEqual('routine')
+ expect(typeSelect.prop('options')[4].label).toEqual('scheduling.appointment.types.walkUp')
+ expect(typeSelect.prop('options')[4].value).toEqual('walk up')
+ })
+
+ it('should render a reason text field input', () => {
+ const reasonTextField = wrapper.findWhere((w) => w.prop('name') === 'reason')
+
+ expect(reasonTextField).toHaveLength(1)
+ expect(reasonTextField.prop('label')).toEqual('scheduling.appointment.reason')
+ })
+ })
+
+ describe('change handlers', () => {
+ let wrapper: ReactWrapper
+ let appointment = {
+ startDateTime: roundToNearestMinutes(new Date(), { nearestTo: 15 }).toISOString(),
+ endDateTime: addMinutes(
+ roundToNearestMinutes(new Date(), { nearestTo: 15 }),
+ 30,
+ ).toISOString(),
+ } as Appointment
+ const onAppointmentChangeSpy = jest.fn()
+
+ beforeEach(() => {
+ wrapper = mount(
+ ,
+ )
+ })
+
+ it('should call the onAppointmentChange when patient input changes', () => {
+ const expectedPatientId = '123'
+
+ act(() => {
+ const patientTypeahead = wrapper.find(Typeahead)
+ patientTypeahead.prop('onChange')([{ id: expectedPatientId }] as Patient[])
+ })
+ wrapper.update()
+
+ expect(onAppointmentChangeSpy).toHaveBeenLastCalledWith({
+ patientId: expectedPatientId,
+ startDateTime: appointment.startDateTime,
+ endDateTime: appointment.endDateTime,
+ })
+ })
+
+ it('should call the onAppointmentChange when start date time changes', () => {
+ const expectedStartDateTime = roundToNearestMinutes(new Date(), { nearestTo: 15 })
+
+ act(() => {
+ const startDateTimePicker = wrapper.findWhere((w) => w.prop('name') === 'startDate')
+ startDateTimePicker.prop('onChange')(expectedStartDateTime)
+ })
+ wrapper.update()
+
+ expect(onAppointmentChangeSpy).toHaveBeenLastCalledWith({
+ startDateTime: expectedStartDateTime.toISOString(),
+ endDateTime: appointment.endDateTime,
+ })
+ })
+
+ it('should call the onAppointmentChange when end date time changes', () => {
+ const expectedStartDateTime = roundToNearestMinutes(new Date(), { nearestTo: 15 })
+ const expectedEndDateTime = addMinutes(expectedStartDateTime, 30)
+
+ act(() => {
+ const endDateTimePicker = wrapper.findWhere((w) => w.prop('name') === 'endDate')
+ endDateTimePicker.prop('onChange')(expectedEndDateTime)
+ })
+ wrapper.update()
+
+ expect(onAppointmentChangeSpy).toHaveBeenLastCalledWith({
+ startDateTime: appointment.startDateTime,
+ endDateTime: expectedEndDateTime.toISOString(),
+ })
+ })
+
+ it('should call the onAppointmentChange when location changes', () => {
+ const expectedLocation = 'location'
+
+ act(() => {
+ const locationTextInputBox = wrapper.findWhere((w) => w.prop('name') === 'location')
+ locationTextInputBox.prop('onChange')({ target: { value: expectedLocation } })
+ })
+ wrapper.update()
+
+ expect(onAppointmentChangeSpy).toHaveBeenLastCalledWith({
+ startDateTime: appointment.startDateTime,
+ endDateTime: appointment.endDateTime,
+ location: expectedLocation,
+ })
+ })
+
+ it('should call the onAppointmentChange when type changes', () => {
+ const expectedType = 'follow up'
+
+ act(() => {
+ const typeSelect = wrapper.findWhere((w) => w.prop('name') === 'type')
+ typeSelect.prop('onChange')({ currentTarget: { value: expectedType } })
+ })
+ wrapper.update()
+
+ expect(onAppointmentChangeSpy).toHaveBeenLastCalledWith({
+ startDateTime: appointment.startDateTime,
+ endDateTime: appointment.endDateTime,
+ type: expectedType,
+ })
+ })
+
+ it('should call the onAppointmentChange when reason changes', () => {
+ const expectedReason = 'reason'
+
+ act(() => {
+ const reasonTextField = wrapper.findWhere((w) => w.prop('name') === 'reason')
+ reasonTextField.prop('onChange')({ target: { value: expectedReason } })
+ })
+ wrapper.update()
+
+ expect(onAppointmentChangeSpy).toHaveBeenLastCalledWith({
+ startDateTime: appointment.startDateTime,
+ endDateTime: appointment.endDateTime,
+ reason: expectedReason,
+ })
+ })
+ })
+
+ describe('typeahead search', () => {
+ let wrapper: ReactWrapper
+ beforeEach(() => {
+ wrapper = mount(
+ ,
+ )
+ })
+
+ it('should call the PatientRepository search when typeahead changes', () => {
+ const patientTypeahead = wrapper.find(Typeahead)
+ const patientRepositorySearch = jest.spyOn(PatientRepository, 'search')
+ const expectedSearchString = 'search'
+
+ act(() => {
+ patientTypeahead.prop('onSearch')(expectedSearchString)
+ })
+
+ expect(patientRepositorySearch).toHaveBeenCalledWith(expectedSearchString)
+ })
+ })
+})
diff --git a/src/__tests__/scheduling/appointments/new/NewAppointment.test.tsx b/src/__tests__/scheduling/appointments/new/NewAppointment.test.tsx
index 3d50f419b0..bbcaadd833 100644
--- a/src/__tests__/scheduling/appointments/new/NewAppointment.test.tsx
+++ b/src/__tests__/scheduling/appointments/new/NewAppointment.test.tsx
@@ -15,6 +15,7 @@ import PatientRepository from 'clients/db/PatientRepository'
import AppointmentRepository from 'clients/db/AppointmentsRepository'
import { mocked } from 'ts-jest/utils'
import Appointment from 'model/Appointment'
+import AppointmentDetailForm from 'scheduling/appointments/AppointmentDetailForm'
import * as titleUtil from '../../../../page-header/useTitle'
import * as appointmentsSlice from '../../../../scheduling/appointments/appointments-slice'
@@ -51,136 +52,30 @@ describe('New Appointment', () => {
})
describe('layout', () => {
- it('should render a typeahead for patients', () => {
- const patientTypeahead = wrapper.find(Typeahead)
-
- expect(patientTypeahead).toHaveLength(1)
- expect(patientTypeahead.prop('placeholder')).toEqual('scheduling.appointment.patient')
- })
-
- it('should render as start date date time picker', () => {
- const startDateTimePicker = wrapper.findWhere((w) => w.prop('name') === 'startDate')
-
- expect(startDateTimePicker).toHaveLength(1)
- expect(startDateTimePicker.prop('label')).toEqual('scheduling.appointment.startDate')
- expect(startDateTimePicker.prop('value')).toEqual(
- roundToNearestMinutes(new Date(), { nearestTo: 15 }),
- )
- })
-
- it('should render an end date time picker', () => {
- const endDateTimePicker = wrapper.findWhere((w) => w.prop('name') === 'endDate')
-
- expect(endDateTimePicker).toHaveLength(1)
- expect(endDateTimePicker.prop('label')).toEqual('scheduling.appointment.endDate')
- expect(endDateTimePicker.prop('value')).toEqual(
- addMinutes(roundToNearestMinutes(new Date(), { nearestTo: 15 }), 60),
- )
- })
-
- it('should render a location text input box', () => {
- const locationTextInputBox = wrapper.findWhere((w) => w.prop('name') === 'location')
-
- expect(locationTextInputBox).toHaveLength(1)
- expect(locationTextInputBox.prop('label')).toEqual('scheduling.appointment.location')
- })
-
- it('should render a type select box', () => {
- const typeSelect = wrapper.findWhere((w) => w.prop('name') === 'type')
-
- expect(typeSelect).toHaveLength(1)
- expect(typeSelect.prop('label')).toEqual('scheduling.appointment.type')
- expect(typeSelect.prop('options')[0].label).toEqual('scheduling.appointment.types.checkup')
- expect(typeSelect.prop('options')[0].value).toEqual('checkup')
- expect(typeSelect.prop('options')[1].label).toEqual('scheduling.appointment.types.emergency')
- expect(typeSelect.prop('options')[1].value).toEqual('emergency')
- expect(typeSelect.prop('options')[2].label).toEqual('scheduling.appointment.types.followUp')
- expect(typeSelect.prop('options')[2].value).toEqual('follow up')
- expect(typeSelect.prop('options')[3].label).toEqual('scheduling.appointment.types.routine')
- expect(typeSelect.prop('options')[3].value).toEqual('routine')
- expect(typeSelect.prop('options')[4].label).toEqual('scheduling.appointment.types.walkUp')
- expect(typeSelect.prop('options')[4].value).toEqual('walk up')
- })
-
- it('should render a reason text field input', () => {
- const reasonTextField = wrapper.findWhere((w) => w.prop('name') === 'reason')
-
- expect(reasonTextField).toHaveLength(1)
- expect(reasonTextField.prop('label')).toEqual('scheduling.appointment.reason')
- })
-
- it('should render a save button', () => {
- const saveButton = wrapper.find(Button).at(0)
-
- expect(saveButton).toHaveLength(1)
- expect(saveButton.text().trim()).toEqual('actions.save')
- })
-
- it('should render a cancel button', () => {
- const cancelButton = wrapper.find(Button).at(1)
-
- expect(cancelButton).toHaveLength(1)
- expect(cancelButton.text().trim()).toEqual('actions.cancel')
- })
- })
-
- describe('typeahead search', () => {
- it('should call the PatientRepository search when typeahead changes', () => {
- const patientTypeahead = wrapper.find(Typeahead)
- const patientRepositorySearch = jest.spyOn(PatientRepository, 'search')
- const expectedSearchString = 'search'
-
- act(() => {
- patientTypeahead.prop('onSearch')(expectedSearchString)
- })
-
- expect(patientRepositorySearch).toHaveBeenCalledWith(expectedSearchString)
+ it('should render a Appointment Detail Component', () => {
+ expect(AppointmentDetailForm).toHaveLength(1)
})
})
describe('on save click', () => {
- it('should call createAppointment with the proper date', () => {
+ it('should call createAppointment with the proper data', () => {
+ const expectedAppointmentDetails = {
+ patientId: '123',
+ startDateTime: roundToNearestMinutes(new Date(), { nearestTo: 15 }).toISOString(),
+ endDateTime: addMinutes(
+ roundToNearestMinutes(new Date(), { nearestTo: 15 }),
+ 60,
+ ).toISOString(),
+ location: 'location',
+ reason: 'reason',
+ type: 'type',
+ } as Appointment
const createAppointmentSpy = jest.spyOn(appointmentsSlice, 'createAppointment')
- const expectedPatientId = '123'
- const expectedStartDateTime = roundToNearestMinutes(new Date(), { nearestTo: 15 })
- const expectedEndDateTime = addMinutes(expectedStartDateTime, 30)
- const expectedLocation = 'location'
- const expectedType = 'follow up'
- const expectedReason = 'reason'
act(() => {
- const patientTypeahead = wrapper.find(Typeahead)
- patientTypeahead.prop('onChange')([{ id: expectedPatientId }] as Patient[])
- })
- wrapper.update()
-
- act(() => {
- const startDateTimePicker = wrapper.findWhere((w) => w.prop('name') === 'startDate')
- startDateTimePicker.prop('onChange')(expectedStartDateTime)
- })
- wrapper.update()
-
- act(() => {
- const endDateTimePicker = wrapper.findWhere((w) => w.prop('name') === 'endDate')
- endDateTimePicker.prop('onChange')(expectedEndDateTime)
- })
- wrapper.update()
-
- act(() => {
- const locationTextInputBox = wrapper.findWhere((w) => w.prop('name') === 'location')
- locationTextInputBox.prop('onChange')({ target: { value: expectedLocation } })
- })
- wrapper.update()
-
- act(() => {
- const typeSelect = wrapper.findWhere((w) => w.prop('name') === 'type')
- typeSelect.prop('onChange')({ currentTarget: { value: expectedType } })
- })
- wrapper.update()
-
- act(() => {
- const reasonTextField = wrapper.findWhere((w) => w.prop('name') === 'reason')
- reasonTextField.prop('onChange')({ target: { value: expectedReason } })
+ const appointmentDetailForm = wrapper.find(AppointmentDetailForm)
+ const appointmentChangeHandler = appointmentDetailForm.prop('onAppointmentChange')
+ appointmentChangeHandler(expectedAppointmentDetails)
})
wrapper.update()
@@ -189,17 +84,11 @@ describe('New Appointment', () => {
const onClick = saveButton.prop('onClick') as any
onClick()
})
+ wrapper.update()
expect(createAppointmentSpy).toHaveBeenCalledTimes(1)
expect(createAppointmentSpy).toHaveBeenCalledWith(
- {
- patientId: expectedPatientId,
- startDateTime: expectedStartDateTime.toISOString(),
- endDateTime: expectedEndDateTime.toISOString(),
- location: expectedLocation,
- reason: expectedReason,
- type: expectedType,
- },
+ expectedAppointmentDetails,
expect.anything(),
)
})
@@ -224,20 +113,12 @@ describe('New Appointment', () => {
const expectedEndDateTime = subDays(expectedStartDateTime, 1)
act(() => {
- const patientTypeahead = wrapper.find(Typeahead)
- patientTypeahead.prop('onChange')([{ id: expectedPatientId }] as Patient[])
- })
- wrapper.update()
-
- act(() => {
- const startDateTimePicker = wrapper.findWhere((w) => w.prop('name') === 'startDate')
- startDateTimePicker.prop('onChange')(expectedStartDateTime)
- })
- wrapper.update()
-
- act(() => {
- const endDateTimePicker = wrapper.findWhere((w) => w.prop('name') === 'endDate')
- endDateTimePicker.prop('onChange')(expectedEndDateTime)
+ const onAppointmentChange = wrapper.find(AppointmentDetailForm).prop('onAppointmentChange')
+ onAppointmentChange({
+ patientId: expectedPatientId,
+ startDateTime: expectedStartDateTime.toISOString(),
+ endDateTime: expectedEndDateTime.toISOString(),
+ } as Appointment)
})
wrapper.update()
diff --git a/src/scheduling/appointments/new/NewAppointment.tsx b/src/scheduling/appointments/new/NewAppointment.tsx
index e434f68d3b..538ae33f98 100644
--- a/src/scheduling/appointments/new/NewAppointment.tsx
+++ b/src/scheduling/appointments/new/NewAppointment.tsx
@@ -1,20 +1,16 @@
import React, { useState } from 'react'
import useTitle from 'page-header/useTitle'
import { useTranslation } from 'react-i18next'
-import DateTimePickerWithLabelFormGroup from 'components/input/DateTimePickerWithLabelFormGroup'
-import { Typeahead, Label, Button, Alert } from '@hospitalrun/components'
-import Patient from 'model/Patient'
-import PatientRepository from 'clients/db/PatientRepository'
-import TextInputWithLabelFormGroup from 'components/input/TextInputWithLabelFormGroup'
-import TextFieldWithLabelFormGroup from 'components/input/TextFieldWithLabelFormGroup'
-import SelectWithLabelFormGroup from 'components/input/SelectWithLableFormGroup'
+
import roundToNearestMinutes from 'date-fns/roundToNearestMinutes'
import { useHistory } from 'react-router'
import { useDispatch } from 'react-redux'
import Appointment from 'model/Appointment'
import addMinutes from 'date-fns/addMinutes'
import { isBefore } from 'date-fns'
+import { Button, Alert } from '@hospitalrun/components'
import { createAppointment } from '../appointments-slice'
+import AppointmentDetailForm from '../AppointmentDetailForm'
const NewAppointment = () => {
const { t } = useTranslation()
@@ -65,96 +61,11 @@ const NewAppointment = () => {
message={errorMessage}
/>
)}
-
-
-
-
-
{
- setAppointment({ ...appointment, patientId: patient[0].id })
- }}
- onSearch={async (query: string) => PatientRepository.search(query)}
- searchAccessor="fullName"
- renderMenuItemChildren={(patient: Patient) => (
- {`${patient.fullName} (${patient.friendlyId})`}
- )}
- />
-
-
-
-
-
- {
- setAppointment({ ...appointment, startDateTime: date.toISOString() })
- }}
- />
-
-
- {
- setAppointment({ ...appointment, endDateTime: date.toISOString() })
- }}
- />
-
-
-
-
- {
- setAppointment({ ...appointment, location: event?.target.value })
- }}
- />
-
-
-
-
- ) => {
- setAppointment({ ...appointment, type: event.currentTarget.value })
- }}
- />
-
-
-
-
-
- {
- setAppointment({ ...appointment, reason: event?.target.value })
- }}
- />
-
-
-
+
+