katello 4.9.0.rc2 → 4.9.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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/capsule_content_controller.rb +1 -1
  3. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +1 -4
  4. data/app/controllers/katello/api/v2/content_views_controller.rb +2 -1
  5. data/app/controllers/katello/api/v2/organizations_controller.rb +7 -4
  6. data/app/controllers/katello/api/v2/repositories_controller.rb +4 -4
  7. data/app/lib/actions/katello/content_view/promote_to_environment.rb +1 -1
  8. data/app/lib/actions/katello/content_view_version/auto_create_redhat_repositories.rb +2 -1
  9. data/app/lib/actions/katello/content_view_version/republish_repositories.rb +1 -1
  10. data/app/lib/actions/katello/orphan_cleanup/remove_orphaned_content_units.rb +22 -0
  11. data/app/lib/actions/katello/orphan_cleanup/remove_orphans.rb +4 -15
  12. data/app/lib/actions/katello/repository/clone_to_version.rb +1 -1
  13. data/app/lib/actions/katello/repository/multi_clone_to_version.rb +1 -1
  14. data/app/lib/actions/katello/repository_set/enable_repository.rb +3 -1
  15. data/app/lib/katello/resources/cdn/katello_cdn.rb +8 -4
  16. data/app/models/katello/concerns/pulp_database_unit.rb +2 -2
  17. data/app/models/katello/content_view.rb +7 -0
  18. data/app/models/katello/repository.rb +0 -1
  19. data/app/models/katello/root_repository.rb +1 -1
  20. data/app/services/katello/pulp3/content_view_version/importable_repositories.rb +10 -6
  21. data/app/services/katello/pulp3/repository/docker.rb +1 -1
  22. data/app/services/katello/pulp3/repository.rb +4 -2
  23. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +12 -11
  24. data/app/views/katello/api/v2/content_facet/base.json.rabl +9 -10
  25. data/app/views/katello/hosts/_errata_counts.html.erb +13 -0
  26. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository.factory.js +1 -1
  27. data/lib/katello/plugin.rb +1 -1
  28. data/lib/katello/tasks/upgrades/4.9/update_custom_products_enablement.rake +4 -2
  29. data/lib/katello/version.rb +1 -1
  30. data/webpack/components/RoutedTabs/index.js +1 -0
  31. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard.js +2 -2
  32. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/index.js +1 -0
  33. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +1 -1
  34. data/webpack/components/extensions/RegistrationCommands/__tests__/__snapshots__/ActivationKeys.test.js.snap +3 -3
  35. data/webpack/components/extensions/RegistrationCommands/fields/ActivationKeys.js +3 -3
  36. data/webpack/redux/actions/RedHatRepositories/helpers.js +3 -5
  37. data/webpack/scenes/Content/Details/ContentRepositories.js +1 -1
  38. data/webpack/scenes/Content/Table/ContentTable.js +1 -1
  39. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +1 -14
  40. data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +0 -4
  41. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentEnvironments.js +1 -1
  42. data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +1 -1
  43. data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +41 -32
  44. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +32 -26
  45. data/webpack/scenes/ContentViews/Details/Filters/CVContainerImageFilterContent.js +10 -2
  46. data/webpack/scenes/ContentViews/Details/Filters/CVDebFilterContent.js +10 -2
  47. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +10 -2
  48. data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +10 -2
  49. data/webpack/scenes/ContentViews/Details/Filters/CVModuleStreamFilterContent.js +10 -2
  50. data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +10 -2
  51. data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +10 -2
  52. data/webpack/scenes/ContentViews/Details/Histories/ContentViewHistories.js +2 -2
  53. data/webpack/scenes/ContentViews/Details/Repositories/ContentCounts.js +3 -3
  54. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompare.js +1 -0
  55. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js +1 -1
  56. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedHosts.js +1 -1
  57. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetails.js +1 -0
  58. data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersions.test.js +7 -0
  59. data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetail.test.js +28 -4
  60. data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetails.fixtures.json +1 -0
  61. data/webpack/scenes/ContentViews/Publish/CVPublishReview.js +13 -2
  62. data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +4 -1
  63. data/webpack/scenes/ContentViews/Publish/__tests__/publishContentView.test.js +33 -10
  64. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +0 -2
  65. data/webpack/scenes/ContentViews/expansions/RelatedContentViewComponentsModal.js +1 -1
  66. data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceForm.js +7 -2
  67. data/webpack/scenes/Subscriptions/Manifest/DeleteManifestModalText.js +38 -21
  68. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +19 -4
  69. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +1 -0
  70. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +1 -0
  71. metadata +10 -9
