foreman_rh_cloud 12.2.13 → 12.2.15
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 +2 -2
- data/app/controllers/concerns/insights_cloud/package_profile_upload_extensions.rb +3 -0
- data/app/controllers/foreman_inventory_upload/accounts_controller.rb +1 -1
- data/app/controllers/foreman_inventory_upload/uploads_controller.rb +1 -1
- data/app/controllers/insights_cloud/ui_requests_controller.rb +2 -3
- data/app/models/concerns/rh_cloud_host.rb +14 -0
- data/app/models/foreman_rh_cloud/ping.rb +2 -1
- data/app/services/foreman_rh_cloud/tags_auth.rb +13 -3
- data/app/views/api/v2/advisor_engine/host_details.json.rabl +1 -3
- data/app/views/api/v2/hosts/insights/base.rabl +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 +0 -4
- data/lib/foreman_rh_cloud/plugin.rb +11 -4
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/lib/foreman_rh_cloud.rb +3 -3
- data/lib/insights_cloud/async/connector_playbook_execution_reporter_task.rb +3 -3
- data/lib/inventory_sync/async/inventory_hosts_sync.rb +0 -2
- data/package.json +1 -1
- data/test/controllers/accounts_controller_test.rb +1 -1
- data/test/controllers/insights_cloud/api/advisor_engine_controller_test.rb +28 -1
- data/test/controllers/insights_cloud/ui_requests_controller_test.rb +26 -0
- data/test/controllers/uploads_controller_test.rb +1 -1
- data/test/factories/insights_factories.rb +29 -0
- data/test/jobs/queue_for_upload_job_test.rb +1 -12
- data/test/jobs/upload_report_direct_job_test.rb +399 -0
- data/test/unit/foreman_rh_cloud_iop_metadata_test.rb +200 -0
- data/test/unit/lib/foreman_rh_cloud/registration_manager_extensions_test.rb +4 -42
- data/test/unit/rh_cloud_host_test.rb +191 -0
- data/test/unit/services/foreman_rh_cloud/tags_auth_test.rb +14 -0
- data/webpack/ForemanColumnExtensions/index.js +2 -0
- 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/__tests__/__snapshots__/PageTitle.test.js.snap +1 -1
- 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/ForemanInventoryUpload/ForemanInventoryHelpers.js +1 -1
- data/webpack/ForemanInventoryUpload/__tests__/__snapshots__/ForemanInventoryHelpers.test.js.snap +1 -1
- 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 +24 -4
- 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 +9 -9
- 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 -38
- 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
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
require 'test_plugin_helper'
|
|
2
|
+
|
|
3
|
+
class RhCloudHostTest < ActiveSupport::TestCase
|
|
4
|
+
setup do
|
|
5
|
+
@org = FactoryBot.create(:organization)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
teardown do
|
|
9
|
+
ForemanRhCloud.unstub(:with_iop_smart_proxy?)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
context 'insights_uuid method' do
|
|
13
|
+
test 'returns insights_facet uuid in non-IoP mode' do
|
|
14
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
15
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
16
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'insights-123')
|
|
17
|
+
|
|
18
|
+
assert_equal 'insights-123', @host.insights_uuid
|
|
19
|
+
assert_not_equal @host.subscription_facet.uuid, @host.insights_uuid
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
test 'returns subscription_facet uuid in IoP mode' do
|
|
23
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
24
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
25
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'insights-456')
|
|
26
|
+
|
|
27
|
+
assert_equal @host.subscription_facet.uuid, @host.insights_uuid
|
|
28
|
+
assert_not_equal 'insights-456', @host.insights_uuid
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
test 'returns nil when insights_facet missing in non-IoP mode' do
|
|
32
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
33
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
34
|
+
|
|
35
|
+
assert_nil @host.insights_uuid
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test 'returns nil when subscription_facet missing in IoP mode' do
|
|
39
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
40
|
+
@host = FactoryBot.create(:host, :managed, organization: @org)
|
|
41
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'insights-789')
|
|
42
|
+
|
|
43
|
+
assert_nil @host.insights_uuid
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
test 'returns nil when both facets missing' do
|
|
47
|
+
@host = FactoryBot.create(:host, :managed, organization: @org)
|
|
48
|
+
|
|
49
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
50
|
+
assert_nil @host.insights_uuid
|
|
51
|
+
|
|
52
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
53
|
+
assert_nil @host.insights_uuid
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
test 'never returns stale insights_facet uuid in IoP mode' do
|
|
57
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
58
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
59
|
+
current_uuid = @host.subscription_facet.uuid
|
|
60
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'stale-456')
|
|
61
|
+
|
|
62
|
+
# Should return subscription_facet UUID, never the stale insights_facet UUID
|
|
63
|
+
assert_equal current_uuid, @host.insights_uuid
|
|
64
|
+
assert_not_equal 'stale-456', @host.insights_uuid
|
|
65
|
+
|
|
66
|
+
# Verify multiple calls always return subscription_facet UUID
|
|
67
|
+
3.times do
|
|
68
|
+
assert_equal current_uuid, @host.insights_uuid
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
test 'dynamically responds to IoP mode changes' do
|
|
73
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
74
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'insights-123')
|
|
75
|
+
subscription_uuid = @host.subscription_facet.uuid
|
|
76
|
+
|
|
77
|
+
# Non-IoP mode: should return insights_facet UUID
|
|
78
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
79
|
+
assert_equal 'insights-123', @host.insights_uuid
|
|
80
|
+
|
|
81
|
+
# IoP mode: should return subscription_facet UUID
|
|
82
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
83
|
+
assert_equal subscription_uuid, @host.insights_uuid
|
|
84
|
+
|
|
85
|
+
# Toggle back to non-IoP mode
|
|
86
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
87
|
+
assert_equal 'insights-123', @host.insights_uuid
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context 'ensure_iop_insights_uuid method' do
|
|
92
|
+
test 'updates insights_facet uuid when different from subscription_facet' do
|
|
93
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
94
|
+
correct_uuid = @host.subscription_facet.uuid
|
|
95
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'wrong-456')
|
|
96
|
+
|
|
97
|
+
assert_equal 'wrong-456', @host.insights_facet.uuid
|
|
98
|
+
|
|
99
|
+
@host.ensure_iop_insights_uuid
|
|
100
|
+
|
|
101
|
+
assert_equal correct_uuid, @host.insights_facet.reload.uuid
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
test 'does nothing when uuids already match' do
|
|
105
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
106
|
+
matching_uuid = @host.subscription_facet.uuid
|
|
107
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: matching_uuid)
|
|
108
|
+
|
|
109
|
+
# Expect no update call since UUIDs already match
|
|
110
|
+
@host.insights_facet.expects(:update!).never
|
|
111
|
+
|
|
112
|
+
@host.ensure_iop_insights_uuid
|
|
113
|
+
|
|
114
|
+
assert_equal matching_uuid, @host.insights_facet.uuid
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
test 'does nothing when insights_facet missing' do
|
|
118
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
119
|
+
|
|
120
|
+
assert_nothing_raised do
|
|
121
|
+
@host.ensure_iop_insights_uuid
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
test 'does nothing when subscription_facet missing' do
|
|
126
|
+
@host = FactoryBot.create(:host, :managed, organization: @org)
|
|
127
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'insights-999')
|
|
128
|
+
original_uuid = @host.insights_facet.uuid
|
|
129
|
+
|
|
130
|
+
assert_nothing_raised do
|
|
131
|
+
@host.ensure_iop_insights_uuid
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
assert_equal original_uuid, @host.insights_facet.uuid
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
test 'does nothing when both facets missing' do
|
|
138
|
+
@host = FactoryBot.create(:host, :managed, organization: @org)
|
|
139
|
+
|
|
140
|
+
assert_nothing_raised do
|
|
141
|
+
@host.ensure_iop_insights_uuid
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
test 'handles nil uuids gracefully' do
|
|
146
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
147
|
+
|
|
148
|
+
# Scenario 1: subscription_facet uuid is nil (shouldn't happen but test gracefully)
|
|
149
|
+
@host.subscription_facet.update(uuid: nil)
|
|
150
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'some-uuid')
|
|
151
|
+
|
|
152
|
+
assert_nothing_raised do
|
|
153
|
+
@host.ensure_iop_insights_uuid
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Scenario 2: insights_facet uuid is nil
|
|
157
|
+
@host.subscription_facet.update(uuid: 'valid-uuid')
|
|
158
|
+
@host.insights_facet.update(uuid: nil)
|
|
159
|
+
|
|
160
|
+
assert_nothing_raised do
|
|
161
|
+
@host.ensure_iop_insights_uuid
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Should update to match subscription_facet
|
|
165
|
+
assert_equal 'valid-uuid', @host.insights_facet.reload.uuid
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
test 'corrects stale uuid after cloud registration' do
|
|
169
|
+
# Simulate a host that was previously registered to cloud with cloud-assigned UUID
|
|
170
|
+
@host = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
171
|
+
local_uuid = @host.subscription_facet.uuid
|
|
172
|
+
@host.insights = FactoryBot.create(:insights_facet, host_id: @host.id, uuid: 'cloud-456')
|
|
173
|
+
|
|
174
|
+
# Before sync: insights_facet has stale cloud UUID
|
|
175
|
+
assert_equal 'cloud-456', @host.insights_facet.uuid
|
|
176
|
+
|
|
177
|
+
# In IoP mode, insights_uuid should return subscription_facet UUID (not stale)
|
|
178
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
179
|
+
assert_equal local_uuid, @host.insights_uuid
|
|
180
|
+
|
|
181
|
+
# Call sync to correct the stale UUID
|
|
182
|
+
@host.ensure_iop_insights_uuid
|
|
183
|
+
|
|
184
|
+
# After sync: insights_facet UUID should match subscription_facet UUID
|
|
185
|
+
assert_equal local_uuid, @host.insights_facet.reload.uuid
|
|
186
|
+
|
|
187
|
+
# Verify insights_uuid still returns correct value
|
|
188
|
+
assert_equal local_uuid, @host.insights_uuid
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
@@ -40,4 +40,18 @@ class TagsAuthTest < ActiveSupport::TestCase
|
|
|
40
40
|
|
|
41
41
|
@auth.update_tag
|
|
42
42
|
end
|
|
43
|
+
|
|
44
|
+
test 'Generates tags with wildcard location when location is nil' do
|
|
45
|
+
auth_with_nil_loc = ::ForemanRhCloud::TagsAuth.new(@user, @org, nil, @logger)
|
|
46
|
+
uuid1 = 'test_uuid1'
|
|
47
|
+
|
|
48
|
+
auth_with_nil_loc.expects(:allowed_hosts).returns([uuid1])
|
|
49
|
+
auth_with_nil_loc.expects(:execute_cloud_request).with do |actual_params|
|
|
50
|
+
actual = JSON.parse(actual_params[:payload])
|
|
51
|
+
assert_includes actual['host_id_list'], uuid1
|
|
52
|
+
assert_equal "U:\"#{@user.login}\"O:\"#{@org.name}\"L:\"*\"", actual['tags'].first['value']
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
auth_with_nil_loc.update_tag
|
|
56
|
+
end
|
|
43
57
|
end
|
|
@@ -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
|
});
|
|
@@ -32,7 +32,7 @@ exports[`PageTitle rendering render without Props 1`] = `
|
|
|
32
32
|
Actions history
|
|
33
33
|
</DropdownItem>,
|
|
34
34
|
<DropdownItem
|
|
35
|
-
href="/links/manual/?root_url=https%3A%2F%
|
|
35
|
+
href="/links/manual/?root_url=https%3A%2F%2Fdocs.redhat.com%2Fen%2Fdocumentation%2Fred_hat_lightspeed%2F1-latest%2Fhtml-single%2Fred_hat_lightspeed_remediations_guide%2Findex"
|
|
36
36
|
ouiaId="inventory-documentation-button"
|
|
37
37
|
rel="noopener noreferrer"
|
|
38
38
|
target="_blank"
|
|
@@ -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
|
});
|
|
@@ -7,7 +7,7 @@ export const inventoryUrl = path =>
|
|
|
7
7
|
export const getInventoryDocsUrl = () =>
|
|
8
8
|
foremanUrl(
|
|
9
9
|
`/links/manual/?root_url=${URI.encode(
|
|
10
|
-
'https://
|
|
10
|
+
'https://docs.redhat.com/en/documentation/red_hat_lightspeed/1-latest/html-single/red_hat_lightspeed_remediations_guide/index'
|
|
11
11
|
)}`
|
|
12
12
|
);
|
|
13
13
|
|
data/webpack/ForemanInventoryUpload/__tests__/__snapshots__/ForemanInventoryHelpers.test.js.snap
CHANGED
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`ForemanInventoryUpload helpers should return inventory Url 1`] = `"/foreman_inventory_upload/test_path"`;
|
|
4
4
|
|
|
5
|
-
exports[`ForemanInventoryUpload helpers should return inventory docs url 1`] = `"/links/manual/?root_url=https%3A%2F%
|
|
5
|
+
exports[`ForemanInventoryUpload helpers should return inventory docs url 1`] = `"/links/manual/?root_url=https%3A%2F%2Fdocs.redhat.com%2Fen%2Fdocumentation%2Fred_hat_lightspeed%2F1-latest%2Fhtml-single%2Fred_hat_lightspeed_remediations_guide%2Findex"`;
|
|
@@ -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">
|