foreman_rh_cloud 13.2.8 → 14.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/foreman_rh_cloud/locale/fr/foreman_rh_cloud.js +61 -61
  3. data/app/assets/javascripts/foreman_rh_cloud/locale/ja/foreman_rh_cloud.js +68 -68
  4. data/app/assets/javascripts/foreman_rh_cloud/locale/ka/foreman_rh_cloud.js +9 -9
  5. data/app/assets/javascripts/foreman_rh_cloud/locale/ko/foreman_rh_cloud.js +60 -60
  6. data/app/assets/javascripts/foreman_rh_cloud/locale/zh_CN/foreman_rh_cloud.js +60 -60
  7. data/app/models/concerns/rh_cloud_host.rb +1 -31
  8. data/app/services/foreman_rh_cloud/insights_api_forwarder.rb +5 -12
  9. data/lib/foreman_inventory_upload/async/create_missing_insights_facets.rb +2 -8
  10. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +0 -8
  11. data/lib/foreman_inventory_upload/generators/queries.rb +1 -1
  12. data/lib/foreman_inventory_upload/generators/slice.rb +1 -1
  13. data/lib/foreman_rh_cloud/version.rb +1 -1
  14. data/lib/insights_cloud/async/vmaas_reposcan_sync.rb +8 -23
  15. data/locale/fr/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
  16. data/locale/fr/foreman_rh_cloud.edit.po +1032 -0
  17. data/locale/fr/foreman_rh_cloud.po +65 -66
  18. data/locale/fr/foreman_rh_cloud.po.time_stamp +0 -0
  19. data/locale/ja/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
  20. data/locale/ja/foreman_rh_cloud.edit.po +1026 -0
  21. data/locale/ja/foreman_rh_cloud.po +70 -72
  22. data/locale/ja/foreman_rh_cloud.po.time_stamp +0 -0
  23. data/locale/ka/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
  24. data/locale/ka/foreman_rh_cloud.edit.po +1025 -0
  25. data/locale/ka/foreman_rh_cloud.po +10 -11
  26. data/locale/ka/foreman_rh_cloud.po.time_stamp +0 -0
  27. data/locale/ko/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
  28. data/locale/ko/foreman_rh_cloud.edit.po +1029 -0
  29. data/locale/ko/foreman_rh_cloud.po +63 -64
  30. data/locale/ko/foreman_rh_cloud.po.time_stamp +0 -0
  31. data/locale/zh_CN/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
  32. data/locale/zh_CN/foreman_rh_cloud.edit.po +1031 -0
  33. data/locale/zh_CN/foreman_rh_cloud.po +64 -65
  34. data/locale/zh_CN/foreman_rh_cloud.po.time_stamp +0 -0
  35. data/package.json +1 -1
  36. data/test/controllers/insights_cloud/api/machine_telemetries_controller_test.rb +1 -1
  37. data/test/jobs/inventory_full_sync_test.rb +4 -7
  38. data/test/jobs/inventory_hosts_sync_test.rb +5 -7
  39. data/test/jobs/inventory_self_host_sync_test.rb +1 -1
  40. data/test/unit/archived_report_generator_test.rb +1 -2
  41. data/test/unit/fact_helpers_test.rb +0 -16
  42. data/test/unit/lib/insights_cloud/async/vmaas_reposcan_sync_test.rb +25 -80
  43. data/test/unit/rh_cloud_host_test.rb +0 -154
  44. data/test/unit/services/foreman_rh_cloud/branch_info_test.rb +1 -1
  45. data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +1 -1
  46. data/test/unit/slice_generator_test.rb +2 -21
  47. data/webpack/CVEsHostDetailsTab/CVEsHostDetailsTab.js +1 -6
  48. data/webpack/CVEsHostDetailsTab/__tests__/CVEsHostDetailsTab.test.js +6 -45
  49. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +1 -3
  50. data/webpack/ForemanInventoryUpload/ForemanInventoryHelpers.js +0 -7
  51. data/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js +14 -44
  52. metadata +16 -4
  53. data/webpack/InsightsHostDetailsTab/__tests__/NewHostDetailsTab.test.js +0 -154
