mirror of
https://github.com/ansible/awx.git
synced 2026-05-07 17:37:37 -02:30
Changes settings revert all to send DELETE on individual endpoint rather than PATCHing
This commit is contained in:
@@ -29,6 +29,10 @@ class Settings extends Base {
|
|||||||
createTest(category, data) {
|
createTest(category, data) {
|
||||||
return this.http.post(`${this.baseUrl}${category}/test/`, data);
|
return this.http.post(`${this.baseUrl}${category}/test/`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
revertCategory(category) {
|
||||||
|
return this.http.delete(`${this.baseUrl}${category}/`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Settings;
|
export default Settings;
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { act } from 'react-dom/test-utils';
|
|
||||||
import {
|
|
||||||
mountWithContexts,
|
|
||||||
waitForElement,
|
|
||||||
} from '../../../../../testUtils/enzymeHelpers';
|
|
||||||
import { SettingsProvider } from '../../../../contexts/Settings';
|
|
||||||
import { SettingsAPI } from '../../../../api';
|
|
||||||
import { assertDetail } from '../../shared/settingTestUtils';
|
|
||||||
import mockAllOptions from '../../shared/data.allSettingOptions.json';
|
|
||||||
import ActivityStreamDetail from './ActivityStreamDetail';
|
|
||||||
|
|
||||||
jest.mock('../../../../api');
|
|
||||||
|
|
||||||
describe('<ActivityStreamDetail />', () => {
|
|
||||||
let wrapper;
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
|
||||||
data: {
|
|
||||||
ACTIVITY_STREAM_ENABLED: true,
|
|
||||||
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await act(async () => {
|
|
||||||
wrapper = mountWithContexts(
|
|
||||||
<SettingsProvider value={mockAllOptions.actions}>
|
|
||||||
<ActivityStreamDetail />
|
|
||||||
</SettingsProvider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
wrapper.unmount();
|
|
||||||
jest.clearAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('initially renders without crashing', () => {
|
|
||||||
expect(wrapper.find('ActivityStreamDetail').length).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should render expected tabs', () => {
|
|
||||||
const expectedTabs = ['Back to Settings', 'Details'];
|
|
||||||
wrapper.find('RoutedTabs li').forEach((tab, index) => {
|
|
||||||
expect(tab.text()).toEqual(expectedTabs[index]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should render expected details', () => {
|
|
||||||
assertDetail(wrapper, 'Enable Activity Stream', 'On');
|
|
||||||
assertDetail(wrapper, 'Enable Activity Stream for Inventory Sync', 'Off');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should hide edit button from non-superusers', async () => {
|
|
||||||
const config = {
|
|
||||||
me: {
|
|
||||||
is_superuser: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
await act(async () => {
|
|
||||||
wrapper = mountWithContexts(
|
|
||||||
<SettingsProvider value={mockAllOptions.actions}>
|
|
||||||
<ActivityStreamDetail />
|
|
||||||
</SettingsProvider>,
|
|
||||||
{
|
|
||||||
context: { config },
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
|
||||||
expect(wrapper.find('Button[aria-label="Edit"]').exists()).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should display content error when api throws error on initial render', async () => {
|
|
||||||
SettingsAPI.readCategory.mockRejectedValue(new Error());
|
|
||||||
await act(async () => {
|
|
||||||
wrapper = mountWithContexts(
|
|
||||||
<SettingsProvider value={mockAllOptions.actions}>
|
|
||||||
<ActivityStreamDetail />
|
|
||||||
</SettingsProvider>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
|
||||||
expect(wrapper.find('ContentError').length).toBe(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { default } from './ActivityStreamDetail';
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
import React, { useCallback, useEffect } from 'react';
|
|
||||||
import { useHistory } from 'react-router-dom';
|
|
||||||
import { Formik } from 'formik';
|
|
||||||
import { Form } from '@patternfly/react-core';
|
|
||||||
import { CardBody } 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,
|
|
||||||
RevertAllAlert,
|
|
||||||
RevertFormActionGroup,
|
|
||||||
} from '../../shared';
|
|
||||||
import useModal from '../../../../util/useModal';
|
|
||||||
import useRequest from '../../../../util/useRequest';
|
|
||||||
import { SettingsAPI } from '../../../../api';
|
|
||||||
|
|
||||||
function ActivityStreamEdit() {
|
|
||||||
const history = useHistory();
|
|
||||||
const { isModalOpen, toggleModal, closeModal } = useModal();
|
|
||||||
const { PUT: options } = useSettings();
|
|
||||||
|
|
||||||
const {
|
|
||||||
isLoading,
|
|
||||||
error,
|
|
||||||
request,
|
|
||||||
result: {
|
|
||||||
ACTIVITY_STREAM_ENABLED,
|
|
||||||
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC,
|
|
||||||
},
|
|
||||||
} = useRequest(
|
|
||||||
useCallback(async () => {
|
|
||||||
const { data } = await SettingsAPI.readCategory('system');
|
|
||||||
return {
|
|
||||||
ACTIVITY_STREAM_ENABLED: {
|
|
||||||
...options.ACTIVITY_STREAM_ENABLED,
|
|
||||||
value: data.ACTIVITY_STREAM_ENABLED,
|
|
||||||
},
|
|
||||||
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC: {
|
|
||||||
...options.ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC,
|
|
||||||
value: data.ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}, [options]),
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
request();
|
|
||||||
}, [request]);
|
|
||||||
|
|
||||||
const { error: submitError, request: submitForm } = useRequest(
|
|
||||||
useCallback(
|
|
||||||
async values => {
|
|
||||||
await SettingsAPI.updateAll(values);
|
|
||||||
history.push('/settings/activity_stream/details');
|
|
||||||
},
|
|
||||||
[history]
|
|
||||||
),
|
|
||||||
null
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
|
||||||
await submitForm(form);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
history.push('/settings/activity_stream/details');
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
|
||||||
const defaultValues = {
|
|
||||||
ACTIVITY_STREAM_ENABLED: ACTIVITY_STREAM_ENABLED.default,
|
|
||||||
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC:
|
|
||||||
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC.default,
|
|
||||||
};
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CardBody>
|
|
||||||
{isLoading && <ContentLoading />}
|
|
||||||
{!isLoading && error && <ContentError error={error} />}
|
|
||||||
{!isLoading && ACTIVITY_STREAM_ENABLED && (
|
|
||||||
<Formik
|
|
||||||
initialValues={{
|
|
||||||
ACTIVITY_STREAM_ENABLED: ACTIVITY_STREAM_ENABLED.value,
|
|
||||||
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC:
|
|
||||||
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC.value,
|
|
||||||
}}
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
>
|
|
||||||
{formik => {
|
|
||||||
return (
|
|
||||||
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
|
||||||
<FormColumnLayout>
|
|
||||||
<BooleanField
|
|
||||||
name="ACTIVITY_STREAM_ENABLED"
|
|
||||||
config={ACTIVITY_STREAM_ENABLED}
|
|
||||||
/>
|
|
||||||
<BooleanField
|
|
||||||
name="ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC"
|
|
||||||
config={ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC}
|
|
||||||
/>
|
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
|
||||||
</FormColumnLayout>
|
|
||||||
<RevertFormActionGroup
|
|
||||||
onCancel={handleCancel}
|
|
||||||
onSubmit={formik.handleSubmit}
|
|
||||||
onRevert={toggleModal}
|
|
||||||
/>
|
|
||||||
{isModalOpen && (
|
|
||||||
<RevertAllAlert
|
|
||||||
onClose={closeModal}
|
|
||||||
onRevertAll={handleRevertAll}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Form>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Formik>
|
|
||||||
)}
|
|
||||||
</CardBody>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ActivityStreamEdit;
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { default } from './ActivityStreamEdit';
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { default } from './ActivityStream';
|
|
||||||
@@ -55,6 +55,13 @@ function AzureADEdit() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await SettingsAPI.revertCategory('azuread-oauth2');
|
||||||
|
}, []),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
const handleSubmit = async form => {
|
||||||
await submitForm({
|
await submitForm({
|
||||||
...form,
|
...form,
|
||||||
@@ -68,13 +75,11 @@ function AzureADEdit() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const handleRevertAll = async () => {
|
||||||
const defaultValues = Object.assign(
|
await revertAll();
|
||||||
...Object.entries(azure).map(([key, value]) => ({
|
|
||||||
[key]: value.default,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/azure/details');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -120,6 +125,7 @@ function AzureADEdit() {
|
|||||||
config={azure.SOCIAL_AUTH_AZUREAD_OAUTH2_TEAM_MAP}
|
config={azure.SOCIAL_AUTH_AZUREAD_OAUTH2_TEAM_MAP}
|
||||||
/>
|
/>
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
</FormColumnLayout>
|
</FormColumnLayout>
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ describe('<AzureADEdit />', () => {
|
|||||||
let history;
|
let history;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
@@ -60,7 +61,7 @@ describe('<AzureADEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -75,13 +76,8 @@ describe('<AzureADEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('azuread-oauth2');
|
||||||
SOCIAL_AUTH_AZUREAD_OAUTH2_KEY: '',
|
|
||||||
SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET: '',
|
|
||||||
SOCIAL_AUTH_AZUREAD_OAUTH2_ORGANIZATION_MAP: null,
|
|
||||||
SOCIAL_AUTH_AZUREAD_OAUTH2_TEAM_MAP: null,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
@@ -55,6 +55,13 @@ function GitHubEdit() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await SettingsAPI.revertCategory('github');
|
||||||
|
}, []),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
const handleSubmit = async form => {
|
||||||
await submitForm({
|
await submitForm({
|
||||||
...form,
|
...form,
|
||||||
@@ -66,13 +73,11 @@ function GitHubEdit() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const handleRevertAll = async () => {
|
||||||
const defaultValues = Object.assign(
|
await revertAll();
|
||||||
...Object.entries(github).map(([key, value]) => ({
|
|
||||||
[key]: value.default,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/github/details');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -118,6 +123,7 @@ function GitHubEdit() {
|
|||||||
config={github.SOCIAL_AUTH_GITHUB_TEAM_MAP}
|
config={github.SOCIAL_AUTH_GITHUB_TEAM_MAP}
|
||||||
/>
|
/>
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
</FormColumnLayout>
|
</FormColumnLayout>
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ describe('<GitHubEdit />', () => {
|
|||||||
let history;
|
let history;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
@@ -72,7 +73,7 @@ describe('<GitHubEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -87,13 +88,8 @@ describe('<GitHubEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('github');
|
||||||
SOCIAL_AUTH_GITHUB_KEY: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_SECRET: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_ORGANIZATION_MAP: null,
|
|
||||||
SOCIAL_AUTH_GITHUB_TEAM_MAP: null,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
@@ -55,6 +55,13 @@ function GitHubEnterpriseEdit() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await SettingsAPI.revertCategory('github-enterprise');
|
||||||
|
}, []),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
const handleSubmit = async form => {
|
||||||
await submitForm({
|
await submitForm({
|
||||||
...form,
|
...form,
|
||||||
@@ -68,13 +75,11 @@ function GitHubEnterpriseEdit() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const handleRevertAll = async () => {
|
||||||
const defaultValues = Object.assign(
|
await revertAll();
|
||||||
...Object.entries(github).map(([key, value]) => ({
|
|
||||||
[key]: value.default,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/github/enterprise/details');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -128,6 +133,7 @@ function GitHubEnterpriseEdit() {
|
|||||||
config={github.SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_MAP}
|
config={github.SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_MAP}
|
||||||
/>
|
/>
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
</FormColumnLayout>
|
</FormColumnLayout>
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ describe('<GitHubEnterpriseEdit />', () => {
|
|||||||
let history;
|
let history;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
@@ -82,7 +83,7 @@ describe('<GitHubEnterpriseEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -97,15 +98,10 @@ describe('<GitHubEnterpriseEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith(
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_URL: '',
|
'github-enterprise'
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_API_URL: '',
|
);
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_KEY: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_SECRET: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_ORGANIZATION_MAP: null,
|
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_MAP: null,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
@@ -55,6 +55,13 @@ function GitHubEnterpriseOrgEdit() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await SettingsAPI.revertCategory('github-enterprise-org');
|
||||||
|
}, []),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
const handleSubmit = async form => {
|
||||||
await submitForm({
|
await submitForm({
|
||||||
...form,
|
...form,
|
||||||
@@ -68,13 +75,11 @@ function GitHubEnterpriseOrgEdit() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const handleRevertAll = async () => {
|
||||||
const defaultValues = Object.assign(
|
await revertAll();
|
||||||
...Object.entries(github).map(([key, value]) => ({
|
|
||||||
[key]: value.default,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/github/enterprise_organization/details');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -134,6 +139,7 @@ function GitHubEnterpriseOrgEdit() {
|
|||||||
config={github.SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_TEAM_MAP}
|
config={github.SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_TEAM_MAP}
|
||||||
/>
|
/>
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
</FormColumnLayout>
|
</FormColumnLayout>
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ describe('<GitHubEnterpriseOrgEdit />', () => {
|
|||||||
let history;
|
let history;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
@@ -94,7 +95,7 @@ describe('<GitHubEnterpriseOrgEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -109,16 +110,10 @@ describe('<GitHubEnterpriseOrgEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith(
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_URL: '',
|
'github-enterprise-org'
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_API_URL: '',
|
);
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_KEY: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_SECRET: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_NAME: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_ORGANIZATION_MAP: null,
|
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_TEAM_MAP: null,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
@@ -55,6 +55,13 @@ function GitHubEnterpriseTeamEdit() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await SettingsAPI.revertCategory('github-enterprise-team');
|
||||||
|
}, []),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
const handleSubmit = async form => {
|
||||||
await submitForm({
|
await submitForm({
|
||||||
...form,
|
...form,
|
||||||
@@ -68,13 +75,11 @@ function GitHubEnterpriseTeamEdit() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const handleRevertAll = async () => {
|
||||||
const defaultValues = Object.assign(
|
await revertAll();
|
||||||
...Object.entries(github).map(([key, value]) => ({
|
|
||||||
[key]: value.default,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/github/enterprise_team/details');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -134,6 +139,7 @@ function GitHubEnterpriseTeamEdit() {
|
|||||||
config={github.SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_TEAM_MAP}
|
config={github.SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_TEAM_MAP}
|
||||||
/>
|
/>
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
</FormColumnLayout>
|
</FormColumnLayout>
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ describe('<GitHubEnterpriseTeamEdit />', () => {
|
|||||||
let history;
|
let history;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
@@ -88,7 +89,7 @@ describe('<GitHubEnterpriseTeamEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -103,16 +104,10 @@ describe('<GitHubEnterpriseTeamEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith(
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_URL: '',
|
'github-enterprise-team'
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_API_URL: '',
|
);
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_KEY: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_SECRET: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_ID: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_ORGANIZATION_MAP: null,
|
|
||||||
SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_TEAM_MAP: null,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
@@ -55,6 +55,13 @@ function GitHubOrgEdit() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await SettingsAPI.revertCategory('github-org');
|
||||||
|
}, []),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
const handleSubmit = async form => {
|
||||||
await submitForm({
|
await submitForm({
|
||||||
...form,
|
...form,
|
||||||
@@ -68,13 +75,11 @@ function GitHubOrgEdit() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const handleRevertAll = async () => {
|
||||||
const defaultValues = Object.assign(
|
await revertAll();
|
||||||
...Object.entries(github).map(([key, value]) => ({
|
|
||||||
[key]: value.default,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/github/organization/details');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -124,6 +129,7 @@ function GitHubOrgEdit() {
|
|||||||
config={github.SOCIAL_AUTH_GITHUB_ORG_TEAM_MAP}
|
config={github.SOCIAL_AUTH_GITHUB_ORG_TEAM_MAP}
|
||||||
/>
|
/>
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
</FormColumnLayout>
|
</FormColumnLayout>
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ describe('<GitHubOrgEdit />', () => {
|
|||||||
let history;
|
let history;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
@@ -79,7 +80,7 @@ describe('<GitHubOrgEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -94,14 +95,8 @@ describe('<GitHubOrgEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('github-org');
|
||||||
SOCIAL_AUTH_GITHUB_ORG_KEY: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_ORG_SECRET: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_ORG_NAME: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_ORG_ORGANIZATION_MAP: null,
|
|
||||||
SOCIAL_AUTH_GITHUB_ORG_TEAM_MAP: null,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
@@ -55,6 +55,13 @@ function GitHubTeamEdit() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await SettingsAPI.revertCategory('github-team');
|
||||||
|
}, []),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
const handleSubmit = async form => {
|
||||||
await submitForm({
|
await submitForm({
|
||||||
...form,
|
...form,
|
||||||
@@ -68,13 +75,11 @@ function GitHubTeamEdit() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const handleRevertAll = async () => {
|
||||||
const defaultValues = Object.assign(
|
await revertAll();
|
||||||
...Object.entries(github).map(([key, value]) => ({
|
|
||||||
[key]: value.default,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/github/team/details');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -124,6 +129,7 @@ function GitHubTeamEdit() {
|
|||||||
config={github.SOCIAL_AUTH_GITHUB_TEAM_TEAM_MAP}
|
config={github.SOCIAL_AUTH_GITHUB_TEAM_TEAM_MAP}
|
||||||
/>
|
/>
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
</FormColumnLayout>
|
</FormColumnLayout>
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ describe('<GitHubTeamEdit />', () => {
|
|||||||
let history;
|
let history;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
@@ -74,7 +75,7 @@ describe('<GitHubTeamEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -89,14 +90,8 @@ describe('<GitHubTeamEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('github-team');
|
||||||
SOCIAL_AUTH_GITHUB_TEAM_KEY: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_TEAM_SECRET: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_TEAM_ID: '',
|
|
||||||
SOCIAL_AUTH_GITHUB_TEAM_ORGANIZATION_MAP: null,
|
|
||||||
SOCIAL_AUTH_GITHUB_TEAM_TEAM_MAP: null,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
@@ -60,6 +60,13 @@ function GoogleOAuth2Edit() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await SettingsAPI.revertCategory('google-oauth2');
|
||||||
|
}, []),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
const handleSubmit = async form => {
|
||||||
await submitForm({
|
await submitForm({
|
||||||
...form,
|
...form,
|
||||||
@@ -79,13 +86,11 @@ function GoogleOAuth2Edit() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const handleRevertAll = async () => {
|
||||||
const defaultValues = Object.assign(
|
await revertAll();
|
||||||
...Object.entries(googleOAuth2).map(([key, value]) => ({
|
|
||||||
[key]: value.default,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/google_oauth2/details');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -148,6 +153,7 @@ function GoogleOAuth2Edit() {
|
|||||||
config={googleOAuth2.SOCIAL_AUTH_GOOGLE_OAUTH2_TEAM_MAP}
|
config={googleOAuth2.SOCIAL_AUTH_GOOGLE_OAUTH2_TEAM_MAP}
|
||||||
/>
|
/>
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
</FormColumnLayout>
|
</FormColumnLayout>
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ describe('<GoogleOAuth2Edit />', () => {
|
|||||||
let history;
|
let history;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
@@ -82,7 +83,7 @@ describe('<GoogleOAuth2Edit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -97,15 +98,8 @@ describe('<GoogleOAuth2Edit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('google-oauth2');
|
||||||
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY: '',
|
|
||||||
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET: '',
|
|
||||||
SOCIAL_AUTH_GOOGLE_OAUTH2_WHITELISTED_DOMAINS: [],
|
|
||||||
SOCIAL_AUTH_GOOGLE_OAUTH2_AUTH_EXTRA_ARGUMENTS: {},
|
|
||||||
SOCIAL_AUTH_GOOGLE_OAUTH2_ORGANIZATION_MAP: null,
|
|
||||||
SOCIAL_AUTH_GOOGLE_OAUTH2_TEAM_MAP: null,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
@@ -63,6 +63,13 @@ function JobsEdit() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await SettingsAPI.revertCategory('jobs');
|
||||||
|
}, []),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
const handleSubmit = async form => {
|
||||||
await submitForm({
|
await submitForm({
|
||||||
...form,
|
...form,
|
||||||
@@ -76,12 +83,11 @@ function JobsEdit() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const handleRevertAll = async () => {
|
||||||
const defaultValues = {};
|
await revertAll();
|
||||||
Object.entries(jobs).forEach(([key, value]) => {
|
|
||||||
defaultValues[key] = value.default;
|
|
||||||
});
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/jobs/details');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -181,6 +187,7 @@ function JobsEdit() {
|
|||||||
/>
|
/>
|
||||||
<ObjectField name="AWX_TASK_ENV" config={jobs.AWX_TASK_ENV} />
|
<ObjectField name="AWX_TASK_ENV" config={jobs.AWX_TASK_ENV} />
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
</FormColumnLayout>
|
</FormColumnLayout>
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import {
|
|||||||
} from '../../../../../testUtils/enzymeHelpers';
|
} from '../../../../../testUtils/enzymeHelpers';
|
||||||
import mockAllOptions from '../../shared/data.allSettingOptions.json';
|
import mockAllOptions from '../../shared/data.allSettingOptions.json';
|
||||||
import mockJobSettings from '../../shared/data.jobSettings.json';
|
import mockJobSettings from '../../shared/data.jobSettings.json';
|
||||||
import mockDefaultJobSettings from './data.defaultJobSettings.json';
|
|
||||||
import { SettingsProvider } from '../../../../contexts/Settings';
|
import { SettingsProvider } from '../../../../contexts/Settings';
|
||||||
import { SettingsAPI } from '../../../../api';
|
import { SettingsAPI } from '../../../../api';
|
||||||
import JobsEdit from './JobsEdit';
|
import JobsEdit from './JobsEdit';
|
||||||
@@ -19,6 +18,7 @@ describe('<JobsEdit />', () => {
|
|||||||
let history;
|
let history;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: mockJobSettings,
|
data: mockJobSettings,
|
||||||
@@ -51,7 +51,7 @@ describe('<JobsEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -66,8 +66,8 @@ describe('<JobsEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith(mockDefaultJobSettings);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('jobs');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
@@ -75,14 +75,19 @@ function LoggingEdit() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
const defaultValues = {};
|
useCallback(async () => {
|
||||||
Object.entries(logging).forEach(([key, value]) => {
|
await SettingsAPI.revertCategory('logging');
|
||||||
defaultValues[key] = value.default;
|
}, []),
|
||||||
});
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleRevertAll = async () => {
|
||||||
|
await revertAll();
|
||||||
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/logging/details');
|
||||||
};
|
};
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -221,6 +226,7 @@ function LoggingEdit() {
|
|||||||
config={logging.LOG_AGGREGATOR_LOGGERS}
|
config={logging.LOG_AGGREGATOR_LOGGERS}
|
||||||
/>
|
/>
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
onSubmit={formik.handleSubmit}
|
onSubmit={formik.handleSubmit}
|
||||||
|
|||||||
@@ -35,29 +35,6 @@ const mockSettings = {
|
|||||||
LOG_AGGREGATOR_MAX_DISK_USAGE_PATH: '/var/lib/awx',
|
LOG_AGGREGATOR_MAX_DISK_USAGE_PATH: '/var/lib/awx',
|
||||||
LOG_AGGREGATOR_RSYSLOGD_DEBUG: false,
|
LOG_AGGREGATOR_RSYSLOGD_DEBUG: false,
|
||||||
};
|
};
|
||||||
const mockDefaultSettings = {
|
|
||||||
LOG_AGGREGATOR_HOST: null,
|
|
||||||
LOG_AGGREGATOR_PORT: null,
|
|
||||||
LOG_AGGREGATOR_TYPE: null,
|
|
||||||
LOG_AGGREGATOR_USERNAME: '',
|
|
||||||
LOG_AGGREGATOR_PASSWORD: '',
|
|
||||||
LOG_AGGREGATOR_LOGGERS: [
|
|
||||||
'awx',
|
|
||||||
'activity_stream',
|
|
||||||
'job_events',
|
|
||||||
'system_tracking',
|
|
||||||
],
|
|
||||||
LOG_AGGREGATOR_INDIVIDUAL_FACTS: false,
|
|
||||||
LOG_AGGREGATOR_ENABLED: false,
|
|
||||||
LOG_AGGREGATOR_TOWER_UUID: '',
|
|
||||||
LOG_AGGREGATOR_PROTOCOL: 'https',
|
|
||||||
LOG_AGGREGATOR_TCP_TIMEOUT: 5,
|
|
||||||
LOG_AGGREGATOR_VERIFY_CERT: true,
|
|
||||||
LOG_AGGREGATOR_LEVEL: 'INFO',
|
|
||||||
LOG_AGGREGATOR_MAX_DISK_USAGE_GB: 1,
|
|
||||||
LOG_AGGREGATOR_MAX_DISK_USAGE_PATH: '/var/lib/awx',
|
|
||||||
LOG_AGGREGATOR_RSYSLOGD_DEBUG: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('<LoggingEdit />', () => {
|
describe('<LoggingEdit />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
@@ -68,6 +45,7 @@ describe('<LoggingEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: mockSettings,
|
data: mockSettings,
|
||||||
@@ -227,7 +205,7 @@ describe('<LoggingEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -242,8 +220,8 @@ describe('<LoggingEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith(mockDefaultSettings);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('logging');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link, Redirect, Route, Switch } from 'react-router-dom';
|
import { Link, Redirect, Route, Switch } from 'react-router-dom';
|
||||||
|
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { PageSection, Card } from '@patternfly/react-core';
|
import { PageSection, Card } from '@patternfly/react-core';
|
||||||
import ContentError from '../../../components/ContentError';
|
import ContentError from '../../../components/ContentError';
|
||||||
import { useConfig } from '../../../contexts/Config';
|
import { useConfig } from '../../../contexts/Config';
|
||||||
import ActivityStreamDetail from './ActivityStreamDetail';
|
import MiscAuthenticationDetail from './MiscAuthenticationDetail';
|
||||||
import ActivityStreamEdit from './ActivityStreamEdit';
|
import MiscAuthenticationEdit from './MiscAuthenticationEdit';
|
||||||
|
|
||||||
function ActivityStream() {
|
function MiscAuthentication() {
|
||||||
const baseURL = '/settings/activity_stream';
|
const baseURL = '/settings/miscellaneous_authentication';
|
||||||
const { me } = useConfig();
|
const { me } = useConfig();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -18,11 +17,11 @@ function ActivityStream() {
|
|||||||
<Switch>
|
<Switch>
|
||||||
<Redirect from={baseURL} to={`${baseURL}/details`} exact />
|
<Redirect from={baseURL} to={`${baseURL}/details`} exact />
|
||||||
<Route path={`${baseURL}/details`}>
|
<Route path={`${baseURL}/details`}>
|
||||||
<ActivityStreamDetail />
|
<MiscAuthenticationDetail />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path={`${baseURL}/edit`}>
|
<Route path={`${baseURL}/edit`}>
|
||||||
{me?.is_superuser ? (
|
{me?.is_superuser ? (
|
||||||
<ActivityStreamEdit />
|
<MiscAuthenticationEdit />
|
||||||
) : (
|
) : (
|
||||||
<Redirect to={`${baseURL}/details`} />
|
<Redirect to={`${baseURL}/details`} />
|
||||||
)}
|
)}
|
||||||
@@ -30,7 +29,7 @@ function ActivityStream() {
|
|||||||
<Route key="not-found" path={`${baseURL}/*`}>
|
<Route key="not-found" path={`${baseURL}/*`}>
|
||||||
<ContentError isNotFound>
|
<ContentError isNotFound>
|
||||||
<Link to={`${baseURL}/details`}>
|
<Link to={`${baseURL}/details`}>
|
||||||
{t`View Activity Stream settings`}
|
{t`View Miscellaneous Authentication settings`}
|
||||||
</Link>
|
</Link>
|
||||||
</ContentError>
|
</ContentError>
|
||||||
</Route>
|
</Route>
|
||||||
@@ -40,4 +39,4 @@ function ActivityStream() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ActivityStream;
|
export default MiscAuthentication;
|
||||||
@@ -5,55 +5,57 @@ import {
|
|||||||
mountWithContexts,
|
mountWithContexts,
|
||||||
waitForElement,
|
waitForElement,
|
||||||
} from '../../../../testUtils/enzymeHelpers';
|
} from '../../../../testUtils/enzymeHelpers';
|
||||||
import ActivityStream from './ActivityStream';
|
|
||||||
import { SettingsAPI } from '../../../api';
|
import { SettingsAPI } from '../../../api';
|
||||||
|
import MiscAuthentication from './MiscAuthentication';
|
||||||
|
|
||||||
jest.mock('../../../api/models/Settings');
|
jest.mock('../../../api');
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
|
||||||
data: {
|
|
||||||
ACTIVITY_STREAM_ENABLED: true,
|
|
||||||
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('<ActivityStream />', () => {
|
describe('<MiscAuthentication />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
wrapper.unmount();
|
wrapper.unmount();
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should render activity stream details', async () => {
|
test('should render miscellaneous authentication details', async () => {
|
||||||
const history = createMemoryHistory({
|
const history = createMemoryHistory({
|
||||||
initialEntries: ['/settings/activity_stream/details'],
|
initialEntries: ['/settings/miscellaneous_authentication/details'],
|
||||||
});
|
});
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper = mountWithContexts(<ActivityStream />, {
|
wrapper = mountWithContexts(<MiscAuthentication />, {
|
||||||
context: { router: { history } },
|
context: { router: { history } },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
expect(wrapper.find('ActivityStreamDetail').length).toBe(1);
|
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||||
|
expect(wrapper.find('MiscAuthenticationDetail').length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should render activity stream edit', async () => {
|
test('should render miscellaneous authentication edit', async () => {
|
||||||
const history = createMemoryHistory({
|
const history = createMemoryHistory({
|
||||||
initialEntries: ['/settings/activity_stream/edit'],
|
initialEntries: ['/settings/miscellaneous_authentication/edit'],
|
||||||
});
|
});
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper = mountWithContexts(<ActivityStream />, {
|
wrapper = mountWithContexts(<MiscAuthentication />, {
|
||||||
context: { router: { history } },
|
context: { router: { history } },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
expect(wrapper.find('ActivityStreamEdit').length).toBe(1);
|
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||||
|
expect(wrapper.find('MiscAuthenticationEdit').length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should show content error when user navigates to erroneous route', async () => {
|
test('should show content error when user navigates to erroneous route', async () => {
|
||||||
const history = createMemoryHistory({
|
const history = createMemoryHistory({
|
||||||
initialEntries: ['/settings/activity_stream/foo'],
|
initialEntries: ['/settings/miscellaneous_authentication/foo'],
|
||||||
});
|
});
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper = mountWithContexts(<ActivityStream />, {
|
wrapper = mountWithContexts(<MiscAuthentication />, {
|
||||||
context: { router: { history } },
|
context: { router: { history } },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -62,10 +64,10 @@ describe('<ActivityStream />', () => {
|
|||||||
|
|
||||||
test('should redirect to details for users without system admin permissions', async () => {
|
test('should redirect to details for users without system admin permissions', async () => {
|
||||||
const history = createMemoryHistory({
|
const history = createMemoryHistory({
|
||||||
initialEntries: ['/settings/activity_stream/edit'],
|
initialEntries: ['/settings/miscellaneous_authentication/edit'],
|
||||||
});
|
});
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper = mountWithContexts(<ActivityStream />, {
|
wrapper = mountWithContexts(<MiscAuthentication />, {
|
||||||
context: {
|
context: {
|
||||||
router: {
|
router: {
|
||||||
history,
|
history,
|
||||||
@@ -79,7 +81,7 @@ describe('<ActivityStream />', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||||
expect(wrapper.find('ActivityStreamDetail').length).toBe(1);
|
expect(wrapper.find('MiscAuthenticationDetail').length).toBe(1);
|
||||||
expect(wrapper.find('ActivityStreamEdit').length).toBe(0);
|
expect(wrapper.find('MiscAuthenticationEdit').length).toBe(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,36 +1,27 @@
|
|||||||
import React, { useEffect, useCallback } from 'react';
|
import React, { useEffect, useCallback } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { CaretLeftIcon } from '@patternfly/react-icons';
|
|
||||||
import { Button } from '@patternfly/react-core';
|
import { Button } from '@patternfly/react-core';
|
||||||
|
import { CaretLeftIcon } from '@patternfly/react-icons';
|
||||||
import { CardBody, CardActionsRow } from '../../../../components/Card';
|
import { CardBody, CardActionsRow } from '../../../../components/Card';
|
||||||
import ContentLoading from '../../../../components/ContentLoading';
|
import ContentLoading from '../../../../components/ContentLoading';
|
||||||
import ContentError from '../../../../components/ContentError';
|
import ContentError from '../../../../components/ContentError';
|
||||||
import { DetailList } from '../../../../components/DetailList';
|
import { DetailList } from '../../../../components/DetailList';
|
||||||
import RoutedTabs from '../../../../components/RoutedTabs';
|
import RoutedTabs from '../../../../components/RoutedTabs';
|
||||||
import useRequest from '../../../../util/useRequest';
|
|
||||||
import { useConfig } from '../../../../contexts/Config';
|
import { useConfig } from '../../../../contexts/Config';
|
||||||
import { useSettings } from '../../../../contexts/Settings';
|
import { useSettings } from '../../../../contexts/Settings';
|
||||||
|
import useRequest from '../../../../util/useRequest';
|
||||||
import { SettingsAPI } from '../../../../api';
|
import { SettingsAPI } from '../../../../api';
|
||||||
import { SettingDetail } from '../../shared';
|
import { SettingDetail } from '../../shared';
|
||||||
|
|
||||||
function ActivityStreamDetail() {
|
function MiscAuthenticationDetail() {
|
||||||
const { me } = useConfig();
|
const { me } = useConfig();
|
||||||
const { GET: options } = useSettings();
|
const { GET: options } = useSettings();
|
||||||
|
|
||||||
const { isLoading, error, request, result: activityStream } = useRequest(
|
const { isLoading, error, request, result: authentication } = useRequest(
|
||||||
useCallback(async () => {
|
useCallback(async () => {
|
||||||
const {
|
const { data } = await SettingsAPI.readCategory('authentication');
|
||||||
data: {
|
return data;
|
||||||
ACTIVITY_STREAM_ENABLED,
|
|
||||||
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC,
|
|
||||||
},
|
|
||||||
} = await SettingsAPI.readCategory('system');
|
|
||||||
return {
|
|
||||||
ACTIVITY_STREAM_ENABLED,
|
|
||||||
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC,
|
|
||||||
};
|
|
||||||
}, []),
|
}, []),
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
@@ -52,7 +43,7 @@ function ActivityStreamDetail() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: t`Details`,
|
name: t`Details`,
|
||||||
link: `/settings/activity_stream/details`,
|
link: `/settings/miscellaneous_authentication/details`,
|
||||||
id: 0,
|
id: 0,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -63,9 +54,9 @@ function ActivityStreamDetail() {
|
|||||||
<CardBody>
|
<CardBody>
|
||||||
{isLoading && <ContentLoading />}
|
{isLoading && <ContentLoading />}
|
||||||
{!isLoading && error && <ContentError error={error} />}
|
{!isLoading && error && <ContentError error={error} />}
|
||||||
{!isLoading && activityStream && (
|
{!isLoading && authentication && (
|
||||||
<DetailList>
|
<DetailList>
|
||||||
{Object.keys(activityStream).map(key => {
|
{Object.keys(authentication).map(key => {
|
||||||
const record = options?.[key];
|
const record = options?.[key];
|
||||||
return (
|
return (
|
||||||
<SettingDetail
|
<SettingDetail
|
||||||
@@ -75,7 +66,7 @@ function ActivityStreamDetail() {
|
|||||||
label={record?.label}
|
label={record?.label}
|
||||||
type={record?.type}
|
type={record?.type}
|
||||||
unit={record?.unit}
|
unit={record?.unit}
|
||||||
value={activityStream?.[key]}
|
value={authentication?.[key]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -84,10 +75,10 @@ function ActivityStreamDetail() {
|
|||||||
{me?.is_superuser && (
|
{me?.is_superuser && (
|
||||||
<CardActionsRow>
|
<CardActionsRow>
|
||||||
<Button
|
<Button
|
||||||
ouiaId="activity-stream-detail-edit-button"
|
ouiaId="authentication-detail-edit-button"
|
||||||
aria-label={t`Edit`}
|
aria-label={t`Edit`}
|
||||||
component={Link}
|
component={Link}
|
||||||
to="/settings/activity_stream/edit"
|
to="/settings/miscellaneous_authentication/edit"
|
||||||
>
|
>
|
||||||
{t`Edit`}
|
{t`Edit`}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -98,4 +89,4 @@ function ActivityStreamDetail() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ActivityStreamDetail;
|
export default MiscAuthenticationDetail;
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
|
import {
|
||||||
|
mountWithContexts,
|
||||||
|
waitForElement,
|
||||||
|
} from '../../../../../testUtils/enzymeHelpers';
|
||||||
|
import { SettingsProvider } from '../../../../contexts/Settings';
|
||||||
|
import { SettingsAPI } from '../../../../api';
|
||||||
|
import {
|
||||||
|
assertDetail,
|
||||||
|
assertVariableDetail,
|
||||||
|
} from '../../shared/settingTestUtils';
|
||||||
|
import mockAllOptions from '../../shared/data.allSettingOptions.json';
|
||||||
|
import MiscAuthenticationDetail from './MiscAuthenticationDetail';
|
||||||
|
|
||||||
|
jest.mock('../../../../api');
|
||||||
|
|
||||||
|
describe('<MiscAuthenticationDetail />', () => {
|
||||||
|
let wrapper;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
SettingsAPI.readCategory = jest.fn();
|
||||||
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
SESSION_COOKIE_AGE: 1800,
|
||||||
|
SESSIONS_PER_USER: -1,
|
||||||
|
DISABLE_LOCAL_AUTH: false,
|
||||||
|
AUTH_BASIC_ENABLED: true,
|
||||||
|
OAUTH2_PROVIDER: {
|
||||||
|
ACCESS_TOKEN_EXPIRE_SECONDS: 31536000000,
|
||||||
|
REFRESH_TOKEN_EXPIRE_SECONDS: 2628000,
|
||||||
|
AUTHORIZATION_CODE_EXPIRE_SECONDS: 600,
|
||||||
|
},
|
||||||
|
ALLOW_OAUTH2_FOR_EXTERNAL_USERS: false,
|
||||||
|
LOGIN_REDIRECT_OVERRIDE: 'https://foohost',
|
||||||
|
AUTHENTICATION_BACKENDS: [
|
||||||
|
'awx.sso.backends.TACACSPlusBackend',
|
||||||
|
'awx.main.backends.AWXModelBackend',
|
||||||
|
],
|
||||||
|
SOCIAL_AUTH_ORGANIZATION_MAP: {},
|
||||||
|
SOCIAL_AUTH_TEAM_MAP: {},
|
||||||
|
SOCIAL_AUTH_USER_FIELDS: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await act(async () => {
|
||||||
|
wrapper = mountWithContexts(
|
||||||
|
<SettingsProvider value={mockAllOptions.actions}>
|
||||||
|
<MiscAuthenticationDetail />
|
||||||
|
</SettingsProvider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('initially renders without crashing', () => {
|
||||||
|
expect(wrapper.find('MiscAuthenticationDetail').length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render expected tabs', () => {
|
||||||
|
const expectedTabs = ['Back to Settings', 'Details'];
|
||||||
|
wrapper.find('RoutedTabs li').forEach((tab, index) => {
|
||||||
|
expect(tab.text()).toEqual(expectedTabs[index]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render expected details', () => {
|
||||||
|
assertDetail(wrapper, 'Disable the built-in authentication system', 'Off');
|
||||||
|
assertVariableDetail(
|
||||||
|
wrapper,
|
||||||
|
'OAuth 2 Timeout Settings',
|
||||||
|
'{\n "ACCESS_TOKEN_EXPIRE_SECONDS": 31536000000,\n "REFRESH_TOKEN_EXPIRE_SECONDS": 2628000,\n "AUTHORIZATION_CODE_EXPIRE_SECONDS": 600\n}'
|
||||||
|
);
|
||||||
|
assertDetail(wrapper, 'Login redirect override URL', 'https://foohost');
|
||||||
|
assertVariableDetail(
|
||||||
|
wrapper,
|
||||||
|
'Authentication Backends',
|
||||||
|
'[\n "awx.sso.backends.TACACSPlusBackend",\n "awx.main.backends.AWXModelBackend"\n]'
|
||||||
|
);
|
||||||
|
assertVariableDetail(wrapper, 'Social Auth Organization Map', '{}');
|
||||||
|
assertVariableDetail(wrapper, 'Social Auth Team Map', '{}');
|
||||||
|
assertVariableDetail(wrapper, 'Social Auth User Fields', '[]');
|
||||||
|
assertDetail(
|
||||||
|
wrapper,
|
||||||
|
'Allow External Users to Create OAuth2 Tokens',
|
||||||
|
'Off'
|
||||||
|
);
|
||||||
|
assertDetail(wrapper, 'Enable HTTP Basic Auth', 'On');
|
||||||
|
assertDetail(wrapper, 'Idle Time Force Log Out', '1800 seconds');
|
||||||
|
assertDetail(
|
||||||
|
wrapper,
|
||||||
|
'Maximum number of simultaneous logged in sessions',
|
||||||
|
'-1'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should hide edit button from non-superusers', async () => {
|
||||||
|
const config = {
|
||||||
|
me: {
|
||||||
|
is_superuser: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
await act(async () => {
|
||||||
|
wrapper = mountWithContexts(
|
||||||
|
<SettingsProvider value={mockAllOptions.actions}>
|
||||||
|
<MiscAuthenticationDetail />
|
||||||
|
</SettingsProvider>,
|
||||||
|
{
|
||||||
|
context: { config },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||||
|
expect(wrapper.find('Button[aria-label="Edit"]').exists()).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should display content error when api throws error on initial render', async () => {
|
||||||
|
SettingsAPI.readCategory.mockRejectedValue(new Error());
|
||||||
|
await act(async () => {
|
||||||
|
wrapper = mountWithContexts(
|
||||||
|
<SettingsProvider value={mockAllOptions.actions}>
|
||||||
|
<MiscAuthenticationDetail />
|
||||||
|
</SettingsProvider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||||
|
expect(wrapper.find('ContentError').length).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { default } from './MiscAuthenticationDetail';
|
||||||
@@ -0,0 +1,270 @@
|
|||||||
|
import React, { useCallback, useEffect } from 'react';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
import { t } from '@lingui/macro';
|
||||||
|
import { Formik } from 'formik';
|
||||||
|
import { Form } from '@patternfly/react-core';
|
||||||
|
import { CardBody } 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 { RevertAllAlert, RevertFormActionGroup } from '../../shared';
|
||||||
|
import {
|
||||||
|
BooleanField,
|
||||||
|
InputField,
|
||||||
|
ObjectField,
|
||||||
|
} from '../../shared/SharedFields';
|
||||||
|
import useModal from '../../../../util/useModal';
|
||||||
|
import useRequest from '../../../../util/useRequest';
|
||||||
|
import { SettingsAPI } from '../../../../api';
|
||||||
|
import { formatJson, pluck } from '../../shared/settingUtils';
|
||||||
|
|
||||||
|
function MiscAuthenticationEdit() {
|
||||||
|
const history = useHistory();
|
||||||
|
const { isModalOpen, toggleModal, closeModal } = useModal();
|
||||||
|
const { PUT: options } = useSettings();
|
||||||
|
|
||||||
|
const {
|
||||||
|
isLoading,
|
||||||
|
error,
|
||||||
|
request: fetchAuthentication,
|
||||||
|
result: authentication,
|
||||||
|
} = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
const { data } = await SettingsAPI.readCategory('authentication');
|
||||||
|
|
||||||
|
const {
|
||||||
|
OAUTH2_PROVIDER: {
|
||||||
|
ACCESS_TOKEN_EXPIRE_SECONDS,
|
||||||
|
REFRESH_TOKEN_EXPIRE_SECONDS,
|
||||||
|
AUTHORIZATION_CODE_EXPIRE_SECONDS,
|
||||||
|
},
|
||||||
|
...pluckedAuthenticationData
|
||||||
|
} = pluck(
|
||||||
|
data,
|
||||||
|
'ALLOW_OAUTH2_FOR_EXTERNAL_USERS',
|
||||||
|
'AUTH_BASIC_ENABLED',
|
||||||
|
'LOGIN_REDIRECT_OVERRIDE',
|
||||||
|
'DISABLE_LOCAL_AUTH',
|
||||||
|
'OAUTH2_PROVIDER',
|
||||||
|
'SESSIONS_PER_USER',
|
||||||
|
'SESSION_COOKIE_AGE',
|
||||||
|
'SOCIAL_AUTH_ORGANIZATION_MAP',
|
||||||
|
'SOCIAL_AUTH_TEAM_MAP',
|
||||||
|
'SOCIAL_AUTH_USER_FIELDS'
|
||||||
|
);
|
||||||
|
|
||||||
|
const authenticationData = {
|
||||||
|
ACCESS_TOKEN_EXPIRE_SECONDS,
|
||||||
|
REFRESH_TOKEN_EXPIRE_SECONDS,
|
||||||
|
AUTHORIZATION_CODE_EXPIRE_SECONDS,
|
||||||
|
...pluckedAuthenticationData,
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
OAUTH2_PROVIDER: OAUTH2_PROVIDER_OPTIONS,
|
||||||
|
...restOptions
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
const authenticationOptions = {
|
||||||
|
...restOptions,
|
||||||
|
ACCESS_TOKEN_EXPIRE_SECONDS: {
|
||||||
|
...OAUTH2_PROVIDER_OPTIONS,
|
||||||
|
default: OAUTH2_PROVIDER_OPTIONS.default.ACCESS_TOKEN_EXPIRE_SECONDS,
|
||||||
|
type: OAUTH2_PROVIDER_OPTIONS.child.type,
|
||||||
|
label: t`Access Token Expiration`,
|
||||||
|
},
|
||||||
|
REFRESH_TOKEN_EXPIRE_SECONDS: {
|
||||||
|
...OAUTH2_PROVIDER_OPTIONS,
|
||||||
|
default: OAUTH2_PROVIDER_OPTIONS.default.REFRESH_TOKEN_EXPIRE_SECONDS,
|
||||||
|
type: OAUTH2_PROVIDER_OPTIONS.child.type,
|
||||||
|
label: t`Refresh Token Expiration`,
|
||||||
|
},
|
||||||
|
AUTHORIZATION_CODE_EXPIRE_SECONDS: {
|
||||||
|
...OAUTH2_PROVIDER_OPTIONS,
|
||||||
|
default:
|
||||||
|
OAUTH2_PROVIDER_OPTIONS.default.AUTHORIZATION_CODE_EXPIRE_SECONDS,
|
||||||
|
type: OAUTH2_PROVIDER_OPTIONS.child.type,
|
||||||
|
label: t`Authorization Code Expiration`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const mergedData = {};
|
||||||
|
|
||||||
|
Object.keys(authenticationData).forEach(key => {
|
||||||
|
if (!authenticationOptions[key]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mergedData[key] = authenticationOptions[key];
|
||||||
|
mergedData[key].value = authenticationData[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
return mergedData;
|
||||||
|
}, [options]),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchAuthentication();
|
||||||
|
}, [fetchAuthentication]);
|
||||||
|
|
||||||
|
const { error: submitError, request: submitForm } = useRequest(
|
||||||
|
useCallback(
|
||||||
|
async values => {
|
||||||
|
await SettingsAPI.updateAll(values);
|
||||||
|
history.push('/settings/miscellaneous_authentication/details');
|
||||||
|
},
|
||||||
|
[history]
|
||||||
|
),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await SettingsAPI.revertCategory('authentication');
|
||||||
|
}, []),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSubmit = async form => {
|
||||||
|
const {
|
||||||
|
ACCESS_TOKEN_EXPIRE_SECONDS,
|
||||||
|
REFRESH_TOKEN_EXPIRE_SECONDS,
|
||||||
|
AUTHORIZATION_CODE_EXPIRE_SECONDS,
|
||||||
|
...formData
|
||||||
|
} = form;
|
||||||
|
|
||||||
|
await submitForm({
|
||||||
|
...formData,
|
||||||
|
OAUTH2_PROVIDER: {
|
||||||
|
ACCESS_TOKEN_EXPIRE_SECONDS,
|
||||||
|
REFRESH_TOKEN_EXPIRE_SECONDS,
|
||||||
|
AUTHORIZATION_CODE_EXPIRE_SECONDS,
|
||||||
|
},
|
||||||
|
SOCIAL_AUTH_ORGANIZATION_MAP: formatJson(
|
||||||
|
formData.SOCIAL_AUTH_ORGANIZATION_MAP
|
||||||
|
),
|
||||||
|
SOCIAL_AUTH_TEAM_MAP: formatJson(formData.SOCIAL_AUTH_TEAM_MAP),
|
||||||
|
SOCIAL_AUTH_USER_FIELDS: formatJson(formData.SOCIAL_AUTH_USER_FIELDS),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRevertAll = async () => {
|
||||||
|
await revertAll();
|
||||||
|
|
||||||
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/miscellaneous_authentication/details');
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
history.push('/settings/miscellaneous_authentication/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;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CardBody>
|
||||||
|
{isLoading && <ContentLoading />}
|
||||||
|
{!isLoading && error && <ContentError error={error} />}
|
||||||
|
{!isLoading && authentication && (
|
||||||
|
<Formik
|
||||||
|
initialValues={initialValues(authentication)}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
>
|
||||||
|
{formik => (
|
||||||
|
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||||
|
<FormColumnLayout>
|
||||||
|
<BooleanField
|
||||||
|
name="DISABLE_LOCAL_AUTH"
|
||||||
|
needsConfirmationModal
|
||||||
|
modalTitle={t`Confirm Disable Local Authorization`}
|
||||||
|
config={authentication.DISABLE_LOCAL_AUTH}
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="SESSION_COOKIE_AGE"
|
||||||
|
config={authentication.SESSION_COOKIE_AGE}
|
||||||
|
type="number"
|
||||||
|
isRequired
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="SESSIONS_PER_USER"
|
||||||
|
config={authentication.SESSIONS_PER_USER}
|
||||||
|
type="number"
|
||||||
|
isRequired
|
||||||
|
/>
|
||||||
|
<BooleanField
|
||||||
|
name="AUTH_BASIC_ENABLED"
|
||||||
|
config={authentication.AUTH_BASIC_ENABLED}
|
||||||
|
/>
|
||||||
|
<BooleanField
|
||||||
|
name="ALLOW_OAUTH2_FOR_EXTERNAL_USERS"
|
||||||
|
config={authentication.ALLOW_OAUTH2_FOR_EXTERNAL_USERS}
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="LOGIN_REDIRECT_OVERRIDE"
|
||||||
|
config={authentication.LOGIN_REDIRECT_OVERRIDE}
|
||||||
|
type="url"
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="ACCESS_TOKEN_EXPIRE_SECONDS"
|
||||||
|
config={authentication.ACCESS_TOKEN_EXPIRE_SECONDS}
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="REFRESH_TOKEN_EXPIRE_SECONDS"
|
||||||
|
config={authentication.REFRESH_TOKEN_EXPIRE_SECONDS}
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
<InputField
|
||||||
|
name="AUTHORIZATION_CODE_EXPIRE_SECONDS"
|
||||||
|
config={authentication.AUTHORIZATION_CODE_EXPIRE_SECONDS}
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
<ObjectField
|
||||||
|
name="SOCIAL_AUTH_ORGANIZATION_MAP"
|
||||||
|
config={authentication.SOCIAL_AUTH_ORGANIZATION_MAP}
|
||||||
|
/>
|
||||||
|
<ObjectField
|
||||||
|
name="SOCIAL_AUTH_TEAM_MAP"
|
||||||
|
config={authentication.SOCIAL_AUTH_TEAM_MAP}
|
||||||
|
/>
|
||||||
|
<ObjectField
|
||||||
|
name="SOCIAL_AUTH_USER_FIELDS"
|
||||||
|
config={authentication.SOCIAL_AUTH_USER_FIELDS}
|
||||||
|
/>
|
||||||
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
|
</FormColumnLayout>
|
||||||
|
<RevertFormActionGroup
|
||||||
|
onCancel={handleCancel}
|
||||||
|
onSubmit={formik.handleSubmit}
|
||||||
|
onRevert={toggleModal}
|
||||||
|
/>
|
||||||
|
{isModalOpen && (
|
||||||
|
<RevertAllAlert
|
||||||
|
onClose={closeModal}
|
||||||
|
onRevertAll={handleRevertAll}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
)}
|
||||||
|
</CardBody>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MiscAuthenticationEdit;
|
||||||
@@ -6,36 +6,55 @@ import {
|
|||||||
waitForElement,
|
waitForElement,
|
||||||
} from '../../../../../testUtils/enzymeHelpers';
|
} from '../../../../../testUtils/enzymeHelpers';
|
||||||
import mockAllOptions from '../../shared/data.allSettingOptions.json';
|
import mockAllOptions from '../../shared/data.allSettingOptions.json';
|
||||||
|
import mockAllSettings from '../../shared/data.allSettings.json';
|
||||||
import { SettingsProvider } from '../../../../contexts/Settings';
|
import { SettingsProvider } from '../../../../contexts/Settings';
|
||||||
import { SettingsAPI } from '../../../../api';
|
import { SettingsAPI } from '../../../../api';
|
||||||
import ActivityStreamEdit from './ActivityStreamEdit';
|
import MiscAuthenticationEdit from './MiscAuthenticationEdit';
|
||||||
|
|
||||||
jest.mock('../../../../api');
|
jest.mock('../../../../api');
|
||||||
|
|
||||||
describe('<ActivityStreamEdit />', () => {
|
const authenticationData = {
|
||||||
|
SESSION_COOKIE_AGE: 1800,
|
||||||
|
SESSIONS_PER_USER: -1,
|
||||||
|
DISABLE_LOCAL_AUTH: false,
|
||||||
|
AUTH_BASIC_ENABLED: true,
|
||||||
|
OAUTH2_PROVIDER: {
|
||||||
|
ACCESS_TOKEN_EXPIRE_SECONDS: 31536000000,
|
||||||
|
REFRESH_TOKEN_EXPIRE_SECONDS: 2628000,
|
||||||
|
AUTHORIZATION_CODE_EXPIRE_SECONDS: 600,
|
||||||
|
},
|
||||||
|
ALLOW_OAUTH2_FOR_EXTERNAL_USERS: false,
|
||||||
|
LOGIN_REDIRECT_OVERRIDE: '',
|
||||||
|
AUTHENTICATION_BACKENDS: [
|
||||||
|
'awx.sso.backends.TACACSPlusBackend',
|
||||||
|
'awx.main.backends.AWXModelBackend',
|
||||||
|
],
|
||||||
|
SOCIAL_AUTH_ORGANIZATION_MAP: {},
|
||||||
|
SOCIAL_AUTH_TEAM_MAP: {},
|
||||||
|
SOCIAL_AUTH_USER_FIELDS: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('<MiscAuthenticationEdit />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
let history;
|
let history;
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
wrapper.unmount();
|
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
history = createMemoryHistory({
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
initialEntries: ['/settings/activity_stream/edit'],
|
|
||||||
});
|
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
|
||||||
data: {
|
|
||||||
ACTIVITY_STREAM_ENABLED: false,
|
|
||||||
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
|
data: mockAllSettings,
|
||||||
|
});
|
||||||
|
history = createMemoryHistory({
|
||||||
|
initialEntries: ['/settings/miscellaneous_authentication/edit'],
|
||||||
|
});
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper = mountWithContexts(
|
wrapper = mountWithContexts(
|
||||||
<SettingsProvider value={mockAllOptions.actions}>
|
<SettingsProvider value={mockAllOptions.actions}>
|
||||||
<ActivityStreamEdit />
|
<MiscAuthenticationEdit />
|
||||||
</SettingsProvider>,
|
</SettingsProvider>,
|
||||||
{
|
{
|
||||||
context: { router: { history } },
|
context: { router: { history } },
|
||||||
@@ -45,54 +64,23 @@ describe('<ActivityStreamEdit />', () => {
|
|||||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('initially renders without crashing', () => {
|
test('initially renders without crashing', async () => {
|
||||||
expect(wrapper.find('ActivityStreamEdit').length).toBe(1);
|
expect(wrapper.find('MiscAuthenticationEdit').length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should navigate to activity stream detail when cancel is clicked', async () => {
|
test('save button should call updateAll', async () => {
|
||||||
|
expect(wrapper.find('MiscAuthenticationEdit').length).toBe(1);
|
||||||
|
wrapper.update();
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper.find('button[aria-label="Cancel"]').invoke('onClick')();
|
wrapper.find('button[aria-label="Save"]').simulate('click');
|
||||||
});
|
|
||||||
expect(history.location.pathname).toEqual(
|
|
||||||
'/settings/activity_stream/details'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should navigate to activity stream detail on successful submission', async () => {
|
|
||||||
await act(async () => {
|
|
||||||
wrapper.find('Form').invoke('onSubmit')();
|
|
||||||
});
|
|
||||||
expect(history.location.pathname).toEqual(
|
|
||||||
'/settings/activity_stream/details'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
|
||||||
expect(
|
|
||||||
wrapper.find('Switch#ACTIVITY_STREAM_ENABLED').prop('isChecked')
|
|
||||||
).toEqual(false);
|
|
||||||
|
|
||||||
await act(async () => {
|
|
||||||
wrapper.find('Switch#ACTIVITY_STREAM_ENABLED').invoke('onChange')(true);
|
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(
|
const { AUTHENTICATION_BACKENDS, ...rest } = authenticationData;
|
||||||
wrapper.find('Switch#ACTIVITY_STREAM_ENABLED').prop('isChecked')
|
expect(SettingsAPI.updateAll).toHaveBeenCalledWith(rest);
|
||||||
).toEqual(true);
|
|
||||||
|
|
||||||
await act(async () => {
|
|
||||||
wrapper.find('Form').invoke('onSubmit')();
|
|
||||||
});
|
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
|
|
||||||
ACTIVITY_STREAM_ENABLED: true,
|
|
||||||
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC: true,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -107,11 +95,33 @@ describe('<ActivityStreamEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('authentication');
|
||||||
ACTIVITY_STREAM_ENABLED: true,
|
});
|
||||||
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC: false,
|
|
||||||
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
await act(async () => {
|
||||||
|
wrapper.find('Form').invoke('onSubmit')();
|
||||||
});
|
});
|
||||||
|
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should navigate to miscellaneous detail on successful submission', async () => {
|
||||||
|
await act(async () => {
|
||||||
|
wrapper.find('Form').invoke('onSubmit')();
|
||||||
|
});
|
||||||
|
expect(history.location.pathname).toEqual(
|
||||||
|
'/settings/miscellaneous_authentication/details'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should navigate to miscellaneous detail when cancel is clicked', async () => {
|
||||||
|
await act(async () => {
|
||||||
|
wrapper.find('button[aria-label="Cancel"]').invoke('onClick')();
|
||||||
|
});
|
||||||
|
expect(history.location.pathname).toEqual(
|
||||||
|
'/settings/miscellaneous_authentication/details'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should display error message on unsuccessful submission', async () => {
|
test('should display error message on unsuccessful submission', async () => {
|
||||||
@@ -138,7 +148,7 @@ describe('<ActivityStreamEdit />', () => {
|
|||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper = mountWithContexts(
|
wrapper = mountWithContexts(
|
||||||
<SettingsProvider value={mockAllOptions.actions}>
|
<SettingsProvider value={mockAllOptions.actions}>
|
||||||
<ActivityStreamEdit />
|
<MiscAuthenticationEdit />
|
||||||
</SettingsProvider>
|
</SettingsProvider>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { default } from './MiscAuthenticationEdit';
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { default } from './MiscAuthentication';
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link, Redirect, Route, Switch } from 'react-router-dom';
|
import { Link, Redirect, Route, Switch } from 'react-router-dom';
|
||||||
|
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { PageSection, Card } from '@patternfly/react-core';
|
import { PageSection, Card } from '@patternfly/react-core';
|
||||||
import ContentError from '../../../components/ContentError';
|
import ContentError from '../../../components/ContentError';
|
||||||
|
|||||||
@@ -18,84 +18,49 @@ import { sortNestedDetails, pluck } from '../../shared/settingUtils';
|
|||||||
|
|
||||||
function MiscSystemDetail() {
|
function MiscSystemDetail() {
|
||||||
const { me } = useConfig();
|
const { me } = useConfig();
|
||||||
const { GET: allOptions } = useSettings();
|
const { GET: options } = useSettings();
|
||||||
|
|
||||||
const { isLoading, error, request, result: system } = useRequest(
|
const { isLoading, error, request, result: system } = useRequest(
|
||||||
useCallback(async () => {
|
useCallback(async () => {
|
||||||
const { data } = await SettingsAPI.readCategory('all');
|
const { data } = await SettingsAPI.readCategory('system');
|
||||||
let DEFAULT_EXECUTION_ENVIRONMENT = '';
|
|
||||||
if (data.DEFAULT_EXECUTION_ENVIRONMENT) {
|
if (data.DEFAULT_EXECUTION_ENVIRONMENT) {
|
||||||
const {
|
const {
|
||||||
data: { name },
|
data: { name },
|
||||||
} = await ExecutionEnvironmentsAPI.readDetail(
|
} = await ExecutionEnvironmentsAPI.readDetail(
|
||||||
data.DEFAULT_EXECUTION_ENVIRONMENT
|
data.DEFAULT_EXECUTION_ENVIRONMENT
|
||||||
);
|
);
|
||||||
DEFAULT_EXECUTION_ENVIRONMENT = name;
|
data.DEFAULT_EXECUTION_ENVIRONMENT = name;
|
||||||
}
|
}
|
||||||
const {
|
|
||||||
OAUTH2_PROVIDER: {
|
const systemData = pluck(
|
||||||
ACCESS_TOKEN_EXPIRE_SECONDS,
|
|
||||||
REFRESH_TOKEN_EXPIRE_SECONDS,
|
|
||||||
AUTHORIZATION_CODE_EXPIRE_SECONDS,
|
|
||||||
},
|
|
||||||
...pluckedSystemData
|
|
||||||
} = pluck(
|
|
||||||
data,
|
data,
|
||||||
'ALLOW_OAUTH2_FOR_EXTERNAL_USERS',
|
'ACTIVITY_STREAM_ENABLED',
|
||||||
'AUTH_BASIC_ENABLED',
|
'ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC',
|
||||||
'AUTOMATION_ANALYTICS_GATHER_INTERVAL',
|
'AUTOMATION_ANALYTICS_GATHER_INTERVAL',
|
||||||
'AUTOMATION_ANALYTICS_URL',
|
'AUTOMATION_ANALYTICS_URL',
|
||||||
'INSIGHTS_TRACKING_STATE',
|
'INSIGHTS_TRACKING_STATE',
|
||||||
'LOGIN_REDIRECT_OVERRIDE',
|
|
||||||
'MANAGE_ORGANIZATION_AUTH',
|
'MANAGE_ORGANIZATION_AUTH',
|
||||||
'DISABLE_LOCAL_AUTH',
|
|
||||||
'OAUTH2_PROVIDER',
|
|
||||||
'ORG_ADMINS_CAN_SEE_ALL_USERS',
|
'ORG_ADMINS_CAN_SEE_ALL_USERS',
|
||||||
'REDHAT_PASSWORD',
|
|
||||||
'REDHAT_USERNAME',
|
'REDHAT_USERNAME',
|
||||||
'REMOTE_HOST_HEADERS',
|
'REDHAT_PASSWORD',
|
||||||
'SESSIONS_PER_USER',
|
|
||||||
'SESSION_COOKIE_AGE',
|
|
||||||
'SUBSCRIPTIONS_USERNAME',
|
'SUBSCRIPTIONS_USERNAME',
|
||||||
'SUBSCRIPTIONS_PASSWORD',
|
'SUBSCRIPTIONS_PASSWORD',
|
||||||
'TOWER_URL_BASE'
|
'INSTALL_UUID',
|
||||||
|
'REMOTE_HOST_HEADERS',
|
||||||
|
'TOWER_URL_BASE',
|
||||||
|
'DEFAULT_EXECUTION_ENVIRONMENT',
|
||||||
|
'PROXY_IP_ALLOWED_LIST',
|
||||||
|
'AUTOMATION_ANALYTICS_LAST_GATHER',
|
||||||
|
'AUTOMATION_ANALYTICS_LAST_ENTRIES'
|
||||||
);
|
);
|
||||||
const systemData = {
|
|
||||||
...pluckedSystemData,
|
|
||||||
ACCESS_TOKEN_EXPIRE_SECONDS,
|
|
||||||
REFRESH_TOKEN_EXPIRE_SECONDS,
|
|
||||||
AUTHORIZATION_CODE_EXPIRE_SECONDS,
|
|
||||||
DEFAULT_EXECUTION_ENVIRONMENT,
|
|
||||||
};
|
|
||||||
const {
|
|
||||||
OAUTH2_PROVIDER: OAUTH2_PROVIDER_OPTIONS,
|
|
||||||
...options
|
|
||||||
} = allOptions;
|
|
||||||
const systemOptions = {
|
|
||||||
...options,
|
|
||||||
ACCESS_TOKEN_EXPIRE_SECONDS: {
|
|
||||||
...OAUTH2_PROVIDER_OPTIONS,
|
|
||||||
type: OAUTH2_PROVIDER_OPTIONS.child.type,
|
|
||||||
label: t`Access Token Expiration`,
|
|
||||||
},
|
|
||||||
REFRESH_TOKEN_EXPIRE_SECONDS: {
|
|
||||||
...OAUTH2_PROVIDER_OPTIONS,
|
|
||||||
type: OAUTH2_PROVIDER_OPTIONS.child.type,
|
|
||||||
label: t`Refresh Token Expiration`,
|
|
||||||
},
|
|
||||||
AUTHORIZATION_CODE_EXPIRE_SECONDS: {
|
|
||||||
...OAUTH2_PROVIDER_OPTIONS,
|
|
||||||
type: OAUTH2_PROVIDER_OPTIONS.child.type,
|
|
||||||
label: t`Authorization Code Expiration`,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const mergedData = {};
|
const mergedData = {};
|
||||||
Object.keys(systemData).forEach(key => {
|
Object.keys(systemData).forEach(key => {
|
||||||
mergedData[key] = systemOptions[key];
|
mergedData[key] = options[key];
|
||||||
mergedData[key].value = systemData[key];
|
mergedData[key].value = systemData[key];
|
||||||
});
|
});
|
||||||
return sortNestedDetails(mergedData);
|
return sortNestedDetails(mergedData);
|
||||||
}, [allOptions]),
|
}, [options]),
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -22,28 +22,26 @@ describe('<MiscSystemDetail />', () => {
|
|||||||
SettingsAPI.readCategory = jest.fn();
|
SettingsAPI.readCategory = jest.fn();
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
ALLOW_OAUTH2_FOR_EXTERNAL_USERS: false,
|
ACTIVITY_STREAM_ENABLED: true,
|
||||||
AUTH_BASIC_ENABLED: true,
|
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC: false,
|
||||||
AUTOMATION_ANALYTICS_GATHER_INTERVAL: 14400,
|
ORG_ADMINS_CAN_SEE_ALL_USERS: true,
|
||||||
|
MANAGE_ORGANIZATION_AUTH: true,
|
||||||
|
TOWER_URL_BASE: 'https://towerhost',
|
||||||
|
REMOTE_HOST_HEADERS: [],
|
||||||
|
PROXY_IP_ALLOWED_LIST: [],
|
||||||
|
LICENSE: null,
|
||||||
|
REDHAT_USERNAME: 'name1',
|
||||||
|
REDHAT_PASSWORD: '$encrypted$',
|
||||||
|
SUBSCRIPTIONS_USERNAME: 'name2',
|
||||||
|
SUBSCRIPTIONS_PASSWORD: '$encrypted$',
|
||||||
AUTOMATION_ANALYTICS_URL: 'https://example.com',
|
AUTOMATION_ANALYTICS_URL: 'https://example.com',
|
||||||
|
INSTALL_UUID: 'db39b9ec-0c6e-4554-987d-42aw9c732ed8',
|
||||||
|
DEFAULT_EXECUTION_ENVIRONMENT: 1,
|
||||||
CUSTOM_VENV_PATHS: [],
|
CUSTOM_VENV_PATHS: [],
|
||||||
INSIGHTS_TRACKING_STATE: false,
|
INSIGHTS_TRACKING_STATE: false,
|
||||||
LOGIN_REDIRECT_OVERRIDE: 'https://redirect.com',
|
AUTOMATION_ANALYTICS_LAST_GATHER: null,
|
||||||
MANAGE_ORGANIZATION_AUTH: true,
|
AUTOMATION_ANALYTICS_LAST_ENTRIES: 'foo',
|
||||||
DISABLE_LOCAL_AUTH: false,
|
AUTOMATION_ANALYTICS_GATHER_INTERVAL: 14400,
|
||||||
OAUTH2_PROVIDER: {
|
|
||||||
ACCESS_TOKEN_EXPIRE_SECONDS: 1,
|
|
||||||
AUTHORIZATION_CODE_EXPIRE_SECONDS: 2,
|
|
||||||
REFRESH_TOKEN_EXPIRE_SECONDS: 3,
|
|
||||||
},
|
|
||||||
ORG_ADMINS_CAN_SEE_ALL_USERS: true,
|
|
||||||
REDHAT_PASSWORD: '$encrypted$',
|
|
||||||
REDHAT_USERNAME: 'mock name',
|
|
||||||
REMOTE_HOST_HEADERS: [],
|
|
||||||
SESSIONS_PER_USER: -1,
|
|
||||||
SESSION_COOKIE_AGE: 30000000000,
|
|
||||||
TOWER_URL_BASE: 'https://towerhost',
|
|
||||||
DEFAULT_EXECUTION_ENVIRONMENT: 1,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
ExecutionEnvironmentsAPI.readDetail = jest.fn();
|
ExecutionEnvironmentsAPI.readDetail = jest.fn();
|
||||||
@@ -77,14 +75,17 @@ describe('<MiscSystemDetail />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should render expected details', () => {
|
test('should render expected details', () => {
|
||||||
assertDetail(wrapper, 'Access Token Expiration', '1 seconds');
|
|
||||||
assertDetail(wrapper, 'All Users Visible to Organization Admins', 'On');
|
|
||||||
assertDetail(
|
assertDetail(
|
||||||
wrapper,
|
wrapper,
|
||||||
'Allow External Users to Create OAuth2 Tokens',
|
'Unique identifier for an installation',
|
||||||
'Off'
|
'db39b9ec-0c6e-4554-987d-42aw9c732ed8'
|
||||||
);
|
);
|
||||||
assertDetail(wrapper, 'Authorization Code Expiration', '2 seconds');
|
assertDetail(
|
||||||
|
wrapper,
|
||||||
|
'Last gathered entries for expensive collectors for Insights for Ansible Automation Platform.',
|
||||||
|
'foo'
|
||||||
|
);
|
||||||
|
assertDetail(wrapper, 'All Users Visible to Organization Admins', 'On');
|
||||||
assertDetail(
|
assertDetail(
|
||||||
wrapper,
|
wrapper,
|
||||||
'Insights for Ansible Automation Platform Gather Interval',
|
'Insights for Ansible Automation Platform Gather Interval',
|
||||||
@@ -96,32 +97,24 @@ describe('<MiscSystemDetail />', () => {
|
|||||||
'https://example.com'
|
'https://example.com'
|
||||||
);
|
);
|
||||||
assertDetail(wrapper, 'Base URL of the service', 'https://towerhost');
|
assertDetail(wrapper, 'Base URL of the service', 'https://towerhost');
|
||||||
assertDetail(wrapper, 'Enable HTTP Basic Auth', 'On');
|
|
||||||
assertDetail(
|
assertDetail(
|
||||||
wrapper,
|
wrapper,
|
||||||
'Gather data for Insights for Ansible Automation Platform',
|
'Gather data for Insights for Ansible Automation Platform',
|
||||||
'Off'
|
'Off'
|
||||||
);
|
);
|
||||||
assertDetail(wrapper, 'Idle Time Force Log Out', '30000000000 seconds');
|
|
||||||
assertDetail(
|
|
||||||
wrapper,
|
|
||||||
'Login redirect override URL',
|
|
||||||
'https://redirect.com'
|
|
||||||
);
|
|
||||||
assertDetail(
|
|
||||||
wrapper,
|
|
||||||
'Maximum number of simultaneous logged in sessions',
|
|
||||||
'-1'
|
|
||||||
);
|
|
||||||
assertDetail(
|
assertDetail(
|
||||||
wrapper,
|
wrapper,
|
||||||
'Organization Admins Can Manage Users and Teams',
|
'Organization Admins Can Manage Users and Teams',
|
||||||
'On'
|
'On'
|
||||||
);
|
);
|
||||||
|
assertDetail(wrapper, 'Enable Activity Stream', 'On');
|
||||||
|
assertDetail(wrapper, 'Enable Activity Stream for Inventory Sync', 'Off');
|
||||||
assertDetail(wrapper, 'Red Hat customer password', 'Encrypted');
|
assertDetail(wrapper, 'Red Hat customer password', 'Encrypted');
|
||||||
assertDetail(wrapper, 'Red Hat customer username', 'mock name');
|
assertDetail(wrapper, 'Red Hat customer username', 'name1');
|
||||||
assertDetail(wrapper, 'Refresh Token Expiration', '3 seconds');
|
assertDetail(wrapper, 'Red Hat or Satellite password', 'Encrypted');
|
||||||
|
assertDetail(wrapper, 'Red Hat or Satellite username', 'name2');
|
||||||
assertVariableDetail(wrapper, 'Remote Host Headers', '[]');
|
assertVariableDetail(wrapper, 'Remote Host Headers', '[]');
|
||||||
|
assertVariableDetail(wrapper, 'Proxy IP Allowed List', '[]');
|
||||||
assertDetail(wrapper, 'Global default execution environment', 'Foo');
|
assertDetail(wrapper, 'Global default execution environment', 'Foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -30,76 +30,33 @@ function MiscSystemEdit() {
|
|||||||
|
|
||||||
const { isLoading, error, request: fetchSystem, result: system } = useRequest(
|
const { isLoading, error, request: fetchSystem, result: system } = useRequest(
|
||||||
useCallback(async () => {
|
useCallback(async () => {
|
||||||
const { data } = await SettingsAPI.readCategory('all');
|
const { data } = await SettingsAPI.readCategory('system');
|
||||||
const {
|
const systemData = pluck(
|
||||||
OAUTH2_PROVIDER: {
|
|
||||||
ACCESS_TOKEN_EXPIRE_SECONDS,
|
|
||||||
REFRESH_TOKEN_EXPIRE_SECONDS,
|
|
||||||
AUTHORIZATION_CODE_EXPIRE_SECONDS,
|
|
||||||
},
|
|
||||||
...pluckedSystemData
|
|
||||||
} = pluck(
|
|
||||||
data,
|
data,
|
||||||
'ALLOW_OAUTH2_FOR_EXTERNAL_USERS',
|
'ACTIVITY_STREAM_ENABLED',
|
||||||
'AUTH_BASIC_ENABLED',
|
'ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC',
|
||||||
'AUTOMATION_ANALYTICS_GATHER_INTERVAL',
|
'AUTOMATION_ANALYTICS_GATHER_INTERVAL',
|
||||||
'AUTOMATION_ANALYTICS_URL',
|
'AUTOMATION_ANALYTICS_URL',
|
||||||
|
'AUTOMATION_ANALYTICS_LAST_ENTRIES',
|
||||||
'INSIGHTS_TRACKING_STATE',
|
'INSIGHTS_TRACKING_STATE',
|
||||||
'LOGIN_REDIRECT_OVERRIDE',
|
|
||||||
'MANAGE_ORGANIZATION_AUTH',
|
'MANAGE_ORGANIZATION_AUTH',
|
||||||
'DISABLE_LOCAL_AUTH',
|
|
||||||
'OAUTH2_PROVIDER',
|
|
||||||
'ORG_ADMINS_CAN_SEE_ALL_USERS',
|
'ORG_ADMINS_CAN_SEE_ALL_USERS',
|
||||||
'REDHAT_PASSWORD',
|
|
||||||
'REDHAT_USERNAME',
|
'REDHAT_USERNAME',
|
||||||
|
'REDHAT_PASSWORD',
|
||||||
|
'SUBSCRIPTIONS_USERNAME',
|
||||||
|
'SUBSCRIPTIONS_PASSWORD',
|
||||||
'REMOTE_HOST_HEADERS',
|
'REMOTE_HOST_HEADERS',
|
||||||
'SESSIONS_PER_USER',
|
|
||||||
'SESSION_COOKIE_AGE',
|
|
||||||
'TOWER_URL_BASE',
|
'TOWER_URL_BASE',
|
||||||
'DEFAULT_EXECUTION_ENVIRONMENT'
|
'DEFAULT_EXECUTION_ENVIRONMENT',
|
||||||
|
'PROXY_IP_ALLOWED_LIST'
|
||||||
);
|
);
|
||||||
|
|
||||||
const systemData = {
|
|
||||||
...pluckedSystemData,
|
|
||||||
ACCESS_TOKEN_EXPIRE_SECONDS,
|
|
||||||
REFRESH_TOKEN_EXPIRE_SECONDS,
|
|
||||||
AUTHORIZATION_CODE_EXPIRE_SECONDS,
|
|
||||||
};
|
|
||||||
|
|
||||||
const {
|
|
||||||
OAUTH2_PROVIDER: OAUTH2_PROVIDER_OPTIONS,
|
|
||||||
...restOptions
|
|
||||||
} = options;
|
|
||||||
|
|
||||||
const systemOptions = {
|
|
||||||
...restOptions,
|
|
||||||
ACCESS_TOKEN_EXPIRE_SECONDS: {
|
|
||||||
...OAUTH2_PROVIDER_OPTIONS,
|
|
||||||
default: OAUTH2_PROVIDER_OPTIONS.default.ACCESS_TOKEN_EXPIRE_SECONDS,
|
|
||||||
type: OAUTH2_PROVIDER_OPTIONS.child.type,
|
|
||||||
label: t`Access Token Expiration`,
|
|
||||||
},
|
|
||||||
REFRESH_TOKEN_EXPIRE_SECONDS: {
|
|
||||||
...OAUTH2_PROVIDER_OPTIONS,
|
|
||||||
default: OAUTH2_PROVIDER_OPTIONS.default.REFRESH_TOKEN_EXPIRE_SECONDS,
|
|
||||||
type: OAUTH2_PROVIDER_OPTIONS.child.type,
|
|
||||||
label: t`Refresh Token Expiration`,
|
|
||||||
},
|
|
||||||
AUTHORIZATION_CODE_EXPIRE_SECONDS: {
|
|
||||||
...OAUTH2_PROVIDER_OPTIONS,
|
|
||||||
default:
|
|
||||||
OAUTH2_PROVIDER_OPTIONS.default.AUTHORIZATION_CODE_EXPIRE_SECONDS,
|
|
||||||
type: OAUTH2_PROVIDER_OPTIONS.child.type,
|
|
||||||
label: t`Authorization Code Expiration`,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const mergedData = {};
|
const mergedData = {};
|
||||||
Object.keys(systemData).forEach(key => {
|
Object.keys(systemData).forEach(key => {
|
||||||
if (!systemOptions[key]) {
|
if (!options[key]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mergedData[key] = systemOptions[key];
|
mergedData[key] = options[key];
|
||||||
mergedData[key].value = systemData[key];
|
mergedData[key].value = systemData[key];
|
||||||
});
|
});
|
||||||
return mergedData;
|
return mergedData;
|
||||||
@@ -122,50 +79,29 @@ function MiscSystemEdit() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
const {
|
useCallback(async () => {
|
||||||
ACCESS_TOKEN_EXPIRE_SECONDS,
|
await SettingsAPI.revertCategory('system');
|
||||||
REFRESH_TOKEN_EXPIRE_SECONDS,
|
}, []),
|
||||||
AUTHORIZATION_CODE_EXPIRE_SECONDS,
|
null
|
||||||
...formData
|
);
|
||||||
} = form;
|
|
||||||
|
|
||||||
|
const handleSubmit = async form => {
|
||||||
await submitForm({
|
await submitForm({
|
||||||
...formData,
|
...form,
|
||||||
REMOTE_HOST_HEADERS: formatJson(formData.REMOTE_HOST_HEADERS),
|
PROXY_IP_ALLOWED_LIST: formatJson(form.PROXY_IP_ALLOWED_LIST),
|
||||||
OAUTH2_PROVIDER: {
|
REMOTE_HOST_HEADERS: formatJson(form.REMOTE_HOST_HEADERS),
|
||||||
ACCESS_TOKEN_EXPIRE_SECONDS,
|
|
||||||
REFRESH_TOKEN_EXPIRE_SECONDS,
|
|
||||||
AUTHORIZATION_CODE_EXPIRE_SECONDS,
|
|
||||||
},
|
|
||||||
DEFAULT_EXECUTION_ENVIRONMENT:
|
DEFAULT_EXECUTION_ENVIRONMENT:
|
||||||
formData.DEFAULT_EXECUTION_ENVIRONMENT?.id || null,
|
form.DEFAULT_EXECUTION_ENVIRONMENT?.id || null,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const handleRevertAll = async () => {
|
||||||
const {
|
await revertAll();
|
||||||
ACCESS_TOKEN_EXPIRE_SECONDS,
|
|
||||||
REFRESH_TOKEN_EXPIRE_SECONDS,
|
|
||||||
AUTHORIZATION_CODE_EXPIRE_SECONDS,
|
|
||||||
...systemData
|
|
||||||
} = system;
|
|
||||||
|
|
||||||
const defaultValues = {};
|
|
||||||
Object.entries(systemData).forEach(([key, value]) => {
|
|
||||||
defaultValues[key] = value.default;
|
|
||||||
});
|
|
||||||
|
|
||||||
await submitForm({
|
|
||||||
...defaultValues,
|
|
||||||
OAUTH2_PROVIDER: {
|
|
||||||
ACCESS_TOKEN_EXPIRE_SECONDS: ACCESS_TOKEN_EXPIRE_SECONDS.default,
|
|
||||||
REFRESH_TOKEN_EXPIRE_SECONDS: REFRESH_TOKEN_EXPIRE_SECONDS.default,
|
|
||||||
AUTHORIZATION_CODE_EXPIRE_SECONDS:
|
|
||||||
AUTHORIZATION_CODE_EXPIRE_SECONDS.default,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/miscellaneous_system/details');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -226,6 +162,14 @@ function MiscSystemEdit() {
|
|||||||
return (
|
return (
|
||||||
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
<Form autoComplete="off" onSubmit={formik.handleSubmit}>
|
||||||
<FormColumnLayout>
|
<FormColumnLayout>
|
||||||
|
<BooleanField
|
||||||
|
name="ACTIVITY_STREAM_ENABLED"
|
||||||
|
config={system.ACTIVITY_STREAM_ENABLED}
|
||||||
|
/>
|
||||||
|
<BooleanField
|
||||||
|
name="ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC"
|
||||||
|
config={system.ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC}
|
||||||
|
/>
|
||||||
<ExecutionEnvironmentLookup
|
<ExecutionEnvironmentLookup
|
||||||
helperTextInvalid={
|
helperTextInvalid={
|
||||||
formik.errors.DEFAULT_EXECUTION_ENVIRONMENT
|
formik.errors.DEFAULT_EXECUTION_ENVIRONMENT
|
||||||
@@ -267,52 +211,6 @@ function MiscSystemEdit() {
|
|||||||
name="MANAGE_ORGANIZATION_AUTH"
|
name="MANAGE_ORGANIZATION_AUTH"
|
||||||
config={system.MANAGE_ORGANIZATION_AUTH}
|
config={system.MANAGE_ORGANIZATION_AUTH}
|
||||||
/>
|
/>
|
||||||
<BooleanField
|
|
||||||
name="DISABLE_LOCAL_AUTH"
|
|
||||||
needsConfirmationModal
|
|
||||||
modalTitle={t`Confirm Disable Local Authorization`}
|
|
||||||
config={system.DISABLE_LOCAL_AUTH}
|
|
||||||
/>
|
|
||||||
<InputField
|
|
||||||
name="SESSION_COOKIE_AGE"
|
|
||||||
config={system.SESSION_COOKIE_AGE}
|
|
||||||
type="number"
|
|
||||||
isRequired
|
|
||||||
/>
|
|
||||||
<InputField
|
|
||||||
name="SESSIONS_PER_USER"
|
|
||||||
config={system.SESSIONS_PER_USER}
|
|
||||||
type="number"
|
|
||||||
isRequired
|
|
||||||
/>
|
|
||||||
<BooleanField
|
|
||||||
name="AUTH_BASIC_ENABLED"
|
|
||||||
config={system.AUTH_BASIC_ENABLED}
|
|
||||||
/>
|
|
||||||
<BooleanField
|
|
||||||
name="ALLOW_OAUTH2_FOR_EXTERNAL_USERS"
|
|
||||||
config={system.ALLOW_OAUTH2_FOR_EXTERNAL_USERS}
|
|
||||||
/>
|
|
||||||
<InputField
|
|
||||||
name="LOGIN_REDIRECT_OVERRIDE"
|
|
||||||
config={system.LOGIN_REDIRECT_OVERRIDE}
|
|
||||||
type="url"
|
|
||||||
/>
|
|
||||||
<InputField
|
|
||||||
name="ACCESS_TOKEN_EXPIRE_SECONDS"
|
|
||||||
config={system.ACCESS_TOKEN_EXPIRE_SECONDS}
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
<InputField
|
|
||||||
name="REFRESH_TOKEN_EXPIRE_SECONDS"
|
|
||||||
config={system.REFRESH_TOKEN_EXPIRE_SECONDS}
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
<InputField
|
|
||||||
name="AUTHORIZATION_CODE_EXPIRE_SECONDS"
|
|
||||||
config={system.AUTHORIZATION_CODE_EXPIRE_SECONDS}
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
<BooleanField
|
<BooleanField
|
||||||
name="INSIGHTS_TRACKING_STATE"
|
name="INSIGHTS_TRACKING_STATE"
|
||||||
config={system.INSIGHTS_TRACKING_STATE}
|
config={system.INSIGHTS_TRACKING_STATE}
|
||||||
@@ -325,6 +223,14 @@ function MiscSystemEdit() {
|
|||||||
name="REDHAT_PASSWORD"
|
name="REDHAT_PASSWORD"
|
||||||
config={system.REDHAT_PASSWORD}
|
config={system.REDHAT_PASSWORD}
|
||||||
/>
|
/>
|
||||||
|
<InputField
|
||||||
|
name="SUBSCRIPTIONS_USERNAME"
|
||||||
|
config={system.SUBSCRIPTIONS_USERNAME}
|
||||||
|
/>
|
||||||
|
<EncryptedField
|
||||||
|
name="SUBSCRIPTIONS_PASSWORD"
|
||||||
|
config={system.SUBSCRIPTIONS_PASSWORD}
|
||||||
|
/>
|
||||||
<InputField
|
<InputField
|
||||||
name="AUTOMATION_ANALYTICS_URL"
|
name="AUTOMATION_ANALYTICS_URL"
|
||||||
config={system.AUTOMATION_ANALYTICS_URL}
|
config={system.AUTOMATION_ANALYTICS_URL}
|
||||||
@@ -336,12 +242,22 @@ function MiscSystemEdit() {
|
|||||||
type="number"
|
type="number"
|
||||||
isRequired
|
isRequired
|
||||||
/>
|
/>
|
||||||
|
<InputField
|
||||||
|
name="AUTOMATION_ANALYTICS_LAST_ENTRIES"
|
||||||
|
config={system.AUTOMATION_ANALYTICS_LAST_ENTRIES}
|
||||||
|
/>
|
||||||
<ObjectField
|
<ObjectField
|
||||||
name="REMOTE_HOST_HEADERS"
|
name="REMOTE_HOST_HEADERS"
|
||||||
config={system.REMOTE_HOST_HEADERS}
|
config={system.REMOTE_HOST_HEADERS}
|
||||||
isRequired
|
isRequired
|
||||||
/>
|
/>
|
||||||
|
<ObjectField
|
||||||
|
name="PROXY_IP_ALLOWED_LIST"
|
||||||
|
config={system.PROXY_IP_ALLOWED_LIST}
|
||||||
|
isRequired
|
||||||
|
/>
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
</FormColumnLayout>
|
</FormColumnLayout>
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -23,27 +23,22 @@ const mockExecutionEnvironment = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const systemData = {
|
const systemData = {
|
||||||
ALLOW_OAUTH2_FOR_EXTERNAL_USERS: false,
|
ACTIVITY_STREAM_ENABLED: true,
|
||||||
AUTH_BASIC_ENABLED: true,
|
ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC: false,
|
||||||
AUTOMATION_ANALYTICS_GATHER_INTERVAL: 14400,
|
AUTOMATION_ANALYTICS_GATHER_INTERVAL: 14400,
|
||||||
|
AUTOMATION_ANALYTICS_LAST_ENTRIES: '',
|
||||||
AUTOMATION_ANALYTICS_URL: 'https://example.com',
|
AUTOMATION_ANALYTICS_URL: 'https://example.com',
|
||||||
DEFAULT_EXECUTION_ENVIRONMENT: 1,
|
DEFAULT_EXECUTION_ENVIRONMENT: 1,
|
||||||
INSIGHTS_TRACKING_STATE: false,
|
INSIGHTS_TRACKING_STATE: false,
|
||||||
LOGIN_REDIRECT_OVERRIDE: '',
|
|
||||||
MANAGE_ORGANIZATION_AUTH: true,
|
MANAGE_ORGANIZATION_AUTH: true,
|
||||||
DISABLE_LOCAL_AUTH: false,
|
|
||||||
OAUTH2_PROVIDER: {
|
|
||||||
ACCESS_TOKEN_EXPIRE_SECONDS: 31536000000,
|
|
||||||
AUTHORIZATION_CODE_EXPIRE_SECONDS: 600,
|
|
||||||
REFRESH_TOKEN_EXPIRE_SECONDS: 2628000,
|
|
||||||
},
|
|
||||||
ORG_ADMINS_CAN_SEE_ALL_USERS: true,
|
ORG_ADMINS_CAN_SEE_ALL_USERS: true,
|
||||||
REDHAT_PASSWORD: '',
|
|
||||||
REDHAT_USERNAME: '',
|
REDHAT_USERNAME: '',
|
||||||
|
REDHAT_PASSWORD: '',
|
||||||
|
SUBSCRIPTIONS_USERNAME: '',
|
||||||
|
SUBSCRIPTIONS_PASSWORD: '',
|
||||||
REMOTE_HOST_HEADERS: ['REMOTE_ADDR', 'REMOTE_HOST'],
|
REMOTE_HOST_HEADERS: ['REMOTE_ADDR', 'REMOTE_HOST'],
|
||||||
SESSIONS_PER_USER: -1,
|
|
||||||
SESSION_COOKIE_AGE: 1800,
|
|
||||||
TOWER_URL_BASE: 'https://localhost:3000',
|
TOWER_URL_BASE: 'https://localhost:3000',
|
||||||
|
PROXY_IP_ALLOWED_LIST: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('<MiscSystemEdit />', () => {
|
describe('<MiscSystemEdit />', () => {
|
||||||
@@ -55,6 +50,7 @@ describe('<MiscSystemEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: mockAllSettings,
|
data: mockAllSettings,
|
||||||
@@ -116,7 +112,7 @@ describe('<MiscSystemEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -131,7 +127,8 @@ describe('<MiscSystemEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('system');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
@@ -47,18 +47,23 @@ function RADIUSEdit() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await SettingsAPI.revertCategory('radius');
|
||||||
|
}, []),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
const handleSubmit = async form => {
|
||||||
await submitForm(form);
|
await submitForm(form);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const handleRevertAll = async () => {
|
||||||
const defaultValues = Object.assign(
|
await revertAll();
|
||||||
...Object.entries(radius).map(([key, value]) => ({
|
|
||||||
[key]: value.default,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/radius/details');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -90,6 +95,7 @@ function RADIUSEdit() {
|
|||||||
config={radius.RADIUS_SECRET}
|
config={radius.RADIUS_SECRET}
|
||||||
/>
|
/>
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
</FormColumnLayout>
|
</FormColumnLayout>
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ describe('<RADIUSEdit />', () => {
|
|||||||
let history;
|
let history;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
@@ -60,7 +61,7 @@ describe('<RADIUSEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -75,12 +76,8 @@ describe('<RADIUSEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('radius');
|
||||||
RADIUS_SERVER: '',
|
|
||||||
RADIUS_PORT: 1812,
|
|
||||||
RADIUS_SECRET: '',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
@@ -56,6 +56,13 @@ function SAMLEdit() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await SettingsAPI.revertCategory('saml');
|
||||||
|
}, []),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
const handleSubmit = async form => {
|
||||||
await submitForm({
|
await submitForm({
|
||||||
...form,
|
...form,
|
||||||
@@ -86,13 +93,11 @@ function SAMLEdit() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const handleRevertAll = async () => {
|
||||||
const defaultValues = Object.assign(
|
await revertAll();
|
||||||
...Object.entries(saml).map(([key, value]) => ({
|
|
||||||
[key]: value.default,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/saml/details');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -185,6 +190,7 @@ function SAMLEdit() {
|
|||||||
config={saml.SOCIAL_AUTH_SAML_EXTRA_DATA}
|
config={saml.SOCIAL_AUTH_SAML_EXTRA_DATA}
|
||||||
/>
|
/>
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
</FormColumnLayout>
|
</FormColumnLayout>
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ describe('<SAMLEdit />', () => {
|
|||||||
let history;
|
let history;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
@@ -131,7 +132,7 @@ describe('<SAMLEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -146,26 +147,8 @@ describe('<SAMLEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('saml');
|
||||||
SAML_AUTO_CREATE_OBJECTS: true,
|
|
||||||
SOCIAL_AUTH_SAML_ENABLED_IDPS: {},
|
|
||||||
SOCIAL_AUTH_SAML_EXTRA_DATA: null,
|
|
||||||
SOCIAL_AUTH_SAML_ORGANIZATION_ATTR: {},
|
|
||||||
SOCIAL_AUTH_SAML_ORGANIZATION_MAP: null,
|
|
||||||
SOCIAL_AUTH_SAML_ORG_INFO: {},
|
|
||||||
SOCIAL_AUTH_SAML_SP_ENTITY_ID: '',
|
|
||||||
SOCIAL_AUTH_SAML_SP_EXTRA: null,
|
|
||||||
SOCIAL_AUTH_SAML_SP_PRIVATE_KEY: '',
|
|
||||||
SOCIAL_AUTH_SAML_SP_PUBLIC_CERT: '',
|
|
||||||
SOCIAL_AUTH_SAML_SUPPORT_CONTACT: {},
|
|
||||||
SOCIAL_AUTH_SAML_TEAM_ATTR: {},
|
|
||||||
SOCIAL_AUTH_SAML_TEAM_MAP: null,
|
|
||||||
SOCIAL_AUTH_SAML_TECHNICAL_CONTACT: {},
|
|
||||||
SOCIAL_AUTH_SAML_SECURITY_CONFIG: {
|
|
||||||
requestedAuthnContext: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
@@ -107,8 +107,8 @@ function SettingList() {
|
|||||||
path: '/settings/miscellaneous_system',
|
path: '/settings/miscellaneous_system',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t`Activity Stream settings`,
|
title: t`Miscellaneous Authentication settings`,
|
||||||
path: '/settings/activity_stream',
|
path: '/settings/miscellaneous_authentication',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t`Logging settings`,
|
title: t`Logging settings`,
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import React, { useCallback, useEffect } from 'react';
|
import React, { useCallback, useEffect } from 'react';
|
||||||
import { Link, Route, Switch, Redirect } from 'react-router-dom';
|
import { Link, Route, Switch, Redirect } from 'react-router-dom';
|
||||||
|
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import { PageSection, Card } from '@patternfly/react-core';
|
import { PageSection, Card } from '@patternfly/react-core';
|
||||||
import ContentError from '../../components/ContentError';
|
import ContentError from '../../components/ContentError';
|
||||||
import ContentLoading from '../../components/ContentLoading';
|
import ContentLoading from '../../components/ContentLoading';
|
||||||
import ScreenHeader from '../../components/ScreenHeader';
|
import ScreenHeader from '../../components/ScreenHeader';
|
||||||
import ActivityStream from './ActivityStream';
|
|
||||||
import AzureAD from './AzureAD';
|
import AzureAD from './AzureAD';
|
||||||
import GitHub from './GitHub';
|
import GitHub from './GitHub';
|
||||||
import GoogleOAuth2 from './GoogleOAuth2';
|
import GoogleOAuth2 from './GoogleOAuth2';
|
||||||
@@ -14,6 +12,7 @@ import Jobs from './Jobs';
|
|||||||
import LDAP from './LDAP';
|
import LDAP from './LDAP';
|
||||||
import Subscription from './Subscription';
|
import Subscription from './Subscription';
|
||||||
import Logging from './Logging';
|
import Logging from './Logging';
|
||||||
|
import MiscAuthentication from './MiscAuthentication';
|
||||||
import MiscSystem from './MiscSystem';
|
import MiscSystem from './MiscSystem';
|
||||||
import RADIUS from './RADIUS';
|
import RADIUS from './RADIUS';
|
||||||
import SAML from './SAML';
|
import SAML from './SAML';
|
||||||
@@ -94,6 +93,9 @@ function Settings() {
|
|||||||
'/settings/logging': t`Logging`,
|
'/settings/logging': t`Logging`,
|
||||||
'/settings/logging/details': t`Details`,
|
'/settings/logging/details': t`Details`,
|
||||||
'/settings/logging/edit': t`Edit Details`,
|
'/settings/logging/edit': t`Edit Details`,
|
||||||
|
'/settings/miscellaneous_authentication': t`Miscellaneous Authentication`,
|
||||||
|
'/settings/miscellaneous_authentication/details': t`Details`,
|
||||||
|
'/settings/miscellaneous_authentication/edit': t`Edit Details`,
|
||||||
'/settings/miscellaneous_system': t`Miscellaneous System`,
|
'/settings/miscellaneous_system': t`Miscellaneous System`,
|
||||||
'/settings/miscellaneous_system/details': t`Details`,
|
'/settings/miscellaneous_system/details': t`Details`,
|
||||||
'/settings/miscellaneous_system/edit': t`Edit Details`,
|
'/settings/miscellaneous_system/edit': t`Edit Details`,
|
||||||
@@ -142,9 +144,6 @@ function Settings() {
|
|||||||
<SettingsProvider value={result}>
|
<SettingsProvider value={result}>
|
||||||
<ScreenHeader streamType="setting" breadcrumbConfig={breadcrumbConfig} />
|
<ScreenHeader streamType="setting" breadcrumbConfig={breadcrumbConfig} />
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/settings/activity_stream">
|
|
||||||
<ActivityStream />
|
|
||||||
</Route>
|
|
||||||
<Route path="/settings/azure">
|
<Route path="/settings/azure">
|
||||||
<AzureAD />
|
<AzureAD />
|
||||||
</Route>
|
</Route>
|
||||||
@@ -170,6 +169,9 @@ function Settings() {
|
|||||||
<Route path="/settings/logging">
|
<Route path="/settings/logging">
|
||||||
<Logging />
|
<Logging />
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route path="/settings/miscellaneous_authentication">
|
||||||
|
<MiscAuthentication />
|
||||||
|
</Route>
|
||||||
<Route path="/settings/miscellaneous_system">
|
<Route path="/settings/miscellaneous_system">
|
||||||
<MiscSystem />
|
<MiscSystem />
|
||||||
</Route>
|
</Route>
|
||||||
|
|||||||
@@ -51,18 +51,23 @@ function TACACSEdit() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await SettingsAPI.revertCategory('tacacsplus');
|
||||||
|
}, []),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
const handleSubmit = async form => {
|
||||||
await submitForm(form);
|
await submitForm(form);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const handleRevertAll = async () => {
|
||||||
const defaultValues = Object.assign(
|
await revertAll();
|
||||||
...Object.entries(tacacs).map(([key, value]) => ({
|
|
||||||
[key]: value.default,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push('/settings/tacacs/details');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -107,6 +112,7 @@ function TACACSEdit() {
|
|||||||
config={tacacs.TACACSPLUS_AUTH_PROTOCOL}
|
config={tacacs.TACACSPLUS_AUTH_PROTOCOL}
|
||||||
/>
|
/>
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
</FormColumnLayout>
|
</FormColumnLayout>
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ describe('<TACACSEdit />', () => {
|
|||||||
let history;
|
let history;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
@@ -68,7 +69,7 @@ describe('<TACACSEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -83,14 +84,8 @@ describe('<TACACSEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('tacacsplus');
|
||||||
TACACSPLUS_HOST: '',
|
|
||||||
TACACSPLUS_PORT: 49,
|
|
||||||
TACACSPLUS_SECRET: '',
|
|
||||||
TACACSPLUS_SESSION_TIMEOUT: 5,
|
|
||||||
TACACSPLUS_AUTH_PROTOCOL: 'ascii',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
@@ -65,18 +65,26 @@ function UIEdit() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { error: revertError, request: revertAll } = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await SettingsAPI.revertCategory('ui');
|
||||||
|
}, []),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const handleSubmit = async form => {
|
const handleSubmit = async form => {
|
||||||
await submitForm(form);
|
await submitForm(form);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRevertAll = async () => {
|
const handleRevertAll = async () => {
|
||||||
const defaultValues = Object.assign(
|
await revertAll();
|
||||||
...Object.entries(uiData).map(([key, value]) => ({
|
|
||||||
[key]: value.default,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
await submitForm(defaultValues);
|
|
||||||
closeModal();
|
closeModal();
|
||||||
|
|
||||||
|
history.push({
|
||||||
|
pathname: '/settings/ui/details',
|
||||||
|
hardReload: true,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
@@ -115,6 +123,7 @@ function UIEdit() {
|
|||||||
type="dataURL"
|
type="dataURL"
|
||||||
/>
|
/>
|
||||||
{submitError && <FormSubmitError error={submitError} />}
|
{submitError && <FormSubmitError error={submitError} />}
|
||||||
|
{revertError && <FormSubmitError error={revertError} />}
|
||||||
</FormColumnLayout>
|
</FormColumnLayout>
|
||||||
<RevertFormActionGroup
|
<RevertFormActionGroup
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ describe('<UIEdit />', () => {
|
|||||||
let history;
|
let history;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
SettingsAPI.revertCategory.mockResolvedValue({});
|
||||||
SettingsAPI.updateAll.mockResolvedValue({});
|
SettingsAPI.updateAll.mockResolvedValue({});
|
||||||
SettingsAPI.readCategory.mockResolvedValue({
|
SettingsAPI.readCategory.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
@@ -62,7 +63,7 @@ describe('<UIEdit />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send default values to api on form revert all', async () => {
|
test('should successfully send default values to api on form revert all', async () => {
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(0);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(0);
|
||||||
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
expect(wrapper.find('RevertAllAlert')).toHaveLength(0);
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
wrapper
|
wrapper
|
||||||
@@ -77,12 +78,8 @@ describe('<UIEdit />', () => {
|
|||||||
.invoke('onClick')();
|
.invoke('onClick')();
|
||||||
});
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
|
||||||
expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
|
expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('ui');
|
||||||
CUSTOM_LOGIN_INFO: '',
|
|
||||||
CUSTOM_LOGO: '',
|
|
||||||
PENDO_TRACKING_STATE: 'off',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully send request to api on form submission', async () => {
|
test('should successfully send request to api on form submission', async () => {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user