@@ -24,7 +24,6 @@ const recommendedRepositoriesRHEL = [
24
24
  'rhel-7-server-optional-rpms',
25
25
  'rhel-7-server-extras-rpms',
26
26
  'rhel-7-server-kickstart',
27
- 'rhel-6-server-els-rpms',
28
27
  ];
29
28
 
30
29
  const recommendedRepositoriesSatTools = [
@@ -35,10 +34,9 @@ const recommendedRepositoriesSatTools = [
35
34
  ];
36
35
 
37
36
  const recommendedRepositoriesMisc = [
38
- 'satellite-capsule-6.13-for-rhel-8-x86_64-rpms',
39
- 'ansible-2-for-rhel-8-x86_64-rpms',
40
- 'satellite-maintenance-6.13-for-rhel-8-x86_64-rpms',
41
- 'satellite-utils-6.13-for-rhel-8-x86_64-rpms',
37
+ 'satellite-capsule-6.14-for-rhel-8-x86_64-rpms',
38
+ 'satellite-maintenance-6.14-for-rhel-8-x86_64-rpms',
39
+ 'satellite-utils-6.14-for-rhel-8-x86_64-rpms',
42
40
  ];
43
41
 
44
42
  const recommendedRepositorySetLables = recommendedRepositoriesRHEL
@@ -59,7 +59,7 @@ const ContentRepositories = ({ contentType, id, tabKey }) => {
59
59
  </Thead>
60
60
  <Tbody>
61
61
  {results?.map((details, idx) => (
62
- <Tr key={`${details.id}`} ouiaId={`content-repositories-row-${idx}`}>
62
+ <Tr key={details.id} ouiaId={`content-repositories-row-${idx}`}>
63
63
  {columnHeaders.map((col, index) =>
64
64
  <Td key={index}>{col.getProperty(details, typeSingularLabel)}</Td>)
65
65
  }
@@ -65,7 +65,7 @@ const ContentTable = ({
65
65
  </Thead>
66
66
  <Tbody>
67
67
  {results?.map(details => (
68
- <Tr key={`${details.id}`} ouiaId={`${details.id}-tr`}>
68
+ <Tr key={details.id} ouiaId={`${details.id}-tr`}>
69
69
  {columnHeaders.map((col, index) =>
70
70
  <Td key={index}>{col.getProperty(details)}</Td>)
71
71
  }
@@ -7,7 +7,7 @@ import { useDispatch, useSelector } from 'react-redux';
7
7
  import { Form, FormGroup, TextInput, TextArea, Checkbox, ActionGroup, Button, Tile, Grid, GridItem } from '@patternfly/react-core';
8
8
  import { createContentView } from '../ContentViewsActions';
9
9
  import { selectCreateContentViews, selectCreateContentViewStatus, selectCreateContentViewError } from './ContentViewCreateSelectors';
10
- import { LabelDependencies, LabelAutoPublish, LabelImportOnly } from './ContentViewFormComponents';
10
+ import { LabelDependencies, LabelAutoPublish } from './ContentViewFormComponents';
11
11
  import ContentViewIcon from '../components/ContentViewIcon';
12
12
  import './CreateContentViewForm.scss';
13
13
 
@@ -19,7 +19,6 @@ const CreateContentViewForm = ({ setModalOpen }) => {
19
19
  const [composite, setComposite] = useState(false);
20
20
  const [component, setComponent] = useState(true);
21
21
  const [autoPublish, setAutoPublish] = useState(false);
22
- const [importOnly, setImportOnly] = useState(false);
23
22
  const [dependencies, setDependencies] = useState(false);
24
23
  const [redirect, setRedirect] = useState(false);
25
24
  const [saving, setSaving] = useState(false);
@@ -59,7 +58,6 @@ const CreateContentViewForm = ({ setModalOpen }) => {
59
58
  composite,
60
59
  solve_dependencies: dependencies,
61
60
  auto_publish: (autoPublish && composite),
62
- import_only: importOnly,
63
61
  }));
64
62
  };
65
63
 
@@ -168,17 +166,6 @@ const CreateContentViewForm = ({ setModalOpen }) => {
168
166
  onChange={checked => setDependencies(checked)}
169
167
  />
170
168
  </FormGroup>}
171
- {!composite &&
172
- <FormGroup isInline fieldId="importOnly">
173
- <Checkbox
174
- id="importOnly"
175
- ouiaId="importOnly"
176
- name="importOnly"
177
- label={LabelImportOnly()}
178
- isChecked={importOnly}
179
- onChange={checked => setImportOnly(checked)}
180
- />
181
- </FormGroup>}
182
169
  {composite &&
183
170
  <FormGroup isInline fieldId="autoPublish">
184
171
  <Checkbox
@@ -24,7 +24,6 @@ const createDetails = {
24
24
  composite: false,
25
25
  solve_dependencies: false,
26
26
  auto_publish: false,
27
- import_only: false,
28
27
  };
29
28
 
30
29
  const createdCVDetails = { ...cvCreateData };
@@ -78,7 +77,6 @@ test('Displays dependent fields correctly', () => {
78
77
  expect(getByText('Content view')).toBeInTheDocument();
79
78
  expect(getByText('Solve dependencies')).toBeInTheDocument();
80
79
  expect(queryByText('Auto publish')).not.toBeInTheDocument();
81
- expect(getByText('Import only')).toBeInTheDocument();
82
80
 
83
81
  // label auto_set
84
82
  fireEvent.change(getByLabelText('input_name'), { target: { value: '123 2123' } });
@@ -88,13 +86,11 @@ test('Displays dependent fields correctly', () => {
88
86
  fireEvent.click(getByLabelText('composite_tile'));
89
87
  expect(queryByText('Solve dependencies')).not.toBeInTheDocument();
90
88
  expect(getByText('Auto publish')).toBeInTheDocument();
91
- expect(queryByText('Import only')).not.toBeInTheDocument();
92
89
 
93
90
  // display Solve Dependencies when Component CV
94
91
  fireEvent.click(getByLabelText('component_tile'));
95
92
  expect(getByText('Solve dependencies')).toBeInTheDocument();
96
93
  expect(queryByText('Auto publish')).not.toBeInTheDocument();
97
- expect(getByText('Import only')).toBeInTheDocument();
98
94
  });
99
95
 
100
96
  test('Validates label field', () => {
@@ -10,7 +10,7 @@ const ComponentEnvironments = ({ environments }) => environments.map((env, index
10
10
  href={`/lifecycle_environments/${env.id}`}
11
11
  isTruncated
12
12
  >
13
- {`${env.name}`}
13
+ {env.name}
14
14
  </Label>
15
15
  ));
16
16
 
@@ -592,7 +592,7 @@ export const republishCVVRepoMetadata = (params, handleSuccess) => put({
592
592
  type: API_OPERATIONS.PUT,
593
593
  key: cvVersionRepublishRepoMetadataKey(params.cvId, params.id),
594
594
  url: api.getApiUrl(`/content_view_versions/${params.id}/republish_repositories`),
595
- params: { ...params, force: true },
595
+ params,
596
596
  handleSuccess: (response) => {
597
597
  if (handleSuccess) return handleSuccess();
598
598
  return renderTaskStartedToast(response.data);
@@ -37,7 +37,7 @@ import { hasPermission } from '../helpers';
37
37
  import CopyContentViewModal from '../Copy/CopyContentViewModal';
38
38
  import ContentViewDeleteWizard from '../Delete/ContentViewDeleteWizard';
39
39
  import EmptyStateMessage from '../../../components/Table/EmptyStateMessage';
40
- import { cvVersionTaskPollingKey } from '../ContentViewsConstants';
40
+ import { CONTENT_VIEW_NEEDS_PUBLISH_RESET, cvVersionTaskPollingKey } from '../ContentViewsConstants';
41
41
  import { clearPollTaskData, stopPollingTask } from '../../Tasks/TaskActions';
42
42
 
43
43
  export default () => {
@@ -73,6 +73,7 @@ export default () => {
73
73
 
74
74
  useEffect(() => {
75
75
  dispatch(getContentViewDetails(cvId));
76
+ dispatch({ type: CONTENT_VIEW_NEEDS_PUBLISH_RESET });
76
77
  }, [cvId, dispatch]);
77
78
 
78
79
 
@@ -105,39 +106,47 @@ export default () => {
105
106
  generated_for: generatedFor, import_only: importOnly,
106
107
  } = details;
107
108
  const generatedContentView = generatedFor !== 'none';
109
+ const detailsTab = {
110
+ key: 'details',
111
+ title: __('Details'),
112
+ content: <ContentViewInfo {...{ cvId, details }} />,
113
+ };
114
+ const versionsTab = {
115
+ key: 'versions',
116
+ title: __('Versions'),
117
+ content: <ContentViewVersionsRoutes {...{ cvId, details }} />,
118
+ };
119
+ const contentViewsTab = {
120
+ key: 'contentviews',
121
+ title: __('Content views'),
122
+ content: <ContentViewComponents {...{ cvId, details }} />,
123
+ };
124
+ const repositoriesTab = {
125
+ key: 'repositories',
126
+ title: __('Repositories'),
127
+ content: <ContentViewRepositories {...{ cvId, details }} />,
128
+ };
129
+ const filtersTab = {
130
+ key: 'filters',
131
+ title: __('Filters'),
132
+ content: <ContentViewFilterRoutes {...{ cvId, details }} />,
133
+ };
134
+ const historyTab = {
135
+ key: 'history',
136
+ title: __('History'),
137
+ content: <ContentViewHistories cvId={cvId} />,
138
+ };
139
+
140
+ /* eslint-disable no-nested-ternary */
108
141
  const tabs = [
109
- {
110
- key: 'details',
111
- title: __('Details'),
112
- content: <ContentViewInfo {...{ cvId, details }} />,
113
- },
114
- {
115
- key: 'versions',
116
- title: __('Versions'),
117
- content: <ContentViewVersionsRoutes {...{ cvId, details }} />,
118
- },
119
- ...composite ? [{
120
- key: 'contentviews',
121
- title: __('Content views'),
122
- content: <ContentViewComponents {...{ cvId, details }} />,
123
- }] : [{
124
- key: 'repositories',
125
- title: __('Repositories'),
126
- content: <ContentViewRepositories {...{ cvId, details }} />,
127
- },
128
- !(importOnly || generatedContentView) &&
129
- {
130
- key: 'filters',
131
- title: __('Filters'),
132
- content: <ContentViewFilterRoutes {...{ cvId, details }} />,
133
- }],
134
- {
135
- key: 'history',
136
- title: __('History'),
137
- content: <ContentViewHistories cvId={cvId} />,
138
- },
142
+ detailsTab,
143
+ versionsTab,
144
+ ...(composite ? [contentViewsTab] :
145
+ ((importOnly || generatedContentView) ?
146
+ [repositoriesTab] : [repositoriesTab, filtersTab])),
147
+ historyTab,
139
148
  ];
140
-
149
+ /* eslint-enable no-nested-ternary */
141
150
 
142
151
  return (
143
152
  <>
@@ -111,32 +111,38 @@ const ContentViewInfo = ({ cvId, details }) => {
111
111
  boolean
112
112
  {...{ currentAttribute, setCurrentAttribute }}
113
113
  />)}
114
- <TextListItem component={TextListItemVariants.dt}>
115
- {LabelImportOnly()}
116
- </TextListItem>
117
- <TextListItem component={TextListItemVariants.dd} className="foreman-spaced-list">
118
- <Switch
119
- id="import_only_switch"
120
- ouiaId="import_only_switch"
121
- aria-label="import_only_switch"
122
- isChecked={importOnly}
123
- className="foreman-spaced-list"
124
- disabled
125
- />
126
- </TextListItem>
127
- <TextListItem component={TextListItemVariants.dt}>
128
- {LabelGenerated()}
129
- </TextListItem>
130
- <TextListItem component={TextListItemVariants.dd} className="foreman-spaced-list">
131
- <Switch
132
- id="generated_by_export_switch"
133
- ouiaId="generated_by_export_switch"
134
- aria-label="generated_by_export_switch"
135
- isChecked={generatedContentView}
136
- className="foreman-spaced-list"
137
- disabled
138
- />
139
- </TextListItem>
114
+ {importOnly &&
115
+ <>
116
+ <TextListItem component={TextListItemVariants.dt}>
117
+ {LabelImportOnly()}
118
+ </TextListItem>
119
+ <TextListItem component={TextListItemVariants.dd} className="foreman-spaced-list">
120
+ <Switch
121
+ id="import_only_switch"
122
+ ouiaId="import_only_switch"
123
+ aria-label="import_only_switch"
124
+ isChecked={importOnly}
125
+ className="foreman-spaced-list"
126
+ disabled
127
+ />
128
+ </TextListItem>
129
+ </>}
130
+ {generatedContentView &&
131
+ <>
132
+ <TextListItem component={TextListItemVariants.dt}>
133
+ {LabelGenerated()}
134
+ </TextListItem>
135
+ <TextListItem component={TextListItemVariants.dd} className="foreman-spaced-list">
136
+ <Switch
137
+ id="generated_by_export_switch"
138
+ ouiaId="generated_by_export_switch"
139
+ aria-label="generated_by_export_switch"
140
+ isChecked={generatedContentView}
141
+ className="foreman-spaced-list"
142
+ disabled
143
+ />
144
+ </TextListItem>
145
+ </>}
140
146
  </TextList>
141
147
  </TextContent>
142
148
  );
@@ -135,7 +135,11 @@ const CVContainerImageFilterContent = ({
135
135
  ouiaId="cv-container-image-filter-tabs"
136
136
  onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
137
137
  >
138
- <Tab eventKey={0} title={<TabTitleText>{__('Tags')}</TabTitleText>}>
138
+ <Tab
139
+ ouiaId="cv-container-image-filter-tags-tab"
140
+ eventKey={0}
141
+ title={<TabTitleText>{__('Tags')}</TabTitleText>}
142
+ >
139
143
  <div className="margin-24-0">
140
144
  <TableWrapper
141
145
  {...{
@@ -200,7 +204,11 @@ const CVContainerImageFilterContent = ({
200
204
  </div>
201
205
  </Tab>
202
206
  {(repositories.length || showAffectedRepos) &&
203
- <Tab eventKey={1} title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}>
207
+ <Tab
208
+ ouiaId="cv-container-image-affected-repos-tab"
209
+ eventKey={1}
210
+ title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}
211
+ >
204
212
  <div className="margin-24-0">
205
213
  <AffectedRepositoryTable cvId={cvId} filterId={filterId} repoType="docker" setShowAffectedRepos={setShowAffectedRepos} details={details} />
206
214
  </div>
@@ -150,7 +150,11 @@ const CVDebFilterContent = ({
150
150
  activeKey={activeTabKey}
151
151
  onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
152
152
  >
153
- <Tab eventKey={0} title={<TabTitleText>{tabTitle}</TabTitleText>}>
153
+ <Tab
154
+ ouiaId="cv-deb-filter-content-table-tab"
155
+ eventKey={0}
156
+ title={<TabTitleText>{tabTitle}</TabTitleText>}
157
+ >
154
158
  <div className="tab-body-with-spacing">
155
159
  <TableWrapper
156
160
  {...{
@@ -225,7 +229,11 @@ const CVDebFilterContent = ({
225
229
  </div>
226
230
  </Tab>
227
231
  {(repositories.length || showAffectedRepos) &&
228
- <Tab eventKey={1} title={<TabTitleText>{__('Affected Repositories')}</TabTitleText>}>
232
+ <Tab
233
+ ouiaId="cv-deb-filter-content-affected-repos-tab"
234
+ eventKey={1}
235
+ title={<TabTitleText>{__('Affected Repositories')}</TabTitleText>}
236
+ >
229
237
  <div className="tab-body-with-spacing">
230
238
  <AffectedRepositoryTable cvId={cvId} filterId={filterId} repoType="deb" setShowAffectedRepos={setShowAffectedRepos} details={details} />
231
239
  </div>
@@ -119,7 +119,11 @@ const CVErrataDateFilterContent = ({
119
119
  activeKey={activeTabKey}
120
120
  onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
121
121
  >
122
- <Tab eventKey={0} title={<TabTitleText>{tabTitle}</TabTitleText>}>
122
+ <Tab
123
+ ouiaId="errata-date-filter-form-tab"
124
+ eventKey={0}
125
+ title={<TabTitleText>{tabTitle}</TabTitleText>}
126
+ >
123
127
  <div className="margin-24">
124
128
  <Form onSubmit={(e) => {
125
129
  e.preventDefault();
@@ -309,7 +313,11 @@ const CVErrataDateFilterContent = ({
309
313
  </div>
310
314
  </Tab>
311
315
  {(repositories.length || showAffectedRepos) &&
312
- <Tab eventKey={1} title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}>
316
+ <Tab
317
+ ouiaId="affected-repositories-tab"
318
+ eventKey={1}
319
+ title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}
320
+ >
313
321
  <div className="margin-24-0">
314
322
  <AffectedRepositoryTable cvId={cvId} filterId={filterId} repoType="yum" setShowAffectedRepos={setShowAffectedRepos} details={details} />
315
323
  </div>
@@ -251,7 +251,11 @@ const CVErrataIDFilterContent = ({
251
251
  activeKey={activeTabKey}
252
252
  onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
253
253
  >
254
- <Tab eventKey={0} title={<TabTitleText>{__('Errata')}</TabTitleText>}>
254
+ <Tab
255
+ ouiaId="errata-filter-table-tab"
256
+ eventKey={0}
257
+ title={<TabTitleText>{__('Errata')}</TabTitleText>}
258
+ >
255
259
  <div className="margin-24-0">
256
260
  <TableWrapper
257
261
  {...{
@@ -452,7 +456,11 @@ const CVErrataIDFilterContent = ({
452
456
  </div>
453
457
  </Tab>
454
458
  {(repositories.length || showAffectedRepos) &&
455
- <Tab eventKey={1} title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}>
459
+ <Tab
460
+ ouiaId="affected-repos-tab"
461
+ eventKey={1}
462
+ title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}
463
+ >
456
464
  <div className="margin-24-0">
457
465
  <AffectedRepositoryTable cvId={cvId} filterId={filterId} repoType="yum" setShowAffectedRepos={setShowAffectedRepos} details={details} />
458
466
  </div>
@@ -207,7 +207,11 @@ const CVModuleStreamFilterContent = ({
207
207
  activeKey={activeTabKey}
208
208
  onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
209
209
  >
210
- <Tab eventKey={0} title={<TabTitleText>{__('Module Streams')}</TabTitleText>}>
210
+ <Tab
211
+ ouiaId="module-stream-filter-content-table-tab"
212
+ eventKey={0}
213
+ title={<TabTitleText>{__('Module Streams')}</TabTitleText>}
214
+ >
211
215
  <div className="margin-24-0">
212
216
  <TableWrapper
213
217
  {...{
@@ -285,7 +289,11 @@ const CVModuleStreamFilterContent = ({
285
289
  </div>
286
290
  </Tab>
287
291
  {(repositories.length || showAffectedRepos) &&
288
- <Tab eventKey={1} title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}>
292
+ <Tab
293
+ ouiaId="affected-repos-tab"
294
+ eventKey={1}
295
+ title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}
296
+ >
289
297
  <div className="margin-24-0">
290
298
  <AffectedRepositoryTable cvId={cvId} filterId={filterId} repoType="yum" setShowAffectedRepos={setShowAffectedRepos} details={details} />
291
299
  </div>
@@ -197,7 +197,11 @@ const CVPackageGroupFilterContent = ({
197
197
  activeKey={activeTabKey}
198
198
  onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
199
199
  >
200
- <Tab eventKey={0} title={<TabTitleText>{__('Package groups')}</TabTitleText>}>
200
+ <Tab
201
+ ouiaId="cv-package-group-filter-content-table-tab"
202
+ eventKey={0}
203
+ title={<TabTitleText>{__('Package groups')}</TabTitleText>}
204
+ >
201
205
  <div className="margin-24-0">
202
206
  <TableWrapper
203
207
  {...{
@@ -275,7 +279,11 @@ const CVPackageGroupFilterContent = ({
275
279
  </div>
276
280
  </Tab>
277
281
  {(repositories.length || showAffectedRepos) &&
278
- <Tab eventKey={1} title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}>
282
+ <Tab
283
+ ouiaId="affected-repos-tab"
284
+ eventKey={1}
285
+ title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}
286
+ >
279
287
  <div className="margin-24-0">
280
288
  <AffectedRepositoryTable cvId={cvId} filterId={filterId} repoType="yum" setShowAffectedRepos={setShowAffectedRepos} details={details} />
281
289
  </div>
@@ -167,7 +167,11 @@ const CVRpmFilterContent = ({
167
167
  activeKey={activeTabKey}
168
168
  onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
169
169
  >
170
- <Tab eventKey={0} title={<TabTitleText>{tabTitle}</TabTitleText>}>
170
+ <Tab
171
+ ouiaId="cv-rpm-filter-content-table-tab"
172
+ eventKey={0}
173
+ title={<TabTitleText>{tabTitle}</TabTitleText>}
174
+ >
171
175
  <div className="margin-24-0">
172
176
  <TableWrapper
173
177
  {...{
@@ -239,7 +243,11 @@ const CVRpmFilterContent = ({
239
243
  </div>
240
244
  </Tab>
241
245
  {(repositories.length || showAffectedRepos) &&
242
- <Tab eventKey={1} title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}>
246
+ <Tab
247
+ ouiaId="cv-rpm-filter-content-affected-repos-tab"
248
+ eventKey={1}
249
+ title={<TabTitleText>{__('Affected repositories')}</TabTitleText>}
250
+ >
243
251
  <div className="margin-24-0">
244
252
  <AffectedRepositoryTable cvId={cvId} filterId={filterId} repoType="yum" setShowAffectedRepos={setShowAffectedRepos} details={details} />
245
253
  </div>
@@ -49,9 +49,9 @@ const ContentViewHistories = ({ cvId }) => {
49
49
  const taskType = task ? task.label : taskTypes[action];
50
50
 
51
51
  if (taskType === taskTypes.removal) {
52
- return <>{__('Deleted from ')} <Label isTruncated key="1" color="blue" href={`/lifecycle_environments/${environment?.id}`}>{`${environment?.name ?? __('all environments')}`}</Label></>;
52
+ return <>{__('Deleted from ')} <Label isTruncated key="1" color="blue" href={`/lifecycle_environments/${environment?.id}`}>{environment?.name ?? __('all environments')}</Label></>;
53
53
  } else if (action === 'promotion' || taskType === taskTypes.promotion) {
54
- return <>{__('Promoted to ')}<Label isTruncated key="2" color="blue" href={`/lifecycle_environments/${environment?.id}`}>{`${environment?.name}`}</Label></>;
54
+ return <>{__('Promoted to ')}<Label isTruncated key="2" color="blue" href={`/lifecycle_environments/${environment?.id}`}>{environment?.name}</Label></>;
55
55
  } else if (taskType === taskTypes.publish) {
56
56
  return __('Published new version');
57
57
  } else if (taskType === taskTypes.export) {
@@ -12,9 +12,9 @@ const repoLabels = {
12
12
  erratum: ['errata', 'erratum', 'errata'], // need to handle link, its $URL/errata?repositoryId=107
13
13
  deb: ['deb packages', 'deb package', 'debs'],
14
14
  ansible_collection: ['Ansible collections', 'Ansible collection', 'ansible_collections'],
15
- docker_manifest: ['container manifests', 'container manifest', 'content/docker_manifests'],
16
- docker_manifest_list: ['container manifest lists', 'container manifest list', 'content/docker_manifest_lists'],
17
- docker_tag: ['container tags', 'container tag', 'content/docker_tags'],
15
+ docker_manifest: ['container manifests', 'container manifest', 'docker_manifests'],
16
+ docker_manifest_list: ['container manifest lists', 'container manifest list', 'docker_manifest_lists'],
17
+ docker_tag: ['container tags', 'container tag', 'docker_tags'],
18
18
  file: ['files', 'file', 'content/files'],
19
19
  package_group: ['package groups', 'package group', 'package_groups'],
20
20
  srpm: ['source RPMs', 'source RPM', 'source_rpms'], // no link?
@@ -106,6 +106,7 @@ const CVVersionCompare = ({
106
106
  const { name } = config;
107
107
  return (
108
108
  <Tab
109
+ ouiaId={`cv-version-compare-tab-${name}`}
109
110
  key={name}
110
111
  eventKey={name}
111
112
  title={
@@ -66,7 +66,7 @@ const AffectedActivationKeys = ({
66
66
  </Thead>
67
67
  <Tbody>
68
68
  {results?.map(({ name, id, environment }) => (
69
- <Tr ouiaId={`${id}`} key={`${id}`}>
69
+ <Tr ouiaId={id} key={id}>
70
70
  <Td>
71
71
  <a rel="noreferrer" target="_blank" href={urlBuilder(`activation_keys/${id}`, '')}>{name}</a>
72
72
  </Td>
@@ -65,7 +65,7 @@ const AffectedHosts = ({
65
65
  id,
66
66
  content_facet_attributes: { lifecycle_environment: environment },
67
67
  }) => (
68
- <Tr ouiaId={`${id}`} key={`${id}`}>
68
+ <Tr ouiaId={id} key={id}>
69
69
  <Td>
70
70
  <a rel="noreferrer" target="_blank" href={urlBuilder(`new/hosts/${id}`, '')}>{name}</a>
71
71
  </Td>
@@ -76,6 +76,7 @@ const ContentViewVersionDetails = ({ cvId, details }) => {
76
76
  >
77
77
  {filteredTableConfigs.map(({ route, name, getCountKey }) => (
78
78
  <Tab
79
+ ouiaId={`cv-version-details-tabs-tab-${route}`}
79
80
  key={route}
80
81
  eventKey={route}
81
82
  title={
@@ -13,6 +13,7 @@ import contentViewTaskResponseData from './contentViewTaskResponse.fixtures.json
13
13
  import cvDetailData from '../../../../ContentViews/__tests__/mockDetails.fixtures.json';
14
14
  import environmentPathsData from '../../../Publish/__tests__/environmentPaths.fixtures.json';
15
15
  import cvIndexData from '../../../__tests__/contentViewList.fixtures.json';
16
+ import contentViewFilterData from '../../Filters/__tests__/contentViewFilters.fixtures.json';
16
17
 
17
18
  const cvPromotePath = api.getApiUrl('/content_view_versions/10/promote');
18
19
  const cvIndexPath = api.getApiUrl('/content_views');
@@ -34,6 +35,7 @@ const renderOptions = {
34
35
  const cvVersions = api.getApiUrl('/content_view_versions');
35
36
  const autocompleteUrl = '/content_view_versions/auto_complete_search';
36
37
  const taskPollingUrl = '/foreman_tasks/api/tasks/6b900ff8-62bb-42ac-8c45-da86b7258520';
38
+ const cvFiltersPath = api.getApiUrl('/content_view_filters?content_view_id=5');
37
39
 
38
40
  let firstVersion;
39
41
  let envScope;
@@ -330,6 +332,10 @@ test('Shows call-to-action when there are no versions', async (done) => {
330
332
  .query(true)
331
333
  .reply(200, environmentPathsData);
332
334
 
335
+ const filterScope = nockInstance
336
+ .get(cvFiltersPath)
337
+ .reply(200, contentViewFilterData);
338
+
333
339
  const { getByText, queryByText } = renderWithRedux(
334
340
  withCVRoute(<ContentViewVersions cvId={5} details={cvDetailData} />),
335
341
  renderOptions,
@@ -347,6 +353,7 @@ test('Shows call-to-action when there are no versions', async (done) => {
347
353
  assertNockRequest(scopeWizard);
348
354
  assertNockRequest(autocompleteScope);
349
355
  assertNockRequest(scope);
356
+ assertNockRequest(filterScope);
350
357
  act(done);
351
358
  });
352
359
 
@@ -28,7 +28,7 @@ test('Can call API and show details on page load', async (done) => {
28
28
  .query(true)
29
29
  .reply(200, cvDetailData);
30
30
 
31
- const { getByLabelText } = renderWithRedux(
31
+ const { getByLabelText, queryByLabelText } = renderWithRedux(
32
32
  withCVRoute(<ContentViewDetails />),
33
33
  renderOptions,
34
34
  );
@@ -40,6 +40,8 @@ test('Can call API and show details on page load', async (done) => {
40
40
  expect(getByLabelText('a_cv_index')).toBeInTheDocument();
41
41
  expect(getByLabelText(`b_${name}`)).toBeInTheDocument();
42
42
  expect(getByLabelText('c_details')).toBeInTheDocument();
43
+ expect(queryByLabelText('Import only')).not.toBeInTheDocument();
44
+ expect(queryByLabelText('Generated')).not.toBeInTheDocument();
43
45
  });
44
46
 
45
47
  assertNockRequest(scope, done);
@@ -98,7 +100,7 @@ test('Can edit boolean details such as solve dependencies', async (done) => {
98
100
  .query(true)
99
101
  .reply(200, updatedCVDetails);
100
102
 
101
- const { getByLabelText } = renderWithRedux(
103
+ const { getByLabelText, queryByLabelText } = renderWithRedux(
102
104
  withCVRoute(<ContentViewDetails />),
103
105
  renderOptions,
104
106
  );
@@ -110,8 +112,7 @@ test('Can edit boolean details such as solve dependencies', async (done) => {
110
112
  await patientlyWaitFor(() => expect(getByLabelText(checkboxLabel).checked).toBeTruthy());
111
113
 
112
114
  const disabledImportLabel = /import_only_switch/;
113
- expect(getByLabelText(disabledImportLabel)).toBeInTheDocument();
114
- expect(getByLabelText(disabledImportLabel)).toHaveAttribute('disabled');
115
+ expect(queryByLabelText(disabledImportLabel)).not.toBeInTheDocument();
115
116
 
116
117
  assertNockRequest(getscope);
117
118
  assertNockRequest(updatescope);
@@ -137,3 +138,26 @@ test('Can link to view tasks', async () => {
137
138
 
138
139
  assertNockRequest(scope);
139
140
  });
141
+
142
+ test('Can show import_only and generated when true', async (done) => {
143
+ const updatedCVDetails = { ...cvDetailData };
144
+ updatedCVDetails.generated_for = 'Library';
145
+ updatedCVDetails.import_only = true;
146
+
147
+ const scope = nockInstance
148
+ .get(cvDetailsPath)
149
+ .query(true)
150
+ .reply(200, updatedCVDetails);
151
+
152
+ const { getByLabelText } = renderWithRedux(
153
+ withCVRoute(<ContentViewDetails />),
154
+ renderOptions,
155
+ );
156
+
157
+ await patientlyWaitFor(() => {
158
+ expect(getByLabelText('import_only_switch')).toBeInTheDocument();
159
+ expect(getByLabelText('generated_by_export_switch')).toBeInTheDocument();
160
+ });
161
+
162
+ assertNockRequest(scope, done);
163
+ });