katello 4.3.0 → 4.4.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 (337) 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/api_controller.rb +13 -4
  4. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +3 -0
  5. data/app/controllers/katello/api/v2/content_views_controller.rb +46 -0
  6. data/app/controllers/katello/api/v2/host_packages_controller.rb +21 -1
  7. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +30 -1
  8. data/app/controllers/katello/api/v2/organizations_controller.rb +10 -6
  9. data/app/controllers/katello/api/v2/packages_controller.rb +4 -0
  10. data/app/controllers/katello/api/v2/repositories_controller.rb +17 -7
  11. data/app/controllers/katello/api/v2/repository_sets_controller.rb +7 -0
  12. data/app/controllers/katello/concerns/api/v2/repository_content_controller.rb +3 -0
  13. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +32 -0
  14. data/app/controllers/katello/remote_execution_controller.rb +5 -4
  15. data/app/helpers/katello/content_source_helper.rb +43 -0
  16. data/app/helpers/katello/hosts_and_hostgroups_helper.rb +4 -0
  17. data/app/lib/actions/katello/cdn_configuration/update.rb +5 -7
  18. data/app/lib/actions/katello/content_view/publish.rb +5 -0
  19. data/app/lib/actions/katello/content_view_version/incremental_update.rb +17 -3
  20. data/app/lib/actions/katello/repository/discover.rb +1 -14
  21. data/app/lib/actions/katello/repository/filtered_index_content.rb +1 -1
  22. data/app/lib/actions/pulp3/content_view_version/import.rb +7 -0
  23. data/app/lib/actions/pulp3/orchestration/content_view_version/import.rb +7 -5
  24. data/app/lib/actions/pulp3/repository/copy_content.rb +1 -1
  25. data/app/lib/actions/pulp3/repository/save_artifact.rb +1 -0
  26. data/app/lib/katello/concerns/base_template_scope_extensions.rb +11 -0
  27. data/app/lib/katello/errors.rb +3 -3
  28. data/app/lib/katello/logging.rb +6 -1
  29. data/app/lib/katello/repo_discovery.rb +27 -19
  30. data/app/lib/katello/resources/cdn/katello_cdn.rb +41 -3
  31. data/app/lib/katello/resources/cdn.rb +4 -2
  32. data/app/lib/katello/util/deduplication_migrator.rb +105 -0
  33. data/app/models/katello/candlepin/repository_mapper.rb +1 -1
  34. data/app/models/katello/cdn_configuration.rb +38 -6
  35. data/app/models/katello/concerns/host_managed_extensions.rb +23 -1
  36. data/app/models/katello/concerns/organization_extensions.rb +5 -1
  37. data/app/models/katello/concerns/pulp_database_unit.rb +59 -173
  38. data/app/models/katello/concerns/remote_execution_proxy_selector_extensions.rb +11 -0
  39. data/app/models/katello/concerns/smart_proxy_extensions.rb +1 -1
  40. data/app/models/katello/content_view.rb +4 -4
  41. data/app/models/katello/content_view_filter.rb +1 -1
  42. data/app/models/katello/content_view_history.rb +1 -1
  43. data/app/models/katello/content_view_version.rb +6 -2
  44. data/app/models/katello/content_view_version_export_history.rb +1 -1
  45. data/app/models/katello/deb.rb +1 -3
  46. data/app/models/katello/docker_meta_tag.rb +1 -1
  47. data/app/models/katello/erratum.rb +0 -15
  48. data/app/models/katello/glue/pulp/repos.rb +1 -1
  49. data/app/models/katello/host/content_facet.rb +2 -27
  50. data/app/models/katello/host/info_provider.rb +9 -0
  51. data/app/models/katello/host/subscription_facet.rb +2 -2
  52. data/app/models/katello/hostgroup/content_facet.rb +2 -2
  53. data/app/models/katello/product.rb +1 -1
  54. data/app/models/katello/product_content.rb +2 -2
  55. data/app/models/katello/repository.rb +10 -9
  56. data/app/models/katello/root_repository.rb +24 -13
  57. data/app/models/katello/rpm.rb +8 -2
  58. data/app/models/setting/content.rb +6 -3
  59. data/app/services/cert/rhsm_client.rb +1 -5
  60. data/app/services/katello/content_unit_indexer.rb +166 -0
  61. data/app/services/katello/organization_creator.rb +12 -4
  62. data/app/services/katello/pulp/repository/docker.rb +1 -1
  63. data/app/services/katello/pulp/repository/yum.rb +0 -54
  64. data/app/services/katello/pulp/repository.rb +0 -6
  65. data/app/services/katello/pulp3/ansible_collection.rb +26 -10
  66. data/app/services/katello/pulp3/api/apt.rb +7 -0
  67. data/app/services/katello/pulp3/content_view_version/import.rb +11 -2
  68. data/app/services/katello/pulp3/deb.rb +10 -9
  69. data/app/services/katello/pulp3/docker_manifest.rb +6 -5
  70. data/app/services/katello/pulp3/docker_manifest_list.rb +23 -6
  71. data/app/services/katello/pulp3/docker_tag.rb +16 -7
  72. data/app/services/katello/pulp3/erratum.rb +51 -56
  73. data/app/services/katello/pulp3/file_unit.rb +9 -6
  74. data/app/services/katello/pulp3/generic_content_unit.rb +11 -12
  75. data/app/services/katello/pulp3/module_stream.rb +76 -30
  76. data/app/services/katello/pulp3/package_group.rb +5 -5
  77. data/app/services/katello/pulp3/pulp_content_unit.rb +19 -11
  78. data/app/services/katello/pulp3/repository/apt.rb +5 -3
  79. data/app/services/katello/pulp3/repository/docker.rb +14 -7
  80. data/app/services/katello/pulp3/repository/generic.rb +1 -1
  81. data/app/services/katello/pulp3/repository/yum.rb +10 -12
  82. data/app/services/katello/pulp3/repository.rb +26 -7
  83. data/app/services/katello/pulp3/repository_mirror.rb +18 -5
  84. data/app/services/katello/pulp3/rpm.rb +13 -13
  85. data/app/services/katello/pulp3/srpm.rb +10 -9
  86. data/app/services/katello/repository_type.rb +15 -4
  87. data/app/services/katello/repository_type_manager.rb +1 -1
  88. data/app/services/katello/ui_notifications/subscriptions/manifest_expired_warning.rb +1 -1
  89. data/app/services/katello/upstream_connection_checker.rb +2 -2
  90. data/app/views/foreman/job_templates/change_content_source.erb +1 -31
  91. data/app/views/foreman/job_templates/install_errata.erb +6 -9
  92. data/app/views/foreman/job_templates/install_errata_by_search_query.erb +26 -0
  93. data/app/views/foreman/job_templates/install_packages_by_search_query.erb +19 -0
  94. data/app/views/katello/api/v2/cdn_configurations/show.json.rabl +1 -1
  95. data/app/views/katello/api/v2/environments/show.json.rabl +9 -0
  96. data/app/views/katello/api/v2/repositories/show.json.rabl +2 -0
  97. data/app/views/katello/layouts/react.html.erb +0 -1
  98. data/app/views/katello/sync_management/_repo.html.erb +36 -25
  99. data/config/initializers/monkeys.rb +0 -1
  100. data/config/routes/api/v2.rb +1 -0
  101. data/config/routes/overrides.rb +3 -0
  102. data/config/routes.rb +2 -0
  103. data/db/migrate/20150930183738_migrate_content_hosts.rb +1 -1
  104. data/db/migrate/20180612164926_add_content_org_id.rb +2 -2
  105. data/db/migrate/20211201154845_add_unique_indexes.rb +20 -0
  106. data/db/migrate/20211208034230_add_content_view_and_lifecycle_environment.rb +6 -0
  107. data/db/migrate/20211220185935_clean_duplicate_content_units.rb +144 -0
  108. data/db/migrate/20220110223754_update_disconnected_settings.rb +20 -0
  109. data/db/migrate/20220120163252_fix_docker_download_policy.rb +11 -0
  110. data/db/migrate/20220124191056_add_type_to_cdn_configuration.rb +22 -0
  111. data/db/migrate/20220127120843_fix_debian_download_policy.rb +11 -0
  112. data/db/migrate/20220204171908_rename_docker_tags_whitelist_and_add_exclude_tags.rb +8 -0
  113. data/db/migrate/20220207140355_change_deb_attributes_size_limit.rb +7 -0
  114. data/db/seeds.d/111-upgrade_tasks.rb +2 -1
  115. data/engines/bastion/app/views/bastion/layouts/application.html.erb +0 -1
  116. data/engines/bastion/app/views/bastion/layouts/assets.html.erb +0 -1
  117. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credentials.controller.js +1 -1
  118. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-products.controller.js +1 -1
  119. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-repositories.controller.js +1 -1
  120. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-traces-modal.html +1 -1
  121. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment.html +26 -1
  122. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +212 -152
  123. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/packages.controller.js +1 -0
  124. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.controller.js +20 -8
  125. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-manage-content.controller.js +2 -3
  126. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +8 -3
  127. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +34 -30
  128. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +16 -2
  129. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +35 -15
  130. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery.controller.js +5 -4
  131. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.routes.js +4 -3
  132. data/lib/katello/engine.rb +4 -0
  133. data/lib/katello/permission_creator.rb +1 -1
  134. data/lib/katello/permissions/host_permissions.rb +3 -1
  135. data/lib/katello/plugin.rb +4 -1
  136. data/lib/katello/repository_types/deb.rb +0 -1
  137. data/lib/katello/repository_types/docker.rb +4 -4
  138. data/lib/katello/repository_types/file.rb +0 -1
  139. data/lib/katello/repository_types/ostree.rb +4 -0
  140. data/lib/katello/repository_types/python.rb +5 -1
  141. data/lib/katello/repository_types/yum.rb +2 -9
  142. data/lib/katello/tasks/content_view_import_only.rake +34 -0
  143. data/lib/katello/tasks/import_applicability.rake +1 -1
  144. data/lib/katello/tasks/jenkins.rake +0 -2
  145. data/lib/katello/tasks/repository.rake +4 -1
  146. data/lib/katello/tasks/upgrades/4.4/publish_import_cvvs.rake +17 -0
  147. data/lib/katello/version.rb +1 -1
  148. data/locale/action_names.rb +8 -7
  149. data/locale/bn/katello.po +1402 -650
  150. data/locale/cs/katello.po +1217 -96
  151. data/locale/de/katello.po +2359 -1347
  152. data/locale/en/katello.po +1216 -94
  153. data/locale/es/katello.po +2201 -1172
  154. data/locale/fr/katello.po +2601 -1615
  155. data/locale/gu/katello.po +1564 -814
  156. data/locale/hi/katello.po +1563 -810
  157. data/locale/it/katello.po +1311 -282
  158. data/locale/ja/katello.po +2534 -1518
  159. data/locale/katello.pot +3430 -1326
  160. data/locale/kn/katello.po +1564 -812
  161. data/locale/ko/katello.po +1441 -409
  162. data/locale/mr/katello.po +1564 -776
  163. data/locale/or/katello.po +1565 -813
  164. data/locale/pa/katello.po +1559 -792
  165. data/locale/pt/katello.po +1314 -277
  166. data/locale/pt_BR/katello.po +2226 -1181
  167. data/locale/ru/katello.po +1587 -563
  168. data/locale/ta/katello.po +1373 -619
  169. data/locale/te/katello.po +1564 -810
  170. data/locale/zh_CN/katello.po +2936 -1890
  171. data/locale/zh_TW/katello.po +1508 -606
  172. data/webpack/__mocks__/foremanReact/{redux/actions/toasts.js → components/ToastsList/index.js} +3 -2
  173. data/webpack/components/ActionableDetail.js +35 -21
  174. data/webpack/components/Content/Details/__tests__/ContentDetailInfo.test.js +0 -2
  175. data/webpack/components/Content/Details/__tests__/ContentDetailRepositories.test.js +0 -2
  176. data/webpack/components/Content/Details/__tests__/ContentDetails.test.js +0 -2
  177. data/webpack/components/Content/__tests__/ContentPage.test.js +0 -2
  178. data/webpack/components/Content/__tests__/ContentTable.test.js +0 -2
  179. data/webpack/components/EditableSwitch.js +8 -2
  180. data/webpack/components/EditableTextInput/EditableTextInput.js +44 -86
  181. data/webpack/components/EditableTextInput/__tests__/editableTextInput.test.js +3 -3
  182. data/webpack/components/Errata/index.js +19 -11
  183. data/webpack/components/Packages/index.js +1 -1
  184. data/webpack/components/Search/Search.js +5 -2
  185. data/webpack/components/Search/__tests__/search.test.js +2 -3
  186. data/webpack/components/SelectOrg/SetOrganization.js +1 -1
  187. data/webpack/components/Table/PageControls.js +3 -6
  188. data/webpack/components/Table/TableHooks.js +46 -7
  189. data/webpack/components/Table/TableWrapper.js +14 -3
  190. data/webpack/components/TypeAhead/TypeAhead.js +5 -1
  191. data/webpack/components/TypeAhead/pf4Search/TypeAheadInput.js +4 -1
  192. data/webpack/components/TypeAhead/pf4Search/TypeAheadSearch.js +2 -1
  193. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard.js +1 -1
  194. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.js +3 -4
  195. data/webpack/components/extensions/HostDetails/HostDetailsActions.js +2 -0
  196. data/webpack/components/extensions/HostDetails/HostPackages/HostPackagesActions.js +18 -2
  197. data/webpack/components/extensions/HostDetails/HostPackages/HostPackagesConstants.js +12 -0
  198. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/SecondaryTabsRoutes.js +1 -1
  199. data/webpack/components/extensions/HostDetails/Tabs/{ErrataTab.js → ErrataTab/ErrataTab.js} +30 -21
  200. data/webpack/components/extensions/HostDetails/Tabs/{ErrataTab.scss → ErrataTab/ErrataTab.scss} +0 -0
  201. data/webpack/components/extensions/HostDetails/Tabs/{ErratumExpansionContents.js → ErrataTab/ErratumExpansionContents.js} +0 -0
  202. data/webpack/components/extensions/HostDetails/Tabs/{ErratumExpansionDetail.js → ErrataTab/ErratumExpansionDetail.js} +0 -0
  203. data/webpack/components/extensions/HostDetails/{HostErrata → Tabs/ErrataTab}/HostErrataActions.js +3 -3
  204. data/webpack/components/extensions/HostDetails/{HostErrata → Tabs/ErrataTab}/HostErrataConstants.js +11 -0
  205. data/webpack/components/extensions/HostDetails/{HostErrata → Tabs/ErrataTab}/HostErrataSelectors.js +0 -0
  206. data/webpack/components/extensions/HostDetails/Tabs/PackageInstallModal.js +279 -0
  207. data/webpack/components/extensions/HostDetails/Tabs/PackageInstallModal.scss +3 -0
  208. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab.js +125 -8
  209. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +27 -4
  210. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionConstants.js +2 -1
  211. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +6 -3
  212. data/webpack/components/extensions/HostDetails/Tabs/{EnableTracerEmptyState.js → TracesTab/EnableTracerEmptyState.js} +0 -0
  213. data/webpack/components/extensions/HostDetails/Tabs/{EnableTracerModal.js → TracesTab/EnableTracerModal.js} +3 -2
  214. data/webpack/components/extensions/HostDetails/Tabs/{HostTracesActions.js → TracesTab/HostTracesActions.js} +2 -2
  215. data/webpack/components/extensions/HostDetails/Tabs/{HostTracesConstants.js → TracesTab/HostTracesConstants.js} +0 -0
  216. data/webpack/components/extensions/HostDetails/Tabs/{HostTracesSelectors.js → TracesTab/HostTracesSelectors.js} +0 -0
  217. data/webpack/components/extensions/HostDetails/Tabs/{TracesTab.js → TracesTab/TracesTab.js} +8 -5
  218. data/webpack/components/extensions/HostDetails/Tabs/{TracesTab.scss → TracesTab/TracesTab.scss} +0 -0
  219. data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +17 -18
  220. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packageInstallModal.test.js +385 -0
  221. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packages.fixtures.json +1 -1
  222. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +58 -7
  223. data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySetsTab.test.js +2 -2
  224. data/webpack/components/extensions/HostDetails/Tabs/__tests__/tracesTab.test.js +4 -4
  225. data/webpack/components/extensions/HostDetails/Tabs/__tests__/yumInstallablePackages.fixtures.json +72 -0
  226. data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +12 -5
  227. data/webpack/components/extensions/HostDetails/YumInstallablePackages/YumInstallablePackagesActions.js +18 -0
  228. data/webpack/components/extensions/HostDetails/YumInstallablePackages/YumInstallablePackagesConstants.js +3 -0
  229. data/webpack/components/extensions/HostDetails/YumInstallablePackages/YumInstallablePackagesSelectors.js +16 -0
  230. data/webpack/components/extensions/HostDetails/hostDetailsHelpers.js +19 -0
  231. data/webpack/components/pf3Table/components/Table.js +2 -3
  232. data/webpack/components/pf3Table/components/Table.test.js +0 -3
  233. data/webpack/components/pf3Table/components/__snapshots__/Table.test.js.snap +9 -8
  234. data/webpack/containers/Application/config.js +5 -0
  235. data/webpack/global_index.js +1 -1
  236. data/webpack/global_test_setup.js +1 -1
  237. data/webpack/index.js +7 -0
  238. data/webpack/scenes/AnsibleCollections/Details/__tests__/AnsibleCollectionDetails.test.js +0 -2
  239. data/webpack/scenes/AnsibleCollections/__tests__/AnsibleCollectionPage.test.js +0 -2
  240. data/webpack/scenes/AnsibleCollections/__tests__/AnsibleCollectionsTable.test.js +0 -2
  241. data/webpack/scenes/Content/ContentConfig.js +55 -5
  242. data/webpack/scenes/Content/ContentPage.js +1 -1
  243. data/webpack/scenes/Content/Details/ContentDetails.js +1 -1
  244. data/webpack/scenes/Content/Details/ContentInfo.js +1 -1
  245. data/webpack/scenes/Content/Details/ContentRepositories.js +1 -1
  246. data/webpack/scenes/Content/Details/__tests__/contentDetail.test.js +4 -4
  247. data/webpack/scenes/Content/Table/ContentTable.js +1 -1
  248. data/webpack/scenes/Content/__tests__/contentTable.test.js +3 -3
  249. data/webpack/scenes/ContentViews/ContentViewsConstants.js +2 -1
  250. data/webpack/scenes/ContentViews/Delete/__tests__/contentViewDelete.test.js +6 -6
  251. data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/contentViewComponents.test.js +2 -2
  252. data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +21 -27
  253. data/webpack/scenes/ContentViews/Details/ContentViewDetailSelectors.js +5 -5
  254. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +8 -3
  255. data/webpack/scenes/ContentViews/Details/DetailsContainer.js +11 -16
  256. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilterDetails.js +2 -2
  257. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilterDetailsHeader.js +14 -8
  258. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/__tests__/CVRpmMatchContentModal.test.js +2 -2
  259. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVContainerImageFilterContent.test.js +2 -3
  260. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVRpmFilterContent.test.js +2 -9
  261. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilterDetails.test.js +3 -5
  262. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilters.test.js +2 -10
  263. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvErrataIDFilter.test.js +2 -3
  264. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvModuleStreamFilter.test.js +2 -3
  265. data/webpack/scenes/ContentViews/Details/Histories/__tests__/contentViewHistory.test.js +2 -2
  266. data/webpack/scenes/ContentViews/Details/Repositories/ContentCounts.js +1 -1
  267. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +23 -2
  268. data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewAddRemove.test.js +11 -5
  269. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionContent.js +16 -17
  270. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +1 -1
  271. data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/cvVersionRemove.test.js +6 -6
  272. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailConfig.js +30 -34
  273. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetails.js +9 -8
  274. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsHeader.js +13 -15
  275. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionRepositoryCell.js +1 -1
  276. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetails.test.js +4 -4
  277. data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersions.test.js +3 -3
  278. data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetail.test.js +5 -3
  279. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +2 -2
  280. data/webpack/scenes/Hosts/ChangeContentSource/actions.js +43 -0
  281. data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceForm.js +87 -0
  282. data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceTemplate.js +90 -0
  283. data/webpack/scenes/Hosts/ChangeContentSource/components/FormField.js +43 -0
  284. data/webpack/scenes/Hosts/ChangeContentSource/constants.js +3 -0
  285. data/webpack/scenes/Hosts/ChangeContentSource/helpers.js +27 -0
  286. data/webpack/scenes/Hosts/ChangeContentSource/index.js +126 -0
  287. data/webpack/scenes/Hosts/ChangeContentSource/selectors.js +42 -0
  288. data/webpack/scenes/Hosts/ChangeContentSource/styles.scss +11 -0
  289. data/webpack/scenes/ModuleStreams/Details/Profiles/__tests__/ModuleStreamDetailProfiles.test.js +0 -1
  290. data/webpack/scenes/ModuleStreams/Details/__tests__/ModuleStreamDetails.test.js +0 -2
  291. data/webpack/scenes/ModuleStreams/__tests__/ModuleStreamPage.test.js +0 -2
  292. data/webpack/scenes/ModuleStreams/__tests__/ModuleStreamsTable.test.js +0 -2
  293. data/webpack/scenes/Organizations/OrganizationActions.js +5 -1
  294. data/webpack/scenes/RedHatRepositories/RedHatRepositoriesPage.js +31 -1
  295. data/webpack/scenes/RedHatRepositories/__tests__/RedHatRepositoriesPage.test.js +16 -0
  296. data/webpack/scenes/RedHatRepositories/__tests__/__snapshots__/RedHatRepositoriesPage.test.js.snap +11 -2
  297. data/webpack/scenes/RedHatRepositories/helpers.js +5 -5
  298. data/webpack/scenes/RedHatRepositories/index.js +11 -3
  299. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/AirGappedTypeForm.js +81 -0
  300. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnConfigurationConstants.js +13 -0
  301. data/webpack/scenes/Subscriptions/Manifest/{CdnConfigurationForm.scss → CdnConfigurationTab/CdnConfigurationForm.scss} +0 -0
  302. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnTypeForm.js +106 -0
  303. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/UpstreamServerTypeForm.js +259 -0
  304. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/AirGappedTypeForm.test.js +44 -0
  305. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/CdnTypeForm.test.js +67 -0
  306. data/webpack/scenes/Subscriptions/Manifest/{__tests__/CdnConfigurationForm.test.js → CdnConfigurationTab/__tests__/UpstreamServerTypeForm.test.js} +46 -17
  307. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/index.js +97 -0
  308. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +6 -1
  309. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsPage.test.js +0 -1
  310. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +0 -1
  311. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap +3 -2
  312. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js +4 -0
  313. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +9 -0
  314. data/webpack/scenes/Tasks/TaskActions.js +1 -1
  315. data/webpack/scenes/Tasks/__tests__/__snapshots__/TaskActions.test.js.snap +3 -2
  316. data/webpack/services/api/testHelpers.js +5 -3
  317. data/webpack/utils/helpers.js +6 -3
  318. metadata +81 -58
  319. data/app/services/katello/pulp/deb.rb +0 -55
  320. data/app/services/katello/pulp/distribution.rb +0 -7
  321. data/app/services/katello/pulp/docker_blob.rb +0 -7
  322. data/app/services/katello/pulp/docker_manifest.rb +0 -13
  323. data/app/services/katello/pulp/docker_manifest_list.rb +0 -14
  324. data/app/services/katello/pulp/docker_tag.rb +0 -14
  325. data/app/services/katello/pulp/erratum.rb +0 -129
  326. data/app/services/katello/pulp/file_unit.rb +0 -21
  327. data/app/services/katello/pulp/module_stream.rb +0 -39
  328. data/app/services/katello/pulp/package_category.rb +0 -7
  329. data/app/services/katello/pulp/package_group.rb +0 -20
  330. data/app/services/katello/pulp/pulp_content_unit.rb +0 -156
  331. data/app/services/katello/pulp/rpm.rb +0 -57
  332. data/app/services/katello/pulp/srpm.rb +0 -29
  333. data/app/services/katello/pulp/yum_metadata_file.rb +0 -30
  334. data/lib/monkeys/pulp3_13_checksumfix.rb +0 -17
  335. data/webpack/__mocks__/foremanReact/components/Pagination/PaginationHooks.js +0 -2
  336. data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +0 -2
  337. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationForm.js +0 -185
