foreman_rh_cloud 13.2.7 → 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 (48) 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/services/foreman_rh_cloud/insights_api_forwarder.rb +5 -12
  8. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +0 -8
  9. data/lib/foreman_inventory_upload/generators/queries.rb +1 -1
  10. data/lib/foreman_inventory_upload/generators/slice.rb +1 -1
  11. data/lib/foreman_rh_cloud/version.rb +1 -1
  12. data/locale/fr/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
  13. data/locale/fr/foreman_rh_cloud.edit.po +1032 -0
  14. data/locale/fr/foreman_rh_cloud.po +65 -66
  15. data/locale/fr/foreman_rh_cloud.po.time_stamp +0 -0
  16. data/locale/ja/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
  17. data/locale/ja/foreman_rh_cloud.edit.po +1026 -0
  18. data/locale/ja/foreman_rh_cloud.po +70 -72
  19. data/locale/ja/foreman_rh_cloud.po.time_stamp +0 -0
  20. data/locale/ka/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
  21. data/locale/ka/foreman_rh_cloud.edit.po +1025 -0
  22. data/locale/ka/foreman_rh_cloud.po +10 -11
  23. data/locale/ka/foreman_rh_cloud.po.time_stamp +0 -0
  24. data/locale/ko/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
  25. data/locale/ko/foreman_rh_cloud.edit.po +1029 -0
  26. data/locale/ko/foreman_rh_cloud.po +63 -64
  27. data/locale/ko/foreman_rh_cloud.po.time_stamp +0 -0
  28. data/locale/zh_CN/LC_MESSAGES/foreman_rh_cloud.mo +0 -0
  29. data/locale/zh_CN/foreman_rh_cloud.edit.po +1031 -0
  30. data/locale/zh_CN/foreman_rh_cloud.po +64 -65
  31. data/locale/zh_CN/foreman_rh_cloud.po.time_stamp +0 -0
  32. data/package.json +1 -1
  33. data/test/controllers/insights_cloud/api/machine_telemetries_controller_test.rb +1 -1
  34. data/test/jobs/inventory_full_sync_test.rb +4 -7
  35. data/test/jobs/inventory_hosts_sync_test.rb +5 -7
  36. data/test/jobs/inventory_self_host_sync_test.rb +1 -1
  37. data/test/unit/archived_report_generator_test.rb +1 -2
  38. data/test/unit/fact_helpers_test.rb +0 -16
  39. data/test/unit/services/foreman_rh_cloud/branch_info_test.rb +1 -1
  40. data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +1 -1
  41. data/test/unit/slice_generator_test.rb +2 -21
  42. data/webpack/CVEsHostDetailsTab/CVEsHostDetailsTab.js +1 -6
  43. data/webpack/CVEsHostDetailsTab/__tests__/CVEsHostDetailsTab.test.js +6 -45
  44. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +1 -3
  45. data/webpack/ForemanInventoryUpload/ForemanInventoryHelpers.js +0 -7
  46. data/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js +14 -44
  47. metadata +16 -4
  48. data/webpack/InsightsHostDetailsTab/__tests__/NewHostDetailsTab.test.js +0 -154
