katello 4.4.2.2 → 4.5.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 (444) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +5 -1
  3. data/app/controllers/katello/api/v2/alternate_content_sources_controller.rb +98 -0
  4. data/app/controllers/katello/api/v2/content_export_incrementals_controller.rb +39 -3
  5. data/app/controllers/katello/api/v2/content_exports_controller.rb +19 -0
  6. data/app/controllers/katello/api/v2/content_imports_controller.rb +13 -16
  7. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +0 -12
  8. data/app/controllers/katello/api/v2/content_views_controller.rb +13 -0
  9. data/app/controllers/katello/api/v2/environments_controller.rb +1 -1
  10. data/app/controllers/katello/api/v2/host_module_streams_controller.rb +8 -2
  11. data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +25 -3
  12. data/app/controllers/katello/api/v2/organizations_controller.rb +4 -2
  13. data/app/controllers/katello/api/v2/repositories_bulk_actions_controller.rb +1 -1
  14. data/app/controllers/katello/api/v2/repositories_controller.rb +9 -3
  15. data/app/controllers/katello/api/v2/repository_sets_controller.rb +40 -7
  16. data/app/controllers/katello/api/v2/subscriptions_controller.rb +2 -2
  17. data/app/controllers/katello/concerns/api/v2/hosts_controller_extensions.rb +1 -1
  18. data/app/helpers/katello/concerns/smart_proxy_helper_extensions.rb +4 -0
  19. data/app/helpers/katello/hosts_and_hostgroups_helper.rb +21 -3
  20. data/app/lib/actions/katello/alternate_content_source/create.rb +24 -0
  21. data/app/lib/actions/katello/alternate_content_source/destroy.rb +27 -0
  22. data/app/lib/actions/katello/alternate_content_source/update.rb +41 -0
  23. data/app/lib/actions/katello/cdn_configuration/update.rb +2 -2
  24. data/app/lib/actions/katello/content_view/destroy.rb +2 -1
  25. data/app/lib/actions/katello/content_view/incremental_updates.rb +7 -3
  26. data/app/lib/actions/katello/content_view/publish.rb +7 -9
  27. data/app/lib/actions/katello/content_view_version/auto_create_products.rb +4 -4
  28. data/app/lib/actions/katello/content_view_version/auto_create_redhat_repositories.rb +6 -4
  29. data/app/lib/actions/katello/content_view_version/auto_create_repositories.rb +6 -4
  30. data/app/lib/actions/katello/content_view_version/import.rb +25 -22
  31. data/app/lib/actions/katello/content_view_version/import_library.rb +0 -1
  32. data/app/lib/actions/katello/content_view_version/import_repository.rb +21 -0
  33. data/app/lib/actions/katello/content_view_version/incremental_update.rb +85 -93
  34. data/app/lib/actions/katello/content_view_version/reset_content_view_repositories_from_metadata.rb +2 -2
  35. data/app/lib/actions/katello/product/content_create.rb +10 -8
  36. data/app/lib/actions/katello/repository/destroy.rb +36 -12
  37. data/app/lib/actions/katello/repository_set/disable_repository.rb +8 -3
  38. data/app/lib/actions/pulp3/alternate_content_source/create.rb +20 -0
  39. data/app/lib/actions/pulp3/alternate_content_source/create_remote.rb +20 -0
  40. data/app/lib/actions/pulp3/alternate_content_source/delete.rb +16 -0
  41. data/app/lib/actions/pulp3/alternate_content_source/delete_remote.rb +16 -0
  42. data/app/lib/actions/pulp3/alternate_content_source/update.rb +16 -0
  43. data/app/lib/actions/pulp3/alternate_content_source/update_remote.rb +17 -0
  44. data/app/lib/actions/pulp3/content_view_version/{import.rb → create_import.rb} +5 -5
  45. data/app/lib/actions/pulp3/content_view_version/create_importer.rb +4 -3
  46. data/app/lib/actions/pulp3/content_view_version/destroy_importer.rb +12 -1
  47. data/app/lib/actions/pulp3/orchestration/alternate_content_source/create.rb +18 -0
  48. data/app/lib/actions/pulp3/orchestration/alternate_content_source/delete.rb +23 -0
  49. data/app/lib/actions/pulp3/orchestration/alternate_content_source/update.rb +18 -0
  50. data/app/lib/actions/pulp3/orchestration/content_view_version/copy_version_units_to_library.rb +1 -1
  51. data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +51 -0
  52. data/app/lib/actions/pulp3/orchestration/content_view_version/import.rb +5 -2
  53. data/app/lib/actions/pulp3/repository/refresh_distribution.rb +4 -1
  54. data/app/lib/actions/pulp3/repository/save_distribution_references.rb +2 -0
  55. data/app/lib/katello/api/v2/error_handling.rb +1 -0
  56. data/app/lib/katello/resources/cdn/katello_cdn.rb +3 -1
  57. data/app/lib/katello/util/errata.rb +2 -3
  58. data/app/lib/katello/validators/alternate_content_source_path_validator.rb +29 -0
  59. data/app/lib/katello/validators/content_default_http_proxy_setting_validator.rb +12 -0
  60. data/app/lib/katello/validators/content_view_environment_validator.rb +10 -5
  61. data/app/models/katello/alternate_content_source.rb +66 -0
  62. data/app/models/katello/authorization/alternate_content_source.rb +33 -0
  63. data/app/models/katello/authorization/repository.rb +3 -3
  64. data/app/models/katello/candlepin/repository_mapper.rb +13 -6
  65. data/app/models/katello/cdn_configuration.rb +15 -15
  66. data/app/models/katello/concerns/content_facet_host_extensions.rb +25 -0
  67. data/app/models/katello/concerns/host_managed_extensions.rb +7 -5
  68. data/app/models/katello/concerns/http_proxy_extensions.rb +14 -0
  69. data/app/models/katello/concerns/organization_extensions.rb +4 -2
  70. data/app/models/katello/concerns/setting_extensions.rb +14 -0
  71. data/app/models/katello/concerns/smart_proxy_extensions.rb +2 -1
  72. data/app/models/katello/content.rb +1 -0
  73. data/app/models/katello/content_credential.rb +6 -0
  74. data/app/models/katello/content_override.rb +7 -3
  75. data/app/models/katello/content_view.rb +33 -2
  76. data/app/models/katello/content_view_erratum_filter.rb +26 -12
  77. data/app/models/katello/content_view_filter.rb +4 -0
  78. data/app/models/katello/content_view_version.rb +12 -0
  79. data/app/models/katello/content_view_version_export_history.rb +3 -1
  80. data/app/models/katello/erratum.rb +9 -5
  81. data/app/models/katello/events/delete_latest_content_view_version.rb +40 -0
  82. data/app/models/katello/host/content_facet.rb +14 -0
  83. data/app/models/katello/host_available_module_stream.rb +12 -0
  84. data/app/models/katello/product_content.rb +1 -0
  85. data/app/models/katello/purpose_sla_status.rb +1 -1
  86. data/app/models/katello/purpose_status.rb +2 -2
  87. data/app/models/katello/repository.rb +7 -4
  88. data/app/models/katello/root_repository.rb +1 -1
  89. data/app/models/katello/smart_proxy_alternate_content_source.rb +8 -0
  90. data/app/models/katello/sync_plan.rb +1 -1
  91. data/app/presenters/katello/product_content_presenter.rb +15 -0
  92. data/app/services/katello/applicable_host_queue.rb +1 -1
  93. data/app/services/katello/content_unit_indexer.rb +2 -1
  94. data/app/services/katello/product_content_finder.rb +12 -2
  95. data/app/services/katello/pulp3/alternate_content_source.rb +117 -0
  96. data/app/services/katello/pulp3/api/file.rb +8 -0
  97. data/app/services/katello/pulp3/api/yum.rb +8 -0
  98. data/app/services/katello/pulp3/content_view_version/export.rb +27 -5
  99. data/app/services/katello/pulp3/content_view_version/import.rb +97 -71
  100. data/app/services/katello/pulp3/content_view_version/import_export_common.rb +4 -4
  101. data/app/services/katello/pulp3/content_view_version/import_gpg_keys.rb +13 -11
  102. data/app/services/katello/pulp3/content_view_version/import_validator.rb +67 -72
  103. data/app/services/katello/pulp3/content_view_version/importable_products.rb +40 -24
  104. data/app/services/katello/pulp3/content_view_version/importable_repositories.rb +88 -39
  105. data/app/services/katello/pulp3/content_view_version/metadata_generator.rb +2 -2
  106. data/app/services/katello/pulp3/content_view_version/metadata_map.rb +117 -0
  107. data/app/services/katello/pulp3/pulp_content_unit.rb +6 -1
  108. data/app/services/katello/pulp3/repository/yum.rb +70 -12
  109. data/app/services/katello/pulp3/repository.rb +7 -91
  110. data/app/services/katello/pulp3/service_common.rb +66 -0
  111. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +4 -1
  112. data/app/services/katello/ui_notifications/content_view/delete_latest_version_failure.rb +22 -0
  113. data/app/views/foreman/job_templates/change_content_source.erb +1 -1
  114. data/app/views/foreman/job_templates/install_errata.erb +5 -5
  115. data/app/views/foreman/job_templates/install_errata_by_search_query.erb +7 -6
  116. data/app/views/foreman/job_templates/install_group.erb +4 -4
  117. data/app/views/foreman/job_templates/install_package.erb +4 -4
  118. data/app/views/foreman/job_templates/install_packages_by_search_query.erb +3 -3
  119. data/app/views/foreman/job_templates/remove_group.erb +4 -4
  120. data/app/views/foreman/job_templates/remove_package.erb +4 -4
  121. data/app/views/foreman/job_templates/remove_packages_by_search_query.erb +3 -3
  122. data/app/views/foreman/job_templates/resolve_traces.erb +2 -2
  123. data/app/views/foreman/job_templates/restart_services.erb +3 -3
  124. data/app/views/foreman/job_templates/update_group.erb +4 -4
  125. data/app/views/foreman/job_templates/update_package.erb +4 -4
  126. data/app/views/foreman/job_templates/update_packages_by_search_query.erb +3 -3
  127. data/app/views/katello/api/v2/alternate_content_sources/base.json.rabl +15 -0
  128. data/app/views/katello/api/v2/alternate_content_sources/index.json.rabl +7 -0
  129. data/app/views/katello/api/v2/alternate_content_sources/show.json.rabl +3 -0
  130. data/app/views/katello/api/v2/capsule_content/sync_status.json.rabl +1 -1
  131. data/app/views/katello/api/v2/content_view_version_export_histories/show.json.rabl +2 -3
  132. data/app/views/katello/api/v2/content_view_versions/base.json.rabl +1 -1
  133. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -0
  134. data/app/views/katello/api/v2/environments/show.json.rabl +2 -0
  135. data/app/views/katello/api/v2/errata/_counts.json.rabl +2 -2
  136. data/app/views/katello/api/v2/host_module_streams/base.json.rabl +2 -2
  137. data/app/views/katello/api/v2/hosts/host_collections.json.rabl +1 -1
  138. data/app/views/katello/api/v2/organizations/show.json.rabl +7 -1
  139. data/app/views/katello/api/v2/repositories/show.json.rabl +2 -1
  140. data/app/views/katello/sync_management/_repo.html.erb +8 -29
  141. data/config/routes/api/v2.rb +7 -0
  142. data/db/migrate/20150930183738_migrate_content_hosts.rb +0 -399
  143. data/db/migrate/20171025163149_remove_use_pulp_oauth_setting.rb +1 -1
  144. data/db/migrate/20171114150937_cleanup_installed_packages.rb +1 -1
  145. data/db/migrate/20180402160223_clean_up_force_post_sync_action_setting.rb +1 -1
  146. data/db/migrate/20211129200124_remove_dependency_solving_algorithm_setting.rb +1 -1
  147. data/db/migrate/20211220185935_clean_duplicate_content_units.rb +10 -12
  148. data/db/migrate/20220110223754_update_disconnected_settings.rb +5 -5
  149. data/db/migrate/20220117151612_add_alternate_content_sources.rb +48 -0
  150. data/db/migrate/20220124191056_add_type_to_cdn_configuration.rb +9 -4
  151. data/db/migrate/20220209203251_add_generated_for_to_content_views.rb +13 -0
  152. data/db/migrate/20220209205137_expand_sync_timeout_settings.rb +7 -7
  153. data/db/migrate/20220228173251_remove_drpm_from_ignorable_content.rb +12 -0
  154. data/db/migrate/20220404190836_delete_old_setting_data.rb +9 -0
  155. data/db/migrate/20220405220616_update_cdn_configuration_type.rb +11 -0
  156. data/db/migrate/20220419193414_content_settings_to_dsl_category.rb +5 -0
  157. data/db/seeds.d/110-content-view-autopublish.rb +13 -0
  158. data/db/seeds.d/150-module_job_templates.rb +1 -1
  159. data/engines/bastion/README.md +1 -0
  160. data/engines/bastion/app/assets/javascripts/bastion/components/bst-modal.directive.js +1 -0
  161. data/engines/bastion/app/views/bastion/layouts/assets.html.erb +1 -0
  162. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-details.controller.js +4 -2
  163. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.controller.js +10 -5
  164. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-module-streams.controller.js +1 -0
  165. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages-installed.controller.js +1 -0
  166. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-traces.controller.js +1 -0
  167. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-actions.html +1 -1
  168. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-applicable.html +1 -1
  169. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +8 -0
  170. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details.controller.js +4 -2
  171. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +2 -2
  172. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/content.service.js +10 -0
  173. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-deb-repositories.html +26 -0
  174. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-debs.html +27 -0
  175. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/environments.controller.js +1 -0
  176. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/environments.routes.js +22 -0
  177. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/views/environments.html +13 -7
  178. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +63 -17
  179. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.controller.js +7 -8
  180. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +10 -1
  181. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +21 -3
  182. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +8 -9
  183. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +7 -5
  184. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +2 -1
  185. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery-create.controller.js +1 -1
  186. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/views/discovery-create.html +1 -1
  187. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.routes.js +1 -0
  188. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/views/content-access-mode-banner.html +6 -1
  189. data/lib/katello/engine.rb +1 -5
  190. data/lib/katello/permission_creator.rb +32 -4
  191. data/lib/katello/plugin.rb +378 -4
  192. data/lib/katello/tasks/reset.rake.bak +67 -0
  193. data/lib/katello/tasks/update_content_default_http_proxy.rake +2 -3
  194. data/lib/katello/version.rb +1 -1
  195. data/locale/action_names.rb +47 -41
  196. data/locale/bn/LC_MESSAGES/katello.mo +0 -0
  197. data/locale/bn/katello.po +820 -106
  198. data/locale/bn/katello.po.time_stamp +0 -0
  199. data/locale/cs/LC_MESSAGES/katello.mo +0 -0
  200. data/locale/cs/katello.po +818 -104
  201. data/locale/cs/katello.po.time_stamp +0 -0
  202. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  203. data/locale/de/katello.po +893 -179
  204. data/locale/de/katello.po.time_stamp +0 -0
  205. data/locale/en/LC_MESSAGES/katello.mo +0 -0
  206. data/locale/en/katello.po +817 -103
  207. data/locale/en/katello.po.time_stamp +0 -0
  208. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  209. data/locale/es/katello.po +882 -168
  210. data/locale/es/katello.po.time_stamp +0 -0
  211. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  212. data/locale/fr/katello.po +1219 -505
  213. data/locale/fr/katello.po.time_stamp +0 -0
  214. data/locale/gu/LC_MESSAGES/katello.mo +0 -0
  215. data/locale/gu/katello.po +826 -112
  216. data/locale/gu/katello.po.time_stamp +0 -0
  217. data/locale/hi/LC_MESSAGES/katello.mo +0 -0
  218. data/locale/hi/katello.po +826 -112
  219. data/locale/hi/katello.po.time_stamp +0 -0
  220. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  221. data/locale/it/katello.po +863 -148
  222. data/locale/it/katello.po.time_stamp +0 -0
  223. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  224. data/locale/ja/katello.po +1216 -499
  225. data/locale/ja/katello.po.time_stamp +0 -0
  226. data/locale/katello.pot +3847 -2507
  227. data/locale/kn/LC_MESSAGES/katello.mo +0 -0
  228. data/locale/kn/katello.po +826 -112
  229. data/locale/kn/katello.po.time_stamp +0 -0
  230. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  231. data/locale/ko/katello.po +912 -198
  232. data/locale/ko/katello.po.time_stamp +0 -0
  233. data/locale/mr/LC_MESSAGES/katello.mo +0 -0
  234. data/locale/mr/katello.po +826 -112
  235. data/locale/mr/katello.po.time_stamp +0 -0
  236. data/locale/or/LC_MESSAGES/katello.mo +0 -0
  237. data/locale/or/katello.po +826 -112
  238. data/locale/or/katello.po.time_stamp +0 -0
  239. data/locale/pa/LC_MESSAGES/katello.mo +0 -0
  240. data/locale/pa/katello.po +826 -112
  241. data/locale/pa/katello.po.time_stamp +0 -0
  242. data/locale/pt/LC_MESSAGES/katello.mo +0 -0
  243. data/locale/pt/katello.po +817 -103
  244. data/locale/pt/katello.po.time_stamp +0 -0
  245. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  246. data/locale/pt_BR/katello.po +879 -165
  247. data/locale/pt_BR/katello.po.time_stamp +0 -0
  248. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  249. data/locale/ru/katello.po +927 -213
  250. data/locale/ru/katello.po.time_stamp +0 -0
  251. data/locale/ta/LC_MESSAGES/katello.mo +0 -0
  252. data/locale/ta/katello.po +820 -106
  253. data/locale/ta/katello.po.time_stamp +0 -0
  254. data/locale/te/LC_MESSAGES/katello.mo +0 -0
  255. data/locale/te/katello.po +826 -112
  256. data/locale/te/katello.po.time_stamp +0 -0
  257. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  258. data/locale/zh_CN/katello.po +1202 -486
  259. data/locale/zh_CN/katello.po.time_stamp +0 -0
  260. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  261. data/locale/zh_TW/katello.po +856 -142
  262. data/locale/zh_TW/katello.po.time_stamp +0 -0
  263. data/webpack/components/EditableTextInput/EditableTextInput.js +20 -5
  264. data/webpack/components/Errata/index.js +38 -8
  265. data/webpack/components/Packages/index.js +1 -4
  266. data/webpack/components/Search/Search.js +18 -3
  267. data/webpack/components/SelectAllCheckbox/index.js +1 -0
  268. data/webpack/components/SelectableDropdown/SelectableDropdown.js +4 -2
  269. data/webpack/components/Table/EmptyStateMessage.js +21 -7
  270. data/webpack/components/Table/MainTable.js +29 -4
  271. data/webpack/components/Table/TableHooks.js +63 -19
  272. data/webpack/components/Table/TableWrapper.js +4 -2
  273. data/webpack/components/Table/components/SortableColumnHeaders.js +19 -0
  274. data/webpack/components/Table/components/TranslatedPlural.js +57 -0
  275. data/webpack/components/TypeAhead/TypeAhead.js +8 -0
  276. data/webpack/components/TypeAhead/pf4Search/TypeAheadInput.js +13 -11
  277. data/webpack/components/TypeAhead/pf4Search/TypeAheadSearch.js +5 -2
  278. data/webpack/components/extensions/HostDetails/ActionsBar/index.js +27 -0
  279. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ChangeHostCVModal.js +256 -0
  280. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard.js +202 -0
  281. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/HostContentViewActions.js +19 -0
  282. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/HostContentViewConstants.js +2 -0
  283. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/__tests__/changeHostCVModal.test.js +131 -0
  284. data/webpack/components/extensions/HostDetails/Cards/{__tests__ → ContentViewDetailsCard/__tests__}/contentViewDetailsCard.test.js +22 -0
  285. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/__tests__/contentViews.fixtures.json +443 -0
  286. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/__tests__/envPaths.fixtures.json +320 -0
  287. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.js +57 -33
  288. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.scss +3 -0
  289. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsActions.js +30 -0
  290. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.js +187 -0
  291. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsConstants.js +7 -0
  292. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsModal.js +227 -0
  293. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsSelectors.js +18 -0
  294. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/__tests__/availableHostCollections.fixtures.json +106 -0
  295. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/__tests__/hostCollectionsCard.test.js +110 -0
  296. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/__tests__/hostCollectionsModal.test.js +235 -0
  297. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/__tests__/removableHostCollections.fixtures.json +45 -0
  298. data/webpack/components/extensions/HostDetails/Cards/__tests__/errataOverviewCard.test.js +33 -8
  299. data/webpack/components/extensions/HostDetails/DetailsTabCards/InstalledProductsCard.js +44 -0
  300. data/webpack/components/extensions/HostDetails/DetailsTabCards/RegistrationCard.js +107 -0
  301. data/webpack/components/extensions/HostDetails/DetailsTabCards/SystemPropertiesCardExtensions.js +38 -0
  302. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +62 -39
  303. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/HostErrataActions.js +1 -7
  304. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsActions.js +1 -3
  305. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsConstants.js +28 -0
  306. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +486 -116
  307. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/__tests__/moduleStreamsTab.test.js +147 -1
  308. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/__tests__/modules.fixtures.json +6 -3
  309. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/HostPackagesActions.js +1 -7
  310. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js +2 -1
  311. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +48 -19
  312. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +35 -47
  313. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionConstants.js +1 -0
  314. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsActions.js +33 -54
  315. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsConstants.js +20 -0
  316. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +269 -132
  317. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesTab.js +47 -11
  318. data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +30 -42
  319. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +36 -1
  320. data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySetsTab.test.js +94 -46
  321. data/webpack/components/extensions/HostDetails/Tabs/__tests__/tracesTab.test.js +18 -2
  322. data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +6 -0
  323. data/webpack/containers/Application/config.js +5 -0
  324. data/webpack/global_index.js +30 -7
  325. data/webpack/global_test_setup.js +13 -0
  326. data/webpack/redux/actions/RedHatRepositories/enabled.js +2 -1
  327. data/webpack/redux/actions/RedHatRepositories/helpers.js +9 -8
  328. data/webpack/scenes/AlternateContentSources/ACSActions.js +53 -0
  329. data/webpack/scenes/AlternateContentSources/ACSConstants.js +4 -0
  330. data/webpack/scenes/AlternateContentSources/ACSIndexPage.js +23 -0
  331. data/webpack/scenes/AlternateContentSources/ACSSelectors.js +15 -0
  332. data/webpack/scenes/AlternateContentSources/MainTable/ACSTable.js +152 -0
  333. data/webpack/scenes/AlternateContentSources/MainTable/__tests__/acsIndex.fixtures.json +91 -0
  334. data/webpack/scenes/AlternateContentSources/MainTable/__tests__/acsTable.test.js +67 -0
  335. data/webpack/scenes/AlternateContentSources/index.js +4 -0
  336. data/webpack/scenes/Content/Details/ContentRepositories.js +1 -0
  337. data/webpack/scenes/Content/Table/ContentTable.js +1 -0
  338. data/webpack/scenes/ContentViews/ContentViewsActions.js +6 -2
  339. data/webpack/scenes/ContentViews/ContentViewsConstants.js +11 -3
  340. data/webpack/scenes/ContentViews/Copy/CopyContentViewForm.js +2 -1
  341. data/webpack/scenes/ContentViews/Create/ContentViewFormComponents.js +10 -1
  342. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +4 -3
  343. data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +1 -1
  344. data/webpack/scenes/ContentViews/Delete/ContentViewDeleteWizard.js +7 -5
  345. data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionFinish.js +29 -21
  346. data/webpack/scenes/ContentViews/Delete/__tests__/contentViewDelete.test.js +15 -8
  347. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +3 -3
  348. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +4 -4
  349. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +3 -1
  350. data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/contentViewComponents.test.js +4 -4
  351. data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +34 -8
  352. data/webpack/scenes/ContentViews/Details/ContentViewDetailSelectors.js +33 -29
  353. data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +130 -79
  354. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +17 -3
  355. data/webpack/scenes/ContentViews/Details/Filters/Add/CVFilterAddModal.js +2 -1
  356. data/webpack/scenes/ContentViews/Details/Filters/AffectedRepositories/AffectedRepositoryTable.js +2 -1
  357. data/webpack/scenes/ContentViews/Details/Filters/CVContainerImageFilterContent.js +6 -1
  358. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +41 -21
  359. data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +38 -20
  360. data/webpack/scenes/ContentViews/Details/Filters/CVModuleStreamFilterContent.js +2 -0
  361. data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +8 -1
  362. data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +9 -1
  363. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilters.js +2 -1
  364. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/CVRpmMatchContentModal.js +1 -0
  365. data/webpack/scenes/ContentViews/Details/Filters/Rules/ContainerTag/AddEditContainerTagRuleModal.js +27 -12
  366. data/webpack/scenes/ContentViews/Details/Filters/Rules/Package/AddEditPackageRuleModal.js +39 -17
  367. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVContainerImageFilterContent.test.js +27 -10
  368. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVRpmFilterContent.test.js +46 -23
  369. data/webpack/scenes/ContentViews/Details/Histories/ContentViewHistories.js +3 -2
  370. data/webpack/scenes/ContentViews/Details/Promote/ContentViewVersionPromote.js +5 -2
  371. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +161 -108
  372. data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewAddRemove.test.js +7 -7
  373. data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewRepoAdd.fixture.json +1 -0
  374. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/ActionSummary.js +58 -0
  375. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/BulkDeleteContextWrapper.js +45 -0
  376. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/BulkDeleteHelpers.js +30 -0
  377. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/BulkDeleteModal.js +56 -0
  378. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/Steps/ConfirmBulkDelete.js +126 -0
  379. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/Steps/FinishBulkDelete.js +61 -0
  380. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/Steps/ReassignActivationKeys.js +196 -0
  381. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/Steps/ReassignHosts.js +220 -0
  382. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/Steps/ReviewEnvironments.js +104 -0
  383. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/BulkDeleteModal.test.js +122 -0
  384. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/BulkDeleteVersions.fixtures.json +600 -0
  385. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/contentView.fixtures.json +1504 -0
  386. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/contentViewVersion.fixtures.json +936 -0
  387. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/environmentPaths.fixtures.json +261 -0
  388. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/hosts.fixtures.json +163 -0
  389. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/bulkDeleteSteps.js +79 -0
  390. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +192 -167
  391. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveCVVersionWizard.js +2 -5
  392. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVVersionDeleteFinish.js +38 -53
  393. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVVersionRemoveReview.js +1 -1
  394. data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/cvVersionRemove.test.js +6 -12
  395. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js +1 -0
  396. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedHosts.js +1 -0
  397. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailConfig.js +1 -0
  398. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetails.js +8 -20
  399. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsHeader.js +23 -13
  400. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsTable.js +3 -0
  401. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetails.fixtures.json +4 -4
  402. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetails.test.js +0 -3
  403. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetailsEmpty.test.js +4 -4
  404. data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersions.test.js +12 -14
  405. data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetails.fixtures.json +1 -0
  406. data/webpack/scenes/ContentViews/Publish/CVPublishFinish.js +96 -117
  407. data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +13 -19
  408. data/webpack/scenes/ContentViews/Publish/__tests__/publishContentView.test.js +9 -20
  409. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +165 -148
  410. data/webpack/scenes/ContentViews/Table/tableDataGenerator.js +2 -0
  411. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +4 -4
  412. data/webpack/scenes/ContentViews/components/ContentViewIcon.js +14 -3
  413. data/webpack/scenes/ContentViews/components/ContentViewsCounter.js +1 -1
  414. data/webpack/scenes/ContentViews/components/EnvironmentLabels.js +4 -3
  415. data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.js +9 -5
  416. data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.scss +6 -1
  417. data/webpack/scenes/ContentViews/components/TaskPresenter/TaskPresenter.js +40 -35
  418. data/webpack/scenes/ContentViews/expansions/DetailsExpansion.js +2 -2
  419. data/webpack/scenes/ContentViews/expansions/RelatedCompositeContentViewsModal.js +1 -1
  420. data/webpack/scenes/ContentViews/expansions/RelatedContentViewComponentsModal.js +4 -4
  421. data/webpack/scenes/ContentViews/expansions/__tests__/contentViewComponentsModal.test.js +1 -1
  422. data/webpack/scenes/ContentViews/helpers.js +3 -0
  423. data/webpack/scenes/Hosts/ChangeContentSource/helpers.js +5 -0
  424. data/webpack/scenes/RedHatRepositories/RedHatRepositoriesPage.js +3 -3
  425. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepository.js +2 -1
  426. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/EnabledRepository.test.js +2 -0
  427. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnConfigurationConstants.js +3 -3
  428. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnTypeForm.js +2 -0
  429. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/{AirGappedTypeForm.js → ExportSyncForm.js} +7 -6
  430. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/{UpstreamServerTypeForm.js → NetworkSyncForm.js} +15 -7
  431. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/{AirGappedTypeForm.test.js → ExportSyncForm.test.js} +4 -4
  432. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/{UpstreamServerTypeForm.test.js → NetworkSyncForm.test.js} +8 -8
  433. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/index.js +11 -11
  434. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +1 -0
  435. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +8 -7
  436. data/webpack/scenes/Tasks/TaskActions.js +6 -0
  437. data/webpack/scenes/Tasks/TaskSelectors.js +11 -0
  438. data/webpack/scenes/Tasks/helpers.js +33 -5
  439. data/webpack/utils/helpers.js +2 -0
  440. metadata +158 -40
  441. data/app/models/setting/content.rb +0 -201
  442. data/webpack/components/Table/__test__/useBulkSelect.test.js +0 -99
  443. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard.js +0 -96
  444. data/webpack/scenes/ContentViews/Details/DetailsContainer.js +0 -36
