diff --git a/awx/ui_next/src/api/models/Settings.js b/awx/ui_next/src/api/models/Settings.js
index 55babf213d..b5d0679e9c 100644
--- a/awx/ui_next/src/api/models/Settings.js
+++ b/awx/ui_next/src/api/models/Settings.js
@@ -29,6 +29,10 @@ class Settings extends Base {
createTest(category, data) {
return this.http.post(`${this.baseUrl}${category}/test/`, data);
}
+
+ revertCategory(category) {
+ return this.http.delete(`${this.baseUrl}${category}/`);
+ }
}
export default Settings;
diff --git a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamDetail/ActivityStreamDetail.test.jsx b/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamDetail/ActivityStreamDetail.test.jsx
deleted file mode 100644
index 2bcc60701b..0000000000
--- a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamDetail/ActivityStreamDetail.test.jsx
+++ /dev/null
@@ -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('', () => {
- let wrapper;
-
- beforeAll(async () => {
- SettingsAPI.readCategory.mockResolvedValue({
- data: {
- ACTIVITY_STREAM_ENABLED: true,
- ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC: false,
- },
- });
- await act(async () => {
- wrapper = mountWithContexts(
-
-
-
- );
- });
- 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(
-
-
- ,
- {
- 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(
-
-
-
- );
- });
- await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
- expect(wrapper.find('ContentError').length).toBe(1);
- });
-});
diff --git a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamDetail/index.js b/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamDetail/index.js
deleted file mode 100644
index 442e39b0e7..0000000000
--- a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamDetail/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './ActivityStreamDetail';
diff --git a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamEdit/ActivityStreamEdit.jsx b/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamEdit/ActivityStreamEdit.jsx
deleted file mode 100644
index 489979c748..0000000000
--- a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamEdit/ActivityStreamEdit.jsx
+++ /dev/null
@@ -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 (
-
- {isLoading && }
- {!isLoading && error && }
- {!isLoading && ACTIVITY_STREAM_ENABLED && (
-
- {formik => {
- return (
-
- );
- }}
-
- )}
-
- );
-}
-
-export default ActivityStreamEdit;
diff --git a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamEdit/index.js b/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamEdit/index.js
deleted file mode 100644
index 0818b2b1a3..0000000000
--- a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamEdit/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './ActivityStreamEdit';
diff --git a/awx/ui_next/src/screens/Setting/ActivityStream/index.js b/awx/ui_next/src/screens/Setting/ActivityStream/index.js
deleted file mode 100644
index 5c0c72d9ef..0000000000
--- a/awx/ui_next/src/screens/Setting/ActivityStream/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './ActivityStream';
diff --git a/awx/ui_next/src/screens/Setting/AzureAD/AzureADEdit/AzureADEdit.jsx b/awx/ui_next/src/screens/Setting/AzureAD/AzureADEdit/AzureADEdit.jsx
index b6958388ff..e6a579c92b 100644
--- a/awx/ui_next/src/screens/Setting/AzureAD/AzureADEdit/AzureADEdit.jsx
+++ b/awx/ui_next/src/screens/Setting/AzureAD/AzureADEdit/AzureADEdit.jsx
@@ -55,6 +55,13 @@ function AzureADEdit() {
null
);
+ const { error: revertError, request: revertAll } = useRequest(
+ useCallback(async () => {
+ await SettingsAPI.revertCategory('azuread-oauth2');
+ }, []),
+ null
+ );
+
const handleSubmit = async form => {
await submitForm({
...form,
@@ -68,13 +75,11 @@ function AzureADEdit() {
};
const handleRevertAll = async () => {
- const defaultValues = Object.assign(
- ...Object.entries(azure).map(([key, value]) => ({
- [key]: value.default,
- }))
- );
- await submitForm(defaultValues);
+ await revertAll();
+
closeModal();
+
+ history.push('/settings/azure/details');
};
const handleCancel = () => {
@@ -120,6 +125,7 @@ function AzureADEdit() {
config={azure.SOCIAL_AUTH_AZUREAD_OAUTH2_TEAM_MAP}
/>
{submitError && }
+ {revertError && }
', () => {
let history;
beforeEach(() => {
+ SettingsAPI.revertCategory.mockResolvedValue({});
SettingsAPI.updateAll.mockResolvedValue({});
SettingsAPI.readCategory.mockResolvedValue({
data: {
@@ -60,7 +61,7 @@ describe('', () => {
});
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);
await act(async () => {
wrapper
@@ -75,13 +76,8 @@ describe('', () => {
.invoke('onClick')();
});
wrapper.update();
- expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
- expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
- SOCIAL_AUTH_AZUREAD_OAUTH2_KEY: '',
- SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET: '',
- SOCIAL_AUTH_AZUREAD_OAUTH2_ORGANIZATION_MAP: null,
- SOCIAL_AUTH_AZUREAD_OAUTH2_TEAM_MAP: null,
- });
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('azuread-oauth2');
});
test('should successfully send request to api on form submission', async () => {
diff --git a/awx/ui_next/src/screens/Setting/GitHub/GitHubEdit/GitHubEdit.jsx b/awx/ui_next/src/screens/Setting/GitHub/GitHubEdit/GitHubEdit.jsx
index f1b562043d..2e6c958936 100644
--- a/awx/ui_next/src/screens/Setting/GitHub/GitHubEdit/GitHubEdit.jsx
+++ b/awx/ui_next/src/screens/Setting/GitHub/GitHubEdit/GitHubEdit.jsx
@@ -55,6 +55,13 @@ function GitHubEdit() {
null
);
+ const { error: revertError, request: revertAll } = useRequest(
+ useCallback(async () => {
+ await SettingsAPI.revertCategory('github');
+ }, []),
+ null
+ );
+
const handleSubmit = async form => {
await submitForm({
...form,
@@ -66,13 +73,11 @@ function GitHubEdit() {
};
const handleRevertAll = async () => {
- const defaultValues = Object.assign(
- ...Object.entries(github).map(([key, value]) => ({
- [key]: value.default,
- }))
- );
- await submitForm(defaultValues);
+ await revertAll();
+
closeModal();
+
+ history.push('/settings/github/details');
};
const handleCancel = () => {
@@ -118,6 +123,7 @@ function GitHubEdit() {
config={github.SOCIAL_AUTH_GITHUB_TEAM_MAP}
/>
{submitError && }
+ {revertError && }
', () => {
let history;
beforeEach(() => {
+ SettingsAPI.revertCategory.mockResolvedValue({});
SettingsAPI.updateAll.mockResolvedValue({});
SettingsAPI.readCategory.mockResolvedValue({
data: {
@@ -72,7 +73,7 @@ describe('', () => {
});
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);
await act(async () => {
wrapper
@@ -87,13 +88,8 @@ describe('', () => {
.invoke('onClick')();
});
wrapper.update();
- expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
- expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
- SOCIAL_AUTH_GITHUB_KEY: '',
- SOCIAL_AUTH_GITHUB_SECRET: '',
- SOCIAL_AUTH_GITHUB_ORGANIZATION_MAP: null,
- SOCIAL_AUTH_GITHUB_TEAM_MAP: null,
- });
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('github');
});
test('should successfully send request to api on form submission', async () => {
diff --git a/awx/ui_next/src/screens/Setting/GitHub/GitHubEnterpriseEdit/GitHubEnterpriseEdit.jsx b/awx/ui_next/src/screens/Setting/GitHub/GitHubEnterpriseEdit/GitHubEnterpriseEdit.jsx
index 3d6ee60c3e..76c4060037 100644
--- a/awx/ui_next/src/screens/Setting/GitHub/GitHubEnterpriseEdit/GitHubEnterpriseEdit.jsx
+++ b/awx/ui_next/src/screens/Setting/GitHub/GitHubEnterpriseEdit/GitHubEnterpriseEdit.jsx
@@ -55,6 +55,13 @@ function GitHubEnterpriseEdit() {
null
);
+ const { error: revertError, request: revertAll } = useRequest(
+ useCallback(async () => {
+ await SettingsAPI.revertCategory('github-enterprise');
+ }, []),
+ null
+ );
+
const handleSubmit = async form => {
await submitForm({
...form,
@@ -68,13 +75,11 @@ function GitHubEnterpriseEdit() {
};
const handleRevertAll = async () => {
- const defaultValues = Object.assign(
- ...Object.entries(github).map(([key, value]) => ({
- [key]: value.default,
- }))
- );
- await submitForm(defaultValues);
+ await revertAll();
+
closeModal();
+
+ history.push('/settings/github/enterprise/details');
};
const handleCancel = () => {
@@ -128,6 +133,7 @@ function GitHubEnterpriseEdit() {
config={github.SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_MAP}
/>
{submitError && }
+ {revertError && }
', () => {
let history;
beforeEach(() => {
+ SettingsAPI.revertCategory.mockResolvedValue({});
SettingsAPI.updateAll.mockResolvedValue({});
SettingsAPI.readCategory.mockResolvedValue({
data: {
@@ -82,7 +83,7 @@ describe('', () => {
});
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);
await act(async () => {
wrapper
@@ -97,15 +98,10 @@ describe('', () => {
.invoke('onClick')();
});
wrapper.update();
- expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
- expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
- SOCIAL_AUTH_GITHUB_ENTERPRISE_URL: '',
- 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,
- });
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledWith(
+ 'github-enterprise'
+ );
});
test('should successfully send request to api on form submission', async () => {
diff --git a/awx/ui_next/src/screens/Setting/GitHub/GitHubEnterpriseOrgEdit/GitHubEnterpriseOrgEdit.jsx b/awx/ui_next/src/screens/Setting/GitHub/GitHubEnterpriseOrgEdit/GitHubEnterpriseOrgEdit.jsx
index 272b1866ff..274468e6fe 100644
--- a/awx/ui_next/src/screens/Setting/GitHub/GitHubEnterpriseOrgEdit/GitHubEnterpriseOrgEdit.jsx
+++ b/awx/ui_next/src/screens/Setting/GitHub/GitHubEnterpriseOrgEdit/GitHubEnterpriseOrgEdit.jsx
@@ -55,6 +55,13 @@ function GitHubEnterpriseOrgEdit() {
null
);
+ const { error: revertError, request: revertAll } = useRequest(
+ useCallback(async () => {
+ await SettingsAPI.revertCategory('github-enterprise-org');
+ }, []),
+ null
+ );
+
const handleSubmit = async form => {
await submitForm({
...form,
@@ -68,13 +75,11 @@ function GitHubEnterpriseOrgEdit() {
};
const handleRevertAll = async () => {
- const defaultValues = Object.assign(
- ...Object.entries(github).map(([key, value]) => ({
- [key]: value.default,
- }))
- );
- await submitForm(defaultValues);
+ await revertAll();
+
closeModal();
+
+ history.push('/settings/github/enterprise_organization/details');
};
const handleCancel = () => {
@@ -134,6 +139,7 @@ function GitHubEnterpriseOrgEdit() {
config={github.SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_TEAM_MAP}
/>
{submitError && }
+ {revertError && }
', () => {
let history;
beforeEach(() => {
+ SettingsAPI.revertCategory.mockResolvedValue({});
SettingsAPI.updateAll.mockResolvedValue({});
SettingsAPI.readCategory.mockResolvedValue({
data: {
@@ -94,7 +95,7 @@ describe('', () => {
});
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);
await act(async () => {
wrapper
@@ -109,16 +110,10 @@ describe('', () => {
.invoke('onClick')();
});
wrapper.update();
- expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
- expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
- SOCIAL_AUTH_GITHUB_ENTERPRISE_ORG_URL: '',
- 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,
- });
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledWith(
+ 'github-enterprise-org'
+ );
});
test('should successfully send request to api on form submission', async () => {
diff --git a/awx/ui_next/src/screens/Setting/GitHub/GitHubEnterpriseTeamEdit/GitHubEnterpriseTeamEdit.jsx b/awx/ui_next/src/screens/Setting/GitHub/GitHubEnterpriseTeamEdit/GitHubEnterpriseTeamEdit.jsx
index d9b725dc13..f245c2e61d 100644
--- a/awx/ui_next/src/screens/Setting/GitHub/GitHubEnterpriseTeamEdit/GitHubEnterpriseTeamEdit.jsx
+++ b/awx/ui_next/src/screens/Setting/GitHub/GitHubEnterpriseTeamEdit/GitHubEnterpriseTeamEdit.jsx
@@ -55,6 +55,13 @@ function GitHubEnterpriseTeamEdit() {
null
);
+ const { error: revertError, request: revertAll } = useRequest(
+ useCallback(async () => {
+ await SettingsAPI.revertCategory('github-enterprise-team');
+ }, []),
+ null
+ );
+
const handleSubmit = async form => {
await submitForm({
...form,
@@ -68,13 +75,11 @@ function GitHubEnterpriseTeamEdit() {
};
const handleRevertAll = async () => {
- const defaultValues = Object.assign(
- ...Object.entries(github).map(([key, value]) => ({
- [key]: value.default,
- }))
- );
- await submitForm(defaultValues);
+ await revertAll();
+
closeModal();
+
+ history.push('/settings/github/enterprise_team/details');
};
const handleCancel = () => {
@@ -134,6 +139,7 @@ function GitHubEnterpriseTeamEdit() {
config={github.SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_TEAM_MAP}
/>
{submitError && }
+ {revertError && }
', () => {
let history;
beforeEach(() => {
+ SettingsAPI.revertCategory.mockResolvedValue({});
SettingsAPI.updateAll.mockResolvedValue({});
SettingsAPI.readCategory.mockResolvedValue({
data: {
@@ -88,7 +89,7 @@ describe('', () => {
});
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);
await act(async () => {
wrapper
@@ -103,16 +104,10 @@ describe('', () => {
.invoke('onClick')();
});
wrapper.update();
- expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
- expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
- SOCIAL_AUTH_GITHUB_ENTERPRISE_TEAM_URL: '',
- 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,
- });
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledWith(
+ 'github-enterprise-team'
+ );
});
test('should successfully send request to api on form submission', async () => {
diff --git a/awx/ui_next/src/screens/Setting/GitHub/GitHubOrgEdit/GitHubOrgEdit.jsx b/awx/ui_next/src/screens/Setting/GitHub/GitHubOrgEdit/GitHubOrgEdit.jsx
index 6224acb5b7..8a14272467 100644
--- a/awx/ui_next/src/screens/Setting/GitHub/GitHubOrgEdit/GitHubOrgEdit.jsx
+++ b/awx/ui_next/src/screens/Setting/GitHub/GitHubOrgEdit/GitHubOrgEdit.jsx
@@ -55,6 +55,13 @@ function GitHubOrgEdit() {
null
);
+ const { error: revertError, request: revertAll } = useRequest(
+ useCallback(async () => {
+ await SettingsAPI.revertCategory('github-org');
+ }, []),
+ null
+ );
+
const handleSubmit = async form => {
await submitForm({
...form,
@@ -68,13 +75,11 @@ function GitHubOrgEdit() {
};
const handleRevertAll = async () => {
- const defaultValues = Object.assign(
- ...Object.entries(github).map(([key, value]) => ({
- [key]: value.default,
- }))
- );
- await submitForm(defaultValues);
+ await revertAll();
+
closeModal();
+
+ history.push('/settings/github/organization/details');
};
const handleCancel = () => {
@@ -124,6 +129,7 @@ function GitHubOrgEdit() {
config={github.SOCIAL_AUTH_GITHUB_ORG_TEAM_MAP}
/>
{submitError && }
+ {revertError && }
', () => {
let history;
beforeEach(() => {
+ SettingsAPI.revertCategory.mockResolvedValue({});
SettingsAPI.updateAll.mockResolvedValue({});
SettingsAPI.readCategory.mockResolvedValue({
data: {
@@ -79,7 +80,7 @@ describe('', () => {
});
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);
await act(async () => {
wrapper
@@ -94,14 +95,8 @@ describe('', () => {
.invoke('onClick')();
});
wrapper.update();
- expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
- expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
- 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,
- });
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('github-org');
});
test('should successfully send request to api on form submission', async () => {
diff --git a/awx/ui_next/src/screens/Setting/GitHub/GitHubTeamEdit/GitHubTeamEdit.jsx b/awx/ui_next/src/screens/Setting/GitHub/GitHubTeamEdit/GitHubTeamEdit.jsx
index f898539283..d49673982e 100644
--- a/awx/ui_next/src/screens/Setting/GitHub/GitHubTeamEdit/GitHubTeamEdit.jsx
+++ b/awx/ui_next/src/screens/Setting/GitHub/GitHubTeamEdit/GitHubTeamEdit.jsx
@@ -55,6 +55,13 @@ function GitHubTeamEdit() {
null
);
+ const { error: revertError, request: revertAll } = useRequest(
+ useCallback(async () => {
+ await SettingsAPI.revertCategory('github-team');
+ }, []),
+ null
+ );
+
const handleSubmit = async form => {
await submitForm({
...form,
@@ -68,13 +75,11 @@ function GitHubTeamEdit() {
};
const handleRevertAll = async () => {
- const defaultValues = Object.assign(
- ...Object.entries(github).map(([key, value]) => ({
- [key]: value.default,
- }))
- );
- await submitForm(defaultValues);
+ await revertAll();
+
closeModal();
+
+ history.push('/settings/github/team/details');
};
const handleCancel = () => {
@@ -124,6 +129,7 @@ function GitHubTeamEdit() {
config={github.SOCIAL_AUTH_GITHUB_TEAM_TEAM_MAP}
/>
{submitError && }
+ {revertError && }
', () => {
let history;
beforeEach(() => {
+ SettingsAPI.revertCategory.mockResolvedValue({});
SettingsAPI.updateAll.mockResolvedValue({});
SettingsAPI.readCategory.mockResolvedValue({
data: {
@@ -74,7 +75,7 @@ describe('', () => {
});
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);
await act(async () => {
wrapper
@@ -89,14 +90,8 @@ describe('', () => {
.invoke('onClick')();
});
wrapper.update();
- expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
- expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
- 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,
- });
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('github-team');
});
test('should successfully send request to api on form submission', async () => {
diff --git a/awx/ui_next/src/screens/Setting/GoogleOAuth2/GoogleOAuth2Edit/GoogleOAuth2Edit.jsx b/awx/ui_next/src/screens/Setting/GoogleOAuth2/GoogleOAuth2Edit/GoogleOAuth2Edit.jsx
index ebc6f3d662..8bedb9095a 100644
--- a/awx/ui_next/src/screens/Setting/GoogleOAuth2/GoogleOAuth2Edit/GoogleOAuth2Edit.jsx
+++ b/awx/ui_next/src/screens/Setting/GoogleOAuth2/GoogleOAuth2Edit/GoogleOAuth2Edit.jsx
@@ -60,6 +60,13 @@ function GoogleOAuth2Edit() {
null
);
+ const { error: revertError, request: revertAll } = useRequest(
+ useCallback(async () => {
+ await SettingsAPI.revertCategory('google-oauth2');
+ }, []),
+ null
+ );
+
const handleSubmit = async form => {
await submitForm({
...form,
@@ -79,13 +86,11 @@ function GoogleOAuth2Edit() {
};
const handleRevertAll = async () => {
- const defaultValues = Object.assign(
- ...Object.entries(googleOAuth2).map(([key, value]) => ({
- [key]: value.default,
- }))
- );
- await submitForm(defaultValues);
+ await revertAll();
+
closeModal();
+
+ history.push('/settings/google_oauth2/details');
};
const handleCancel = () => {
@@ -148,6 +153,7 @@ function GoogleOAuth2Edit() {
config={googleOAuth2.SOCIAL_AUTH_GOOGLE_OAUTH2_TEAM_MAP}
/>
{submitError && }
+ {revertError && }
', () => {
let history;
beforeEach(() => {
+ SettingsAPI.revertCategory.mockResolvedValue({});
SettingsAPI.updateAll.mockResolvedValue({});
SettingsAPI.readCategory.mockResolvedValue({
data: {
@@ -82,7 +83,7 @@ describe('', () => {
});
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);
await act(async () => {
wrapper
@@ -97,15 +98,8 @@ describe('', () => {
.invoke('onClick')();
});
wrapper.update();
- expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
- expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
- 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,
- });
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('google-oauth2');
});
test('should successfully send request to api on form submission', async () => {
diff --git a/awx/ui_next/src/screens/Setting/Jobs/JobsEdit/JobsEdit.jsx b/awx/ui_next/src/screens/Setting/Jobs/JobsEdit/JobsEdit.jsx
index 7ba1e96f51..2d92b456c2 100644
--- a/awx/ui_next/src/screens/Setting/Jobs/JobsEdit/JobsEdit.jsx
+++ b/awx/ui_next/src/screens/Setting/Jobs/JobsEdit/JobsEdit.jsx
@@ -63,6 +63,13 @@ function JobsEdit() {
null
);
+ const { error: revertError, request: revertAll } = useRequest(
+ useCallback(async () => {
+ await SettingsAPI.revertCategory('jobs');
+ }, []),
+ null
+ );
+
const handleSubmit = async form => {
await submitForm({
...form,
@@ -76,12 +83,11 @@ function JobsEdit() {
};
const handleRevertAll = async () => {
- const defaultValues = {};
- Object.entries(jobs).forEach(([key, value]) => {
- defaultValues[key] = value.default;
- });
- await submitForm(defaultValues);
+ await revertAll();
+
closeModal();
+
+ history.push('/settings/jobs/details');
};
const handleCancel = () => {
@@ -181,6 +187,7 @@ function JobsEdit() {
/>
{submitError && }
+ {revertError && }
', () => {
let history;
beforeEach(() => {
+ SettingsAPI.revertCategory.mockResolvedValue({});
SettingsAPI.updateAll.mockResolvedValue({});
SettingsAPI.readCategory.mockResolvedValue({
data: mockJobSettings,
@@ -51,7 +51,7 @@ describe('', () => {
});
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);
await act(async () => {
wrapper
@@ -66,8 +66,8 @@ describe('', () => {
.invoke('onClick')();
});
wrapper.update();
- expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
- expect(SettingsAPI.updateAll).toHaveBeenCalledWith(mockDefaultJobSettings);
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('jobs');
});
test('should successfully send request to api on form submission', async () => {
diff --git a/awx/ui_next/src/screens/Setting/Logging/LoggingEdit/LoggingEdit.jsx b/awx/ui_next/src/screens/Setting/Logging/LoggingEdit/LoggingEdit.jsx
index 6a292cbb38..fd403b67f8 100644
--- a/awx/ui_next/src/screens/Setting/Logging/LoggingEdit/LoggingEdit.jsx
+++ b/awx/ui_next/src/screens/Setting/Logging/LoggingEdit/LoggingEdit.jsx
@@ -75,14 +75,19 @@ function LoggingEdit() {
});
};
- const handleRevertAll = async () => {
- const defaultValues = {};
- Object.entries(logging).forEach(([key, value]) => {
- defaultValues[key] = value.default;
- });
+ const { error: revertError, request: revertAll } = useRequest(
+ useCallback(async () => {
+ await SettingsAPI.revertCategory('logging');
+ }, []),
+ null
+ );
+
+ const handleRevertAll = async () => {
+ await revertAll();
- await submitForm(defaultValues);
closeModal();
+
+ history.push('/settings/logging/details');
};
const {
@@ -221,6 +226,7 @@ function LoggingEdit() {
config={logging.LOG_AGGREGATOR_LOGGERS}
/>
{submitError && }
+ {revertError && }
', () => {
let wrapper;
@@ -68,6 +45,7 @@ describe('', () => {
});
beforeEach(async () => {
+ SettingsAPI.revertCategory.mockResolvedValue({});
SettingsAPI.updateAll.mockResolvedValue({});
SettingsAPI.readCategory.mockResolvedValue({
data: mockSettings,
@@ -227,7 +205,7 @@ describe('', () => {
});
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);
await act(async () => {
wrapper
@@ -242,8 +220,8 @@ describe('', () => {
.invoke('onClick')();
});
wrapper.update();
- expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
- expect(SettingsAPI.updateAll).toHaveBeenCalledWith(mockDefaultSettings);
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('logging');
});
test('should successfully send request to api on form submission', async () => {
diff --git a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStream.jsx b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthentication.jsx
similarity index 70%
rename from awx/ui_next/src/screens/Setting/ActivityStream/ActivityStream.jsx
rename to awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthentication.jsx
index 3be6063096..bdff141ad8 100644
--- a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStream.jsx
+++ b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthentication.jsx
@@ -1,15 +1,14 @@
import React from 'react';
import { Link, Redirect, Route, Switch } from 'react-router-dom';
-
import { t } from '@lingui/macro';
import { PageSection, Card } from '@patternfly/react-core';
import ContentError from '../../../components/ContentError';
import { useConfig } from '../../../contexts/Config';
-import ActivityStreamDetail from './ActivityStreamDetail';
-import ActivityStreamEdit from './ActivityStreamEdit';
+import MiscAuthenticationDetail from './MiscAuthenticationDetail';
+import MiscAuthenticationEdit from './MiscAuthenticationEdit';
-function ActivityStream() {
- const baseURL = '/settings/activity_stream';
+function MiscAuthentication() {
+ const baseURL = '/settings/miscellaneous_authentication';
const { me } = useConfig();
return (
@@ -18,11 +17,11 @@ function ActivityStream() {
-
+
{me?.is_superuser ? (
-
+
) : (
)}
@@ -30,7 +29,7 @@ function ActivityStream() {
- {t`View Activity Stream settings`}
+ {t`View Miscellaneous Authentication settings`}
@@ -40,4 +39,4 @@ function ActivityStream() {
);
}
-export default ActivityStream;
+export default MiscAuthentication;
diff --git a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStream.test.jsx b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthentication.test.jsx
similarity index 51%
rename from awx/ui_next/src/screens/Setting/ActivityStream/ActivityStream.test.jsx
rename to awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthentication.test.jsx
index 14b698cefb..6d23d24933 100644
--- a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStream.test.jsx
+++ b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthentication.test.jsx
@@ -5,55 +5,57 @@ import {
mountWithContexts,
waitForElement,
} from '../../../../testUtils/enzymeHelpers';
-import ActivityStream from './ActivityStream';
import { SettingsAPI } from '../../../api';
+import MiscAuthentication from './MiscAuthentication';
-jest.mock('../../../api/models/Settings');
-SettingsAPI.readCategory.mockResolvedValue({
- data: {
- ACTIVITY_STREAM_ENABLED: true,
- ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC: false,
- },
-});
+jest.mock('../../../api');
-describe('', () => {
+describe('', () => {
let wrapper;
+ beforeEach(() => {
+ SettingsAPI.readCategory.mockResolvedValue({
+ data: {},
+ });
+ });
+
afterEach(() => {
wrapper.unmount();
jest.clearAllMocks();
});
- test('should render activity stream details', async () => {
+ test('should render miscellaneous authentication details', async () => {
const history = createMemoryHistory({
- initialEntries: ['/settings/activity_stream/details'],
+ initialEntries: ['/settings/miscellaneous_authentication/details'],
});
await act(async () => {
- wrapper = mountWithContexts(, {
+ wrapper = mountWithContexts(, {
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({
- initialEntries: ['/settings/activity_stream/edit'],
+ initialEntries: ['/settings/miscellaneous_authentication/edit'],
});
await act(async () => {
- wrapper = mountWithContexts(, {
+ wrapper = mountWithContexts(, {
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 () => {
const history = createMemoryHistory({
- initialEntries: ['/settings/activity_stream/foo'],
+ initialEntries: ['/settings/miscellaneous_authentication/foo'],
});
await act(async () => {
- wrapper = mountWithContexts(, {
+ wrapper = mountWithContexts(, {
context: { router: { history } },
});
});
@@ -62,10 +64,10 @@ describe('', () => {
test('should redirect to details for users without system admin permissions', async () => {
const history = createMemoryHistory({
- initialEntries: ['/settings/activity_stream/edit'],
+ initialEntries: ['/settings/miscellaneous_authentication/edit'],
});
await act(async () => {
- wrapper = mountWithContexts(, {
+ wrapper = mountWithContexts(, {
context: {
router: {
history,
@@ -79,7 +81,7 @@ describe('', () => {
});
});
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
- expect(wrapper.find('ActivityStreamDetail').length).toBe(1);
- expect(wrapper.find('ActivityStreamEdit').length).toBe(0);
+ expect(wrapper.find('MiscAuthenticationDetail').length).toBe(1);
+ expect(wrapper.find('MiscAuthenticationEdit').length).toBe(0);
});
});
diff --git a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamDetail/ActivityStreamDetail.jsx b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationDetail/MiscAuthenticationDetail.jsx
similarity index 74%
rename from awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamDetail/ActivityStreamDetail.jsx
rename to awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationDetail/MiscAuthenticationDetail.jsx
index b63e1ac96b..dd3f1b655e 100644
--- a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamDetail/ActivityStreamDetail.jsx
+++ b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationDetail/MiscAuthenticationDetail.jsx
@@ -1,36 +1,27 @@
import React, { useEffect, useCallback } from 'react';
import { Link } from 'react-router-dom';
-
import { t } from '@lingui/macro';
-import { CaretLeftIcon } from '@patternfly/react-icons';
import { Button } from '@patternfly/react-core';
+import { CaretLeftIcon } from '@patternfly/react-icons';
import { CardBody, CardActionsRow } from '../../../../components/Card';
import ContentLoading from '../../../../components/ContentLoading';
import ContentError from '../../../../components/ContentError';
import { DetailList } from '../../../../components/DetailList';
import RoutedTabs from '../../../../components/RoutedTabs';
-import useRequest from '../../../../util/useRequest';
import { useConfig } from '../../../../contexts/Config';
import { useSettings } from '../../../../contexts/Settings';
+import useRequest from '../../../../util/useRequest';
import { SettingsAPI } from '../../../../api';
import { SettingDetail } from '../../shared';
-function ActivityStreamDetail() {
+function MiscAuthenticationDetail() {
const { me } = useConfig();
const { GET: options } = useSettings();
- const { isLoading, error, request, result: activityStream } = useRequest(
+ const { isLoading, error, request, result: authentication } = useRequest(
useCallback(async () => {
- const {
- data: {
- ACTIVITY_STREAM_ENABLED,
- ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC,
- },
- } = await SettingsAPI.readCategory('system');
- return {
- ACTIVITY_STREAM_ENABLED,
- ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC,
- };
+ const { data } = await SettingsAPI.readCategory('authentication');
+ return data;
}, []),
null
);
@@ -52,7 +43,7 @@ function ActivityStreamDetail() {
},
{
name: t`Details`,
- link: `/settings/activity_stream/details`,
+ link: `/settings/miscellaneous_authentication/details`,
id: 0,
},
];
@@ -63,9 +54,9 @@ function ActivityStreamDetail() {
{isLoading && }
{!isLoading && error && }
- {!isLoading && activityStream && (
+ {!isLoading && authentication && (
- {Object.keys(activityStream).map(key => {
+ {Object.keys(authentication).map(key => {
const record = options?.[key];
return (
);
})}
@@ -84,10 +75,10 @@ function ActivityStreamDetail() {
{me?.is_superuser && (
@@ -98,4 +89,4 @@ function ActivityStreamDetail() {
);
}
-export default ActivityStreamDetail;
+export default MiscAuthenticationDetail;
diff --git a/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationDetail/MiscAuthenticationDetail.test.jsx b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationDetail/MiscAuthenticationDetail.test.jsx
new file mode 100644
index 0000000000..3f25df44e4
--- /dev/null
+++ b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationDetail/MiscAuthenticationDetail.test.jsx
@@ -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('', () => {
+ 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(
+
+
+
+ );
+ });
+ 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(
+
+
+ ,
+ {
+ 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(
+
+
+
+ );
+ });
+ await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
+ expect(wrapper.find('ContentError').length).toBe(1);
+ });
+});
diff --git a/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationDetail/index.js b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationDetail/index.js
new file mode 100644
index 0000000000..805d3d480b
--- /dev/null
+++ b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationDetail/index.js
@@ -0,0 +1 @@
+export { default } from './MiscAuthenticationDetail';
diff --git a/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/MiscAuthenticationEdit.jsx b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/MiscAuthenticationEdit.jsx
new file mode 100644
index 0000000000..6c748440d9
--- /dev/null
+++ b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/MiscAuthenticationEdit.jsx
@@ -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 (
+
+ {isLoading && }
+ {!isLoading && error && }
+ {!isLoading && authentication && (
+
+ {formik => (
+
+ )}
+
+ )}
+
+ );
+}
+
+export default MiscAuthenticationEdit;
diff --git a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamEdit/ActivityStreamEdit.test.jsx b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/MiscAuthenticationEdit.test.jsx
similarity index 62%
rename from awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamEdit/ActivityStreamEdit.test.jsx
rename to awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/MiscAuthenticationEdit.test.jsx
index 356dfcb61d..516553f55c 100644
--- a/awx/ui_next/src/screens/Setting/ActivityStream/ActivityStreamEdit/ActivityStreamEdit.test.jsx
+++ b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/MiscAuthenticationEdit.test.jsx
@@ -6,36 +6,55 @@ import {
waitForElement,
} from '../../../../../testUtils/enzymeHelpers';
import mockAllOptions from '../../shared/data.allSettingOptions.json';
+import mockAllSettings from '../../shared/data.allSettings.json';
import { SettingsProvider } from '../../../../contexts/Settings';
import { SettingsAPI } from '../../../../api';
-import ActivityStreamEdit from './ActivityStreamEdit';
+import MiscAuthenticationEdit from './MiscAuthenticationEdit';
jest.mock('../../../../api');
-describe('', () => {
+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('', () => {
let wrapper;
let history;
afterEach(() => {
- wrapper.unmount();
jest.clearAllMocks();
});
beforeEach(async () => {
- history = createMemoryHistory({
- initialEntries: ['/settings/activity_stream/edit'],
- });
- SettingsAPI.readCategory.mockResolvedValue({
- data: {
- ACTIVITY_STREAM_ENABLED: false,
- ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC: true,
- },
- });
+ SettingsAPI.revertCategory.mockResolvedValue({});
SettingsAPI.updateAll.mockResolvedValue({});
+ SettingsAPI.readCategory.mockResolvedValue({
+ data: mockAllSettings,
+ });
+ history = createMemoryHistory({
+ initialEntries: ['/settings/miscellaneous_authentication/edit'],
+ });
await act(async () => {
wrapper = mountWithContexts(
-
+
,
{
context: { router: { history } },
@@ -45,54 +64,23 @@ describe('', () => {
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
});
- test('initially renders without crashing', () => {
- expect(wrapper.find('ActivityStreamEdit').length).toBe(1);
+ test('initially renders without crashing', async () => {
+ 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 () => {
- wrapper.find('button[aria-label="Cancel"]').invoke('onClick')();
- });
- 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.find('button[aria-label="Save"]').simulate('click');
});
wrapper.update();
- expect(
- wrapper.find('Switch#ACTIVITY_STREAM_ENABLED').prop('isChecked')
- ).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,
- });
+ const { AUTHENTICATION_BACKENDS, ...rest } = authenticationData;
+ expect(SettingsAPI.updateAll).toHaveBeenCalledWith(rest);
});
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);
await act(async () => {
wrapper
@@ -107,11 +95,33 @@ describe('', () => {
.invoke('onClick')();
});
wrapper.update();
- expect(SettingsAPI.updateAll).toHaveBeenCalledTimes(1);
- expect(SettingsAPI.updateAll).toHaveBeenCalledWith({
- ACTIVITY_STREAM_ENABLED: true,
- ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC: false,
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledTimes(1);
+ expect(SettingsAPI.revertCategory).toHaveBeenCalledWith('authentication');
+ });
+
+ 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 () => {
@@ -138,7 +148,7 @@ describe('', () => {
await act(async () => {
wrapper = mountWithContexts(
-
+
);
});
diff --git a/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/index.js b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/index.js
new file mode 100644
index 0000000000..56fcea40c0
--- /dev/null
+++ b/awx/ui_next/src/screens/Setting/MiscAuthentication/MiscAuthenticationEdit/index.js
@@ -0,0 +1 @@
+export { default } from './MiscAuthenticationEdit';
diff --git a/awx/ui_next/src/screens/Setting/MiscAuthentication/index.js b/awx/ui_next/src/screens/Setting/MiscAuthentication/index.js
new file mode 100644
index 0000000000..08a9ec6a11
--- /dev/null
+++ b/awx/ui_next/src/screens/Setting/MiscAuthentication/index.js
@@ -0,0 +1 @@
+export { default } from './MiscAuthentication';
diff --git a/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystem.jsx b/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystem.jsx
index a3d79809cd..ea307cf51a 100644
--- a/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystem.jsx
+++ b/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystem.jsx
@@ -1,6 +1,5 @@
import React from 'react';
import { Link, Redirect, Route, Switch } from 'react-router-dom';
-
import { t } from '@lingui/macro';
import { PageSection, Card } from '@patternfly/react-core';
import ContentError from '../../../components/ContentError';
diff --git a/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystemDetail/MiscSystemDetail.jsx b/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystemDetail/MiscSystemDetail.jsx
index de5080eec4..2e51472ea5 100644
--- a/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystemDetail/MiscSystemDetail.jsx
+++ b/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystemDetail/MiscSystemDetail.jsx
@@ -18,84 +18,49 @@ import { sortNestedDetails, pluck } from '../../shared/settingUtils';
function MiscSystemDetail() {
const { me } = useConfig();
- const { GET: allOptions } = useSettings();
+ const { GET: options } = useSettings();
const { isLoading, error, request, result: system } = useRequest(
useCallback(async () => {
- const { data } = await SettingsAPI.readCategory('all');
- let DEFAULT_EXECUTION_ENVIRONMENT = '';
+ const { data } = await SettingsAPI.readCategory('system');
if (data.DEFAULT_EXECUTION_ENVIRONMENT) {
const {
data: { name },
} = await ExecutionEnvironmentsAPI.readDetail(
data.DEFAULT_EXECUTION_ENVIRONMENT
);
- DEFAULT_EXECUTION_ENVIRONMENT = name;
+ data.DEFAULT_EXECUTION_ENVIRONMENT = name;
}
- const {
- OAUTH2_PROVIDER: {
- ACCESS_TOKEN_EXPIRE_SECONDS,
- REFRESH_TOKEN_EXPIRE_SECONDS,
- AUTHORIZATION_CODE_EXPIRE_SECONDS,
- },
- ...pluckedSystemData
- } = pluck(
+
+ const systemData = pluck(
data,
- 'ALLOW_OAUTH2_FOR_EXTERNAL_USERS',
- 'AUTH_BASIC_ENABLED',
+ 'ACTIVITY_STREAM_ENABLED',
+ 'ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC',
'AUTOMATION_ANALYTICS_GATHER_INTERVAL',
'AUTOMATION_ANALYTICS_URL',
'INSIGHTS_TRACKING_STATE',
- 'LOGIN_REDIRECT_OVERRIDE',
'MANAGE_ORGANIZATION_AUTH',
- 'DISABLE_LOCAL_AUTH',
- 'OAUTH2_PROVIDER',
'ORG_ADMINS_CAN_SEE_ALL_USERS',
- 'REDHAT_PASSWORD',
'REDHAT_USERNAME',
- 'REMOTE_HOST_HEADERS',
- 'SESSIONS_PER_USER',
- 'SESSION_COOKIE_AGE',
+ 'REDHAT_PASSWORD',
'SUBSCRIPTIONS_USERNAME',
'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 = {};
Object.keys(systemData).forEach(key => {
- mergedData[key] = systemOptions[key];
+ mergedData[key] = options[key];
mergedData[key].value = systemData[key];
});
return sortNestedDetails(mergedData);
- }, [allOptions]),
+ }, [options]),
null
);
diff --git a/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystemDetail/MiscSystemDetail.test.jsx b/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystemDetail/MiscSystemDetail.test.jsx
index 2f9dd48dff..f8fae74a08 100644
--- a/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystemDetail/MiscSystemDetail.test.jsx
+++ b/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystemDetail/MiscSystemDetail.test.jsx
@@ -22,28 +22,26 @@ describe('', () => {
SettingsAPI.readCategory = jest.fn();
SettingsAPI.readCategory.mockResolvedValue({
data: {
- ALLOW_OAUTH2_FOR_EXTERNAL_USERS: false,
- AUTH_BASIC_ENABLED: true,
- AUTOMATION_ANALYTICS_GATHER_INTERVAL: 14400,
+ ACTIVITY_STREAM_ENABLED: true,
+ ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC: false,
+ 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',
+ INSTALL_UUID: 'db39b9ec-0c6e-4554-987d-42aw9c732ed8',
+ DEFAULT_EXECUTION_ENVIRONMENT: 1,
CUSTOM_VENV_PATHS: [],
INSIGHTS_TRACKING_STATE: false,
- LOGIN_REDIRECT_OVERRIDE: 'https://redirect.com',
- MANAGE_ORGANIZATION_AUTH: true,
- DISABLE_LOCAL_AUTH: false,
- 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,
+ AUTOMATION_ANALYTICS_LAST_GATHER: null,
+ AUTOMATION_ANALYTICS_LAST_ENTRIES: 'foo',
+ AUTOMATION_ANALYTICS_GATHER_INTERVAL: 14400,
},
});
ExecutionEnvironmentsAPI.readDetail = jest.fn();
@@ -77,14 +75,17 @@ describe('', () => {
});
test('should render expected details', () => {
- assertDetail(wrapper, 'Access Token Expiration', '1 seconds');
- assertDetail(wrapper, 'All Users Visible to Organization Admins', 'On');
assertDetail(
wrapper,
- 'Allow External Users to Create OAuth2 Tokens',
- 'Off'
+ 'Unique identifier for an installation',
+ '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(
wrapper,
'Insights for Ansible Automation Platform Gather Interval',
@@ -96,32 +97,24 @@ describe('', () => {
'https://example.com'
);
assertDetail(wrapper, 'Base URL of the service', 'https://towerhost');
- assertDetail(wrapper, 'Enable HTTP Basic Auth', 'On');
assertDetail(
wrapper,
'Gather data for Insights for Ansible Automation Platform',
'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(
wrapper,
'Organization Admins Can Manage Users and Teams',
'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 username', 'mock name');
- assertDetail(wrapper, 'Refresh Token Expiration', '3 seconds');
+ assertDetail(wrapper, 'Red Hat customer username', 'name1');
+ assertDetail(wrapper, 'Red Hat or Satellite password', 'Encrypted');
+ assertDetail(wrapper, 'Red Hat or Satellite username', 'name2');
assertVariableDetail(wrapper, 'Remote Host Headers', '[]');
+ assertVariableDetail(wrapper, 'Proxy IP Allowed List', '[]');
assertDetail(wrapper, 'Global default execution environment', 'Foo');
});
diff --git a/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystemEdit/MiscSystemEdit.jsx b/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystemEdit/MiscSystemEdit.jsx
index 843a715bca..35b7a81d28 100644
--- a/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystemEdit/MiscSystemEdit.jsx
+++ b/awx/ui_next/src/screens/Setting/MiscSystem/MiscSystemEdit/MiscSystemEdit.jsx
@@ -30,76 +30,33 @@ function MiscSystemEdit() {
const { isLoading, error, request: fetchSystem, result: system } = useRequest(
useCallback(async () => {
- const { data } = await SettingsAPI.readCategory('all');
- const {
- OAUTH2_PROVIDER: {
- ACCESS_TOKEN_EXPIRE_SECONDS,
- REFRESH_TOKEN_EXPIRE_SECONDS,
- AUTHORIZATION_CODE_EXPIRE_SECONDS,
- },
- ...pluckedSystemData
- } = pluck(
+ const { data } = await SettingsAPI.readCategory('system');
+ const systemData = pluck(
data,
- 'ALLOW_OAUTH2_FOR_EXTERNAL_USERS',
- 'AUTH_BASIC_ENABLED',
+ 'ACTIVITY_STREAM_ENABLED',
+ 'ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC',
'AUTOMATION_ANALYTICS_GATHER_INTERVAL',
'AUTOMATION_ANALYTICS_URL',
+ 'AUTOMATION_ANALYTICS_LAST_ENTRIES',
'INSIGHTS_TRACKING_STATE',
- 'LOGIN_REDIRECT_OVERRIDE',
'MANAGE_ORGANIZATION_AUTH',
- 'DISABLE_LOCAL_AUTH',
- 'OAUTH2_PROVIDER',
'ORG_ADMINS_CAN_SEE_ALL_USERS',
- 'REDHAT_PASSWORD',
'REDHAT_USERNAME',
+ 'REDHAT_PASSWORD',
+ 'SUBSCRIPTIONS_USERNAME',
+ 'SUBSCRIPTIONS_PASSWORD',
'REMOTE_HOST_HEADERS',
- 'SESSIONS_PER_USER',
- 'SESSION_COOKIE_AGE',
'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 = {};
Object.keys(systemData).forEach(key => {
- if (!systemOptions[key]) {
+ if (!options[key]) {
return;
}
- mergedData[key] = systemOptions[key];
+ mergedData[key] = options[key];
mergedData[key].value = systemData[key];
});
return mergedData;
@@ -122,50 +79,29 @@ function MiscSystemEdit() {
null
);
- const handleSubmit = async form => {
- const {
- ACCESS_TOKEN_EXPIRE_SECONDS,
- REFRESH_TOKEN_EXPIRE_SECONDS,
- AUTHORIZATION_CODE_EXPIRE_SECONDS,
- ...formData
- } = form;
+ const { error: revertError, request: revertAll } = useRequest(
+ useCallback(async () => {
+ await SettingsAPI.revertCategory('system');
+ }, []),
+ null
+ );
+ const handleSubmit = async form => {
await submitForm({
- ...formData,
- REMOTE_HOST_HEADERS: formatJson(formData.REMOTE_HOST_HEADERS),
- OAUTH2_PROVIDER: {
- ACCESS_TOKEN_EXPIRE_SECONDS,
- REFRESH_TOKEN_EXPIRE_SECONDS,
- AUTHORIZATION_CODE_EXPIRE_SECONDS,
- },
+ ...form,
+ PROXY_IP_ALLOWED_LIST: formatJson(form.PROXY_IP_ALLOWED_LIST),
+ REMOTE_HOST_HEADERS: formatJson(form.REMOTE_HOST_HEADERS),
DEFAULT_EXECUTION_ENVIRONMENT:
- formData.DEFAULT_EXECUTION_ENVIRONMENT?.id || null,
+ form.DEFAULT_EXECUTION_ENVIRONMENT?.id || null,
});
};
const handleRevertAll = async () => {
- const {
- ACCESS_TOKEN_EXPIRE_SECONDS,
- REFRESH_TOKEN_EXPIRE_SECONDS,
- AUTHORIZATION_CODE_EXPIRE_SECONDS,
- ...systemData
- } = system;
+ await revertAll();
- 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();
+
+ history.push('/settings/miscellaneous_system/details');
};
const handleCancel = () => {
@@ -226,6 +162,14 @@ function MiscSystemEdit() {
return (