foreman_leapp 4.2.0 → 4.3.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/assets/javascripts/foreman_leapp/locale/de/foreman_leapp.js +2 -2
- data/app/assets/javascripts/foreman_leapp/locale/en/foreman_leapp.js +1 -1
- data/app/assets/javascripts/foreman_leapp/locale/fr/foreman_leapp.js +12 -12
- data/app/assets/javascripts/foreman_leapp/locale/ja/foreman_leapp.js +12 -12
- data/app/assets/javascripts/foreman_leapp/locale/ka/foreman_leapp.js +1 -1
- data/app/assets/javascripts/foreman_leapp/locale/ko/foreman_leapp.js +13 -13
- data/app/assets/javascripts/foreman_leapp/locale/zh_CN/foreman_leapp.js +12 -12
- data/app/controllers/api/v2/preupgrade_report_entries_controller.rb +17 -29
- data/app/controllers/concerns/foreman_leapp/preupgrade_report_entry_bulk_remediate.rb +69 -0
- data/config/routes.rb +1 -2
- data/lib/foreman_leapp/engine.rb +1 -12
- data/lib/foreman_leapp/version.rb +1 -1
- data/locale/de/LC_MESSAGES/foreman_leapp.mo +0 -0
- data/locale/de/foreman_leapp.po +3 -3
- data/locale/en/LC_MESSAGES/foreman_leapp.mo +0 -0
- data/locale/en/foreman_leapp.po +1 -1
- data/locale/foreman_leapp.pot +2 -2
- data/locale/fr/LC_MESSAGES/foreman_leapp.mo +0 -0
- data/locale/fr/foreman_leapp.po +13 -13
- data/locale/ja/LC_MESSAGES/foreman_leapp.mo +0 -0
- data/locale/ja/foreman_leapp.po +13 -13
- data/locale/ka/LC_MESSAGES/foreman_leapp.mo +0 -0
- data/locale/ka/foreman_leapp.po +1 -1
- data/locale/ko/LC_MESSAGES/foreman_leapp.mo +0 -0
- data/locale/ko/foreman_leapp.po +15 -16
- data/locale/zh_CN/LC_MESSAGES/foreman_leapp.mo +0 -0
- data/locale/zh_CN/foreman_leapp.po +13 -13
- data/package.json +0 -1
- data/test/functional/api/v2/preupgrade_report_entries_controller_test.rb +64 -0
- data/webpack/components/PreupgradeReportsTable/PreupgradeReportsTableHelpers.js +43 -16
- data/webpack/components/PreupgradeReportsTable/__tests__/PreupgradeReportsTable.test.js +41 -8
- data/webpack/components/PreupgradeReportsTable/index.js +64 -71
- data/webpack/index.js +0 -13
- metadata +3 -66
- data/app/controllers/preupgrade_reports_controller.rb +0 -17
- data/app/views/job_invocations/_leapp_preupgrade_report.html.erb +0 -11
- data/app/views/preupgrade_report_entries/base.json.rabl +0 -4
- data/app/views/preupgrade_reports/index.json.rabl +0 -3
- data/app/views/preupgrade_reports/show.json.rabl +0 -7
- data/test/functional/preupgrade_reports_controller_test.rb +0 -39
- data/webpack/components/PreupgradeReports/PreupgradeReports.js +0 -154
- data/webpack/components/PreupgradeReports/PreupgradeReportsActions.js +0 -31
- data/webpack/components/PreupgradeReports/PreupgradeReportsHelpers.js +0 -152
- data/webpack/components/PreupgradeReports/PreupgradeReportsReducer.js +0 -37
- data/webpack/components/PreupgradeReports/PreupgradeReportsSelectors.js +0 -18
- data/webpack/components/PreupgradeReports/__tests__/PreupgradeReports.fixtures.js +0 -129
- data/webpack/components/PreupgradeReports/__tests__/PreupgradeReports.test.js +0 -159
- data/webpack/components/PreupgradeReports/__tests__/PreupgradeReportsHelpers.test.js +0 -78
- data/webpack/components/PreupgradeReports/__tests__/PreupgradeReportsReducer.test.js +0 -44
- data/webpack/components/PreupgradeReports/__tests__/PreupgradeReportsSelectors.test.js +0 -28
- data/webpack/components/PreupgradeReports/__tests__/__snapshots__/PreupgradeReportsHelpers.test.js.snap +0 -489
- data/webpack/components/PreupgradeReports/__tests__/__snapshots__/PreupgradeReportsReducer.test.js.snap +0 -102
- data/webpack/components/PreupgradeReports/__tests__/__snapshots__/PreupgradeReportsSelectors.test.js.snap +0 -76
- data/webpack/components/PreupgradeReports/components/EntriesFilter.js +0 -121
- data/webpack/components/PreupgradeReports/components/EntriesFilter.scss +0 -3
- data/webpack/components/PreupgradeReports/components/EntriesFilter.test.js +0 -30
- data/webpack/components/PreupgradeReports/components/FixSelectedButton.js +0 -35
- data/webpack/components/PreupgradeReports/components/FixSelectedButton.test.js +0 -15
- data/webpack/components/PreupgradeReports/components/NoReports.js +0 -35
- data/webpack/components/PreupgradeReports/components/NoReports.test.js +0 -29
- data/webpack/components/PreupgradeReports/components/UpgradeAllButton.js +0 -28
- data/webpack/components/PreupgradeReports/components/UpgradeAllButton.test.js +0 -17
- data/webpack/components/PreupgradeReports/components/__snapshots__/EntriesFilter.test.js.snap +0 -330
- data/webpack/components/PreupgradeReports/components/__snapshots__/FixSelectedButton.test.js.snap +0 -40
- data/webpack/components/PreupgradeReports/components/__snapshots__/UpgradeAllButton.test.js.snap +0 -41
- data/webpack/components/PreupgradeReports/index.js +0 -57
- data/webpack/components/PreupgradeReportsList/PreupgradeReportList.scss +0 -37
- data/webpack/components/PreupgradeReportsList/__tests__/PreupgradeReportsList.test.js +0 -124
- data/webpack/components/PreupgradeReportsList/components/EmptyInfoItem.js +0 -16
- data/webpack/components/PreupgradeReportsList/components/InfoItem.js +0 -34
- data/webpack/components/PreupgradeReportsList/components/InhibitorInfoItem.js +0 -33
- data/webpack/components/PreupgradeReportsList/components/PreupgradeReportEntry.js +0 -64
- data/webpack/components/PreupgradeReportsList/components/PreupgradeReportsListHeader.js +0 -56
- data/webpack/components/PreupgradeReportsList/components/SortableHeaderItem.js +0 -50
- data/webpack/components/PreupgradeReportsList/components/__tests__/EmptyInfoItem.test.js +0 -13
- data/webpack/components/PreupgradeReportsList/components/__tests__/InhibitorInfoItem.test.js +0 -27
- data/webpack/components/PreupgradeReportsList/components/__tests__/PreupgradeReportEntry.fixtures.js +0 -38
- data/webpack/components/PreupgradeReportsList/components/__tests__/PreupgradeReportEntry.test.js +0 -14
- data/webpack/components/PreupgradeReportsList/components/__tests__/PreupgradeReportsListHeader.test.js +0 -14
- data/webpack/components/PreupgradeReportsList/components/__tests__/SortableHeaderItem.test.js +0 -29
- data/webpack/components/PreupgradeReportsList/components/__tests__/__snapshots__/EmptyInfoItem.test.js.snap +0 -8
- data/webpack/components/PreupgradeReportsList/components/__tests__/__snapshots__/InhibitorInfoItem.test.js.snap +0 -32
- data/webpack/components/PreupgradeReportsList/components/__tests__/__snapshots__/PreupgradeReportEntry.test.js.snap +0 -134
- data/webpack/components/PreupgradeReportsList/components/__tests__/__snapshots__/PreupgradeReportsListHeader.test.js.snap +0 -113
- data/webpack/components/PreupgradeReportsList/components/__tests__/__snapshots__/SortableHeaderItem.test.js.snap +0 -36
- data/webpack/components/PreupgradeReportsList/components/__tests__/__snapshots__/helpers.test.js.snap +0 -197
- data/webpack/components/PreupgradeReportsList/components/__tests__/helpers.test.js +0 -28
- data/webpack/components/PreupgradeReportsList/components/foreman_leapp.scss +0 -15
- data/webpack/components/PreupgradeReportsList/components/helpers.js +0 -186
- data/webpack/components/PreupgradeReportsList/components/images/i_severity-critical.svg +0 -61
- data/webpack/components/PreupgradeReportsList/components/images/i_severity-high.svg +0 -61
- data/webpack/components/PreupgradeReportsList/components/images/i_severity-low.svg +0 -62
- data/webpack/components/PreupgradeReportsList/components/images/i_severity-med.svg +0 -62
- data/webpack/components/PreupgradeReportsList/index.js +0 -61
- data/webpack/consts.js +0 -3
- data/webpack/csrf.js +0 -4
- data/webpack/reducer.js +0 -5
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import api from 'foremanReact/API';
|
|
2
|
-
import { deepPropsToCamelCase } from 'foremanReact/common/helpers';
|
|
3
|
-
import { translate as __ } from 'foremanReact/common/I18n';
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
PREUPGRADE_REPORTS_REQUEST,
|
|
7
|
-
PREUPGRADE_REPORTS_SUCCESS,
|
|
8
|
-
PREUPGRADE_REPORTS_FAILURE,
|
|
9
|
-
} from '../../consts';
|
|
10
|
-
|
|
11
|
-
export const getPreupgradeReportsAction = url => async dispatch => {
|
|
12
|
-
dispatch({ type: PREUPGRADE_REPORTS_REQUEST });
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
const { data } = await api.get(url);
|
|
16
|
-
return dispatch({
|
|
17
|
-
type: PREUPGRADE_REPORTS_SUCCESS,
|
|
18
|
-
payload: deepPropsToCamelCase(data),
|
|
19
|
-
});
|
|
20
|
-
} catch (error) {
|
|
21
|
-
return dispatch(errorHandler(PREUPGRADE_REPORTS_FAILURE, error));
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const errorHandler = (msg, err) => {
|
|
26
|
-
const error = {
|
|
27
|
-
errorMsg: __('Failed to fetch preupgrade reports from server.'),
|
|
28
|
-
statusText: err.response.statusText,
|
|
29
|
-
};
|
|
30
|
-
return { type: msg, payload: { error } };
|
|
31
|
-
};
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import Immutable from 'seamless-immutable';
|
|
2
|
-
|
|
3
|
-
export const flattenEntries = reports =>
|
|
4
|
-
reports.reduce((memo, report) => [...memo, ...report.entries], []);
|
|
5
|
-
|
|
6
|
-
const entryWithFixKind = kind => entry =>
|
|
7
|
-
entry.detail &&
|
|
8
|
-
entry.detail.remediations &&
|
|
9
|
-
entry.detail.remediations.some(remediation => remediation.type === kind);
|
|
10
|
-
|
|
11
|
-
export const entryFixable = entryWithFixKind('command');
|
|
12
|
-
|
|
13
|
-
export const isInhibitor = entry =>
|
|
14
|
-
entry.flags && entry.flags.some(flag => flag === 'inhibitor');
|
|
15
|
-
|
|
16
|
-
export const filterByInhibitor = value => entry => {
|
|
17
|
-
const inhibitsUpgrade = isInhibitor(entry);
|
|
18
|
-
|
|
19
|
-
if (value === 'yes') {
|
|
20
|
-
return inhibitsUpgrade;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (value === 'no') {
|
|
24
|
-
return !inhibitsUpgrade;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return true;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export const isEmpty = obj => Object.keys(obj).length === 0;
|
|
31
|
-
|
|
32
|
-
export const anyEntriesFixable = reports =>
|
|
33
|
-
reportsToEntries(reports, Array.prototype.some, entryFixable);
|
|
34
|
-
|
|
35
|
-
export const fixableEntries = reports =>
|
|
36
|
-
reportsToEntries(reports, Array.prototype.filter, entryFixable);
|
|
37
|
-
|
|
38
|
-
const reportsToEntries = (reports, iterator, predicate) =>
|
|
39
|
-
iterator.call(flattenEntries(reports), predicate);
|
|
40
|
-
|
|
41
|
-
export const idsForInvocationFromEntries = entries =>
|
|
42
|
-
entries.reduce(
|
|
43
|
-
(memo, entry) => {
|
|
44
|
-
if (entryFixable(entry)) {
|
|
45
|
-
memo.entryIds = [...memo.entryIds, entry.id];
|
|
46
|
-
|
|
47
|
-
if (!memo.hostIds.includes(entry.hostId)) {
|
|
48
|
-
memo.hostIds = [...memo.hostIds, entry.hostId];
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return memo;
|
|
52
|
-
},
|
|
53
|
-
{ hostIds: [], entryIds: [] }
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
export const idsForInvocationFromReports = reports =>
|
|
57
|
-
idsForInvocationFromEntries(flattenEntries(reports));
|
|
58
|
-
|
|
59
|
-
export const entriesPage = (entries, pagination) => {
|
|
60
|
-
const offset = (pagination.page - 1) * pagination.perPage;
|
|
61
|
-
|
|
62
|
-
return entries.slice(offset, offset + pagination.perPage);
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export const filterEntries = (attribute, value, entries) => {
|
|
66
|
-
if (!value) {
|
|
67
|
-
return entries;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (attribute === 'fix') {
|
|
71
|
-
return entries.filter(entryWithFixKind(value));
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (attribute === 'inhibitor') {
|
|
75
|
-
return entries.filter(filterByInhibitor(value));
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return entries.filter(entry =>
|
|
79
|
-
entry[attribute].toLowerCase().includes(value.toLowerCase())
|
|
80
|
-
);
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
export const byText = attribute => (first, second) => {
|
|
84
|
-
const firstAttr = first[attribute].toLowerCase();
|
|
85
|
-
const secondAttr = second[attribute].toLowerCase();
|
|
86
|
-
|
|
87
|
-
if (firstAttr < secondAttr) {
|
|
88
|
-
return -1;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (firstAttr > secondAttr) {
|
|
92
|
-
return 1;
|
|
93
|
-
}
|
|
94
|
-
return 0;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
export const bySeverity = attribute => (first, second) => {
|
|
98
|
-
const sevList = ['info', 'low', 'medium', 'high'];
|
|
99
|
-
|
|
100
|
-
const firstAttr = first[attribute].toLowerCase();
|
|
101
|
-
const secondAttr = second[attribute].toLowerCase();
|
|
102
|
-
|
|
103
|
-
return sevList.indexOf(firstAttr) - sevList.indexOf(secondAttr);
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
export const byFix = (first, second) => {
|
|
107
|
-
const firstAttr = !!(first.detail && first.detail.remediations);
|
|
108
|
-
const secondAttr = !!(second.detail && second.detail.remediations);
|
|
109
|
-
return byBoolComparison(firstAttr, secondAttr);
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
export const byInhibitor = (first, second) =>
|
|
113
|
-
byBoolComparison(isInhibitor(first), isInhibitor(second));
|
|
114
|
-
|
|
115
|
-
const byBoolComparison = (first, second) => {
|
|
116
|
-
if (first === second) {
|
|
117
|
-
return 0;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (first) {
|
|
121
|
-
return -1;
|
|
122
|
-
}
|
|
123
|
-
return 1;
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
export const sortEntries = (entries, sort) => {
|
|
127
|
-
const entriesCopy = Immutable.asMutable(entries);
|
|
128
|
-
|
|
129
|
-
if (!sort.attribute) {
|
|
130
|
-
return entriesCopy;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
let sorted;
|
|
134
|
-
|
|
135
|
-
if (['title', 'hostname'].includes(sort.attribute)) {
|
|
136
|
-
sorted = entriesCopy.sort(byText(sort.attribute));
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if (sort.attribute === 'severity') {
|
|
140
|
-
sorted = entriesCopy.sort(bySeverity(sort.attribute));
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if (sort.attribute === 'fix') {
|
|
144
|
-
sorted = entriesCopy.sort(byFix);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (sort.attribute === 'inhibitor') {
|
|
148
|
-
sorted = entriesCopy.sort(byInhibitor);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return sort.order === 'asc' ? sorted : sorted.reverse();
|
|
152
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import Immutable from 'seamless-immutable';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
PREUPGRADE_REPORTS_REQUEST,
|
|
5
|
-
PREUPGRADE_REPORTS_SUCCESS,
|
|
6
|
-
PREUPGRADE_REPORTS_FAILURE,
|
|
7
|
-
} from '../../consts';
|
|
8
|
-
|
|
9
|
-
export const initialState = Immutable({
|
|
10
|
-
loadingPreupgradeReports: false,
|
|
11
|
-
reportsExpected: false,
|
|
12
|
-
preupgradeReports: [],
|
|
13
|
-
error: {},
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
const reducer = (state = initialState, action) => {
|
|
17
|
-
const { payload } = action;
|
|
18
|
-
switch (action.type) {
|
|
19
|
-
case PREUPGRADE_REPORTS_REQUEST:
|
|
20
|
-
return state.set('loadingPreupgradeReports', true);
|
|
21
|
-
case PREUPGRADE_REPORTS_SUCCESS:
|
|
22
|
-
return state.merge({
|
|
23
|
-
loadingPreupgradeReports: false,
|
|
24
|
-
preupgradeReports: payload.results,
|
|
25
|
-
reportsExpected: true,
|
|
26
|
-
});
|
|
27
|
-
case PREUPGRADE_REPORTS_FAILURE:
|
|
28
|
-
return state.merge({
|
|
29
|
-
error: payload.error,
|
|
30
|
-
loadingPreupgradeReports: false,
|
|
31
|
-
});
|
|
32
|
-
default:
|
|
33
|
-
return state;
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export default reducer;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export const selectPreupgrade = state => state.foremanLeapp.preupgrade;
|
|
2
|
-
|
|
3
|
-
export const selectPreupgradeReports = state =>
|
|
4
|
-
selectPreupgrade(state).preupgradeReports;
|
|
5
|
-
|
|
6
|
-
export const selectLoadingPreupgradeReports = state =>
|
|
7
|
-
selectPreupgrade(state).loadingPreupgradeReports;
|
|
8
|
-
export const selectError = state => selectPreupgrade(state).error;
|
|
9
|
-
|
|
10
|
-
export const selectReportsExpected = state =>
|
|
11
|
-
selectPreupgrade(state).reportsExpected;
|
|
12
|
-
|
|
13
|
-
export const selectRexState = state => state.foremanRemoteExecutionReducers;
|
|
14
|
-
|
|
15
|
-
export const selectJobInvocations = state =>
|
|
16
|
-
selectRexState(state).jobInvocations;
|
|
17
|
-
export const selectJobInvocationsPolling = state =>
|
|
18
|
-
selectJobInvocations(state).isPolling;
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
export const preupgradeReports = [
|
|
2
|
-
{
|
|
3
|
-
hostId: 5,
|
|
4
|
-
entries: [
|
|
5
|
-
{
|
|
6
|
-
title: 'Fix me!',
|
|
7
|
-
severity: 'info',
|
|
8
|
-
id: 42,
|
|
9
|
-
hostname: 'host.example.com',
|
|
10
|
-
flags: [],
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
title: 'I am broken too',
|
|
14
|
-
severity: 'medium',
|
|
15
|
-
id: 43,
|
|
16
|
-
hostname: 'host.example.com',
|
|
17
|
-
flags: [],
|
|
18
|
-
},
|
|
19
|
-
],
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
hostId: 6,
|
|
23
|
-
entries: [
|
|
24
|
-
{
|
|
25
|
-
title: 'Octocat is not happy',
|
|
26
|
-
severity: 'high',
|
|
27
|
-
id: 44,
|
|
28
|
-
hostname: 'foo.example.com',
|
|
29
|
-
flags: ['inhibitor'],
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
title: 'Not enough credits',
|
|
33
|
-
severity: 'low',
|
|
34
|
-
id: 45,
|
|
35
|
-
hostname: 'foo.example.com',
|
|
36
|
-
flags: [],
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
title: 'SELinux is turned off',
|
|
40
|
-
severity: 'medium',
|
|
41
|
-
id: 46,
|
|
42
|
-
hostname: 'foo.example.com',
|
|
43
|
-
flags: [],
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
title: 'Root password is too short',
|
|
47
|
-
severity: 'medium',
|
|
48
|
-
id: 47,
|
|
49
|
-
hostname: 'foo.example.com',
|
|
50
|
-
flags: [],
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
title: 'No chocolate chip cookies in cookie jar',
|
|
54
|
-
severity: 'high',
|
|
55
|
-
id: 49,
|
|
56
|
-
hostname: 'foo.example.com',
|
|
57
|
-
flags: [],
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
},
|
|
61
|
-
];
|
|
62
|
-
|
|
63
|
-
export const preupgradeReportsWithFixableEntries = [
|
|
64
|
-
{
|
|
65
|
-
hostId: 5,
|
|
66
|
-
entries: [
|
|
67
|
-
{
|
|
68
|
-
title: 'Fixable entry',
|
|
69
|
-
severity: 'high',
|
|
70
|
-
id: 100,
|
|
71
|
-
hostId: 5,
|
|
72
|
-
hostname: 'host.example.com',
|
|
73
|
-
flags: [],
|
|
74
|
-
detail: {
|
|
75
|
-
remediations: [{ type: 'command', context: ['echo', 'fix'] }],
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
title: 'Not fixable entry',
|
|
80
|
-
severity: 'low',
|
|
81
|
-
id: 101,
|
|
82
|
-
hostId: 5,
|
|
83
|
-
hostname: 'host.example.com',
|
|
84
|
-
flags: [],
|
|
85
|
-
},
|
|
86
|
-
],
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
hostId: 6,
|
|
90
|
-
entries: [
|
|
91
|
-
{
|
|
92
|
-
title: 'Another fixable entry',
|
|
93
|
-
severity: 'medium',
|
|
94
|
-
id: 102,
|
|
95
|
-
hostId: 6,
|
|
96
|
-
hostname: 'foo.example.com',
|
|
97
|
-
flags: [],
|
|
98
|
-
detail: {
|
|
99
|
-
remediations: [{ type: 'command', context: ['echo', 'fix2'] }],
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
],
|
|
103
|
-
},
|
|
104
|
-
];
|
|
105
|
-
|
|
106
|
-
export const reportsWithRemediations = [
|
|
107
|
-
{
|
|
108
|
-
hostId: 5,
|
|
109
|
-
entries: [
|
|
110
|
-
{
|
|
111
|
-
title: 'Fix me!',
|
|
112
|
-
severity: 'info',
|
|
113
|
-
detail: { remediations: [{ type: 'hint' }] },
|
|
114
|
-
},
|
|
115
|
-
{ title: 'I am broken too', severity: 'medium' },
|
|
116
|
-
],
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
hostId: 6,
|
|
120
|
-
entries: [
|
|
121
|
-
{
|
|
122
|
-
title: 'Octocat is not happy',
|
|
123
|
-
severity: 'high',
|
|
124
|
-
detail: { remediations: [{ type: 'command' }] },
|
|
125
|
-
},
|
|
126
|
-
{ title: 'Not enough credits', severity: 'low' },
|
|
127
|
-
],
|
|
128
|
-
},
|
|
129
|
-
];
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Provider } from 'react-redux';
|
|
3
|
-
import configureMockStore from 'redux-mock-store';
|
|
4
|
-
import { fireEvent, render, screen } from '@testing-library/react';
|
|
5
|
-
import '@testing-library/jest-dom';
|
|
6
|
-
|
|
7
|
-
import PreupgradeReports from '../PreupgradeReports';
|
|
8
|
-
import {
|
|
9
|
-
preupgradeReports,
|
|
10
|
-
preupgradeReportsWithFixableEntries,
|
|
11
|
-
} from './PreupgradeReports.fixtures';
|
|
12
|
-
|
|
13
|
-
jest.mock('foremanReact/components/Pagination', () => {
|
|
14
|
-
const MockPagination = () => <div data-testid="pagination">Pagination</div>;
|
|
15
|
-
return MockPagination;
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
jest.mock('../../PreupgradeReportsList/components/images/i_severity-high.svg', () => 'severity-high.svg');
|
|
19
|
-
jest.mock('../../PreupgradeReportsList/components/images/i_severity-med.svg', () => 'severity-med.svg');
|
|
20
|
-
jest.mock('../../PreupgradeReportsList/components/images/i_severity-low.svg', () => 'severity-low.svg');
|
|
21
|
-
|
|
22
|
-
const mockStore = configureMockStore([]);
|
|
23
|
-
|
|
24
|
-
const csrfToken = 'xyz';
|
|
25
|
-
const newJobInvocationUrl = '/job_invocations/new';
|
|
26
|
-
|
|
27
|
-
const defaultProps = {
|
|
28
|
-
loading: false,
|
|
29
|
-
error: {},
|
|
30
|
-
preupgradeReports,
|
|
31
|
-
csrfToken,
|
|
32
|
-
newJobInvocationUrl,
|
|
33
|
-
reportsExpected: true,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const renderComponent = (props = {}) =>
|
|
37
|
-
render(
|
|
38
|
-
<Provider store={mockStore({})}>
|
|
39
|
-
<PreupgradeReports {...defaultProps} {...props} />
|
|
40
|
-
</Provider>
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
const getFixSelectedForm = () =>
|
|
44
|
-
screen.getByRole('button', { name: 'Fix Selected' }).closest('form');
|
|
45
|
-
|
|
46
|
-
describe('PreupgradeReports', () => {
|
|
47
|
-
// withLoadingState wraps content in patternfly-react LoadingState, which
|
|
48
|
-
// delays showing the spinner by 300ms and always schedules that timeout on
|
|
49
|
-
// mount — even when loading=false. Without fake timers the timeout fires
|
|
50
|
-
// after the test unmounts and React logs a setState-on-unmounted warning.
|
|
51
|
-
beforeEach(() => {
|
|
52
|
-
jest.useFakeTimers();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
afterEach(() => {
|
|
56
|
-
jest.runOnlyPendingTimers();
|
|
57
|
-
jest.useRealTimers();
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('renders report entries when loaded with reports', () => {
|
|
61
|
-
renderComponent();
|
|
62
|
-
|
|
63
|
-
expect(screen.getByText('Fix me!')).toBeInTheDocument();
|
|
64
|
-
expect(screen.getByText('I am broken too')).toBeInTheDocument();
|
|
65
|
-
expect(screen.getByText('Octocat is not happy')).toBeInTheDocument();
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('renders empty state when loaded without reports', () => {
|
|
69
|
-
renderComponent({ preupgradeReports: [] });
|
|
70
|
-
|
|
71
|
-
expect(
|
|
72
|
-
screen.getByRole('heading', {
|
|
73
|
-
name: 'No Preupgrade Report Available',
|
|
74
|
-
level: 5,
|
|
75
|
-
})
|
|
76
|
-
).toBeInTheDocument();
|
|
77
|
-
expect(
|
|
78
|
-
screen.getByText(
|
|
79
|
-
'The preupgrade report could not be generated, check the job details for the reason'
|
|
80
|
-
)
|
|
81
|
-
).toBeInTheDocument();
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('renders loading state while data is being fetched', () => {
|
|
85
|
-
renderComponent({
|
|
86
|
-
loading: true,
|
|
87
|
-
preupgradeReports: [],
|
|
88
|
-
reportsExpected: false,
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// LoadingState renders nothing until its 300ms timeout elapses.
|
|
92
|
-
jest.advanceTimersByTime(300);
|
|
93
|
-
|
|
94
|
-
expect(screen.getByText('Loading')).toBeInTheDocument();
|
|
95
|
-
expect(
|
|
96
|
-
screen.queryByRole('heading', {
|
|
97
|
-
name: 'No Preupgrade Report Available',
|
|
98
|
-
})
|
|
99
|
-
).not.toBeInTheDocument();
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('renders error empty state when data retrieval fails', () => {
|
|
103
|
-
renderComponent({
|
|
104
|
-
error: {
|
|
105
|
-
statusText: 'Internal server error',
|
|
106
|
-
errorMsg: 'Unexpected error',
|
|
107
|
-
},
|
|
108
|
-
preupgradeReports: [],
|
|
109
|
-
reportsExpected: false,
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
expect(
|
|
113
|
-
screen.getByRole('heading', {
|
|
114
|
-
name: 'Could not retrieve data: Internal server error - Unexpected error',
|
|
115
|
-
level: 5,
|
|
116
|
-
})
|
|
117
|
-
).toBeInTheDocument();
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('disables Fix Selected when no fixable entries are selected', () => {
|
|
121
|
-
renderComponent({ preupgradeReports: preupgradeReportsWithFixableEntries });
|
|
122
|
-
|
|
123
|
-
expect(screen.getByRole('button', { name: 'Fix Selected' })).toBeDisabled();
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it('enables Fix Selected and passes selected entry ids when a fixable entry is selected', () => {
|
|
127
|
-
renderComponent({ preupgradeReports: preupgradeReportsWithFixableEntries });
|
|
128
|
-
|
|
129
|
-
const [, fixableEntryCheckbox] = screen.getAllByRole('checkbox');
|
|
130
|
-
|
|
131
|
-
fireEvent.click(fixableEntryCheckbox);
|
|
132
|
-
|
|
133
|
-
expect(screen.getByRole('button', { name: 'Fix Selected' })).toBeEnabled();
|
|
134
|
-
expect(
|
|
135
|
-
getFixSelectedForm().querySelector('input[name="inputs[remediation_ids]"]')
|
|
136
|
-
).toHaveValue('100');
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('selects all fixable entries when header checkbox is clicked', () => {
|
|
140
|
-
renderComponent({ preupgradeReports: preupgradeReportsWithFixableEntries });
|
|
141
|
-
|
|
142
|
-
const [selectAllCheckbox] = screen.getAllByRole('checkbox');
|
|
143
|
-
|
|
144
|
-
fireEvent.click(selectAllCheckbox);
|
|
145
|
-
|
|
146
|
-
expect(screen.getByRole('button', { name: 'Fix Selected' })).toBeEnabled();
|
|
147
|
-
|
|
148
|
-
const form = getFixSelectedForm();
|
|
149
|
-
|
|
150
|
-
expect(
|
|
151
|
-
form.querySelector('input[name="inputs[remediation_ids]"]')
|
|
152
|
-
).toHaveValue('100,102');
|
|
153
|
-
expect(
|
|
154
|
-
[...form.querySelectorAll('input[name="host_ids[]"]')].map(
|
|
155
|
-
input => input.value
|
|
156
|
-
)
|
|
157
|
-
).toEqual(['5', '6']);
|
|
158
|
-
});
|
|
159
|
-
});
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { testSelectorsSnapshotWithFixtures } from '@theforeman/test';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
preupgradeReports,
|
|
5
|
-
reportsWithRemediations,
|
|
6
|
-
} from './PreupgradeReports.fixtures';
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
flattenEntries,
|
|
10
|
-
isEmpty,
|
|
11
|
-
entryFixable,
|
|
12
|
-
anyEntriesFixable,
|
|
13
|
-
idsForInvocationFromReports,
|
|
14
|
-
entriesPage,
|
|
15
|
-
filterEntries,
|
|
16
|
-
fixableEntries,
|
|
17
|
-
sortEntries,
|
|
18
|
-
} from '../PreupgradeReportsHelpers';
|
|
19
|
-
|
|
20
|
-
const fixtures = {
|
|
21
|
-
'should return flattened entrues': () => flattenEntries(preupgradeReports),
|
|
22
|
-
'should detect empty object': () => isEmpty({}),
|
|
23
|
-
'should detect non-empty object': () => isEmpty({ foo: 'bar' }),
|
|
24
|
-
'should detect entry is fixable': () =>
|
|
25
|
-
entryFixable({ detail: { remediations: [{ type: 'command' }] } }),
|
|
26
|
-
'should detect entry is not fixable when not having a command': () =>
|
|
27
|
-
entryFixable({ detail: { remediations: [{ type: 'hint' }] } }),
|
|
28
|
-
'should detect entry is not fixable when not having remediations': () =>
|
|
29
|
-
!!entryFixable({ detail: {} }),
|
|
30
|
-
'should detect no entry is fixable': () =>
|
|
31
|
-
anyEntriesFixable(preupgradeReports),
|
|
32
|
-
'should detect a fixable entry in reports': () =>
|
|
33
|
-
anyEntriesFixable(reportsWithRemediations),
|
|
34
|
-
'should collect ids for job invocation from reports': () =>
|
|
35
|
-
idsForInvocationFromReports(preupgradeReports),
|
|
36
|
-
'should return entries page': () =>
|
|
37
|
-
entriesPage(flattenEntries(preupgradeReports), { page: 2, perPage: 3 }),
|
|
38
|
-
'should filter entries by title': () =>
|
|
39
|
-
filterEntries('title', 'broken', flattenEntries(preupgradeReports)),
|
|
40
|
-
'should filter entries by severity': () =>
|
|
41
|
-
filterEntries('severity', 'medium', flattenEntries(preupgradeReports)),
|
|
42
|
-
'should filter entries by host': () =>
|
|
43
|
-
filterEntries('hostname', 'foo', flattenEntries(preupgradeReports)),
|
|
44
|
-
'should filter entries by remediations': () =>
|
|
45
|
-
filterEntries('fix', 'command', flattenEntries(reportsWithRemediations)),
|
|
46
|
-
'should filter entries by inhibitor': () =>
|
|
47
|
-
filterEntries('inhibitor', 'yes', flattenEntries(preupgradeReports)),
|
|
48
|
-
'should return fixable entries': () =>
|
|
49
|
-
fixableEntries(reportsWithRemediations),
|
|
50
|
-
'should sort entries by title in ascending order': () =>
|
|
51
|
-
sortEntries(flattenEntries(preupgradeReports), {
|
|
52
|
-
attribute: 'title',
|
|
53
|
-
order: 'asc',
|
|
54
|
-
}),
|
|
55
|
-
'should sort entries by title in descending order': () =>
|
|
56
|
-
sortEntries(flattenEntries(preupgradeReports), {
|
|
57
|
-
attribute: 'title',
|
|
58
|
-
order: 'desc',
|
|
59
|
-
}),
|
|
60
|
-
'should sort entries by hostname': () =>
|
|
61
|
-
sortEntries(flattenEntries(preupgradeReports), {
|
|
62
|
-
attribute: 'hostname',
|
|
63
|
-
order: 'asc',
|
|
64
|
-
}),
|
|
65
|
-
'should sort entries by severity': () =>
|
|
66
|
-
sortEntries(flattenEntries(preupgradeReports), {
|
|
67
|
-
attribute: 'severity',
|
|
68
|
-
order: 'asc',
|
|
69
|
-
}),
|
|
70
|
-
'should sort entries by remediations': () =>
|
|
71
|
-
sortEntries(flattenEntries(reportsWithRemediations), {
|
|
72
|
-
attribute: 'fix',
|
|
73
|
-
order: 'asc',
|
|
74
|
-
}),
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
describe('PreupgradeReportsHelpers', () =>
|
|
78
|
-
testSelectorsSnapshotWithFixtures(fixtures));
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { testReducerSnapshotWithFixtures } from '@theforeman/test';
|
|
2
|
-
|
|
3
|
-
import reducer, { initialState } from '../PreupgradeReportsReducer';
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
PREUPGRADE_REPORTS_REQUEST,
|
|
7
|
-
PREUPGRADE_REPORTS_SUCCESS,
|
|
8
|
-
PREUPGRADE_REPORTS_FAILURE,
|
|
9
|
-
} from '../../../consts';
|
|
10
|
-
|
|
11
|
-
import { preupgradeReports } from './PreupgradeReports.fixtures';
|
|
12
|
-
|
|
13
|
-
const fixtures = {
|
|
14
|
-
'should return initial state': {
|
|
15
|
-
state: initialState,
|
|
16
|
-
action: {
|
|
17
|
-
type: undefined,
|
|
18
|
-
payload: [],
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
'should start loading reports on request': {
|
|
22
|
-
state: initialState,
|
|
23
|
-
action: {
|
|
24
|
-
type: PREUPGRADE_REPORTS_REQUEST,
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
'should stop loading on reports success': {
|
|
28
|
-
state: initialState.set('loadingPreupgradeReports', true),
|
|
29
|
-
action: {
|
|
30
|
-
type: PREUPGRADE_REPORTS_SUCCESS,
|
|
31
|
-
payload: { results: preupgradeReports },
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
'should show error on request failure': {
|
|
35
|
-
state: initialState.set('loadingPreupgradeReports', true),
|
|
36
|
-
action: {
|
|
37
|
-
type: PREUPGRADE_REPORTS_FAILURE,
|
|
38
|
-
payload: { error: { errorMsg: 'This is error', statusText: 'Not good' } },
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
describe('PreupgradeReportsReducer', () =>
|
|
44
|
-
testReducerSnapshotWithFixtures(reducer, fixtures));
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { testSelectorsSnapshotWithFixtures } from '@theforeman/test';
|
|
2
|
-
|
|
3
|
-
import { preupgradeReports } from './PreupgradeReports.fixtures';
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
selectPreupgradeReports,
|
|
7
|
-
selectLoadingPreupgradeReports,
|
|
8
|
-
selectError,
|
|
9
|
-
} from '../PreupgradeReportsSelectors';
|
|
10
|
-
|
|
11
|
-
const state = {
|
|
12
|
-
foremanLeapp: {
|
|
13
|
-
preupgrade: {
|
|
14
|
-
preupgradeReports,
|
|
15
|
-
loadingPreupgradeReports: false,
|
|
16
|
-
error: { errorMsg: 'Error', statusText: 'Status text' },
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const fixtures = {
|
|
22
|
-
'should return preupgrade reports': () => selectPreupgradeReports(state),
|
|
23
|
-
'should return loading state': () => selectLoadingPreupgradeReports(state),
|
|
24
|
-
'should return error': () => selectError(state),
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
describe('PreupgradeReportsSelectors', () =>
|
|
28
|
-
testSelectorsSnapshotWithFixtures(fixtures));
|