mirror of
https://github.com/ansible/awx.git
synced 2024-10-27 00:55:06 +03:00
Merge pull request #7341 from AlexSCorey/7235-ApplicationsAddEdit
7235 applications add Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
commit
c5addd7c67
@ -1,15 +1,94 @@
|
||||
import React from 'react';
|
||||
import { Card, PageSection } from '@patternfly/react-core';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
function ApplicatonAdd() {
|
||||
import { Card, PageSection } from '@patternfly/react-core';
|
||||
import useRequest from '../../../util/useRequest';
|
||||
import ContentError from '../../../components/ContentError';
|
||||
import ApplicationForm from '../shared/ApplicationForm';
|
||||
import { ApplicationsAPI } from '../../../api';
|
||||
import { CardBody } from '../../../components/Card';
|
||||
|
||||
function ApplicationAdd() {
|
||||
const history = useHistory();
|
||||
const [submitError, setSubmitError] = useState(null);
|
||||
|
||||
const {
|
||||
error,
|
||||
request: fetchOptions,
|
||||
result: { authorizationOptions, clientTypeOptions },
|
||||
} = useRequest(
|
||||
useCallback(async () => {
|
||||
const {
|
||||
data: {
|
||||
actions: {
|
||||
GET: {
|
||||
authorization_grant_type: { choices: authChoices },
|
||||
client_type: { choices: clientChoices },
|
||||
},
|
||||
},
|
||||
},
|
||||
} = await ApplicationsAPI.readOptions();
|
||||
|
||||
const authorization = authChoices.map(choice => ({
|
||||
value: choice[0],
|
||||
label: choice[1],
|
||||
key: choice[0],
|
||||
}));
|
||||
const clientType = clientChoices.map(choice => ({
|
||||
value: choice[0],
|
||||
label: choice[1],
|
||||
key: choice[0],
|
||||
}));
|
||||
|
||||
return {
|
||||
authorizationOptions: authorization,
|
||||
clientTypeOptions: clientType,
|
||||
};
|
||||
}, []),
|
||||
{
|
||||
authorizationOptions: [],
|
||||
clientTypeOptions: [],
|
||||
}
|
||||
);
|
||||
const handleSubmit = async ({ ...values }) => {
|
||||
values.organization = values.organization.id;
|
||||
try {
|
||||
const {
|
||||
data: { id },
|
||||
} = await ApplicationsAPI.create(values);
|
||||
history.push(`/applications/${id}/details`);
|
||||
} catch (err) {
|
||||
setSubmitError(err);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
history.push(`/applications`);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchOptions();
|
||||
}, [fetchOptions]);
|
||||
|
||||
if (error) {
|
||||
return <ContentError error={error} />;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<PageSection>
|
||||
<Card>
|
||||
<div>Applications Add</div>
|
||||
<CardBody>
|
||||
<ApplicationForm
|
||||
onSubmit={handleSubmit}
|
||||
onCancel={handleCancel}
|
||||
authorizationOptions={authorizationOptions}
|
||||
clientTypeOptions={clientTypeOptions}
|
||||
submitError={submitError}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</PageSection>
|
||||
</>
|
||||
);
|
||||
}
|
||||
export default ApplicatonAdd;
|
||||
export default ApplicationAdd;
|
||||
|
@ -0,0 +1,190 @@
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import {
|
||||
mountWithContexts,
|
||||
waitForElement,
|
||||
} from '../../../../testUtils/enzymeHelpers';
|
||||
|
||||
import { ApplicationsAPI } from '../../../api';
|
||||
import ApplicationAdd from './ApplicationAdd';
|
||||
|
||||
jest.mock('../../../api/models/Applications');
|
||||
jest.mock('../../../api/models/Organizations');
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
history: () => ({
|
||||
location: '/applications/add',
|
||||
}),
|
||||
}));
|
||||
const options = {
|
||||
data: {
|
||||
actions: {
|
||||
GET: {
|
||||
client_type: {
|
||||
choices: [
|
||||
['confidential', 'Confidential'],
|
||||
['public', 'Public'],
|
||||
],
|
||||
},
|
||||
authorization_grant_type: {
|
||||
choices: [
|
||||
['authorization-code', 'Authorization code'],
|
||||
['password', 'Resource owner password-based'],
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
describe('<ApplicationAdd/>', () => {
|
||||
let wrapper;
|
||||
test('should render properly', async () => {
|
||||
ApplicationsAPI.readOptions.mockResolvedValue(options);
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(<ApplicationAdd />);
|
||||
});
|
||||
expect(wrapper.find('ApplicationAdd').length).toBe(1);
|
||||
expect(wrapper.find('ApplicationForm').length).toBe(1);
|
||||
expect(ApplicationsAPI.readOptions).toBeCalled();
|
||||
});
|
||||
|
||||
test('expect values to be updated and submitted properly', async () => {
|
||||
const history = createMemoryHistory({
|
||||
initialEntries: ['/applications/add'],
|
||||
});
|
||||
ApplicationsAPI.readOptions.mockResolvedValue(options);
|
||||
|
||||
ApplicationsAPI.create.mockResolvedValue({ data: { id: 8 } });
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(<ApplicationAdd />, {
|
||||
context: { router: { history } },
|
||||
});
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
wrapper.find('input#name').simulate('change', {
|
||||
target: { value: 'new foo', name: 'name' },
|
||||
});
|
||||
wrapper.find('input#description').simulate('change', {
|
||||
target: { value: 'new bar', name: 'description' },
|
||||
});
|
||||
wrapper
|
||||
.find('AnsibleSelect[name="authorization_grant_type"]')
|
||||
.prop('onChange')({}, 'authorization code');
|
||||
|
||||
wrapper.find('input#redirect_uris').simulate('change', {
|
||||
target: { value: 'https://www.google.com', name: 'redirect_uris' },
|
||||
});
|
||||
wrapper.find('AnsibleSelect[name="client_type"]').prop('onChange')(
|
||||
{},
|
||||
'confidential'
|
||||
);
|
||||
wrapper.find('OrganizationLookup').invoke('onChange')({
|
||||
id: 1,
|
||||
name: 'organization',
|
||||
});
|
||||
});
|
||||
|
||||
wrapper.update();
|
||||
expect(wrapper.find('input#name').prop('value')).toBe('new foo');
|
||||
expect(wrapper.find('input#description').prop('value')).toBe('new bar');
|
||||
expect(wrapper.find('InnerChipGroup').length).toBe(1);
|
||||
expect(wrapper.find('InnerChipGroup').text()).toBe('organization');
|
||||
expect(
|
||||
wrapper
|
||||
.find('AnsibleSelect[name="authorization_grant_type"]')
|
||||
.prop('value')
|
||||
).toBe('authorization code');
|
||||
expect(
|
||||
wrapper.find('AnsibleSelect[name="client_type"]').prop('value')
|
||||
).toBe('confidential');
|
||||
expect(wrapper.find('input#redirect_uris').prop('value')).toBe(
|
||||
'https://www.google.com'
|
||||
);
|
||||
await act(async () => {
|
||||
wrapper.find('Formik').prop('onSubmit')({
|
||||
authorization_grant_type: 'authorization-code',
|
||||
client_type: 'confidential',
|
||||
description: 'bar',
|
||||
name: 'foo',
|
||||
organization: { id: 1 },
|
||||
redirect_uris: 'http://www.google.com',
|
||||
});
|
||||
});
|
||||
|
||||
expect(ApplicationsAPI.create).toBeCalledWith({
|
||||
authorization_grant_type: 'authorization-code',
|
||||
client_type: 'confidential',
|
||||
description: 'bar',
|
||||
name: 'foo',
|
||||
organization: 1,
|
||||
redirect_uris: 'http://www.google.com',
|
||||
});
|
||||
expect(history.location.pathname).toBe('/applications/8/details');
|
||||
});
|
||||
|
||||
test('should cancel form properly', async () => {
|
||||
const history = createMemoryHistory({
|
||||
initialEntries: ['/applications/add'],
|
||||
});
|
||||
ApplicationsAPI.readOptions.mockResolvedValue(options);
|
||||
|
||||
ApplicationsAPI.create.mockResolvedValue({ data: { id: 8 } });
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(<ApplicationAdd />, {
|
||||
context: { router: { history } },
|
||||
});
|
||||
});
|
||||
await act(async () => {
|
||||
wrapper.find('Button[aria-label="Cancel"]').prop('onClick')();
|
||||
});
|
||||
expect(history.location.pathname).toBe('/applications');
|
||||
});
|
||||
|
||||
test('should throw error on submit', async () => {
|
||||
const error = {
|
||||
response: {
|
||||
config: {
|
||||
method: 'patch',
|
||||
url: '/api/v2/applications/',
|
||||
},
|
||||
data: { detail: 'An error occurred' },
|
||||
},
|
||||
};
|
||||
ApplicationsAPI.create.mockRejectedValue(error);
|
||||
ApplicationsAPI.readOptions.mockResolvedValue(options);
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(<ApplicationAdd />);
|
||||
});
|
||||
await act(async () => {
|
||||
wrapper.find('Formik').prop('onSubmit')({
|
||||
id: 1,
|
||||
organization: { id: 1 },
|
||||
});
|
||||
});
|
||||
|
||||
waitForElement(wrapper, 'FormSubmitError', el => el.length > 0);
|
||||
});
|
||||
test('should render content error on failed read options request', async () => {
|
||||
ApplicationsAPI.readOptions.mockRejectedValue(
|
||||
new Error({
|
||||
response: {
|
||||
config: {
|
||||
method: 'options',
|
||||
},
|
||||
data: 'An error occurred',
|
||||
status: 403,
|
||||
},
|
||||
})
|
||||
);
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(<ApplicationAdd />);
|
||||
});
|
||||
|
||||
wrapper.update();
|
||||
expect(wrapper.find('ContentError').length).toBe(1);
|
||||
});
|
||||
});
|
177
awx/ui_next/src/screens/Application/shared/ApplicationForm.jsx
Normal file
177
awx/ui_next/src/screens/Application/shared/ApplicationForm.jsx
Normal file
@ -0,0 +1,177 @@
|
||||
import React from 'react';
|
||||
import { useRouteMatch } from 'react-router-dom';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import { Formik, useField } from 'formik';
|
||||
import { Form, FormGroup } from '@patternfly/react-core';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { required } from '../../../util/validators';
|
||||
import FormField, {
|
||||
FormSubmitError,
|
||||
FieldTooltip,
|
||||
} from '../../../components/FormField';
|
||||
import { FormColumnLayout } from '../../../components/FormLayout';
|
||||
import FormActionGroup from '../../../components/FormActionGroup/FormActionGroup';
|
||||
import OrganizationLookup from '../../../components/Lookup/OrganizationLookup';
|
||||
import AnsibleSelect from '../../../components/AnsibleSelect';
|
||||
|
||||
function ApplicationFormFields({
|
||||
i18n,
|
||||
authorizationOptions,
|
||||
clientTypeOptions,
|
||||
}) {
|
||||
const match = useRouteMatch();
|
||||
const [organizationField, organizationMeta, organizationHelpers] = useField({
|
||||
name: 'organization',
|
||||
validate: required(null, i18n),
|
||||
});
|
||||
const [
|
||||
authorizationTypeField,
|
||||
authorizationTypeMeta,
|
||||
authorizationTypeHelpers,
|
||||
] = useField({
|
||||
name: 'authorization_grant_type',
|
||||
validate: required(null, i18n),
|
||||
});
|
||||
|
||||
const [clientTypeField, clientTypeMeta, clientTypeHelpers] = useField({
|
||||
name: 'client_type',
|
||||
validate: required(null, i18n),
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<FormField
|
||||
id="name"
|
||||
label={i18n._(t`Name`)}
|
||||
name="name"
|
||||
type="text"
|
||||
validate={required(null, i18n)}
|
||||
isRequired
|
||||
/>
|
||||
<FormField
|
||||
id="description"
|
||||
label={i18n._(t`Description`)}
|
||||
name="description"
|
||||
type="text"
|
||||
/>
|
||||
<OrganizationLookup
|
||||
helperTextInvalid={organizationMeta.error}
|
||||
isValid={!organizationMeta.touched || !organizationMeta.error}
|
||||
onBlur={() => organizationHelpers.setTouched()}
|
||||
onChange={value => {
|
||||
organizationHelpers.setValue(value);
|
||||
}}
|
||||
value={organizationField.value}
|
||||
required
|
||||
/>
|
||||
<FormGroup
|
||||
fieldId="authType"
|
||||
helperTextInvalid={authorizationTypeMeta.error}
|
||||
isRequired
|
||||
isValid={!authorizationTypeMeta.touched || !authorizationTypeMeta.error}
|
||||
label={i18n._(t`Authorization grant type`)}
|
||||
>
|
||||
<FieldTooltip
|
||||
content={i18n._(
|
||||
t`The Grant type the user must use for acquire tokens for this application`
|
||||
)}
|
||||
/>
|
||||
<AnsibleSelect
|
||||
{...authorizationTypeField}
|
||||
isDisabled={match.url.endsWith('edit')}
|
||||
id="authType"
|
||||
data={[{ label: '', key: 1, value: '' }, ...authorizationOptions]}
|
||||
onChange={(event, value) => {
|
||||
authorizationTypeHelpers.setValue(value);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormField
|
||||
id="redirect_uris"
|
||||
label={i18n._(t`Redirect URIs`)}
|
||||
name="redirect_uris"
|
||||
type="text"
|
||||
isRequired={Boolean(
|
||||
authorizationTypeField.value === 'authorization-code'
|
||||
)}
|
||||
validate={
|
||||
authorizationTypeField.value === 'authorization-code'
|
||||
? required(null, i18n)
|
||||
: null
|
||||
}
|
||||
tooltip={i18n._(t`Allowed URIs list, space separated`)}
|
||||
/>
|
||||
<FormGroup
|
||||
fieldId="clientType"
|
||||
helperTextInvalid={clientTypeMeta.error}
|
||||
isRequired
|
||||
isValid={!clientTypeMeta.touched || !clientTypeMeta.error}
|
||||
label={i18n._(t`Client type`)}
|
||||
>
|
||||
<FieldTooltip
|
||||
content={i18n._(
|
||||
t`Set to Public or Confidential depending on how secure the client device is.`
|
||||
)}
|
||||
/>
|
||||
<AnsibleSelect
|
||||
{...clientTypeField}
|
||||
id="clientType"
|
||||
data={[{ label: '', key: 1, value: '' }, ...clientTypeOptions]}
|
||||
onChange={(event, value) => {
|
||||
clientTypeHelpers.setValue(value);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
</>
|
||||
);
|
||||
}
|
||||
function ApplicationForm({
|
||||
onCancel,
|
||||
onSubmit,
|
||||
i18n,
|
||||
submitError,
|
||||
application,
|
||||
authorizationOptions,
|
||||
clientTypeOptions,
|
||||
}) {
|
||||
const initialValues = {
|
||||
name: application?.name || '',
|
||||
description: application?.description || '',
|
||||
organization: application?.summary_fields?.organization || null,
|
||||
authorization_grant_type: application?.authorization_grant_type || '',
|
||||
redirect_uris: application?.redirect_uris || '',
|
||||
client_type: application?.client_type || '',
|
||||
};
|
||||
|
||||
return (
|
||||
<Formik initialValues={initialValues} onSubmit={values => onSubmit(values)}>
|
||||
{formik => (
|
||||
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||
<FormColumnLayout>
|
||||
<ApplicationFormFields
|
||||
formik={formik}
|
||||
authorizationOptions={authorizationOptions}
|
||||
clientTypeOptions={clientTypeOptions}
|
||||
i18n={i18n}
|
||||
/>
|
||||
{submitError && <FormSubmitError error={submitError} />}
|
||||
<FormActionGroup
|
||||
onCancel={onCancel}
|
||||
onSubmit={formik.handleSubmit}
|
||||
/>
|
||||
</FormColumnLayout>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
);
|
||||
}
|
||||
|
||||
ApplicationForm.propTypes = {
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
onCancel: PropTypes.func.isRequired,
|
||||
authorizationOptions: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
clientTypeOptions: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
};
|
||||
|
||||
export default withI18n()(ApplicationForm);
|
@ -0,0 +1,181 @@
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
|
||||
import { OrganizationsAPI } from '../../../api';
|
||||
import ApplicationForm from './ApplicationForm';
|
||||
|
||||
jest.mock('../../../api');
|
||||
|
||||
const authorizationOptions = [
|
||||
{
|
||||
key: 'authorization-code',
|
||||
label: 'Authorization code',
|
||||
value: 'authorization-code',
|
||||
},
|
||||
{
|
||||
key: 'password',
|
||||
label: 'Resource owner password-based',
|
||||
value: 'password',
|
||||
},
|
||||
];
|
||||
|
||||
const clientTypeOptions = [
|
||||
{ key: 'confidential', label: 'Confidential', value: 'confidential' },
|
||||
{ key: 'public', label: 'Public', value: 'public' },
|
||||
];
|
||||
|
||||
describe('<ApplicationForm', () => {
|
||||
let wrapper;
|
||||
test('should mount properly', async () => {
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<ApplicationForm
|
||||
onSubmit={() => {}}
|
||||
application={{}}
|
||||
onCancel={() => {}}
|
||||
authorizationOptions={authorizationOptions}
|
||||
clientTypeOptions={clientTypeOptions}
|
||||
/>
|
||||
);
|
||||
});
|
||||
expect(wrapper.find('ApplicationForm').length).toBe(1);
|
||||
});
|
||||
|
||||
test('all fields should render successsfully', async () => {
|
||||
OrganizationsAPI.read.mockResolvedValue({
|
||||
results: [{ id: 1 }, { id: 2 }],
|
||||
});
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<ApplicationForm
|
||||
onSubmit={() => {}}
|
||||
application={{}}
|
||||
onCancel={() => {}}
|
||||
authorizationOptions={authorizationOptions}
|
||||
clientTypeOptions={clientTypeOptions}
|
||||
/>
|
||||
);
|
||||
});
|
||||
expect(wrapper.find('input#name').length).toBe(1);
|
||||
expect(wrapper.find('input#description').length).toBe(1);
|
||||
expect(
|
||||
wrapper.find('AnsibleSelect[name="authorization_grant_type"]').length
|
||||
).toBe(1);
|
||||
expect(wrapper.find('input#redirect_uris').length).toBe(1);
|
||||
expect(wrapper.find('AnsibleSelect[name="client_type"]').length).toBe(1);
|
||||
expect(wrapper.find('OrganizationLookup').length).toBe(1);
|
||||
});
|
||||
|
||||
test('should update field values', async () => {
|
||||
OrganizationsAPI.read.mockResolvedValue({
|
||||
results: [{ id: 1 }, { id: 2 }],
|
||||
});
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<ApplicationForm
|
||||
onSubmit={() => {}}
|
||||
application={{}}
|
||||
onCancel={() => {}}
|
||||
authorizationOptions={authorizationOptions}
|
||||
clientTypeOptions={clientTypeOptions}
|
||||
/>
|
||||
);
|
||||
await act(async () => {
|
||||
wrapper.find('input#name').simulate('change', {
|
||||
target: { value: 'new foo', name: 'name' },
|
||||
});
|
||||
wrapper.find('input#description').simulate('change', {
|
||||
target: { value: 'new bar', name: 'description' },
|
||||
});
|
||||
wrapper
|
||||
.find('AnsibleSelect[name="authorization_grant_type"]')
|
||||
.prop('onChange')({}, 'authorization-code');
|
||||
|
||||
wrapper.find('input#redirect_uris').simulate('change', {
|
||||
target: { value: 'https://www.google.com', name: 'redirect_uris' },
|
||||
});
|
||||
wrapper.find('AnsibleSelect[name="client_type"]').prop('onChange')(
|
||||
{},
|
||||
'confidential'
|
||||
);
|
||||
wrapper.find('OrganizationLookup').invoke('onChange')({
|
||||
id: 3,
|
||||
name: 'organization',
|
||||
});
|
||||
});
|
||||
});
|
||||
wrapper.update();
|
||||
expect(wrapper.find('input#name').prop('value')).toBe('new foo');
|
||||
expect(wrapper.find('input#description').prop('value')).toBe('new bar');
|
||||
expect(wrapper.find('InnerChipGroup').length).toBe(1);
|
||||
expect(wrapper.find('InnerChipGroup').text()).toBe('organization');
|
||||
expect(
|
||||
wrapper
|
||||
.find('AnsibleSelect[name="authorization_grant_type"]')
|
||||
.prop('value')
|
||||
).toBe('authorization-code');
|
||||
expect(
|
||||
wrapper.find('AnsibleSelect[name="client_type"]').prop('value')
|
||||
).toBe('confidential');
|
||||
expect(
|
||||
wrapper.find('FormField[label="Redirect URIs"]').prop('isRequired')
|
||||
).toBe(true);
|
||||
expect(wrapper.find('input#redirect_uris').prop('value')).toBe(
|
||||
'https://www.google.com'
|
||||
);
|
||||
});
|
||||
test('should call onCancel', async () => {
|
||||
OrganizationsAPI.read.mockResolvedValue({
|
||||
results: [{ id: 1 }, { id: 2 }],
|
||||
});
|
||||
const onSubmit = jest.fn();
|
||||
const onCancel = jest.fn();
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<ApplicationForm
|
||||
onSubmit={onSubmit}
|
||||
application={{}}
|
||||
onCancel={onCancel}
|
||||
authorizationOptions={authorizationOptions}
|
||||
clientTypeOptions={clientTypeOptions}
|
||||
/>
|
||||
);
|
||||
});
|
||||
wrapper.find('Button[aria-label="Cancel"]').prop('onClick')();
|
||||
expect(onCancel).toBeCalled();
|
||||
});
|
||||
test('should call onSubmit', async () => {
|
||||
OrganizationsAPI.read.mockResolvedValue({
|
||||
results: [{ id: 1 }, { id: 2 }],
|
||||
});
|
||||
const onSubmit = jest.fn();
|
||||
const onCancel = jest.fn();
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<ApplicationForm
|
||||
onSubmit={onSubmit}
|
||||
application={{}}
|
||||
onCancel={onCancel}
|
||||
authorizationOptions={authorizationOptions}
|
||||
clientTypeOptions={clientTypeOptions}
|
||||
/>
|
||||
);
|
||||
});
|
||||
wrapper.find('Formik').prop('onSubmit')({
|
||||
authorization_grant_type: 'authorization-code',
|
||||
client_type: 'confidential',
|
||||
description: 'bar',
|
||||
name: 'foo',
|
||||
organization: 1,
|
||||
redirect_uris: 'http://www.google.com',
|
||||
});
|
||||
expect(onSubmit).toBeCalledWith({
|
||||
authorization_grant_type: 'authorization-code',
|
||||
client_type: 'confidential',
|
||||
description: 'bar',
|
||||
name: 'foo',
|
||||
organization: 1,
|
||||
redirect_uris: 'http://www.google.com',
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user