diff --git a/pwa/src/App.tsx b/pwa/src/App.tsx index 2f614fd..0f251d0 100644 --- a/pwa/src/App.tsx +++ b/pwa/src/App.tsx @@ -10,6 +10,7 @@ import Wrapper from './Wrapper' import PatientInfoForm from './components/PatientInfoForm' import PatientSearch from './components/PatientSearch' import DiagnosisForm from './components/DiagnosisForm' +import TestResults from './components/TestResultsForm' import './scss/App.scss' import './antd-mobile.css' @@ -45,14 +46,24 @@ const App: React.FunctionComponent = () => { - - - - + + + + + + + + + diff --git a/pwa/src/components/TestResultsFields.json b/pwa/src/components/TestResultsFields.json new file mode 100644 index 0000000..da5b972 --- /dev/null +++ b/pwa/src/components/TestResultsFields.json @@ -0,0 +1,3 @@ +{ + "uaResultFields": ["Glucose", "Nitrites", "Protein", "Leukocytes"] +} diff --git a/pwa/src/components/TestResultsForm.test.tsx b/pwa/src/components/TestResultsForm.test.tsx new file mode 100644 index 0000000..6f3f96d --- /dev/null +++ b/pwa/src/components/TestResultsForm.test.tsx @@ -0,0 +1,184 @@ +import React from 'react' +import { render, fireEvent } from '@testing-library/react' +import TestResultsForm from './TestResultsForm' +import * as data from './TestResultsFields.json' + +const testText = [ + 'HCG \\(Pregnancy\\)', + 'Blood Sugar', + 'UA \\(Urine Analysis\\)', +] + +const testID = ['pregnancy-test', 'blood-sugar-test', 'ua-test'] + +test('renders the form', () => { + const dom = render() + expect(dom.getByTestId('test-results-form-wrapper')).toBeTruthy() +}) + +test('renders each test option as a checkbox and is able to be checked / unchecked', () => { + const { getByText, getByTestId } = render() + + testText.forEach((testName) => { + const re = new RegExp(testName, 'gi') + const field = getByText(re) + expect(field).toBeInTheDocument() + }) + + testID.forEach((testID) => { + const checkboxItem = getByTestId(testID) + expect(checkboxItem).toHaveClass('am-checkbox-item') + + const checkBox = checkboxItem.getElementsByTagName('span')[0] + expect(checkBox).not.toHaveClass('am-checkbox-checked') + const checkBoxInput = checkboxItem.getElementsByClassName( + 'am-checkbox-input', + )[0] + fireEvent.click(checkBoxInput) + expect(checkBox).toHaveClass('am-checkbox-checked') + }) +}) + +test('pregnancy-results div is only displayed if pregnancy test is selected', () => { + const { getByTestId, queryByTestId } = render() + + // ensure the pregnancy-results div is not displayed + const re = new RegExp('^pregnancy-results$', 'gi') + expect(queryByTestId(re)).toBeFalsy() + + // check the pregnancy-test checkbox + const checkboxItem = getByTestId('pregnancy-test') + expect(checkboxItem).toHaveClass('am-checkbox-item') + const checkBoxInput = checkboxItem + .getElementsByTagName('span')[0] + .getElementsByClassName('am-checkbox-input')[0] + fireEvent.click(checkBoxInput) + + // ensure the pregnancy-results div is displayed + expect(getByTestId(re)).toBeTruthy() + + // Uncheck the checkbox + fireEvent.click(checkBoxInput) + + // ensure the pregnancy-results div is no longer displayed + expect(queryByTestId(re)).toBeFalsy() +}) + +test('pregnancy results is displayed as a checkbox and is able to be checked / unchecked', () => { + const { getByTestId } = render() + + // check the pregnancy-test checkbox to display the pregnancy-results div + const checkBoxInput = getByTestId('pregnancy-test') + .getElementsByTagName('span')[0] + .getElementsByClassName('am-checkbox-input')[0] + fireEvent.click(checkBoxInput) + + // ensure negative and positive checkboxes are initilaly displayed unchecked + const negativeRadioButtonDiv = getByTestId('pregnancy-results-negative') + const positiveRadioButtonDiv = getByTestId('pregnancy-results-positive') + const negativeRadioButton = negativeRadioButtonDiv.getElementsByTagName( + 'span', + )[0] + const positiveRadioButton = positiveRadioButtonDiv.getElementsByTagName( + 'span', + )[0] + expect(negativeRadioButton).not.toHaveClass('am-radio-checked') + expect(positiveRadioButton).not.toHaveClass('am-radio-checked') + + // select "Negative" + fireEvent.click(negativeRadioButtonDiv) + + // ensure negative is checked and positive is unchecked + expect(negativeRadioButton).toHaveClass('am-radio-checked') + expect(positiveRadioButton).not.toHaveClass('am-radio-checked') + + // select "Positive" + fireEvent.click(positiveRadioButtonDiv) + + // ensure negative is unchecked and positive is checked + expect(negativeRadioButton).not.toHaveClass('am-radio-checked') + expect(positiveRadioButton).toHaveClass('am-radio-checked') +}) + +test('blood-sugar-results div is only displayed if blood sugar test is selected', () => { + const { getByTestId, queryByTestId } = render() + + // ensure the blood-sugar-results div is not displayed + const re = new RegExp('^blood-sugar-results$', 'gi') + expect(queryByTestId(re)).toBeFalsy() + + // check the blood-sugar-test checkbox + const checkboxItem = getByTestId('blood-sugar-test') + expect(checkboxItem).toHaveClass('am-checkbox-item') + const checkBoxInput = checkboxItem + .getElementsByTagName('span')[0] + .getElementsByClassName('am-checkbox-input')[0] + fireEvent.click(checkBoxInput) + + // ensure the blood-sugar-results div is displayed + expect(getByTestId(re)).toBeTruthy() + + // uncheck the checkbox + fireEvent.click(checkBoxInput) + + // ensure the blood-sugar-results div is no longer displayed + expect(queryByTestId(re)).not.toBeTruthy() +}) + +test('blood sugar results fields is a number input box', () => { + const { getByTestId } = render() + + // check the blood-sugar-test checkbox to display the blood-sugar-results div + const checkBoxInput = getByTestId('blood-sugar-test') + .getElementsByTagName('span')[0] + .getElementsByClassName('am-checkbox-input')[0] + fireEvent.click(checkBoxInput) + + // ensure result field is displayed as a number input box + expect(getByTestId('blood-sugar-results-val')).toBeTruthy() + expect(getByTestId('blood-sugar-results-val')).toHaveAttribute( + 'type', + 'text', + ) +}) + +test('ua-results div is only displayed if UA test is selected', () => { + const { getByTestId, queryByTestId } = render() + + // ensure the ua-results div is not displayed + const re = new RegExp('^ua-results$', 'gi') + expect(queryByTestId(re)).toBeFalsy() + + // check the ua-test checkbox + const checkboxItem = getByTestId('ua-test') + expect(checkboxItem).toHaveClass('am-checkbox-item') + const checkBoxInput = checkboxItem + .getElementsByTagName('span')[0] + .getElementsByClassName('am-checkbox-input')[0] + fireEvent.click(checkBoxInput) + + // ensure the ua-results div is displayed + expect(getByTestId(re)).toBeTruthy() + + // uncheck the checkbox + fireEvent.click(checkBoxInput) + + // ensure the ua-results div is no longer displayed + expect(queryByTestId(re)).not.toBeTruthy() +}) + +test('ua test results are rendered as number input boxes', () => { + const { getByTestId } = render() + // check the ua-test checkbox to display the ua-results div + const checkBoxInput = getByTestId('ua-test') + .getElementsByTagName('span')[0] + .getElementsByClassName('am-checkbox-input')[0] + fireEvent.click(checkBoxInput) + + // ensure each result field is displayed as a number input box + data.uaResultFields.forEach((field) => { + const fieldRe = new RegExp(field.toLowerCase() + `-results-val`, 'gi') + expect(getByTestId(fieldRe)).toBeTruthy() + expect(getByTestId(fieldRe)).toHaveAttribute('type', 'text') + }) +}) diff --git a/pwa/src/components/TestResultsForm.tsx b/pwa/src/components/TestResultsForm.tsx new file mode 100644 index 0000000..ad5ada7 --- /dev/null +++ b/pwa/src/components/TestResultsForm.tsx @@ -0,0 +1,122 @@ +import React, { ReactElement, useState } from 'react' +import { Checkbox, List, Radio, WhiteSpace, InputItem } from 'antd-mobile' +import '../scss/TestResultsForm.scss' +import * as data from './TestResultsFields.json' + +const RadioItem = Radio.RadioItem +const CheckboxItem = Checkbox.CheckboxItem + +export default function TestResultsForm(): ReactElement { + // State Hooks used for result div visibility + const [pregnancyTest, setPregnancyTest] = useState(0) // Default: 0 (unchecked) + const [pregnancyTestPositive, setPregnancyTestPositive] = useState( + null as number, + ) // Default: null (none selected) + const [bloodSugarTest, setBloodSugarTest] = useState(0) // Default: 0 (unchecked) + const [ua, setUA] = useState(0) // Default: 0 (unchecked) + + // Data for Radio Buttons + const radioPosNeg = [ + { value: 0, label: 'Negative' }, + { value: 1, label: 'Positive' }, + ] + const uaResultElements: ReactElement[] = [] + + return ( +
+ + {' '} + setPregnancyTest(pregnancyTest ? 0 : 1)} + title="HCG (Pregnancy) Test Performed" + > + HCG (Pregnancy) Test Performed + + {pregnancyTest ? ( +
+ 'HCG (Pregnancy) Results'}> + {radioPosNeg.map((i) => ( + + setPregnancyTestPositive(i.value) + } + > + {i.label} + + ))} + + +
+ ) : null} + setBloodSugarTest(bloodSugarTest ? 0 : 1)} + > + Blood Sugar Test Performed + + {bloodSugarTest ? ( +
+ 'Blood Sugar Results'}> + + + +
+ ) : null} + setUA(ua ? 0 : 1)} + > + UA (Urine Analysis) Test Performed + + {/* Create UA Results internal elements to insert*/} + {data.uaResultFields.map((fieldName) => { + uaResultElements.push( + + {fieldName} + , + ) + })} + {ua ? ( +
+ 'UA Results'}> + {uaResultElements} + +
+ ) : null} +
+
+ ) +} diff --git a/pwa/src/scss/TestResultsForm.scss b/pwa/src/scss/TestResultsForm.scss new file mode 100644 index 0000000..11a37ec --- /dev/null +++ b/pwa/src/scss/TestResultsForm.scss @@ -0,0 +1,5 @@ +#test-results-form-wrapper { + .list-whitespace { + background-color: #f5f5f9; + } +}