Skip to content

Commit c126764

Browse files
committed
Tests and prettier
1 parent 6e94027 commit c126764

File tree

3 files changed

+81
-15
lines changed

3 files changed

+81
-15
lines changed

src/app/components/form-radiogroup/form-radiogroup.tsx

+27-14
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@ type OptionItem = {
55
value: string;
66
label: string;
77
checked?: boolean;
8-
}
8+
};
99

10-
function Option({item, name, required, selectedValue, onChange}: {
10+
function Option({
11+
item,
12+
name,
13+
required,
14+
selectedValue,
15+
onChange
16+
}: {
1117
item: OptionItem;
1218
name: string;
1319
required?: boolean;
@@ -33,10 +39,13 @@ function Option({item, name, required, selectedValue, onChange}: {
3339

3440
type InputElementWithValidationMessage = HTMLInputElement & {
3541
validationMessage: string;
36-
}
42+
};
3743

3844
export default function FormRadioGroup({
39-
longLabel, name, options, required
45+
longLabel,
46+
name,
47+
options,
48+
required
4049
}: {
4150
longLabel?: string;
4251
name: string;
@@ -47,14 +56,14 @@ export default function FormRadioGroup({
4756
const [validationMessage, setValidationMessage] = useState('');
4857
const checkedValue = options.find((opt) => opt.checked)?.value;
4958
const [selectedValue, setSelectedValue] = useState(checkedValue);
50-
const validate = React.useCallback(
51-
() => {
52-
const invalid = ref.current?.querySelector<InputElementWithValidationMessage>(':invalid');
59+
const validate = React.useCallback(() => {
60+
const invalid =
61+
ref.current?.querySelector<InputElementWithValidationMessage>(
62+
':invalid'
63+
);
5364

54-
setValidationMessage(invalid ? invalid.validationMessage : '');
55-
},
56-
[]
57-
);
65+
setValidationMessage(invalid ? invalid.validationMessage : '');
66+
}, []);
5867
const onChange = React.useCallback(
5968
({target: {value}}: React.ChangeEvent<HTMLInputElement>) => {
6069
setSelectedValue(value);
@@ -70,10 +79,14 @@ export default function FormRadioGroup({
7079
React.useEffect(validate, [validate]);
7180

7281
return (
73-
<div className='form-radiogroup'>
74-
{longLabel && <label className="field-long-label">{longLabel}</label>}
82+
<div className="form-radiogroup">
83+
{longLabel && (
84+
<label className="field-long-label">{longLabel}</label>
85+
)}
7586
<div ref={ref}>
76-
{options.map((item) => <Option item={item} {...passThruProps} key={item.value} />)}
87+
{options.map((item) => (
88+
<Option item={item} {...passThruProps} key={item.value} />
89+
))}
7790
</div>
7891
<div className="invalid-message">{validationMessage}</div>
7992
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React from 'react';
2+
import {render, screen, fireEvent} from '@testing-library/preact';
3+
import FormRadioGroup from '~/components/form-radiogroup/form-radiogroup';
4+
import userEvent from '@testing-library/user-event';
5+
6+
const adoptionYesNoOptions = [
7+
{label: 'Yes', value: 'y'},
8+
{label: 'No', value: 'n'}
9+
];
10+
11+
describe('components/form-radiogroup', () => {
12+
const user = userEvent.setup();
13+
14+
it('displays validation message when required until selected', async () => {
15+
render(
16+
<FormRadioGroup
17+
name="test1"
18+
options={adoptionYesNoOptions}
19+
required={true}
20+
/>
21+
);
22+
const options = screen.getAllByRole('radio');
23+
24+
expect(document.querySelector('.invalid-message')?.textContent).toBe(
25+
'Constraints not satisfied'
26+
);
27+
28+
expect(options).toHaveLength(2);
29+
await user.click(options[1]);
30+
expect(document.querySelector('.invalid-message')?.textContent).toBe(
31+
''
32+
);
33+
});
34+
it('displays with optional longLabel', () => {
35+
render(
36+
<FormRadioGroup
37+
name="test1"
38+
options={adoptionYesNoOptions}
39+
longLabel="This is your instruction"
40+
/>
41+
);
42+
screen.getByText('This is your instruction');
43+
});
44+
});

test/src/pages/blog/gated-content-dialog.test.tsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import GatedContentDialog from '~/pages/blog/gated-content-dialog/gated-content-
99
import type {ArticleData} from '~/pages/blog/article/article';
1010
import userEvent from '@testing-library/user-event';
1111

12+
// @ts-expect-error does not exist on
13+
const {routerFuture} = global;
14+
1215
const articleData: ArticleData = {
1316
gatedContent: true,
1417
heading: 'heading',
@@ -64,7 +67,11 @@ mockUseFormTarget.mockImplementation((fn) => {
6467

6568
function Component({path}: {path: string}) {
6669
return (
67-
<MemoryRouter basename="/blog" initialEntries={[path]}>
70+
<MemoryRouter
71+
basename="/blog"
72+
initialEntries={[path]}
73+
future={routerFuture}
74+
>
6875
<ShellContextProvider>
6976
<MainClassContextProvider>
7077
<BlogContextProvider>
@@ -92,6 +99,8 @@ describe('blog/gated-content-dialog', () => {
9299
mockClose.mockReset();
93100
});
94101

102+
console.debug = jest.fn();
103+
95104
it('displays when gatedContent is set in article data', async () => {
96105
render(<Component path="/blog/some-post" />);
97106

0 commit comments

Comments
 (0)