foreman_rh_cloud 12.1.4 → 12.1.5

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +1 -2
  3. data/app/controllers/insights_cloud/ui_requests_controller.rb +99 -0
  4. data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +7 -13
  5. data/app/services/foreman_rh_cloud/gateway_request.rb +26 -0
  6. data/app/services/foreman_rh_cloud/insights_api_forwarder.rb +116 -0
  7. data/app/services/foreman_rh_cloud/tags_auth.rb +55 -0
  8. data/config/routes.rb +2 -0
  9. data/lib/foreman_rh_cloud/engine.rb +2 -1
  10. data/lib/foreman_rh_cloud/version.rb +1 -1
  11. data/lib/insights_cloud.rb +8 -0
  12. data/package.json +5 -1
  13. data/test/controllers/insights_cloud/ui_requests_controller_test.rb +169 -0
  14. data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +3 -3
  15. data/test/unit/services/foreman_rh_cloud/insights_api_forwarder_test.rb +176 -0
  16. data/test/unit/services/foreman_rh_cloud/tags_auth_test.rb +29 -0
  17. data/webpack/CVEsHostDetailsTab/CVEsHostDetailsTab.js +30 -10
  18. data/webpack/CVEsHostDetailsTab/__tests__/CVEsHostDetailsTab.test.js +18 -11
  19. data/webpack/CVEsHostDetailsTab/index.js +2 -2
  20. data/webpack/ForemanColumnExtensions/index.js +16 -6
  21. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilter.js +1 -0
  22. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilter.test.js.snap +1 -0
  23. data/webpack/ForemanInventoryUpload/Components/InventorySettings/MinimalInventoryDropdown.js +2 -0
  24. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageTitle.js +8 -1
  25. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageTitle.test.js.snap +4 -0
  26. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/CloudConnectorButton.js +3 -3
  27. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/__snapshots__/CloudConnectorButton.test.js.snap +3 -0
  28. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.js +10 -4
  29. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +6 -6
  30. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/SettingsWarning.js +2 -0
  31. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/__snapshots__/SettingsWarning.test.js.snap +2 -0
  32. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButton.js +1 -0
  33. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButton.test.js.snap +1 -0
  34. data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/InventoryAutoUpload.js +3 -1
  35. data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/__tests__/__snapshots__/InventoryAutoUpload.test.js.snap +3 -0
  36. data/webpack/ForemanRhCloudFills.js +6 -3
  37. data/webpack/ForemanRhCloudPages.js +6 -3
  38. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +1 -0
  39. data/webpack/InsightsCloudSync/Components/InsightsTable/SelectAllAlert.js +2 -0
  40. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +1 -0
  41. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +3 -0
  42. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModalFooter.js +12 -2
  43. data/webpack/InsightsCloudSync/Components/RemediationModal/Resolutions.js +1 -0
  44. data/webpack/InsightsCloudSync/Components/ToolbarDropdown.js +6 -1
  45. data/webpack/InsightsVulnerability/InsightsVulnerabilityListPage.js +21 -0
  46. data/webpack/InsightsVulnerability/InsightsVulnerabilityListPage.test.js +20 -0
  47. data/webpack/InsightsVulnerabilityHostIndexExtensions/CVECountCell.js +45 -0
  48. data/webpack/InsightsVulnerabilityHostIndexExtensions/__tests__/CVECountCell.test.js +28 -0
  49. data/webpack/common/DropdownToggle.js +1 -0
  50. data/webpack/common/ScalprumModule/ScalprumContext.js +63 -0
  51. data/webpack/common/Switcher/SwitcherPF4.js +1 -0
  52. data/webpack/common/Switcher/__tests__/__snapshots__/SwitcherPF4.test.js.snap +1 -0
  53. data/webpack/common/Switcher/index.js +1 -0
  54. metadata +17 -4
  55. data/webpack/InsightsVulnerability/InsightsVulnerability.js +0 -13
  56. data/webpack/InsightsVulnerability/InsightsVulnerability.test.js +0 -18