@@ -5,17 +5,19 @@ class VmaasReposcanSyncTest < ActiveSupport::TestCase
5
5
  include ForemanTasks::TestHelpers::WithInThreadExecutor
6
6
 
7
7
  setup do
8
- @organization = FactoryBot.create(:organization)
9
- # Create a simple repository - we only need id and organization_id for the action
10
- @repo = ::Katello::Repository.new(id: 1)
11
- @repo.stubs(:organization_id).returns(@organization.id)
12
- ::Katello::Repository.stubs(:find).with(1).returns(@repo)
13
-
8
+ @root = FactoryBot.build(:katello_root_repository, :fedora_17_x86_64_dev_root)
9
+ @root.save(validate: false)
10
+ @repo = FactoryBot.create(
11
+ :katello_repository,
12
+ :with_product,
13
+ distribution_family: 'Red Hat',
14
+ distribution_version: '7.5',
15
+ root: @root
16
+ )
14
17
  @repo_payload = { id: @repo.id }
15
18
  @expected_url = 'https://example.com/api/v1/vmaas/reposcan/sync'
16
19
  InsightsCloud.stubs(:vmaas_reposcan_sync_url).returns(@expected_url)
17
20
  ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
18
- Organization.stubs(:find).with(@organization.id).returns(@organization)
19
21
  end
20
22
 
21
23
  teardown do
@@ -81,7 +83,7 @@ class VmaasReposcanSyncTest < ActiveSupport::TestCase
81
83
  params[:url] == @expected_url &&
82
84
  params[:headers].is_a?(Hash) &&
83
85
  params[:headers]['Content-Type'] == 'application/json' &&
84
- params[:organization] == @organization
86
+ params[:organization] == @repo.organization
85
87
  end
86
88
  .returns(mock_response)
87
89
 
@@ -114,94 +116,37 @@ class VmaasReposcanSyncTest < ActiveSupport::TestCase
114
116
  .stubs(:execute_cloud_request)
115
117
  .raises(exception)
116
118
 
117
- task = ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
119
+ error = assert_raises(ForemanTasks::TaskError) do
120
+ ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
121
+ end
118
122
 
119
- assert_equal 'VMaaS reposcan sync failed: 500 - Server Error', task.output[:message]
123
+ assert_equal 'VMaaS reposcan sync failed: 500 - Server Error', error.task.output[:message]
120
124
  end
121
125
 
122
126
  test 'run sets error message in task output for StandardError exception' do
123
- mock_logger = mock('logger')
124
- mock_logger.expects(:error).with('Error triggering VMaaS reposcan sync: Network timeout')
125
- InsightsCloud::Async::VmaasReposcanSync.any_instance.stubs(:logger).returns(mock_logger)
126
-
127
127
  InsightsCloud::Async::VmaasReposcanSync.any_instance
128
128
  .stubs(:execute_cloud_request)
129
129
  .raises(StandardError.new('Network timeout'))
130
130
 
131
- task = ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
132
-
133
- assert_equal 'Error triggering VMaaS reposcan sync: Network timeout', task.output[:message]
134
- end
135
-
136
- test 'run logs and handles error response without raising' do
137
- error_response = mock('error_response')
138
- error_response.stubs(:code).returns(500)
139
- error_response.stubs(:body).returns('error')
140
- exception = RestClient::ExceptionWithResponse.new(error_response)
141
-
142
- InsightsCloud::Async::VmaasReposcanSync.any_instance
143
- .stubs(:execute_cloud_request)
144
- .raises(exception)
145
-
146
- task = ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
147
-
148
- assert_equal 'VMaaS reposcan sync failed: 500 - error', task.output[:message]
149
- end
150
-
151
- test 'run handles 429 error with warning log level' do
152
- error_response = mock('error_response')
153
- error_response.stubs(:code).returns(429)
154
- error_response.stubs(:body).returns('{"msg": "Another task already in progress"}')
155
- exception = RestClient::ExceptionWithResponse.new(error_response)
156
-
157
- mock_logger = mock('logger')
158
- mock_logger.expects(:warn).with('VMaaS reposcan sync skipped: another sync already in progress (429)')
159
- InsightsCloud::Async::VmaasReposcanSync.any_instance.stubs(:logger).returns(mock_logger)
160
-
161
- InsightsCloud::Async::VmaasReposcanSync.any_instance
162
- .stubs(:execute_cloud_request)
163
- .raises(exception)
164
-
165
- task = ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
131
+ error = assert_raises(ForemanTasks::TaskError) do
132
+ ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
133
+ end
166
134
 
