foreman_remote_execution 4.5.6 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  );