@@ -0,0 +1,176 @@
1
+ require 'test_plugin_helper'
2
+ require 'puma/null_io'
3
+
4
+ class UIRequestForwarderTest < ActiveSupport::TestCase
5
+ include MockCerts
6
+
7
+ setup do
8
+ @forwarder = ::ForemanRhCloud::InsightsApiForwarder.new
9
+ @user = FactoryBot.build(:user)
10
+ @organization = FactoryBot.build(:organization)
11
+ @location = FactoryBot.build(:location)
12
+
13
+ setup_certs_expectation do
14
+ @forwarder.stubs(:foreman_certificates)
15
+ end
16
+
17
+ ForemanRhCloud.stubs(:cert_base_url).returns('https://cert.cloud.example.com')
18
+ end
19
+
20
+ test 'should scope GET requests with proper tags' do
21
+ user_agent = { :foo => :bar }
22
+ params = {}
23
+
24
+ req = ActionDispatch::Request.new(
25
+ 'REQUEST_URI' => '/api/vulnerability/v1/cves/abc-123/affected_systems',
26
+ 'REQUEST_METHOD' => 'GET',
27
+ 'HTTP_USER_AGENT' => user_agent,
28
+ 'rack.input' => ::Puma::NullIO.new,
29
+ 'action_dispatch.request.query_parameters' => params
30
+ )
31
+
32
+ ::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag)
33
+ @forwarder.expects(:execute_cloud_request).with do |actual_params|
34
+ actual = actual_params[:headers][:params]
35
+ assert_equal "U:\"#{@user.login}\"O:\"#{@organization.name}\"L:\"#{@location.name}\"", tag_value(actual.find { |param| param[0] == :tag && tag_name(param[1]) =~ /#{ForemanRhCloud::TagsAuth::TAG_NAME}/ }[1])
36
+ true
37
+ end
38
+
39
+ @forwarder.forward_request(req, '/api/vulnerability/v1/cves/abc-123/affected_systems', 'test_controller', @user, @organization, @location)
40
+
41
+ # This test asserts the parameters that are sent to the execute_cloud_request method.
42
+ # This is done by setting the expectation before the actual call.
43
+ end
44
+
45
+ test 'should not scope GET requests for unknown uris' do
46
+ user_agent = { :foo => :bar }
47
+ params = {}
48
+
49
+ req = ActionDispatch::Request.new(
50
+ 'REQUEST_URI' => '/api/vulnerability/foo/bar',
51
+ 'REQUEST_METHOD' => 'GET',
52
+ 'HTTP_USER_AGENT' => user_agent,
53
+ 'rack.input' => ::Puma::NullIO.new,
54
+ 'action_dispatch.request.query_parameters' => params
55
+ )
56
+
57
+ ::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag).never
58
+ @forwarder.expects(:execute_cloud_request).with do |actual_params|
59
+ actual = actual_params[:headers][:params]
60
+ assert_equal 0, actual.count
61
+ true
62
+ end
63
+
64
+ @forwarder.forward_request(req, '/api/vulnerability/foo/bar', 'test_controller', @user, @organization, @location)
65
+
66
+ # This test asserts the parameters that are sent to the execute_cloud_request method.
67
+ # This is done by setting the expectation before the actual call.
68
+ end
69
+
70
+ test 'should merge URI params in GET requests' do
71
+ user_agent = { :foo => :bar }
72
+ params = { :page => 5, :per_page => 42 }
73
+
74
+ req = ActionDispatch::Request.new(
75
+ 'REQUEST_URI' => '/api/vulnerability/v1/cves/abc-123/affected_systems',
76
+ 'REQUEST_METHOD' => 'GET',
77
+ 'HTTP_USER_AGENT' => user_agent,
78
+ 'rack.input' => ::Puma::NullIO.new,
79
+ 'action_dispatch.request.query_parameters' => params
80
+ )
81
+
82
+ ::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag)
83
+ @forwarder.expects(:execute_cloud_request).with do |actual_params|
84
+ actual = actual_params[:headers][:params]
85
+ assert_equal "U:\"#{@user.login}\"O:\"#{@organization.name}\"L:\"#{@location.name}\"", tag_value(actual.find { |param| param[0] == :tag && tag_name(param[1]) =~ /#{ForemanRhCloud::TagsAuth::TAG_NAME}/ }[1])
86
+ assert_equal 5, actual.find { |param| param[0] == :page }[1]
87
+ assert_equal 42, actual.find { |param| param[0] == :per_page }[1]
88
+ true
89
+ end
90
+
91
+ @forwarder.forward_request(req, '/api/vulnerability/v1/cves/abc-123/affected_systems', 'test_controller', @user, @organization, @location)
92
+ # This test asserts the parameters that are sent to the execute_cloud_request method.
93
+ # This is done by setting the expectation before the actual call.
94
+ end
95
+
96
+ test 'should not scope POST requests' do
97
+ post_data = 'Random POST data'
98
+ req = ActionDispatch::Request.new(
99
+ 'REQUEST_URI' => '/foo/bar',
100
+ 'REQUEST_METHOD' => 'POST',
101
+ 'rack.input' => ::Puma::NullIO.new,
102
+ 'RAW_POST_DATA' => post_data
103
+ )
104
+
105
+ ::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag).never
106
+ @forwarder.expects(:execute_cloud_request).with do |actual_params|
107
+ actual = actual_params[:headers][:params]
108
+ assert_equal 0, actual.count
109
+ true
110
+ end
111
+
112
+ @forwarder.forward_request(req, '/api/vulnerability/v1/cves', 'test_controller', @user, @organization, @location)
113
+
114
+ # This test asserts the parameters that are sent to the execute_cloud_request method.
115
+ # This is done by setting the expectation before the actual call.
116
+ end
117
+
118
+ test 'should not scope PUT requests' do
119
+ put_data = 'Random PUT data'
120
+ req = ActionDispatch::Request.new(
121
+ 'REQUEST_URI' => '/foo/bar',
122
+ 'REQUEST_METHOD' => 'PUT',
123
+ 'rack.input' => ::Puma::NullIO.new,
124
+ 'RAW_POST_DATA' => put_data
125
+ )
126
+
127
+ ::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag).never
128
+ @forwarder.expects(:execute_cloud_request).with do |actual_params|
129
+ actual = actual_params[:headers][:params]
130
+ assert_equal 0, actual.count
131
+ true
132
+ end
133
+
134
+ @forwarder.forward_request(req, '/api/vulnerability/v1/cves', 'test_controller', @user, @organization, @location)
135
+
136
+ # This test asserts the parameters that are sent to the execute_cloud_request method.
137
+ # This is done by setting the expectation before the actual call.
138
+ end
139
+
140
+ test 'should not scope PATCH requests' do
141
+ post_data = 'Random PATCH data'
142
+ req = ActionDispatch::Request.new(
143
+ 'REQUEST_URI' => '/foo/bar',
144
+ 'REQUEST_METHOD' => 'PATCH',
145
+ 'rack.input' => ::Puma::NullIO.new,
146
+ 'RAW_POST_DATA' => post_data,
147
+ "action_dispatch.request.path_parameters" => { :format => "json" }
148
+ )
149
+
150
+ ::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag).never
151
+ @forwarder.expects(:execute_cloud_request).with do |actual_params|
152
+ actual = actual_params[:headers][:params]
153
+ assert_equal 0, actual.count
154
+ true
155
+ end
156
+
157
+ @forwarder.forward_request(req, '/api/vulnerability/v1/cves', 'test_controller', @user, @organization, @location)
158
+
159
+ # This test asserts the parameters that are sent to the execute_cloud_request method.
160
+ # This is done by setting the expectation before the actual call.
161
+ end
162
+
163
+ def tag_value(param_value)
164
+ return param_value unless param_value.is_a?(String)
165
+
166
+ tag_string = CGI.unescape(param_value)
167
+ tag_string.split('=')[1]
168
+ end
169
+
170
+ def tag_name(param_value)
171
+ return param_value unless param_value.is_a?(String)
172
+
173
+ tag_string = CGI.unescape(param_value)
174
+ tag_string.split('=')[0]
175
+ end
176
+ end
@@ -0,0 +1,29 @@
1
+ require 'test_plugin_helper'
2
+ require 'json'
3
+
4
+ class TagsAuthTest < ActiveSupport::TestCase
5
+ setup do
6
+ @user = FactoryBot.build(:user)
7
+ @logger = Logger.new(IO::NULL)
8
+ @org = FactoryBot.build(:organization)
9
+ @loc = FactoryBot.build(:location)
10
+ @auth = ::ForemanRhCloud::TagsAuth.new(@user, @org, @loc, @logger)
11
+ end
12
+
13
+ test 'Generates tags update request' do
14
+ uuid1 = 'test_uuid1'
15
+ uuid2 = 'test_uuid2'
16
+
17
+ @auth.expects(:allowed_hosts).returns([uuid1, uuid2])
18
+ @auth.expects(:execute_cloud_request).with do |actual_params|
19
+ actual = JSON.parse(actual_params[:payload])
20
+ assert_includes actual['host_id_list'], uuid1
21
+ assert_includes actual['host_id_list'], uuid2
22
+ assert_equal ForemanRhCloud::TagsAuth::TAG_SHORT_NAME, actual['tags'].first['key']
23
+ assert_equal ForemanRhCloud::TagsAuth::TAG_NAMESPACE, actual['tags'].first['namespace']
24
+ assert_equal "U:\"#{@user.login}\"O:\"#{@org.name}\"L:\"#{@loc.name}\"", actual['tags'].first['value']
25
+ end
26
+
27
+ @auth.update_tag
28
+ end
29
+ end
@@ -1,17 +1,37 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { translate as __ } from 'foremanReact/common/I18n';
3
+ import { ScalprumComponent, ScalprumProvider } from '@scalprum/react-core';
4
+ import { providerOptions } from '../common/ScalprumModule/ScalprumContext';
4
5
 