167
- assert_equal 'VMaaS reposcan sync skipped: another sync already in progress (429)',
168
- task.output[:message]
135
+ # The task is available via main_action
136
+ assert_match(/Error triggering VMaaS reposcan sync: Network timeout, response: /,
137
+ error.task.main_action.output[:message])
169
138
  end
170
139
 
171
- test 'run handles non-429 errors with error log level' do
172
- error_response = mock('error_response')
173
- error_response.stubs(:code).returns(500)
174
- error_response.stubs(:body).returns('Internal Server Error')
140
+ test 'run logs and re-raises when cloud request returns error response' do
141
+ error_response = mock('error_response', code: 500, body: 'error')
175
142
  exception = RestClient::ExceptionWithResponse.new(error_response)
176
143
 
177
- mock_logger = mock('logger')
178
- mock_logger.expects(:error).with('VMaaS reposcan sync failed: 500 - Internal Server Error')
179
- InsightsCloud::Async::VmaasReposcanSync.any_instance.stubs(:logger).returns(mock_logger)
180
-
181
144
  InsightsCloud::Async::VmaasReposcanSync.any_instance
182
145
  .stubs(:execute_cloud_request)
183
146
  .raises(exception)
184
147
 
185
- task = ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
186
-
187
- assert_equal 'VMaaS reposcan sync failed: 500 - Internal Server Error',
188
- task.output[:message]
189
- end
190
-
191
- test 'run handles RestClient::ExceptionWithResponse with nil response' do
192
- exception = RestClient::ExceptionWithResponse.new(nil)
193
-
194
- mock_logger = mock('logger')
195
- mock_logger.expects(:error).with('VMaaS reposcan sync failed: - ')
196
- InsightsCloud::Async::VmaasReposcanSync.any_instance.stubs(:logger).returns(mock_logger)
197
-
198
- InsightsCloud::Async::VmaasReposcanSync.any_instance
199
- .stubs(:execute_cloud_request)
200
- .raises(exception)
201
-
202
- task = ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
203
-
204
- refute_nil task.output[:message]
205
- assert_equal 'VMaaS reposcan sync failed: - ', task.output[:message]
148
+ assert_raises(ForemanTasks::TaskError) do
149
+ ForemanTasks.sync_task(InsightsCloud::Async::VmaasReposcanSync, @repo_payload)
150
+ end
206
151
  end
207
152
  end
@@ -188,158 +188,4 @@ class RhCloudHostTest < ActiveSupport::TestCase
188
188
  assert_equal local_uuid, @host.insights_uuid
189
189
  end
190
190
  end
