diff --git a/src/__tests__/labs/ViewLab.test.tsx b/src/__tests__/labs/ViewLab.test.tsx index 464494bcdf..dfe0a126bf 100644 --- a/src/__tests__/labs/ViewLab.test.tsx +++ b/src/__tests__/labs/ViewLab.test.tsx @@ -1,7 +1,6 @@ -import { Badge, Button, Alert } from '@hospitalrun/components' -import { act } from '@testing-library/react' +import { render, screen, waitFor } from '@testing-library/react' +import userEvent from '@testing-library/user-event' import format from 'date-fns/format' -import { mount, ReactWrapper } from 'enzyme' import { createMemoryHistory } from 'history' import React from 'react' import { Provider } from 'react-redux' @@ -14,7 +13,6 @@ import { LabError } from '../../labs/utils/validate-lab' import ViewLab from '../../labs/ViewLab' import * as ButtonBarProvider from '../../page-header/button-toolbar/ButtonBarProvider' import * as titleUtil from '../../page-header/title/TitleContext' -import TextFieldWithLabelFormGroup from '../../shared/components/input/TextFieldWithLabelFormGroup' import LabRepository from '../../shared/db/LabRepository' import PatientRepository from '../../shared/db/PatientRepository' import Lab from '../../shared/model/Lab' @@ -42,7 +40,7 @@ describe('View Lab', () => { let labRepositorySaveSpy: any const expectedDate = new Date() - const setup = async (lab: Lab, permissions: Permissions[], error = {}) => { + const setup = (lab: Lab, permissions: Permissions[], error = {}) => { jest.resetAllMocks() Date.now = jest.fn(() => expectedDate.valueOf()) setButtonToolBarSpy = jest.fn() @@ -66,80 +64,71 @@ describe('View Lab', () => { }, } as any) - let wrapper: any - await act(async () => { - wrapper = await mount( - - - - - - - - - - - , - ) - }) - wrapper.find(ViewLab).props().updateTitle = jest.fn() - wrapper.update() - return { wrapper: wrapper as ReactWrapper } + return render( + + + + + + + + + + + , + ) } - describe('title', () => { - it('should have called the useUpdateTitle hook', async () => { - const expectedLab = { ...mockLab } as Lab - await setup(expectedLab, [Permissions.ViewLab]) - expect(titleUtil.useUpdateTitle).toHaveBeenCalled() - }) - }) - describe('page content', () => { - it('should display the patient full name for the for', async () => { + it("should display the patients' full name", async () => { const expectedLab = { ...mockLab } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - const forPatientDiv = wrapper.find('.for-patient') - - expect(forPatientDiv.find('h4').text().trim()).toEqual('labs.lab.for') + setup(expectedLab, [Permissions.ViewLab]) - expect(forPatientDiv.find('h5').text().trim()).toEqual(mockPatient.fullName) + await waitFor(() => { + expect(screen.getByText('labs.lab.for')).toBeInTheDocument() + expect(screen.getByText(mockPatient.fullName)).toBeInTheDocument() + }) }) - it('should display the lab type for type', async () => { + it('should display the lab-type', async () => { const expectedLab = { ...mockLab, type: 'expected type' } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - const labTypeDiv = wrapper.find('.lab-type') - expect(labTypeDiv.find('h4').text().trim()).toEqual('labs.lab.type') + setup(expectedLab, [Permissions.ViewLab]) - expect(labTypeDiv.find('h5').text().trim()).toEqual(expectedLab.type) + await waitFor(() => { + expect(screen.getByRole('heading', { name: /labs.lab.type/i })).toBeInTheDocument() + expect(screen.getByText(expectedLab.type)).toBeInTheDocument() + }) }) it('should display the requested on date', async () => { const expectedLab = { ...mockLab, requestedOn: '2020-03-30T04:43:20.102Z' } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - const requestedOnDiv = wrapper.find('.requested-on') - expect(requestedOnDiv.find('h4').text().trim()).toEqual('labs.lab.requestedOn') + setup(expectedLab, [Permissions.ViewLab]) - expect(requestedOnDiv.find('h5').text().trim()).toEqual( - format(new Date(expectedLab.requestedOn), 'yyyy-MM-dd hh:mm a'), - ) + await waitFor(() => { + expect(screen.getByText('labs.lab.requestedOn')).toBeInTheDocument() + expect( + screen.getByText(format(new Date(expectedLab.requestedOn), 'yyyy-MM-dd hh:mm a')), + ).toBeInTheDocument() + }) }) it('should not display the completed date if the lab is not completed', async () => { const expectedLab = { ...mockLab } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - const completedOnDiv = wrapper.find('.completed-on') + const { container } = setup(expectedLab, [Permissions.ViewLab]) - expect(completedOnDiv).toHaveLength(0) + await waitFor(() => { + // TODO: make sure it's not loading + expect(container.querySelector('.completed-on')).not.toBeInTheDocument() + }) }) it('should not display the canceled date if the lab is not canceled', async () => { const expectedLab = { ...mockLab } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - const completedOnDiv = wrapper.find('.canceled-on') + const { container } = setup(expectedLab, [Permissions.ViewLab]) - expect(completedOnDiv).toHaveLength(0) + await waitFor(() => { + expect(container.querySelector('.canceled-on')).not.toBeInTheDocument() + }) }) it('should render a result text field', async () => { @@ -147,114 +136,121 @@ describe('View Lab', () => { ...mockLab, result: 'expected results', } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - - const resultTextField = wrapper.find(TextFieldWithLabelFormGroup).at(0) - - expect(resultTextField).toBeDefined() - expect(resultTextField.prop('label')).toEqual('labs.lab.result') - expect(resultTextField.prop('value')).toEqual(expectedLab.result) + setup(expectedLab, [Permissions.ViewLab]) + + await waitFor(() => { + expect( + screen.getByRole('textbox', { + name: /labs\.lab\.result/i, + }), + ).toHaveValue(expectedLab.result) + }) }) it('should display the past notes', async () => { const expectedNotes = 'expected notes' const expectedLab = { ...mockLab, notes: [expectedNotes] } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - - const notes = wrapper.findWhere((w) => w.prop('data-test') === 'note') - const pastNotesIndex = notes.reduce( - (result: number, item: ReactWrapper, index: number) => - item.text().trim() === expectedNotes ? index : result, - -1, - ) + const { container } = setup(expectedLab, [Permissions.ViewLab]) - expect(pastNotesIndex).not.toBe(-1) - expect(notes).toHaveLength(1) + await waitFor(() => { + expect(screen.getByText(expectedNotes)).toBeInTheDocument() + expect(container.querySelector('.callout')).toBeInTheDocument() + }) }) it('should not display past notes if there is not', async () => { const expectedLab = { ...mockLab, notes: undefined } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - - const notes = wrapper.findWhere((w) => w.prop('data-test') === 'note') + const { container } = setup(expectedLab, [Permissions.ViewLab]) - expect(notes).toHaveLength(0) + await waitFor(() => { + // TODO: make sure it's not loading + expect(container.querySelector('.callout')).not.toBeInTheDocument() + }) }) it('should display the notes text field empty', async () => { const expectedNotes = 'expected notes' const expectedLab = { ...mockLab, notes: [expectedNotes] } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - - const notesTextField = wrapper.find(TextFieldWithLabelFormGroup).at(1) + setup(expectedLab, [Permissions.ViewLab]) - expect(notesTextField).toBeDefined() - expect(notesTextField.prop('value')).toEqual('') + await waitFor(() => { + expect(screen.getByLabelText('labs.lab.notes')).toHaveValue('') + }) }) it('should display errors', async () => { const expectedLab = { ...mockLab, status: 'requested' } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab, Permissions.CompleteLab]) + setup(expectedLab, [Permissions.ViewLab, Permissions.CompleteLab]) const expectedError = { message: 'some message', result: 'some result feedback' } as LabError expectOneConsoleError(expectedError) jest.spyOn(validateUtil, 'validateLabComplete').mockReturnValue(expectedError) - const completeButton = wrapper.find(Button).at(1) - await act(async () => { - const onClick = completeButton.prop('onClick') as any - await onClick() + await waitFor(() => { + userEvent.click( + screen.getByRole('button', { + name: /labs\.requests\.complete/i, + }), + ) }) - wrapper.update() - - const alert = wrapper.find(Alert) - const resultTextField = wrapper.find(TextFieldWithLabelFormGroup).at(0) - expect(alert.prop('message')).toEqual(expectedError.message) - expect(alert.prop('title')).toEqual('states.error') - expect(alert.prop('color')).toEqual('danger') - expect(resultTextField.prop('isInvalid')).toBeTruthy() - expect(resultTextField.prop('feedback')).toEqual(expectedError.result) + + const alert = await screen.findByRole('alert') + + expect(alert).toContainElement(screen.getByText(/states\.error/i)) + expect(alert).toContainElement(screen.getByText(/some message/i)) + + expect(screen.getByLabelText(/labs\.lab\.result/i)).toHaveClass('is-invalid') }) describe('requested lab request', () => { it('should display a warning badge if the status is requested', async () => { const expectedLab = { ...mockLab, status: 'requested' } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - const labStatusDiv = wrapper.find('.lab-status') - const badge = labStatusDiv.find(Badge) - expect(labStatusDiv.find('h4').text().trim()).toEqual('labs.lab.status') - - expect(badge.prop('color')).toEqual('warning') - expect(badge.text().trim()).toEqual(expectedLab.status) + setup(expectedLab, [Permissions.ViewLab]) + + await waitFor(() => { + expect( + screen.getByRole('heading', { + name: /labs\.lab\.status/i, + }), + ).toBeInTheDocument() + expect(screen.getByText(expectedLab.status)).toBeInTheDocument() + }) }) it('should display a update lab, complete lab, and cancel lab button if the lab is in a requested state', async () => { - const { wrapper } = await setup(mockLab, [ - Permissions.ViewLab, - Permissions.CompleteLab, - Permissions.CancelLab, - ]) - - const buttons = wrapper.find(Button) - expect(buttons.at(0).text().trim()).toEqual('actions.update') - - expect(buttons.at(1).text().trim()).toEqual('labs.requests.complete') - - expect(buttons.at(2).text().trim()).toEqual('labs.requests.cancel') + setup(mockLab, [Permissions.ViewLab, Permissions.CompleteLab, Permissions.CancelLab]) + + await waitFor(() => { + screen.getByRole('button', { + name: /actions\.update/i, + }) + screen.getByRole('button', { + name: /actions\.update/i, + }) + screen.getByRole('button', { + name: /actions\.update/i, + }) + }) }) }) describe('canceled lab request', () => { it('should display a danger badge if the status is canceled', async () => { const expectedLab = { ...mockLab, status: 'canceled' } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - - const labStatusDiv = wrapper.find('.lab-status') - const badge = labStatusDiv.find(Badge) - expect(labStatusDiv.find('h4').text().trim()).toEqual('labs.lab.status') - - expect(badge.prop('color')).toEqual('danger') - expect(badge.text().trim()).toEqual(expectedLab.status) + setup(expectedLab, [Permissions.ViewLab]) + + await waitFor(() => { + expect( + screen.getByRole('heading', { + name: /labs\.lab\.status/i, + }), + ).toBeInTheDocument() + expect( + screen.getByRole('heading', { + name: /canceled/i, + }), + ).toBeInTheDocument() + }) }) it('should display the canceled on date if the lab request has been canceled', async () => { @@ -263,47 +259,39 @@ describe('View Lab', () => { status: 'canceled', canceledOn: '2020-03-30T04:45:20.102Z', } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - const canceledOnDiv = wrapper.find('.canceled-on') - - expect(canceledOnDiv.find('h4').text().trim()).toEqual('labs.lab.canceledOn') - - expect(canceledOnDiv.find('h5').text().trim()).toEqual( - format(new Date(expectedLab.canceledOn as string), 'yyyy-MM-dd hh:mm a'), - ) + setup(expectedLab, [Permissions.ViewLab]) + + await waitFor(() => { + expect( + screen.getByRole('heading', { + name: /labs\.lab\.canceledon/i, + }), + ).toBeInTheDocument() + expect( + screen.getByRole('heading', { + name: format(new Date(expectedLab.canceledOn as string), 'yyyy-MM-dd hh:mm a'), + }), + ).toBeInTheDocument() + }) }) it('should not display update, complete, and cancel button if the lab is canceled', async () => { const expectedLab = { ...mockLab, status: 'canceled' } as Lab - const { wrapper } = await setup(expectedLab, [ - Permissions.ViewLab, - Permissions.CompleteLab, - Permissions.CancelLab, - ]) - - const buttons = wrapper.find(Button) - expect(buttons).toHaveLength(0) - }) - - it('should not display an update button if the lab is canceled', async () => { - const expectedLab = { ...mockLab, status: 'canceled' } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) + setup(expectedLab, [Permissions.ViewLab, Permissions.CompleteLab, Permissions.CancelLab]) - const updateButton = wrapper.find(Button) - expect(updateButton).toHaveLength(0) + await waitFor(() => { + expect(screen.queryByRole('button')).not.toBeInTheDocument() + }) }) it('should not display notes text field if the status is canceled', async () => { const expectedLab = { ...mockLab, status: 'canceled' } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - - const textsField = wrapper.find(TextFieldWithLabelFormGroup) - const notesTextField = wrapper.find('notesTextField') + setup(expectedLab, [Permissions.ViewLab]) - expect(textsField.length).toBe(1) - expect(notesTextField).toHaveLength(0) + expect(screen.getByText('labs.lab.notes')).toBeInTheDocument() + expect(screen.queryByLabelText('labs.lab.notes')).not.toBeInTheDocument() }) }) @@ -311,13 +299,12 @@ describe('View Lab', () => { it('should display a primary badge if the status is completed', async () => { jest.resetAllMocks() const expectedLab = { ...mockLab, status: 'completed' } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - const labStatusDiv = wrapper.find('.lab-status') - const badge = labStatusDiv.find(Badge) - expect(labStatusDiv.find('h4').text().trim()).toEqual('labs.lab.status') + setup(expectedLab, [Permissions.ViewLab]) - expect(badge.prop('color')).toEqual('primary') - expect(badge.text().trim()).toEqual(expectedLab.status) + await waitFor(() => { + expect(screen.getByRole('heading', { name: 'labs.lab.status' })).toBeInTheDocument() + expect(screen.getByText(expectedLab.status)).toBeInTheDocument() + }) }) it('should display the completed on date if the lab request has been completed', async () => { @@ -326,151 +313,126 @@ describe('View Lab', () => { status: 'completed', completedOn: '2020-03-30T04:44:20.102Z', } as Lab - const { wrapper } = await setup(expectedLab, [Permissions.ViewLab]) - const completedOnDiv = wrapper.find('.completed-on') - - expect(completedOnDiv.find('h4').text().trim()).toEqual('labs.lab.completedOn') - - expect(completedOnDiv.find('h5').text().trim()).toEqual( - format(new Date(expectedLab.completedOn as string), 'yyyy-MM-dd hh:mm a'), - ) + setup(expectedLab, [Permissions.ViewLab]) + + await waitFor(() => { + expect(screen.getByRole('heading', { name: 'labs.lab.completedOn' })).toBeInTheDocument() + expect( + screen.getByText( + format(new Date(expectedLab.completedOn as string), 'yyyy-MM-dd hh:mm a'), + ), + ).toBeInTheDocument() + }) }) it('should not display update, complete, and cancel buttons if the lab is completed', async () => { const expectedLab = { ...mockLab, status: 'completed' } as Lab - const { wrapper } = await setup(expectedLab, [ - Permissions.ViewLab, - Permissions.CompleteLab, - Permissions.CancelLab, - ]) + setup(expectedLab, [Permissions.ViewLab, Permissions.CompleteLab, Permissions.CancelLab]) - const buttons = wrapper.find(Button) - expect(buttons).toHaveLength(0) + await waitFor(() => { + expect(screen.queryByRole('button')).not.toBeInTheDocument() + }) }) it('should not display notes text field if the status is completed', async () => { const expectedLab = { ...mockLab, status: 'completed' } as Lab - const { wrapper } = await setup(expectedLab, [ - Permissions.ViewLab, - Permissions.CompleteLab, - Permissions.CancelLab, - ]) - - const textsField = wrapper.find(TextFieldWithLabelFormGroup) - const notesTextField = wrapper.find('notesTextField') + setup(expectedLab, [Permissions.ViewLab, Permissions.CompleteLab, Permissions.CancelLab]) - expect(textsField.length).toBe(1) - expect(notesTextField).toHaveLength(0) + expect(screen.getByText('labs.lab.notes')).toBeInTheDocument() + expect(screen.queryByLabelText('labs.lab.notes')).not.toBeInTheDocument() }) }) }) describe('on update', () => { it('should update the lab with the new information', async () => { - const { wrapper } = await setup(mockLab, [Permissions.ViewLab]) + setup(mockLab, [Permissions.ViewLab]) const expectedResult = 'expected result' const newNotes = 'expected notes' - const resultTextField = wrapper.find(TextFieldWithLabelFormGroup).at(0) - act(() => { - const onChange = resultTextField.prop('onChange') as any - onChange({ currentTarget: { value: expectedResult } }) - }) - wrapper.update() + const resultTextField = await screen.findByLabelText('labs.lab.result') - const notesTextField = wrapper.find(TextFieldWithLabelFormGroup).at(1) - act(() => { - const onChange = notesTextField.prop('onChange') as any - onChange({ currentTarget: { value: newNotes } }) - }) - wrapper.update() - const updateButton = wrapper.find(Button) - await act(async () => { - const onClick = updateButton.prop('onClick') as any - onClick() + userEvent.type(resultTextField, expectedResult) + + const notesTextField = screen.getByLabelText('labs.lab.notes') + userEvent.type(notesTextField, newNotes) + + const updateButton = screen.getByRole('button', { + name: 'actions.update', }) + userEvent.click(updateButton) const expectedNotes = mockLab.notes ? [...mockLab.notes, newNotes] : [newNotes] - expect(labRepositorySaveSpy).toHaveBeenCalledTimes(1) - expect(labRepositorySaveSpy).toHaveBeenCalledWith( - expect.objectContaining({ ...mockLab, result: expectedResult, notes: expectedNotes }), - ) - expect(history.location.pathname).toEqual('/labs/12456') + await waitFor(() => { + expect(labRepositorySaveSpy).toHaveBeenCalledTimes(1) + expect(labRepositorySaveSpy).toHaveBeenCalledWith( + expect.objectContaining({ ...mockLab, result: expectedResult, notes: expectedNotes }), + ) + expect(history.location.pathname).toEqual('/labs/12456') + }) }) }) describe('on complete', () => { it('should mark the status as completed and fill in the completed date with the current time', async () => { - const { wrapper } = await setup(mockLab, [ - Permissions.ViewLab, - Permissions.CompleteLab, - Permissions.CancelLab, - ]) + setup(mockLab, [Permissions.ViewLab, Permissions.CompleteLab, Permissions.CancelLab]) const expectedResult = 'expected result' - const resultTextField = wrapper.find(TextFieldWithLabelFormGroup).at(0) - await act(async () => { - const onChange = resultTextField.prop('onChange') as any - await onChange({ currentTarget: { value: expectedResult } }) - }) - wrapper.update() + const resultTextField = await screen.findByLabelText('labs.lab.result') - const completeButton = wrapper.find(Button).at(1) - await act(async () => { - const onClick = completeButton.prop('onClick') as any - await onClick() + userEvent.type(resultTextField, expectedResult) + + const completeButton = screen.getByRole('button', { + name: 'labs.requests.complete', }) - wrapper.update() - expect(labRepositorySaveSpy).toHaveBeenCalledTimes(1) - expect(labRepositorySaveSpy).toHaveBeenCalledWith( - expect.objectContaining({ - ...mockLab, - result: expectedResult, - status: 'completed', - completedOn: expectedDate.toISOString(), - }), - ) - expect(history.location.pathname).toEqual('/labs/12456') + userEvent.click(completeButton) + + await waitFor(() => { + expect(labRepositorySaveSpy).toHaveBeenCalledTimes(1) + expect(labRepositorySaveSpy).toHaveBeenCalledWith( + expect.objectContaining({ + ...mockLab, + result: expectedResult, + status: 'completed', + completedOn: expectedDate.toISOString(), + }), + ) + expect(history.location.pathname).toEqual('/labs/12456') + }) }) }) describe('on cancel', () => { it('should mark the status as canceled and fill in the cancelled on date with the current time', async () => { - const { wrapper } = await setup(mockLab, [ - Permissions.ViewLab, - Permissions.CompleteLab, - Permissions.CancelLab, - ]) + setup(mockLab, [Permissions.ViewLab, Permissions.CompleteLab, Permissions.CancelLab]) const expectedResult = 'expected result' - const resultTextField = wrapper.find(TextFieldWithLabelFormGroup).at(0) - await act(async () => { - const onChange = resultTextField.prop('onChange') as any - await onChange({ currentTarget: { value: expectedResult } }) - }) - wrapper.update() + const resultTextField = await screen.findByLabelText('labs.lab.result') - const cancelButton = wrapper.find(Button).at(2) - await act(async () => { - const onClick = cancelButton.prop('onClick') as any - await onClick() + userEvent.type(resultTextField, expectedResult) + + const completeButton = screen.getByRole('button', { + name: 'labs.requests.cancel', }) - wrapper.update() - expect(labRepositorySaveSpy).toHaveBeenCalledTimes(1) - expect(labRepositorySaveSpy).toHaveBeenCalledWith( - expect.objectContaining({ - ...mockLab, - result: expectedResult, - status: 'canceled', - canceledOn: expectedDate.toISOString(), - }), - ) - expect(history.location.pathname).toEqual('/labs') + userEvent.click(completeButton) + + await waitFor(() => { + expect(labRepositorySaveSpy).toHaveBeenCalledTimes(1) + expect(labRepositorySaveSpy).toHaveBeenCalledWith( + expect.objectContaining({ + ...mockLab, + result: expectedResult, + status: 'canceled', + canceledOn: expectedDate.toISOString(), + }), + ) + expect(history.location.pathname).toEqual('/labs') + }) }) }) })