@@ -1,6 +1,6 @@
1
1
  import { API_OPERATIONS, APIActions, get, put, post } from 'foremanReact/redux/API';
2
- import { addToast } from 'foremanReact/redux/actions/toasts';
3
2
  import { translate as __ } from 'foremanReact/common/I18n';
3
+ import { lowerCase } from 'lodash';
4
4
  import {
5
5
  RPM_PACKAGES_CONTENT,
6
6
  RPM_PACKAGE_GROUPS_CONTENT,
@@ -45,11 +45,11 @@ import {
45
45
  ERRATA_CONTENT,
46
46
  MODULE_STREAMS_CONTENT,
47
47
  DEB_PACKAGES_CONTENT,
48
- ANSIBLE_COLLECTIONS_CONTENT,
49
48
  DOCKER_TAGS_CONTENT,
49
+ generatedContentKey,
50
50
  } from '../ContentViewsConstants';
51
51
  import api, { foremanApi, orgId } from '../../../services/api';
52
- import { getResponseErrorMsgs, apiError } from '../../../utils/helpers';
52
+ import { getResponseErrorMsgs } from '../../../utils/helpers';
53
53
  import { renderTaskStartedToast } from '../../Tasks/helpers';
54
54
  import { cvErrorToast } from '../ContentViewsActions';
55
55
 
@@ -60,15 +60,13 @@ const getContentViewDetails = (cvId, extraParams = {}) => get({
60
60
  url: api.getApiUrl(`/content_views/${cvId}`),
61
61
  });
62
62
 
63
- const cvUpdateSuccess = (response, dispatch) => {
64
- const { data: { id } } = response;
65
- // Update CV info in redux with the updated CV info from API
66
- dispatch(getContentViewDetails(id));
67
- return dispatch(addToast({
68
- type: 'success',
69
- message: __(' Content view updated'),
70
- }));
71
- };
63
+ export const getContent = (pluralLabel, params) => get({
64
+ type: API_OPERATIONS.GET,
65
+ key: generatedContentKey(pluralLabel),
66
+ url: api.getApiUrl(`/${pluralLabel}`),
67
+ params,
68
+ errorToast: error => __(`Something went wrong while fetching ${lowerCase(pluralLabel)}! ${getResponseErrorMsgs(error.response)}`),
69
+ });
72
70
 
73
71
  export const getRPMPackages = params => get({
74
72
  type: API_OPERATIONS.GET,
@@ -86,19 +84,21 @@ export const getFiles = params => get({
86
84
  errorToast: error => __(`Something went wrong while fetching files! ${getResponseErrorMsgs(error.response)}`),
87
85
  });
88
86
 
89
- export const updateContentView = (cvId, params) => dispatch => dispatch(put({
87
+ export const updateContentView = (cvId, params, handleSuccess) => put({
90
88
  type: API_OPERATIONS.PUT,
91
89
  key: cvDetailsKey(cvId),
92
90
  url: api.getApiUrl(`/content_views/${cvId}`),
93
- params,
94
- handleSuccess: response => cvUpdateSuccess(response, dispatch),
95
- handleError: error => dispatch(apiError(null, error)),
91
+ handleSuccess,
92
+ params: { include_permissions: true, ...params },
93
+ successToast: () => __(' Content view updated'),
94
+ errorToast: error => getResponseErrorMsgs(error.response),
95
+ updateData: (_prevState, respState) => respState,
96
96
  actionTypes: {
97
97
  REQUEST: UPDATE_CONTENT_VIEW,
98
98
  SUCCESS: UPDATE_CONTENT_VIEW_SUCCESS,
99
99
  FAILURE: UPDATE_CONTENT_VIEW_FAILURE,
100
100
  },
101
- }));
101
+ });
102
102
 
103
103
  export const addComponent = params => put({
104
104
  type: API_OPERATIONS.PUT,
@@ -135,14 +135,6 @@ export const getDockerTags = params => get({
135
135
  errorToast: error => __(`Something went wrong while getting docker tags! ${getResponseErrorMsgs(error.response)}`),
136
136
  });
137
137
 
138
- export const getAnsibleCollections = params => get({
139
- type: API_OPERATIONS.GET,
140
- key: ANSIBLE_COLLECTIONS_CONTENT,
141
- url: api.getApiUrl('/ansible_collections'),
142
- params,
143
- errorToast: error => __(`Something went wrong while getting ansible collections! ${getResponseErrorMsgs(error.response)}`),
144
- });
145
-
146
138
  export const getErrata = params => get({
147
139
  type: API_OPERATIONS.GET,
148
140
  key: ERRATA_CONTENT,
@@ -176,7 +168,7 @@ export const getRepositories = params => get({
176
168
  });
177
169
 
178
170
  export const getContentViewRepositories = (cvId, params, status) => {
179
- const apiParams = { ...params };
171
+ const apiParams = { organization_id: orgId(), ...params };
180
172
  let apiUrl = `/content_views/${cvId}/repositories`;
181
173
 
182
174
  if (status === ALL_STATUSES) {
@@ -205,12 +197,13 @@ export const getFilterRepositories = (cvId, filterId, params) => {
205
197
  });
206
198
  };
207
199
 
208
- export const editCVFilter = (filterId, params, handleSuccess) => put({
200
+ export const editCVFilter = (filterId, params, handleSuccess, handleError) => put({
209
201
  type: API_OPERATIONS.PUT,
210
202
  key: EDIT_CONTENT_VIEW_FILTER,
211
203
  url: api.getApiUrl(`/content_view_filters/${filterId}`),
212
204
  params,
213
205
  handleSuccess,
206
+ handleError,
214
207
  successToast: () => __('Filter edited'),
215
208
  errorToast: error => __(`Something went wrong while editing the filter! ${getResponseErrorMsgs(error.response)}`),
216
209
  });
@@ -416,6 +409,7 @@ export const editContentViewVersionDetails = (versionId, cvId, params, handleSuc
416
409
  url: api.getApiUrl(`/content_view_versions/${versionId}`),
417
410
  params,
418
411
  handleSuccess,
412
+ successToast: () => __('Version details updated.'),
419
413
  errorToast: error => __(`Something went wrong while editing version details. ${getResponseErrorMsgs(error.response)}`),
420
414
  });
421
415
 
@@ -33,8 +33,8 @@ import {
33
33
  ERRATA_CONTENT,
34
34
  MODULE_STREAMS_CONTENT,
35
35
  DEB_PACKAGES_CONTENT,
36
- ANSIBLE_COLLECTIONS_CONTENT,
37
36
  DOCKER_TAGS_CONTENT,
37
+ generatedContentKey,
38
38
  } from '../ContentViewsConstants';
39
39
  import { pollTaskKey } from '../../Tasks/helpers';
40
40
 
@@ -131,11 +131,11 @@ export const selectCVFilterRules = (state, filterId) =>
131
131
  export const selectCVFilterRulesStatus = (state, filterId) =>
132
132
  selectAPIStatus(state, cvFilterRulesKey(filterId)) || STATUS.PENDING;
133
133
 
134
- export const selectAnsibleCollections = state =>
135
- selectAPIResponse(state, ANSIBLE_COLLECTIONS_CONTENT);
134
+ export const selectContent = (pluralLabel, state) =>
135
+ selectAPIResponse(state, generatedContentKey(pluralLabel));
136
136
 
137
- export const selectAnsibleCollectionsStatus = state =>
138
- selectAPIStatus(state, ANSIBLE_COLLECTIONS_CONTENT) || STATUS.PENDING;
137
+ export const selectContentStatus = (pluralLabel, state) =>
138
+ selectAPIStatus(state, generatedContentKey(pluralLabel)) || STATUS.PENDING;
139
139
 
140
140
  export const selectDockerTags = state =>
141
141
  selectAPIResponse(state, DOCKER_TAGS_CONTENT);
@@ -15,7 +15,6 @@ import { translate as __ } from 'foremanReact/common/I18n';
15
15
 
16
16
  import { updateContentView } from './ContentViewDetailActions';
17
17
  import { selectIsCVUpdating } from './ContentViewDetailSelectors';
18
- import Loading from '../../../components/Loading';
19
18
  import ContentViewIcon from '../components/ContentViewIcon';
20
19
  import ActionableDetail from '../../../components/ActionableDetail';
21
20
  import './contentViewInfo.scss';
@@ -37,8 +36,6 @@ const ContentViewInfo = ({ cvId, details }) => {
37
36
  permissions,
38
37
  } = details;
39
38
 
40
- if (updating) return <Loading size="sm" showText={false} />;
41
-
42
39
  const onEdit = (val, attribute) => {
43
40
  if (val === details[attribute]) return;
44
41
  dispatch(updateContentView(cvId, { [attribute]: val }));
@@ -48,8 +45,10 @@ const ContentViewInfo = ({ cvId, details }) => {
48
45
  <TextContent className="margin-0-24">
49
46
  <TextList component={TextListVariants.dl}>
50
47
  <ActionableDetail
48
+ key={name}
51
49
  label={__('Name')}
52
50
  attribute="name"
51
+ loading={updating && currentAttribute === 'name'}
53
52
  onEdit={onEdit}
54
53
  disabled={!hasPermission(permissions, 'edit_content_views')}
55
54
  value={name}
@@ -76,9 +75,11 @@ const ContentViewInfo = ({ cvId, details }) => {
76
75
  </Flex>
77
76
  </TextListItem>
78
77
  <ActionableDetail
78
+ key={description}
79
79
  textArea
80
80
  label={__('Description')}
81
81
  attribute="description"
82
+ loading={updating && currentAttribute === 'description'}
82
83
  onEdit={onEdit}
83
84
  disabled={!hasPermission(permissions, 'edit_content_views')}
84
85
  value={description}
@@ -86,8 +87,10 @@ const ContentViewInfo = ({ cvId, details }) => {
86
87
  />
87
88
  {composite ?
88
89
  (<ActionableDetail
90
+ key={autoPublish}
89
91
  label={__('Autopublish')}
90
92
  attribute="auto_publish"
93
+ loading={updating && currentAttribute === 'auto_publish'}
91
94
  value={autoPublish}
92
95
  onEdit={onEdit}
93
96
  disabled={!hasPermission(permissions, 'edit_content_views')}
@@ -98,6 +101,8 @@ const ContentViewInfo = ({ cvId, details }) => {
98
101
  (<ActionableDetail
99
102
  label={__('Solve dependencies')}
100
103
  attribute="solve_dependencies"
104
+ key={solveDependencies}
105
+ loading={updating && currentAttribute === 'solve_dependencies'}
101
106
  value={solveDependencies}
102
107
  onEdit={onEdit}
103
108
  disabled={!hasPermission(permissions, 'edit_content_views')}
@@ -1,27 +1,27 @@
1
1
  import React, { useEffect } from 'react';
2
- import { useDispatch, useSelector, shallowEqual } from 'react-redux';
3
- import PropTypes from 'prop-types';
4
2
  import { STATUS } from 'foremanReact/constants';
5
- import EmptyStateMessage from '../../../components/Table/EmptyStateMessage';
3
+ import PropTypes from 'prop-types';
4
+ import {
5
+ shallowEqual,
6
+ useDispatch,
7
+ useSelector,
8
+ } from 'react-redux';
6
9
  import Loading from '../../../components/Loading';
10
+ import EmptyStateMessage from '../../../components/Table/EmptyStateMessage';
7
11
  import getContentViewDetails from './ContentViewDetailActions';
8
12
  import {
9
- selectCVDetails,
10
- selectCVDetailStatus,
11
13
  selectCVDetailError,
14
+ selectCVDetailStatus,
12
15
  } from './ContentViewDetailSelectors';
13
16
 
14
- const DetailsContainer = ({ children, cvId, isOpen }) => {
17
+ const DetailsContainer = ({ children, cvId }) => {
15
18
  const dispatch = useDispatch();
16
- const details = useSelector(state => selectCVDetails(state, cvId), shallowEqual);
17
19
  const status = useSelector(state => selectCVDetailStatus(state, cvId), shallowEqual);
18
20
  const error = useSelector(state => selectCVDetailError(state, cvId), shallowEqual);
19
21
 
20
22
  useEffect(() => {
21
- if (isOpen && Object.keys(details).length === 0) {
22
- dispatch(getContentViewDetails(cvId));
23
- }
24
- });
23
+ dispatch(getContentViewDetails(cvId));
24
+ }, [cvId, dispatch]);
25
25
 
26
26
  if (status === STATUS.PENDING) return (<Loading />);
27
27
  if (status === STATUS.ERROR) return (<EmptyStateMessage error={error} />);
@@ -31,11 +31,6 @@ const DetailsContainer = ({ children, cvId, isOpen }) => {
31
31
  DetailsContainer.propTypes = {
32
32
  children: PropTypes.element.isRequired,
33
33
  cvId: PropTypes.number.isRequired,
34
- isOpen: PropTypes.bool,
35
- };
36
-
37
- DetailsContainer.defaultProps = {
38
- isOpen: true,
39
34
  };
40
35
 
41
36
  export default DetailsContainer;
@@ -50,8 +50,8 @@ const ContentViewFilterDetails = ({ cvId, details }) => {
50
50
  {loaded && (Object.keys(filterDetails).length > 0) ?
51
51
  <ContentViewFilterDetailsHeader
52
52
  {...{
53
- cvId, filterId, filterDetails, setShowAffectedRepos, details,
54
- }}
53
+ cvId, filterId, filterDetails, setShowAffectedRepos, details,
54
+ }}
55
55
  /> :
56
56
  <Loading />
57
57
  }
@@ -8,15 +8,16 @@ import { getCVFilterDetails, editCVFilter } from '../ContentViewDetailActions';
8
8
  import AffectedRepositorySelection from './AffectedRepositories/AffectedRepositorySelection';
9
9
  import RepoIcon from '../Repositories/RepoIcon';
10
10
  import { repoType } from '../../../../utils/helpers';
11
- import EditableTextInput from '../../../../components/EditableTextInput';
12
11
  import { hasPermission } from '../../helpers';
13
12
  import { typeName } from './ContentType';
13
+ import ActionableDetail from '../../../../components/ActionableDetail';
14
14
 
15
15
  const ContentViewFilterDetailsHeader = ({
16
16
  cvId, filterId, filterDetails, setShowAffectedRepos, details,
17
17
  }) => {
18
18
  const dispatch = useDispatch();
19
19
  const [currentAttribute, setCurrentAttribute] = useState('');
20
+ const [loading, setLoading] = useState(false);
20
21
  const {
21
22
  type, name, inclusion, description, rules,
22
23
  } = filterDetails;
@@ -26,12 +27,17 @@ const ContentViewFilterDetailsHeader = ({
26
27
 
27
28
  const displayedType = () => typeName(type, errataByDate);
28
29
 
29
- const onEdit = (val, attribute) => {
30
+ const onEdit = async (val, attribute) => {
30
31
  if (val === filterDetails[attribute]) return;
31
- dispatch(editCVFilter(
32
+ setLoading(true);
33
+ await dispatch(editCVFilter(
32
34
  filterId,
33
35
  { [attribute]: val },
34
- () => dispatch(getCVFilterDetails(cvId, filterId)),
36
+ () => {
37
+ setLoading(false);
38
+ dispatch(getCVFilterDetails(cvId, filterId));
39
+ },
40
+ () => setLoading(false),
35
41
  ));
36
42
  };
37
43
 
@@ -39,10 +45,10 @@ const ContentViewFilterDetailsHeader = ({
39
45
  <Grid className="margin-0-24">
40
46
  <GridItem span={9}>
41
47
  <TextContent>
42
- <EditableTextInput
48
+ <ActionableDetail
43
49
  key={name} // This fixes a render issue with the initial value
44
- label={__('Name')}
45
50
  attribute="name"
51
+ loading={loading && currentAttribute === 'name'}
46
52
  placeholder={__('Enter a name')}
47
53
  onEdit={onEdit}
48
54
  disabled={!hasPermission(permissions, 'edit_content_views')}
@@ -53,11 +59,11 @@ const ContentViewFilterDetailsHeader = ({
53
59
  />
54
60
  </TextContent>
55
61
  <TextContent style={{ padding: '24px 0 12px' }}>
56
- <EditableTextInput
62
+ <ActionableDetail
57
63
  key={description} // This fixes a render issue with the initial value
58
64
  textArea
59
- label={__('Description')}
60
65
  attribute="description"
66
+ loading={loading && currentAttribute === 'description'}
61
67
  placeholder={__('No description')}
62
68
  onEdit={onEdit}
63
69
  disabled={!hasPermission(permissions, 'edit_content_views')}
@@ -22,8 +22,8 @@ const MatchContentModal =
22
22
  let searchDelayScope;
23
23
  let autoSearchScope;
24
24
  beforeEach(() => {
25
- searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 500);
26
- autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing', true);
25
+ searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
26
+ autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
27
27
  });
28
28
 
29
29
  afterEach(() => {
@@ -43,9 +43,8 @@ const withCVRoute = component => <Route path="/content_views/:id([0-9]+)#/filter
43
43
  let searchDelayScope;
44
44
  let autoSearchScope;
45
45
  beforeEach(() => {
46
- searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 500);
47
- // Autosearch can cause some asynchronous issues with the typing timeout, using basic search
48
- autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing', false);
46
+ searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
47
+ autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
49
48
  });
50
49
 
51
50
  afterEach(() => {
@@ -35,9 +35,8 @@ const withCVRoute = component => <Route path="/content_views/:id([0-9]+)#/filter
35
35
  let searchDelayScope;
36
36
  let autoSearchScope;
37
37
  beforeEach(() => {
38
- searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 500);
39
- // Autosearch can cause some asynchronous issues with the typing timeout, using basic search
40
- autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing', false);
38
+ searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
39
+ autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
41
40
  });
42
41
 
43
42
  afterEach(() => {
@@ -46,11 +45,6 @@ afterEach(() => {
46
45
  nock.cleanAll();
47
46
  });
48
47
 
49
- jest.mock('../../../../../utils/useDebounce', () => ({
50
- __esModule: true,
51
- default: value => value,
52
- }));
53
-
54
48
  test('Can show filter details and package groups on page load', async (done) => {
55
49
  const { name: cvFilterName } = cvFilterDetails;
56
50
  const cvFilterScope = nockInstance
@@ -127,7 +121,6 @@ test('Can search for package rules in package filter details', async (done) => {
127
121
 
128
122
  // Search and only searched result shows
129
123
  fireEvent.change(getByLabelText(/text input for search/i), { target: { value: lastPackageRuleName } });
130
- getByLabelText(/search button/i).click();
131
124
  await patientlyWaitFor(() => {
132
125
  expect(getByText(lastPackageRuleName)).toBeInTheDocument();
133
126
  expect(queryByText(firstPackageRuleName)).not.toBeInTheDocument();
@@ -33,9 +33,8 @@ const withCVRoute = component => <Route path="/content_views/:id([0-9]+)#/filter
33
33
  let searchDelayScope;
34
34
  let autoSearchScope;
35
35
  beforeEach(() => {
36
- searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 500);
37
- // Autosearch can cause some asynchronous issues with the typing timeout, using basic search
38
- autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing', false);
36
+ searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
37
+ autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
39
38
  });
40
39
 
41
40
  afterEach(() => {
@@ -105,7 +104,7 @@ test('Can search for package groups in package group filter', async (done) => {
105
104
  .reply(200, { results: [lastPackageGroup] });
106
105
 
107
106
  const autocompleteScope =
108
- mockAutocomplete(nockInstance, autocompleteUrl, undefined, undefined, 2);
107
+ mockAutocomplete(nockInstance, autocompleteUrl);
109
108
  const withSearchScope = mockAutocomplete(nockInstance, autocompleteUrl, searchQueryMatcher);
110
109
  const { getByText, queryByText, getByLabelText } =
111
110
  renderWithRedux(withCVRoute(<ContentViewFilterDetails
@@ -121,7 +120,6 @@ test('Can search for package groups in package group filter', async (done) => {
121
120
 
122
121
  // Search and only searched result shows
123
122
  fireEvent.change(getByLabelText(/text input for search/i), { target: { value: lastPackageGroupName } });
124
- getByLabelText(/search button/i).click();
125
123
  await patientlyWaitFor(() => {
126
124
  expect(getByText(lastPackageGroupName)).toBeInTheDocument();
127
125
  expect(queryByText(firstPackageGroupName)).not.toBeInTheDocument();
@@ -31,11 +31,9 @@ let autoSearchScope;
31
31
  beforeEach(() => {
32
32
  const { results } = cvFilterFixtures;
33
33
  [firstFilter] = results;
34
- // lastFilter = results.pop();
35
34
  [lastFilter] = results.slice(-1);
36
- searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 500);
37
- // Autosearch can cause some asynchronous issues with the typing timeout, using basic search
38
- autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing', false);
35
+ searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
36
+ autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
39
37
  });
40
38
 
41
39
  afterEach(() => {
@@ -44,11 +42,6 @@ afterEach(() => {
44
42
  nock.cleanAll();
45
43
  });
46
44
 
47
- jest.mock('../../../../../utils/useDebounce', () => ({
48
- __esModule: true,
49
- default: value => value,
50
- }));
51
-
52
45
  test('Can call API and show filters on page load', async (done) => {
53
46
  const { name, description } = firstFilter;
54
47
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
@@ -96,7 +89,6 @@ test('Can search for filter', async (done) => {
96
89
  await patientlyWaitFor(() => expect(getByText(description)).toBeInTheDocument());
97
90
  // Search for a filter by name
98
91
  fireEvent.change(getByLabelText(/text input for search/i), { target: { value: name } });
99
- getByLabelText(/search button/i).click();
100
92
  // Only the first filter should be showing, not the last one
101
93
  await patientlyWaitFor(() => {
102
94
  expect(getByText(description)).toBeInTheDocument();
@@ -40,9 +40,8 @@ const withCVRoute = component => <Route path="/content_views/:id([0-9]+)#/filter
40
40
  let searchDelayScope;
41
41
  let autoSearchScope;
42
42
  beforeEach(() => {
43
- searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 500);
44
- // Autosearch can cause some asynchronous issues with the typing timeout, using basic search
45
- autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing', false);
43
+ searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
44
+ autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
46
45
  });
47
46
 
48
47
  afterEach(() => {
@@ -40,9 +40,8 @@ const withCVRoute = component => <Route path="/content_views/:id([0-9]+)#/filter
40
40
  let searchDelayScope;
41
41
  let autoSearchScope;
42
42
  beforeEach(() => {
43
- searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 500);
44
- // Autosearch can cause some asynchronous issues with the typing timeout, using basic search
45
- autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing', false);
43
+ searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
44
+ autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
46
45
  });
47
46
 
48
47
  afterEach(() => {
@@ -18,8 +18,8 @@ let autoSearchScope;
18
18
  beforeEach(() => {
19
19
  const { results } = historyData;
20
20
  [firstHistory] = results;
21
- searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 500);
22
- autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing', true);
21
+ searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
22
+ autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
23
23
  });
24
24
 
25
25
  afterEach(() => {
@@ -41,7 +41,7 @@ const ContentCounts = ({ productId, repoId, counts }) => {
41
41
  Object.keys(counts).forEach((type) => {
42
42
  const count = counts[type];
43
43
  let info = repoLabels[type];
44
- const config = ContentConfig().find(typeConfig =>
44
+ const config = ContentConfig.find(typeConfig =>
45
45
  typeConfig.names.singularLabel === type);
46
46
 
47
47
  if (config) {
@@ -143,14 +143,35 @@ const ContentViewRepositories = ({ cvId, details }) => {
143
143
 
144
144
  const onAdd = (repos) => {
145
145
  const { repository_ids: repositoryIds = [] } = details;
146
- dispatch(updateContentView(cvId, { repository_ids: repositoryIds.concat(repos) }));
146
+ dispatch(updateContentView(
147
+ cvId,
148
+ { repository_ids: repositoryIds.concat(repos) },
149
+ () =>
150
+ dispatch(getContentViewRepositories(
151
+ cvId,
152
+ typeSelected !== 'All repositories' ? {
153
+ content_type: repoTypes[typeSelected],
154
+ } : {},
155
+ statusSelected,
156
+ )),
157
+ ));
147
158
  };
148
159
 
149
160
  const onRemove = (repos) => {
150
161
  const reposToDelete = [].concat(repos);
151
162
  const { repository_ids: repositoryIds = [] } = details;
152
163
  const deletedRepos = repositoryIds.filter(x => !reposToDelete.includes(x));
153
- dispatch(updateContentView(cvId, { repository_ids: deletedRepos }));
164
+ dispatch(updateContentView(
165
+ cvId, { repository_ids: deletedRepos },
166
+ () =>
167
+ dispatch(getContentViewRepositories(
168
+ cvId,
169
+ typeSelected !== 'All repositories' ? {
170
+ content_type: repoTypes[typeSelected],
171
+ } : {},
172
+ statusSelected,
173
+ )),
174
+ ));
154
175
  };
155
176
 
156
177
  const addBulk = () => {
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { renderWithRedux, patientlyWaitFor } from 'react-testing-lib-wrapper';
2
+ import { renderWithRedux, patientlyWaitFor, act } from 'react-testing-lib-wrapper';
3
3
 
4
4
  import nock, { nockInstance, assertNockRequest, mockAutocomplete, mockSetting } from '../../../../../test-utils/nockWrapper';
5
5
  import api from '../../../../../services/api';
@@ -23,8 +23,8 @@ let autoSearchScope;
23
23
  beforeEach(() => {
24
24
  const { results } = repoData;
25
25
  [firstRepo] = results;
26
- searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 500);
27
- autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing', true);
26
+ searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
27
+ autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
28
28
  nockInstance
29
29
  .persist() // match any query to this endpoint, gets cleaned up by `nock.cleanAll()`
30
30
  .get(api.getApiUrl('/repositories/repository_types'))
@@ -66,7 +66,7 @@ test('Can enable and disable add repositories button', async (done) => {
66
66
 
67
67
  test('Can add repositories', async (done) => {
68
68
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
69
- const cvAddparams = { repository_ids: [58, 62, 64, 106] };
69
+ const cvAddparams = { include_permissions: true, repository_ids: [58, 62, 64, 106] };
70
70
 
71
71
  const repoAddscope = nockInstance
72
72
  .put(cvDetailsPath, cvAddparams)
@@ -92,16 +92,19 @@ test('Can add repositories', async (done) => {
92
92
  expect(getByLabelText('add_repositories')).toHaveAttribute('aria-disabled', 'true');
93
93
  getByLabelText('Select all rows').click();
94
94
  getByLabelText('add_repositories').click();
95
+ await patientlyWaitFor(() => expect(getByText(firstRepo.name)).toBeInTheDocument());
96
+
95
97
  assertNockRequest(repoAddscope);
96
98
 
97
99
  assertNockRequest(cvDetailScope);
98
100
  assertNockRequest(autocompleteScope);
99
101
  assertNockRequest(scope, done);
102
+ act(done);
100
103
  });
101
104
 
102
105
  test('Can remove repositories', async (done) => {
103
106
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
104
- const cvRemoveParams = { repository_ids: [58, 62, 64] };
107
+ const cvRemoveParams = { include_permissions: true, repository_ids: [58, 62, 64] };
105
108
  const scope = nockInstance
106
109
  .get(cvAllRepos)
107
110
  .query(true)
@@ -131,9 +134,12 @@ test('Can remove repositories', async (done) => {
131
134
  expect(getByLabelText('bulk_remove')).toBeInTheDocument();
132
135
  });
133
136
  getByLabelText('bulk_remove').click();
137
+ await patientlyWaitFor(() => expect(getByText(firstRepo.name)).toBeInTheDocument());
138
+
134
139
  assertNockRequest(repoRemoveScope);
135
140
 
136
141
  assertNockRequest(autocompleteScope);
137
142
  assertNockRequest(cvDetailScope);
138
143
  assertNockRequest(scope, done);
144
+ act(done);
139
145
  });