191
-
192
- context 'scoped search on insights_uuid' do
193
- setup do
194
- @org = FactoryBot.create(:organization)
195
- end
196
-
197
- teardown do
198
- ForemanRhCloud.unstub(:with_iop_smart_proxy?)
199
- end
200
-
201
- test 'searches insights_facet.uuid in non-IoP mode with = operator' do
202
- ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
203
- host1 = FactoryBot.create(:host, :managed, organization: @org)
204
- host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'insights-uuid-123')
205
- host2 = FactoryBot.create(:host, :managed, organization: @org)
206
- host2.insights = FactoryBot.create(:insights_facet, host_id: host2.id, uuid: 'insights-uuid-456')
207
-
208
- results = Host::Managed.search_for('insights_uuid = insights-uuid-123')
209
-
210
- assert_includes results, host1
211
- assert_not_includes results, host2
212
- end
213
-
214
- test 'searches subscription_facet.uuid in IoP mode with = operator' do
215
- ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
216
- host1 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
217
- host2 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
218
-
219
- # Even if insights_facet has different UUID, should use subscription_facet UUID
220
- host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'stale-123')
221
-
222
- results = Host::Managed.search_for("insights_uuid = #{host1.subscription_facet.uuid}")
223
-
224
- assert_includes results, host1
225
- assert_not_includes results, host2
226
- end
227
-
228
- test 'searches with ^ operator (IN) in non-IoP mode' do
229
- ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
230
- host1 = FactoryBot.create(:host, :managed, organization: @org)
231
- host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'uuid-1')
232
- host2 = FactoryBot.create(:host, :managed, organization: @org)
233
- host2.insights = FactoryBot.create(:insights_facet, host_id: host2.id, uuid: 'uuid-2')
234
- host3 = FactoryBot.create(:host, :managed, organization: @org)
235
- host3.insights = FactoryBot.create(:insights_facet, host_id: host3.id, uuid: 'uuid-3')
236
-
237
- results = Host::Managed.search_for('insights_uuid ^ (uuid-1,uuid-2)')
238
-
239
- assert_includes results, host1
240
- assert_includes results, host2
241
- assert_not_includes results, host3
242
- end
243
-
244
- test 'searches with ^ operator (IN) in IoP mode - THE BUG FIX' do
245
- ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
246
- host1 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
247
- host2 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
248
- host3 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
249
-
250
- # Create insights facets with stale UUIDs to verify we're using subscription_facet
251
- host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'stale-1')
252
- host2.insights = FactoryBot.create(:insights_facet, host_id: host2.id, uuid: 'stale-2')
253
- host3.insights = FactoryBot.create(:insights_facet, host_id: host3.id, uuid: 'stale-3')
254
-
255
- uuid1 = host1.subscription_facet.uuid
256
- uuid2 = host2.subscription_facet.uuid
257
-
258
- # This is the search query that remediation modal creates
259
- results = Host::Managed.search_for("insights_uuid ^ (#{uuid1},#{uuid2})")
260
-
261
- # Should find hosts by subscription_facet UUID, not insights_facet UUID
262
- assert_includes results, host1
263
- assert_includes results, host2
264
- assert_not_includes results, host3
265
- end
266
-
267
- test 'searches with !^ operator (NOT IN) in non-IoP mode' do
268
- ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
269
- host1 = FactoryBot.create(:host, :managed, organization: @org)
270
- host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'uuid-1')
271
- host2 = FactoryBot.create(:host, :managed, organization: @org)
272
- host2.insights = FactoryBot.create(:insights_facet, host_id: host2.id, uuid: 'uuid-2')
273
- host3 = FactoryBot.create(:host, :managed, organization: @org)
274
- host3.insights = FactoryBot.create(:insights_facet, host_id: host3.id, uuid: 'uuid-3')
275
-
276
- results = Host::Managed.search_for('insights_uuid !^ (uuid-1,uuid-2)')
277
-
278
- assert_not_includes results, host1
279
- assert_not_includes results, host2
280
- assert_includes results, host3
281
- end
282
-
283
- test 'searches with !^ operator (NOT IN) in IoP mode' do
284
- ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
285
- host1 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
286
- host2 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
287
- host3 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
288
-
289
- uuid1 = host1.subscription_facet.uuid
290
- uuid2 = host2.subscription_facet.uuid
291
-
292
- results = Host::Managed.search_for("insights_uuid !^ (#{uuid1},#{uuid2})")
293
-
294
- assert_not_includes results, host1
295
- assert_not_includes results, host2
296
- assert_includes results, host3
297
- end
298
-
299
- test 'handles hosts without facets in non-IoP mode' do
300
- ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
301
- host_without_facet = FactoryBot.create(:host, :managed, organization: @org)
302
- host_with_facet = FactoryBot.create(:host, :managed, organization: @org)
303
- host_with_facet.insights = FactoryBot.create(:insights_facet, host_id: host_with_facet.id, uuid: 'uuid-1')
304
-
305
- results = Host::Managed.search_for('insights_uuid = uuid-1')
306
-
307
- assert_includes results, host_with_facet
308
- assert_not_includes results, host_without_facet
309
- end
310
-
311
- test 'handles hosts without subscription_facet in IoP mode' do
312
- ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
313
- host_without_sub = FactoryBot.create(:host, :managed, organization: @org)
314
- host_with_sub = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
315
-
316
- uuid = host_with_sub.subscription_facet.uuid
317
-
318
- results = Host::Managed.search_for("insights_uuid = #{uuid}")
319
-
320
- assert_includes results, host_with_sub
321
- assert_not_includes results, host_without_sub
322
- end
323
-
324
- test 'mode changes are reflected in searches' do
325
- host1 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
326
- host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'insights-uuid-abc')
327
- insights_uuid = 'insights-uuid-abc'
328
- subscription_uuid = host1.subscription_facet.uuid
329
-
330
- # Non-IoP mode: should find by insights_facet UUID
331
- ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
332
- results = Host::Managed.search_for("insights_uuid = #{insights_uuid}")
333
- assert_includes results, host1
334
-
335
- # IoP mode: should find by subscription_facet UUID
336
- ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
337
- results = Host::Managed.search_for("insights_uuid = #{subscription_uuid}")
338
- assert_includes results, host1
339
-
340
- # Should NOT find by old insights_facet UUID in IoP mode
341
- results = Host::Managed.search_for("insights_uuid = #{insights_uuid}")
342
- assert_not_includes results, host1
343
- end
344
- end
345
191
  end
