foreman_rh_cloud 13.0.7 → 13.0.9
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/concerns/foreman_rh_cloud/registration_manager_extensions.rb +39 -0
- data/app/controllers/foreman_inventory_upload/accounts_controller.rb +1 -1
- data/app/controllers/foreman_inventory_upload/uploads_controller.rb +1 -1
- data/lib/foreman_inventory_upload/async/create_missing_insights_facets.rb +3 -2
- data/lib/foreman_inventory_upload/async/queue_for_upload_job.rb +1 -23
- data/lib/foreman_inventory_upload/async/upload_report_direct_job.rb +200 -0
- data/lib/foreman_inventory_upload.rb +6 -6
- data/lib/foreman_rh_cloud/engine.rb +1 -0
- data/lib/foreman_rh_cloud/plugin.rb +4 -0
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/inventory_sync/async/inventory_hosts_sync.rb +0 -2
- data/lib/tasks/rh_cloud_inventory.rake +11 -1
- data/package.json +1 -1
- data/test/controllers/accounts_controller_test.rb +1 -1
- data/test/controllers/uploads_controller_test.rb +1 -1
- data/test/jobs/cloud_connector_announce_task_test.rb +3 -2
- data/test/jobs/connector_playbook_execution_reporter_task_test.rb +32 -20
- data/test/jobs/create_missing_insights_facets_test.rb +151 -0
- data/test/jobs/exponential_backoff_test.rb +9 -8
- data/test/jobs/generate_host_report_test.rb +100 -0
- data/test/jobs/generate_report_job_test.rb +146 -0
- data/test/jobs/host_inventory_report_job_test.rb +244 -0
- data/test/jobs/insights_client_status_aging_test.rb +3 -2
- data/test/jobs/insights_full_sync_test.rb +13 -7
- data/test/jobs/insights_resolutions_sync_test.rb +9 -5
- data/test/jobs/insights_rules_sync_test.rb +5 -3
- data/test/jobs/inventory_full_sync_test.rb +9 -5
- data/test/jobs/inventory_hosts_sync_test.rb +11 -6
- data/test/jobs/inventory_scheduled_sync_test.rb +10 -6
- data/test/jobs/inventory_self_host_sync_test.rb +1 -1
- data/test/jobs/queue_for_upload_job_test.rb +10 -19
- data/test/jobs/remove_insights_hosts_job_test.rb +14 -15
- data/test/jobs/single_host_report_job_test.rb +155 -0
- data/test/jobs/upload_report_direct_job_test.rb +399 -0
- data/test/unit/lib/foreman_rh_cloud/registration_manager_extensions_test.rb +192 -0
- data/webpack/ForemanColumnExtensions/index.js +2 -0
- data/webpack/ForemanInventoryUpload/Components/AccountList/AccountList.js +1 -1
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/ListItem.fixtures.js +4 -5
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/ListItem.js +4 -2
- data/webpack/ForemanInventoryUpload/Components/AccountList/Components/ListItem/__tests__/__snapshots__/ListItem.test.js.snap +9 -10
- data/webpack/ForemanInventoryUpload/Components/Dashboard/Dashboard.js +4 -1
- data/webpack/ForemanInventoryUpload/Components/PageHeader/PageHeader.js +24 -17
- data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/PageHeader.test.js +178 -8
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/ToolbarButtons/ToolbarButtons.js +3 -1
- data/webpack/ForemanInventoryUpload/Components/PageHeader/components/ToolbarButtons/__tests__/ToolbarButtons.test.js +69 -51
- data/webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettings.js +3 -3
- data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +3 -9
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/InsightsTable.test.js +12 -7
- data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +2 -2
- data/webpack/InsightsCloudSync/Components/ToolbarDropdown.js +3 -3
- data/webpack/InsightsCloudSync/InsightsCloudSync.js +3 -3
- data/webpack/InsightsCloudSync/InsightsCloudSync.test.js +10 -0
- data/webpack/InsightsCloudSync/__snapshots__/InsightsCloudSync.test.js.snap +1 -1
- data/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js +5 -5
- data/webpack/InsightsVulnerabilityHostIndexExtensions/CVECountCell.js +2 -2
- data/webpack/InsightsVulnerabilityHostIndexExtensions/__tests__/CVECountCell.test.js +77 -22
- data/webpack/common/Hooks/ConfigHooks.js +3 -16
- metadata +17 -8
- data/lib/foreman_inventory_upload/async/upload_report_job.rb +0 -97
- data/lib/foreman_inventory_upload/scripts/uploader.sh.erb +0 -55
- data/test/jobs/upload_report_job_test.rb +0 -37
- data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageHeader.test.js.snap +0 -36
- data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +0 -112
- data/webpack/__mocks__/foremanReact/common/hooks/API/APIHooks.js +0 -3
|
@@ -49,7 +49,8 @@ class Dashboard extends React.Component {
|
|
|
49
49
|
showFullScreen,
|
|
50
50
|
activeTab,
|
|
51
51
|
} = this.props;
|
|
52
|
-
const downloadButtonDisabled = () =>
|
|
52
|
+
const downloadButtonDisabled = () =>
|
|
53
|
+
!account.report_file_paths || account.report_file_paths.length === 0;
|
|
53
54
|
return (
|
|
54
55
|
<NavContainer
|
|
55
56
|
items={[
|
|
@@ -120,6 +121,7 @@ Dashboard.propTypes = {
|
|
|
120
121
|
generate_report_status: PropTypes.string,
|
|
121
122
|
upload_report_status: PropTypes.string,
|
|
122
123
|
report_file_paths: PropTypes.arrayOf(PropTypes.string),
|
|
124
|
+
id: PropTypes.number,
|
|
123
125
|
}),
|
|
124
126
|
showFullScreen: PropTypes.bool,
|
|
125
127
|
toggleFullScreen: PropTypes.func,
|
|
@@ -140,6 +142,7 @@ Dashboard.defaultProps = {
|
|
|
140
142
|
generate_report_status: 'unknown',
|
|
141
143
|
upload_report_status: 'unknown',
|
|
142
144
|
report_file_paths: [],
|
|
145
|
+
id: 0,
|
|
143
146
|
},
|
|
144
147
|
showFullScreen: false,
|
|
145
148
|
toggleFullScreen: noop,
|
|
@@ -6,26 +6,33 @@ import InventoryFilter from '../InventoryFilter';
|
|
|
6
6
|
import ToolbarButtons from './components/ToolbarButtons';
|
|
7
7
|
import SettingsWarning from './components/SettingsWarning';
|
|
8
8
|
import PageTitle from './PageTitle';
|
|
9
|
+
import { useIopConfig } from '../../../common/Hooks/ConfigHooks';
|
|
9
10
|
import './PageHeader.scss';
|
|
10
11
|
|
|
11
|
-
const PageHeader = () =>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<div className="inventory-upload-header
|
|
16
|
-
<
|
|
17
|
-
<
|
|
12
|
+
const PageHeader = () => {
|
|
13
|
+
const isIop = useIopConfig();
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div className="inventory-upload-header">
|
|
17
|
+
<SettingsWarning />
|
|
18
|
+
<PageTitle />
|
|
19
|
+
{!isIop && (
|
|
20
|
+
<div className="inventory-upload-header-description">
|
|
21
|
+
<InventorySettings />
|
|
22
|
+
<PageDescription />
|
|
23
|
+
</div>
|
|
24
|
+
)}
|
|
25
|
+
<Grid.Row>
|
|
26
|
+
<Grid.Col xs={4}>
|
|
27
|
+
<InventoryFilter />
|
|
28
|
+
</Grid.Col>
|
|
29
|
+
<Grid.Col xs={7} xsOffset={1}>
|
|
30
|
+
<ToolbarButtons />
|
|
31
|
+
</Grid.Col>
|
|
32
|
+
</Grid.Row>
|
|
18
33
|
</div>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
<InventoryFilter />
|
|
22
|
-
</Grid.Col>
|
|
23
|
-
<Grid.Col xs={7} xsOffset={1}>
|
|
24
|
-
<ToolbarButtons />
|
|
25
|
-
</Grid.Col>
|
|
26
|
-
</Grid.Row>
|
|
27
|
-
</div>
|
|
28
|
-
);
|
|
34
|
+
);
|
|
35
|
+
};
|
|
29
36
|
|
|
30
37
|
PageHeader.propTypes = {};
|
|
31
38
|
|
|
@@ -1,13 +1,183 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { screen } from '@testing-library/react';
|
|
3
|
+
import { rtlHelpers } from 'foremanReact/common/rtlTestHelpers';
|
|
3
4
|
import PageHeader from '../PageHeader';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
// Create a variable to control IoP mode in tests
|
|
7
|
+
let mockIopMode = false;
|
|
8
|
+
|
|
9
|
+
// Mock ForemanContext
|
|
10
|
+
jest.mock('foremanReact/Root/Context/ForemanContext', () => ({
|
|
11
|
+
useForemanContext: () => ({
|
|
12
|
+
metadata: {
|
|
13
|
+
foreman_rh_cloud: {
|
|
14
|
+
iop: mockIopMode,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
UI: {},
|
|
18
|
+
}),
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
// Mock child components to isolate PageHeader testing
|
|
22
|
+
// This prevents child component complexity from affecting our tests
|
|
23
|
+
jest.mock('../components/SettingsWarning', () => () => (
|
|
24
|
+
<div data-testid="settings-warning">SettingsWarning</div>
|
|
25
|
+
));
|
|
26
|
+
jest.mock('../PageTitle', () => () => (
|
|
27
|
+
<div data-testid="page-title">PageTitle</div>
|
|
28
|
+
));
|
|
29
|
+
jest.mock('../../InventorySettings', () => () => (
|
|
30
|
+
<div data-testid="inventory-settings">InventorySettings</div>
|
|
31
|
+
));
|
|
32
|
+
jest.mock('../components/PageDescription', () => () => (
|
|
33
|
+
<div data-testid="page-description">PageDescription</div>
|
|
34
|
+
));
|
|
35
|
+
jest.mock('../../InventoryFilter', () => () => (
|
|
36
|
+
<div data-testid="inventory-filter">InventoryFilter</div>
|
|
37
|
+
));
|
|
38
|
+
jest.mock('../components/ToolbarButtons', () => () => (
|
|
39
|
+
<div data-testid="toolbar-buttons">ToolbarButtons</div>
|
|
40
|
+
));
|
|
41
|
+
|
|
42
|
+
const { renderWithStore } = rtlHelpers;
|
|
9
43
|
|
|
10
44
|
describe('PageHeader', () => {
|
|
11
|
-
describe('
|
|
12
|
-
|
|
45
|
+
describe('component behavior', () => {
|
|
46
|
+
test('renders all components when not in IoP mode', () => {
|
|
47
|
+
mockIopMode = false; // Ensure IoP mode is disabled for this test
|
|
48
|
+
|
|
49
|
+
renderWithStore(<PageHeader />, {
|
|
50
|
+
API: {
|
|
51
|
+
INVENTORY_SETTINGS: {
|
|
52
|
+
response: { subscriptionConnectionEnabled: true },
|
|
53
|
+
},
|
|
54
|
+
ADVISOR_ENGINE_CONFIG: {
|
|
55
|
+
response: { use_iop_mode: false },
|
|
56
|
+
status: 'RESOLVED',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// All components should be present when not in IoP mode
|
|
62
|
+
expect(screen.getByTestId('settings-warning')).toBeTruthy();
|
|
63
|
+
expect(screen.getByTestId('page-title')).toBeTruthy();
|
|
64
|
+
expect(screen.getByTestId('inventory-settings')).toBeTruthy();
|
|
65
|
+
expect(screen.getByTestId('page-description')).toBeTruthy();
|
|
66
|
+
expect(screen.getByTestId('inventory-filter')).toBeTruthy();
|
|
67
|
+
expect(screen.getByTestId('toolbar-buttons')).toBeTruthy();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('hides inventory settings and description when in IoP mode', () => {
|
|
71
|
+
mockIopMode = true; // Enable IoP mode for this test
|
|
72
|
+
|
|
73
|
+
renderWithStore(<PageHeader />, {
|
|
74
|
+
API: {
|
|
75
|
+
INVENTORY_SETTINGS: {
|
|
76
|
+
response: { subscriptionConnectionEnabled: true },
|
|
77
|
+
},
|
|
78
|
+
ADVISOR_ENGINE_CONFIG: {
|
|
79
|
+
response: { use_iop_mode: true },
|
|
80
|
+
status: 'RESOLVED',
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Core components should still be present
|
|
86
|
+
expect(screen.getByTestId('settings-warning')).toBeTruthy();
|
|
87
|
+
expect(screen.getByTestId('page-title')).toBeTruthy();
|
|
88
|
+
expect(screen.getByTestId('inventory-filter')).toBeTruthy();
|
|
89
|
+
expect(screen.getByTestId('toolbar-buttons')).toBeTruthy();
|
|
90
|
+
|
|
91
|
+
// These components should be hidden in IoP mode
|
|
92
|
+
expect(screen.queryByTestId('inventory-settings')).toBeNull();
|
|
93
|
+
expect(screen.queryByTestId('page-description')).toBeNull();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('renders with correct CSS class', () => {
|
|
97
|
+
mockIopMode = false; // Ensure IoP mode is disabled for this test
|
|
98
|
+
|
|
99
|
+
const { container } = renderWithStore(<PageHeader />, {
|
|
100
|
+
API: {
|
|
101
|
+
INVENTORY_SETTINGS: {
|
|
102
|
+
response: { subscriptionConnectionEnabled: true },
|
|
103
|
+
},
|
|
104
|
+
ADVISOR_ENGINE_CONFIG: {
|
|
105
|
+
response: { use_iop_mode: false },
|
|
106
|
+
status: 'RESOLVED',
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
expect(container.querySelector('.inventory-upload-header')).toBeTruthy();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('renders grid layout with correct structure', () => {
|
|
115
|
+
mockIopMode = false; // Ensure IoP mode is disabled for this test
|
|
116
|
+
|
|
117
|
+
const { container } = renderWithStore(<PageHeader />, {
|
|
118
|
+
API: {
|
|
119
|
+
INVENTORY_SETTINGS: {
|
|
120
|
+
response: { subscriptionConnectionEnabled: true },
|
|
121
|
+
},
|
|
122
|
+
ADVISOR_ENGINE_CONFIG: {
|
|
123
|
+
response: { use_iop_mode: false },
|
|
124
|
+
status: 'RESOLVED',
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const gridRow = container.querySelector('.row');
|
|
130
|
+
expect(gridRow).toBeTruthy();
|
|
131
|
+
|
|
132
|
+
const filterColumn = container.querySelector('.col-xs-4');
|
|
133
|
+
expect(filterColumn).toBeTruthy();
|
|
134
|
+
|
|
135
|
+
const toolbarColumn = container.querySelector('.col-xs-7');
|
|
136
|
+
expect(toolbarColumn).toBeTruthy();
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('renders description section only when not in IoP mode', () => {
|
|
140
|
+
mockIopMode = false; // Ensure IoP mode is disabled for this test
|
|
141
|
+
|
|
142
|
+
const { container } = renderWithStore(<PageHeader />, {
|
|
143
|
+
API: {
|
|
144
|
+
INVENTORY_SETTINGS: {
|
|
145
|
+
response: { subscriptionConnectionEnabled: true },
|
|
146
|
+
},
|
|
147
|
+
ADVISOR_ENGINE_CONFIG: {
|
|
148
|
+
response: { use_iop_mode: false },
|
|
149
|
+
status: 'RESOLVED',
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// Description section should be present when not in IoP mode
|
|
155
|
+
const descriptionSection = container.querySelector(
|
|
156
|
+
'.inventory-upload-header-description'
|
|
157
|
+
);
|
|
158
|
+
expect(descriptionSection).toBeTruthy();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test('does not render description section when in IoP mode', () => {
|
|
162
|
+
mockIopMode = true; // Enable IoP mode for this test
|
|
163
|
+
|
|
164
|
+
const { container } = renderWithStore(<PageHeader />, {
|
|
165
|
+
API: {
|
|
166
|
+
INVENTORY_SETTINGS: {
|
|
167
|
+
response: { subscriptionConnectionEnabled: true },
|
|
168
|
+
},
|
|
169
|
+
ADVISOR_ENGINE_CONFIG: {
|
|
170
|
+
response: { use_iop_mode: true },
|
|
171
|
+
status: 'RESOLVED',
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Description section should not be present in IoP mode
|
|
177
|
+
const descriptionSection = container.querySelector(
|
|
178
|
+
'.inventory-upload-header-description'
|
|
179
|
+
);
|
|
180
|
+
expect(descriptionSection).toBeNull();
|
|
181
|
+
});
|
|
182
|
+
});
|
|
13
183
|
});
|
|
@@ -4,11 +4,13 @@ import SyncButton from '../SyncButton';
|
|
|
4
4
|
import CloudConnectorButton from '../CloudConnectorButton';
|
|
5
5
|
import './toolbarButtons.scss';
|
|
6
6
|
import { selectSubscriptionConnectionEnabled } from '../../../InventorySettings/InventorySettingsSelectors';
|
|
7
|
+
import { useIopConfig } from '../../../../../common/Hooks/ConfigHooks';
|
|
7
8
|
|
|
8
9
|
const ToolbarButtons = () => {
|
|
9
10
|
const subscriptionConnectionEnabled = useSelector(
|
|
10
11
|
selectSubscriptionConnectionEnabled
|
|
11
12
|
);
|
|
13
|
+
const isIop = useIopConfig();
|
|
12
14
|
|
|
13
15
|
if (!subscriptionConnectionEnabled) {
|
|
14
16
|
return null;
|
|
@@ -16,7 +18,7 @@ const ToolbarButtons = () => {
|
|
|
16
18
|
|
|
17
19
|
return (
|
|
18
20
|
<div className="inventory_toolbar_buttons">
|
|
19
|
-
<CloudConnectorButton />
|
|
21
|
+
{!isIop && <CloudConnectorButton />}
|
|
20
22
|
<SyncButton />
|
|
21
23
|
</div>
|
|
22
24
|
);
|
|
@@ -1,60 +1,78 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import thunk from 'redux-thunk';
|
|
5
|
-
import { screen, render } from '@testing-library/react';
|
|
2
|
+
import { screen } from '@testing-library/react';
|
|
3
|
+
import { rtlHelpers } from 'foremanReact/common/rtlTestHelpers';
|
|
6
4
|
import ToolbarButtons from '../ToolbarButtons';
|
|
5
|
+
import { useIopConfig } from '../../../../../../common/Hooks/ConfigHooks';
|
|
6
|
+
import { selectSubscriptionConnectionEnabled } from '../../../../InventorySettings/InventorySettingsSelectors';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
8
|
+
// Mock the config hook
|
|
9
|
+
jest.mock('../../../../../../common/Hooks/ConfigHooks', () => ({
|
|
10
|
+
useIopConfig: jest.fn(),
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
// Mock the selector
|
|
14
|
+
jest.mock('../../../../InventorySettings/InventorySettingsSelectors', () => ({
|
|
15
|
+
selectSubscriptionConnectionEnabled: jest.fn(),
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
// Mock child components to isolate ToolbarButtons testing
|
|
19
|
+
jest.mock(
|
|
20
|
+
'../../SyncButton',
|
|
21
|
+
() =>
|
|
22
|
+
function MockSyncButton() {
|
|
23
|
+
return <div data-testid="sync-button">Sync all inventory status</div>;
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
jest.mock(
|
|
27
|
+
'../../CloudConnectorButton',
|
|
28
|
+
() =>
|
|
29
|
+
function MockCloudConnectorButton() {
|
|
30
|
+
return (
|
|
31
|
+
<div data-testid="cloud-connector-button">
|
|
32
|
+
Configure cloud connector
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const { renderWithStore } = rtlHelpers;
|
|
25
39
|
|
|
26
40
|
describe('ToolbarButtons', () => {
|
|
27
|
-
test('when subscription connection is enabled', () => {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
);
|
|
35
|
-
expect(screen.queryAllByText('Configure cloud connector')).toHaveLength(1);
|
|
36
|
-
expect(screen.queryAllByText('Sync all inventory status')).toHaveLength(1);
|
|
41
|
+
test('renders both buttons when subscription connection is enabled and not in IOP mode', () => {
|
|
42
|
+
useIopConfig.mockReturnValue(false);
|
|
43
|
+
selectSubscriptionConnectionEnabled.mockReturnValue(true);
|
|
44
|
+
|
|
45
|
+
renderWithStore(<ToolbarButtons />);
|
|
46
|
+
|
|
47
|
+
expect(screen.getByTestId('cloud-connector-button')).toBeTruthy();
|
|
48
|
+
expect(screen.getByTestId('sync-button')).toBeTruthy();
|
|
37
49
|
});
|
|
38
50
|
|
|
39
|
-
test('
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
test('renders only sync button when in IOP mode', () => {
|
|
52
|
+
useIopConfig.mockReturnValue(true);
|
|
53
|
+
selectSubscriptionConnectionEnabled.mockReturnValue(true);
|
|
54
|
+
|
|
55
|
+
renderWithStore(<ToolbarButtons />);
|
|
56
|
+
|
|
57
|
+
expect(screen.queryByTestId('cloud-connector-button')).toBeNull();
|
|
58
|
+
expect(screen.getByTestId('sync-button')).toBeTruthy();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('renders nothing when subscription connection is not enabled', () => {
|
|
62
|
+
useIopConfig.mockReturnValue(false);
|
|
63
|
+
selectSubscriptionConnectionEnabled.mockReturnValue(false);
|
|
64
|
+
|
|
65
|
+
const { container } = renderWithStore(<ToolbarButtons />);
|
|
66
|
+
|
|
67
|
+
expect(container.firstChild).toBeNull();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('renders toolbar buttons container with correct className when enabled', () => {
|
|
71
|
+
useIopConfig.mockReturnValue(false);
|
|
72
|
+
selectSubscriptionConnectionEnabled.mockReturnValue(true);
|
|
73
|
+
|
|
74
|
+
const { container } = renderWithStore(<ToolbarButtons />);
|
|
75
|
+
|
|
76
|
+
expect(container.querySelector('.inventory_toolbar_buttons')).toBeTruthy();
|
|
59
77
|
});
|
|
60
78
|
});
|
|
@@ -3,19 +3,19 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import { translate as __ } from 'foremanReact/common/I18n';
|
|
4
4
|
import SwitcherPF4 from '../../../common/Switcher/SwitcherPF4';
|
|
5
5
|
import './insightsSettings.scss';
|
|
6
|
-
import {
|
|
6
|
+
import { useIopConfig } from '../../../common/Hooks/ConfigHooks';
|
|
7
7
|
|
|
8
8
|
const InsightsSettings = ({
|
|
9
9
|
insightsSyncEnabled,
|
|
10
10
|
getInsightsSyncSettings,
|
|
11
11
|
setInsightsSyncEnabled,
|
|
12
12
|
}) => {
|
|
13
|
-
const
|
|
13
|
+
const isIop = useIopConfig();
|
|
14
14
|
useEffect(() => {
|
|
15
15
|
getInsightsSyncSettings();
|
|
16
16
|
}, [getInsightsSyncSettings]);
|
|
17
17
|
|
|
18
|
-
if (
|
|
18
|
+
if (isIop) return null;
|
|
19
19
|
|
|
20
20
|
return (
|
|
21
21
|
<div className="insights_settings">
|
|
@@ -16,7 +16,7 @@ import TableEmptyState from '../../../common/table/EmptyState';
|
|
|
16
16
|
import { modifySelectedRows, getSortColumnIndex } from './InsightsTableHelpers';
|
|
17
17
|
import Pagination from './Pagination';
|
|
18
18
|
import './table.scss';
|
|
19
|
-
import {
|
|
19
|
+
import { useIopConfig } from '../../../common/Hooks/ConfigHooks';
|
|
20
20
|
|
|
21
21
|
const InsightsTable = ({
|
|
22
22
|
page,
|
|
@@ -48,17 +48,11 @@ const InsightsTable = ({
|
|
|
48
48
|
fetchInsights({ page, perPage, query, sortBy, sortOrder });
|
|
49
49
|
}, [hostname]);
|
|
50
50
|
|
|
51
|
-
const
|
|
51
|
+
const isIop = useIopConfig();
|
|
52
52
|
|
|
53
53
|
useEffect(() => {
|
|
54
54
|
setRows(
|
|
55
|
-
modifySelectedRows(
|
|
56
|
-
hits,
|
|
57
|
-
selectedIds,
|
|
58
|
-
showSelectAllAlert,
|
|
59
|
-
hideHost,
|
|
60
|
-
isLocalAdvisorEngine
|
|
61
|
-
)
|
|
55
|
+
modifySelectedRows(hits, selectedIds, showSelectAllAlert, hideHost, isIop)
|
|
62
56
|
);
|
|
63
57
|
|
|
64
58
|
if (hideHost) setColumns(getColumnsWithoutHostname());
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { rtlHelpers } from 'foremanReact/common/rtlTestHelpers';
|
|
3
3
|
import InsightsTable from '../InsightsTable';
|
|
4
4
|
import { tableProps } from './fixtures';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
};
|
|
6
|
+
jest.mock('../../../../common/Hooks/ConfigHooks');
|
|
7
|
+
|
|
8
|
+
const { renderWithStore } = rtlHelpers;
|
|
9
9
|
|
|
10
10
|
describe('InsightsTable', () => {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
jest.clearAllMocks();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('renders without crashing', () => {
|
|
16
|
+
renderWithStore(<InsightsTable {...tableProps} />);
|
|
17
|
+
});
|
|
13
18
|
});
|
|
@@ -16,7 +16,7 @@ import { modifyRows } from './RemediationHelpers';
|
|
|
16
16
|
import ModalFooter from './RemediationModalFooter';
|
|
17
17
|
import TableEmptyState from '../../../common/table/EmptyState';
|
|
18
18
|
import './RemediationModal.scss';
|
|
19
|
-
import {
|
|
19
|
+
import { useIopConfig } from '../../../common/Hooks/ConfigHooks';
|
|
20
20
|
|
|
21
21
|
/* eslint-disable spellcheck/spell-checker */
|
|
22
22
|
|
|
@@ -82,7 +82,7 @@ const RemediationModal = ({
|
|
|
82
82
|
const [rows, setRows] = React.useState([]);
|
|
83
83
|
const toggleModal = () => setOpen(prevValue => !prevValue);
|
|
84
84
|
|
|
85
|
-
const isIop =
|
|
85
|
+
const isIop = useIopConfig();
|
|
86
86
|
useEffect(() => {
|
|
87
87
|
// only fetch for Hosted. IoP provides via props.
|
|
88
88
|
if (!isIop && open)
|
|
@@ -8,12 +8,12 @@ import {
|
|
|
8
8
|
} from '@patternfly/react-core/deprecated';
|
|
9
9
|
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
|
|
10
10
|
import { redHatAdvisorSystems } from '../InsightsCloudSyncHelpers';
|
|
11
|
-
import {
|
|
11
|
+
import { useIopConfig } from '../../common/Hooks/ConfigHooks';
|
|
12
12
|
|
|
13
13
|
const ToolbarDropdown = ({ onRecommendationSync }) => {
|
|
14
14
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
15
|
-
const
|
|
16
|
-
if (
|
|
15
|
+
const isIop = useIopConfig();
|
|
16
|
+
if (isIop) {
|
|
17
17
|
return null;
|
|
18
18
|
}
|
|
19
19
|
const dropdownItems = [
|
|
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
|
|
4
4
|
import { ScalprumComponent, ScalprumProvider } from '@scalprum/react-core';
|
|
5
5
|
import InsightsTable from './Components/InsightsTable';
|
|
6
|
-
import {
|
|
6
|
+
import { useIopConfig } from '../common/Hooks/ConfigHooks';
|
|
7
7
|
import { foremanUrl } from '../ForemanRhCloudHelpers';
|
|
8
8
|
import RemediationModal from './Components/RemediationModal';
|
|
9
9
|
import {
|
|
@@ -85,9 +85,9 @@ const IopRecommendationsPageWrapped = props => (
|
|
|
85
85
|
);
|
|
86
86
|
|
|
87
87
|
const RecommendationsPage = props => {
|
|
88
|
-
const
|
|
88
|
+
const isIop = useIopConfig();
|
|
89
89
|
|
|
90
|
-
return
|
|
90
|
+
return isIop ? (
|
|
91
91
|
<IopRecommendationsPageWrapped {...props} />
|
|
92
92
|
) : (
|
|
93
93
|
<InsightsCloudSync {...props} />
|
|
@@ -2,6 +2,16 @@ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
|
|
|
2
2
|
import { noop } from 'foremanReact/common/helpers';
|
|
3
3
|
import InsightsCloudSync from './InsightsCloudSync';
|
|
4
4
|
|
|
5
|
+
jest.mock('foremanReact/Root/Context/ForemanContext', () => ({
|
|
6
|
+
useForemanContext: () => ({
|
|
7
|
+
metadata: {
|
|
8
|
+
foreman_rh_cloud: {
|
|
9
|
+
iop: true,
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
}),
|
|
13
|
+
}));
|
|
14
|
+
|
|
5
15
|
const fixtures = {
|
|
6
16
|
render: {
|
|
7
17
|
status: 'RESOLVED',
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
selectHits,
|
|
22
22
|
} from '../InsightsCloudSync/Components/InsightsTable/InsightsTableSelectors';
|
|
23
23
|
import { redHatAdvisorSystems } from '../InsightsCloudSync/InsightsCloudSyncHelpers';
|
|
24
|
-
import {
|
|
24
|
+
import { useIopConfig } from '../common/Hooks/ConfigHooks';
|
|
25
25
|
import { generateRuleUrl } from '../InsightsCloudSync/InsightsCloudSync';
|
|
26
26
|
import { providerOptions } from '../common/ScalprumModule/ScalprumContext';
|
|
27
27
|
|
|
@@ -30,7 +30,7 @@ const NewHostDetailsTab = ({ hostName, router }) => {
|
|
|
30
30
|
const dispatch = useDispatch();
|
|
31
31
|
const query = useSelector(selectSearch);
|
|
32
32
|
const hits = useSelector(selectHits);
|
|
33
|
-
const
|
|
33
|
+
const isIop = useIopConfig();
|
|
34
34
|
|
|
35
35
|
useEffect(() => () => router.replace({ search: null }), [router]);
|
|
36
36
|
|
|
@@ -46,7 +46,7 @@ const NewHostDetailsTab = ({ hostName, router }) => {
|
|
|
46
46
|
</DropdownItem>,
|
|
47
47
|
];
|
|
48
48
|
|
|
49
|
-
if (hits.length && !
|
|
49
|
+
if (hits.length && !isIop) {
|
|
50
50
|
const { host_uuid: uuid } = hits[0];
|
|
51
51
|
dropdownItems.push(
|
|
52
52
|
<DropdownItem key="insights-advisor-link" ouiaId="insights-advisor-link">
|
|
@@ -131,9 +131,9 @@ const IopInsightsTabWrapped = props => (
|
|
|
131
131
|
);
|
|
132
132
|
|
|
133
133
|
const InsightsTab = props => {
|
|
134
|
-
const
|
|
134
|
+
const isIop = useIopConfig();
|
|
135
135
|
|
|
136
|
-
return
|
|
136
|
+
return isIop ? (
|
|
137
137
|
<IopInsightsTabWrapped {...props} />
|
|
138
138
|
) : (
|
|
139
139
|
<NewHostDetailsTab {...props} />
|
|
@@ -4,13 +4,13 @@ import { UnknownIcon } from '@patternfly/react-icons';
|
|
|
4
4
|
import { Link } from 'react-router-dom';
|
|
5
5
|
import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
|
|
6
6
|
import { insightsCloudUrl } from '../InsightsCloudSync/InsightsCloudSyncHelpers';
|
|
7
|
-
import {
|
|
7
|
+
import { useIopConfig } from '../common/Hooks/ConfigHooks';
|
|
8
8
|
|
|
9
9
|
const vulnerabilityApiPath = path =>
|
|
10
10
|
insightsCloudUrl(`api/vulnerability/v1/${path}`);
|
|
11
11
|
|
|
12
12
|
export const CVECountCell = ({ hostDetails }) => {
|
|
13
|
-
const isIopEnabled =
|
|
13
|
+
const isIopEnabled = useIopConfig();
|
|
14
14
|
|
|
15
15
|
// eslint-disable-next-line camelcase
|
|
16
16
|
const uuid = hostDetails?.subscription_facet_attributes?.uuid;
|