foreman_remote_execution 4.5.6 → 4.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/job_invocations_controller.rb +1 -1
  3. data/app/controllers/ui_job_wizard_controller.rb +0 -7
  4. data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +1 -5
  5. data/app/helpers/remote_execution_helper.rb +3 -9
  6. data/app/lib/actions/remote_execution/run_host_job.rb +1 -5
  7. data/app/lib/actions/remote_execution/run_hosts_job.rb +1 -1
  8. data/app/models/concerns/foreman_remote_execution/host_extensions.rb +0 -2
  9. data/app/models/concerns/foreman_remote_execution/orchestration/ssh.rb +70 -0
  10. data/app/models/concerns/foreman_remote_execution/smart_proxy_extensions.rb +0 -6
  11. data/app/models/host_status/execution_status.rb +3 -3
  12. data/app/models/job_invocation.rb +6 -9
  13. data/app/models/job_invocation_composer.rb +4 -4
  14. data/app/models/remote_execution_feature.rb +1 -5
  15. data/app/models/remote_execution_provider.rb +2 -3
  16. data/app/models/setting/remote_execution.rb +2 -2
  17. data/app/models/targeting.rb +1 -5
  18. data/app/views/job_invocations/index.html.erb +1 -1
  19. data/app/views/templates/ssh/module_action.erb +0 -1
  20. data/app/views/templates/ssh/power_action.erb +0 -2
  21. data/app/views/templates/ssh/puppet_run_once.erb +0 -1
  22. data/foreman_remote_execution.gemspec +0 -1
  23. data/lib/foreman_remote_execution/engine.rb +2 -0
  24. data/lib/foreman_remote_execution/version.rb +1 -1
  25. data/test/models/orchestration/ssh_test.rb +56 -0
  26. data/test/unit/job_invocation_composer_test.rb +1 -14
  27. data/test/unit/job_invocation_test.rb +1 -1
  28. data/test/unit/remote_execution_provider_test.rb +0 -12
  29. data/webpack/JobWizard/JobWizard.js +16 -59
  30. data/webpack/JobWizard/JobWizard.scss +0 -58
  31. data/webpack/JobWizard/JobWizardConstants.js +0 -18
  32. data/webpack/JobWizard/JobWizardSelectors.js +0 -9
  33. data/webpack/JobWizard/__tests__/JobWizard.test.js +13 -0
  34. data/webpack/JobWizard/__tests__/__snapshots__/JobWizard.test.js.snap +32 -0
  35. data/webpack/JobWizard/__tests__/fixtures.js +2 -112
  36. data/webpack/JobWizard/__tests__/integration.test.js +92 -16
  37. data/webpack/JobWizard/steps/AdvancedFields/AdvancedFields.js +9 -37
  38. data/webpack/JobWizard/steps/AdvancedFields/Fields.js +55 -116
  39. data/webpack/JobWizard/steps/AdvancedFields/__tests__/AdvancedFields.test.js +16 -150
  40. data/webpack/JobWizard/steps/AdvancedFields/__tests__/__snapshots__/AdvancedFields.test.js.snap +249 -0
  41. data/webpack/JobWizard/steps/CategoryAndTemplate/CategoryAndTemplate.js +2 -4
  42. data/webpack/JobWizard/steps/CategoryAndTemplate/CategoryAndTemplate.test.js +51 -123
  43. data/webpack/JobWizard/steps/CategoryAndTemplate/__snapshots__/CategoryAndTemplate.test.js.snap +113 -0
  44. data/webpack/JobWizard/steps/form/FormHelpers.js +0 -1
  45. data/webpack/JobWizard/steps/form/SelectField.js +2 -14
  46. data/webpack/JobWizard/steps/form/__tests__/GroupedSelectField.test.js +38 -0
  47. data/webpack/JobWizard/steps/form/__tests__/SelectField.test.js +23 -0
  48. data/webpack/JobWizard/steps/form/__tests__/__snapshots__/GroupedSelectField.test.js.snap +37 -0
  49. data/webpack/JobWizard/steps/form/__tests__/__snapshots__/SelectField.test.js.snap +23 -0
  50. data/webpack/__mocks__/foremanReact/components/SearchBar.js +1 -18
  51. data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHostsPage.test.js.snap +0 -1
  52. metadata +13 -35
  53. data/app/models/host_proxy_invocation.rb +0 -4
  54. data/db/migrate/2021051713291621250977_add_host_proxy_invocations.rb +0 -12
  55. data/webpack/JobWizard/steps/AdvancedFields/DescriptionField.js +0 -67
  56. data/webpack/JobWizard/steps/AdvancedFields/__tests__/DescriptionField.test.js +0 -23
  57. data/webpack/JobWizard/steps/HostsAndInputs/SelectedChips.js +0 -25
  58. data/webpack/JobWizard/steps/HostsAndInputs/TemplateInputs.js +0 -23
  59. data/webpack/JobWizard/steps/HostsAndInputs/__tests__/SelectedChips.test.js +0 -37
  60. data/webpack/JobWizard/steps/HostsAndInputs/__tests__/TemplateInputs.test.js +0 -50
  61. data/webpack/JobWizard/steps/HostsAndInputs/index.js +0 -66
  62. data/webpack/JobWizard/steps/Schedule/QueryType.js +0 -48
  63. data/webpack/JobWizard/steps/Schedule/RepeatOn.js +0 -61
  64. data/webpack/JobWizard/steps/Schedule/ScheduleType.js +0 -25
  65. data/webpack/JobWizard/steps/Schedule/StartEndDates.js +0 -51
  66. data/webpack/JobWizard/steps/Schedule/__tests__/StartEndDates.test.js +0 -22
  67. data/webpack/JobWizard/steps/Schedule/index.js +0 -44
  68. data/webpack/JobWizard/steps/form/Formatter.js +0 -150
  69. data/webpack/JobWizard/steps/form/NumberInput.js +0 -35
  70. data/webpack/JobWizard/steps/form/WizardTitle.js +0 -14
  71. data/webpack/JobWizard/steps/form/__tests__/Formatter.test.js.example +0 -76