@@ -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.7
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:
@@ -1,154 +0,0 @@
1
- import React from 'react';
2
- import { render } from '@testing-library/react';
3
- import '@testing-library/jest-dom';
4
- import { Provider } from 'react-redux';
5
- import configureMockStore from 'redux-mock-store';
6
- import thunk from 'redux-thunk';
7
- import NewHostDetailsTab from '../NewHostDetailsTab';
8
-
9
- jest.mock('../../common/Hooks/ConfigHooks', () => ({
10
- useIopConfig: jest.fn(() => false),
11
- }));
12
-
13
- jest.mock('foremanReact/common/I18n', () => ({
14
- translate: jest.fn(str => str),
15
- }));
16
-
17
- const mockStore = configureMockStore([thunk]);
18
-
19
- describe('NewHostDetailsTab', () => {
20
- let store;
21
- let mockRouter;
22
-
23
- beforeEach(() => {
24
- mockRouter = {
25
- push: jest.fn(),
26
- replace: jest.fn(),
27
- location: {
28
- pathname: '/new/hosts/test-host.example.com',
29
- search: '?page=1&per_page=20',
30
- hash: '#/Insights',
31
- query: { page: '1', per_page: '20' },
32
- },
33
- };
34
-
35
- store = mockStore({
36
- API: {},
37
- ForemanRhCloud: {
38
- InsightsCloudSync: {
39
- table: {
40
- selectedIds: {},
41
- isAllSelected: false,
42
- showSelectAllAlert: false,
43
- },
44
- },
45
- },
46
- insightsHostDetailsTab: {
47
- query: '',
48
- hits: [],
49
- selectedIds: {},
50
- error: null,
51
- },
52
- router: {
53
- location: {
54
- pathname: '/new/hosts/test-host.example.com',
55
- search: '?page=1&per_page=20',
56
- hash: '#/Insights',
57
- query: { page: '1', per_page: '20' },
58
- },
59
- },
60
- });
61
- });
62
-
63
- afterEach(() => {
64
- jest.clearAllMocks();
65
- });
66
-
67
- describe('cleanup effect', () => {
68
- it('should preserve hash when clearing search params on unmount', () => {
69
- const { unmount } = render(
70
- <Provider store={store}>
71
- <NewHostDetailsTab
72
- hostName="test-host.example.com"
73
- router={mockRouter}
74
- />
75
- </Provider>
76
- );
77
-
78
- // Unmount the component to trigger cleanup
79
- unmount();
80
-
81
- // Verify router.replace was called with both search: null AND the existing hash
82
- expect(mockRouter.replace).toHaveBeenCalledWith({
83
- search: null,
84
- hash: '#/Insights',
85
- });
86
- });
87
-
88
- it('should only clear search params when no hash exists', () => {
89
- mockRouter.location.hash = '';
90
-
91
- const { unmount } = render(
92
- <Provider store={store}>
93
- <NewHostDetailsTab
94
- hostName="test-host.example.com"
95
- router={mockRouter}
96
- />
97
- </Provider>
98
- );
99
-
100
- unmount();
101
-
102
- // When there's no hash, should only pass search: null
103
- expect(mockRouter.replace).toHaveBeenCalledWith({
104
- search: null,
105
- });
106
- });
107
-
108
- it('should handle router.location being undefined gracefully', () => {
109
- const routerWithoutLocation = {
110
- push: jest.fn(),
111
- replace: jest.fn(),
112
- location: undefined,
113
- };
114
-
115
- const { unmount } = render(
116
- <Provider store={store}>
117
- <NewHostDetailsTab
118
- hostName="test-host.example.com"
119
- router={routerWithoutLocation}
120
- />
121
- </Provider>
122
- );
123
-
124
- unmount();
125
-
126
- // Should still call replace with search: null even if location is undefined
127
- expect(routerWithoutLocation.replace).toHaveBeenCalledWith({
128
- search: null,
129
- });
130
- });
131
-
132
- it('should use the latest hash value at unmount time, not a stale captured value', () => {
133
- const { unmount } = render(
134
- <Provider store={store}>
135
- <NewHostDetailsTab
136
- hostName="test-host.example.com"
137
- router={mockRouter}
138
- />
139
- </Provider>
140
- );
141
-
142
- // Change the hash after mount, before unmount
143
- mockRouter.location.hash = '#/Overview';
144
-
145
- unmount();
146
-
147
- // Verify router.replace was called with the UPDATED hash, not the initial '#/Insights'
148
- expect(mockRouter.replace).toHaveBeenCalledWith({
149
- search: null,
150
- hash: '#/Overview',
151
- });
152
- });
153
- });
154
- });