5
- const CVEsHostDetailsTab = ({ hostName }) => (
6
- <div>
7
- <h1>
8
- {__('CVEs tab for host:')} {hostName}
9
- </h1>
10
- </div>
11
- );
6
+ const CVEsHostDetailsTab = ({ systemId }) => {
7
+ const scope = 'vulnerability';
8
+ const module = './SystemDetailTable';
9
+ return (
10
+ <div className="rh-cloud-insights-vulnerability-host-details-component">
11
+ <ScalprumComponent scope={scope} module={module} systemId={systemId} />
12
+ </div>
13
+ );
14
+ };
12
15
 
13
16
  CVEsHostDetailsTab.propTypes = {
14
- hostName: PropTypes.string.isRequired,
17
+ systemId: PropTypes.string.isRequired,
18
+ };
19
+
20
+ const CVEsHostDetailsTabWrapper = ({ response }) => (
21
+ <ScalprumProvider {...providerOptions}>
22
+ <CVEsHostDetailsTab
23
+ // eslint-disable-next-line camelcase
24
+ systemId={response?.subscription_facet_attributes?.uuid}
25
+ />
26
+ </ScalprumProvider>
27
+ );
28
+
29
+ CVEsHostDetailsTabWrapper.propTypes = {
30
+ response: PropTypes.shape({
31
+ subscription_facet_attributes: PropTypes.shape({
32
+ uuid: PropTypes.string.isRequired,
33
+ }),
34
+ }).isRequired,
15
35
  };
