@k-int/stripes-kint-components 5.8.2 → 5.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [5.8.3](https://gitlab.com/knowledge-integration/folio/stripes-kint-components/compare/v5.8.2...v5.8.3) (2024-10-23)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* ERM-3391--NumberField doesnt update display value from form state changes ([cb44d06](https://gitlab.com/knowledge-integration/folio/stripes-kint-components/commit/cb44d063aed221cb544204b8b5d9df6dc313e9c2))
|
|
7
|
+
|
|
1
8
|
## [5.8.2](https://gitlab.com/knowledge-integration/folio/stripes-kint-components/compare/v5.8.1...v5.8.2) (2024-09-11)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -31,13 +31,18 @@ const NumberField = props => {
|
|
|
31
31
|
|
|
32
32
|
// Allow direct control of field
|
|
33
33
|
(0, _react.useEffect)(() => {
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
const valueToUse = value ?? input.value;
|
|
35
|
+
if (!valueToUse && numValue) {
|
|
36
|
+
// Make sure to empty out if it's cleared. Treating '' as empty instead of undefined
|
|
37
|
+
setNumValue('');
|
|
38
|
+
}
|
|
39
|
+
if (valueToUse && numValue !== valueToUse) {
|
|
40
|
+
setNumValue(valueToUse);
|
|
36
41
|
}
|
|
37
|
-
if (
|
|
42
|
+
if (forceControl !== numValue) {
|
|
38
43
|
setForceControl(numValue);
|
|
39
44
|
}
|
|
40
|
-
}, [forceControl, numValue, value]);
|
|
45
|
+
}, [forceControl, numValue, value, input]);
|
|
41
46
|
const handleChange = e => {
|
|
42
47
|
// Actually set the value in the form
|
|
43
48
|
if (input?.onChange) {
|
|
@@ -55,7 +60,7 @@ const NumberField = props => {
|
|
|
55
60
|
const handleUserChange = e => {
|
|
56
61
|
const parsedValue = parseFloat(e.target.value);
|
|
57
62
|
|
|
58
|
-
// ReturnValue needed for
|
|
63
|
+
// ReturnValue needed for controlled components
|
|
59
64
|
if (parsedValue || parsedValue === 0) {
|
|
60
65
|
setNumValue(parsedValue);
|
|
61
66
|
changeField(parsedValue);
|
|
@@ -83,6 +88,7 @@ const NumberField = props => {
|
|
|
83
88
|
ref: inputRef,
|
|
84
89
|
...input,
|
|
85
90
|
hidden: true,
|
|
91
|
+
id: input?.name,
|
|
86
92
|
onChange: handleChange,
|
|
87
93
|
type: "number",
|
|
88
94
|
value: numValue
|
|
@@ -93,6 +99,7 @@ NumberField.propTypes = {
|
|
|
93
99
|
onBlur: _propTypes.default.func,
|
|
94
100
|
onChange: _propTypes.default.func,
|
|
95
101
|
input: _propTypes.default.shape({
|
|
102
|
+
name: _propTypes.default.string.isRequired,
|
|
96
103
|
onChange: _propTypes.default.func.isRequired,
|
|
97
104
|
onBlur: _propTypes.default.func,
|
|
98
105
|
value: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string])
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = require("react");
|
|
4
|
+
var _reactFinalForm = require("react-final-form");
|
|
5
|
+
var _userEvent = _interopRequireDefault(require("@folio/jest-config-stripes/testing-library/user-event"));
|
|
6
|
+
var _react2 = require("@folio/jest-config-stripes/testing-library/react");
|
|
7
|
+
var _stripesErmTesting = require("@folio/stripes-erm-testing");
|
|
8
|
+
var _components = require("@folio/stripes/components");
|
|
9
|
+
var _NumberField = _interopRequireDefault(require("./NumberField"));
|
|
10
|
+
var _helpers = require("../../../test/jest/helpers");
|
|
11
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
+
const onSubmit = jest.fn();
|
|
14
|
+
const NUMBER_FIELD_LABEL = 'TEST NUMBER FIELD';
|
|
15
|
+
const NUMBER_FIELD_ID = 'number-field-test';
|
|
16
|
+
const NUMBER_FIELD_INPUT_ID = 'input-id-test';
|
|
17
|
+
const RESET_BUTTON_LABEL = 'RESET NUMBER FIELD';
|
|
18
|
+
|
|
19
|
+
// We need to use jest selectors instead of interactors as the TextField interactor
|
|
20
|
+
// can't handle the double-text-field nature of NumberField
|
|
21
|
+
const getTextField = () => {
|
|
22
|
+
// Spinbutton because it's a "number" type textField...
|
|
23
|
+
return _react2.screen.getByRole('spinbutton', {
|
|
24
|
+
name: NUMBER_FIELD_LABEL
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
const submitForm = async () => {
|
|
28
|
+
await (0, _react2.waitFor)(async () => {
|
|
29
|
+
await (0, _stripesErmTesting.Button)('Submit').click();
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
const SpecialResetButton = () => {
|
|
33
|
+
const {
|
|
34
|
+
change
|
|
35
|
+
} = (0, _reactFinalForm.useForm)();
|
|
36
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, {
|
|
37
|
+
onClick: () => change(NUMBER_FIELD_INPUT_ID, undefined),
|
|
38
|
+
children: RESET_BUTTON_LABEL
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
const NonControlledComponent = () => {
|
|
42
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
43
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(SpecialResetButton, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFinalForm.Field, {
|
|
44
|
+
component: _NumberField.default,
|
|
45
|
+
id: NUMBER_FIELD_ID,
|
|
46
|
+
label: NUMBER_FIELD_LABEL,
|
|
47
|
+
name: NUMBER_FIELD_INPUT_ID
|
|
48
|
+
})]
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
const ControlledComponent = () => {
|
|
52
|
+
const [value, setValue] = (0, _react.useState)();
|
|
53
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
54
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(SpecialResetButton, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFinalForm.Field, {
|
|
55
|
+
component: _NumberField.default,
|
|
56
|
+
id: NUMBER_FIELD_ID,
|
|
57
|
+
label: NUMBER_FIELD_LABEL,
|
|
58
|
+
name: NUMBER_FIELD_INPUT_ID,
|
|
59
|
+
onChange: e => setValue(e.target.value),
|
|
60
|
+
value: value
|
|
61
|
+
})]
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// EXAMPLE nesting repeated tests with describe.each or test.each might speed up some of our test writing
|
|
66
|
+
describe.each([['Non-Controlled', /*#__PURE__*/(0, _jsxRuntime.jsx)(NonControlledComponent, {})], ['Controlled', /*#__PURE__*/(0, _jsxRuntime.jsx)(ControlledComponent, {})]])('NumberField', (controlType, component) => {
|
|
67
|
+
let _renderComponent;
|
|
68
|
+
let textField;
|
|
69
|
+
describe(`Regular usage (${controlType})`, () => {
|
|
70
|
+
beforeEach(async () => {
|
|
71
|
+
onSubmit.mockClear();
|
|
72
|
+
_renderComponent = (0, _helpers.renderWithKintHarness)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_stripesErmTesting.TestForm, {
|
|
73
|
+
initialValues: {},
|
|
74
|
+
onSubmit: onSubmit,
|
|
75
|
+
children: component
|
|
76
|
+
}));
|
|
77
|
+
textField = getTextField();
|
|
78
|
+
});
|
|
79
|
+
it('renders text field as expected', () => {
|
|
80
|
+
expect(textField).toBeInTheDocument();
|
|
81
|
+
});
|
|
82
|
+
describe.each([['non-numeric characters', 'sdhukjasklfs', '', {}], ['numeric characters', '12345', '12345', {
|
|
83
|
+
[NUMBER_FIELD_INPUT_ID]: '12345'
|
|
84
|
+
}], ['scientific notation', '1e5', '100000', {
|
|
85
|
+
[NUMBER_FIELD_INPUT_ID]: '100000'
|
|
86
|
+
}], ['negative numbers', '-100', '-100', {
|
|
87
|
+
[NUMBER_FIELD_INPUT_ID]: '-100'
|
|
88
|
+
}]])('Typing', (characterType, typedChars, expectedDisplay, expectedSubmit) => {
|
|
89
|
+
describe(`typing ${characterType}`, () => {
|
|
90
|
+
beforeEach(async () => {
|
|
91
|
+
await (0, _react2.waitFor)(async () => {
|
|
92
|
+
await _userEvent.default.type(textField, typedChars);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
it('does not render typed characters', async () => {
|
|
96
|
+
expect(textField).toHaveDisplayValue(expectedDisplay);
|
|
97
|
+
});
|
|
98
|
+
describe('submitting the form', () => {
|
|
99
|
+
beforeEach(submitForm);
|
|
100
|
+
it('submits with expected values', () => {
|
|
101
|
+
expect(onSubmit.mock.calls[0][0]).toEqual(expectedSubmit);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
describe.each([['numeric initialvalues', {
|
|
108
|
+
[NUMBER_FIELD_INPUT_ID]: '7654321'
|
|
109
|
+
}, '7654321', {
|
|
110
|
+
[NUMBER_FIELD_INPUT_ID]: '7654321'
|
|
111
|
+
}], ['regular scientific initialvalue NOTE: scientific value parsing does NOT work from initialValues', {
|
|
112
|
+
[NUMBER_FIELD_INPUT_ID]: '3e7'
|
|
113
|
+
}, '3e7', {
|
|
114
|
+
[NUMBER_FIELD_INPUT_ID]: '3e7'
|
|
115
|
+
}], ['negative initialvalue', {
|
|
116
|
+
[NUMBER_FIELD_INPUT_ID]: '-100'
|
|
117
|
+
}, '-100', {
|
|
118
|
+
[NUMBER_FIELD_INPUT_ID]: '-100'
|
|
119
|
+
}]])(`Initial values (${controlType})`, (describeTitle, initialValues, displayValue, submitValue) => {
|
|
120
|
+
describe(describeTitle, () => {
|
|
121
|
+
beforeEach(async () => {
|
|
122
|
+
onSubmit.mockClear();
|
|
123
|
+
_renderComponent = (0, _helpers.renderWithKintHarness)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_stripesErmTesting.TestForm, {
|
|
124
|
+
initialValues: initialValues,
|
|
125
|
+
onSubmit: onSubmit,
|
|
126
|
+
children: component
|
|
127
|
+
}));
|
|
128
|
+
textField = getTextField();
|
|
129
|
+
});
|
|
130
|
+
it('renders initial value', async () => {
|
|
131
|
+
expect(textField).toHaveDisplayValue(displayValue);
|
|
132
|
+
});
|
|
133
|
+
describe('submitting the form', () => {
|
|
134
|
+
beforeEach(submitForm);
|
|
135
|
+
it('submits with expected values', () => {
|
|
136
|
+
expect(onSubmit.mock.calls[0][0]).toEqual(submitValue);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe.each([['Clear after typing', async () => {
|
|
142
|
+
onSubmit.mockClear();
|
|
143
|
+
_renderComponent = (0, _helpers.renderWithKintHarness)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_stripesErmTesting.TestForm, {
|
|
144
|
+
initialValues: {},
|
|
145
|
+
onSubmit: onSubmit,
|
|
146
|
+
children: component
|
|
147
|
+
}));
|
|
148
|
+
textField = getTextField();
|
|
149
|
+
await (0, _react2.waitFor)(async () => {
|
|
150
|
+
await _userEvent.default.type(textField, '32786843');
|
|
151
|
+
});
|
|
152
|
+
}], ['Clear from initialValues', async () => {
|
|
153
|
+
onSubmit.mockClear();
|
|
154
|
+
_renderComponent = (0, _helpers.renderWithKintHarness)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_stripesErmTesting.TestForm, {
|
|
155
|
+
initialValues: {
|
|
156
|
+
[NUMBER_FIELD_INPUT_ID]: '32786843'
|
|
157
|
+
},
|
|
158
|
+
onSubmit: onSubmit,
|
|
159
|
+
children: component
|
|
160
|
+
}));
|
|
161
|
+
textField = getTextField();
|
|
162
|
+
}]])(`ERM-3391: state change underneath component (${controlType})`, (clearType, beforeEachFunc) => {
|
|
163
|
+
describe(clearType, () => {
|
|
164
|
+
beforeEach(beforeEachFunc);
|
|
165
|
+
it('renders text field', () => {
|
|
166
|
+
expect(textField).toBeInTheDocument();
|
|
167
|
+
});
|
|
168
|
+
it('renders special reset button', async () => {
|
|
169
|
+
await (0, _stripesErmTesting.Button)(RESET_BUTTON_LABEL).exists();
|
|
170
|
+
});
|
|
171
|
+
describe.each([['Control', false, '32786843', {
|
|
172
|
+
[NUMBER_FIELD_INPUT_ID]: '32786843'
|
|
173
|
+
}], ['After reset', true, '', {}]])('Test reset', (describeTitle, clearField, expectedValue, expectedSubmit) => {
|
|
174
|
+
describe(describeTitle, () => {
|
|
175
|
+
beforeEach(async () => {
|
|
176
|
+
onSubmit.mockClear();
|
|
177
|
+
if (clearField) {
|
|
178
|
+
await (0, _react2.waitFor)(async () => {
|
|
179
|
+
await (0, _stripesErmTesting.Button)(RESET_BUTTON_LABEL).click();
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
it(`renders text field with display value: ${expectedValue}`, async () => {
|
|
184
|
+
await (0, _react2.waitFor)(() => {
|
|
185
|
+
expect(textField).toHaveDisplayValue(expectedValue);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
describe('submitting', () => {
|
|
189
|
+
describe('submitting the form', () => {
|
|
190
|
+
beforeEach(submitForm);
|
|
191
|
+
it('submits with expected values', () => {
|
|
192
|
+
expect(onSubmit.mock.calls[0][0]).toEqual(expectedSubmit);
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
});
|
package/package.json
CHANGED
|
@@ -37,14 +37,21 @@ const NumberField = (props) => {
|
|
|
37
37
|
|
|
38
38
|
// Allow direct control of field
|
|
39
39
|
useEffect(() => {
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
const valueToUse = value ?? input.value;
|
|
41
|
+
|
|
42
|
+
if (!valueToUse && numValue) {
|
|
43
|
+
// Make sure to empty out if it's cleared. Treating '' as empty instead of undefined
|
|
44
|
+
setNumValue('');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (valueToUse && numValue !== valueToUse) {
|
|
48
|
+
setNumValue(valueToUse);
|
|
42
49
|
}
|
|
43
50
|
|
|
44
|
-
if (
|
|
51
|
+
if (forceControl !== numValue) {
|
|
45
52
|
setForceControl(numValue);
|
|
46
53
|
}
|
|
47
|
-
}, [forceControl, numValue, value]);
|
|
54
|
+
}, [forceControl, numValue, value, input]);
|
|
48
55
|
|
|
49
56
|
const handleChange = (e) => {
|
|
50
57
|
// Actually set the value in the form
|
|
@@ -61,12 +68,10 @@ const NumberField = (props) => {
|
|
|
61
68
|
}
|
|
62
69
|
};
|
|
63
70
|
|
|
64
|
-
|
|
65
|
-
|
|
66
71
|
const handleUserChange = (e) => {
|
|
67
72
|
const parsedValue = parseFloat(e.target.value);
|
|
68
73
|
|
|
69
|
-
// ReturnValue needed for
|
|
74
|
+
// ReturnValue needed for controlled components
|
|
70
75
|
if (parsedValue || parsedValue === 0) {
|
|
71
76
|
setNumValue(parsedValue);
|
|
72
77
|
changeField(parsedValue);
|
|
@@ -96,6 +101,7 @@ const NumberField = (props) => {
|
|
|
96
101
|
ref={inputRef}
|
|
97
102
|
{...input}
|
|
98
103
|
hidden
|
|
104
|
+
id={input?.name}
|
|
99
105
|
onChange={handleChange}
|
|
100
106
|
type="number"
|
|
101
107
|
value={numValue}
|
|
@@ -108,6 +114,7 @@ NumberField.propTypes = {
|
|
|
108
114
|
onBlur: PropTypes.func,
|
|
109
115
|
onChange: PropTypes.func,
|
|
110
116
|
input: PropTypes.shape({
|
|
117
|
+
name: PropTypes.string.isRequired,
|
|
111
118
|
onChange: PropTypes.func.isRequired,
|
|
112
119
|
onBlur: PropTypes.func,
|
|
113
120
|
value: PropTypes.oneOfType([
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { Field, useForm } from 'react-final-form';
|
|
3
|
+
|
|
4
|
+
import userEvent from '@folio/jest-config-stripes/testing-library/user-event';
|
|
5
|
+
import { screen, waitFor } from '@folio/jest-config-stripes/testing-library/react';
|
|
6
|
+
|
|
7
|
+
import { Button, TestForm, TextField } from '@folio/stripes-erm-testing';
|
|
8
|
+
import { Button as StripesButton } from '@folio/stripes/components';
|
|
9
|
+
|
|
10
|
+
import NumberField from './NumberField';
|
|
11
|
+
|
|
12
|
+
import { renderWithKintHarness } from '../../../test/jest/helpers';
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
const onSubmit = jest.fn();
|
|
16
|
+
|
|
17
|
+
const NUMBER_FIELD_LABEL = 'TEST NUMBER FIELD';
|
|
18
|
+
const NUMBER_FIELD_ID = 'number-field-test';
|
|
19
|
+
const NUMBER_FIELD_INPUT_ID = 'input-id-test';
|
|
20
|
+
|
|
21
|
+
const RESET_BUTTON_LABEL = 'RESET NUMBER FIELD';
|
|
22
|
+
|
|
23
|
+
// We need to use jest selectors instead of interactors as the TextField interactor
|
|
24
|
+
// can't handle the double-text-field nature of NumberField
|
|
25
|
+
const getTextField = () => {
|
|
26
|
+
// Spinbutton because it's a "number" type textField...
|
|
27
|
+
return screen.getByRole('spinbutton', { name: NUMBER_FIELD_LABEL });
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const submitForm = async () => {
|
|
31
|
+
await waitFor(async () => {
|
|
32
|
+
await Button('Submit').click();
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const SpecialResetButton = () => {
|
|
37
|
+
const { change } = useForm();
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<StripesButton
|
|
41
|
+
onClick={() => change(NUMBER_FIELD_INPUT_ID, undefined)}
|
|
42
|
+
>
|
|
43
|
+
{RESET_BUTTON_LABEL}
|
|
44
|
+
</StripesButton>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const NonControlledComponent = () => {
|
|
49
|
+
return (
|
|
50
|
+
<>
|
|
51
|
+
<SpecialResetButton />
|
|
52
|
+
<Field
|
|
53
|
+
component={NumberField}
|
|
54
|
+
id={NUMBER_FIELD_ID}
|
|
55
|
+
label={NUMBER_FIELD_LABEL}
|
|
56
|
+
name={NUMBER_FIELD_INPUT_ID}
|
|
57
|
+
/>
|
|
58
|
+
</>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const ControlledComponent = () => {
|
|
63
|
+
const [value, setValue] = useState();
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<>
|
|
67
|
+
<SpecialResetButton />
|
|
68
|
+
<Field
|
|
69
|
+
component={NumberField}
|
|
70
|
+
id={NUMBER_FIELD_ID}
|
|
71
|
+
label={NUMBER_FIELD_LABEL}
|
|
72
|
+
name={NUMBER_FIELD_INPUT_ID}
|
|
73
|
+
onChange={e => setValue(e.target.value)}
|
|
74
|
+
value={value}
|
|
75
|
+
/>
|
|
76
|
+
</>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// EXAMPLE nesting repeated tests with describe.each or test.each might speed up some of our test writing
|
|
81
|
+
describe.each([
|
|
82
|
+
['Non-Controlled', <NonControlledComponent />],
|
|
83
|
+
['Controlled', <ControlledComponent />],
|
|
84
|
+
])('NumberField', (controlType, component) => {
|
|
85
|
+
let _renderComponent;
|
|
86
|
+
let textField;
|
|
87
|
+
describe(`Regular usage (${controlType})`, () => {
|
|
88
|
+
beforeEach(async () => {
|
|
89
|
+
onSubmit.mockClear();
|
|
90
|
+
_renderComponent = renderWithKintHarness(
|
|
91
|
+
<TestForm
|
|
92
|
+
initialValues={{}}
|
|
93
|
+
onSubmit={onSubmit}
|
|
94
|
+
>
|
|
95
|
+
{component}
|
|
96
|
+
</TestForm>
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
textField = getTextField();
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('renders text field as expected', () => {
|
|
103
|
+
expect(textField).toBeInTheDocument();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe.each([
|
|
107
|
+
['non-numeric characters', 'sdhukjasklfs', '', {}],
|
|
108
|
+
['numeric characters', '12345', '12345', { [NUMBER_FIELD_INPUT_ID]: '12345' }],
|
|
109
|
+
['scientific notation', '1e5', '100000', { [NUMBER_FIELD_INPUT_ID]: '100000' }],
|
|
110
|
+
['negative numbers', '-100', '-100', { [NUMBER_FIELD_INPUT_ID]: '-100' }],
|
|
111
|
+
])('Typing', (characterType, typedChars, expectedDisplay, expectedSubmit) => {
|
|
112
|
+
describe(`typing ${characterType}`, () => {
|
|
113
|
+
beforeEach(async () => {
|
|
114
|
+
await waitFor(async () => {
|
|
115
|
+
await userEvent.type(textField, typedChars);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('does not render typed characters', async () => {
|
|
120
|
+
expect(textField).toHaveDisplayValue(expectedDisplay);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
describe('submitting the form', () => {
|
|
124
|
+
beforeEach(submitForm);
|
|
125
|
+
|
|
126
|
+
it('submits with expected values', () => {
|
|
127
|
+
expect(onSubmit.mock.calls[0][0]).toEqual(expectedSubmit);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe.each([
|
|
135
|
+
['numeric initialvalues', { [NUMBER_FIELD_INPUT_ID]: '7654321' }, '7654321', { [NUMBER_FIELD_INPUT_ID]: '7654321' }],
|
|
136
|
+
['regular scientific initialvalue NOTE: scientific value parsing does NOT work from initialValues', { [NUMBER_FIELD_INPUT_ID]: '3e7' }, '3e7', { [NUMBER_FIELD_INPUT_ID]: '3e7' }],
|
|
137
|
+
['negative initialvalue', { [NUMBER_FIELD_INPUT_ID]: '-100' }, '-100', { [NUMBER_FIELD_INPUT_ID]: '-100' }],
|
|
138
|
+
])(`Initial values (${controlType})`, (describeTitle, initialValues, displayValue, submitValue) => {
|
|
139
|
+
describe(describeTitle, () => {
|
|
140
|
+
beforeEach(async () => {
|
|
141
|
+
onSubmit.mockClear();
|
|
142
|
+
_renderComponent = renderWithKintHarness(
|
|
143
|
+
<TestForm
|
|
144
|
+
initialValues={initialValues}
|
|
145
|
+
onSubmit={onSubmit}
|
|
146
|
+
>
|
|
147
|
+
{component}
|
|
148
|
+
</TestForm>
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
textField = getTextField();
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('renders initial value', async () => {
|
|
155
|
+
expect(textField).toHaveDisplayValue(displayValue);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
describe('submitting the form', () => {
|
|
159
|
+
beforeEach(submitForm);
|
|
160
|
+
|
|
161
|
+
it('submits with expected values', () => {
|
|
162
|
+
expect(onSubmit.mock.calls[0][0]).toEqual(submitValue);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe.each([
|
|
169
|
+
[
|
|
170
|
+
'Clear after typing',
|
|
171
|
+
async () => {
|
|
172
|
+
onSubmit.mockClear();
|
|
173
|
+
_renderComponent = renderWithKintHarness(
|
|
174
|
+
<TestForm
|
|
175
|
+
initialValues={{}}
|
|
176
|
+
onSubmit={onSubmit}
|
|
177
|
+
>
|
|
178
|
+
{component}
|
|
179
|
+
</TestForm>
|
|
180
|
+
);
|
|
181
|
+
textField = getTextField();
|
|
182
|
+
|
|
183
|
+
await waitFor(async () => {
|
|
184
|
+
await userEvent.type(textField, '32786843');
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
],
|
|
188
|
+
[
|
|
189
|
+
'Clear from initialValues',
|
|
190
|
+
async () => {
|
|
191
|
+
onSubmit.mockClear();
|
|
192
|
+
_renderComponent = renderWithKintHarness(
|
|
193
|
+
<TestForm
|
|
194
|
+
initialValues={{ [NUMBER_FIELD_INPUT_ID]: '32786843' }}
|
|
195
|
+
onSubmit={onSubmit}
|
|
196
|
+
>
|
|
197
|
+
{component}
|
|
198
|
+
</TestForm>
|
|
199
|
+
);
|
|
200
|
+
textField = getTextField();
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
])(`ERM-3391: state change underneath component (${controlType})`, (clearType, beforeEachFunc) => {
|
|
204
|
+
describe(clearType, () => {
|
|
205
|
+
beforeEach(beforeEachFunc);
|
|
206
|
+
|
|
207
|
+
it('renders text field', () => {
|
|
208
|
+
expect(textField).toBeInTheDocument();
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('renders special reset button', async () => {
|
|
212
|
+
await Button(RESET_BUTTON_LABEL).exists();
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
describe.each([
|
|
216
|
+
[
|
|
217
|
+
'Control',
|
|
218
|
+
false,
|
|
219
|
+
'32786843',
|
|
220
|
+
{ [NUMBER_FIELD_INPUT_ID]: '32786843' }
|
|
221
|
+
],
|
|
222
|
+
[
|
|
223
|
+
'After reset',
|
|
224
|
+
true,
|
|
225
|
+
'',
|
|
226
|
+
{}
|
|
227
|
+
]
|
|
228
|
+
])('Test reset', (describeTitle, clearField, expectedValue, expectedSubmit) => {
|
|
229
|
+
describe(describeTitle, () => {
|
|
230
|
+
beforeEach(async () => {
|
|
231
|
+
onSubmit.mockClear();
|
|
232
|
+
if (clearField) {
|
|
233
|
+
await waitFor(async () => {
|
|
234
|
+
await Button(RESET_BUTTON_LABEL).click();
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it(`renders text field with display value: ${expectedValue}`, async () => {
|
|
240
|
+
await waitFor(() => {
|
|
241
|
+
expect(textField).toHaveDisplayValue(expectedValue);
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
describe('submitting', () => {
|
|
246
|
+
describe('submitting the form', () => {
|
|
247
|
+
beforeEach(submitForm);
|
|
248
|
+
|
|
249
|
+
it('submits with expected values', () => {
|
|
250
|
+
expect(onSubmit.mock.calls[0][0]).toEqual(expectedSubmit);
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
});
|