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

Commit

Permalink
Browse files Browse the repository at this point in the history
…rontend into breadcrumbs
  • Loading branch information
oliv37 committed Feb 9, 2020
2 parents a68ed7e + 1f1ea4a commit 3e43558
Show file tree
Hide file tree
Showing 33 changed files with 981 additions and 1,015 deletions.
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

<div align="center">

[![Release](https://img.shields.io/github/release/HospitalRun/hospitalrun-frontend.svg)](https://github.com/HospitalRun/hospitalrun-frontend/releases) [![Version](https://img.shields.io/github/package-json/v/hospitalrun/hospitalrun-frontend)](https://github.com/HospitalRun/hospitalrun-frontend/releases)
![Status](https://img.shields.io/badge/Status-developing-brightgree) [![GitHub CI](https://github.com/HospitalRun/frontend/workflows/GitHub%20CI/badge.svg)](https://github.com/HospitalRun/frontend/actions) [![Build Status](https://dev.azure.com/HospitalRun/hospitalrun-frontend/_apis/build/status/HospitalRun.hospitalrun-frontend?branchName=master)](https://dev.azure.com/HospitalRun/hospitalrun-frontend/_build/latest?definitionId=3&branchName=master) [![Build Status](https://travis-ci.com/HospitalRun/hospitalrun-frontend.svg?branch=master)](https://travis-ci.com/HospitalRun/hospitalrun-frontend) [![Coverage Status](https://coveralls.io/repos/github/HospitalRun/hospitalrun-frontend/badge.svg?branch=master)](https://coveralls.io/github/HospitalRun/hospitalrun-frontend?branch=master) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FHospitalRun%2Fhospitalrun-frontend.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FHospitalRun%2Fhospitalrun-frontend?ref=badge_large) [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release) ![dependabot](https://api.dependabot.com/badges/status?host=github&repo=HospitalRun/frontend) [![Slack](https://hospitalrun-slack.herokuapp.com/badge.svg)](https://hospitalrun-slack.herokuapp.com) [![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/hospitalrun) [![Run on Repl.it](https://repl.it/badge/github/HospitalRun/hospitalrun-frontend)](https://repl.it/github/HospitalRun/hospitalrun-frontend)
![Status](https://img.shields.io/badge/Status-developing-brightgree) [![Release](https://img.shields.io/github/release/HospitalRun/hospitalrun-frontend.svg)](https://github.com/HospitalRun/hospitalrun-frontend/releases) [![Version](https://img.shields.io/github/package-json/v/hospitalrun/hospitalrun-frontend)](https://github.com/HospitalRun/hospitalrun-frontend/releases)
[![GitHub CI](https://github.com/HospitalRun/frontend/workflows/GitHub%20CI/badge.svg)](https://github.com/HospitalRun/frontend/actions) [![Build Status](https://dev.azure.com/HospitalRun/hospitalrun-frontend/_apis/build/status/HospitalRun.hospitalrun-frontend?branchName=master)](https://dev.azure.com/HospitalRun/hospitalrun-frontend/_build/latest?definitionId=3&branchName=master) [![Build Status](https://travis-ci.com/HospitalRun/hospitalrun-frontend.svg?branch=master)](https://travis-ci.com/HospitalRun/hospitalrun-frontend) [![Coverage Status](https://coveralls.io/repos/github/HospitalRun/hospitalrun-frontend/badge.svg?branch=master)](https://coveralls.io/github/HospitalRun/hospitalrun-frontend?branch=master) [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/HospitalRun/hospitalrun-frontend.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/HospitalRun/hospitalrun-frontend/context:javascript) [![Documentation Status](https://readthedocs.org/projects/hospitalrun-frontend/badge/?version=latest)](https://hospitalrun-frontend.readthedocs.io)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FHospitalRun%2Fhospitalrun-frontend.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FHospitalRun%2Fhospitalrun-frontend?ref=badge_large) [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
![dependabot](https://api.dependabot.com/badges/status?host=github&repo=HospitalRun/hospitalrun-frontend) [![Slack](https://hospitalrun-slack.herokuapp.com/badge.svg)](https://hospitalrun-slack.herokuapp.com) [![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/hospitalrun) [![Run on Repl.it](https://repl.it/badge/github/HospitalRun/hospitalrun-frontend)](https://repl.it/github/HospitalRun/hospitalrun-frontend)

</div>

Expand All @@ -27,15 +28,12 @@ Contributions are always welcome. Before contributing please read our [contribut
4. Run `yarn run start` to build and watch for code changes

## Working on an Issue

In order to optimize the workflow and to prevent multiple contributors working on the same issue without interactions, a contributor must ask to be assigned to an issue by one of the core team members: it's enough to ask it inside the specific issue.

## How to commit

This repo uses [Conventional Commits](https://www.conventionalcommits.org/). [Commitizen](https://github.com/commitizen/cz-cli) is recommended for development. Once you have changes staged
you can run `git cz` from the root directory in order to commit to the proper standards.

Alternatively, if you are using NPM 5.2+ you can use [npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) instead of installing globally:
`npx git-cz`
This repo uses Conventional Commits. Commitizen is mandatory for making proper commits. Once you have staged your changes, can run npm run commit or yarn commit from the root directory in order to commit following our standards.

<hr />

Expand Down
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Hospitalrun Frontend Documentation
13 changes: 13 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
site_name: HospitalRun
site_url: https://hospitalrun.io
site_description: HospitalRun project documentation
site_author: HospitalRun Core Team

repo_url: https://github.com/hospitalrun/hospitalrun-frontend/

theme:
name: readthedocs
highlightjs: true

plugins:
- search
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
"eslint-config-airbnb": "~18.0.1",
"eslint-config-prettier": "~6.10.0",
"eslint-plugin-import": "~2.20.0",
"eslint-plugin-jest": "~23.6.0",
"eslint-plugin-jest": "~23.7.0",
"eslint-plugin-jsx-a11y": "~6.2.3",
"eslint-plugin-prettier": "~3.1.1",
"eslint-plugin-react": "~7.18.0",
Expand Down
10 changes: 10 additions & 0 deletions src/HospitalRun.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Permissions from './model/Permissions'
import Dashboard from './dashboard/Dashboard'
import Patients from './patients/list/Patients'
import NewPatient from './patients/new/NewPatient'
import EditPatient from './patients/edit/EditPatient'
import ViewPatient from './patients/view/ViewPatient'
import { RootState } from './store'
import Navbar from './components/Navbar'
Expand Down Expand Up @@ -45,6 +46,15 @@ const HospitalRun = () => {
path="/patients/new"
component={NewPatient}
/>
<PrivateRoute
isAuthenticated={
permissions.includes(Permissions.WritePatients) &&
permissions.includes(Permissions.ReadPatients)
}
exact
path="/patients/edit/:id"
component={EditPatient}
/>
<PrivateRoute
isAuthenticated={permissions.includes(Permissions.ReadPatients)}
path="/patients/:id"
Expand Down
68 changes: 68 additions & 0 deletions src/__tests__/HospitalRun.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Dashboard from 'dashboard/Dashboard'
import Appointments from 'scheduling/appointments/Appointments'
import NewAppointment from 'scheduling/appointments/new/NewAppointment'
import NewPatient from '../patients/new/NewPatient'
import EditPatient from '../patients/edit/EditPatient'
import ViewPatient from '../patients/view/ViewPatient'
import PatientRepository from '../clients/db/PatientRepository'
import Patient from '../model/Patient'
Expand Down Expand Up @@ -57,6 +58,73 @@ describe('HospitalRun', () => {
})
})

describe('/patients/edit/:id', () => {
it('should render the edit patient screen when /patients/edit/:id is accessed', () => {
jest.spyOn(PatientRepository, 'find')
const mockedPatientRepository = mocked(PatientRepository, true)
const patient = {
id: '123',
prefix: 'test',
givenName: 'test',
familyName: 'test',
suffix: 'test',
friendlyId: 'P00001',
} as Patient

mockedPatientRepository.find.mockResolvedValue(patient)

const wrapper = mount(
<Provider
store={mockStore({
title: 'test',
user: { permissions: [Permissions.WritePatients, Permissions.ReadPatients] },
patient: { patient: {} as Patient },
})}
>
<MemoryRouter initialEntries={['/patients/edit/123']}>
<HospitalRun />
</MemoryRouter>
</Provider>,
)

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

it('should render the Dashboard when the user does not have read patient privileges', () => {
const wrapper = mount(
<Provider
store={mockStore({
title: 'test',
user: { permissions: [Permissions.WritePatients] },
})}
>
<MemoryRouter initialEntries={['/patients/edit/123']}>
<HospitalRun />
</MemoryRouter>
</Provider>,
)

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

it('should render the Dashboard when the user does not have read patient privileges', () => {
const wrapper = mount(
<Provider
store={mockStore({
title: 'test',
user: { permissions: [Permissions.ReadPatients] },
})}
>
<MemoryRouter initialEntries={['/patients/edit/123']}>
<HospitalRun />
</MemoryRouter>
</Provider>,
)

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

describe('/patients/:id', () => {
it('should render the view patient screen when /patients/:id is accessed', async () => {
jest.spyOn(PatientRepository, 'find')
Expand Down
182 changes: 182 additions & 0 deletions src/__tests__/patients/GeneralInformation.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import '../../__mocks__/matchMediaMock'
import React from 'react'
import { Router } from 'react-router'
import { mount, ReactWrapper } from 'enzyme'
import GeneralInformation from 'patients/GeneralInformation'
import { createMemoryHistory } from 'history'
import { Alert } from '@hospitalrun/components'
import { act } from '@testing-library/react'
import Patient from '../../model/Patient'

describe('Error handling', () => {
it('should display no given name error when errorMessage prop is non-empty string', () => {
const history = createMemoryHistory()
const wrapper = mount(
<Router history={history}>
<GeneralInformation
patient={{} as Patient}
isEditable
errorMessage="patient.errors.patientGivenNameRequired"
/>
</Router>,
)

const errorMessage = wrapper.find(Alert)
expect(errorMessage).toBeTruthy()
expect(errorMessage.prop('message')).toMatch('patient.errors.patientGivenNameRequired')
})
})

describe('General Information', () => {
const patient = {
id: '123',
prefix: 'prefix',
givenName: 'givenName',
familyName: 'familyName',
suffix: 'suffix',
sex: 'male',
type: 'charity',
occupation: 'occupation',
preferredLanguage: 'preferredLanguage',
phoneNumber: 'phoneNumber',
email: 'email@email.com',
address: 'address',
friendlyId: 'P00001',
dateOfBirth: new Date().toISOString(),
isApproximateDateOfBirth: false,
} as Patient

let wrapper: ReactWrapper
let history = createMemoryHistory()

beforeEach(() => {
history = createMemoryHistory()
wrapper = mount(
<Router history={history}>
<GeneralInformation patient={patient} />)
</Router>,
)
})

beforeEach(() => {
jest.restoreAllMocks()
})

it('should render the prefix', () => {
const prefixInput = wrapper.findWhere((w: any) => w.prop('name') === 'prefix')
expect(prefixInput.prop('value')).toEqual(patient.prefix)
expect(prefixInput.prop('label')).toEqual('patient.prefix')
expect(prefixInput.prop('isEditable')).toBeFalsy()
})

it('should render the given name', () => {
const givenNameInput = wrapper.findWhere((w: any) => w.prop('name') === 'givenName')
expect(givenNameInput.prop('value')).toEqual(patient.givenName)
expect(givenNameInput.prop('label')).toEqual('patient.givenName')
expect(givenNameInput.prop('isEditable')).toBeFalsy()
})

it('should render the family name', () => {
const familyNameInput = wrapper.findWhere((w: any) => w.prop('name') === 'familyName')
expect(familyNameInput.prop('value')).toEqual(patient.familyName)
expect(familyNameInput.prop('label')).toEqual('patient.familyName')
expect(familyNameInput.prop('isEditable')).toBeFalsy()
})

it('should render the suffix', () => {
const suffixInput = wrapper.findWhere((w: any) => w.prop('name') === 'suffix')
expect(suffixInput.prop('value')).toEqual(patient.suffix)
expect(suffixInput.prop('label')).toEqual('patient.suffix')
expect(suffixInput.prop('isEditable')).toBeFalsy()
})

it('should render the sex select', () => {
const sexSelect = wrapper.findWhere((w: any) => w.prop('name') === 'sex')
expect(sexSelect.prop('value')).toEqual(patient.sex)
expect(sexSelect.prop('label')).toEqual('patient.sex')
expect(sexSelect.prop('isEditable')).toBeFalsy()
expect(sexSelect.prop('options')).toHaveLength(4)
expect(sexSelect.prop('options')[0].label).toEqual('sex.male')
expect(sexSelect.prop('options')[0].value).toEqual('male')
expect(sexSelect.prop('options')[1].label).toEqual('sex.female')
expect(sexSelect.prop('options')[1].value).toEqual('female')
expect(sexSelect.prop('options')[2].label).toEqual('sex.other')
expect(sexSelect.prop('options')[2].value).toEqual('other')
expect(sexSelect.prop('options')[3].label).toEqual('sex.unknown')
expect(sexSelect.prop('options')[3].value).toEqual('unknown')
})

it('should render the patient type select', () => {
const typeSelect = wrapper.findWhere((w: any) => w.prop('name') === 'type')
expect(typeSelect.prop('value')).toEqual(patient.type)
expect(typeSelect.prop('label')).toEqual('patient.type')
expect(typeSelect.prop('isEditable')).toBeFalsy()
expect(typeSelect.prop('options')).toHaveLength(2)
expect(typeSelect.prop('options')[0].label).toEqual('patient.types.charity')
expect(typeSelect.prop('options')[0].value).toEqual('charity')
expect(typeSelect.prop('options')[1].label).toEqual('patient.types.private')
expect(typeSelect.prop('options')[1].value).toEqual('private')
})

it('should render the date of the birth of the patient', () => {
const dateOfBirthInput = wrapper.findWhere((w: any) => w.prop('name') === 'dateOfBirth')
expect(dateOfBirthInput.prop('value')).toEqual(new Date(patient.dateOfBirth))
expect(dateOfBirthInput.prop('label')).toEqual('patient.dateOfBirth')
expect(dateOfBirthInput.prop('isEditable')).toBeFalsy()
})

it('should render the occupation of the patient', () => {
const occupationInput = wrapper.findWhere((w: any) => w.prop('name') === 'occupation')
expect(occupationInput.prop('value')).toEqual(patient.occupation)
expect(occupationInput.prop('label')).toEqual('patient.occupation')
expect(occupationInput.prop('isEditable')).toBeFalsy()
})

it('should render the preferred language of the patient', () => {
const preferredLanguageInput = wrapper.findWhere(
(w: any) => w.prop('name') === 'preferredLanguage',
)
expect(preferredLanguageInput.prop('value')).toEqual(patient.preferredLanguage)
expect(preferredLanguageInput.prop('label')).toEqual('patient.preferredLanguage')
expect(preferredLanguageInput.prop('isEditable')).toBeFalsy()
})

it('should render the phone number of the patient', () => {
const phoneNumberInput = wrapper.findWhere((w: any) => w.prop('name') === 'phoneNumber')
expect(phoneNumberInput.prop('value')).toEqual(patient.phoneNumber)
expect(phoneNumberInput.prop('label')).toEqual('patient.phoneNumber')
expect(phoneNumberInput.prop('isEditable')).toBeFalsy()
})

it('should render the email of the patient', () => {
const emailInput = wrapper.findWhere((w: any) => w.prop('name') === 'email')
expect(emailInput.prop('value')).toEqual(patient.email)
expect(emailInput.prop('label')).toEqual('patient.email')
expect(emailInput.prop('isEditable')).toBeFalsy()
})

it('should render the address of the patient', () => {
const addressInput = wrapper.findWhere((w: any) => w.prop('name') === 'address')
expect(addressInput.prop('value')).toEqual(patient.address)
expect(addressInput.prop('label')).toEqual('patient.address')
expect(addressInput.prop('isEditable')).toBeFalsy()
})

it('should render the age and date of birth as approximate if patient.isApproximateDateOfBirth is true', async () => {
patient.isApproximateDateOfBirth = true
await act(async () => {
wrapper = await mount(
<Router history={history}>
<GeneralInformation patient={patient} />)
</Router>,
)
})

wrapper.update()

const ageInput = wrapper.findWhere((w: any) => w.prop('name') === 'approximateAge')
expect(ageInput.prop('value')).toEqual('0')
expect(ageInput.prop('label')).toEqual('patient.approximateAge')
expect(ageInput.prop('isEditable')).toBeFalsy()
})
})

0 comments on commit 3e43558

Please sign in to comment.