foreman_remote_execution 16.6.5 → 16.7.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.
- checksums.yaml +4 -4
- data/app/controllers/api/v2/job_invocations_controller.rb +22 -13
- data/app/views/api/v2/job_invocations/main.json.rabl +15 -11
- data/lib/foreman_remote_execution/version.rb +1 -1
- data/package.json +3 -3
- data/test/functional/api/v2/job_invocations_controller_test.rb +68 -3
- data/webpack/JobInvocationDetail/CheckboxesActions.js +4 -10
- data/webpack/JobInvocationDetail/JobInvocationActions.js +2 -1
- data/webpack/JobInvocationDetail/JobInvocationConstants.js +4 -4
- data/webpack/JobInvocationDetail/JobInvocationEmptyState.js +52 -0
- data/webpack/JobInvocationDetail/JobInvocationSelectors.js +0 -15
- data/webpack/JobInvocationDetail/JobInvocationToolbarButtons.js +201 -150
- data/webpack/JobInvocationDetail/__tests__/JobInvocationDetailEmptyState.test.js +53 -0
- data/webpack/JobInvocationDetail/__tests__/MainInformation.test.js +109 -11
- data/webpack/JobInvocationDetail/__tests__/TableToolbarActions.test.js +3 -1
- data/webpack/JobInvocationDetail/__tests__/foremanTestHelpers.js +30 -0
- data/webpack/JobInvocationDetail/index.js +42 -9
- data/webpack/__mocks__/foremanReact/Root/Context/ForemanContext/index.js +15 -0
- data/webpack/__mocks__/foremanReact/common/hooks/Permissions/permissionHooks.js +1 -0
- data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +5 -0
- metadata +6 -2
|
@@ -2,6 +2,7 @@ import '@testing-library/jest-dom/extend-expect';
|
|
|
2
2
|
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
3
3
|
import axios from 'axios';
|
|
4
4
|
import { foremanUrl } from 'foremanReact/common/helpers';
|
|
5
|
+
import { usePermissions } from 'foremanReact/common/hooks/Permissions/permissionHooks';
|
|
5
6
|
import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
|
|
6
7
|
import React from 'react';
|
|
7
8
|
import { Provider } from 'react-redux';
|
|
@@ -13,6 +14,7 @@ import { PopupAlert } from '../OpenAllInvocationsModal';
|
|
|
13
14
|
|
|
14
15
|
jest.mock('axios');
|
|
15
16
|
jest.mock('foremanReact/common/hooks/API/APIHooks');
|
|
17
|
+
jest.mock('foremanReact/common/hooks/Permissions/permissionHooks');
|
|
16
18
|
jest.mock('../JobInvocationSelectors');
|
|
17
19
|
|
|
18
20
|
jest.mock('../JobInvocationConstants', () => ({
|
|
@@ -26,8 +28,8 @@ jest.mock('../JobInvocationConstants', () => ({
|
|
|
26
28
|
selectors.selectItems.mockImplementation(() => ({
|
|
27
29
|
targeting: { search_query: 'name~*' },
|
|
28
30
|
}));
|
|
29
|
-
selectors.selectHasPermission.mockImplementation(() => () => true);
|
|
30
31
|
selectors.selectTaskCancelable.mockImplementation(() => true);
|
|
32
|
+
usePermissions.mockReturnValue(true);
|
|
31
33
|
|
|
32
34
|
const mockStore = configureStore([]);
|
|
33
35
|
const store = mockStore({});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { getForemanContext } from 'foremanReact/Root/Context/ForemanContext';
|
|
4
|
+
|
|
5
|
+
export const createForemanContextWrapper = (
|
|
6
|
+
permissions = ['view_job_invocations', 'create_job_invocations']
|
|
7
|
+
) => {
|
|
8
|
+
const foremanContextValue = {
|
|
9
|
+
context: {
|
|
10
|
+
metadata: {
|
|
11
|
+
permissions: new Set(permissions),
|
|
12
|
+
UISettings: { perPage: 20 },
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
setContext: jest.fn(),
|
|
16
|
+
};
|
|
17
|
+
const ForemanContext = getForemanContext(foremanContextValue);
|
|
18
|
+
|
|
19
|
+
const ForemanContextWrapper = ({ children }) => (
|
|
20
|
+
<ForemanContext.Provider value={foremanContextValue}>
|
|
21
|
+
{children}
|
|
22
|
+
</ForemanContext.Provider>
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
ForemanContextWrapper.propTypes = {
|
|
26
|
+
children: PropTypes.node.isRequired,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
return ForemanContextWrapper;
|
|
30
|
+
};
|
|
@@ -5,29 +5,33 @@ import {
|
|
|
5
5
|
PageSectionVariants,
|
|
6
6
|
Skeleton,
|
|
7
7
|
} from '@patternfly/react-core';
|
|
8
|
-
import React, { useEffect, useState } from 'react';
|
|
8
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
9
9
|
import { translate as __, documentLocale } from 'foremanReact/common/I18n';
|
|
10
10
|
import { useDispatch, useSelector } from 'react-redux';
|
|
11
11
|
import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
|
|
12
12
|
import PropTypes from 'prop-types';
|
|
13
13
|
import SkeletonLoader from 'foremanReact/components/common/SkeletonLoader';
|
|
14
14
|
import { stopInterval } from 'foremanReact/redux/middlewares/IntervalMiddleware';
|
|
15
|
-
import {
|
|
15
|
+
import { STATUS as API_STATUS } from 'foremanReact/constants';
|
|
16
|
+
import {
|
|
17
|
+
selectAPIErrorMessage,
|
|
18
|
+
selectAPIHttpStatus,
|
|
19
|
+
selectAPIStatus,
|
|
20
|
+
} from 'foremanReact/redux/API/APISelectors';
|
|
16
21
|
|
|
17
22
|
import { JobAdditionInfo } from './JobAdditionInfo';
|
|
18
23
|
import JobInvocationHostTable from './JobInvocationHostTable';
|
|
19
24
|
import JobInvocationOverview from './JobInvocationOverview';
|
|
20
25
|
import JobInvocationSystemStatusChart from './JobInvocationSystemStatusChart';
|
|
26
|
+
import JobInvocationEmptyState from './JobInvocationEmptyState';
|
|
21
27
|
import JobInvocationToolbarButtons from './JobInvocationToolbarButtons';
|
|
22
28
|
import { getJobInvocation, getTask } from './JobInvocationActions';
|
|
23
29
|
import './JobInvocationDetail.scss';
|
|
24
30
|
import {
|
|
25
|
-
CURRENT_PERMISSIONS,
|
|
26
31
|
DATE_OPTIONS,
|
|
27
32
|
JOB_INVOCATION_KEY,
|
|
28
33
|
STATUS,
|
|
29
34
|
STATUS_UPPERCASE,
|
|
30
|
-
currentPermissionsUrl,
|
|
31
35
|
} from './JobInvocationConstants';
|
|
32
36
|
import { selectItems } from './JobInvocationSelectors';
|
|
33
37
|
|
|
@@ -51,9 +55,15 @@ const JobInvocationDetailPage = ({
|
|
|
51
55
|
statusLabel === STATUS.SUCCEEDED ||
|
|
52
56
|
statusLabel === STATUS.CANCELLED;
|
|
53
57
|
const autoRefresh = task?.state === STATUS.PENDING || false;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
const jobInvocationApiStatus = useSelector(state =>
|
|
59
|
+
selectAPIStatus(state, JOB_INVOCATION_KEY)
|
|
60
|
+
);
|
|
61
|
+
const jobInvocationErrorMessage = useSelector(state =>
|
|
62
|
+
selectAPIErrorMessage(state, JOB_INVOCATION_KEY)
|
|
63
|
+
);
|
|
64
|
+
const jobInvocationHttpStatus = useSelector(state =>
|
|
65
|
+
selectAPIHttpStatus(state, JOB_INVOCATION_KEY)
|
|
66
|
+
);
|
|
57
67
|
const [selectedFilter, setSelectedFilter] = useState('');
|
|
58
68
|
|
|
59
69
|
const handleFilterChange = newFilter => {
|
|
@@ -72,7 +82,7 @@ const JobInvocationDetailPage = ({
|
|
|
72
82
|
}
|
|
73
83
|
|
|
74
84
|
useEffect(() => {
|
|
75
|
-
dispatch(getJobInvocation(`/api/job_invocations/${id}
|
|
85
|
+
dispatch(getJobInvocation(`/api/job_invocations/${id}`));
|
|
76
86
|
if (finished && !autoRefresh) {
|
|
77
87
|
dispatch(stopInterval(JOB_INVOCATION_KEY));
|
|
78
88
|
}
|
|
@@ -88,6 +98,25 @@ const JobInvocationDetailPage = ({
|
|
|
88
98
|
}
|
|
89
99
|
}, [dispatch, taskId]);
|
|
90
100
|
|
|
101
|
+
const apiFailed = jobInvocationApiStatus === API_STATUS.ERROR;
|
|
102
|
+
|
|
103
|
+
const backendErrorMessage = useMemo(() => {
|
|
104
|
+
if (jobInvocationApiStatus === API_STATUS.ERROR) {
|
|
105
|
+
return jobInvocationErrorMessage || null;
|
|
106
|
+
}
|
|
107
|
+
return null;
|
|
108
|
+
}, [jobInvocationApiStatus, jobInvocationErrorMessage]);
|
|
109
|
+
|
|
110
|
+
if (apiFailed) {
|
|
111
|
+
return (
|
|
112
|
+
<JobInvocationEmptyState
|
|
113
|
+
jobInvocationId={id}
|
|
114
|
+
httpStatus={jobInvocationHttpStatus}
|
|
115
|
+
errorMessage={backendErrorMessage}
|
|
116
|
+
/>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
91
120
|
const pageStatus =
|
|
92
121
|
items.id === undefined
|
|
93
122
|
? STATUS_UPPERCASE.PENDING
|
|
@@ -123,7 +152,11 @@ const JobInvocationDetailPage = ({
|
|
|
123
152
|
<PageLayout
|
|
124
153
|
header={description}
|
|
125
154
|
breadcrumbOptions={breadcrumbOptions}
|
|
126
|
-
toolbarButtons={
|
|
155
|
+
toolbarButtons={
|
|
156
|
+
items.id !== undefined && (
|
|
157
|
+
<JobInvocationToolbarButtons jobId={id} data={items} />
|
|
158
|
+
)
|
|
159
|
+
}
|
|
127
160
|
searchable={false}
|
|
128
161
|
>
|
|
129
162
|
<Flex className="job-invocation-detail-flex">
|
|
@@ -1,6 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const getForemanContext = contextData => {
|
|
4
|
+
window.tfm_forced_singletons = window.tfm_forced_singletons || {};
|
|
5
|
+
|
|
6
|
+
if (!window.tfm_forced_singletons.Context) {
|
|
7
|
+
window.tfm_forced_singletons.Context = React.createContext(contextData);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return window.tfm_forced_singletons.Context;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { getForemanContext };
|
|
1
14
|
export const useForemanOrganization = () => ({ id: 1 });
|
|
2
15
|
export const useForemanLocation = () => ({ id: 2 });
|
|
3
16
|
export const useForemanVersion = () => '3.7';
|
|
4
17
|
export const useForemanHostsPageUrl = () => '/hosts';
|
|
5
18
|
export const useForemanHostDetailsPageUrl = () => '/hosts/';
|
|
6
19
|
export const useForemanSettings = () => ({ perPage: 20 });
|
|
20
|
+
export const useForemanPermissions = () =>
|
|
21
|
+
new Set(['view_job_invocations', 'create_job_invocations']);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const usePermissions = jest.fn(() => true);
|
|
@@ -19,3 +19,8 @@ export const selectAPIErrorMessage = (state, key) => {
|
|
|
19
19
|
const error = selectAPIError(state, key);
|
|
20
20
|
return error && error.message;
|
|
21
21
|
};
|
|
22
|
+
|
|
23
|
+
export const selectAPIHttpStatus = (state, key) => {
|
|
24
|
+
const error = selectAPIError(state, key);
|
|
25
|
+
return error?.response?.status;
|
|
26
|
+
};
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foreman_remote_execution
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 16.
|
|
4
|
+
version: 16.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Foreman Remote Execution team
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-07-13 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: deface
|
|
@@ -382,6 +382,7 @@ files:
|
|
|
382
382
|
- webpack/JobInvocationDetail/JobInvocationActions.js
|
|
383
383
|
- webpack/JobInvocationDetail/JobInvocationConstants.js
|
|
384
384
|
- webpack/JobInvocationDetail/JobInvocationDetail.scss
|
|
385
|
+
- webpack/JobInvocationDetail/JobInvocationEmptyState.js
|
|
385
386
|
- webpack/JobInvocationDetail/JobInvocationHostTable.js
|
|
386
387
|
- webpack/JobInvocationDetail/JobInvocationOverview.js
|
|
387
388
|
- webpack/JobInvocationDetail/JobInvocationSelectors.js
|
|
@@ -395,11 +396,13 @@ files:
|
|
|
395
396
|
- webpack/JobInvocationDetail/TemplateInvocationComponents/TemplateActionButtons.js
|
|
396
397
|
- webpack/JobInvocationDetail/TemplateInvocationComponents/index.scss
|
|
397
398
|
- webpack/JobInvocationDetail/TemplateInvocationPage.js
|
|
399
|
+
- webpack/JobInvocationDetail/__tests__/JobInvocationDetailEmptyState.test.js
|
|
398
400
|
- webpack/JobInvocationDetail/__tests__/MainInformation.test.js
|
|
399
401
|
- webpack/JobInvocationDetail/__tests__/OutputCodeBlock.test.js
|
|
400
402
|
- webpack/JobInvocationDetail/__tests__/TableToolbarActions.test.js
|
|
401
403
|
- webpack/JobInvocationDetail/__tests__/TemplateInvocation.test.js
|
|
402
404
|
- webpack/JobInvocationDetail/__tests__/fixtures.js
|
|
405
|
+
- webpack/JobInvocationDetail/__tests__/foremanTestHelpers.js
|
|
403
406
|
- webpack/JobInvocationDetail/index.js
|
|
404
407
|
- webpack/JobWizard/Footer.js
|
|
405
408
|
- webpack/JobWizard/JobWizard.js
|
|
@@ -469,6 +472,7 @@ files:
|
|
|
469
472
|
- webpack/__mocks__/foremanReact/common/globalIdHelpers.js
|
|
470
473
|
- webpack/__mocks__/foremanReact/common/helpers.js
|
|
471
474
|
- webpack/__mocks__/foremanReact/common/hooks/API/APIHooks.js
|
|
475
|
+
- webpack/__mocks__/foremanReact/common/hooks/Permissions/permissionHooks.js
|
|
472
476
|
- webpack/__mocks__/foremanReact/components/AutoComplete/AutoCompleteActions.js
|
|
473
477
|
- webpack/__mocks__/foremanReact/components/AutoComplete/AutoCompleteConstants.js
|
|
474
478
|
- webpack/__mocks__/foremanReact/components/BreadcrumbBar/index.js
|