katello 4.6.2.1 → 4.7.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of katello might be problematic. Click here for more details.

Files changed (333) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/common/vendor.js +0 -1
  3. data/app/controllers/katello/api/v2/activation_keys_controller.rb +1 -0
  4. data/app/controllers/katello/api/v2/alternate_content_sources_controller.rb +4 -4
  5. data/app/controllers/katello/api/v2/capsule_content_controller.rb +5 -0
  6. data/app/controllers/katello/api/v2/content_imports_controller.rb +1 -0
  7. data/app/controllers/katello/api/v2/content_view_components_controller.rb +1 -1
  8. data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +2 -1
  9. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +1 -1
  10. data/app/controllers/katello/api/v2/organizations_controller.rb +1 -0
  11. data/app/controllers/katello/api/v2/repositories_controller.rb +78 -12
  12. data/app/controllers/katello/api/v2/upstream_subscriptions_controller.rb +1 -1
  13. data/app/controllers/katello/concerns/api/v2/registration_controller_extensions.rb +7 -1
  14. data/app/controllers/katello/concerns/api/v2/smart_proxies_controller_extensions.rb +1 -0
  15. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +11 -9
  16. data/app/helpers/katello/content_source_helper.rb +9 -0
  17. data/app/helpers/katello/hosts_and_hostgroups_helper.rb +31 -0
  18. data/app/lib/actions/katello/activation_key/destroy.rb +1 -0
  19. data/app/lib/actions/katello/agent_action.rb +1 -0
  20. data/app/lib/actions/katello/alternate_content_source/create.rb +1 -1
  21. data/app/lib/actions/katello/alternate_content_source/update.rb +2 -2
  22. data/app/lib/actions/katello/capsule_content/sync.rb +10 -2
  23. data/app/lib/actions/katello/cdn_configuration/update.rb +1 -1
  24. data/app/lib/actions/katello/content_view/promote.rb +1 -0
  25. data/app/lib/actions/katello/content_view/publish.rb +5 -2
  26. data/app/lib/actions/katello/content_view_version/auto_create_redhat_repositories.rb +7 -3
  27. data/app/lib/actions/katello/content_view_version/auto_create_repositories.rb +4 -2
  28. data/app/lib/actions/katello/content_view_version/import.rb +22 -10
  29. data/app/lib/actions/katello/product/destroy.rb +1 -1
  30. data/app/lib/actions/katello/repository/destroy.rb +3 -3
  31. data/app/lib/actions/katello/repository/errata_mail.rb +9 -6
  32. data/app/lib/actions/katello/repository/refresh_repository.rb +1 -1
  33. data/app/lib/actions/katello/repository/sync.rb +13 -6
  34. data/app/lib/actions/katello/repository_set/enable_repository.rb +6 -2
  35. data/app/lib/actions/pulp3/alternate_content_source/refresh_remote.rb +16 -0
  36. data/app/lib/actions/pulp3/orchestration/alternate_content_source/refresh.rb +1 -0
  37. data/app/lib/actions/pulp3/orchestration/content_view_version/export_library.rb +1 -1
  38. data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +10 -2
  39. data/app/lib/katello/concerns/renderer_extensions.rb +2 -1
  40. data/app/lib/katello/errors.rb +2 -2
  41. data/app/lib/katello/resources/candlepin.rb +7 -1
  42. data/app/lib/katello/resources/cdn/katello_cdn.rb +3 -13
  43. data/app/lib/katello/resources/cdn.rb +14 -9
  44. data/app/lib/katello/util/candlepin_repository_checker.rb +73 -0
  45. data/app/models/katello/activation_key.rb +12 -1
  46. data/app/models/katello/alternate_content_source.rb +15 -4
  47. data/app/models/katello/alternate_content_source_product.rb +1 -1
  48. data/app/models/katello/authorization/repository.rb +2 -2
  49. data/app/models/katello/cdn_configuration.rb +12 -3
  50. data/app/models/katello/concerns/host_managed_extensions.rb +15 -2
  51. data/app/models/katello/concerns/http_proxy_extensions.rb +5 -10
  52. data/app/models/katello/concerns/smart_proxy_extensions.rb +30 -15
  53. data/app/models/katello/content.rb +15 -0
  54. data/app/models/katello/content_credential.rb +8 -9
  55. data/app/models/katello/content_view.rb +7 -3
  56. data/app/models/katello/content_view_component.rb +4 -0
  57. data/app/models/katello/content_view_version.rb +1 -1
  58. data/app/models/katello/erratum.rb +6 -2
  59. data/app/models/katello/host/content_facet.rb +13 -3
  60. data/app/models/katello/repository.rb +15 -1
  61. data/app/models/katello/root_repository.rb +0 -2
  62. data/app/overrides/add_smart_proxy_form.rb +5 -0
  63. data/app/presenters/katello/content_view_version_compare_presenter.rb +5 -0
  64. data/app/presenters/katello/host_package_presenter.rb +4 -4
  65. data/app/services/katello/pulp3/alternate_content_source.rb +23 -15
  66. data/app/services/katello/pulp3/ansible_collection.rb +7 -10
  67. data/app/services/katello/pulp3/content_view_version/export.rb +19 -6
  68. data/app/services/katello/pulp3/content_view_version/import.rb +2 -0
  69. data/app/services/katello/pulp3/content_view_version/import_validator.rb +21 -5
  70. data/app/services/katello/pulp3/content_view_version/importable_products.rb +11 -1
  71. data/app/services/katello/pulp3/content_view_version/importable_repositories.rb +38 -9
  72. data/app/services/katello/pulp3/content_view_version/metadata_generator.rb +12 -5
  73. data/app/services/katello/pulp3/content_view_version/metadata_map.rb +13 -2
  74. data/app/services/katello/pulp3/content_view_version/syncable_format_export.rb +5 -1
  75. data/app/services/katello/pulp3/pulp_content_unit.rb +3 -0
  76. data/app/services/katello/pulp3/repository.rb +18 -6
  77. data/app/services/katello/pulp3/repository_mirror.rb +0 -1
  78. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +2 -2
  79. data/app/services/katello/pulp3/task_group.rb +18 -1
  80. data/app/services/katello/repository_type.rb +5 -2
  81. data/app/services/katello/repository_type_manager.rb +4 -3
  82. data/app/views/dashboard/_content_views_widget.html.erb +1 -1
  83. data/app/views/foreman/job_templates/change_content_source.erb +6 -0
  84. data/app/views/foreman/job_templates/update_packages_by_search_query.erb +7 -1
  85. data/app/views/katello/api/v2/alternate_content_sources/base.json.rabl +4 -4
  86. data/app/views/katello/api/v2/alternate_content_sources/index.json.rabl +1 -0
  87. data/app/views/katello/api/v2/alternate_content_sources/permissions.rabl +11 -0
  88. data/app/views/katello/api/v2/content_credentials/show.json.rabl +12 -0
  89. data/app/views/katello/api/v2/content_views/permissions.rabl +1 -0
  90. data/app/views/katello/api/v2/host_packages/base.json.rabl +1 -1
  91. data/app/views/katello/api/v2/module_streams/show.json.rabl +7 -0
  92. data/app/views/katello/api/v2/repositories/compare.json.rabl +10 -0
  93. data/app/views/katello/api/v2/smart_proxies/pulp_info.json.rabl +1 -0
  94. data/app/views/katello/hosts/_errata_counts.html.erb +46 -0
  95. data/app/views/overrides/activation_keys/_host_synced_content_select.html.erb +1 -0
  96. data/app/views/overrides/smart_proxies/_acs_http_proxy.html.erb +6 -0
  97. data/config/initializers/monkeys.rb +1 -0
  98. data/config/routes/api/v2.rb +2 -0
  99. data/config/routes.rb +3 -0
  100. data/db/migrate/20220730033504_update_custom_cdn.rb +13 -0
  101. data/db/migrate/20220920173656_add_http_proxy_to_smart_proxy.rb +7 -0
  102. data/db/migrate/20220920180858_remove_http_proxy_from_katello_alternate_content_sources.rb +6 -0
  103. data/engines/bastion/app/assets/javascripts/bastion/components/notification.service.js +1 -1
  104. data/engines/bastion/app/views/bastion/layouts/assets.html.erb +5 -5
  105. data/engines/bastion/vendor/assets/javascripts/bastion/angular/angular.js +1 -1
  106. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credential.factory.js +17 -0
  107. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credentials.routes.js +10 -0
  108. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-acs.controller.js +36 -0
  109. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-details.controller.js +7 -1
  110. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/views/content-credential-acs.html +38 -0
  111. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/views/content-credential-details.html +3 -0
  112. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/views/content-credentials.html +7 -2
  113. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +4 -2
  114. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-info.html +1 -1
  115. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +4 -3
  116. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +14 -1392
  117. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/katello-features.run.js +1 -0
  118. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +7 -0
  119. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +1 -1
  120. data/lib/katello/permission_creator.rb +1 -0
  121. data/lib/katello/plugin.rb +34 -11
  122. data/lib/katello/repository_types/deb.rb +1 -1
  123. data/lib/katello/repository_types/docker.rb +1 -1
  124. data/lib/katello/repository_types/python.rb +3 -3
  125. data/lib/katello/tasks/check_candlepin_content.rake +16 -0
  126. data/lib/katello/tasks/reset.rake +1 -1
  127. data/lib/katello/version.rb +1 -1
  128. data/lib/monkeys/try_pulp_container_path.rb +35 -0
  129. data/locale/action_names.rb +7 -7
  130. data/locale/bn/katello.po +395 -63
  131. data/locale/cs/katello.po +396 -64
  132. data/locale/de/katello.po +399 -67
  133. data/locale/en/katello.po +395 -63
  134. data/locale/es/katello.po +399 -67
  135. data/locale/fr/katello.po +400 -68
  136. data/locale/gu/katello.po +395 -63
  137. data/locale/hi/katello.po +395 -63
  138. data/locale/it/katello.po +396 -64
  139. data/locale/ja/katello.po +400 -68
  140. data/locale/katello.pot +1916 -1213
  141. data/locale/kn/katello.po +395 -63
  142. data/locale/ko/katello.po +396 -64
  143. data/locale/mr/katello.po +395 -63
  144. data/locale/or/katello.po +395 -63
  145. data/locale/pa/katello.po +395 -63
  146. data/locale/pt/katello.po +395 -63
  147. data/locale/pt_BR/katello.po +399 -67
  148. data/locale/ru/katello.po +396 -64
  149. data/locale/ta/katello.po +395 -63
  150. data/locale/te/katello.po +395 -63
  151. data/locale/zh_CN/katello.po +400 -68
  152. data/locale/zh_TW/katello.po +396 -64
  153. data/webpack/components/Bookmark/index.js +5 -1
  154. data/webpack/components/Content/Details/ContentDetails.js +1 -1
  155. data/webpack/components/Content/Details/__tests__/__snapshots__/ContentDetails.test.js.snap +6 -0
  156. data/webpack/components/EditableSwitch.js +1 -0
  157. data/webpack/components/EditableTextInput/EditableTextInput.js +3 -3
  158. data/webpack/components/Errata/errataHelpers.js +33 -0
  159. data/webpack/components/Errata/index.js +45 -12
  160. data/webpack/components/Loading.js +18 -8
  161. data/webpack/components/Packages/index.js +8 -24
  162. data/webpack/components/RoutedTabs/index.js +1 -0
  163. data/webpack/components/Search/Search.js +20 -2
  164. data/webpack/components/Search/__tests__/search.test.js +3 -3
  165. data/webpack/components/Table/EmptyStateMessage.js +1 -1
  166. data/webpack/components/Table/PageControls.js +1 -0
  167. data/webpack/components/Table/TableHooks.js +4 -0
  168. data/webpack/components/Table/TableWrapper.js +7 -7
  169. data/webpack/components/TypeAhead/pf4Search/TypeAheadInput.js +1 -0
  170. data/webpack/components/TypeAhead/pf4Search/TypeAheadItems.js +2 -0
  171. data/webpack/components/TypeAhead/pf4Search/TypeAheadSearch.js +1 -1
  172. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ChangeHostCVModal.js +3 -1
  173. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard.js +2 -1
  174. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.js +124 -68
  175. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.scss +5 -0
  176. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.js +30 -4
  177. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.scss +23 -0
  178. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsModal.js +5 -4
  179. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/__tests__/hostCollectionsCard.test.js +25 -10
  180. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.js +3 -3
  181. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeEditModal.js +6 -0
  182. data/webpack/components/extensions/HostDetails/Cards/__tests__/errataOverviewCard.test.js +145 -32
  183. data/webpack/components/extensions/HostDetails/DetailsTabCards/RegistrationCard.js +3 -1
  184. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/constants.js +2 -1
  185. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/index.js +1 -0
  186. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +78 -26
  187. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +23 -10
  188. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/HostPackagesConstants.js +1 -0
  189. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js +9 -4
  190. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +141 -23
  191. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.scss +6 -1
  192. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +9 -8
  193. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +24 -3
  194. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerModal.js +7 -2
  195. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesEnabler.js +2 -1
  196. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesTab.js +20 -4
  197. data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +56 -38
  198. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packages.fixtures.json +3 -3
  199. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +5 -4
  200. data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +3 -3
  201. data/webpack/containers/Application/config.js +2 -2
  202. data/webpack/containers/Application/overrides.scss +12 -0
  203. data/webpack/global_test_setup.js +19 -1
  204. data/webpack/ouia_id_check.js +0 -2
  205. data/webpack/redux/actions/RedHatRepositories/helpers.js +4 -8
  206. data/webpack/scenes/AlternateContentSources/ACSActions.js +37 -6
  207. data/webpack/scenes/AlternateContentSources/ACSConstants.js +2 -0
  208. data/webpack/scenes/AlternateContentSources/ACSIndexPage.js +1 -1
  209. data/webpack/scenes/AlternateContentSources/ACSSelectors.js +6 -6
  210. data/webpack/scenes/AlternateContentSources/Acs.scss +3 -0
  211. data/webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js +24 -3
  212. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js +10 -8
  213. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSCredentials.js +25 -4
  214. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSReview.js +22 -11
  215. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSSmartProxies.js +27 -2
  216. data/webpack/scenes/AlternateContentSources/Create/Steps/AcsUrlPaths.js +49 -17
  217. data/webpack/scenes/AlternateContentSources/Create/Steps/SelectSource.js +76 -23
  218. data/webpack/scenes/AlternateContentSources/Create/__tests__/acsCreate.test.js +159 -11
  219. data/webpack/scenes/AlternateContentSources/Details/ACSExpandableDetails.js +83 -29
  220. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditCredentials.js +9 -8
  221. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditDetails.js +2 -2
  222. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditProducts.js +2 -2
  223. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditSmartProxies.js +39 -7
  224. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditURLPaths.js +27 -11
  225. data/webpack/scenes/AlternateContentSources/Details/__tests__/ACSEdits.test.js +58 -55
  226. data/webpack/scenes/AlternateContentSources/Details/__tests__/ACSExpandableDetails.test.js +35 -32
  227. data/webpack/scenes/AlternateContentSources/MainTable/ACSTable.js +323 -150
  228. data/webpack/scenes/AlternateContentSources/MainTable/__tests__/acsIndex.fixtures.json +5 -1
  229. data/webpack/scenes/AlternateContentSources/MainTable/__tests__/acsTable.test.js +10 -11
  230. data/webpack/scenes/AlternateContentSources/helpers.js +26 -0
  231. data/webpack/scenes/ContentViews/ContentViewsConstants.js +1 -0
  232. data/webpack/scenes/ContentViews/ContentViewsPage.js +1 -1
  233. data/webpack/scenes/ContentViews/Copy/CopyContentViewForm.js +1 -0
  234. data/webpack/scenes/ContentViews/Copy/CopyContentViewModal.js +1 -0
  235. data/webpack/scenes/ContentViews/Create/ContentViewFormComponents.js +10 -5
  236. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +30 -7
  237. data/webpack/scenes/ContentViews/Create/CreateContentViewModal.js +1 -0
  238. data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +21 -6
  239. data/webpack/scenes/ContentViews/Delete/Steps/CVDeleteEnvironmentsSelection.js +3 -3
  240. data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionReassignActivationKeysForm.js +1 -0
  241. data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionReassignHostsForm.js +1 -0
  242. data/webpack/scenes/ContentViews/Delete/__tests__/CvData.fixtures.json +2 -0
  243. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +3 -0
  244. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +4 -1
  245. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentVersion.js +1 -1
  246. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +2 -1
  247. data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +14 -0
  248. data/webpack/scenes/ContentViews/Details/ContentViewDetailSelectors.js +11 -1
  249. data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +1 -1
  250. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +2 -0
  251. data/webpack/scenes/ContentViews/Details/Filters/Add/CVFilterAddModal.js +5 -0
  252. data/webpack/scenes/ContentViews/Details/Filters/AffectedRepositories/AffectedRepositorySelection.js +1 -0
  253. data/webpack/scenes/ContentViews/Details/Filters/ArtifactsWithNoErrata.js +1 -0
  254. data/webpack/scenes/ContentViews/Details/Filters/CVContainerImageFilterContent.js +8 -2
  255. data/webpack/scenes/ContentViews/Details/Filters/CVDebFilterContent.js +5 -1
  256. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +22 -6
  257. data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +19 -9
  258. data/webpack/scenes/ContentViews/Details/Filters/CVModuleStreamFilterContent.js +9 -2
  259. data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +9 -2
  260. data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +8 -2
  261. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilterDetailsHeader.js +1 -1
  262. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilters.js +2 -1
  263. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/CVRpmMatchContentModal.js +3 -2
  264. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/__tests__/CVRpmMatchContentModal.test.js +1 -1
  265. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVContainerImageFilterContent.test.js +2 -2
  266. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVRpmFilterContent.test.js +1 -1
  267. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilterDetails.test.js +1 -1
  268. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilters.test.js +1 -1
  269. data/webpack/scenes/ContentViews/Details/Histories/ContentViewHistories.js +2 -2
  270. data/webpack/scenes/ContentViews/Details/Promote/ContentViewVersionPromote.js +2 -0
  271. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +2 -1
  272. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/Steps/ReviewEnvironments.js +3 -3
  273. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompare.js +9 -1
  274. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareConfig.js +83 -0
  275. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareTable.js +32 -8
  276. data/webpack/scenes/ContentViews/Details/Versions/Compare/__tests__/CVVersionCompare.test.js +56 -3
  277. data/webpack/scenes/ContentViews/Details/Versions/Compare/__tests__/cvCompareRepositories.fixtures.json +175 -0
  278. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +6 -2
  279. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVEnvironmentSelectionForm.js +3 -3
  280. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignActivationKeysForm.js +1 -0
  281. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignHostsForm.js +1 -0
  282. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js +2 -2
  283. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedHosts.js +2 -2
  284. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailConfig.js +2 -2
  285. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetails.js +1 -0
  286. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsHeader.js +4 -1
  287. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsTable.js +5 -4
  288. data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +5 -1
  289. data/webpack/scenes/ContentViews/Publish/CVPublishReview.js +3 -3
  290. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +10 -5
  291. data/webpack/scenes/ContentViews/__tests__/basicContentViews.fixtures.js +2 -0
  292. data/webpack/scenes/ContentViews/__tests__/contentViewList.fixtures.json +1 -0
  293. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +81 -19
  294. data/webpack/scenes/ContentViews/components/CVBreadCrumb.js +1 -1
  295. data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.js +1 -0
  296. data/webpack/scenes/ContentViews/components/InactiveText.js +9 -1
  297. data/webpack/scenes/ContentViews/expansions/RelatedCompositeContentViewsModal.js +4 -2
  298. data/webpack/scenes/ContentViews/expansions/RelatedContentViewComponentsModal.js +3 -2
  299. data/webpack/scenes/Hosts/ChangeContentSource/actions.js +18 -11
  300. data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceForm.js +15 -8
  301. data/webpack/scenes/Hosts/ChangeContentSource/components/FormField.js +3 -4
  302. data/webpack/scenes/Hosts/ChangeContentSource/components/Hosts.js +55 -0
  303. data/webpack/scenes/Hosts/ChangeContentSource/components/HostsModal.js +59 -0
  304. data/webpack/scenes/Hosts/ChangeContentSource/constants.js +1 -0
  305. data/webpack/scenes/Hosts/ChangeContentSource/helpers.js +2 -5
  306. data/webpack/scenes/Hosts/ChangeContentSource/index.js +46 -41
  307. data/webpack/scenes/Hosts/ChangeContentSource/selectors.js +5 -5
  308. data/webpack/scenes/ModuleStreams/Details/ModuleDetailsSchema.js +10 -1
  309. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetails.js +1 -1
  310. data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetails.test.js.snap +97 -2
  311. data/webpack/scenes/Organizations/OrganizationSelectors.js +1 -0
  312. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnConfigurationConstants.js +2 -1
  313. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnTypeForm.js +10 -25
  314. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CustomCdnTypeForm.js +154 -0
  315. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/ExportSyncForm.js +4 -4
  316. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/NetworkSyncForm.js +59 -44
  317. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/CdnTypeForm.test.js +3 -28
  318. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/CustomCdnTypeForm.test.js +97 -0
  319. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/ExportSyncForm.test.js +1 -1
  320. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/NetworkSyncForm.test.js +4 -4
  321. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/index.js +23 -10
  322. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +1 -1
  323. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +2 -1
  324. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +5 -5
  325. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +3 -3
  326. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/__snapshots__/UpstreamSubscriptionsPage.test.js.snap +2 -2
  327. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +3 -3
  328. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.js +3 -3
  329. data/webpack/scenes/Tasks/helpers.js +14 -7
  330. metadata +54 -35
  331. data/app/lib/actions/pulp3/orchestration/alternate_content_source/refresh_remote.rb +0 -18
  332. data/db/migrate/20221206170122_update_ignore_srpm_to_false_for_mirror_complete.rb +0 -5
  333. data/vendor/assets/javascripts/katello/jquery.trunk8.js +0 -203
