Skip to content

Commit e38539b

Browse files
authored
test: <Radio /> (#50)
1 parent 72de3cf commit e38539b

File tree

6 files changed

+93
-8
lines changed

6 files changed

+93
-8
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
"vite": "3.2.4",
117117
"vite-plugin-dts": "^2.2.0",
118118
"vite-plugin-pwa": "^0.14.7",
119+
"vite-plugin-react-remove-attributes": "^1.0.3",
119120
"vite-tsconfig-paths": "3.5.2",
120121
"vitest": "0.25.2",
121122
"whatwg-fetch": "3.6.2",

src/components/Radio.stories.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Meta, StoryObj } from '@storybook/react';
2-
import Radio from './Radio';
2+
import { Radio } from './Radio';
33

44
const meta: Meta<typeof Radio> = {
55
component: Radio,

src/components/Radio.test.tsx

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import '@testing-library/jest-dom';
2+
import { render, screen } from '@testing-library/react';
3+
import userEvent from '@testing-library/user-event';
4+
import { Radio } from './Radio';
5+
6+
const buildProperties = (
7+
additive: number | string
8+
): { id: string; label: string } => ({
9+
id: `radio-${additive}`,
10+
label: `label-${additive}`
11+
});
12+
13+
describe('<Radio />', () => {
14+
const helperText = 'helperText goes here';
15+
const role = 'radio';
16+
17+
it('renders labels correctly', () => {
18+
const properties = buildProperties('first');
19+
render(<Radio {...properties} />);
20+
expect(screen.getByText(properties.label)).toBeInTheDocument();
21+
});
22+
23+
it('renders helperText', () => {
24+
const properties = buildProperties('helper');
25+
render(<Radio {...properties} helperText={helperText} />);
26+
expect(screen.getByText(helperText)).toBeInTheDocument();
27+
});
28+
29+
it('isLarge', () => {
30+
const properties = buildProperties('large');
31+
render(<Radio {...properties} helperText={helperText} isLarge />);
32+
33+
expect(screen.getByText(helperText)).toBeInTheDocument();
34+
expect(screen.getByTestId('radio-container').getAttribute('class')).toMatch(
35+
'm-form-field__lg-target'
36+
);
37+
});
38+
39+
it('isDisabled', () => {
40+
const properties = buildProperties('disabled');
41+
render(<Radio {...properties} isDisabled />);
42+
43+
const element = screen.getByRole(role);
44+
45+
expect(element).toBeInTheDocument();
46+
expect(element.getAttribute('disabled')).not.toBe('null');
47+
expect(element.getAttribute('disabled')).toBe('');
48+
});
49+
50+
it('Select via click', () => {
51+
const properties = buildProperties('click');
52+
render(<Radio {...properties} />);
53+
54+
const element = screen.getByRole(role);
55+
expect(element).not.toBeChecked();
56+
57+
screen.getByText(properties.label).click();
58+
59+
expect(element).toBeChecked();
60+
});
61+
62+
it('Select via keyboard', async () => {
63+
const user = userEvent.setup();
64+
const properties = buildProperties('keyboard');
65+
render(<Radio {...properties} />);
66+
67+
const element = screen.getByRole(role);
68+
expect(element).not.toBeChecked();
69+
70+
element.focus();
71+
await user.keyboard(' ');
72+
73+
expect(element).toBeChecked();
74+
});
75+
});

src/components/Radio.tsx

+7-7
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ import type React from 'react';
22

33
interface RadioProperties {
44
id: string;
5-
name: string;
6-
helperText?: string;
7-
className?: string;
8-
isDisabled?: boolean;
9-
isLarge?: boolean;
105
label: string;
6+
className?: string;
7+
helperText?: string;
118
inputRef?:
129
| React.RefObject<HTMLInputElement>
1310
| string
1411
| ((instance: HTMLInputElement | null) => void)
1512
| null
1613
| undefined;
14+
isDisabled?: boolean;
15+
isLarge?: boolean;
16+
name?: string;
1717
}
1818
const baseStyles = ['a-radio'];
1919
const containerBaseStyles = ['m-form-field m-form-field__radio'];
@@ -35,11 +35,11 @@ export const Radio = ({
3535
].join(' ');
3636

3737
return (
38-
<div className={containerClasses}>
38+
<div className={containerClasses} data-testid='radio-container'>
3939
<input
4040
id={id}
4141
type='radio'
42-
name={name}
42+
name={name ?? id}
4343
className={classes}
4444
ref={inputRef}
4545
disabled={isDisabled}

vite.config.ts

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import react from '@vitejs/plugin-react';
33
import { resolve } from 'node:path';
44
import { defineConfig } from 'vite';
55
import dts from 'vite-plugin-dts';
6+
import VitePluginReactRemoveAttributes from 'vite-plugin-react-remove-attributes';
67
import tsConfigPaths from 'vite-tsconfig-paths';
78
import { name } from './package.json';
89

@@ -13,6 +14,9 @@ export default defineConfig(() => ({
1314
tsConfigPaths(),
1415
dts({
1516
insertTypesEntry: true
17+
}),
18+
VitePluginReactRemoveAttributes({
19+
attributes: ['data-testid']
1620
})
1721
],
1822
test: {

yarn.lock

+5
Original file line numberDiff line numberDiff line change
@@ -11038,6 +11038,11 @@ vite-plugin-pwa@^0.14.7:
1103811038
workbox-build "^6.5.4"
1103911039
workbox-window "^6.5.4"
1104011040

11041+
vite-plugin-react-remove-attributes@^1.0.3:
11042+
version "1.0.3"
11043+
resolved "https://registry.yarnpkg.com/vite-plugin-react-remove-attributes/-/vite-plugin-react-remove-attributes-1.0.3.tgz#ffa0a3bc61cc20d15fcbe37c6a361b320a4f5424"
11044+
integrity sha512-f+ox+GFeqyBHzOe94Tcf1knFXEYWMhOGH04glIZRoXoIXQJD23Z1KFgQ7/JwOoLydsvQTlGzUJ/BpLeL7lh2LQ==
11045+
1104111046
1104211047
version "3.5.2"
1104311048
resolved "https://registry.yarnpkg.com/vite-tsconfig-paths/-/vite-tsconfig-paths-3.5.2.tgz#fd3232f93c426311d7e0d581187d8b63fff55fbc"

0 commit comments

Comments
 (0)