@@ -1,4 +1,5 @@
1
1
  import React, { useState, useCallback } from 'react';
2
+ import { FormattedMessage } from 'react-intl';
2
3
  import {
3
4
  Skeleton, Button, Split, SplitItem, ActionList, ActionListItem, Dropdown,
4
5
  DropdownItem, KebabToggle,
@@ -9,13 +10,14 @@ import { useSelector, useDispatch } from 'react-redux';
9
10
  import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
10
11
  import EnableTracerEmptyState from './EnableTracerEmptyState';
11
12
  import TableWrapper from '../../../../Table/TableWrapper';
12
- import { useBulkSelect, useUrlParams } from '../../../../Table/TableHooks';
13
+ import { useBulkSelect, useTableSort, useUrlParams } from '../../../../Table/TableHooks';
13
14
  import { getHostTraces } from './HostTracesActions';
14
15
  import { resolveTraces } from '../RemoteExecutionActions';
15
16
  import { selectHostTracesStatus } from './HostTracesSelectors';
16
17
  import { resolveTraceUrl } from '../customizedRexUrlHelpers';
17
18
  import './TracesTab.scss';
18
19
  import hostIdNotReady from '../../HostDetailsActions';
20
+ import SortableColumnHeaders from '../../../../Table/components/SortableColumnHeaders';
19
21
 
20
22
  const TracesTab = () => {
21
23
  const hostDetails = useSelector(state => selectAPIResponse(state, 'HOST_DETAILS'));
@@ -26,20 +28,41 @@ const TracesTab = () => {
26
28
  content_facet_attributes: contentFacetAttributes,
27
29
  } = hostDetails;
28
30
  const showEnableTracer = (contentFacetAttributes?.katello_tracer_installed === false);
29
- const emptyContentTitle = __('This host currently does not have traces.');
30
- const emptyContentBody = __('Add traces by applying updates on this host.');
31
+ const emptyContentTitle = __('No applications to restart');
32
+ const emptyContentBody = (<FormattedMessage
33
+ id="traces-happy-empty"
34
+ values={{
35
+ pkgLink: <a href="#/Content/packages?status=Upgradable">{__('installing or updating packages')}</a>,
36
+ }}
37
+ defaultMessage={__('Traces may be listed here after {pkgLink}.')}
38
+ />);
31
39
  const emptySearchTitle = __('No matching traces found');
32
40
  const emptySearchBody = __('Try changing your search settings.');
33
- const fetchItems = useCallback(
34
- params =>
35
- (hostId ? getHostTraces(hostId, params) : hostIdNotReady),
36
- [hostId],
37
- );
41
+ const errorSearchTitle = __('Problem searching traces');
42
+ const columnHeaders = [
43
+ __('Application'),
44
+ __('Type'),
45
+ __('Helper'),
46
+ ];
47
+ const COLUMNS_TO_SORT_PARAMS = {
48
+ [columnHeaders[0]]: 'application',
49
+ [columnHeaders[1]]: 'app_type',
50
+ [columnHeaders[2]]: 'helper',
51
+ };
52
+ const {
53
+ pfSortParams, apiSortParams,
54
+ activeSortColumn, activeSortDirection,
55
+ } = useTableSort({
56
+ allColumns: columnHeaders,
57
+ columnsToSortParams: COLUMNS_TO_SORT_PARAMS,
58
+ initialSortColumnName: 'Application',
59
+ });
38
60
  const { searchParam } = useUrlParams();
39
61
  const [isBulkActionOpen, setIsBulkActionOpen] = useState(false);
40
62
  const toggleBulkAction = () => setIsBulkActionOpen(prev => !prev);
41
63
  const response = useSelector(state => selectAPIResponse(state, 'HOST_TRACES'));
42
64
  const { results, ...meta } = response;
65
+ const { error: errorSearchBody } = meta;
43
66
  const tracesSearchQuery = id => `id = ${id}`;
44
67
  const {
45
68
  selectOne, isSelected, searchQuery, selectedCount, isSelectable,
@@ -51,6 +74,11 @@ const TracesTab = () => {
51
74
  initialSearchQuery: searchParam || '',
52
75
  });
53
76
 
77
+ const fetchItems = useCallback(
78
+ params =>
79
+ (hostId ? getHostTraces(hostId, { ...apiSortParams, ...params }) : hostIdNotReady),
80
+ [hostId, apiSortParams],
81
+ );
54
82
 
55
83
  const onBulkRestartApp = () => {
56
84
  dispatch(resolveTraces({
@@ -120,6 +148,8 @@ const TracesTab = () => {
120
148
  emptyContentBody,
121
149
  emptySearchTitle,
122
150
  emptySearchBody,
151
+ errorSearchTitle,
152
+ errorSearchBody,
123
153
  status,
124
154
  searchQuery,
125
155
  updateSearchQuery,
@@ -129,20 +159,26 @@ const TracesTab = () => {
129
159
  actionButtons,
130
160
  }
131
161
  }
162
+ happyEmptyContent
163
+ ouiaId="host-traces-table"
132
164
  metadata={meta}
165
+ bookmarkController="katello_host_tracers"
133
166
  autocompleteEndpoint={`/hosts/${hostId}/traces/auto_complete_search`}
134
167
  foremanApiAutoComplete
135
168
  rowsCount={results?.length}
136
169
  variant={TableVariant.compact}
137
170
  displaySelectAllCheckbox
171
+ additionalListeners={[activeSortColumn, activeSortDirection]}
138
172
  {...selectAll}
139
173
  >
140
174
  <Thead>
141
175
  <Tr>
142
176
  <Th key="select_checkbox" />
143
- <Th>{__('Application')}</Th>
144
- <Th>{__('Type')}</Th>
145
- <Th>{__('Helper')}</Th>
177
+ <SortableColumnHeaders
178
+ columnHeaders={columnHeaders}
179
+ pfSortParams={pfSortParams}
180
+ columnsToSortParams={COLUMNS_TO_SORT_PARAMS}
181
+ />
146
182
  <Th key="action_menu" />
147
183
  </Tr>
148
184
  </Thead>
@@ -8,6 +8,7 @@ import { REX_FEATURES } from '../RemoteExecutionConstants';
8
8
  import { ErrataTab } from '../ErrataTab/ErrataTab.js';
9
9
  import mockErrataData from './errata.fixtures.json';
10
10
  import mockResolveErrataTask from './resolveErrata.fixtures.json';
11
+ import mockBookmarkData from './bookmarks.fixtures.json';
11
12
 
12
13
  const contentFacetAttributes = {
13
14
  id: 11,
@@ -17,6 +18,8 @@ const contentFacetAttributes = {
17
18
  };
18
19
  const hostName = 'foo.example.com';
19
20
 
21
+ const errataBookmarks = foremanApi.getApiUrl('/bookmarks?search=controller%3Dkatello_errata');
22
+
20
23
  const renderOptions = (facetAttributes = contentFacetAttributes) => ({
21
24
  apiNamespace: HOST_ERRATA_KEY,
22
25
  initialState: {
@@ -65,13 +68,18 @@ const makeMockErrata = ({ pageSize = 20, total = 100, page = 1 }) => {
65
68
 
66
69
  const hostErrata = foremanApi.getApiUrl('/hosts/1/errata');
67
70
  const autocompleteUrl = '/hosts/1/errata/auto_complete_search';
68
- const defaultQueryWithoutSearch = {
71
+ const baseQuery = {
69
72
  include_applicable: false,
70
73
  per_page: 20,
71
74
  page: 1,
72
75
  };
73
- const defaultQuery = { ...defaultQueryWithoutSearch, search: '' };
74
- const page2Query = { ...defaultQueryWithoutSearch, page: 2 };
76
+ const baseQueryWithSort = {
77
+ ...baseQuery,
78
+ sort_by: 'errata_id',
79
+ sort_order: 'asc',
80
+ };
81
+ const defaultQuery = { ...baseQueryWithSort, search: '' };
82
+ const page2Query = { ...baseQueryWithSort, page: 2 };
75
83
  const jobInvocations = foremanApi.getApiUrl('/job_invocations');
76
84
  const applyByKatelloAgentUrl = foremanApi.getApiUrl('/hosts/1/errata/apply');
77
85
 
@@ -79,10 +87,12 @@ let firstErrata;
79
87
  let thirdErrata;
80
88
  let searchDelayScope;
81
89
  let autoSearchScope;
90
+ let bookmarkScope;
82
91
 
83
92
  beforeEach(() => {
84
93
  const { results } = mockErrataData;
85
94
  [firstErrata, , thirdErrata] = results;
95
+ bookmarkScope = nockInstance.get(errataBookmarks).reply(200, mockBookmarkData);
86
96
  searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
87
97
  autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
88
98
  });
@@ -90,6 +100,7 @@ beforeEach(() => {
90
100
  afterEach(() => {
91
101
  assertNockRequest(searchDelayScope);
92
102
  assertNockRequest(autoSearchScope);
103
+ assertNockRequest(bookmarkScope);
93
104
  });
94
105
 
95
106
  test('Can call API for errata and show on screen on page load', async (done) => {
@@ -129,7 +140,7 @@ test('Can handle no errata being present', async (done) => {
129
140
  const { queryByText } = renderWithRedux(<ErrataTab />, renderOptions());
130
141
 
131
142
  // Assert that there are not any errata showing on the screen.
132
- await patientlyWaitFor(() => expect(queryByText('This host does not have any installable errata.')).toBeInTheDocument());
143
+ await patientlyWaitFor(() => expect(queryByText('This host has errata that are applicable, but not installable.')).toBeInTheDocument());
133
144
  // Assert request was made and completed, see helper function
134
145
  assertNockRequest(autocompleteScope);
135
146
  assertNockRequest(scope, done); // Pass jest callback to confirm test is done
@@ -171,8 +182,8 @@ test('Can display expanded errata details', async (done) => {
171
182
  expect(queryByText(firstErrata.cves[0].cve_id)).not.toBeInTheDocument();
172
183
 
173
184
  firstExpansion.click();
174
- // the errata details should now be hidden
175
- expect(getByText(firstErrata.summary)).not.toBeVisible();
185
+ // the errata details should now be gone
186
+ expect(queryByText(firstErrata.summary)).not.toBeInTheDocument();
176
187
  // Assert request was made and completed, see helper function
177
188
  assertNockRequest(autocompleteScope);
178
189
  assertNockRequest(scope, done); // Pass jest callback to confirm test is done
@@ -393,7 +404,7 @@ test('Can de-select items in select all mode across pages', async (done) => {
393
404
 
394
405
  const scope2 = nockInstance
395
406
  .get(hostErrata)
396
- .query({ ...defaultQueryWithoutSearch, page: 1 })
407
+ .query({ ...baseQueryWithSort, page: 1 })
397
408
  .reply(200, makeMockErrata({ page: 2 }));
398
409
 
399
410
  const scope3 = nockInstance
@@ -558,7 +569,7 @@ test('Toggle Group shows if it\'s not the default content view or library enviro
558
569
  assertNockRequest(scope, done); // Pass jest callback to confirm test is done
559
570
  });
560
571
 
561
- test('Toggle Group shows if it\'s the default content view but non-library environment', async (done) => {
572
+ test('Toggle Group does not show if it\'s the default content view ', async (done) => {
562
573
  const options = renderOptions({
563
574
  ...contentFacetAttributes,
564
575
  content_view_default: true,
@@ -579,41 +590,14 @@ test('Toggle Group shows if it\'s the default content view but non-library envir
579
590
 
580
591
  // Assert that the errata are now showing on the screen, but wait for them to appear.
581
592
  await patientlyWaitFor(() => expect(getAllByText('Important')[0]).toBeInTheDocument());
582
- expect(queryByLabelText('Installable Errata')).toBeInTheDocument();
583
- assertNockRequest(autocompleteScope);
584
- assertNockRequest(scope, done); // Pass jest callback to confirm test is done
585
- });
586
-
587
- test('Toggle Group shows if it\'s the library environment but non-default content view', async (done) => {
588
- const options = renderOptions({
589
- ...contentFacetAttributes,
590
- lifecycle_environment_library: true,
591
- });
592
- // Setup autocomplete with mockForemanAutoComplete since we aren't adding /katello
593
- const autocompleteScope = mockForemanAutocomplete(nockInstance, autocompleteUrl);
594
- const mockErrata = makeMockErrata({});
595
- // return errata data results when we look for errata
596
- const scope = nockInstance
597
- .get(hostErrata)
598
- .query(defaultQuery)
599
- .reply(200, mockErrata);
600
-
601
- const {
602
- queryByLabelText,
603
- getAllByText,
604
- } = renderWithRedux(<ErrataTab />, options);
605
-
606
- // Assert that the errata are now showing on the screen, but wait for them to appear.
607
- await patientlyWaitFor(() => expect(getAllByText('Important')[0]).toBeInTheDocument());
608
- expect(queryByLabelText('Installable Errata')).toBeInTheDocument();
593
+ expect(queryByLabelText('Installable Errata')).not.toBeInTheDocument();
609
594
  assertNockRequest(autocompleteScope);
610
595
  assertNockRequest(scope, done); // Pass jest callback to confirm test is done
611
596
  });
612
597
 
613
- test('Toggle Group does not show if it\'s the default content view and library environment', async (done) => {
598
+ test('Toggle Group does not show if it\'s the library environment', async (done) => {
614
599
  const options = renderOptions({
615
600
  ...contentFacetAttributes,
616
- content_view_default: true,
617
601
  lifecycle_environment_library: true,
618
602
  });
619
603
  // Setup autocomplete with mockForemanAutoComplete since we aren't adding /katello
@@ -743,6 +727,7 @@ test('Can filter by errata type', async (done) => {
743
727
 
744
728
  const {
745
729
  queryByText,
730
+ queryByLabelText,
746
731
  getByRole,
747
732
  getAllByText,
748
733
  getByText,
@@ -753,7 +738,8 @@ test('Can filter by errata type', async (done) => {
753
738
  // the Bugfix text in the table is just a text node, while the dropdown is a button
754
739
  expect(getByText('Bugfix', { ignore: ['button', 'title'] })).toBeInTheDocument();
755
740
  expect(getByText('Enhancement', { ignore: ['button', 'title'] })).toBeInTheDocument();
756
- const typeDropdown = queryByText('Type', { ignore: 'th' });
741
+ const typeContainer = queryByLabelText('select Type container', { ignore: 'th' });
742
+ const typeDropdown = within(typeContainer).queryByText('Type');
757
743
  expect(typeDropdown).toBeInTheDocument();
758
744
  fireEvent.click(typeDropdown);
759
745
  const security = getByRole('option', { name: 'select Security' });
@@ -786,6 +772,7 @@ test('Can filter by severity', async (done) => {
786
772
  const {
787
773
  queryByText,
788
774
  getByRole,
775
+ queryByLabelText,
789
776
  getAllByText,
790
777
  getByText,
791
778
  } = renderWithRedux(<ErrataTab />, renderOptions());
@@ -796,7 +783,8 @@ test('Can filter by severity', async (done) => {
796
783
  expect(getByText('Moderate', { ignore: ['button', 'title'] })).toBeInTheDocument();
797
784
  expect(getByText('Important', { ignore: ['.pf-c-select__toggle-text', 'title'] })).toBeInTheDocument();
798
785
  expect(getByText('Critical', { ignore: ['button', 'title'] })).toBeInTheDocument();
799
- const severityDropdown = queryByText('Severity', { ignore: 'th' });
786
+ const severityContainer = queryByLabelText('select Severity container', { ignore: 'th' });
787
+ const severityDropdown = within(severityContainer).queryByText('Severity');
800
788
  expect(severityDropdown).toBeInTheDocument();
801
789
  fireEvent.click(severityDropdown);
802
790
  const important = getByRole('option', { name: 'select Important' });
@@ -963,7 +951,7 @@ test('Apply button chooses remote execution', async (done) => {
963
951
 
964
952
  const scope1 = nockInstance
965
953
  .get(hostErrata)
966
- .query(defaultQueryWithoutSearch)
954
+ .query(baseQuery)
967
955
  .reply(200, mockErrata);
968
956
 
969
957
  const resolveErrataScope = nockInstance
@@ -1001,7 +989,7 @@ test('Can bulk apply via remote execution', async (done) => {
1001
989
 
1002
990
  const scope1 = nockInstance
1003
991
  .get(hostErrata)
1004
- .query(defaultQueryWithoutSearch)
992
+ .query(baseQuery)
1005
993
  .reply(200, mockErrata);
1006
994
 
1007
995
  // eslint-disable-next-line camelcase
@@ -1050,7 +1038,7 @@ test('Can select all, exclude and bulk apply via remote execution', async (done)
1050
1038
 
1051
1039
  const scope1 = nockInstance
1052
1040
  .get(hostErrata)
1053
- .query(defaultQueryWithoutSearch)
1041
+ .query(baseQuery)
1054
1042
  .reply(200, mockErrata);
1055
1043
 
1056
1044
  const jobInvocationBody = ({ job_invocation: { inputs } }) =>
@@ -6,6 +6,8 @@ import { HOST_PACKAGES_KEY, PACKAGES_SEARCH_QUERY } from '../PackagesTab/HostPac
6
6
  import { PackagesTab } from '../PackagesTab/PackagesTab.js';
7
7
  import mockPackagesData from './packages.fixtures.json';
8
8
  import { REX_FEATURES } from '../RemoteExecutionConstants';
9
+ import * as hooks from '../../../../Table/TableHooks';
10
+ import mockBookmarkData from './bookmarks.fixtures.json';
9
11
 
10
12
  const contentFacetAttributes = {
11
13
  id: 11,
@@ -15,6 +17,8 @@ const contentFacetAttributes = {
15
17
  };
16
18
 
17
19
  const hostname = 'test-host.example.com';
20
+ const packageBookmarks = foremanApi.getApiUrl('/bookmarks?search=controller%3Dkatello_host_installed_packages');
21
+
18
22
  const renderOptions = (facetAttributes = contentFacetAttributes) => ({
19
23
  apiNamespace: HOST_PACKAGES_KEY,
20
24
  initialState: {
@@ -34,21 +38,29 @@ const renderOptions = (facetAttributes = contentFacetAttributes) => ({
34
38
  const hostPackages = foremanApi.getApiUrl('/hosts/1/packages');
35
39
  const jobInvocations = foremanApi.getApiUrl('/job_invocations');
36
40
  const autocompleteUrl = '/hosts/1/packages/auto_complete_search';
37
- const defaultQueryWithoutSearch = {
41
+ const baseQuery = {
38
42
  include_latest_upgradable: true,
39
43
  per_page: 20,
40
44
  page: 1,
41
45
  };
46
+
47
+ const defaultQueryWithoutSearch = {
48
+ ...baseQuery,
49
+ sort_by: 'nvra',
50
+ sort_order: 'asc',
51
+ };
42
52
  const defaultQuery = { ...defaultQueryWithoutSearch, search: '' };
43
53
 
44
54
  let firstPackage;
45
55
  let secondPackage;
46
56
  let searchDelayScope;
47
57
  let autoSearchScope;
58
+ let bookmarkScope;
48
59
 
49
60
  beforeEach(() => {
50
61
  const { results } = mockPackagesData;
51
62
  [firstPackage, secondPackage] = results;
63
+ bookmarkScope = nockInstance.get(packageBookmarks).reply(200, mockBookmarkData);
52
64
  searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
53
65
  autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
54
66
  });
@@ -56,6 +68,7 @@ beforeEach(() => {
56
68
  afterEach(() => {
57
69
  assertNockRequest(searchDelayScope);
58
70
  assertNockRequest(autoSearchScope);
71
+ assertNockRequest(bookmarkScope);
59
72
  });
60
73
 
61
74
  test('Can call API for packages and show on screen on page load', async (done) => {
@@ -390,3 +403,25 @@ test('Remove is disabled when in select all mode', async (done) => {
390
403
  assertNockRequest(autocompleteScope);
391
404
  assertNockRequest(scope, done);
392
405
  });
406
+
407
+ test('Sets initial search query from url params', async (done) => {
408
+ // Setup autocomplete with mockForemanAutoComplete since we aren't adding /katello
409
+ const autocompleteScope = mockForemanAutocomplete(nockInstance, autocompleteUrl);
410
+ const scope = nockInstance
411
+ .get(hostPackages)
412
+ .query({ ...defaultQuery, search: `name=${firstPackage.name}` })
413
+ .reply(200, { ...mockPackagesData, results: [firstPackage] });
414
+
415
+ jest.spyOn(hooks, 'useUrlParams').mockImplementation(() => ({
416
+ searchParam: `name=${firstPackage.name}`,
417
+ }));
418
+
419
+ const { getAllByText, queryByText } = renderWithRedux(<PackagesTab />, renderOptions());
420
+
421
+ await patientlyWaitFor(() => expect(getAllByText(firstPackage.name)[0]).toBeInTheDocument());
422
+ expect(queryByText(secondPackage.name)).not.toBeInTheDocument();
423
+
424
+ assertNockRequest(autocompleteScope);
425
+ assertNockRequest(scope, done); // Pass jest callback to confirm test is done
426
+ });
427
+
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { renderWithRedux, patientlyWaitFor, fireEvent } from 'react-testing-lib-wrapper';
2
+ import { renderWithRedux, patientlyWaitFor, within, fireEvent } from 'react-testing-lib-wrapper';
3
3
  import { nockInstance, assertNockRequest, mockAutocomplete, mockSetting } from '../../../../../test-utils/nockWrapper';
4
4
  import katelloApi, { foremanApi } from '../../../../../services/api';
5
5
  import { REPOSITORY_SETS_KEY } from '../RepositorySetsTab/RepositorySetsConstants';
@@ -36,20 +36,23 @@ const autocompleteUrl = '/repository_sets/auto_complete_search';
36
36
  const repositorySetBookmarks = foremanApi.getApiUrl('/bookmarks?search=controller%3Dkatello_product_contents');
37
37
  const contentOverride = foremanApi.getApiUrl('/hosts/1/subscriptions/content_override');
38
38
 
39
- const limitToEnvQuery = {
39
+ const defaultQuery = {
40
40
  content_access_mode_env: true,
41
41
  content_access_mode_all: true,
42
42
  host_id: 1,
43
43
  per_page: 20,
44
44
  page: 1,
45
45
  search: '',
46
+ sort_by: 'name',
47
+ sort_order: 'asc',
46
48
  };
47
- const showAllQuery = {
48
- ...limitToEnvQuery,
49
+ const libraryQuery = {
50
+ ...defaultQuery,
49
51
  content_access_mode_env: false,
50
52
  };
51
53
 
52
54
  let firstRepoSet;
55
+ let secondRepoSet;
53
56
  let searchDelayScope;
54
57
  let autoSearchScope;
55
58
  let bookmarkScope;
@@ -57,7 +60,7 @@ let bookmarkScope;
57
60
  beforeEach(() => {
58
61
  // jest.resetModules();
59
62
  const { results } = mockRepoSetData;
60
- [firstRepoSet] = results;
63
+ [firstRepoSet, secondRepoSet] = results;
61
64
  bookmarkScope = nockInstance.get(repositorySetBookmarks).reply(200, mockBookmarkData);
62
65
  searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
63
66
  autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
@@ -73,7 +76,7 @@ test('Can call API for repository sets and show basic table', async (done) => {
73
76
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
74
77
  const scope = nockInstance
75
78
  .get(hostRepositorySets)
76
- .query(limitToEnvQuery)
79
+ .query(defaultQuery)
77
80
  .reply(200, mockRepoSetData);
78
81
 
79
82
  const { getByText } = renderWithRedux(<RepositorySetsTab />, renderOptions());
@@ -97,7 +100,7 @@ test('Can handle no repository sets being present', async (done) => {
97
100
 
98
101
  const scope = nockInstance
99
102
  .get(hostRepositorySets)
100
- .query(limitToEnvQuery)
103
+ .query(defaultQuery)
101
104
  .reply(200, noResults);
102
105
 
103
106
  const { queryByText } = renderWithRedux(<RepositorySetsTab />, renderOptions());
@@ -113,7 +116,7 @@ test('Toggle Group shows if it\'s not the default content view or library enviro
113
116
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
114
117
  const scope = nockInstance
115
118
  .get(hostRepositorySets)
116
- .query(limitToEnvQuery)
119
+ .query(defaultQuery)
117
120
  .reply(200, mockRepoSetData);
118
121
 
119
122
  const {
@@ -128,7 +131,7 @@ test('Toggle Group shows if it\'s not the default content view or library enviro
128
131
  assertNockRequest(scope, done); // Pass jest callback to confirm test is done
129
132
  });
130
133
 
131
- test('Toggle Group shows if it\'s the default content view but non-library environment', async (done) => {
134
+ test('Toggle Group does not show if it\'s the default content view ', async (done) => {
132
135
  const options = renderOptions({
133
136
  ...contentFacetAttributes,
134
137
  content_view_default: true,
@@ -137,7 +140,7 @@ test('Toggle Group shows if it\'s the default content view but non-library envir
137
140
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
138
141
  const scope = nockInstance
139
142
  .get(hostRepositorySets)
140
- .query(limitToEnvQuery)
143
+ .query(libraryQuery)
141
144
  .reply(200, mockRepoSetData);
142
145
 
143
146
  const {
@@ -147,46 +150,21 @@ test('Toggle Group shows if it\'s the default content view but non-library envir
147
150
 
148
151
  // Assert that the errata are now showing on the screen, but wait for them to appear.
149
152
  await patientlyWaitFor(() => expect(getByText(firstRepoSet.contentUrl)).toBeInTheDocument());
150
- expect(queryByLabelText('Limit to environment')).toBeInTheDocument();
151
- assertNockRequest(autocompleteScope);
152
- assertNockRequest(scope, done); // Pass jest callback to confirm test is done
153
- });
154
-
155
- test('Toggle Group shows if it\'s the library environment but a non-default content view', async (done) => {
156
- const options = renderOptions({
157
- ...contentFacetAttributes,
158
- lifecycle_environment_library: true,
159
- });
160
- const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
161
- // return errata data results when we look for errata
162
- const scope = nockInstance
163
- .get(hostRepositorySets)
164
- .query(limitToEnvQuery)
165
- .reply(200, mockRepoSetData);
166
-
167
- const {
168
- queryByLabelText,
169
- getByText,
170
- } = renderWithRedux(<RepositorySetsTab />, options);
171
-
172
- // Assert that the errata are now showing on the screen, but wait for them to appear.
173
- await patientlyWaitFor(() => expect(getByText(firstRepoSet.contentUrl)).toBeInTheDocument());
174
- expect(queryByLabelText('Limit to environment')).toBeInTheDocument();
153
+ expect(queryByLabelText('Limit to environment')).not.toBeInTheDocument();
175
154
  assertNockRequest(autocompleteScope);
176
155
  assertNockRequest(scope, done); // Pass jest callback to confirm test is done
177
156
  });
178
157
 
179
- test('Toggle Group does not show if it\'s the library environment and default content view', async (done) => {
158
+ test('Toggle Group does not show if it\'s the library environment', async (done) => {
180
159
  const options = renderOptions({
181
160
  ...contentFacetAttributes,
182
161
  lifecycle_environment_library: true,
183
- content_view_default: true,
184
162
  });
185
163
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
186
164
  // return errata data results when we look for errata
187
165
  const scope = nockInstance
188
166
  .get(hostRepositorySets)
189
- .query(showAllQuery)
167
+ .query(libraryQuery)
190
168
  .reply(200, mockRepoSetData);
191
169
 
192
170
  const {
@@ -207,7 +185,7 @@ test('Can toggle with the Toggle Group ', async (done) => {
207
185
  // return errata data results when we look for errata
208
186
  const scope = nockInstance
209
187
  .get(hostRepositorySets)
210
- .query(limitToEnvQuery)
188
+ .query(defaultQuery)
211
189
  .reply(200, mockRepoSetData);
212
190
 
213
191
  const {
@@ -227,11 +205,13 @@ test('Can override to disabled', async (done) => {
227
205
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
228
206
  const scope = nockInstance
229
207
  .get(hostRepositorySets)
230
- .query(limitToEnvQuery)
208
+ .query(defaultQuery)
231
209
  .reply(200, mockRepoSetData);
210
+ const overrides = JSON.parse(JSON.stringify(mockContentOverride));
211
+ overrides.results[0].enabled_content_override = false;
232
212
  const contentOverrideScope = nockInstance
233
213
  .put(contentOverride)
234
- .reply(200, mockContentOverride);
214
+ .reply(200, overrides);
235
215
 
236
216
  const { getByText, getAllByText, getAllByLabelText } =
237
217
  renderWithRedux(<RepositorySetsTab />, renderOptions());
@@ -263,11 +243,14 @@ test('Can override to enabled', async (done) => {
263
243
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
264
244
  const scope = nockInstance
265
245
  .get(hostRepositorySets)
266
- .query(limitToEnvQuery)
246
+ .query(defaultQuery)
267
247
  .reply(200, mockRepoSetData);
248
+ const overrides = JSON.parse(JSON.stringify(mockContentOverride));
249
+ overrides.results[1].enabled_content_override = true;
250
+
268
251
  const contentOverrideScope = nockInstance
269
252
  .put(contentOverride)
270
- .reply(200, mockContentOverride);
253
+ .reply(200, overrides);
271
254
 
272
255
  const {
273
256
  getByText, queryByText, getAllByText, getAllByLabelText,
@@ -299,12 +282,14 @@ test('Can reset to default', async (done) => {
299
282
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
300
283
  const scope = nockInstance
301
284
  .get(hostRepositorySets)
302
- .query(limitToEnvQuery)
285
+ .query(defaultQuery)
303
286
  .reply(200, mockRepoSetData);
287
+ const overrides = JSON.parse(JSON.stringify(mockContentOverride));
288
+ overrides.results[1].enabled_content_override = null;
289
+
304
290
  const contentOverrideScope = nockInstance
305
291
  .put(contentOverride)
306
- .reply(200, mockContentOverride);
307
-
292
+ .reply(200, overrides);
308
293
  const {
309
294
  getByText, queryByText, getAllByText, getAllByLabelText,
310
295
  } = renderWithRedux(<RepositorySetsTab />, renderOptions());
@@ -313,6 +298,7 @@ test('Can reset to default', async (done) => {
313
298
  await patientlyWaitFor(() => expect(getByText(firstRepoSet.contentUrl)).toBeInTheDocument());
314
299
  expect(getAllByText('Enabled')).toHaveLength(2);
315
300
  expect(getAllByText('Disabled')).toHaveLength(1);
301
+
316
302
  // The second item is overridden to disabled but would normally be enabled; we're going to reset
317
303
  const actionMenu = getAllByLabelText('Actions')[1].closest('button');
318
304
  fireEvent.click(actionMenu);
@@ -330,3 +316,65 @@ test('Can reset to default', async (done) => {
330
316
  assertNockRequest(scope);
331
317
  assertNockRequest(contentOverrideScope, done); // Pass jest callback to confirm test is done
332
318
  });
319
+
320
+ test('Can override in bulk', async (done) => {
321
+ const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
322
+ const scope = nockInstance
323
+ .get(hostRepositorySets)
324
+ .query(defaultQuery)
325
+ .reply(200, mockRepoSetData);
326
+ const contentOverrideScope = nockInstance
327
+ .put(contentOverride)
328
+ .reply(200, mockContentOverride);
329
+
330
+ const {
331
+ getByText, getByLabelText, queryByText,
332
+ } = renderWithRedux(<RepositorySetsTab />, renderOptions());
333
+
334
+ await patientlyWaitFor(() => expect(getByText(firstRepoSet.contentUrl)).toBeInTheDocument());
335
+ getByLabelText('Select row 0').click();
336
+ getByLabelText('Select row 1').click();
337
+ const actionMenu = getByLabelText('bulk_actions');
338
+ actionMenu.click();
339
+ const resetToDefault = queryByText('Reset to default');
340
+ expect(resetToDefault).toBeInTheDocument();
341
+ resetToDefault.click();
342
+
343
+ assertNockRequest(autocompleteScope);
344
+ assertNockRequest(scope);
345
+ assertNockRequest(contentOverrideScope, done); // Pass jest callback to confirm test is done});
346
+ });
347
+
348
+ test('Can filter by status', async (done) => {
349
+ const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
350
+ const scope = nockInstance
351
+ .get(hostRepositorySets)
352
+ .query(defaultQuery)
353
+ .reply(200, mockRepoSetData);
354
+
355
+ const scope2 = nockInstance
356
+ .get(hostRepositorySets)
357
+ .query({ ...defaultQuery, status: 'overridden' })
358
+ .reply(200, { ...mockRepoSetData, results: [secondRepoSet] });
359
+
360
+ const {
361
+ getByText, queryByLabelText, getByRole,
362
+ } = renderWithRedux(<RepositorySetsTab />, renderOptions());
363
+
364
+ await patientlyWaitFor(() => expect(getByText(firstRepoSet.contentUrl)).toBeInTheDocument());
365
+
366
+ const statusContainer = queryByLabelText('select Status container', { ignore: 'th' });
367
+ const statusDropdown = within(statusContainer).queryByText('Status');
368
+ expect(statusDropdown).toBeInTheDocument();
369
+ fireEvent.click(statusDropdown);
370
+ const overridden = getByRole('option', { name: 'select Overridden' });
371
+ fireEvent.click(overridden);
372
+ await patientlyWaitFor(() => {
373
+ expect(getByText('Overridden')).toBeInTheDocument();
374
+ });
375
+ assertNockRequest(autocompleteScope);
376
+ assertNockRequest(scope);
377
+ assertNockRequest(searchDelayScope);
378
+ assertNockRequest(autoSearchScope);
379
+ assertNockRequest(scope2, done); // Pass jest callback to confirm test is done
380
+ });