mirror of
https://github.com/ansible/awx.git
synced 2026-01-18 05:01:19 -03:30
Add more ui unit test coverage for prompt changes
Flips default job/skip tags value from empty string to null on WF form
This commit is contained in:
parent
34e8087aee
commit
2a30a9b10f
@ -63,7 +63,7 @@ describe('<LabelSelect />', () => {
|
||||
const selectOptions = wrapper.find('SelectOption');
|
||||
expect(selectOptions).toHaveLength(4);
|
||||
});
|
||||
test('Generate a label ', async () => {
|
||||
test('Generate a label', async () => {
|
||||
let wrapper;
|
||||
const onChange = jest.fn();
|
||||
LabelsAPI.read.mockReturnValue({
|
||||
@ -79,4 +79,33 @@ describe('<LabelSelect />', () => {
|
||||
await wrapper.find('Select').invoke('onSelect')({}, 'foo');
|
||||
expect(onChange).toBeCalledWith([{ id: 'foo', name: 'foo' }]);
|
||||
});
|
||||
test('should handle read-only labels', async () => {
|
||||
let wrapper;
|
||||
const onChange = jest.fn();
|
||||
LabelsAPI.read.mockReturnValue({
|
||||
data: {
|
||||
results: [
|
||||
{ id: 1, name: 'read only' },
|
||||
{ id: 2, name: 'not read only' },
|
||||
],
|
||||
},
|
||||
});
|
||||
await act(async () => {
|
||||
wrapper = mount(
|
||||
<LabelSelect
|
||||
value={[
|
||||
{ id: 1, name: 'read only', isReadOnly: true },
|
||||
{ id: 2, name: 'not read only' },
|
||||
]}
|
||||
onError={() => {}}
|
||||
onChange={onChange}
|
||||
/>
|
||||
);
|
||||
});
|
||||
wrapper.find('SelectToggle').simulate('click');
|
||||
const selectOptions = wrapper.find('SelectOption');
|
||||
expect(selectOptions).toHaveLength(2);
|
||||
expect(selectOptions.at(0).prop('isDisabled')).toBe(true);
|
||||
expect(selectOptions.at(1).prop('isDisabled')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@ -37,6 +37,12 @@ describe('LaunchButton', () => {
|
||||
ask_variables_on_launch: false,
|
||||
ask_limit_on_launch: false,
|
||||
ask_scm_branch_on_launch: false,
|
||||
ask_execution_environment_on_launch: false,
|
||||
ask_labels_on_launch: false,
|
||||
ask_forks_on_launch: false,
|
||||
ask_job_slice_count_on_launch: false,
|
||||
ask_timeout_on_launch: false,
|
||||
ask_instance_groups_on_launch: false,
|
||||
survey_enabled: false,
|
||||
variables_needed_to_start: [],
|
||||
},
|
||||
|
||||
@ -20,6 +20,7 @@ import OtherPromptsStep from './steps/OtherPromptsStep';
|
||||
import PreviewStep from './steps/PreviewStep';
|
||||
import ExecutionEnvironmentStep from './steps/ExecutionEnvironmentStep';
|
||||
import InstanceGroupsStep from './steps/InstanceGroupsStep';
|
||||
import SurveyStep from './steps/SurveyStep';
|
||||
|
||||
jest.mock('../../api/models/Inventories');
|
||||
jest.mock('../../api/models/ExecutionEnvironments');
|
||||
@ -378,4 +379,46 @@ describe('LaunchPrompt', () => {
|
||||
expect(isElementOfType(steps[0].component, OtherPromptsStep)).toEqual(true);
|
||||
expect(isElementOfType(steps[1].component, PreviewStep)).toEqual(true);
|
||||
});
|
||||
|
||||
test('should add survey step', async () => {
|
||||
let wrapper;
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<LaunchPrompt
|
||||
launchConfig={{
|
||||
...config,
|
||||
survey_enabled: true,
|
||||
}}
|
||||
resource={resource}
|
||||
onLaunch={noop}
|
||||
onCancel={noop}
|
||||
surveyConfig={{
|
||||
name: '',
|
||||
description: '',
|
||||
spec: [
|
||||
{
|
||||
choices: '',
|
||||
default: '',
|
||||
max: 1024,
|
||||
min: 0,
|
||||
new_question: false,
|
||||
question_description: '',
|
||||
question_name: 'foo',
|
||||
required: true,
|
||||
type: 'text',
|
||||
variable: 'foo',
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
const wizard = await waitForElement(wrapper, 'Wizard');
|
||||
const steps = wizard.prop('steps');
|
||||
|
||||
expect(steps).toHaveLength(2);
|
||||
expect(steps[0].name.props.children).toEqual('Survey');
|
||||
expect(isElementOfType(steps[0].component, SurveyStep)).toEqual(true);
|
||||
expect(isElementOfType(steps[1].component, PreviewStep)).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { Formik } from 'formik';
|
||||
import { ExecutionEnvironmentsAPI } from 'api';
|
||||
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
|
||||
import ExecutionEnvironmentStep from './ExecutionEnvironmentStep';
|
||||
|
||||
jest.mock('../../../api/models/ExecutionEnvironments');
|
||||
|
||||
const execution_environments = [
|
||||
{ id: 1, name: 'ee one', url: '/execution_environments/1' },
|
||||
{ id: 2, name: 'ee two', url: '/execution_environments/2' },
|
||||
{ id: 3, name: 'ee three', url: '/execution_environments/3' },
|
||||
];
|
||||
|
||||
describe('ExecutionEnvironmentStep', () => {
|
||||
beforeEach(() => {
|
||||
ExecutionEnvironmentsAPI.read.mockResolvedValue({
|
||||
data: {
|
||||
results: execution_environments,
|
||||
count: 3,
|
||||
},
|
||||
});
|
||||
|
||||
ExecutionEnvironmentsAPI.readOptions.mockResolvedValue({
|
||||
data: {
|
||||
actions: {
|
||||
GET: {},
|
||||
POST: {},
|
||||
},
|
||||
related_search_fields: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('should load execution environments', async () => {
|
||||
let wrapper;
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<Formik>
|
||||
<ExecutionEnvironmentStep />
|
||||
</Formik>
|
||||
);
|
||||
});
|
||||
wrapper.update();
|
||||
|
||||
expect(ExecutionEnvironmentsAPI.read).toHaveBeenCalled();
|
||||
expect(wrapper.find('OptionsList').prop('options')).toEqual(
|
||||
execution_environments
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { Formik } from 'formik';
|
||||
import { InstanceGroupsAPI } from 'api';
|
||||
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
|
||||
import InstanceGroupsStep from './InstanceGroupsStep';
|
||||
|
||||
jest.mock('../../../api/models/InstanceGroups');
|
||||
|
||||
const instance_groups = [
|
||||
{ id: 1, name: 'ig one', url: '/instance_groups/1' },
|
||||
{ id: 2, name: 'ig two', url: '/instance_groups/2' },
|
||||
{ id: 3, name: 'ig three', url: '/instance_groups/3' },
|
||||
];
|
||||
|
||||
describe('InstanceGroupsStep', () => {
|
||||
beforeEach(() => {
|
||||
InstanceGroupsAPI.read.mockResolvedValue({
|
||||
data: {
|
||||
results: instance_groups,
|
||||
count: 3,
|
||||
},
|
||||
});
|
||||
|
||||
InstanceGroupsAPI.readOptions.mockResolvedValue({
|
||||
data: {
|
||||
actions: {
|
||||
GET: {},
|
||||
POST: {},
|
||||
},
|
||||
related_search_fields: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('should load instance groups', async () => {
|
||||
let wrapper;
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<Formik initialValues={{ instance_groups: [] }}>
|
||||
<InstanceGroupsStep />
|
||||
</Formik>
|
||||
);
|
||||
});
|
||||
wrapper.update();
|
||||
|
||||
expect(InstanceGroupsAPI.read).toHaveBeenCalled();
|
||||
expect(wrapper.find('OptionsList').prop('options')).toEqual(
|
||||
instance_groups
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -58,6 +58,81 @@ describe('OtherPromptsStep', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('should render timeout field', async () => {
|
||||
let wrapper;
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<Formik>
|
||||
<OtherPromptsStep
|
||||
launchConfig={{
|
||||
ask_timeout_on_launch: true,
|
||||
job_template_data: {
|
||||
name: 'Demo Job Template',
|
||||
id: 1,
|
||||
description: '',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
});
|
||||
|
||||
expect(wrapper.find('FormField#prompt-timeout')).toHaveLength(1);
|
||||
expect(wrapper.find('FormField#prompt-timeout input').prop('name')).toEqual(
|
||||
'timeout'
|
||||
);
|
||||
});
|
||||
|
||||
test('should render forks field', async () => {
|
||||
let wrapper;
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<Formik>
|
||||
<OtherPromptsStep
|
||||
launchConfig={{
|
||||
ask_forks_on_launch: true,
|
||||
job_template_data: {
|
||||
name: 'Demo Job Template',
|
||||
id: 1,
|
||||
description: '',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
});
|
||||
|
||||
expect(wrapper.find('FormField#prompt-forks')).toHaveLength(1);
|
||||
expect(wrapper.find('FormField#prompt-forks input').prop('name')).toEqual(
|
||||
'forks'
|
||||
);
|
||||
});
|
||||
|
||||
test('should render job slicing field', async () => {
|
||||
let wrapper;
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<Formik>
|
||||
<OtherPromptsStep
|
||||
launchConfig={{
|
||||
ask_job_slice_count_on_launch: true,
|
||||
job_template_data: {
|
||||
name: 'Demo Job Template',
|
||||
id: 1,
|
||||
description: '',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
});
|
||||
|
||||
expect(wrapper.find('FormField#prompt-job-slicing')).toHaveLength(1);
|
||||
expect(
|
||||
wrapper.find('FormField#prompt-job-slicing input').prop('name')
|
||||
).toEqual('job_slice_count');
|
||||
});
|
||||
|
||||
test('should render source control branch field', async () => {
|
||||
let wrapper;
|
||||
await act(async () => {
|
||||
|
||||
@ -66,6 +66,9 @@ describe('ExecutionEnvironmentLookup', () => {
|
||||
expect(
|
||||
wrapper.find('FormGroup[label="Execution Environment"]').length
|
||||
).toBe(1);
|
||||
expect(wrapper.find('Checkbox[aria-label="Prompt on launch"]').length).toBe(
|
||||
0
|
||||
);
|
||||
});
|
||||
|
||||
test('should fetch execution environments', async () => {
|
||||
@ -132,4 +135,25 @@ describe('ExecutionEnvironmentLookup', () => {
|
||||
page_size: 5,
|
||||
});
|
||||
});
|
||||
|
||||
test('should render prompt on launch checkbox when necessary', async () => {
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<Formik>
|
||||
<ExecutionEnvironmentLookup
|
||||
value={executionEnvironment}
|
||||
onChange={() => {}}
|
||||
projectId={12}
|
||||
globallyAvailable
|
||||
isPromptableField
|
||||
promptId="ee-prompt"
|
||||
promptName="ask_execution_environment_on_launch"
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
});
|
||||
expect(wrapper.find('Checkbox[aria-label="Prompt on launch"]').length).toBe(
|
||||
1
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
111
awx/ui/src/components/Lookup/InstanceGroupsLookup.test.js
Normal file
111
awx/ui/src/components/Lookup/InstanceGroupsLookup.test.js
Normal file
@ -0,0 +1,111 @@
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { Formik } from 'formik';
|
||||
import { InstanceGroupsAPI } from 'api';
|
||||
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
|
||||
import InstanceGroupsLookup from './InstanceGroupsLookup';
|
||||
|
||||
jest.mock('../../api');
|
||||
|
||||
const mockedInstanceGroups = {
|
||||
count: 1,
|
||||
results: [
|
||||
{
|
||||
id: 2,
|
||||
name: 'Foo',
|
||||
image: 'quay.io/ansible/awx-ee',
|
||||
pull: 'missing',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const instanceGroups = [
|
||||
{
|
||||
id: 1,
|
||||
type: 'instance_group',
|
||||
url: '/api/v2/instance_groups/1/',
|
||||
related: {
|
||||
jobs: '/api/v2/instance_groups/1/jobs/',
|
||||
instances: '/api/v2/instance_groups/1/instances/',
|
||||
},
|
||||
name: 'controlplane',
|
||||
created: '2022-09-13T15:44:54.870579Z',
|
||||
modified: '2022-09-13T15:44:54.886047Z',
|
||||
capacity: 59,
|
||||
consumed_capacity: 0,
|
||||
percent_capacity_remaining: 100.0,
|
||||
jobs_running: 0,
|
||||
jobs_total: 40,
|
||||
instances: 1,
|
||||
is_container_group: false,
|
||||
credential: null,
|
||||
policy_instance_percentage: 100,
|
||||
policy_instance_minimum: 0,
|
||||
policy_instance_list: [],
|
||||
pod_spec_override: '',
|
||||
summary_fields: {
|
||||
user_capabilities: {
|
||||
edit: true,
|
||||
delete: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
describe('InstanceGroupsLookup', () => {
|
||||
let wrapper;
|
||||
|
||||
beforeEach(() => {
|
||||
InstanceGroupsAPI.read.mockResolvedValue({
|
||||
data: mockedInstanceGroups,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('should render successfully', async () => {
|
||||
InstanceGroupsAPI.readOptions.mockReturnValue({
|
||||
data: {
|
||||
actions: {
|
||||
GET: {},
|
||||
POST: {},
|
||||
},
|
||||
related_search_fields: [],
|
||||
},
|
||||
});
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<Formik>
|
||||
<InstanceGroupsLookup value={instanceGroups} onChange={() => {}} />
|
||||
</Formik>
|
||||
);
|
||||
});
|
||||
wrapper.update();
|
||||
expect(InstanceGroupsAPI.read).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.find('InstanceGroupsLookup')).toHaveLength(1);
|
||||
expect(wrapper.find('FormGroup[label="Instance Groups"]').length).toBe(1);
|
||||
expect(wrapper.find('Checkbox[aria-label="Prompt on launch"]').length).toBe(
|
||||
0
|
||||
);
|
||||
});
|
||||
test('should render prompt on launch checkbox when necessary', async () => {
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<Formik>
|
||||
<InstanceGroupsLookup
|
||||
value={instanceGroups}
|
||||
onChange={() => {}}
|
||||
isPromptableField
|
||||
promptId="ig-prompt"
|
||||
promptName="ask_instance_groups_on_launch"
|
||||
/>
|
||||
</Formik>
|
||||
);
|
||||
});
|
||||
expect(wrapper.find('Checkbox[aria-label="Prompt on launch"]').length).toBe(
|
||||
1
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -35,6 +35,9 @@ function formatTimeout(timeout) {
|
||||
if (typeof timeout === 'undefined' || timeout === null) {
|
||||
return null;
|
||||
}
|
||||
if (typeof timeout === 'string') {
|
||||
return timeout;
|
||||
}
|
||||
const minutes = Math.floor(timeout / 60);
|
||||
const seconds = timeout - Math.floor(timeout / 60) * 60;
|
||||
return (
|
||||
@ -348,7 +351,10 @@ function PromptDetail({
|
||||
/>
|
||||
)}
|
||||
{launchConfig.ask_timeout_on_launch && (
|
||||
<Detail label={t`Timeout`} value={overrides.timeout} />
|
||||
<Detail
|
||||
label={t`Timeout`}
|
||||
value={formatTimeout(overrides?.timeout)}
|
||||
/>
|
||||
)}
|
||||
{launchConfig.ask_diff_mode_on_launch && (
|
||||
<Detail
|
||||
|
||||
@ -15,6 +15,12 @@ const mockPromptLaunch = {
|
||||
ask_tags_on_launch: true,
|
||||
ask_variables_on_launch: true,
|
||||
ask_verbosity_on_launch: true,
|
||||
ask_execution_environment_on_launch: true,
|
||||
ask_labels_on_launch: true,
|
||||
ask_forks_on_launch: true,
|
||||
ask_job_slice_count_on_launch: true,
|
||||
ask_timeout_on_launch: true,
|
||||
ask_instance_groups_on_launch: true,
|
||||
defaults: {
|
||||
extra_vars: '---foo: bar',
|
||||
diff_mode: false,
|
||||
@ -40,6 +46,10 @@ const mockPromptLaunch = {
|
||||
},
|
||||
],
|
||||
scm_branch: 'Foo branch',
|
||||
execution_environment: 1,
|
||||
forks: 1,
|
||||
job_slice_count: 1,
|
||||
timeout: 100,
|
||||
},
|
||||
};
|
||||
|
||||
@ -73,9 +83,20 @@ describe('PromptDetail', () => {
|
||||
assertDetail('Limit', 'localhost');
|
||||
assertDetail('Verbosity', '3 (Debug)');
|
||||
assertDetail('Show Changes', 'Off');
|
||||
assertDetail('Timeout', '1 min 40 sec');
|
||||
assertDetail('Forks', '1');
|
||||
assertDetail('Job Slicing', '1');
|
||||
expect(wrapper.find('VariablesDetail').prop('value')).toEqual(
|
||||
'---foo: bar'
|
||||
);
|
||||
expect(
|
||||
wrapper
|
||||
.find('Detail[label="Labels"]')
|
||||
.containsAllMatchingElements([
|
||||
<span>L_91o2</span>,
|
||||
<span>L_91o3</span>,
|
||||
])
|
||||
).toEqual(true);
|
||||
expect(
|
||||
wrapper
|
||||
.find('Detail[label="Credentials"]')
|
||||
@ -151,6 +172,19 @@ describe('PromptDetail', () => {
|
||||
job_type: 'check',
|
||||
scm_branch: 'Bar branch',
|
||||
diff_mode: true,
|
||||
forks: 2,
|
||||
job_slice_count: 2,
|
||||
timeout: 160,
|
||||
labels: [
|
||||
{ name: 'foo', id: 1 },
|
||||
{ name: 'bar', id: 2 },
|
||||
],
|
||||
instance_groups: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'controlplane',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
@ -182,9 +216,17 @@ describe('PromptDetail', () => {
|
||||
assertDetail('Limit', 'otherlimit');
|
||||
assertDetail('Verbosity', '0 (Normal)');
|
||||
assertDetail('Show Changes', 'On');
|
||||
assertDetail('Timeout', '2 min 40 sec');
|
||||
assertDetail('Forks', '2');
|
||||
assertDetail('Job Slicing', '2');
|
||||
expect(wrapper.find('VariablesDetail').prop('value')).toEqual(
|
||||
'---one: two\nbar: baz'
|
||||
);
|
||||
expect(
|
||||
wrapper
|
||||
.find('Detail[label="Labels"]')
|
||||
.containsAllMatchingElements([<span>foo</span>, <span>bar</span>])
|
||||
).toEqual(true);
|
||||
expect(
|
||||
wrapper
|
||||
.find('Detail[label="Credentials"]')
|
||||
|
||||
@ -3,159 +3,163 @@
|
||||
"type": "job_template",
|
||||
"url": "/api/v2/job_templates/7/",
|
||||
"related": {
|
||||
"named_url": "/api/v2/job_templates/MockJT/",
|
||||
"created_by": "/api/v2/users/1/",
|
||||
"modified_by": "/api/v2/users/1/",
|
||||
"labels": "/api/v2/job_templates/7/labels/",
|
||||
"inventory": "/api/v2/inventories/1/",
|
||||
"project": "/api/v2/projects/6/",
|
||||
"credentials": "/api/v2/job_templates/7/credentials/",
|
||||
"last_job": "/api/v2/jobs/12/",
|
||||
"jobs": "/api/v2/job_templates/7/jobs/",
|
||||
"schedules": "/api/v2/job_templates/7/schedules/",
|
||||
"activity_stream": "/api/v2/job_templates/7/activity_stream/",
|
||||
"launch": "/api/v2/job_templates/7/launch/",
|
||||
"webhook_key": "/api/v2/job_templates/7/webhook_key/",
|
||||
"webhook_receiver": "/api/v2/job_templates/7/github/",
|
||||
"notification_templates_started": "/api/v2/job_templates/7/notification_templates_started/",
|
||||
"notification_templates_success": "/api/v2/job_templates/7/notification_templates_success/",
|
||||
"notification_templates_error": "/api/v2/job_templates/7/notification_templates_error/",
|
||||
"access_list": "/api/v2/job_templates/7/access_list/",
|
||||
"survey_spec": "/api/v2/job_templates/7/survey_spec/",
|
||||
"object_roles": "/api/v2/job_templates/7/object_roles/",
|
||||
"instance_groups": "/api/v2/job_templates/7/instance_groups/",
|
||||
"slice_workflow_jobs": "/api/v2/job_templates/7/slice_workflow_jobs/",
|
||||
"copy": "/api/v2/job_templates/7/copy/",
|
||||
"callback": "/api/v2/job_templates/7/callback/",
|
||||
"webhook_credential": "/api/v2/credentials/8/"
|
||||
"named_url": "/api/v2/job_templates/MockJT/",
|
||||
"created_by": "/api/v2/users/1/",
|
||||
"modified_by": "/api/v2/users/1/",
|
||||
"labels": "/api/v2/job_templates/7/labels/",
|
||||
"inventory": "/api/v2/inventories/1/",
|
||||
"project": "/api/v2/projects/6/",
|
||||
"credentials": "/api/v2/job_templates/7/credentials/",
|
||||
"last_job": "/api/v2/jobs/12/",
|
||||
"jobs": "/api/v2/job_templates/7/jobs/",
|
||||
"schedules": "/api/v2/job_templates/7/schedules/",
|
||||
"activity_stream": "/api/v2/job_templates/7/activity_stream/",
|
||||
"launch": "/api/v2/job_templates/7/launch/",
|
||||
"webhook_key": "/api/v2/job_templates/7/webhook_key/",
|
||||
"webhook_receiver": "/api/v2/job_templates/7/github/",
|
||||
"notification_templates_started": "/api/v2/job_templates/7/notification_templates_started/",
|
||||
"notification_templates_success": "/api/v2/job_templates/7/notification_templates_success/",
|
||||
"notification_templates_error": "/api/v2/job_templates/7/notification_templates_error/",
|
||||
"access_list": "/api/v2/job_templates/7/access_list/",
|
||||
"survey_spec": "/api/v2/job_templates/7/survey_spec/",
|
||||
"object_roles": "/api/v2/job_templates/7/object_roles/",
|
||||
"instance_groups": "/api/v2/job_templates/7/instance_groups/",
|
||||
"slice_workflow_jobs": "/api/v2/job_templates/7/slice_workflow_jobs/",
|
||||
"copy": "/api/v2/job_templates/7/copy/",
|
||||
"callback": "/api/v2/job_templates/7/callback/",
|
||||
"webhook_credential": "/api/v2/credentials/8/"
|
||||
},
|
||||
"summary_fields": {
|
||||
"inventory": {
|
||||
"id": 1,
|
||||
"name": "Demo Inventory",
|
||||
"description": "",
|
||||
"has_active_failures": false,
|
||||
"total_hosts": 1,
|
||||
"hosts_with_active_failures": 0,
|
||||
"total_groups": 0,
|
||||
"groups_with_active_failures": 0,
|
||||
"has_inventory_sources": false,
|
||||
"total_inventory_sources": 0,
|
||||
"inventory_sources_with_failures": 0,
|
||||
"organization_id": 1,
|
||||
"kind": ""
|
||||
},
|
||||
"execution_environment": {
|
||||
"id": 1,
|
||||
"name": "Default EE",
|
||||
"description": "",
|
||||
"image": "quay.io/ansible/awx-ee"
|
||||
},
|
||||
"project": {
|
||||
"id": 6,
|
||||
"name": "Mock Project",
|
||||
"description": "",
|
||||
"status": "successful",
|
||||
"scm_type": "git"
|
||||
},
|
||||
"last_job": {
|
||||
"id": 12,
|
||||
"name": "Mock JT",
|
||||
"description": "",
|
||||
"finished": "2019-10-01T14:34:35.142483Z",
|
||||
"status": "successful",
|
||||
"failed": false
|
||||
},
|
||||
"last_update": {
|
||||
"id": 12,
|
||||
"name": "Mock JT",
|
||||
"description": "",
|
||||
"status": "successful",
|
||||
"failed": false
|
||||
},
|
||||
"webhook_credential": {
|
||||
"id": 8,
|
||||
"name": "GitHub Cred",
|
||||
"description": "",
|
||||
"kind": "github_token",
|
||||
"cloud": false,
|
||||
"credential_type_id": 12
|
||||
},
|
||||
"created_by": {
|
||||
"id": 1,
|
||||
"username": "admin",
|
||||
"first_name": "",
|
||||
"last_name": ""
|
||||
},
|
||||
"modified_by": {
|
||||
"id": 1,
|
||||
"username": "admin",
|
||||
"first_name": "",
|
||||
"last_name": ""
|
||||
},
|
||||
"object_roles": {
|
||||
"admin_role": {
|
||||
"description": "Can manage all aspects of the job template",
|
||||
"name": "Admin",
|
||||
"id": 24
|
||||
},
|
||||
"execute_role": {
|
||||
"description": "May run the job template",
|
||||
"name": "Execute",
|
||||
"id": 25
|
||||
},
|
||||
"read_role": {
|
||||
"description": "May view settings for the job template",
|
||||
"name": "Read",
|
||||
"id": 26
|
||||
}
|
||||
},
|
||||
"user_capabilities": {
|
||||
"edit": true,
|
||||
"delete": true,
|
||||
"start": true,
|
||||
"schedule": true,
|
||||
"copy": true
|
||||
},
|
||||
"labels": {
|
||||
"count": 1,
|
||||
"results": [
|
||||
{
|
||||
"id": 91,
|
||||
"name": "L_91o2"
|
||||
},
|
||||
{
|
||||
"id": 92,
|
||||
"name": "L_91o3"
|
||||
}
|
||||
]
|
||||
"inventory": {
|
||||
"id": 1,
|
||||
"name": "Demo Inventory",
|
||||
"description": "",
|
||||
"has_active_failures": false,
|
||||
"total_hosts": 1,
|
||||
"hosts_with_active_failures": 0,
|
||||
"total_groups": 0,
|
||||
"groups_with_active_failures": 0,
|
||||
"has_inventory_sources": false,
|
||||
"total_inventory_sources": 0,
|
||||
"inventory_sources_with_failures": 0,
|
||||
"organization_id": 1,
|
||||
"kind": ""
|
||||
},
|
||||
"survey": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
"execution_environment": {
|
||||
"id": 1,
|
||||
"name": "Default EE",
|
||||
"description": "",
|
||||
"image": "quay.io/ansible/awx-ee"
|
||||
},
|
||||
"project": {
|
||||
"id": 6,
|
||||
"name": "Mock Project",
|
||||
"description": "",
|
||||
"status": "successful",
|
||||
"scm_type": "git"
|
||||
},
|
||||
"last_job": {
|
||||
"id": 12,
|
||||
"name": "Mock JT",
|
||||
"description": "",
|
||||
"finished": "2019-10-01T14:34:35.142483Z",
|
||||
"status": "successful",
|
||||
"failed": false
|
||||
},
|
||||
"last_update": {
|
||||
"id": 12,
|
||||
"name": "Mock JT",
|
||||
"description": "",
|
||||
"status": "successful",
|
||||
"failed": false
|
||||
},
|
||||
"webhook_credential": {
|
||||
"id": 8,
|
||||
"name": "GitHub Cred",
|
||||
"description": "",
|
||||
"kind": "github_token",
|
||||
"cloud": false,
|
||||
"credential_type_id": 12
|
||||
},
|
||||
"created_by": {
|
||||
"id": 1,
|
||||
"username": "admin",
|
||||
"first_name": "",
|
||||
"last_name": ""
|
||||
},
|
||||
"modified_by": {
|
||||
"id": 1,
|
||||
"username": "admin",
|
||||
"first_name": "",
|
||||
"last_name": ""
|
||||
},
|
||||
"object_roles": {
|
||||
"admin_role": {
|
||||
"description": "Can manage all aspects of the job template",
|
||||
"name": "Admin",
|
||||
"id": 24
|
||||
},
|
||||
"recent_jobs": [
|
||||
{
|
||||
"id": 12,
|
||||
"status": "successful",
|
||||
"finished": "2019-10-01T14:34:35.142483Z",
|
||||
"type": "job"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"status": "successful",
|
||||
"finished": "2019-10-01T14:34:35.142483Z",
|
||||
"type": "job"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
"execute_role": {
|
||||
"description": "May run the job template",
|
||||
"name": "Execute",
|
||||
"id": 25
|
||||
},
|
||||
"read_role": {
|
||||
"description": "May view settings for the job template",
|
||||
"name": "Read",
|
||||
"id": 26
|
||||
}
|
||||
},
|
||||
"user_capabilities": {
|
||||
"edit": true,
|
||||
"delete": true,
|
||||
"start": true,
|
||||
"schedule": true,
|
||||
"copy": true
|
||||
},
|
||||
"labels": {
|
||||
"count": 1,
|
||||
"results": [
|
||||
{
|
||||
"id": 1, "kind": "ssh" , "name": "Credential 1"
|
||||
"id": 91,
|
||||
"name": "L_91o2"
|
||||
},
|
||||
{
|
||||
"id": 2, "kind": "awx" , "name": "Credential 2"
|
||||
"id": 92,
|
||||
"name": "L_91o3"
|
||||
}
|
||||
]
|
||||
},
|
||||
"survey": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"recent_jobs": [
|
||||
{
|
||||
"id": 12,
|
||||
"status": "successful",
|
||||
"finished": "2019-10-01T14:34:35.142483Z",
|
||||
"type": "job"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"status": "successful",
|
||||
"finished": "2019-10-01T14:34:35.142483Z",
|
||||
"type": "job"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
{
|
||||
"id": 1,
|
||||
"kind": "ssh",
|
||||
"name": "Credential 1"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"kind": "awx",
|
||||
"name": "Credential 2"
|
||||
}
|
||||
]
|
||||
},
|
||||
"created": "2019-09-30T16:18:34.564820Z",
|
||||
"modified": "2019-10-01T14:47:31.818431Z",
|
||||
|
||||
@ -270,9 +270,11 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, surveyConfig }) {
|
||||
const showExecutionEnvironmentDetail =
|
||||
ask_execution_environment_on_launch && execution_environment;
|
||||
const showLabelsDetail = ask_labels_on_launch && labels && labels.length > 0;
|
||||
const showForksDetail = ask_forks_on_launch;
|
||||
const showJobSlicingDetail = ask_job_slice_count_on_launch;
|
||||
const showTimeoutDetail = ask_timeout_on_launch;
|
||||
const showForksDetail = ask_forks_on_launch && typeof forks === 'number';
|
||||
const showJobSlicingDetail =
|
||||
ask_job_slice_count_on_launch && typeof job_slice_count === 'number';
|
||||
const showTimeoutDetail =
|
||||
ask_timeout_on_launch && typeof timeout === 'number';
|
||||
const showInstanceGroupsDetail =
|
||||
ask_instance_groups_on_launch && instanceGroups.length > 0;
|
||||
|
||||
@ -551,17 +553,17 @@ function ScheduleDetail({ hasDaysToKeepField, schedule, surveyConfig }) {
|
||||
value={
|
||||
<ChipGroup
|
||||
numChips={5}
|
||||
totalChips={summary_fields.labels.results.length}
|
||||
totalChips={labels.length}
|
||||
ouiaId="schedule-label-chips"
|
||||
>
|
||||
{summary_fields.labels.results.map((l) => (
|
||||
{labels.map((l) => (
|
||||
<Chip key={l.id} ouiaId={`label-${l.id}-chip`} isReadOnly>
|
||||
{l.name}
|
||||
</Chip>
|
||||
))}
|
||||
</ChipGroup>
|
||||
}
|
||||
isEmpty={summary_fields.labels.results.length === 0}
|
||||
isEmpty={labels.length === 0}
|
||||
/>
|
||||
)}
|
||||
{showTagsDetail && (
|
||||
|
||||
@ -23,6 +23,12 @@ const allPrompts = {
|
||||
ask_tags_on_launch: true,
|
||||
ask_variables_on_launch: true,
|
||||
ask_verbosity_on_launch: true,
|
||||
ask_execution_environment_on_launch: true,
|
||||
ask_labels_on_launch: true,
|
||||
ask_forks_on_launch: true,
|
||||
ask_job_slice_count_on_launch: true,
|
||||
ask_timeout_on_launch: true,
|
||||
ask_instance_groups_on_launch: true,
|
||||
survey_enabled: true,
|
||||
inventory_needed_to_start: true,
|
||||
},
|
||||
@ -40,6 +46,12 @@ const noPrompts = {
|
||||
ask_tags_on_launch: false,
|
||||
ask_variables_on_launch: false,
|
||||
ask_verbosity_on_launch: false,
|
||||
ask_execution_environment_on_launch: false,
|
||||
ask_labels_on_launch: false,
|
||||
ask_forks_on_launch: false,
|
||||
ask_job_slice_count_on_launch: false,
|
||||
ask_timeout_on_launch: false,
|
||||
ask_instance_groups_on_launch: false,
|
||||
survey_enabled: false,
|
||||
},
|
||||
};
|
||||
@ -91,6 +103,10 @@ const schedule = {
|
||||
limit: null,
|
||||
diff_mode: null,
|
||||
verbosity: null,
|
||||
execution_environment: null,
|
||||
forks: null,
|
||||
job_slice_count: null,
|
||||
timeout: null,
|
||||
};
|
||||
|
||||
const scheduleWithPrompts = {
|
||||
@ -104,6 +120,10 @@ const scheduleWithPrompts = {
|
||||
diff_mode: true,
|
||||
verbosity: 1,
|
||||
extra_data: { foo: 'fii' },
|
||||
execution_environment: 1,
|
||||
forks: 1,
|
||||
job_slice_count: 1,
|
||||
timeout: 100,
|
||||
};
|
||||
|
||||
describe('<ScheduleDetail />', () => {
|
||||
@ -182,6 +202,14 @@ describe('<ScheduleDetail />', () => {
|
||||
expect(wrapper.find('Detail[label="Credentials"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Job Tags"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Skip Tags"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Timeout"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Job Slicing"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Forks"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Labels"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Instance Groups"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Execution Environment"]').length).toBe(
|
||||
0
|
||||
);
|
||||
expect(wrapper.find('VariablesDetail').length).toBe(0);
|
||||
});
|
||||
test('details should render with the proper values with prompts', async () => {
|
||||
@ -200,6 +228,28 @@ describe('<ScheduleDetail />', () => {
|
||||
],
|
||||
},
|
||||
});
|
||||
SchedulesAPI.readInstanceGroups.mockResolvedValue({
|
||||
data: {
|
||||
count: 1,
|
||||
results: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'IG 1',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
SchedulesAPI.readAllLabels.mockResolvedValue({
|
||||
data: {
|
||||
count: 1,
|
||||
results: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Label 1',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
JobTemplatesAPI.readLaunch.mockResolvedValueOnce(allPrompts);
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
@ -254,6 +304,14 @@ describe('<ScheduleDetail />', () => {
|
||||
expect(wrapper.find('Detail[label="Credentials"]').length).toBe(1);
|
||||
expect(wrapper.find('Detail[label="Job Tags"]').length).toBe(1);
|
||||
expect(wrapper.find('Detail[label="Skip Tags"]').length).toBe(1);
|
||||
expect(wrapper.find('Detail[label="Timeout"]').length).toBe(1);
|
||||
expect(wrapper.find('Detail[label="Job Slicing"]').length).toBe(1);
|
||||
expect(wrapper.find('Detail[label="Forks"]').length).toBe(1);
|
||||
expect(wrapper.find('Detail[label="Labels"]').length).toBe(1);
|
||||
expect(wrapper.find('Detail[label="Instance Groups"]').length).toBe(1);
|
||||
expect(wrapper.find('Detail[label="Execution Environment"]').length).toBe(
|
||||
1
|
||||
);
|
||||
expect(wrapper.find('VariablesDetail').length).toBe(1);
|
||||
});
|
||||
test('prompt values section should be hidden if no overrides are present on the schedule but ask_ options are all true', async () => {
|
||||
@ -263,6 +321,18 @@ describe('<ScheduleDetail />', () => {
|
||||
results: [],
|
||||
},
|
||||
});
|
||||
SchedulesAPI.readInstanceGroups.mockResolvedValue({
|
||||
data: {
|
||||
count: 0,
|
||||
results: [],
|
||||
},
|
||||
});
|
||||
SchedulesAPI.readAllLabels.mockResolvedValue({
|
||||
data: {
|
||||
count: 0,
|
||||
results: [],
|
||||
},
|
||||
});
|
||||
JobTemplatesAPI.readLaunch.mockResolvedValueOnce(allPrompts);
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
@ -296,6 +366,14 @@ describe('<ScheduleDetail />', () => {
|
||||
expect(wrapper.find('Detail[label="Credentials"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Job Tags"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Skip Tags"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Timeout"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Job Slicing"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Forks"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Labels"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Instance Groups"]').length).toBe(0);
|
||||
expect(wrapper.find('Detail[label="Execution Environment"]').length).toBe(
|
||||
0
|
||||
);
|
||||
expect(wrapper.find('VariablesDetail').length).toBe(0);
|
||||
});
|
||||
test('prompt values section should be hidden if overrides are present on the schedule but ask_ options are all false', async () => {
|
||||
@ -469,6 +547,18 @@ describe('<ScheduleDetail />', () => {
|
||||
results: [],
|
||||
},
|
||||
});
|
||||
SchedulesAPI.readInstanceGroups.mockResolvedValue({
|
||||
data: {
|
||||
count: 0,
|
||||
results: [],
|
||||
},
|
||||
});
|
||||
SchedulesAPI.readAllLabels.mockResolvedValue({
|
||||
data: {
|
||||
count: 0,
|
||||
results: [],
|
||||
},
|
||||
});
|
||||
JobTemplatesAPI.readLaunch.mockResolvedValueOnce(allPrompts);
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
|
||||
@ -22,12 +22,16 @@ function WorkflowJobTemplateAdd() {
|
||||
webhook_credential,
|
||||
webhook_key,
|
||||
limit,
|
||||
job_tags,
|
||||
skip_tags,
|
||||
...templatePayload
|
||||
} = values;
|
||||
templatePayload.inventory = inventory?.id;
|
||||
templatePayload.organization = organization?.id;
|
||||
templatePayload.webhook_credential = webhook_credential?.id;
|
||||
templatePayload.limit = limit === '' ? null : limit;
|
||||
templatePayload.job_tags = job_tags === '' ? null : job_tags;
|
||||
templatePayload.skip_tags = skip_tags === '' ? null : skip_tags;
|
||||
const organizationId =
|
||||
organization?.id || inventory?.summary_fields?.organization.id;
|
||||
try {
|
||||
|
||||
@ -116,11 +116,11 @@ describe('<WorkflowJobTemplateAdd/>', () => {
|
||||
description: '',
|
||||
extra_vars: '---',
|
||||
inventory: undefined,
|
||||
job_tags: '',
|
||||
job_tags: null,
|
||||
limit: null,
|
||||
organization: undefined,
|
||||
scm_branch: '',
|
||||
skip_tags: '',
|
||||
skip_tags: null,
|
||||
webhook_credential: undefined,
|
||||
webhook_service: '',
|
||||
webhook_url: '',
|
||||
|
||||
@ -23,12 +23,16 @@ function WorkflowJobTemplateEdit({ template }) {
|
||||
webhook_credential,
|
||||
webhook_key,
|
||||
limit,
|
||||
job_tags,
|
||||
skip_tags,
|
||||
...templatePayload
|
||||
} = values;
|
||||
templatePayload.inventory = inventory?.id || null;
|
||||
templatePayload.organization = organization?.id || null;
|
||||
templatePayload.webhook_credential = webhook_credential?.id || null;
|
||||
templatePayload.limit = limit === '' ? null : limit;
|
||||
templatePayload.job_tags = job_tags === '' ? null : job_tags;
|
||||
templatePayload.skip_tags = skip_tags === '' ? null : skip_tags;
|
||||
|
||||
const formOrgId =
|
||||
organization?.id || inventory?.summary_fields?.organization.id || null;
|
||||
|
||||
@ -178,8 +178,8 @@ describe('<WorkflowJobTemplateEdit/>', () => {
|
||||
ask_labels_on_launch: false,
|
||||
ask_skip_tags_on_launch: false,
|
||||
ask_tags_on_launch: false,
|
||||
job_tags: '',
|
||||
skip_tags: '',
|
||||
job_tags: null,
|
||||
skip_tags: null,
|
||||
});
|
||||
wrapper.update();
|
||||
await expect(WorkflowJobTemplatesAPI.disassociateLabel).toBeCalledWith(6, {
|
||||
@ -288,12 +288,12 @@ describe('<WorkflowJobTemplateEdit/>', () => {
|
||||
description: 'bar',
|
||||
extra_vars: '---',
|
||||
inventory: 1,
|
||||
job_tags: '',
|
||||
job_tags: null,
|
||||
limit: '5000',
|
||||
name: 'Foo',
|
||||
organization: 1,
|
||||
scm_branch: 'devel',
|
||||
skip_tags: '',
|
||||
skip_tags: null,
|
||||
webhook_credential: null,
|
||||
webhook_service: '',
|
||||
webhook_url: '',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user