Skip to content

Commit d48545a

Browse files
committed
Add tests for carbon mapper components
1 parent dea7daf commit d48545a

File tree

12 files changed

+513
-18
lines changed

12 files changed

+513
-18
lines changed

packages/carbon-component-mapper/src/files/plain-text.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ReactNode } from "react";
22

33
export interface PlainTextProps {
44
label: ReactNode;
5+
element?: string;
56
}
67

78
declare const PlainText: React.ComponentType<PlainTextProps>;
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33

4-
const PlainText = ({ label }) => label.split('\n').map((paragraph, index) => <p key={index}>{paragraph}</p>);
4+
const PlainText = ({ label, element, component, ...rest }) =>
5+
label.split('\n').map((paragraph, index) => React.createElement(element, { key: index, ...rest }, paragraph));
56

67
PlainText.propTypes = {
7-
label: PropTypes.string
8+
label: PropTypes.string,
9+
element: PropTypes.string,
10+
component: PropTypes.string
11+
};
12+
13+
PlainText.defaultProps = {
14+
element: 'p'
815
};
916

1017
export default PlainText;

packages/carbon-component-mapper/src/files/radio.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const Radio = (props) => {
1313
<FormGroup legendText={labelText} {...FormGroupProps}>
1414
<RadioButtonGroup {...input} valueSelected={input.value} disabled={disabled} {...rest}>
1515
{options.map((option) => (
16-
<RadioButton key={option.value} {...props} disabled={disabled} labelText={option.label} value={option.value} {...option} />
16+
<RadioButton key={option.value} disabled={disabled} labelText={option.label} value={option.value} {...option} />
1717
))}
1818
</RadioButtonGroup>
1919
</FormGroup>

packages/carbon-component-mapper/src/files/select.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ import fnToString from '@data-driven-forms/common/src/utils/fn-to-string';
88
import { Select as CarbonSelect, MultiSelect, SelectItem } from 'carbon-components-react';
99
import prepareProps from '../common/prepare-props';
1010

11+
export const multiOnChange = (input, simpleValue) => ({ selectedItems }) => {
12+
if (simpleValue) {
13+
return input.onChange(selectedItems.map(({ value }) => value));
14+
} else {
15+
return input.onChange(selectedItems);
16+
}
17+
};
18+
1119
const ClearedMultiSelectFilterable = ({
1220
invalidText,
1321
hideSelectedOptions,
@@ -170,14 +178,6 @@ const Select = (props) => {
170178

171179
const invalidText = (meta.touched && meta.error) || '';
172180

173-
const specialOnChange = ({ selectedItems }) => {
174-
if (rest.simpleValue) {
175-
return input.onChange(selectedItems.map(({ value }) => value));
176-
} else {
177-
return input.onChange(selectedItems);
178-
}
179-
};
180-
181181
return (
182182
<DataDrivenSelect
183183
SelectComponent={Component}
@@ -187,7 +187,7 @@ const Select = (props) => {
187187
loadOptions={loadOptions}
188188
invalidText={invalidText}
189189
loadOptionsChangeCounter={loadOptionsChangeCounter}
190-
originalOnChange={specialOnChange}
190+
originalOnChange={multiOnChange(input, rest.simpleValue)}
191191
/>
192192
);
193193
};

packages/carbon-component-mapper/src/files/wizard.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { useContext } from 'react';
22
import WizardCommon from '@data-driven-forms/common/src/wizard/wizard';
33
import { FormSpy, WizardContext } from '@data-driven-forms/react-form-renderer';
44

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import React from 'react';
2+
import { mount } from 'enzyme';
3+
4+
import FormRenderer, { componentTypes } from '@data-driven-forms/react-form-renderer';
5+
6+
import FormTemplate from '../files/form-template';
7+
import componentMapper from '../files/component-mapper';
8+
import { Checkbox } from 'carbon-components-react';
9+
10+
describe('<Checkbox />', () => {
11+
it('renders multiple checkbox', () => {
12+
const schema = {
13+
fields: [
14+
{
15+
component: componentTypes.CHECKBOX,
16+
name: 'check',
17+
label: 'Please select on of options',
18+
options: [
19+
{
20+
label: 'option 1',
21+
value: 1
22+
},
23+
{
24+
label: 'option 2',
25+
value: 2
26+
}
27+
]
28+
}
29+
]
30+
};
31+
32+
const wrapper = mount(
33+
<FormRenderer onSubmit={jest.fn()} FormTemplate={(props) => <FormTemplate {...props} />} schema={schema} componentMapper={componentMapper} />
34+
);
35+
36+
expect(wrapper.find(Checkbox)).toHaveLength(2);
37+
expect(
38+
wrapper
39+
.find(Checkbox)
40+
.first()
41+
.props().labelText
42+
).toEqual('option 1');
43+
expect(
44+
wrapper
45+
.find(Checkbox)
46+
.last()
47+
.props().labelText
48+
).toEqual('option 2');
49+
});
50+
});
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
import React from 'react';
2+
import { mount } from 'enzyme';
3+
4+
import FormRenderer, { componentTypes, validatorTypes } from '@data-driven-forms/react-form-renderer';
5+
6+
import FormTemplate from '../files/form-template';
7+
import componentMapper from '../files/component-mapper';
8+
import WithDescription from '../common/with-description';
9+
10+
describe('component tests', () => {
11+
const RendererWrapper = ({ schema = { fields: [] }, ...props }) => (
12+
<FormRenderer
13+
onSubmit={jest.fn()}
14+
FormTemplate={(props) => <FormTemplate {...props} />}
15+
schema={schema}
16+
componentMapper={componentMapper}
17+
{...props}
18+
/>
19+
);
20+
let field;
21+
let schema;
22+
23+
const errorText = 'Required';
24+
const helperText = 'I am helper text';
25+
const description = 'This is description';
26+
const options = [
27+
{ label: 'Cat', value: 'cats' },
28+
{ label: 'Dog', value: 'dogs' },
29+
{ label: 'Hamster', value: 'hamsters' }
30+
];
31+
32+
const componentsWithOptions = [componentTypes.RADIO, componentTypes.SELECT];
33+
34+
beforeEach(() => {
35+
field = {};
36+
schema = [];
37+
});
38+
39+
describe('components', () => {
40+
[
41+
componentTypes.TEXT_FIELD,
42+
componentTypes.TEXTAREA,
43+
componentTypes.RADIO,
44+
componentTypes.CHECKBOX,
45+
componentTypes.DATE_PICKER,
46+
componentTypes.TIME_PICKER,
47+
componentTypes.SWITCH,
48+
componentTypes.SELECT,
49+
componentTypes.SLIDER
50+
].forEach((component) => {
51+
describe(`Component type: ${component}`, () => {
52+
beforeEach(() => {
53+
field.component = component;
54+
field.name = 'field-name';
55+
field.label = 'Some label';
56+
57+
if (componentsWithOptions.includes(component)) {
58+
field = {
59+
...field,
60+
options
61+
};
62+
}
63+
64+
schema = { fields: [field] };
65+
});
66+
67+
it('renders correctly', () => {
68+
const wrapper = mount(<RendererWrapper schema={schema} />);
69+
70+
if (component === componentTypes.RADIO) {
71+
expect(wrapper.find('.bx--radio-button-wrapper')).toHaveLength(options.length);
72+
} else {
73+
expect(wrapper.find(componentMapper[component])).toHaveLength(1);
74+
expect(
75+
wrapper
76+
.find('label')
77+
.text()
78+
.includes(field.label)
79+
).toEqual(true);
80+
}
81+
});
82+
83+
it('renders with error', () => {
84+
if ([componentTypes.RADIO, componentTypes.SWITCH, componentTypes.CHECKBOX].includes(component)) {
85+
// 'skipped because this component does not support this';
86+
return;
87+
}
88+
89+
const errorField = {
90+
...field,
91+
validate: [{ type: validatorTypes.REQUIRED }]
92+
};
93+
const wrapper = mount(<RendererWrapper schema={{ fields: [errorField] }} />);
94+
wrapper.find('form').simulate('submit');
95+
96+
if (wrapper.find('#field-name-error-msg').length) {
97+
expect(wrapper.find('#field-name-error-msg').text()).toEqual(errorText);
98+
}
99+
100+
expect(wrapper.find('[invalid=true]').length).toBeGreaterThanOrEqual(1);
101+
});
102+
103+
it('renders with helperText', () => {
104+
if (
105+
[
106+
componentTypes.RADIO,
107+
componentTypes.SWITCH,
108+
componentTypes.CHECKBOX,
109+
componentTypes.DATE_PICKER,
110+
componentTypes.TIME_PICKER,
111+
componentTypes.SLIDER
112+
].includes(component)
113+
) {
114+
// 'skipped because this component does not support this';
115+
return;
116+
}
117+
118+
const helpertextField = {
119+
...field,
120+
helperText
121+
};
122+
const wrapper = mount(<RendererWrapper schema={{ fields: [helpertextField] }} />);
123+
124+
expect(
125+
wrapper
126+
.find('.bx--form__helper-text')
127+
.last()
128+
.text()
129+
).toEqual(helperText);
130+
});
131+
132+
it('renders with description', () => {
133+
const descriptionField = {
134+
...field,
135+
description
136+
};
137+
const wrapper = mount(<RendererWrapper schema={{ fields: [descriptionField] }} />);
138+
139+
expect(wrapper.find(WithDescription)).toHaveLength(1);
140+
});
141+
142+
it('renders with description and helperText', () => {
143+
const descriptionField = {
144+
...field,
145+
description,
146+
...(![
147+
componentTypes.RADIO,
148+
componentTypes.SWITCH,
149+
componentTypes.CHECKBOX,
150+
componentTypes.DATE_PICKER,
151+
componentTypes.TIME_PICKER,
152+
componentTypes.SLIDER
153+
].includes(component)
154+
? { helperText }
155+
: {})
156+
};
157+
const wrapper = mount(<RendererWrapper schema={{ fields: [descriptionField] }} />);
158+
159+
expect(wrapper.find(WithDescription)).toHaveLength(1);
160+
161+
if (
162+
![
163+
componentTypes.RADIO,
164+
componentTypes.SWITCH,
165+
componentTypes.CHECKBOX,
166+
componentTypes.DATE_PICKER,
167+
componentTypes.TIME_PICKER,
168+
componentTypes.SLIDER
169+
].includes(component)
170+
) {
171+
expect(
172+
wrapper
173+
.find('.bx--form__helper-text')
174+
.last()
175+
.text()
176+
).toEqual(helperText);
177+
}
178+
});
179+
180+
it('renders with error and helperText', () => {
181+
const errorFields = {
182+
...field,
183+
...(![
184+
componentTypes.RADIO,
185+
componentTypes.SWITCH,
186+
componentTypes.CHECKBOX,
187+
componentTypes.DATE_PICKER,
188+
componentTypes.TIME_PICKER,
189+
componentTypes.SLIDER
190+
].includes(component)
191+
? { helperText }
192+
: {}),
193+
validate: [{ type: validatorTypes.REQUIRED }]
194+
};
195+
const wrapper = mount(<RendererWrapper schema={{ fields: [errorFields] }} />);
196+
wrapper.find('form').simulate('submit');
197+
198+
if (wrapper.find('#field-name-error-msg').length) {
199+
expect(wrapper.find('#field-name-error-msg').text()).toEqual(errorText);
200+
}
201+
202+
expect(wrapper.find('.bx--form__helper-text')).toHaveLength(0);
203+
});
204+
205+
it('renders isDisabled', () => {
206+
const disabledField = {
207+
...field,
208+
isDisabled: true
209+
};
210+
const wrapper = mount(<RendererWrapper schema={{ fields: [disabledField] }} />);
211+
212+
expect(wrapper.find('[disabled=true]').length).toBeGreaterThanOrEqual(1);
213+
});
214+
});
215+
});
216+
});
217+
});
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React from 'react';
2+
import { mount } from 'enzyme';
3+
4+
import FormRenderer, { componentTypes } from '@data-driven-forms/react-form-renderer';
5+
6+
import FormTemplate from '../files/form-template';
7+
import componentMapper from '../files/component-mapper';
8+
9+
describe('<PlainText />', () => {
10+
it('renders', () => {
11+
const schema = {
12+
fields: [
13+
{
14+
component: componentTypes.PLAIN_TEXT,
15+
name: 'check',
16+
label: 'I am happy text'
17+
},
18+
{
19+
component: componentTypes.PLAIN_TEXT,
20+
name: 'header',
21+
label: 'header',
22+
element: 'h1'
23+
}
24+
]
25+
};
26+
27+
const wrapper = mount(
28+
<FormRenderer onSubmit={jest.fn()} FormTemplate={(props) => <FormTemplate {...props} />} schema={schema} componentMapper={componentMapper} />
29+
);
30+
31+
expect(wrapper.find('p').text()).toEqual('I am happy text');
32+
expect(wrapper.find('h1').text()).toEqual('header');
33+
});
34+
});

0 commit comments

Comments
 (0)