@@ -0,0 +1,26 @@
1
+ export const isValidUrl = (urlString, acsType = '') => {
2
+ try {
3
+ const urlFromString = new URL(urlString);
4
+ let valid = urlFromString.protocol === 'https:' || urlFromString.protocol === 'http:' || urlFromString.protocol === 'file:';
5
+ if (acsType === 'rhui') {
6
+ valid = valid && urlFromString.pathname === '/pulp/content';
7
+ }
8
+ return valid;
9
+ } catch (e) {
10
+ return false;
11
+ }
12
+ };
13
+
14
+ export const areSubPathsValid = (subpathsString) => {
15
+ try {
16
+ if (subpathsString === '') {
17
+ return true;
18
+ }
19
+ return subpathsString.split(',').every((subpath) => {
20
+ const trimmedPath = subpath.trim();
21
+ return (!trimmedPath.startsWith('/') && trimmedPath.endsWith('/'));
22
+ });
23
+ } catch (e) {
24
+ return false;
25
+ }
26
+ };
@@ -63,6 +63,7 @@ export const addComponentSuccessMessage = component => (component ? __('Updated
63
63
  export const genericContentCompareKey = (pluralLabel, versionOne, versionTwo, viewBy) => `${toUpper(pluralLabel)}_COMPARE_${versionOne}_${versionTwo}_VIEW_BY_${toUpper(viewBy)}`;
64
64
  export const cvPackageGroupsCompareKey = (versionOne, versionTwo, viewBy) => `${PACKAGE_GROUPS_KEY}_COMPARE_${versionOne}_${versionTwo}_VIEW_BY_${toUpper(viewBy)}`;
65
65
  export const cvRPMPackagesCompareKey = (versionOne, versionTwo, viewBy) => `${PACKAGES_KEY}_COMPARE_${versionOne}_${versionTwo}_VIEW_BY_${toUpper(viewBy)}`;
66
+ export const cvRepositoriesCompareKey = (versionOne, versionTwo, viewBy) => `REPOSITORIES_COMPARE_${versionOne}_${versionTwo}_VIEW_BY_${toUpper(viewBy)}`;
66
67
  export const cvErrataCompareKey = (versionOne, versionTwo, viewBy) => `${ERRATA_KEY}_COMPARE_${versionOne}_${versionTwo}_VIEW_BY_${toUpper(viewBy)}`;
67
68
  export const cvModuleStreamsCompareKey = (versionOne, versionTwo, viewBy) => `${MODULE_STREAMS_KEY}_COMPARE_${versionOne}_${versionTwo}_VIEW_BY_${toUpper(viewBy)}`;
68
69
  export const cvDebPackagesCompareKey = (versionOne, versionTwo, viewBy) => `${DEB_PACKAGES_KEY}_COMPARE_${versionOne}_${versionTwo}_VIEW_BY_${toUpper(viewBy)}`;
@@ -9,7 +9,7 @@ const ContentViewsPage = () => (
9
9
  <Grid className="margin-24">
10
10
  <GridItem span={12}>
11
11
  <TextContent>
12
- <Text component={TextVariants.h1}>{__('Content views')}</Text>
12
+ <Text ouiaId="cvPageHeaderText" component={TextVariants.h1}>{__('Content views')}</Text>
13
13
  </TextContent>
14
14
  </GridItem>
15
15
  <GridItem span={12} className="margin-top-8">
@@ -52,6 +52,7 @@ const CopyContentViewForm = ({ cvId, setModalOpen }) => {
52
52
  type="text"
53
53
  id="name"
54
54
  aria-label="input_name"
55
+ ouiaId="input_name"
55
56
  name="name"
56
57
  value={name}
57
58
  onChange={setName}
@@ -18,6 +18,7 @@ const CopyContentViewModal = ({
18
18
  return (
19
19
  <Modal
20
20
  title="Copy content view"
21
+ ouiaId="copy-content-view-modal"
21
22
  variant={ModalVariant.small}
22
23
  isOpen={show}
23
24
  description={description}
@@ -1,11 +1,12 @@
1
1
  import React from 'react';
2
+ import PropTypes from 'prop-types';
2
3
  import { translate as __ } from 'foremanReact/common/I18n';
3
4
  import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons';
4
5
  import { Tooltip, TooltipPosition, Flex, FlexItem } from '@patternfly/react-core';
5
6
  import { autoPublishHelpText, dependenciesHelpText, importOnlyHelpText, generatedContentViewHelpText } from '../helpers';
6
7
  import ContentViewIcon from '../components/ContentViewIcon';
7
8
 
8
- const HelpToolTip = tooltip => (
9
+ export const HelpToolTip = ({ tooltip }) => (
9
10
  <span className="foreman-spaced-icon">
10
11
  <Tooltip
11
12
  position={TooltipPosition.top}
@@ -34,7 +35,7 @@ export const LabelDependencies = () => (
34
35
  <Flex>
35
36
  <FlexItem spacer={{ default: 'spacerSm' }}>{__('Solve dependencies')}</FlexItem>
36
37
  <FlexItem>
37
- {HelpToolTip(dependenciesHelpText)}
38
+ <HelpToolTip tooltip={dependenciesHelpText} />
38
39
  </FlexItem>
39
40
  </Flex>
40
41
  );
@@ -43,7 +44,7 @@ export const LabelAutoPublish = () => (
43
44
  <Flex>
44
45
  <FlexItem spacer={{ default: 'spacerSm' }}>{__('Auto publish')}</FlexItem>
45
46
  <FlexItem>
46
- {HelpToolTip(autoPublishHelpText)}
47
+ <HelpToolTip tooltip={autoPublishHelpText} />
47
48
  </FlexItem>
48
49
  </Flex>
49
50
  );
@@ -52,7 +53,7 @@ export const LabelImportOnly = () => (
52
53
  <Flex>
53
54
  <FlexItem spacer={{ default: 'spacerSm' }}>{__('Import only')}</FlexItem>
54
55
  <FlexItem>
55
- {HelpToolTip(importOnlyHelpText)}
56
+ <HelpToolTip tooltip={importOnlyHelpText} />
56
57
  </FlexItem>
57
58
  </Flex>
58
59
  );
@@ -61,7 +62,11 @@ export const LabelGenerated = () => (
61
62
  <Flex>
62
63
  <FlexItem spacer={{ default: 'spacerSm' }}>{__('Generated')}</FlexItem>
63
64
  <FlexItem>
64
- {HelpToolTip(generatedContentViewHelpText)}
65
+ <HelpToolTip tooltip={generatedContentViewHelpText} />
65
66
  </FlexItem>
66
67
  </Flex>
67
68
  );
69
+
70
+ HelpToolTip.propTypes = {
71
+ tooltip: PropTypes.string.isRequired,
72
+ };
@@ -4,7 +4,6 @@ import { STATUS } from 'foremanReact/constants';
4
4
  import { translate as __ } from 'foremanReact/common/I18n';
5
5
  import PropTypes from 'prop-types';
6
6
  import { useDispatch, useSelector } from 'react-redux';
7
- import { Redirect } from 'react-router-dom';
8
7
  import { Form, FormGroup, TextInput, TextArea, Checkbox, ActionGroup, Button, Tile, Grid, GridItem } from '@patternfly/react-core';
9
8
  import { createContentView } from '../ContentViewsActions';
10
9
  import { selectCreateContentViews, selectCreateContentViewStatus, selectCreateContentViewError } from './ContentViewCreateSelectors';
@@ -25,6 +24,18 @@ const CreateContentViewForm = ({ setModalOpen }) => {
25
24
  const [redirect, setRedirect] = useState(false);
26
25
  const [saving, setSaving] = useState(false);
27
26
 
27
+ const [labelValidated, setLabelValidated] = useState('default');
28
+ const handleLabelChange = (newLabel, _event) => {
29
+ setLabel(newLabel);
30
+ if (newLabel === '') {
31
+ setLabelValidated('default');
32
+ } else if (/^[\w-]+$/.test(newLabel)) {
33
+ setLabelValidated('success');
34
+ } else {
35
+ setLabelValidated('error');
36
+ }
37
+ };
38
+
28
39
  const response = useSelector(selectCreateContentViews);
29
40
  const status = useSelector(selectCreateContentViewStatus);
30
41
  const error = useSelector(selectCreateContentViewError);
@@ -54,18 +65,17 @@ const CreateContentViewForm = ({ setModalOpen }) => {
54
65
 
55
66
  useEffect(
56
67
  () => {
57
- setLabel(name.replace(/ /g, '_'));
68
+ setLabel(name.replace(/[^A-Za-z0-9_-]/g, '_'));
58
69
  },
59
70
  [name],
60
71
  );
61
72
 
62
73
  if (redirect) {
63
74
  const { id } = response;
64
- if (composite) { return (<Redirect to={`/content_views/${id}#/contentviews`} />); }
65
- return (<Redirect to={`/content_views/${id}#/repositories`} />);
75
+ if (composite) { window.location.assign(`/content_views/${id}#/contentviews`); } else { window.location.assign(`/content_views/${id}#/repositories`); }
66
76
  }
67
77
 
68
- const submitDisabled = !name?.length || !label?.length || saving;
78
+ const submitDisabled = !name?.length || !label?.length || saving || redirect || labelValidated === 'error';
69
79
 
70
80
  return (
71
81
  <Form onSubmit={(e) => {
@@ -79,20 +89,29 @@ const CreateContentViewForm = ({ setModalOpen }) => {
79
89
  type="text"
80
90
  id="name"
81
91
  aria-label="input_name"
92
+ ouiaId="input_name"
82
93
  name="name"
83
94
  value={name}
84
95
  onChange={value => setName(value)}
85
96
  />
86
97
  </FormGroup>
87
- <FormGroup label={__('Label')} isRequired fieldId="label">
98
+ <FormGroup
99
+ label={__('Label')}
100
+ isRequired
101
+ fieldId="label"
102
+ helperTextInvalid="Must be Ascii alphanumeric, '_' or '-'"
103
+ validated={labelValidated}
104
+ >
88
105
  <TextInput
89
106
  isRequired
90
107
  type="text"
91
108
  id="label"
92
109
  aria-label="input_label"
110
+ ouiaId="input_label"
93
111
  name="label"
94
112
  value={label}
95
- onChange={value => setLabel(value)}
113
+ validated={labelValidated}
114
+ onChange={handleLabelChange}
96
115
  />
97
116
  </FormGroup>
98
117
  <FormGroup label={__('Description')} fieldId="description">
@@ -142,6 +161,7 @@ const CreateContentViewForm = ({ setModalOpen }) => {
142
161
  <FormGroup isInline fieldId="dependencies">
143
162
  <Checkbox
144
163
  id="dependencies"
164
+ ouiaId="dependencies"
145
165
  name="dependencies"
146
166
  label={LabelDependencies()}
147
167
  isChecked={dependencies}
@@ -152,6 +172,7 @@ const CreateContentViewForm = ({ setModalOpen }) => {
152
172
  <FormGroup isInline fieldId="importOnly">
153
173
  <Checkbox
154
174
  id="importOnly"
175
+ ouiaId="importOnly"
155
176
  name="importOnly"
156
177
  label={LabelImportOnly()}
157
178
  isChecked={importOnly}
@@ -162,6 +183,7 @@ const CreateContentViewForm = ({ setModalOpen }) => {
162
183
  <FormGroup isInline fieldId="autoPublish">
163
184
  <Checkbox
164
185
  id="autoPublish"
186
+ ouiaId="autoPublish"
165
187
  name="autoPublish"
166
188
  label={LabelAutoPublish()}
167
189
  isChecked={autoPublish}
@@ -174,6 +196,7 @@ const CreateContentViewForm = ({ setModalOpen }) => {
174
196
  aria-label="create_content_view"
175
197
  variant="primary"
176
198
  isDisabled={submitDisabled}
199
+ isLoading={saving || redirect}
177
200
  type="submit"
178
201
  >
179
202
  {__('Create content view')}
@@ -6,6 +6,7 @@ import CreateContentViewForm from './CreateContentViewForm';
6
6
 
7
7
  const CreateContentViewModal = ({ show, setIsOpen }) => (
8
8
  <Modal
9
+ ouiaId="create-content-view-modal"
9
10
  title={__('Create content view')}
10
11
  variant={ModalVariant.small}
11
12
  isOpen={show}
@@ -8,7 +8,14 @@ import cvCreateData from './contentViewCreateResult.fixtures.json';
8
8
 
9
9
  const cvCreatePath = api.getApiUrl('/content_views');
10
10
 
11
- const setModalOpen = jest.fn();
11
+ const mockFn = jest.fn();
12
+
13
+ delete window.location;
14
+ window.location = { assign: mockFn };
15
+
16
+ afterEach(() => {
17
+ mockFn.mockClear();
18
+ });
12
19
 
13
20
  const createDetails = {
14
21
  name: '1232123',
@@ -22,7 +29,7 @@ const createDetails = {
22
29
 
23
30
  const createdCVDetails = { ...cvCreateData };
24
31
 
25
- const form = <CreateContentViewForm setModalOpen={setModalOpen} />;
32
+ const form = <CreateContentViewForm setModalOpen={mockFn} />;
26
33
 
27
34
  test('Can save content view from form', async (done) => {
28
35
  const createscope = nockInstance
@@ -44,7 +51,7 @@ test('Form closes itself upon save', async (done) => {
44
51
  const createscope = nockInstance
45
52
  .post(cvCreatePath, createDetails)
46
53
  .reply(201, createdCVDetails);
47
- const { getByText, queryByText, getByLabelText } = renderWithRedux(form);
54
+ const { getByText, getByLabelText } = renderWithRedux(form);
48
55
  expect(getByText('Description')).toBeInTheDocument();
49
56
  expect(getByText('Name')).toBeInTheDocument();
50
57
  expect(getByText('Label')).toBeInTheDocument();
@@ -52,11 +59,11 @@ test('Form closes itself upon save', async (done) => {
52
59
  fireEvent.change(getByLabelText('input_name'), { target: { value: '1232123' } });
53
60
 
54
61
  await patientlyWaitFor(() => { expect(getByLabelText('input_label')).toHaveAttribute('value', '1232123'); });
55
-
62
+ jest.spyOn(window.location, 'assign');
56
63
  getByLabelText('create_content_view').click();
57
- // Form closes it self on success
64
+ // Form closes it self on success by calling location.assign()
58
65
  await patientlyWaitFor(() => {
59
- expect(queryByText('Description')).not.toBeInTheDocument();
66
+ expect(window.location.assign).toHaveBeenCalled();
60
67
  });
61
68
 
62
69
  assertNockRequest(createscope, done);
@@ -89,3 +96,11 @@ test('Displays dependent fields correctly', () => {
89
96
  expect(queryByText('Auto publish')).not.toBeInTheDocument();
90
97
  expect(getByText('Import only')).toBeInTheDocument();
91
98
  });
99
+
100
+ test('Validates label field', () => {
101
+ const { getByText, getByLabelText } = renderWithRedux(form);
102
+ expect(getByText('Label')).toBeInTheDocument();
103
+
104
+ fireEvent.change(getByLabelText('input_label'), { target: { value: '123 2123' } });
105
+ expect(getByText('Must be Ascii alphanumeric, \'_\' or \'-\'')).toBeInTheDocument();
106
+ });
@@ -64,9 +64,9 @@ const CVDeleteEnvironmentSelection = () => {
64
64
  isExpanded={versionExpanded[index]}
65
65
  >
66
66
  {(version?.environments.length !== 0) ?
67
- <TableComposable variant={TableVariant.compact}>
67
+ <TableComposable ouiaId="cv-delete-env-select-table" variant={TableVariant.compact}>
68
68
  <Thead>
69
- <Tr>
69
+ <Tr ouiaId="cv-delete-env-select-table-header">
70
70
  <Th />
71
71
  {columnHeaders.map(col =>
72
72
  <Th key={col}>{col}</Th>)}
@@ -78,7 +78,7 @@ const CVDeleteEnvironmentSelection = () => {
78
78
  id, name, activation_key_count: akCount, host_count: hostCount,
79
79
  } = env;
80
80
  return (
81
- <Tr key={`${name}_${id}`}>
81
+ <Tr ouiaId={`${name}_${id}`} key={`${name}_${id}`}>
82
82
  <Td
83
83
  key={`${name}__${id}_select`}
84
84
  select={{
@@ -93,6 +93,7 @@ const CVDeletionReassignActivationKeysForm = () => {
93
93
  id="selectCV"
94
94
  name="selectCV"
95
95
  aria-label="selectCV"
96
+ ouiaId="selectCV"
96
97
  placeholderText={(cvSelectOptions.length === 0) ? __('No content views available') : __('Select a content view')}
97
98
  >
98
99
  {cvSelectOptions}
@@ -94,6 +94,7 @@ const CVDeletionReassignHostsForm = () => {
94
94
  id="selectCV"
95
95
  name="selectCV"
96
96
  aria-label="selectCV"
97
+ ouiaId="selectCV"
97
98
  placeholderText={(cvSelectOptions.length === 0) ? __('No content views available') : __('Select a content view')}
98
99
  >
99
100
  {cvSelectOptions}
@@ -9,6 +9,8 @@
9
9
  "by": "name",
10
10
  "order": "asc"
11
11
  },
12
+ "can_create": true,
13
+ "can_view": true,
12
14
  "results": [
13
15
  {
14
16
  "composite": false,
@@ -90,6 +90,7 @@ const ComponentContentViewAddModal = ({
90
90
  title={componentId ? __('Update version') : __('Add content view')}
91
91
  variant={ModalVariant.small}
92
92
  isOpen={show}
93
+ ouiaId="add-update-cv-modal"
93
94
  description={__(`Select available version of ${cvName} to use`)}
94
95
  onClose={() => {
95
96
  setIsOpen(false);
@@ -109,6 +110,7 @@ const ComponentContentViewAddModal = ({
109
110
  id="horzontal-form-title"
110
111
  name="horizontal-form-title"
111
112
  aria-label="CvVersion"
113
+ ouiaId="select-cv-version"
112
114
  >
113
115
  {options.map((option, index) => (
114
116
  // eslint-disable-next-line react/no-array-index-key
@@ -119,6 +121,7 @@ const ComponentContentViewAddModal = ({
119
121
  <FormGroup fieldId="latest">
120
122
  <Flex style={{ display: 'inline-flex' }}>
121
123
  <Checkbox
124
+ ouiaId="latest"
122
125
  style={{ marginTop: 0 }}
123
126
  id="latest"
124
127
  name="latest"
@@ -53,6 +53,7 @@ const ComponentContentViewBulkAddModal = ({ cvId, rowsToAdd, onClose }) => {
53
53
  <Modal
54
54
  title={__('Add content views')}
55
55
  variant={ModalVariant.large}
56
+ ouiaId="add-content-views"
56
57
  isOpen
57
58
  description={__('Select available version of content views to use')}
58
59
  onClose={onClose}
@@ -64,12 +65,13 @@ const ComponentContentViewBulkAddModal = ({ cvId, rowsToAdd, onClose }) => {
64
65
  }}
65
66
  >
66
67
  {Object.keys(versionSelectOptions).sort().map(componentCvName => (
67
- <Card key={componentCvName}>
68
+ <Card ouiaId="componentCvName" key={componentCvName}>
68
69
  <CardTitle aria-label={componentCvName}>{componentCvName}</CardTitle>
69
70
  <CardBody>
70
71
  <FormGroup label={__('Version')} isRequired fieldId="version">
71
72
  <FormSelect
72
73
  value={selectedVersion[componentCvName]}
74
+ ouiaId="select-version"
73
75
  isDisabled={versionSelectOptions[componentCvName].length <= 1}
74
76
  onChange={value =>
75
77
  setSelectedVersion({ ...selectedVersion, ...{ [componentCvName]: value } })}
@@ -88,6 +90,7 @@ const ComponentContentViewBulkAddModal = ({ cvId, rowsToAdd, onClose }) => {
88
90
  <Checkbox
89
91
  style={{ marginTop: 0 }}
90
92
  id={`latest-${componentCvName}`}
93
+ ouiaId={`latest-${componentCvName}`}
91
94
  name="latest"
92
95
  label={__('Always update to latest version')}
93
96
  isChecked={selectedComponentLatest[componentCvName]}
@@ -27,7 +27,7 @@ const ComponentVersion = ({ componentCV }) => {
27
27
  {version ? `Version ${version}` : noVersionText}
28
28
  </a>
29
29
  <TextContent>
30
- <Text component={TextVariants.small}>
30
+ <Text ouiaId="version" component={TextVariants.small}>
31
31
  {latest ? latestDescription : manualVersionText}
32
32
  </Text>
33
33
  </TextContent>
@@ -211,7 +211,7 @@ const ContentViewComponents = ({ cvId, details }) => {
211
211
  ];
212
212
 
213
213
  const dropdownItems = [
214
- <DropdownItem aria-label="bulk_remove" key="bulk_remove" isDisabled={!(bulkRemoveEnabled())} component="button" onClick={removeBulk}>
214
+ <DropdownItem ouiaId="bulk-remove" aria-label="bulk_remove" key="bulk_remove" isDisabled={!(bulkRemoveEnabled())} component="button" onClick={removeBulk}>
215
215
  {__('Remove')}
216
216
  </DropdownItem>,
217
217
  ];
@@ -281,6 +281,7 @@ const ContentViewComponents = ({ cvId, details }) => {
281
281
  toggle={<KebabToggle aria-label="bulk_actions" onToggle={toggleBulkAction} />}
282
282
  isOpen={bulkActionOpen}
283
283
  isPlain
284
+ ouiaId="cv-components-bulk-actions"
284
285
  dropdownItems={dropdownItems}
285
286
  />
286
287
  </ActionListItem>
@@ -57,6 +57,7 @@ import {
57
57
  cvDebPackagesCompareKey,
58
58
  filesCompareKey,
59
59
  genericContentCompareKey,
60
+ cvRepositoriesCompareKey,
60
61
  } from '../ContentViewsConstants';
61
62
  import api, { foremanApi, orgId } from '../../../services/api';
62
63
  import { getResponseErrorMsgs } from '../../../utils/helpers';
@@ -99,6 +100,19 @@ export const getRPMPackagesComparison = (versionOne, versionTwo, viewBy, params)
99
100
  });
100
101
  };
101
102
 
103
+ export const getRepositoriesComparison = (versionOne, versionTwo, viewBy, params) => {
104
+ const versions = { content_view_version_ids: [versionOne, versionTwo] };
105
+ const restrictComparison = { restrict_comparison: viewBy };
106
+ const apiParams = { ...versions, ...restrictComparison, ...params };
107
+ const apiUrl = '/repositories/compare';
108
+ return get({
109
+ key: cvRepositoriesCompareKey(versionOne, versionTwo, viewBy),
110
+ params: apiParams,
111
+ errorToast: error => __(`Something went wrong while retrieving the repositories! ${getResponseErrorMsgs(error.response)}`),
112
+ url: api.getApiUrl(apiUrl),
113
+ });
114
+ };
115
+
102
116
  export const getPackageGroupsComparison = (versionOne, versionTwo, viewBy, params) => {
103
117
  const versions = { content_view_version_ids: [versionOne, versionTwo] };
104
118
  const restrictComparison = { restrict_comparison: viewBy };
@@ -44,7 +44,7 @@ import {
44
44
  cvDockerTagsCompareKey,
45
45
  cvDebPackagesCompareKey,
46
46
  filesCompareKey,
47
- genericContentCompareKey,
47
+ genericContentCompareKey, cvRepositoriesCompareKey,
48
48
  } from '../ContentViewsConstants';
49
49
 
50
50
  export const selectCVDetails = (state, cvId) =>
@@ -134,6 +134,16 @@ export const selectCVHistoriesStatus = (state, cvId) =>
134
134
  export const selectCVHistoriesError = (state, cvId) =>
135
135
  selectAPIError(state, cvDetailsHistoryKey(cvId));
136
136
 
137
+ export const selectRepositoriesComparison = (state, versionOne, versionTwo, viewBy) =>
138
+ selectAPIResponse(state, cvRepositoriesCompareKey(versionOne, versionTwo, viewBy)) || {};
139
+
140
+ export const selectRepositoriesComparisonStatus = (state, versionOne, versionTwo, viewBy) =>
141
+ selectAPIStatus(state, cvRepositoriesCompareKey(versionOne, versionTwo, viewBy)) ||
142
+ STATUS.PENDING;
143
+
144
+ export const selectRepositoriesComparisonError = (state, versionOne, versionTwo, viewBy) =>
145
+ selectAPIError(state, cvRepositoriesCompareKey(versionOne, versionTwo, viewBy));
146
+
137
147
  export const selectRPMPackagesComparison = (state, versionOne, versionTwo, viewBy) =>
138
148
  selectAPIResponse(state, cvRPMPackagesCompareKey(versionOne, versionTwo, viewBy)) || {};
139
149
 
@@ -149,7 +149,7 @@ export default () => {
149
149
  >
150
150
  <FlexItem>
151
151
  <TextContent>
152
- <Text component={TextVariants.h1}>
152
+ <Text ouiaId="cv-details-header-name" component={TextVariants.h1}>
153
153
  <ContentViewIcon count={name} composite={composite} />
154
154
  </Text>
155
155
  </TextContent>
@@ -117,6 +117,7 @@ const ContentViewInfo = ({ cvId, details }) => {
117
117
  <TextListItem component={TextListItemVariants.dd} className="foreman-spaced-list">
118
118
  <Switch
119
119
  id="import_only_switch"
120
+ ouiaId="import_only_switch"
120
121
  aria-label="import_only_switch"
121
122
  isChecked={importOnly}
122
123
  className="foreman-spaced-list"
@@ -129,6 +130,7 @@ const ContentViewInfo = ({ cvId, details }) => {
129
130
  <TextListItem component={TextListItemVariants.dd} className="foreman-spaced-list">
130
131
  <Switch
131
132
  id="generated_by_export_switch"
133
+ ouiaId="generated_by_export_switch"
132
134
  aria-label="generated_by_export_switch"
133
135
  isChecked={generatedContentView}
134
136
  className="foreman-spaced-list"
@@ -111,6 +111,7 @@ const CVFilterAddModal = ({ cvId, onClose }) => {
111
111
  title={__('Create filter')}
112
112
  variant={ModalVariant.large}
113
113
  isOpen
114
+ ouiaId="create-filter-modal"
114
115
  onClose={onClose}
115
116
  appendTo={document.body}
116
117
  >
@@ -125,6 +126,7 @@ const CVFilterAddModal = ({ cvId, onClose }) => {
125
126
  type="text"
126
127
  id="name"
127
128
  aria-label="input_name"
129
+ ouiaId="input_name"
128
130
  name="name"
129
131
  value={name}
130
132
  onChange={value => setName(value)}
@@ -136,6 +138,7 @@ const CVFilterAddModal = ({ cvId, onClose }) => {
136
138
  onSelect={onSelect}
137
139
  isOpen={typeSelectOpen}
138
140
  onToggle={setTypeSelectOpen}
141
+ ouiaId="content_type"
139
142
  id="content_type"
140
143
  name="content_type"
141
144
  aria-label="ContentType"
@@ -152,6 +155,7 @@ const CVFilterAddModal = ({ cvId, onClose }) => {
152
155
  onChange={checked => setInclusion(checked)}
153
156
  label={__('Include filter')}
154
157
  id="include_filter"
158
+ ouiaId="include_filter"
155
159
  value="includeFilter"
156
160
  style={{ margin: '1px' }}
157
161
  />
@@ -163,6 +167,7 @@ const CVFilterAddModal = ({ cvId, onClose }) => {
163
167
  onChange={checked => setInclusion(!checked)}
164
168
  label={__('Exclude filter')}
165
169
  id="exclude_filter"
170
+ ouiaId="exclude_filter"
166
171
  value="excludeFilter"
167
172
  style={{ margin: '1px' }}
168
173
  />
@@ -37,6 +37,7 @@ const AffectedRepositorySelection = ({
37
37
 
38
38
  return (
39
39
  <Select
40
+ ouiaId="affected-repos"
40
41
  selections={type}
41
42
  onSelect={onSelect}
42
43
  isOpen={typeSelectOpen}
@@ -34,6 +34,7 @@ export const ArtifactsWithNoErrataRenderer = ({ filterDetails }) => {
34
34
  };
35
35
 
36
36
  return (<Checkbox
37
+ ouiaId="artifactsNoErrata"
37
38
  id="artifactsNoErrata"
38
39
  name="artifactsNoErrata"
39
40
  label=<p style={{ marginTop: '4px' }}>{getLabel()}</p>
@@ -125,7 +125,12 @@ const CVContainerImageFilterContent = ({
125
125
  ];
126
126
 
127
127
  return (
128
- <Tabs className="margin-0-24" activeKey={activeTabKey} onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}>
128
+ <Tabs
129
+ className="margin-0-24"
130
+ activeKey={activeTabKey}
131
+ ouiaId="cv-container-image-filter-tabs"
132
+ onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
133
+ >
129
134
  <Tab eventKey={0} title={<TabTitleText>{__('Tags')}</TabTitleText>}>
130
135
  <div className="margin-24-0">
131
136
  <TableWrapper
@@ -167,9 +172,10 @@ const CVContainerImageFilterContent = ({
167
172
  <Dropdown
168
173
  toggle={<KebabToggle aria-label="bulk_actions" onToggle={toggleBulkAction} />}
169
174
  isOpen={bulkActionOpen}
175
+ ouiaId="cv-container-image-bulk-actions"
170
176
  isPlain
171
177
  dropdownItems={[
172
- <DropdownItem aria-label="bulk_remove" key="bulk_remove" isDisabled={!hasSelected} component="button" onClick={bulkRemove}>
178
+ <DropdownItem ouiaId="cv-container-image-bulk-remove" aria-label="bulk_remove" key="bulk_remove" isDisabled={!hasSelected} component="button" onClick={bulkRemove}>
173
179
  {__('Remove')}
174
180
  </DropdownItem>]
175
181
  }
@@ -145,7 +145,11 @@ const CVDebFilterContent = ({
145
145
  };
146
146
 
147
147
  return (
148
- <Tabs activeKey={activeTabKey} onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}>
148
+ <Tabs
149
+ ouiaId="cv-deb-filter-content-tabs"
150
+ activeKey={activeTabKey}
151
+ onSelect={(_event, eventKey) => setActiveTabKey(eventKey)}
152
+ >
149
153
  <Tab eventKey={0} title={<TabTitleText>{tabTitle}</TabTitleText>}>
150
154
  <div className="tab-body-with-spacing">
151
155
  <TableWrapper