16
36
 
17
- export default CVEsHostDetailsTab;
37
+ export default CVEsHostDetailsTabWrapper;
@@ -1,18 +1,25 @@
1
1
  import React from 'react';
2
- import { render, screen } from '@testing-library/react';
3
- import CVEsHostDetailsTab from '../CVEsHostDetailsTab';
2
+ import { render } from '@testing-library/react';
3
+ import CVEsHostDetailsTabWrapper from '../CVEsHostDetailsTab';
4
4
 
5
- describe('CVEsHostDetailsTab', () => {
5
+ jest.mock('@scalprum/react-core', () => ({
6
+ ScalprumComponent: jest.fn(props => (
7
+ <div data-testid="mock-scalprum-component">{JSON.stringify(props)}</div>
8
+ )),
9
+ ScalprumProvider: jest.fn(({ children }) => <div>{children}</div>),
10
+ }));
11
+
12
+ describe('CVEsHostDetailsTabWrapper', () => {
6
13
  it('renders without crashing', () => {
7
- render(<CVEsHostDetailsTab hostName="test-host.example.com" />);
14
+ const { container } = render(
15
+ <CVEsHostDetailsTabWrapper
16
+ response={{ subscription_facet_attributes: { uuid: '1-2-3' } }}
17
+ />
18
+ );
8
19
  expect(
9
- screen.getByText('CVEs tab for host: test-host.example.com')
20
+ container.querySelector(
21
+ '.rh-cloud-insights-vulnerability-host-details-component'
22
+ )
10
23
  ).toBeTruthy();
11
24
  });
12
-
13
- it('renders the host name', () => {
14
- const hostName = 'test-host.example.com';
15
- render(<CVEsHostDetailsTab hostName={hostName} />);
16
- expect(screen.getByText(`CVEs tab for host: ${hostName}`)).toBeTruthy();
17
- });
18
25
  });
@@ -1,3 +1,3 @@
1
- import CVEsHostDetailsTab from './CVEsHostDetailsTab';
1
+ import CVEsHostDetailsTabWrapper from './CVEsHostDetailsTab';
2
2
 
3
- export default CVEsHostDetailsTab;
3
+ export default CVEsHostDetailsTabWrapper;
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { translate as __ } from 'foremanReact/common/I18n';
3
3
  import { propsToCamelCase } from 'foremanReact/common/helpers';
4
+ import { CVECountCell } from '../InsightsVulnerabilityHostIndexExtensions/CVECountCell';
4
5
 
5
6
  const RecommendationsCell = hostDetails => {
6
7
  const insightsAttributes = propsToCamelCase(
@@ -22,6 +23,8 @@ const RecommendationsCell = hostDetails => {
22
23
  return <a href={hitsUrl}>{hitsCount}</a>;
23
24
  };
24
25
 
26
+ const insightsCategoryName = __('Insights');
27
+
25
28
  const hostsIndexColumnExtensions = [
26
29
  {
27
30
  columnName: 'insights_recommendations_count',
@@ -29,13 +32,20 @@ const hostsIndexColumnExtensions = [
29
32
  wrapper: RecommendationsCell,
30
33
  weight: 1500,
31
34
  isSorted: true,
35
+ tableName: 'hosts',
36
+ categoryName: insightsCategoryName,
37
+ categoryKey: 'insights',
38
+ },
39
+ {
40
+ columnName: 'cves_count',
41
+ title: __('Total CVEs'),
42
+ wrapper: hostDetails => <CVECountCell hostDetails={hostDetails} />,
43
+ weight: 2600,
44
+ tableName: 'hosts',
45
+ categoryName: insightsCategoryName,
46
+ categoryKey: 'insights',
47
+ isSorted: false,
32
48
  },
33
49
  ];
34
50
 
35
- hostsIndexColumnExtensions.forEach(column => {
36
- column.tableName = 'hosts';
37
- column.categoryName = 'Insights';
38
- column.categoryKey = 'insights';
39
- });
40
-
41
51
  export default hostsIndexColumnExtensions;
@@ -26,6 +26,7 @@ const InventoryFilter = ({
26
26
  <FormGroup>
27
27
  <TextInput
28
28
  id="inventory_filter_input"
29
+ ouiaId="inventory_filter_input"
29
30
  value={filterTerm}
30
31
  type="text"
31
32
  placeholder={__('Filter..')}
@@ -8,6 +8,7 @@ exports[`InventoryFilter rendering render with props 1`] = `
8
8
  <TextInput
9
9
  id="inventory_filter_input"
10
10
  onChange={[Function]}
11
+ ouiaId="inventory_filter_input"
11
12
  placeholder="Filter.."
12
13
  type="text"
13
14
  value="test_filter_term"
@@ -68,6 +68,7 @@ const MinimalInventoryDropdown = ({ setChosenValue }) => {
68
68
  };
69
69
  return (
70
70
  <Dropdown
71
+ ouiaId="inventory-dropdown"
71
72
  isOpen={isOpen}
72
73
  onSelect={onSelect}
73
74
  onOpenChange={val => setIsOpen(val)}
@@ -90,6 +91,7 @@ const MinimalInventoryDropdown = ({ setChosenValue }) => {
90
91
  value={value}
91
92
  key={value}
92
93
  description={item.description}
94
+ ouiaId={`inventory-dropdownItem-${value}`}
93
95
  >
94
96
  {item.title}
95
97
  </DropdownItem>
@@ -26,6 +26,7 @@ const PageTitle = () => {
26
26
  const dropdownItems = [
27
27
  <DropdownItem
28
28
  key="tasks-history-button"
29
+ ouiaId="tasks-history-button"
29
30
  href={getActionsHistoryUrl()}
30
31
  target="_blank"
31
32
  rel="noopener noreferrer"
@@ -34,13 +35,18 @@ const PageTitle = () => {
34
35
  </DropdownItem>,
35
36
  <DropdownItem
36
37
  key="inventory-documentation-button"
38
+ ouiaId="inventory-documentation-button"
37
39
  href={getInventoryDocsUrl()}
38
40
  target="_blank"
39
41
  rel="noopener noreferrer"
40
42
  >
41
43
  {DOCS_BUTTON_TEXT}
42
44
  </DropdownItem>,
43
- <DropdownItem key="cloud-ping" onClick={togglePingModal}>
45
+ <DropdownItem
46
+ key="cloud-ping"
47
+ ouiaId="dropdownItem-cloud-ping"
48
+ onClick={togglePingModal}
49
+ >
44
50
  {CLOUD_PING_TITLE}
45
51
  </DropdownItem>,
46
52
  ];
@@ -55,6 +61,7 @@ const PageTitle = () => {
55
61
  <GridItem span={6}>
56
62
  <Dropdown
57
63
  className="title-dropdown"
64
+ ouiaId="title-dropdown"
58
65
  onSelect={() => setIsDropdownOpen(false)}
59
66
  toggle={
60
67
  <KebabToggle
@@ -25,6 +25,7 @@ exports[`PageTitle rendering render without Props 1`] = `
25
25
  Array [
26
26
  <DropdownItem
27
27
  href="/foreman_tasks/tasks?search=label+%3D+ForemanInventoryUpload%3A%3AAsync%3A%3AGenerateReportJob+or+label+%3D+ForemanInventoryUpload%3A%3AAsync%3A%3AGenerateAllReportsJob&page=1"
28
+ ouiaId="tasks-history-button"
28
29
  rel="noopener noreferrer"
29
30
  target="_blank"
30
31
  >
@@ -32,6 +33,7 @@ exports[`PageTitle rendering render without Props 1`] = `
32
33
  </DropdownItem>,
33
34
  <DropdownItem
34
35
  href="/links/manual/?root_url=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fen-us%2Fred_hat_insights%2F2023%2Fhtml%2Fred_hat_insights_remediations_guide%2Fhost-communication-with-insights_red-hat-insights-remediation-guide%23uploading-satellite-host-inventory-to-insights_configuring-satellite-cloud-connector"
36
+ ouiaId="inventory-documentation-button"
35
37
  rel="noopener noreferrer"
36
38
  target="_blank"
37
39
  >
@@ -39,6 +41,7 @@ exports[`PageTitle rendering render without Props 1`] = `
39
41
  </DropdownItem>,
40
42
  <DropdownItem
41
43
  onClick={[Function]}
44
+ ouiaId="dropdownItem-cloud-ping"
42
45
  >
43
46
  Connectivity test
44
47
  </DropdownItem>,
@@ -47,6 +50,7 @@ exports[`PageTitle rendering render without Props 1`] = `
47
50
  isOpen={false}
48
51
  isPlain={true}
49
52
  onSelect={[Function]}
53
+ ouiaId="title-dropdown"
50
54
  position="right"
51
55
  toggle={
52
56
  <KebabToggle
@@ -26,7 +26,7 @@ export const CloudConnectorButton = ({ status, onClick, jobLink }) => {
26
26
  className="cloud-connector-pending-button"
27
27
  onMouseEnter={() => setIsPopoverVisible(true)}
28
28
  >
29
- <Button variant="secondary" isDisabled>
29
+ <Button variant="secondary" ouiaId="button-in-progress" isDisabled>
30
30
  <Spinner size="sm" /> {__('Cloud Connector is in progress')}
31
31
  </Button>
32
32
  </div>
@@ -36,14 +36,14 @@ export const CloudConnectorButton = ({ status, onClick, jobLink }) => {
36
36
 
37
37
  if (status === CONNECTOR_STATUS.RESOLVED) {
38
38
  return (
39
- <Button variant="secondary" onClick={onClick}>
39
+ <Button variant="secondary" ouiaId="button-reconfigure" onClick={onClick}>
40
40
  {__('Reconfigure cloud connector')}
41
41
  </Button>
42
42
  );
43
43
  }
44
44
 
45
45
  return (
46
- <Button variant="secondary" onClick={onClick}>
46
+ <Button variant="secondary" ouiaId="button-configure" onClick={onClick}>
47
47
  {__('Configure cloud connector')}
48
48
  </Button>
49
49
  );
@@ -3,6 +3,7 @@
3
3
  exports[`CloudConnectorButton render no cloud connector 1`] = `
4
4
  <Button
5
5
  onClick={[MockFunction]}
6
+ ouiaId="button-configure"
6
7
  variant="secondary"
7
8
  >
8
9
  Configure cloud connector
@@ -34,6 +35,7 @@ exports[`CloudConnectorButton render pending connector 1`] = `
34
35
  >
35
36
  <Button
36
37
  isDisabled={true}
38
+ ouiaId="button-in-progress"
37
39
  variant="secondary"
38
40
  >
39
41
  <Spinner
@@ -49,6 +51,7 @@ exports[`CloudConnectorButton render pending connector 1`] = `
49
51
  exports[`CloudConnectorButton render resolved cloud connector 1`] = `
50
52
  <Button
51
53
  onClick={[MockFunction]}
54
+ ouiaId="button-reconfigure"
52
55
  variant="secondary"
53
56
  >
54
57
  Reconfigure cloud connector
@@ -79,26 +79,32 @@ const CloudPingModal = ({ title, isOpen, toggle }) => {
79
79
  <>
80
80
  <Modal
81
81
  id="cloud-ping-modal"
82
+ ouiaId="cloud-ping-modal"
82
83
  appendTo={document.getElementsByClassName('react-container')[0]}
83
84
  variant={ModalVariant.large}
84
85
  title={title}
85
86
  isOpen={isOpen}
86
87
  onClose={toggle}
87
88
  >
88
- <Card className="certs-status">
89
+ <Card className="certs-status" ouiaId="card-org-status">
89
90
  <CardTitle>{__('Organization status')}</CardTitle>
90
91
  <CardBody>
91
- <Text>
92
+ <Text ouiaId="text-description">
92
93
  {__('Displays manifest statuses per accessible organizations.')}
93
94
  </Text>
94
95
  {isPending ? (
95
96
  <Spinner size="xl" />
96
97
  ) : (
97
98
  <>
98
- <Text className="pull-right">
99
+ <Text className="pull-right" ouiaId="text-org-count">
99
100
  {sprintf(__('%s organizations'), rows.length)}
100
101
  </Text>
101
- <Table aria-label="Simple Table" cells={['']} rows={rows}>
102
+ <Table
103
+ aria-label="Simple Table"
104
+ ouiaId="simple-table"
105
+ cells={['']}
106
+ rows={rows}
107
+ >
102
108
  <TableHeader />
103
109
  <TableBody />
104
110
  </Table>{' '}
@@ -13,18 +13,18 @@ export const PageDescription = () => {
13
13
 
14
14
  return (
15
15
  <div id="inventory_page_description">
16
- <Text>
16
+ <Text ouiaId="text-cloud-console">
17
17
  {__(
18
18
  'The Red Hat Hybrid Cloud Console provides a set of cloud services, including Red Hat Insights and Subscriptions, that provide predictive analysis, remediation of issues, and unified subscription reporting for this Foreman instance.'
19
19
  )}
20
20
  </Text>
21
- <Text>
21
+ <Text ouiaId="text-inventory-upload">
22
22
  {__(
23
23
  'The Foreman inventory upload plugin automatically uploads Foreman host inventory data to the Inventory service of Insights, where it can also be used by the Subscriptions service for subscription reporting. If you use the Subscriptions service, enabling inventory uploads is required.'
24
24
  )}
25
25
  </Text>
26
26
  {subscriptionConnectionEnabled && (
27
- <Text>
27
+ <Text ouiaId="text-enable-report">
28
28
  <FormattedMessage
29
29
  id="enable-upload-hint"
30
30
  defaultMessage={__(
@@ -39,7 +39,7 @@ export const PageDescription = () => {
39
39
  </Text>
40
40
  )}
41
41
  {subscriptionConnectionEnabled && (
42
- <Text>
42
+ <Text ouiaId="text-restart-button">
43
43
  <FormattedMessage
44
44
  id="restart-button-hint"
45
45
  defaultMessage={__(
@@ -53,7 +53,7 @@ export const PageDescription = () => {
53
53
  />
54
54
  </Text>
55
55
  )}
56
- <Text>
56
+ <Text ouiaId="text-more-info-subscription">
57
57
  {__('For more information about the Subscriptions service, see:')}
58
58
  &nbsp;
59
59
  <a
@@ -64,7 +64,7 @@ export const PageDescription = () => {
64
64
  {__('About subscription watch')}
65
65
  </a>
66
66
  </Text>
67
- <Text>
67
+ <Text ouiaId="text-more-info-insights">
68
68
  {__('For more information about Insights and Cloud Connector, see:')}
69
69
  &nbsp;
70
70
  <a
@@ -22,6 +22,7 @@ export const SettingsWarning = ({
22
22
  alerts.push(
23
23
  <Alert
24
24
  key="auto-upload"
25
+ ouiaId="auto-upload"
25
26
  variant="warning"
26
27
  title={__(
27
28
  "Cloud Connector has been configured however the inventory auto-upload is disabled, it's recommended to enable it"
@@ -36,6 +37,7 @@ export const SettingsWarning = ({
36
37
  alerts.push(
37
38
  <Alert
38
39
  key="obfuscating-host"
40
+ ouiaId="obfuscating-host"
39
41
  variant="warning"
40
42
  title={__(
41
43
  "Cloud Connector has been configured however obfuscating host names setting is enabled, it's recommended to disable it"
@@ -11,6 +11,7 @@ exports[`SettingsWarning with 2 alerts 1`] = `
11
11
  />
12
12
  }
13
13
  key="auto-upload"
14
+ ouiaId="auto-upload"
14
15
  title="Cloud Connector has been configured however the inventory auto-upload is disabled, it's recommended to enable it"
15
16
  variant="warning"
16
17
  />
@@ -21,6 +22,7 @@ exports[`SettingsWarning with 2 alerts 1`] = `
21
22
  />
22
23
  }
23
24
  key="obfuscating-host"
25
+ ouiaId="obfuscating-host"
24
26
  title="Cloud Connector has been configured however obfuscating host names setting is enabled, it's recommended to disable it"
25
27
  variant="warning"
26
28
  />
@@ -21,6 +21,7 @@ class SyncButton extends React.Component {
21
21
  <React.Fragment>
22
22
  <Button
23
23
  className="sync_button"
24
+ ouiaId="sync-button"
24
25
  onClick={handleClick}
25
26
  isDisabled={status === STATUS.PENDING}
26
27
  variant="secondary"
@@ -6,6 +6,7 @@ exports[`SyncButton rendering render with Props 1`] = `
6
6
  className="sync_button"
7
7
  isDisabled={false}
8
8
  onClick={[Function]}
9
+ ouiaId="sync-button"
9
10
  variant="secondary"
10
11
  >
11
12
  Sync all inventory status
@@ -48,6 +48,7 @@ const InventoryAutoUploadSwitcher = ({
48
48
  position="right"
49
49
  >
50
50
  <Button
51
+ ouiaId="button-advanced-settings"
51
52
  variant="secondary"
52
53
  style={{ fontSize: 'small', marginTop: '-4px' }}
53
54
  >
@@ -59,9 +60,10 @@ const InventoryAutoUploadSwitcher = ({
59
60
  <br />
60
61
  <Grid.Row>
61
62
  <Grid.Col sm={12}>
62
- <Text component={TextVariants.p}>
63
+ <Text component={TextVariants.p} ouiaId="text-more-details">
63
64
  <InfoAltIcon /> {__('More details can be found in')}{' '}
64
65
  <Text
66
+ ouiaId="text-details-link"
65
67
  component={TextVariants.a}
66
68
  href={foremanUrl('/foreman_rh_cloud/inventory_upload')}
67
69
  target="_blank"