mirror of
https://github.com/ansible/awx.git
synced 2026-03-11 22:49:32 -02:30
Hide management job for non system admin as node choice (#12341)
Hide management job for non system admin as node type choice. Also, fix related uni-tests related to this change. See: https://github.com/ansible/awx/issues/12334 Also: https://github.com/ansible/awx/pull/10572
This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
|||||||
WorkflowDispatchContext,
|
WorkflowDispatchContext,
|
||||||
WorkflowStateContext,
|
WorkflowStateContext,
|
||||||
} from 'contexts/Workflow';
|
} from 'contexts/Workflow';
|
||||||
|
import { useUserProfile } from 'contexts/Config';
|
||||||
import {
|
import {
|
||||||
mountWithContexts,
|
mountWithContexts,
|
||||||
waitForElement,
|
waitForElement,
|
||||||
@@ -41,6 +42,17 @@ const workflowContext = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
describe('NodeEditModal', () => {
|
describe('NodeEditModal', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
useUserProfile.mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
isSuperUser: true,
|
||||||
|
isSystemAuditor: false,
|
||||||
|
isOrgAdmin: false,
|
||||||
|
isNotificationAdmin: false,
|
||||||
|
isExecEnvAdmin: false,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
test('Node modal confirmation dispatches as expected', async () => {
|
test('Node modal confirmation dispatches as expected', async () => {
|
||||||
const wrapper = mountWithContexts(
|
const wrapper = mountWithContexts(
|
||||||
<WorkflowDispatchContext.Provider value={dispatch}>
|
<WorkflowDispatchContext.Provider value={dispatch}>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
WorkflowDispatchContext,
|
WorkflowDispatchContext,
|
||||||
WorkflowStateContext,
|
WorkflowStateContext,
|
||||||
} from 'contexts/Workflow';
|
} from 'contexts/Workflow';
|
||||||
|
import { useUserProfile } from 'contexts/Config';
|
||||||
import {
|
import {
|
||||||
InventorySourcesAPI,
|
InventorySourcesAPI,
|
||||||
JobTemplatesAPI,
|
JobTemplatesAPI,
|
||||||
@@ -93,6 +94,15 @@ const mockJobTemplate = {
|
|||||||
|
|
||||||
describe('NodeModal', () => {
|
describe('NodeModal', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
useUserProfile.mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
isSuperUser: true,
|
||||||
|
isSystemAuditor: false,
|
||||||
|
isOrgAdmin: false,
|
||||||
|
isNotificationAdmin: false,
|
||||||
|
isExecEnvAdmin: false,
|
||||||
|
};
|
||||||
|
});
|
||||||
JobTemplatesAPI.read = jest.fn();
|
JobTemplatesAPI.read = jest.fn();
|
||||||
JobTemplatesAPI.read.mockResolvedValue({
|
JobTemplatesAPI.read.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
@@ -523,6 +533,17 @@ describe('NodeModal', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('Edit existing node', () => {
|
describe('Edit existing node', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
useUserProfile.mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
isSuperUser: true,
|
||||||
|
isSystemAuditor: false,
|
||||||
|
isOrgAdmin: false,
|
||||||
|
isNotificationAdmin: false,
|
||||||
|
isExecEnvAdmin: false,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
let newWrapper;
|
let newWrapper;
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import Popover from 'components/Popover';
|
|||||||
import AnsibleSelect from 'components/AnsibleSelect';
|
import AnsibleSelect from 'components/AnsibleSelect';
|
||||||
import FormField from 'components/FormField';
|
import FormField from 'components/FormField';
|
||||||
import getDocsBaseUrl from 'util/getDocsBaseUrl';
|
import getDocsBaseUrl from 'util/getDocsBaseUrl';
|
||||||
import { useConfig } from 'contexts/Config';
|
import { useConfig, useUserProfile } from 'contexts/Config';
|
||||||
import InventorySourcesList from './InventorySourcesList';
|
import InventorySourcesList from './InventorySourcesList';
|
||||||
import JobTemplatesList from './JobTemplatesList';
|
import JobTemplatesList from './JobTemplatesList';
|
||||||
import ProjectsList from './ProjectsList';
|
import ProjectsList from './ProjectsList';
|
||||||
@@ -44,6 +44,7 @@ const TimeoutLabel = styled.p`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
function NodeTypeStep({ isIdentifierRequired }) {
|
function NodeTypeStep({ isIdentifierRequired }) {
|
||||||
|
const { isSuperUser } = useUserProfile();
|
||||||
const [nodeTypeField, , nodeTypeHelpers] = useField('nodeType');
|
const [nodeTypeField, , nodeTypeHelpers] = useField('nodeType');
|
||||||
const [nodeResourceField, nodeResourceMeta, nodeResourceHelpers] =
|
const [nodeResourceField, nodeResourceMeta, nodeResourceHelpers] =
|
||||||
useField('nodeResource');
|
useField('nodeResource');
|
||||||
@@ -59,6 +60,51 @@ function NodeTypeStep({ isIdentifierRequired }) {
|
|||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
|
|
||||||
const isValid = !approvalNameMeta.touched || !approvalNameMeta.error;
|
const isValid = !approvalNameMeta.touched || !approvalNameMeta.error;
|
||||||
|
const nodeTypeChoices = [
|
||||||
|
{
|
||||||
|
key: 'workflow_approval_template',
|
||||||
|
value: 'workflow_approval_template',
|
||||||
|
label: t`Approval`,
|
||||||
|
isDisabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'inventory_source',
|
||||||
|
value: 'inventory_source',
|
||||||
|
label: t`Inventory Source Sync`,
|
||||||
|
isDisabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'job_template',
|
||||||
|
value: 'job_template',
|
||||||
|
label: t`Job Template`,
|
||||||
|
isDisabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'project',
|
||||||
|
value: 'project',
|
||||||
|
label: t`Project Sync`,
|
||||||
|
isDisabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'workflow_job_template',
|
||||||
|
value: 'workflow_job_template',
|
||||||
|
label: t`Workflow Job Template`,
|
||||||
|
isDisabled: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const modifiedNodeTypeChoices = isSuperUser
|
||||||
|
? [
|
||||||
|
...nodeTypeChoices,
|
||||||
|
{
|
||||||
|
key: 'system_job_template',
|
||||||
|
value: 'system_job_template',
|
||||||
|
label: t`Management Job`,
|
||||||
|
isDisabled: false,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: nodeTypeChoices;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{nodeResourceMeta.error && (
|
{nodeResourceMeta.error && (
|
||||||
@@ -74,44 +120,7 @@ function NodeTypeStep({ isIdentifierRequired }) {
|
|||||||
<AnsibleSelect
|
<AnsibleSelect
|
||||||
id="nodeResource-select"
|
id="nodeResource-select"
|
||||||
label={t`Select a Node Type`}
|
label={t`Select a Node Type`}
|
||||||
data={[
|
data={modifiedNodeTypeChoices}
|
||||||
{
|
|
||||||
key: 'workflow_approval_template',
|
|
||||||
value: 'workflow_approval_template',
|
|
||||||
label: t`Approval`,
|
|
||||||
isDisabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'inventory_source',
|
|
||||||
value: 'inventory_source',
|
|
||||||
label: t`Inventory Source Sync`,
|
|
||||||
isDisabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'job_template',
|
|
||||||
value: 'job_template',
|
|
||||||
label: t`Job Template`,
|
|
||||||
isDisabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'project',
|
|
||||||
value: 'project',
|
|
||||||
label: t`Project Sync`,
|
|
||||||
isDisabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'system_job_template',
|
|
||||||
value: 'system_job_template',
|
|
||||||
label: t`Management Job`,
|
|
||||||
isDisabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'workflow_job_template',
|
|
||||||
value: 'workflow_job_template',
|
|
||||||
label: t`Workflow Job Template`,
|
|
||||||
isDisabled: false,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
value={nodeTypeField.value}
|
value={nodeTypeField.value}
|
||||||
onChange={(e, val) => {
|
onChange={(e, val) => {
|
||||||
nodeTypeHelpers.setValue(val);
|
nodeTypeHelpers.setValue(val);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
ProjectsAPI,
|
ProjectsAPI,
|
||||||
WorkflowJobTemplatesAPI,
|
WorkflowJobTemplatesAPI,
|
||||||
} from 'api';
|
} from 'api';
|
||||||
|
import { useUserProfile } from 'contexts/Config';
|
||||||
import { mountWithContexts } from '../../../../../../../testUtils/enzymeHelpers';
|
import { mountWithContexts } from '../../../../../../../testUtils/enzymeHelpers';
|
||||||
|
|
||||||
import NodeTypeStep from './NodeTypeStep';
|
import NodeTypeStep from './NodeTypeStep';
|
||||||
@@ -17,6 +18,17 @@ jest.mock('../../../../../../api/models/Projects');
|
|||||||
jest.mock('../../../../../../api/models/WorkflowJobTemplates');
|
jest.mock('../../../../../../api/models/WorkflowJobTemplates');
|
||||||
|
|
||||||
describe('NodeTypeStep', () => {
|
describe('NodeTypeStep', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
useUserProfile.mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
isSuperUser: true,
|
||||||
|
isSystemAuditor: false,
|
||||||
|
isOrgAdmin: false,
|
||||||
|
isNotificationAdmin: false,
|
||||||
|
isExecEnvAdmin: false,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
JobTemplatesAPI.read.mockResolvedValue({
|
JobTemplatesAPI.read.mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
@@ -222,4 +234,65 @@ describe('NodeTypeStep', () => {
|
|||||||
expect(wrapper.find('input[name="timeoutMinutes"]').prop('value')).toBe(5);
|
expect(wrapper.find('input[name="timeoutMinutes"]').prop('value')).toBe(5);
|
||||||
expect(wrapper.find('input[name="timeoutSeconds"]').prop('value')).toBe(30);
|
expect(wrapper.find('input[name="timeoutSeconds"]').prop('value')).toBe(30);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('it does not show management job as a choice for non system admin', async () => {
|
||||||
|
useUserProfile.mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
isSuperUser: false,
|
||||||
|
isSystemAuditor: false,
|
||||||
|
isOrgAdmin: true,
|
||||||
|
isNotificationAdmin: false,
|
||||||
|
isExecEnvAdmin: false,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
let wrapper;
|
||||||
|
await act(async () => {
|
||||||
|
wrapper = mountWithContexts(
|
||||||
|
<Formik initialValues={{ nodeType: 'workflow_job_template' }}>
|
||||||
|
<NodeTypeStep />
|
||||||
|
</Formik>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
wrapper.update();
|
||||||
|
expect(wrapper.find('AnsibleSelect').prop('data').length).toBe(5);
|
||||||
|
expect(
|
||||||
|
wrapper
|
||||||
|
.find('AnsibleSelect')
|
||||||
|
.prop('data')
|
||||||
|
.map((item) => item.key)
|
||||||
|
).toEqual([
|
||||||
|
'workflow_approval_template',
|
||||||
|
'inventory_source',
|
||||||
|
'job_template',
|
||||||
|
'project',
|
||||||
|
'workflow_job_template',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it does show management job as a choice for system admin', async () => {
|
||||||
|
let wrapper;
|
||||||
|
await act(async () => {
|
||||||
|
wrapper = mountWithContexts(
|
||||||
|
<Formik initialValues={{ nodeType: 'workflow_job_template' }}>
|
||||||
|
<NodeTypeStep />
|
||||||
|
</Formik>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
wrapper.update();
|
||||||
|
expect(wrapper.find('AnsibleSelect').prop('data').length).toBe(6);
|
||||||
|
expect(
|
||||||
|
wrapper
|
||||||
|
.find('AnsibleSelect')
|
||||||
|
.prop('data')
|
||||||
|
.map((item) => item.key)
|
||||||
|
).toEqual([
|
||||||
|
'workflow_approval_template',
|
||||||
|
'inventory_source',
|
||||||
|
'job_template',
|
||||||
|
'project',
|
||||||
|
'workflow_job_template',
|
||||||
|
'system_job_template',
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user