Skip to content

Commit 6cfa476

Browse files
committed
test: FieldRadioGroup
1 parent 02a94dc commit 6cfa476

File tree

2 files changed

+245
-1
lines changed

2 files changed

+245
-1
lines changed

app/components/form/field-radio-group/docs.stories.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ export const WithDisabledOption = () => {
163163
type="radio-group"
164164
name="bear"
165165
options={optionsWithDisabled}
166-
className="flex-row gap-4"
167166
/>
168167
</FormField>
169168
<div>
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
import { expect, test, vi } from 'vitest';
2+
import { axe } from 'vitest-axe';
3+
import { z } from 'zod';
4+
5+
import { render, screen, setupUser } from '@/tests/utils';
6+
7+
import { FormField, FormFieldController, FormFieldLabel } from '..';
8+
import { FormMocked } from '../form-test-utils';
9+
10+
const options = [
11+
{
12+
value: 'bearstrong',
13+
label: 'Bearstrong',
14+
},
15+
{
16+
value: 'pawdrin',
17+
label: 'Buzz Pawdrin',
18+
},
19+
{
20+
value: 'grizzlyrin',
21+
label: 'Yuri Grizzlyrin',
22+
},
23+
{
24+
value: 'jemibear',
25+
label: 'Mae Jemibear',
26+
disabled: true,
27+
},
28+
];
29+
30+
test('should have no a11y violations', async () => {
31+
const mockedSubmit = vi.fn();
32+
33+
HTMLCanvasElement.prototype.getContext = vi.fn();
34+
35+
const { container } = render(
36+
<FormMocked
37+
schema={z.object({ bear: z.string() })}
38+
useFormOptions={{ defaultValues: { bear: undefined } }}
39+
onSubmit={mockedSubmit}
40+
>
41+
{({ form }) => (
42+
<FormField>
43+
<FormFieldLabel>Bearstronaut</FormFieldLabel>
44+
<FormFieldController
45+
type="radio-group"
46+
control={form.control}
47+
name="bear"
48+
options={options}
49+
/>
50+
</FormField>
51+
)}
52+
</FormMocked>
53+
);
54+
55+
const results = await axe(container);
56+
57+
expect(results).toHaveNoViolations();
58+
});
59+
60+
test('should select radio on click', async () => {
61+
const user = setupUser();
62+
const mockedSubmit = vi.fn();
63+
64+
render(
65+
<FormMocked
66+
schema={z.object({ bear: z.string() })}
67+
useFormOptions={{ defaultValues: { bear: '' } }}
68+
onSubmit={mockedSubmit}
69+
>
70+
{({ form }) => (
71+
<FormField>
72+
<FormFieldLabel>Bearstronaut</FormFieldLabel>
73+
<FormFieldController
74+
type="radio-group"
75+
control={form.control}
76+
name="bear"
77+
options={options}
78+
/>
79+
</FormField>
80+
)}
81+
</FormMocked>
82+
);
83+
84+
const radio = screen.getByRole('radio', { name: 'Buzz Pawdrin' });
85+
expect(radio).not.toBeChecked();
86+
87+
await user.click(radio);
88+
expect(radio).toBeChecked();
89+
90+
await user.click(screen.getByRole('button', { name: 'Submit' }));
91+
expect(mockedSubmit).toHaveBeenCalledWith({ bear: 'pawdrin' });
92+
});
93+
94+
test('should handle keyboard navigation', async () => {
95+
const user = setupUser();
96+
const mockedSubmit = vi.fn();
97+
98+
render(
99+
<FormMocked
100+
schema={z.object({ bear: z.string() })}
101+
useFormOptions={{ defaultValues: { bear: '' } }}
102+
onSubmit={mockedSubmit}
103+
>
104+
{({ form }) => (
105+
<FormField>
106+
<FormFieldLabel>Bearstronaut</FormFieldLabel>
107+
<FormFieldController
108+
type="radio-group"
109+
control={form.control}
110+
name="bear"
111+
options={options}
112+
/>
113+
</FormField>
114+
)}
115+
</FormMocked>
116+
);
117+
118+
const firstRadio = screen.getByRole('radio', { name: 'Bearstrong' });
119+
const secondRadio = screen.getByRole('radio', { name: 'Buzz Pawdrin' });
120+
const thirdRadio = screen.getByRole('radio', { name: 'Yuri Grizzlyrin' });
121+
122+
await user.tab();
123+
expect(firstRadio).toHaveFocus();
124+
125+
await user.keyboard('{ArrowDown}');
126+
expect(secondRadio).toHaveFocus();
127+
await user.keyboard(' ');
128+
expect(secondRadio).toBeChecked();
129+
130+
await user.keyboard('{ArrowDown}');
131+
expect(thirdRadio).toHaveFocus();
132+
133+
await user.keyboard('{ArrowUp}');
134+
expect(secondRadio).toHaveFocus();
135+
expect(secondRadio).toBeChecked(); // Second radio should still be checked
136+
137+
await user.click(screen.getByRole('button', { name: 'Submit' }));
138+
expect(mockedSubmit).toHaveBeenCalledWith({ bear: 'pawdrin' });
139+
});
140+
141+
test('default value', async () => {
142+
const user = setupUser();
143+
const mockedSubmit = vi.fn();
144+
render(
145+
<FormMocked
146+
schema={z.object({ bear: z.string() })}
147+
useFormOptions={{
148+
defaultValues: {
149+
bear: 'grizzlyrin',
150+
},
151+
}}
152+
onSubmit={mockedSubmit}
153+
>
154+
{({ form }) => (
155+
<FormField>
156+
<FormFieldLabel>Bearstronaut</FormFieldLabel>
157+
<FormFieldController
158+
type="radio-group"
159+
control={form.control}
160+
name="bear"
161+
options={options}
162+
/>
163+
</FormField>
164+
)}
165+
</FormMocked>
166+
);
167+
168+
const radio = screen.getByRole('radio', { name: 'Yuri Grizzlyrin' });
169+
expect(radio).toBeChecked();
170+
171+
await user.click(screen.getByRole('button', { name: 'Submit' }));
172+
expect(mockedSubmit).toHaveBeenCalledWith({ bear: 'grizzlyrin' });
173+
});
174+
175+
test('disabled', async () => {
176+
const user = setupUser();
177+
const mockedSubmit = vi.fn();
178+
render(
179+
<FormMocked
180+
schema={z.object({ bear: z.string() })}
181+
useFormOptions={{
182+
defaultValues: {
183+
bear: 'pawdrin',
184+
},
185+
}}
186+
onSubmit={mockedSubmit}
187+
>
188+
{({ form }) => (
189+
<FormField>
190+
<FormFieldLabel>Bearstronaut</FormFieldLabel>
191+
<FormFieldController
192+
type="radio-group"
193+
control={form.control}
194+
name="bear"
195+
disabled
196+
options={options}
197+
/>
198+
</FormField>
199+
)}
200+
</FormMocked>
201+
);
202+
203+
const radio = screen.getByRole('radio', { name: 'Buzz Pawdrin' });
204+
expect(radio).toBeDisabled();
205+
206+
await user.click(screen.getByRole('button', { name: 'Submit' }));
207+
expect(mockedSubmit).toHaveBeenCalledWith({ bear: undefined });
208+
});
209+
210+
test('disabled option', async () => {
211+
const user = setupUser();
212+
const mockedSubmit = vi.fn();
213+
render(
214+
<FormMocked
215+
schema={z.object({ bear: z.string() })}
216+
useFormOptions={{
217+
defaultValues: {
218+
bear: '',
219+
},
220+
}}
221+
onSubmit={mockedSubmit}
222+
>
223+
{({ form }) => (
224+
<FormField>
225+
<FormFieldLabel>Bearstronaut</FormFieldLabel>
226+
<FormFieldController
227+
type="radio-group"
228+
control={form.control}
229+
name="bear"
230+
options={options}
231+
/>
232+
</FormField>
233+
)}
234+
</FormMocked>
235+
);
236+
237+
const disabledRadio = screen.getByRole('radio', { name: 'Mae Jemibear' });
238+
expect(disabledRadio).toBeDisabled();
239+
240+
await user.click(disabledRadio);
241+
expect(disabledRadio).not.toBeChecked();
242+
243+
await user.click(screen.getByRole('button', { name: 'Submit' }));
244+
expect(mockedSubmit).toHaveBeenCalledWith({ bear: '' });
245+
});

0 commit comments

Comments
 (0)