Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#336/Fix broken unit tests caused by react-children-utilities dependency. #352

Closed
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@
"prop-types": "15.7.2",
"raf": "3.4.1",
"react": "16.13.0",
"react-children-utilities": "2.0.12",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove dependency.

"react-dates": "21.8.0",
"react-dom": "16.13.0",
"react-error-boundary": "1.2.5",
Expand Down
3 changes: 2 additions & 1 deletion src/components/Form/FormDatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Media from 'react-media'
import { Col, FormGroup, Row } from 'reactstrap'

import FormLabel from './FormLabel'
import {HelpProps} from './FormHelpButton'

import { DateRange } from '../../algorithms/types/Param.types'

Expand All @@ -21,7 +22,7 @@ function getNumberOfMonthsCount(media: { tiny: boolean; small: boolean; medium:
export interface FormDatePickerProps {
identifier: string
label: string
help?: string | React.ReactNode
help?: HelpProps
allowPast?: boolean
}

Expand Down
4 changes: 3 additions & 1 deletion src/components/Form/FormDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import React from 'react'
import { Field, FieldProps, FormikErrors, FormikTouched, FormikValues } from 'formik'
import FormDropdownStateless from './FormDropdownStateless'

import HelpProps from './FormHelpButton'

export interface FormDropdownOption<ValueType extends string | number> {
value: ValueType
label: string
Expand All @@ -11,7 +13,7 @@ export interface FormDropdownOption<ValueType extends string | number> {
export interface FormDropdownProps<ValueType extends string | number> {
identifier: string
label: string
help?: string | React.ReactNode
help?: HelpProps
options: FormDropdownOption<ValueType>[]
errors?: FormikErrors<FormikValues>
touched?: FormikTouched<FormikValues>
Expand Down
3 changes: 2 additions & 1 deletion src/components/Form/FormDropdownStateless.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import { Col, FormGroup, Row } from 'reactstrap'

import { FormDropdownOption } from './FormDropdownOption'
import FormLabel from './FormLabel'
import HelpProps from './FormHelpButton'

export interface FormDropdownProps<ValueType extends string | number> {
identifier: string
label: string | React.ReactNode
help?: string | React.ReactNode
help?: HelpProps
options: FormDropdownOption<ValueType>[]
defaultOption?: FormDropdownOption<ValueType>
value?: FormDropdownOption<ValueType>
Expand Down
14 changes: 7 additions & 7 deletions src/components/Form/FormHelpButton.test.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import React from 'react'
import { render, fireEvent, waitForElementToBeRemoved } from '@testing-library/react'
import FormHelpButton from './FormHelpButton'
import FormHelpButton, {help} from './FormHelpButton'

describe('FormHelpButton', () => {
it('renders', () => {
const { getByLabelText } = render(<FormHelpButton identifier="abc" label="def" />)
const { getByLabelText } = render(<FormHelpButton identifier="abc" help={help("def")} />)

expect(getByLabelText('help')).not.toBeNull()
})

it('initially hides help', () => {
const { queryByText } = render(<FormHelpButton identifier="abc" label="def" />)
const { queryByText } = render(<FormHelpButton identifier="abc" help={help("def")} />)

expect(queryByText('def')).toBeNull()
})

it('opens', async () => {
const { getByLabelText, findByText, queryByText } = render(<FormHelpButton identifier="abc" label="def" />)
const { getByLabelText, findByText, queryByText } = render(<FormHelpButton identifier="abc" help={help("def")} />)

fireEvent.click(getByLabelText('help'))

Expand All @@ -26,7 +26,7 @@ describe('FormHelpButton', () => {

it('displays help', async () => {
const { getByLabelText, findByText, queryByText } = render(
<FormHelpButton identifier="abc" label="def" help="some help" />,
<FormHelpButton identifier="abc" help={help("def", "some help")} />,
)

fireEvent.click(getByLabelText('help'))
Expand All @@ -36,7 +36,7 @@ describe('FormHelpButton', () => {
})

it('closes inside', async () => {
const { getByLabelText, findByText, queryByText } = render(<FormHelpButton identifier="abc" label="def" />)
const { getByLabelText, findByText, queryByText } = render(<FormHelpButton identifier="abc" help={help("def")} />)
fireEvent.click(getByLabelText('help'))
await findByText('def')
expect(queryByText('def')).not.toBeNull()
Expand All @@ -50,7 +50,7 @@ describe('FormHelpButton', () => {
it('closes outside', async () => {
const { getByLabelText, findByText, getByText, queryByText } = render(
<div>
<FormHelpButton identifier="abc" label="def" />
<FormHelpButton identifier="abc" help={help("def")} />
<span>click outside</span>
</div>,
)
Expand Down
20 changes: 13 additions & 7 deletions src/components/Form/FormHelpButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import React from 'react'

import { Button, Card, CardBody, UncontrolledPopover } from 'reactstrap'

import { onlyText } from 'react-children-utilities'

import { FaQuestion } from 'react-icons/fa'

import './FormHelpButton.scss'
Expand All @@ -12,13 +10,21 @@ function safeId(id: string) {
return id.replace('.', '-')
}

export interface HelpProps {
label: string
text: string
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @abrie could text be changed to content and be string | React.ReactNode? When I changed this last, @ivan-aksamentov mentioned that he wanted to allow the content of help possibly be more than plain text.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gj262 Yeah, sounds reasonable. PR Updated.

}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This interface is passed into the 'help' attribute for elements that need a help button. Having label in this interface removes the need to try and extract label text from the the 'label' attribute on the element.


export function help(label:string = "", text:string = "") : HelpProps {
return { label, text }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a helper function to create the HelpProps object.

export interface FormHelpButtonProps {
identifier: string
label: string | React.ReactNode
help?: string | React.ReactNode
help?: HelpProps
}

export default function FormHelpButton({ identifier, label, help }: FormHelpButtonProps) {
export default function FormHelpButton({ identifier, help }: FormHelpButtonProps) {
return (
<>
<Button
Expand All @@ -36,8 +42,8 @@ export default function FormHelpButton({ identifier, label, help }: FormHelpButt
<UncontrolledPopover placement="right" target={safeId(identifier)} trigger="legacy" hideArrow>
<Card className="card--help">
<CardBody>
{label && <h4>{onlyText(label)}</h4>}
<p>{help}</p>
<h4>{help.label}</h4>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now we no longer need to invoke onlyText. We just insert the contents of the 'label' field from the HelpProps object.

<p>{help.text}</p>
</CardBody>
</Card>
</UncontrolledPopover>
Expand Down
3 changes: 2 additions & 1 deletion src/components/Form/FormLabel.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import { render } from '@testing-library/react'
import FormLabel from './FormLabel'
import {help} from './FormHelpButton'

const findLabelInTree = (el: HTMLElement | null): HTMLElement | null => {
if (!el) {
Expand All @@ -18,7 +19,7 @@ describe('FormLabel', () => {
// element tree that shows the label text. And that <label> should be for
// the identifier.

const { getByText } = render(<FormLabel identifier="abc" label="def" />)
const { getByText } = render(<FormLabel identifier="abc" label="def" help={help('hij')} />)

const labelElement = findLabelInTree(getByText('def')) as HTMLLabelElement

Expand Down
3 changes: 2 additions & 1 deletion src/components/Form/FormLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from 'react'

import HelpLabel from './HelpLabel'
import {HelpProps} from './FormHelpButton'

export interface LabelWithHelpButtonProps {
identifier: string
label: string | React.ReactNode
help?: string | React.ReactNode
help?: HelpProps
}

export default function FormLabel({ identifier, label, help }: LabelWithHelpButtonProps) {
Expand Down
3 changes: 2 additions & 1 deletion src/components/Form/FormSpinBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import { Field, FormikErrors, FormikTouched } from 'formik'
import { Col, FormGroup, Row } from 'reactstrap'

import FormLabel from './FormLabel'
import HelpProps from './FormHelpButton'

export interface FormSpinBoxProps<T> {
identifier: string
label: string
help?: string | React.ReactNode
help?: HelpProps
step?: number | string
min?: number
max?: number
Expand Down
3 changes: 2 additions & 1 deletion src/components/Form/FormSwitch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import React from 'react'
import { CustomInput } from 'reactstrap'

import FormLabel from './FormLabel'
import HelpProps from './FormHelpButton'

export interface FormSwitchProps {
identifier: string
label: string
help?: string
help?: HelpProps
checked: boolean
hidden?: boolean
onValueChanged(checked: boolean): void
Expand Down
5 changes: 3 additions & 2 deletions src/components/Form/HelpLabel.test.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import React from 'react'
import { render } from '@testing-library/react'
import HelpLabel from './HelpLabel'
import {help} from './FormHelpButton'

describe('HelpLabel', () => {
it('displays the label', () => {
const { getByText } = render(<HelpLabel identifier="abc" label="def" />)
const { getByText } = render(<HelpLabel identifier="abc" label="def" help={help("hij")} />)

expect(getByText('def')).not.toBeNull()
})

it('displays a help button', () => {
const { getByLabelText } = render(<HelpLabel identifier="abc" label="def" />)
const { getByLabelText } = render(<HelpLabel identifier="abc" label="def" help={help("hij")} />)

expect(getByLabelText('help')).not.toBeNull()
})
Expand Down
4 changes: 2 additions & 2 deletions src/components/Form/HelpLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react'

import FormHelpButton from './FormHelpButton'
import FormHelpButton, {HelpProps} from './FormHelpButton'

export interface HelpLabelProps {
identifier: string
label: string | React.ReactNode
help?: string | React.ReactNode
help?: HelpProps
}

export default function HelpLabel({ identifier, label, help }: HelpLabelProps) {
Expand Down
7 changes: 4 additions & 3 deletions src/components/Main/Results/ResultsCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Button, Col, Row } from 'reactstrap'
import { useTranslation } from 'react-i18next'
import ExportSimulationDialog from './ExportSimulationDialog'
import FormSwitch from '../../Form/FormSwitch'
import { help } from '../../Form/FormHelpButton'
import LocalStorage, { LOCAL_STORAGE_KEYS } from '../../../helpers/localStorage'
import processUserResult from '../../../algorithms/utils/userResult'
import { AgeBarChart } from './AgeBarChart'
Expand Down Expand Up @@ -106,7 +107,7 @@ function ResultsCardFunction({
{t('Results')}
</h2>
}
help={t('This section contains simulation results')}
help={help(t('Results'), t('This section contains simulation results'))}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pattern is repeated throughout all elements that have a 'help' attribute. The attribute receives a HelpParams object, created by the help(title, text) helper.

defaultCollapsed={false}
>
<Row className="mb-4">
Expand Down Expand Up @@ -159,7 +160,7 @@ function ResultsCardFunction({
<FormSwitch
identifier="logScale"
label={t('Log scale')}
help={t('Toggle between logarithmic and linear scale on vertical axis of the plot')}
help={help(t('Log scale'), t('Toggle between logarithmic and linear scale on vertical axis of the plot'))}
checked={logScale}
onValueChanged={setPersistLogScale}
/>
Expand All @@ -168,7 +169,7 @@ function ResultsCardFunction({
<FormSwitch
identifier="showHumanized"
label={t('Show humanized results')}
help={t('Show numerical results in a human friendly format')}
help={help(t('Show humanized results'), t('Show numerical results in a human friendly format'))}
checked={showHumanized}
onValueChanged={setPersistShowHumanized}
/>
Expand Down
3 changes: 2 additions & 1 deletion src/components/Main/Scenario/ScenarioCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useTranslation } from 'react-i18next'

import { CardWithDropdown } from '../../Form/CardWithDropdown'
import { stringsToOptions } from '../../Form/FormDropdownOption'
import { help } from '../../Form/FormHelpButton'

import { setScenario } from '../state/actions'
import { State } from '../state/state'
Expand Down Expand Up @@ -40,7 +41,7 @@ function ScenarioCard({ severity, scenarioState, errors, touched, setSeverity, s
<CardWithDropdown
identifier="scenarioName"
label={<h2 className="p-0 m-0 d-inline text-truncate">{t('Scenario')}</h2>}
help={t('Combination of population, epidemiology, and mitigation scenarios')}
help={help(t('Scenario'), t('Combination of population, epidemiology, and mitigation scenarios'))}
Comment on lines 43 to +44
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is an example of a label that renders a React node. Note that we pass both a label and help text to the help() method, which generates a HelpParams object. The label is duplicated in both the label= attribute and the help() function.

options={scenarioOptions}
value={scenarioOptions.find((s) => s.label === scenarioState.current)}
onValueChange={handleChangeScenario}
Expand Down
8 changes: 4 additions & 4 deletions src/components/Main/Scenario/ScenarioCardContainment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { useTranslation } from 'react-i18next'

import { CardWithoutDropdown } from '../../Form/CardWithoutDropdown'
import { FormSpinBox } from '../../Form/FormSpinBox'
import { help } from '../../Form/FormHelpButton'

import { ContainmentGraph } from '../Containment/ContainmentGraph'

import { setContainmentData } from '../state/actions'
Expand All @@ -33,14 +35,12 @@ function ScenarioCardContainment({ scenarioState, errors, touched, scenarioDispa
<CardWithoutDropdown
identifier="containmentScenario"
label={<h3 className="p-0 d-inline text-truncate">{t('Mitigation')}</h3>}
help={t(
'Reduction of transmission through mitigation measures over time. Different presets with variable degree of reduction can be selected from the dropdown.',
)}
help={help(t('Mitigation'), t('Reduction of transmission through mitigation measures over time. Different presets with variable degree of reduction can be selected from the dropdown.'))}
>
<FormSpinBox
identifier="containment.numberPoints"
label={t('Number of points')}
help={t('Number of controllable points on the mitigation curve')}
help={help(t('Number of points'), t('Number of controllable points on the mitigation curve'))}
step={1}
min={5}
max={100}
Expand Down