@@ -19,7 +19,7 @@ class BranchInfoTest < ActiveSupport::TestCase
19
19
  organization: env.organization
20
20
  )
21
21
 
22
- @host.subscription_facet.pools << FactoryBot.create(:katello_pool, account_number: '5678', cp_id: 1)
22
+ @host.organization.pools << FactoryBot.create(:katello_pool, account_number: '5678', cp_id: 1)
23
23
  end
24
24
 
25
25
  test 'should generate branch info for host' do
@@ -29,7 +29,7 @@ class CloudRequestForwarderTest < ActiveSupport::TestCase
29
29
  organization: env.organization
30
30
  )
31
31
 
32
- @host.subscription_facet.pools << FactoryBot.create(:katello_pool, account_number: '5678', cp_id: 1)
32
+ @host.organization.pools << FactoryBot.create(:katello_pool, account_number: '5678', cp_id: 1)
33
33
  end
34
34
 
35
35
  test 'should prepare correct cloud url' do
@@ -641,6 +641,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
641
641
  assert_tag('1', actual_host, 'int_param', 'satellite_parameter')
642
642
 
643
643
  assert_equal false, satellite_facts['is_hostname_obfuscated']
644
+ assert_equal true, satellite_facts['is_simple_content_access']
644
645
 
645
646
  version = satellite_facts['satellite_version']
646
647
  if defined?(ForemanThemeSatellite)
@@ -702,22 +703,6 @@ class SliceGeneratorTest < ActiveSupport::TestCase
702
703
  assert_equal 'test_sla', fact_values['system_purpose_sla']
703
704
  end
704
705
 
705
- test 'generates a report for a golden ticket' do
706
- batch = Host.where(id: @host.id).in_batches.first
707
- generator = create_generator(batch) do |generator|
708
- generator.stubs(:golden_ticket?).returns(true)
709
- end
710
-
711
- json_str = generator.render
712
- actual = JSON.parse(json_str.join("\n"))
713
-
714
- assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
715
- assert_not_nil(actual_host = actual['hosts'].first)
716
- assert_equal @host.fqdn, actual_host['fqdn']
717
- assert_equal '1234', actual_host['account']
718
- assert_equal 1, generator.hosts_count
719
- end
720
-
721
706
  test 'skips hosts without subscription' do