@@ -1,64 +1,28 @@
1
- /* eslint-disable camelcase */
2
1
  import React, { useState, useEffect, useCallback } from 'react';
3
2
  import { useDispatch, useSelector } from 'react-redux';
4
3
  import { Wizard } from '@patternfly/react-core';
5
4
  import { get } from 'foremanReact/redux/API';
5
+ import { translate as __ } from 'foremanReact/common/I18n';
6
6
  import history from 'foremanReact/history';
7
7
  import CategoryAndTemplate from './steps/CategoryAndTemplate/';
8
8
  import { AdvancedFields } from './steps/AdvancedFields/AdvancedFields';
9
- import { JOB_TEMPLATE, WIZARD_TITLES } from './JobWizardConstants';
9
+ import { JOB_TEMPLATE } from './JobWizardConstants';
10
10
  import { selectTemplateError } from './JobWizardSelectors';
11
- import Schedule from './steps/Schedule/';
12
- import HostsAndInputs from './steps/HostsAndInputs/';
13
11
  import './JobWizard.scss';
14
12
 
15
13
  export const JobWizard = () => {
16
14
  const [jobTemplateID, setJobTemplateID] = useState(null);
17
15
  const [category, setCategory] = useState('');
18
16
  const [advancedValues, setAdvancedValues] = useState({});
19
- const [templateValues, setTemplateValues] = useState({}); // TODO use templateValues in advanced fields - description https://github.com/theforeman/foreman_remote_execution/pull/605
20
- const [selectedHosts, setSelectedHosts] = useState(['host1', 'host2']);
21
17
  const dispatch = useDispatch();
22
18
 
23
- const setDefaults = useCallback(
24
- ({
25
- data: {
26
- template_inputs,
27
- advanced_template_inputs,
28
- effective_user,
29
- job_template: { execution_timeout_interval, description_format },
30
- },
31
- }) => {
32
- const advancedTemplateValues = {};
33
- const defaultTemplateValues = {};
34
- const inputs = template_inputs;
35
- const advancedInputs = advanced_template_inputs;
36
- if (inputs) {
37
- setTemplateValues(() => {
38
- inputs.forEach(input => {
39
- defaultTemplateValues[input.name] = input?.default || '';
40
- });
41
- return defaultTemplateValues;
42
- });
43
- }
44
- setAdvancedValues(currentAdvancedValues => {
45
- if (advancedInputs) {
46
- advancedInputs.forEach(input => {
47
- advancedTemplateValues[input.name] = input?.default || '';
48
- });
49
- }
50
- return {
51
- ...currentAdvancedValues,
52
- effectiveUserValue: effective_user?.value || '',
53
- timeoutToKill: execution_timeout_interval || '',
54
- templateValues: advancedTemplateValues,
55
- description: description_format || '',
56
- isRandomizedOrdering: false,
57
- };
58
- });
59
- },
60
- []
61
- );
19
+ const setDefaults = useCallback(response => {
20
+ const responseJob = response.data;
21
+ setAdvancedValues({
22
+ effectiveUserValue: responseJob.effective_user?.value || '',
23
+ timeoutToKill: responseJob.job_template.execution_timeout_interval || '',
24
+ });
25
+ }, []);
62
26
  useEffect(() => {
63
27
  if (jobTemplateID) {
64
28
  dispatch(
@@ -75,7 +39,7 @@ export const JobWizard = () => {
75
39
  const isTemplate = !templateError && !!jobTemplateID;
76
40
  const steps = [
77
41
  {
78
- name: WIZARD_TITLES.categoryAndTemplate,
42
+ name: __('Category and Template'),
79
43
  component: (
80
44
  <CategoryAndTemplate
81
45
  jobTemplate={jobTemplateID}
@@ -86,19 +50,12 @@ export const JobWizard = () => {
86
50
  ),
87
51
  },
88
52
  {
89
- name: WIZARD_TITLES.hostsAndInputs,
90
- component: (
91
- <HostsAndInputs
92
- templateValues={templateValues}
93
- setTemplateValues={setTemplateValues}
94
- selectedHosts={selectedHosts}
95
- setSelectedHosts={setSelectedHosts}
96
- />
97
- ),
53
+ name: __('Target Hosts'),
54
+ component: <p>Target Hosts</p>,
98
55
  canJumpTo: isTemplate,
99
56
  },
100
57
  {
101
- name: WIZARD_TITLES.advanced,
58
+ name: __('Advanced Fields'),
102
59
  component: (
103
60
  <AdvancedFields
104
61
  advancedValues={advancedValues}
@@ -114,12 +71,12 @@ export const JobWizard = () => {
114
71
  canJumpTo: isTemplate,
115
72
  },
116
73
  {
117
- name: WIZARD_TITLES.schedule,
118
- component: <Schedule />,
74
+ name: __('Schedule'),
75
+ component: <p>Schedule</p>,
119
76
  canJumpTo: isTemplate,
120
77
  },
121
78
  {
122
- name: WIZARD_TITLES.review,
79
+ name: __('Review Details'),
123
80
  component: <p>Review Details</p>,
124
81
  nextButtonText: 'Run',
125
82
  canJumpTo: isTemplate,
@@ -1,10 +1,5 @@
1
1
  .job-wizard {
2
- .wizard-title {
3
- margin-bottom: 25px;
4
- }
5
-
6
2
  .pf-c-wizard__main {
7
- overflow: visible;
8
3
  z-index: calc(
9
4
  var(--pf-c-wizard__footer--ZIndex) + 1
10
5
  ); // So the select box can be shown above the wizard footer
@@ -15,58 +10,5 @@
15
10
  .advanced-fields-title {
16
11
  margin-bottom: 10px;
17
12
  }
18
- #advanced-fields-job-template {
19
- .foreman-search-field {
20
- .rbt-input-hint input{
21
- display: none;
22
- }
23
- // Giving pf3 search bar a pf4 look
24
- .search-bar {
25
- display: block;
26
- }
27
- .input-group-btn {
28
- display: none;
29
- }
30
- li {
31
- font-size: 16px;
32
- }
33
- input {
34
- font-size: 16px;
35
- height: 36px;
36
- }
37
- .foreman-autocomplete .autocomplete-focus-shortcut {
38
- top: 8px;
39
- font-size: 16px;
40
- }
41
- .foreman-autocomplete .autocomplete-aux {
42
- top: 8px;
43
- font-size: 16px;
44
- .autocomplete-clear-button {
45
- font-size: 16px;
46
- }
47
- }
48
- }
49
- }
50
- }
51
-
52
- .hosts-chip-group {
53
- margin-top: 8px;
54
- }
55
- input[type='radio'],
56
- input[type='checkbox'] {
57
- margin: 0;
58
- }
59
- .schedule-tab {
60
- input[type='radio'],
61
- input[type='checkbox'] {
62
- margin: 0;
63
- }
64
- .advanced-scheduling-button {
65
- text-align: start;
66
- }
67
- }
68
- textarea {
69
- min-height: 40px;
70
- min-width: 100px;
71
13
  }
72
14
  }
@@ -1,24 +1,6 @@
1
- import { translate as __ } from 'foremanReact/common/I18n';
2
1
  import { foremanUrl } from 'foremanReact/common/helpers';
3
2
 
4
3
  export const JOB_TEMPLATES = 'JOB_TEMPLATES';
5
4
  export const JOB_CATEGORIES = 'JOB_CATEGORIES';
6
5
  export const JOB_TEMPLATE = 'JOB_TEMPLATE';
7
6
  export const templatesUrl = foremanUrl('/api/v2/job_templates');
8
-
9
- export const repeatTypes = {
10
- noRepeat: __('Does not repeat'),
11
- cronline: __('Cronline'),
12
- monthly: __('Monthly'),
13
- weekly: __('Weekly'),
14
- daily: __('Daily'),
15
- hourly: __('Hourly'),
16
- };
17
-
18
- export const WIZARD_TITLES = {
19
- categoryAndTemplate: __('Category and Template'),
20
- hostsAndInputs: __('Target hosts and inputs'),
21
- advanced: __('Advanced Fields'),
22
- schedule: __('Schedule'),
23
- review: __('Review Details'),
24
- };
@@ -36,12 +36,3 @@ export const selectTemplateError = state =>
36
36
 
37
37
  export const selectJobTemplate = state =>
38
38
  selectAPIResponse(state, JOB_TEMPLATE);
39
-
40
- export const selectEffectiveUser = state =>
41
- selectAPIResponse(state, JOB_TEMPLATE).effective_user;
42
-
43
- export const selectAdvancedTemplateInputs = state =>
44
- selectAPIResponse(state, JOB_TEMPLATE).advanced_template_inputs || [];
45
-
46
- export const selectTemplateInputs = state =>
47
- selectAPIResponse(state, JOB_TEMPLATE).template_inputs || [];
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import * as patternfly from '@patternfly/react-core';
3
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
4
+ import JobWizardPage from '../index';
5
+
6
+ jest.spyOn(patternfly, 'Wizard');
7
+ patternfly.Wizard.mockImplementation(props => <div>{props.navAriaLabel}</div>);
8
+
9
+ const fixtures = {
10
+ 'renders ': {},
11
+ };
12
+ describe('JobWizardPage rendering', () =>
13
+ testComponentSnapshotsWithFixtures(JobWizardPage, fixtures));
@@ -0,0 +1,32 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`JobWizardPage rendering renders 1`] = `
4
+ <PageLayout
5
+ breadcrumbOptions={
6
+ Object {
7
+ "breadcrumbItems": Array [
8
+ Object {
9
+ "caption": "Jobs",
10
+ "url": "/jobs",
11
+ },
12
+ Object {
13
+ "caption": "Run job",
14
+ },
15
+ ],
16
+ }
17
+ }
18
+ header="Run job"
19
+ searchable={false}
20
+ >
21
+ <Title
22
+ headingLevel="h2"
23
+ size="2xl"
24
+ >
25
+ Run job
26
+ </Title>
27
+ <Divider
28
+ component="div"
29
+ />
30
+ <JobWizard />
31
+ </PageLayout>
32
+ `;
@@ -1,8 +1,6 @@
1
- import configureMockStore from 'redux-mock-store';
2
-
3
- export const jobTemplate = {
1
+ const jobTemplate = {
4
2
  id: 178,
5
- name: 'template1',
3
+ name: 'Run Command - Ansible Default',
6
4
  template:
7
5
  "---\n- hosts: all\n tasks:\n - shell:\n cmd: |\n<%= indent(10) { input('command') } %>\n register: out\n - debug: var=out",
8
6
  snippet: false,
@@ -25,112 +23,4 @@ export const jobTemplateResponse = {
25
23
  overridable: true,
26
24
  current_user: false,
27
25
  },
28
- advanced_template_inputs: [
29
- {
30
- name: 'adv plain hidden',
31
- required: true,
32
- input_type: 'user',
33
- description: 'some Description',
34
- advanced: true,
35
- value_type: 'plain',
36
- resource_type: 'ansible_roles',
37
- default: 'Default val',
38
- hidden_value: true,
39
- },
40
- {
41
- name: 'adv plain select',
42
- required: false,
43
- input_type: 'user',
44
- options: 'option 1\r\noption 2\r\noption 3\r\noption 4',
45
- advanced: true,
46
- value_type: 'plain',
47
- resource_type: 'ansible_roles',
48
- default: '',
49
- hidden_value: false,
50
- },
51
- {
52
- name: 'adv search',
53
- required: false,
54
- options: '',
55
- advanced: true,
56
- value_type: 'search',
57
- resource_type: 'foreman_tasks/tasks',
58
- default: '',
59
- hidden_value: false,
60
- },
61
- {
62
- name: 'adv date',
63
- required: false,
64
- options: '',
65
- advanced: true,
66
- value_type: 'date',
67
- resource_type: 'ansible_roles',
68
- default: '',
69
- hidden_value: false,
70
- },
71
- ],
72
- template_inputs: [
73
- {
74
- name: 'plain hidden',
75
- required: true,
76
- input_type: 'user',
77
- description: 'some Description',
78
- advanced: false,
79
- value_type: 'plain',
80
- resource_type: 'ansible_roles',
81
- default: 'Default val',
82
- hidden_value: true,
83
- },
84
- ],
85
- };
86
-
87
- export const jobCategories = ['Ansible Commands', 'Puppet', 'Services'];
88
-
89
- export const testSetup = (selectors, api) => {
90
- jest.spyOn(api, 'get');
91
- jest.spyOn(selectors, 'selectJobTemplate');
92
- jest.spyOn(selectors, 'selectJobTemplates');
93
- jest.spyOn(selectors, 'selectJobCategories');
94
- jest.spyOn(selectors, 'selectJobCategoriesStatus');
95
-
96
- jest.spyOn(selectors, 'selectTemplateInputs');
97
- jest.spyOn(selectors, 'selectAdvancedTemplateInputs');
98
- selectors.selectTemplateInputs.mockImplementation(
99
- () => jobTemplateResponse.template_inputs
100
- );
101
- selectors.selectAdvancedTemplateInputs.mockImplementation(
102
- () => jobTemplateResponse.advanced_template_inputs
103
- );
104
- selectors.selectJobCategories.mockImplementation(() => jobCategories);
105
- selectors.selectJobTemplates.mockImplementation(() => [
106
- jobTemplate,
107
- { ...jobTemplate, id: 2, name: 'template2' },
108
- ]);
109
- const mockStore = configureMockStore([]);
110
- const store = mockStore({});
111
- return store;
112
- };
113
-
114
- export const mockTemplate = selectors => {
115
- selectors.selectJobTemplate.mockImplementation(() => jobTemplate);
116
- selectors.selectJobCategoriesStatus.mockImplementation(() => 'RESOLVED');
117
- };
118
- export const mockApi = api => {
119
- api.get.mockImplementation(({ handleSuccess, ...action }) => {
120
- if (action.key === 'JOB_CATEGORIES') {
121
- handleSuccess &&
122
- handleSuccess({ data: { job_categories: jobCategories } });
123
- } else if (action.key === 'JOB_TEMPLATE') {
124
- handleSuccess &&
125
- handleSuccess({
126
- data: jobTemplateResponse,
127
- });
128
- } else if (action.key === 'JOB_TEMPLATES') {
129
- handleSuccess &&
130
- handleSuccess({
131
- data: { results: [jobTemplate] },
132
- });
133
- }
134
- return { type: 'get', ...action };
135
- });
136
26
  };
@@ -1,28 +1,40 @@
1
1
  import React from 'react';
2
2
  import { Provider } from 'react-redux';
3
+ import configureMockStore from 'redux-mock-store';
3
4
  import { mount } from '@theforeman/test';
4
5
  import { render, fireEvent, screen, act } from '@testing-library/react';
5
6
  import * as api from 'foremanReact/redux/API';
6
7
  import { JobWizard } from '../JobWizard';
7
8
  import * as selectors from '../JobWizardSelectors';
8
- import { WIZARD_TITLES } from '../JobWizardConstants';
9
- import {
10
- testSetup,
11
- mockApi,
12
- jobCategories,
13
- jobTemplateResponse as jobTemplate,
14
- } from './fixtures';
9
+ import { jobTemplates, jobTemplateResponse as jobTemplate } from './fixtures';
15
10
 
16
- const store = testSetup(selectors, api);
11
+ jest.spyOn(api, 'get');
12
+ jest.spyOn(selectors, 'selectJobTemplate');
13
+ jest.spyOn(selectors, 'selectJobTemplates');
14
+ jest.spyOn(selectors, 'selectJobCategories');
15
+ jest.spyOn(selectors, 'selectJobCategoriesStatus');
17
16
 
18
- selectors.selectJobTemplate.mockImplementation(() => {});
17
+ const jobCategories = ['Ansible Commands', 'Puppet', 'Services'];
19
18
 
20
19
  api.get.mockImplementation(({ handleSuccess, ...action }) => {
21
20
  if (action.key === 'JOB_CATEGORIES') {
22
21
  handleSuccess && handleSuccess({ data: { job_categories: jobCategories } });
22
+ } else if (action.key === 'JOB_TEMPLATE') {
23
+ handleSuccess &&
24
+ handleSuccess({
25
+ data: jobTemplate,
26
+ });
23
27
  }
24
28
  return { type: 'get', ...action };
25
29
  });
30
+
31
+ selectors.selectJobTemplate.mockImplementation(() => null);
32
+ selectors.selectJobCategories.mockImplementation(() => jobCategories);
33
+ selectors.selectJobCategoriesStatus.mockImplementation(() => null);
34
+ selectors.selectJobTemplates.mockImplementation(() => jobTemplates);
35
+
36
+ const mockStore = configureMockStore([]);
37
+ const store = mockStore({});
26
38
  describe('Job wizard fill', () => {
27
39
  it('should select template', async () => {
28
40
  const wrapper = mount(
@@ -39,10 +51,7 @@ describe('Job wizard fill', () => {
39
51
  selectors.selectJobTemplate.mockImplementation(() => jobTemplate);
40
52
  wrapper.find('.pf-c-button.pf-c-select__toggle-button').simulate('click');
41
53
  await act(async () => {
42
- await wrapper
43
- .find('.pf-c-select__menu-item')
44
- .first()
45
- .simulate('click');
54
+ await wrapper.find('.pf-c-select__menu-item').simulate('click');
46
55
  await wrapper.update();
47
56
  });
48
57
  expect(store.getActions().slice(-1)).toMatchSnapshot('select template');
@@ -51,20 +60,87 @@ describe('Job wizard fill', () => {
51
60
  );
52
61
  });
53
62
 
63
+ it('should save data between steps for advanced fields', async () => {
64
+ const wrapper = mount(
65
+ <Provider store={store}>
66
+ <JobWizard advancedValues={{}} setAdvancedValues={jest.fn()} />
67
+ </Provider>
68
+ );
69
+ // setup
70
+ selectors.selectJobCategoriesStatus.mockImplementation(() => 'RESOLVED');
71
+ selectors.selectJobTemplate.mockImplementation(() => jobTemplate);
72
+ wrapper.find('.pf-c-button.pf-c-select__toggle-button').simulate('click');
73
+ wrapper.find('.pf-c-select__menu-item').simulate('click');
74
+
75
+ // test
76
+ expect(wrapper.find('.pf-c-wizard__nav-link.pf-m-disabled')).toHaveLength(
77
+ 0
78
+ );
79
+ wrapper
80
+ .find('.pf-c-wizard__nav-link')
81
+ .at(2)
82
+ .simulate('click'); // Advanced step
83
+ const effectiveUserInput = () => wrapper.find('input#effective-user');
84
+ const effectiveUesrValue = 'effective user new value';
85
+ effectiveUserInput().getDOMNode().value = effectiveUesrValue;
86
+ await act(async () => {
87
+ await effectiveUserInput().simulate('change');
88
+ wrapper.update();
89
+ });
90
+
91
+ expect(effectiveUserInput().prop('value')).toEqual(effectiveUesrValue);
92
+
93
+ wrapper
94
+ .find('.pf-c-wizard__nav-link')
95
+ .at(1)
96
+ .simulate('click');
97
+
98
+ expect(wrapper.find('.pf-c-wizard__nav-link.pf-m-current').text()).toEqual(
99
+ 'Target Hosts'
100
+ );
101
+ wrapper
102
+ .find('.pf-c-wizard__nav-link')
103
+ .at(2)
104
+ .simulate('click'); // Advanced step
105
+
106
+ expect(effectiveUserInput().prop('value')).toEqual(effectiveUesrValue);
107
+ });
108
+
54
109
  it('have all steps', async () => {
55
110
  selectors.selectJobCategoriesStatus.mockImplementation(() => null);
56
111
  selectors.selectJobTemplate.mockRestore();
57
112
  selectors.selectJobTemplates.mockRestore();
58
113
  selectors.selectJobCategories.mockRestore();
59
- mockApi(api);
114
+ api.get.mockImplementation(({ handleSuccess, ...action }) => {
115
+ if (action.key === 'JOB_CATEGORIES') {
116
+ handleSuccess &&
117
+ handleSuccess({ data: { job_categories: jobCategories } });
118
+ } else if (action.key === 'JOB_TEMPLATE') {
119
+ handleSuccess &&
120
+ handleSuccess({
121
+ data: jobTemplate,
122
+ });
123
+ } else if (action.key === 'JOB_TEMPLATES') {
124
+ handleSuccess &&
125
+ handleSuccess({
126
+ data: { results: [jobTemplate.job_template] },
127
+ });
128
+ }
129
+ return { type: 'get', ...action };
130
+ });
60
131
 
61
132
  render(
62
133
  <Provider store={store}>
63
134
  <JobWizard />
64
135
  </Provider>
65
136
  );
66
- const titles = Object.values(WIZARD_TITLES);
67
- const steps = [titles[1], titles[0], ...titles.slice(2)]; // the first title is selected at the beggining
137
+ const steps = [
138
+ 'Target Hosts',
139
+ 'Advanced Fields',
140
+ 'Schedule',
141
+ 'Review Details',
142
+ 'Category and Template',
143
+ ];
68
144
  // eslint-disable-next-line no-unused-vars
69
145
  for await (const step of steps) {
70
146
  const stepSelector = screen.getByText(step);
@@ -1,12 +1,9 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { useSelector } from 'react-redux';
4
- import { Form } from '@patternfly/react-core';
5
- import {
6
- selectEffectiveUser,
7
- selectAdvancedTemplateInputs,
8
- selectTemplateInputs,
9
- } from '../../JobWizardSelectors';
4
+ import { Title, Form } from '@patternfly/react-core';
5
+ import { translate as __ } from 'foremanReact/common/I18n';
6
+ import { selectJobTemplate } from '../../JobWizardSelectors';
10
7
  import {
11
8
  EffectiveUserField,
12
9
  TimeoutToKillField,
@@ -15,29 +12,17 @@ import {
15
12
  EffectiveUserPasswordField,
16
13
  ConcurrencyLevelField,
17
14
  TimeSpanLevelField,
18
- TemplateInputsFields,
19
- ExecutionOrderingField,
20
15
  } from './Fields';
21
- import { DescriptionField } from './DescriptionField';
22
- import { WIZARD_TITLES } from '../../JobWizardConstants';
23
- import { WizardTitle } from '../form/WizardTitle';
24
16
 
25
17
  export const AdvancedFields = ({ advancedValues, setAdvancedValues }) => {
26
- const effectiveUser = useSelector(selectEffectiveUser);
27
- const advancedTemplateInputs = useSelector(selectAdvancedTemplateInputs);
28
- const templateInputs = useSelector(selectTemplateInputs);
18
+ const jobTemplate = useSelector(selectJobTemplate);
19
+ const effectiveUser = jobTemplate.effective_user;
29
20
  return (
30
21
  <>
31
- <WizardTitle
32
- title={WIZARD_TITLES.advanced}
33
- className="advanced-fields-title"
34
- />
35
- <Form id="advanced-fields-job-template" autoComplete="off">
36
- <TemplateInputsFields
37
- inputs={advancedTemplateInputs}
38
- value={advancedValues.templateValues}
39
- setValue={newValue => setAdvancedValues({ templateValues: newValue })}
40
- />
22
+ <Title headingLevel="h2" className="advanced-fields-title">
23
+ {__('Advanced Fields')}
24
+ </Title>
25
+ <Form>
41
26
  {effectiveUser?.overridable && (
42
27
  <EffectiveUserField
43
28
  value={advancedValues.effectiveUserValue}
@@ -48,11 +33,6 @@ export const AdvancedFields = ({ advancedValues, setAdvancedValues }) => {
48
33
  }
49
34
  />
50
35
  )}
51
- <DescriptionField
52
- inputs={templateInputs}
53
- value={advancedValues.description}
54
- setValue={newValue => setAdvancedValues({ description: newValue })}
55
- />
56
36
  <TimeoutToKillField
57
37
  value={advancedValues.timeoutToKill}
58
38
  setValue={newValue =>
@@ -101,14 +81,6 @@ export const AdvancedFields = ({ advancedValues, setAdvancedValues }) => {
101
81
  })
102
82
  }
103
83
  />
104
- <ExecutionOrderingField
105
- isRandomizedOrdering={advancedValues.isRandomizedOrdering}
106
- setValue={newValue =>
107
- setAdvancedValues({
108
- isRandomizedOrdering: newValue,
109
- })
110
- }
111
- />
112
84
  </Form>
113
85
  </>
114
86
  );