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:
mabashian 2022-09-13 21:33:16 -04:00 committed by Alan Rominger
parent 34e8087aee
commit 2a30a9b10f
No known key found for this signature in database
GPG Key ID: C2D7EAAA12B63559
17 changed files with 702 additions and 158 deletions

View File

@ -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);
});
});

View File

@ -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: [],
},

View File

@ -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);
});
});

View File

@ -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
);
});
});

View File

@ -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
);
});
});

View File

@ -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 () => {

View File

@ -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
);
});
});

View 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
);
});
});

View File

@ -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

View File

@ -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"]')

View File

@ -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",

View File

@ -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 && (

View File

@ -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(

View File

@ -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 {

View File

@ -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: '',

View File

@ -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;

View File

@ -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: '',