722
707
  a_host = FactoryBot.create(
723
708
  :host,
@@ -1131,11 +1116,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
1131
1116
 
1132
1117
  def create_generator(batch, name = '00000000-0000-0000-0000-000000000000')
1133
1118
  generator = ForemanInventoryUpload::Generators::Slice.new(batch, [], name)
1134
- if block_given?
1135
- yield(generator)
1136
- else
1137
- generator.stubs(:golden_ticket?).returns(false)
1138
- end
1119
+ yield(generator) if block_given?
1139
1120
  generator
1140
1121
  end
1141
1122
 
@@ -10,12 +10,7 @@ const CVEsHostDetailsTab = ({ systemId }) => {
10
10
  const module = './SystemDetailTable';
11
11
  return (
12
12
  <div className="rh-cloud-insights-vulnerability-host-details-component vulnerability">
13
- <ScalprumComponent
14
- key={systemId}
15
- scope={scope}
16
- module={module}
17
- systemId={systemId}
18
- />
13
+ <ScalprumComponent scope={scope} module={module} systemId={systemId} />
19
14
  </div>
20
15
  );
21
16
  };
@@ -11,25 +11,14 @@ jest.mock('foremanReact/Root/Context/ForemanContext', () => ({
11
11
  useForemanPermissions: () => new Set(['view_vulnerability']),
12
12
  }));
13
13
 
14
- const mockUnmountTracker = jest.fn();
15
- jest.mock('@scalprum/react-core', () => {
16
- const ReactMock = require('react');
17
- return {
18
- ScalprumComponent: jest.fn(props => {
19
- ReactMock.useEffect(() => mockUnmountTracker, []);
20
- return (
21
- <div data-testid="mock-scalprum-component">{JSON.stringify(props)}</div>
22
- );
23
- }),
24
- ScalprumProvider: jest.fn(({ children }) => <div>{children}</div>),
25
- };
26
- });
14
+ jest.mock('@scalprum/react-core', () => ({
15
+ ScalprumComponent: jest.fn(props => (
16
+ <div data-testid="mock-scalprum-component">{JSON.stringify(props)}</div>
17
+ )),
18
+ ScalprumProvider: jest.fn(({ children }) => <div>{children}</div>),
19
+ }));
27
20
 
28
21
  describe('CVEsHostDetailsTabWrapper', () => {
29
- beforeEach(() => {
30
- jest.clearAllMocks();
31
- });
32
-
33
22
  it('renders without crashing', () => {
34
23
  const { container } = render(
35
24
  <CVEsHostDetailsTabWrapper
@@ -42,32 +31,4 @@ describe('CVEsHostDetailsTabWrapper', () => {
42
31
  )
43
32
  ).toBeTruthy();
44
33
  });
45
-
46
- it('remounts ScalprumComponent when systemId changes', () => {
47
- const { ScalprumComponent } = require('@scalprum/react-core');
48
-
49
- const { rerender } = render(
50
- <CVEsHostDetailsTabWrapper
51
- response={{ subscription_facet_attributes: { uuid: 'uuid-host-A' } }}
52
- />
53
- );
54
-
55
- expect(mockUnmountTracker).not.toHaveBeenCalled();
56
- expect(ScalprumComponent).toHaveBeenLastCalledWith(
57
- expect.objectContaining({ systemId: 'uuid-host-A' }),
58
- expect.anything()
59
- );
60
-
61
- rerender(
62
- <CVEsHostDetailsTabWrapper
63
- response={{ subscription_facet_attributes: { uuid: 'uuid-host-B' } }}
64
- />
65
- );
66
-
67
- expect(mockUnmountTracker).toHaveBeenCalledTimes(1);
68
- expect(ScalprumComponent).toHaveBeenLastCalledWith(
69
- expect.objectContaining({ systemId: 'uuid-host-B' }),
70
- expect.anything()
71
- );
72
- });
73
34
  });
@@ -7,8 +7,6 @@ import { getDocsURL } from 'foremanReact/common/helpers';
7
7
  import { FormattedMessage } from 'react-intl';
8
8
  import { selectSubscriptionConnectionEnabled } from '../../../InventorySettings/InventorySettingsSelectors';
9
9
 
10
- import { getSubscriptionServiceDocsUrl } from '../../../../ForemanInventoryHelpers';
11
-
12
10
  export const PageDescription = () => {
13
11
  const subscriptionConnectionEnabled = useSelector(
14
12
  selectSubscriptionConnectionEnabled
@@ -82,7 +80,7 @@ export const PageDescription = () => {
82
80
  {__('For more information about the Subscriptions service, see:')}
83
81
  &nbsp;
84
82
  <a
85
- href={getSubscriptionServiceDocsUrl()}
83
+ href="https://docs.redhat.com/en/documentation/subscription_central/1-latest/html/getting_started_with_the_subscriptions_service/index"
86
84
  target="_blank"
87
85
  rel="noopener noreferrer"
88
86
  >
@@ -11,13 +11,6 @@ export const getInventoryDocsUrl = () =>
11
11
  )}`
12
12
  );
13
13
 
14
- export const getSubscriptionServiceDocsUrl = () =>
15
- foremanUrl(
16
- `/links/manual/?root_url=${URI.encode(
17
- 'https://docs.redhat.com/en/documentation/subscription_central/1-latest/html-single/getting_started_with_the_subscriptions_service/index'
18
- )}`
19
- );
20
-
21
14
  export const getActionsHistoryUrl = () =>
22
15
  foremanUrl(
23
16
  '/foreman_tasks/tasks?search=label+%3D+ForemanInventoryUpload%3A%3AAsync%3A%3AHostInventoryReportJob+or+label+%3D+ForemanInventoryUpload%3A%3AAsync%3A%3AGenerateAllReportsJob&page=1'
@@ -33,28 +33,13 @@ const NewHostDetailsTab = ({ hostName, router }) => {
33
33
  const hits = useSelector(selectHits);
34
34
  const isIop = useIopConfig();
35
35
 
36
- useEffect(
37
- () => () => {
38
- // Preserve hash when clearing search params to prevent tab navigation bugs
39
- if (router && typeof router.replace === 'function') {
40
- const replaceOptions = { search: null };
41
- if (router.location && router.location.hash) {
42
- replaceOptions.hash = router.location.hash;
43
- }
44
- router.replace(replaceOptions);
45
- }
46
- },
47
- [router]
48
- );
36
+ useEffect(() => () => router.replace({ search: null }), [router]);
49
37
 
50
38
  const onSearch = q => dispatch(fetchInsights({ query: q, page: 1 }));
51
39
 
52
40
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
53
- const onSatInsightsClick = () => {
54
- if (router && typeof router.push === 'function') {
55
- router.push({ pathname: '/foreman_rh_cloud/insights_cloud' });
56
- }
57
- };
41
+ const onSatInsightsClick = () =>
42
+ router.push({ pathname: '/foreman_rh_cloud/insights_cloud' });
58
43
 
59
44
  const dropdownItems = [
60
45
  <DropdownItem key="insights-link" ouiaId="insights-link">
@@ -128,32 +113,17 @@ NewHostDetailsTab.defaultProps = {
128
113
  const scope = 'advisor';
129
114
  const module = './SystemDetailWrapped';
130
115
 
131
- const IopInsightsTab = props => {
132
- // eslint-disable-next-line camelcase
133
- const systemId = props.response?.subscription_facet_attributes?.uuid;
134
- return (
135
- <div className="advisor">
136
- <ScalprumComponent
137
- key={systemId || props.hostName}
138
- scope={scope}
139
- module={module}
140
- IopRemediationModal={RemediationModal}
141
- generateRuleUrl={generateRuleUrl}
142
- {...props}
143
- />
144
- </div>
145
- );
146
- };
147
-
148
- IopInsightsTab.propTypes = {
149
- hostName: PropTypes.string,
150
- response: PropTypes.object,
151
- };
152
-
153
- IopInsightsTab.defaultProps = {
154
- hostName: '',
155
- response: {},
156
- };
116
+ const IopInsightsTab = props => (
117
+ <div className="advisor">
118
+ <ScalprumComponent
119
+ scope={scope}
120
+ module={module}
121
+ IopRemediationModal={RemediationModal}
122
+ generateRuleUrl={generateRuleUrl}
123
+ {...props}
124
+ />
125
+ </div>
126
+ );
157
127
 
158
128
  const IopInsightsTabWrapped = props => {
159
129
  const permissions = useInsightsPermissions();
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_rh_cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 13.2.8
4
+ version: 14.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Foreman Red Hat Cloud team
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-02-25 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: foreman_ansible
@@ -233,16 +234,26 @@ files:
233
234
  - locale/Makefile
234
235
  - locale/foreman_rh_cloud.pot
235
236
  - locale/fr/LC_MESSAGES/foreman_rh_cloud.mo
237
+ - locale/fr/foreman_rh_cloud.edit.po
236
238
  - locale/fr/foreman_rh_cloud.po
239
+ - locale/fr/foreman_rh_cloud.po.time_stamp
237
240
  - locale/gemspec.rb
238
241
  - locale/ja/LC_MESSAGES/foreman_rh_cloud.mo
242
+ - locale/ja/foreman_rh_cloud.edit.po
239
243
  - locale/ja/foreman_rh_cloud.po
244
+ - locale/ja/foreman_rh_cloud.po.time_stamp
240
245
  - locale/ka/LC_MESSAGES/foreman_rh_cloud.mo
246
+ - locale/ka/foreman_rh_cloud.edit.po
241
247
  - locale/ka/foreman_rh_cloud.po
248
+ - locale/ka/foreman_rh_cloud.po.time_stamp
242
249
  - locale/ko/LC_MESSAGES/foreman_rh_cloud.mo
250
+ - locale/ko/foreman_rh_cloud.edit.po
243
251
  - locale/ko/foreman_rh_cloud.po
252
+ - locale/ko/foreman_rh_cloud.po.time_stamp
244
253
  - locale/zh_CN/LC_MESSAGES/foreman_rh_cloud.mo
254
+ - locale/zh_CN/foreman_rh_cloud.edit.po
245
255
  - locale/zh_CN/foreman_rh_cloud.po
256
+ - locale/zh_CN/foreman_rh_cloud.po.time_stamp
246
257
  - package.json
247
258
  - test/controllers/accounts_controller_test.rb
248
259
  - test/controllers/insights_cloud/api/advisor_engine_controller_test.rb
@@ -586,7 +597,6 @@ files:
586
597
  - webpack/InsightsHostDetailsTab/__tests__/InsightsTabReducer.test.js
587
598
  - webpack/InsightsHostDetailsTab/__tests__/InsightsTabSelectors.test.js
588
599
  - webpack/InsightsHostDetailsTab/__tests__/InsightsTotalRiskChart.test.js
589
- - webpack/InsightsHostDetailsTab/__tests__/NewHostDetailsTab.test.js
590
600
  - webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTab.test.js.snap
591
601
  - webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTabActions.test.js.snap
592
602
  - webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTabReducer.test.js.snap
@@ -652,6 +662,7 @@ homepage: https://github.com/theforeman/foreman_rh_cloud
652
662
  licenses:
653
663
  - GPL-3.0
654
664
  metadata: {}
665
+ post_install_message:
655
666
  rdoc_options: []
656
667
  require_paths:
657
668
  - lib
@@ -669,7 +680,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
669
680
  - !ruby/object:Gem::Version
670
681
  version: '0'
671
682
  requirements: []
672
- rubygems_version: 4.0.6
683
+ rubygems_version: 3.2.33
684
+ signing_key:
673
685
  specification_version: 4
674
686
  summary: Summary of ForemanRhCloud.
675
687
  test_files: