mirror of
https://github.com/ansible/awx.git
synced 2026-03-24 12:25:01 -02:30
Merge pull request #8661 from marshmalien/setting-jobs-ui
Add job settings form and unit tests Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
@@ -2,13 +2,13 @@ import React from 'react';
|
|||||||
import { act } from 'react-dom/test-utils';
|
import { act } from 'react-dom/test-utils';
|
||||||
import { createMemoryHistory } from 'history';
|
import { createMemoryHistory } from 'history';
|
||||||
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
|
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
|
||||||
import Jobs from './Jobs';
|
import mockJobSettings from '../shared/data.jobSettings.json';
|
||||||
|
|
||||||
import { SettingsAPI } from '../../../api';
|
import { SettingsAPI } from '../../../api';
|
||||||
|
import Jobs from './Jobs';
|
||||||
|
|
||||||
jest.mock('../../../api/models/Settings');
|
jest.mock('../../../api/models/Settings');
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: {},
|
data: mockJobSettings,
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('<Jobs />', () => {
|
describe('<Jobs />', () => {
|
||||||
|
|||||||
@@ -1,25 +1,242 @@
|
|||||||
import React from 'react';
|
import React, { useCallback, useEffect } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { withI18n } from '@lingui/react';
|
import { Formik } from 'formik';
|
||||||
import { t } from '@lingui/macro';
|
import { Form } from '@patternfly/react-core';
|
||||||
import { Button } from '@patternfly/react-core';
|
import { CardBody } from '../../../../components/Card';
|
||||||
import { CardBody, CardActionsRow } from '../../../../components/Card';
|
import ContentError from '../../../../components/ContentError';
|
||||||
|
import ContentLoading from '../../../../components/ContentLoading';
|
||||||
|
import { FormSubmitError } from '../../../../components/FormField';
|
||||||
|
import { FormColumnLayout } from '../../../../components/FormLayout';
|
||||||
|
import { useSettings } from '../../../../contexts/Settings';
|
||||||
|
import {
|
||||||
|
BooleanField,
|
||||||
|
InputField,
|
||||||
|
ObjectField,
|
||||||
|
RevertAllAlert,
|
||||||
|
RevertFormActionGroup,
|
||||||
|
} from '../../shared';
|
||||||
|
import useModal from '../../../../util/useModal';
|
||||||
|
import useRequest from '../../../../util/useRequest';
|
||||||
|
import { formatJson } from '../../shared/settingUtils';
|
||||||
|
import { SettingsAPI } from '../../../../api';
|
||||||
|
|
||||||
|
function JobsEdit() {
|
||||||
|
const history = useHistory();
|
||||||
|
const { isModalOpen, toggleModal, closeModal } = useModal();
|
||||||
|
const { PUT: options } = useSettings();
|
||||||
|
|
||||||
|
const { isLoading, error, request: fetchJobs, result: jobs } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
const { data } = await SettingsAPI.readCategory('jobs');
|
||||||
|
const {
|
||||||
|
ALLOW_JINJA_IN_EXTRA_VARS,
|
||||||
|
AWX_ISOLATED_KEY_GENERATION,
|
||||||
|
AWX_ISOLATED_PRIVATE_KEY,
|
||||||
|
AWX_ISOLATED_PUBLIC_KEY,
|
||||||
|
EVENT_STDOUT_MAX_BYTES_DISPLAY,
|
||||||
|
STDOUT_MAX_BYTES_DISPLAY,
|
||||||
|
...jobsData
|
||||||
|
} = data;
|
||||||
|
const mergedData = {};
|
||||||
|
Object.keys(jobsData).forEach(key => {
|
||||||
|
if (!options[key]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mergedData[key] = options[key];
|
||||||
|
mergedData[key].value = jobsData[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
return mergedData;
|
||||||
|
}, [options]),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchJobs();
|
||||||
|
}, [fetchJobs]);
|
||||||
|
|
||||||
|
const { error: submitError, request: submitForm } = useRequest(
|
||||||
|
useCallback(
|
||||||
|
async values => {
|
||||||
|
await SettingsAPI.updateAll(values);
|
||||||
|
history.push('/settings/jobs/details');
|
||||||
|
},
|
||||||
|
[history]
|
||||||
|
),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSubmit = async form => {
|
||||||
|
await submitForm({
|
||||||
|
...form,
|
||||||
|
AD_HOC_COMMANDS: formatJson(form.AD_HOC_COMMANDS),
|
||||||
|
AWX_PROOT_SHOW_PATHS: formatJson(form.AWX_PROOT_SHOW_PATHS),
|
||||||
|
AWX_PROOT_HIDE_PATHS: formatJson(form.AWX_PROOT_HIDE_PATHS),
|
||||||
|
AWX_ANSIBLE_CALLBACK_PLUGINS: formatJson(
|
||||||
|
form.AWX_ANSIBLE_CALLBACK_PLUGINS
|
||||||
|
),
|
||||||
|
AWX_TASK_ENV: formatJson(form.AWX_TASK_ENV),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRevertAll = async () => {
|
||||||
|
const defaultValues = {};
|
||||||
|
Object.entries(jobs).forEach(([key, value]) => {
|
||||||
|
defaultValues[key] = value.default;
|
||||||
|
});
|
||||||
|
await submitForm(defaultValues);
|
||||||
|
closeModal();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
history.push('/settings/jobs/details');
|
||||||
|
};
|
||||||
|
|
||||||
|
const initialValues = fields =>
|
||||||
|
Object.keys(fields).reduce((acc, key) => {
|
||||||
|
if (fields[key].type === 'list' || fields[key].type === 'nested object') {
|
||||||
|
const emptyDefault = fields[key].type === 'list' ? '[]' : '{}';
|
||||||
|
acc[key] = fields[key].value
|
||||||
|
? JSON.stringify(fields[key].value, null, 2)
|
||||||
|
: emptyDefault;
|
||||||
|
} else {
|
||||||
|
acc[key] = fields[key].value ?? '';
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
function JobsEdit({ i18n }) {
|
|
||||||
return (
|
return (
|
||||||
<CardBody>
|
<CardBody>
|
||||||
{i18n._(t`Edit form coming soon :)`)}
|
{isLoading && <ContentLoading />}
|
||||||
<CardActionsRow>
|
{!isLoading && error && <ContentError error={error} />}
|
||||||
<Button
|
{!isLoading && jobs && (
|
||||||
aria-label={i18n._(t`Cancel`)}
|
<Formik initialValues={initialValues(jobs)} onSubmit={handleSubmit}>
|
||||||
component={Link}
|
{formik => {
|
||||||
to="/settings/jobs/details"
|
return (
|
||||||
>
|
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||||
{i18n._(t`Cancel`)}
|
<FormColumnLayout>
|
||||||
</Button>
|
<InputField
|
||||||
</CardActionsRow>
|
name="AWX_PROOT_BASE_PATH"
|
||||||
|
config={jobs.AWX_PROOT_BASE_PATH}
|
||||||
|
isRequired
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="SCHEDULE_MAX_JOBS"
|
||||||
|
config={jobs.SCHEDULE_MAX_JOBS}
|
||||||
|
type="number"
|
||||||
|
isRequired
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="DEFAULT_JOB_TIMEOUT"
|
||||||
|
config={jobs.DEFAULT_JOB_TIMEOUT}
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="DEFAULT_INVENTORY_UPDATE_TIMEOUT"
|
||||||
|
config={jobs.DEFAULT_INVENTORY_UPDATE_TIMEOUT}
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="DEFAULT_PROJECT_UPDATE_TIMEOUT"
|
||||||
|
config={jobs.DEFAULT_PROJECT_UPDATE_TIMEOUT}
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="ANSIBLE_FACT_CACHE_TIMEOUT"
|
||||||
|
config={jobs.ANSIBLE_FACT_CACHE_TIMEOUT}
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="MAX_FORKS"
|
||||||
|
config={jobs.MAX_FORKS}
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
<BooleanField
|
||||||
|
name="AWX_PROOT_ENABLED"
|
||||||
|
config={jobs.AWX_PROOT_ENABLED}
|
||||||
|
/>
|
||||||
|
<BooleanField
|
||||||
|
name="PROJECT_UPDATE_VVV"
|
||||||
|
config={jobs.PROJECT_UPDATE_VVV}
|
||||||
|
/>
|
||||||
|
<BooleanField
|
||||||
|
name="GALAXY_IGNORE_CERTS"
|
||||||
|
config={jobs.GALAXY_IGNORE_CERTS}
|
||||||
|
/>
|
||||||
|
<BooleanField
|
||||||
|
name="AWX_ROLES_ENABLED"
|
||||||
|
config={jobs.AWX_ROLES_ENABLED}
|
||||||
|
/>
|
||||||
|
<BooleanField
|
||||||
|
name="AWX_COLLECTIONS_ENABLED"
|
||||||
|
config={jobs.AWX_COLLECTIONS_ENABLED}
|
||||||
|
/>
|
||||||
|
<BooleanField
|
||||||
|
name="AWX_SHOW_PLAYBOOK_LINKS"
|
||||||
|
config={jobs.AWX_SHOW_PLAYBOOK_LINKS}
|
||||||
|
/>
|
||||||
|
<BooleanField
|
||||||
|
name="AWX_ISOLATED_HOST_KEY_CHECKING"
|
||||||
|
config={jobs.AWX_ISOLATED_HOST_KEY_CHECKING}
|
||||||
|
/>
|
||||||
|
<BooleanField
|
||||||
|
name="AWX_RESOURCE_PROFILING_ENABLED"
|
||||||
|
config={jobs.AWX_RESOURCE_PROFILING_ENABLED}
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="AWX_ISOLATED_CHECK_INTERVAL"
|
||||||
|
config={jobs.AWX_ISOLATED_CHECK_INTERVAL}
|
||||||
|
type="number"
|
||||||
|
isRequired
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="AWX_ISOLATED_LAUNCH_TIMEOUT"
|
||||||
|
config={jobs.AWX_ISOLATED_LAUNCH_TIMEOUT}
|
||||||
|
type="number"
|
||||||
|
isRequired
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="AWX_ISOLATED_CONNECTION_TIMEOUT"
|
||||||
|
config={jobs.AWX_ISOLATED_CONNECTION_TIMEOUT}
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
<ObjectField
|
||||||
|
name="AD_HOC_COMMANDS"
|
||||||
|
config={jobs.AD_HOC_COMMANDS}
|
||||||
|
/>
|
||||||
|
<ObjectField
|
||||||
|
name="AWX_ANSIBLE_CALLBACK_PLUGINS"
|
||||||
|
config={jobs.AWX_ANSIBLE_CALLBACK_PLUGINS}
|
||||||
|
/>
|
||||||
|
<ObjectField
|
||||||
|
name="AWX_PROOT_SHOW_PATHS"
|
||||||
|
config={jobs.AWX_PROOT_SHOW_PATHS}
|
||||||
|
/>
|
||||||
|
<ObjectField
|
||||||
|
name="AWX_PROOT_HIDE_PATHS"
|
||||||
|
config={jobs.AWX_PROOT_HIDE_PATHS}
|
||||||
|
/>
|
||||||
|
<ObjectField name="AWX_TASK_ENV" config={jobs.AWX_TASK_ENV} />
|
||||||
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
</FormColumnLayout>
|
||||||
|
<RevertFormActionGroup
|
||||||
|
onCancel={handleCancel}
|
||||||
|
onSubmit={formik.handleSubmit}
|
||||||
|
onRevert={toggleModal}
|
||||||
|
/>
|
||||||
|
{isModalOpen && (
|
||||||
|
<RevertAllAlert
|
||||||
|
onClose={closeModal}
|
||||||
|
onRevertAll={handleRevertAll}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Formik>
|
||||||
|
)}
|
||||||
</CardBody>
|
</CardBody>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withI18n()(JobsEdit);
|
export default JobsEdit;
|
||||||
|
|||||||
@@ -1,16 +1,127 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mountWithContexts } from '../../../../../testUtils/enzymeHelpers';
|
import { act } from 'react-dom/test-utils';
|
||||||
|
import { createMemoryHistory } from 'history';
|
||||||
|
import {
|
||||||
|
mountWithContexts,
|
||||||
|
waitForElement,
|
||||||
|
} from '../../../../../testUtils/enzymeHelpers';
|
||||||
|
import mockAllOptions from '../../shared/data.allSettingOptions.json';
|
||||||
|
import mockJobSettings from '../../shared/data.jobSettings.json';
|
||||||
|
import mockDefaultJobSettings from './data.defaultJobSettings.json';
|
||||||
|
import { SettingsProvider } from '../../../../contexts/Settings';
|
||||||
|
import { SettingsAPI } from '../../../../api';
|
||||||
import JobsEdit from './JobsEdit';
|
import JobsEdit from './JobsEdit';
|
||||||
|
|
||||||
|
jest.mock('../../../../api/models/Settings');
|
||||||
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
|
data: mockJobSettings,
|
||||||
|
});
|
||||||
|
|
||||||
describe('<JobsEdit />', () => {
|
describe('<JobsEdit />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
beforeEach(() => {
|
let history;
|
||||||
wrapper = mountWithContexts(<JobsEdit />);
|
|
||||||
});
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
wrapper.unmount();
|
wrapper.unmount();
|
||||||
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
history = createMemoryHistory({
|
||||||
|
initialEntries: ['/settings/jobs/edit'],
|
||||||
|
});
|
||||||
|
await act(async () => {
|
||||||
|
wrapper = mountWithContexts(
|
||||||
|
<SettingsProvider value={mockAllOptions.actions}>
|
||||||
|
<JobsEdit />
|
||||||
|
</SettingsProvider>,
|
||||||
|
{
|
||||||
|
context: { router: { history } },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||||
|
});
|
||||||
|
|
||||||
test('initially renders without crashing', () => {
|
test('initially renders without crashing', () => {
|
||||||
expect(wrapper.find('JobsEdit').length).toBe(1);
|
expect(wrapper.find('JobsEdit').length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
|
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
||||||
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
|
await act(async () => {
|
||||||
|
wrapper
|
||||||
|
.find('button[aria-label="Revert all to default"]')
|
||||||
|
.invoke('onClick')();
|
||||||
|
});
|
||||||
|
wrapper.update();
|
||||||
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(1);
|
||||||
|
await act(async () => {
|
||||||
|
wrapper
|
||||||
|
.find('RevertAllAlert button[aria-label="Confirm revert all"]')
|
||||||
|
.invoke('onClick')();
|
||||||
|
});
|
||||||
|
wrapper.update();
|
||||||
|
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
||||||
|
expect(SettingsAPI.updateAll).toHaveBeenCalledWith(mockDefaultJobSettings);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
||||||
|
await act(async () => {
|
||||||
|
wrapper.find('Form').invoke('onSubmit')();
|
||||||
|
});
|
||||||
|
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
||||||
|
const {
|
||||||
|
ALLOW_JINJA_IN_EXTRA_VARS,
|
||||||
|
AWX_ISOLATED_KEY_GENERATION,
|
||||||
|
AWX_ISOLATED_PRIVATE_KEY,
|
||||||
|
AWX_ISOLATED_PUBLIC_KEY,
|
||||||
|
EVENT_STDOUT_MAX_BYTES_DISPLAY,
|
||||||
|
STDOUT_MAX_BYTES_DISPLAY,
|
||||||
|
...jobRequest
|
||||||
|
} = mockJobSettings;
|
||||||
|
expect(SettingsAPI.updateAll).toHaveBeenCalledWith(jobRequest);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should display error message on unsuccessful submission', async () => {
|
||||||
|
const error = {
|
||||||
|
response: {
|
||||||
|
data: { detail: 'An error occurred' },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
SettingsAPI.updateAll.mockImplementation(() => Promise.reject(error));
|
||||||
|
expect(wrapper.find('FormSubmitError').length).toBe(0);
|
||||||
|
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
||||||
|
await act(async () => {
|
||||||
|
wrapper.find('Form').invoke('onSubmit')();
|
||||||
|
});
|
||||||
|
wrapper.update();
|
||||||
|
expect(wrapper.find('FormSubmitError').length).toBe(1);
|
||||||
|
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should navigate to job settings detail when cancel is clicked', async () => {
|
||||||
|
await act(async () => {
|
||||||
|
wrapper.find('button[aria-label="Cancel"]').invoke('onClick')();
|
||||||
|
});
|
||||||
|
expect(history.location.pathname).toEqual('/settings/jobs/details');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should display ContentError on throw', async () => {
|
||||||
|
SettingsAPI.readCategory.mockImplementationOnce(() =>
|
||||||
|
Promise.reject(new Error())
|
||||||
|
);
|
||||||
|
await act(async () => {
|
||||||
|
wrapper = mountWithContexts(
|
||||||
|
<SettingsProvider value={mockAllOptions.actions}>
|
||||||
|
<JobsEdit />
|
||||||
|
</SettingsProvider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||||
|
expect(wrapper.find('ContentError').length).toBe(1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"AD_HOC_COMMANDS": [
|
||||||
|
"command",
|
||||||
|
"shell",
|
||||||
|
"yum",
|
||||||
|
"apt",
|
||||||
|
"apt_key",
|
||||||
|
"apt_repository",
|
||||||
|
"apt_rpm",
|
||||||
|
"service",
|
||||||
|
"group",
|
||||||
|
"user",
|
||||||
|
"mount",
|
||||||
|
"ping",
|
||||||
|
"selinux",
|
||||||
|
"setup",
|
||||||
|
"win_ping",
|
||||||
|
"win_service",
|
||||||
|
"win_updates",
|
||||||
|
"win_group",
|
||||||
|
"win_user"
|
||||||
|
],
|
||||||
|
"ANSIBLE_FACT_CACHE_TIMEOUT": 0,
|
||||||
|
"AWX_ANSIBLE_CALLBACK_PLUGINS": [],
|
||||||
|
"AWX_COLLECTIONS_ENABLED": true,
|
||||||
|
"AWX_ISOLATED_CHECK_INTERVAL": 1,
|
||||||
|
"AWX_ISOLATED_CONNECTION_TIMEOUT": 10,
|
||||||
|
"AWX_ISOLATED_HOST_KEY_CHECKING": false,
|
||||||
|
"AWX_ISOLATED_LAUNCH_TIMEOUT": 600,
|
||||||
|
"AWX_PROOT_BASE_PATH": "/tmp",
|
||||||
|
"AWX_PROOT_ENABLED": true,
|
||||||
|
"AWX_PROOT_HIDE_PATHS": [],
|
||||||
|
"AWX_PROOT_SHOW_PATHS": [],
|
||||||
|
"AWX_RESOURCE_PROFILING_CPU_POLL_INTERVAL": 0.25,
|
||||||
|
"AWX_RESOURCE_PROFILING_ENABLED": false,
|
||||||
|
"AWX_RESOURCE_PROFILING_MEMORY_POLL_INTERVAL": 0.25,
|
||||||
|
"AWX_RESOURCE_PROFILING_PID_POLL_INTERVAL": 0.25,
|
||||||
|
"AWX_ROLES_ENABLED": true,
|
||||||
|
"AWX_SHOW_PLAYBOOK_LINKS": false,
|
||||||
|
"AWX_TASK_ENV": {},
|
||||||
|
"DEFAULT_INVENTORY_UPDATE_TIMEOUT": 0,
|
||||||
|
"DEFAULT_JOB_TIMEOUT": 0,
|
||||||
|
"DEFAULT_PROJECT_UPDATE_TIMEOUT": 0,
|
||||||
|
"GALAXY_IGNORE_CERTS": false,
|
||||||
|
"MAX_FORKS": 200,
|
||||||
|
"PROJECT_UPDATE_VVV": false,
|
||||||
|
"SCHEDULE_MAX_JOBS": 10
|
||||||
|
}
|
||||||
@@ -195,7 +195,7 @@ const InputField = withI18n()(
|
|||||||
|
|
||||||
return config ? (
|
return config ? (
|
||||||
<SettingGroup
|
<SettingGroup
|
||||||
defaultValue={config.default || ''}
|
defaultValue={config.default ?? ''}
|
||||||
fieldId={name}
|
fieldId={name}
|
||||||
helperTextInvalid={meta.error}
|
helperTextInvalid={meta.error}
|
||||||
isRequired={isRequired}
|
isRequired={isRequired}
|
||||||
|
|||||||
@@ -133,6 +133,35 @@ describe('Setting form fields', () => {
|
|||||||
expect(wrapper.find('TextInputBase').prop('value')).toEqual('foo');
|
expect(wrapper.find('TextInputBase').prop('value')).toEqual('foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('InputField should revert to expected default value', async () => {
|
||||||
|
const wrapper = mountWithContexts(
|
||||||
|
<Formik
|
||||||
|
initialValues={{
|
||||||
|
number: 5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{() => (
|
||||||
|
<InputField
|
||||||
|
name="number"
|
||||||
|
type="number"
|
||||||
|
config={{
|
||||||
|
label: 'test number input',
|
||||||
|
min_value: -10,
|
||||||
|
default: 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
);
|
||||||
|
expect(wrapper.find('TextInputBase')).toHaveLength(1);
|
||||||
|
expect(wrapper.find('TextInputBase').prop('value')).toEqual(5);
|
||||||
|
await act(async () => {
|
||||||
|
wrapper.find('button[aria-label="Revert"]').invoke('onClick')();
|
||||||
|
});
|
||||||
|
wrapper.update();
|
||||||
|
expect(wrapper.find('TextInputBase').prop('value')).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
test('TextAreaField renders the expected content', async () => {
|
test('TextAreaField renders the expected content', async () => {
|
||||||
const wrapper = mountWithContexts(
|
const wrapper = mountWithContexts(
|
||||||
<Formik
|
<Formik
|
||||||
|
|||||||
Reference in New Issue
Block a user