blacklight 7.41.0 → 8.0.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (425) hide show
  1. checksums.yaml +4 -4
  2. data/.env +2 -3
  3. data/.github/workflows/ruby.yml +81 -0
  4. data/.rubocop.yml +243 -14
  5. data/.rubocop_todo.yml +137 -429
  6. data/Gemfile +11 -6
  7. data/README.md +11 -3
  8. data/VERSION +1 -1
  9. data/app/assets/javascripts/blacklight/blacklight.esm.js +384 -0
  10. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -0
  11. data/app/assets/javascripts/blacklight/blacklight.js +374 -493
  12. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -0
  13. data/app/assets/stylesheets/blacklight/_autocomplete.scss +25 -0
  14. data/app/assets/stylesheets/blacklight/_blacklight_base.scss +1 -1
  15. data/app/assets/stylesheets/blacklight/_bookmark.scss +16 -0
  16. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +8 -0
  17. data/app/assets/stylesheets/blacklight/_constraints.scss +4 -4
  18. data/app/assets/stylesheets/blacklight/_facets.scss +72 -44
  19. data/app/assets/stylesheets/blacklight/_header.scss +0 -15
  20. data/app/assets/stylesheets/blacklight/_icons.scss +0 -14
  21. data/app/assets/stylesheets/blacklight/_mixins.scss +20 -0
  22. data/app/assets/stylesheets/blacklight/_modal.scss +8 -2
  23. data/app/assets/stylesheets/blacklight/_search_form.scss +30 -3
  24. data/app/assets/stylesheets/blacklight/_search_history.scss +10 -1
  25. data/app/assets/stylesheets/blacklight/_search_results.scss +6 -2
  26. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +4 -1
  27. data/app/builders/blacklight/action_builder.rb +18 -9
  28. data/app/components/blacklight/advanced_search_form_component.html.erb +3 -3
  29. data/app/components/blacklight/advanced_search_form_component.rb +8 -10
  30. data/app/components/blacklight/constraints_component.rb +27 -37
  31. data/app/components/blacklight/document/action_component.rb +12 -10
  32. data/app/components/blacklight/document/actions_component.rb +2 -2
  33. data/app/components/blacklight/document/bookmark_component.html.erb +9 -0
  34. data/app/components/blacklight/document/bookmark_component.rb +4 -2
  35. data/app/components/blacklight/document/citation_component.rb +5 -3
  36. data/app/components/blacklight/document/group_component.rb +7 -3
  37. data/app/components/blacklight/document/sidebar_component.html.erb +2 -0
  38. data/app/components/blacklight/document/sidebar_component.rb +16 -0
  39. data/app/components/blacklight/document/thumbnail_component.html.erb +2 -7
  40. data/app/components/blacklight/document/thumbnail_component.rb +1 -9
  41. data/app/components/blacklight/document_component.html.erb +1 -1
  42. data/app/components/blacklight/document_component.rb +16 -78
  43. data/app/components/blacklight/document_metadata_component.html.erb +2 -4
  44. data/app/components/blacklight/document_metadata_component.rb +5 -10
  45. data/app/components/blacklight/facet_component.rb +3 -3
  46. data/app/components/blacklight/facet_field_checkboxes_component.html.erb +4 -4
  47. data/app/components/blacklight/facet_field_checkboxes_component.rb +1 -1
  48. data/app/components/blacklight/facet_field_component.html.erb +4 -5
  49. data/app/components/blacklight/facet_field_component.rb +9 -2
  50. data/app/components/blacklight/facet_field_list_component.html.erb +3 -3
  51. data/app/components/blacklight/facet_field_list_component.rb +37 -5
  52. data/app/components/blacklight/facet_field_no_layout_component.rb +0 -2
  53. data/app/components/blacklight/facet_item_component.rb +1 -43
  54. data/app/components/blacklight/facet_item_pivot_component.rb +21 -23
  55. data/app/components/blacklight/header_component.rb +1 -1
  56. data/app/components/blacklight/hidden_search_state_component.rb +1 -2
  57. data/app/components/blacklight/icons/icon_component.rb +4 -9
  58. data/app/components/blacklight/icons/legacy_icon_component.rb +30 -0
  59. data/app/components/blacklight/icons/list_component.rb +16 -0
  60. data/app/components/blacklight/icons/search_component.rb +16 -0
  61. data/app/components/blacklight/metadata_field_component.html.erb +2 -2
  62. data/app/components/blacklight/metadata_field_component.rb +24 -8
  63. data/app/components/blacklight/metadata_field_layout_component.rb +4 -25
  64. data/app/components/blacklight/response/facet_group_component.html.erb +3 -5
  65. data/app/components/blacklight/response/facet_group_component.rb +29 -8
  66. data/app/components/blacklight/response/pagination_component.html.erb +1 -1
  67. data/app/components/blacklight/response/pagination_component.rb +2 -11
  68. data/app/components/blacklight/response/sort_component.html.erb +6 -1
  69. data/app/components/blacklight/response/sort_component.rb +1 -16
  70. data/app/components/blacklight/response/spellcheck_component.rb +18 -7
  71. data/app/components/blacklight/response/view_type_button_component.rb +3 -7
  72. data/app/components/blacklight/response/view_type_component.rb +4 -6
  73. data/app/components/blacklight/search/sidebar_component.html.erb +8 -0
  74. data/app/components/blacklight/search/sidebar_component.rb +17 -0
  75. data/app/components/blacklight/search_bar_component.html.erb +20 -15
  76. data/app/components/blacklight/search_bar_component.rb +2 -16
  77. data/app/components/blacklight/search_button_component.rb +3 -3
  78. data/app/components/blacklight/search_context_component.rb +43 -10
  79. data/app/components/blacklight/search_header_component.html.erb +2 -0
  80. data/app/components/blacklight/search_header_component.rb +6 -0
  81. data/app/components/blacklight/start_over_button_component.rb +5 -3
  82. data/app/components/blacklight/system/dropdown_component.rb +8 -5
  83. data/app/components/blacklight/system/flash_message_component.html.erb +4 -2
  84. data/app/components/blacklight/system/flash_message_component.rb +12 -3
  85. data/app/components/blacklight/system/modal_component.html.erb +1 -1
  86. data/app/components/blacklight/system/modal_component.rb +1 -3
  87. data/app/components/blacklight/top_navbar_component.html.erb +1 -1
  88. data/app/components/blacklight/top_navbar_component.rb +0 -4
  89. data/app/controllers/bookmarks_controller.rb +1 -0
  90. data/app/controllers/catalog_controller.rb +1 -0
  91. data/app/controllers/concerns/blacklight/bookmarks.rb +10 -9
  92. data/app/controllers/concerns/blacklight/catalog.rb +21 -83
  93. data/app/controllers/concerns/blacklight/controller.rb +3 -41
  94. data/app/controllers/concerns/blacklight/search_context.rb +25 -7
  95. data/app/controllers/concerns/blacklight/search_history.rb +2 -0
  96. data/app/controllers/concerns/blacklight/searchable.rb +12 -1
  97. data/app/controllers/concerns/blacklight/token_based_user.rb +13 -1
  98. data/app/controllers/search_history_controller.rb +1 -0
  99. data/app/helpers/blacklight/blacklight_helper_behavior.rb +12 -310
  100. data/app/helpers/blacklight/catalog_helper_behavior.rb +22 -139
  101. data/app/helpers/blacklight/component_helper_behavior.rb +2 -53
  102. data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -119
  103. data/app/helpers/blacklight/facets_helper_behavior.rb +4 -321
  104. data/app/helpers/blacklight/icon_helper_behavior.rb +5 -7
  105. data/app/helpers/blacklight/layout_helper_behavior.rb +4 -3
  106. data/app/helpers/blacklight/render_partials_helper_behavior.rb +11 -31
  107. data/app/helpers/blacklight/url_helper_behavior.rb +12 -97
  108. data/app/helpers/blacklight_helper.rb +1 -0
  109. data/app/helpers/catalog_helper.rb +1 -0
  110. data/app/javascript/blacklight/bookmark_toggle.js +13 -19
  111. data/app/javascript/blacklight/button_focus.js +12 -10
  112. data/app/javascript/blacklight/checkbox_submit.js +68 -123
  113. data/app/javascript/blacklight/core.js +5 -7
  114. data/app/javascript/blacklight/index.js +13 -0
  115. data/app/javascript/blacklight/modal.js +99 -164
  116. data/app/javascript/blacklight/modalForm.js +60 -0
  117. data/app/javascript/blacklight/search_context.js +46 -54
  118. data/app/models/blacklight/facet_paginator.rb +3 -2
  119. data/app/models/blacklight/icon.rb +4 -2
  120. data/app/models/bookmark.rb +0 -2
  121. data/app/models/concerns/blacklight/configurable.rb +5 -4
  122. data/app/models/concerns/blacklight/document/active_model_shim.rb +1 -10
  123. data/app/models/concerns/blacklight/document/cache_key.rb +1 -0
  124. data/app/models/concerns/blacklight/document/dublin_core.rb +2 -1
  125. data/app/models/concerns/blacklight/document/email.rb +1 -0
  126. data/app/models/concerns/blacklight/document/export.rb +2 -1
  127. data/app/models/concerns/blacklight/document/extensions.rb +1 -0
  128. data/app/models/concerns/blacklight/document/schema_org.rb +1 -0
  129. data/app/models/concerns/blacklight/document/semantic_fields.rb +2 -1
  130. data/app/models/concerns/blacklight/document/sms.rb +1 -0
  131. data/app/models/concerns/blacklight/suggest/response.rb +1 -0
  132. data/app/models/concerns/blacklight/user.rb +17 -8
  133. data/app/models/record_mailer.rb +13 -12
  134. data/app/models/search.rb +1 -7
  135. data/app/models/solr_document.rb +1 -0
  136. data/app/presenters/blacklight/clause_presenter.rb +1 -1
  137. data/app/presenters/blacklight/document_presenter.rb +23 -50
  138. data/app/presenters/blacklight/facet_field_presenter.rb +39 -14
  139. data/app/presenters/blacklight/facet_grouped_item_presenter.rb +1 -5
  140. data/app/presenters/blacklight/facet_item_pivot_presenter.rb +60 -0
  141. data/app/presenters/blacklight/facet_item_presenter.rb +3 -9
  142. data/app/presenters/blacklight/field_presenter.rb +1 -0
  143. data/app/presenters/blacklight/index_presenter.rb +2 -40
  144. data/app/presenters/blacklight/json_presenter.rb +10 -6
  145. data/app/presenters/blacklight/rendering/link_to_facet.rb +2 -5
  146. data/app/presenters/blacklight/show_presenter.rb +1 -9
  147. data/app/presenters/blacklight/thumbnail_presenter.rb +1 -1
  148. data/app/services/blacklight/bookmarks_search_builder.rb +22 -0
  149. data/app/services/blacklight/field_retriever.rb +12 -21
  150. data/app/services/blacklight/search_service.rb +10 -17
  151. data/app/values/blacklight/types.rb +0 -18
  152. data/app/views/bookmarks/_clear_bookmarks_widget.html.erb +8 -1
  153. data/app/views/bookmarks/_tools.html.erb +7 -12
  154. data/app/views/catalog/_advanced_search_form.html.erb +0 -1
  155. data/app/views/catalog/_bookmark_control.html.erb +1 -1
  156. data/app/views/catalog/_citation.html.erb +1 -1
  157. data/app/views/catalog/_constraints.html.erb +1 -14
  158. data/app/views/catalog/_document.atom.builder +12 -14
  159. data/app/views/catalog/_document.html.erb +5 -3
  160. data/app/views/catalog/_document.rss.builder +2 -4
  161. data/app/views/catalog/_facet_layout.html.erb +2 -2
  162. data/app/views/catalog/_facets.html.erb +5 -4
  163. data/app/views/catalog/_home_text.html.erb +2 -14
  164. data/app/views/catalog/_per_page_widget.html.erb +10 -1
  165. data/app/views/catalog/_search_form.html.erb +2 -2
  166. data/app/views/catalog/_search_header.html.erb +1 -2
  167. data/app/views/catalog/_search_results.html.erb +2 -2
  168. data/app/views/catalog/_search_sidebar.html.erb +5 -1
  169. data/app/views/catalog/_show_main_content.html.erb +11 -16
  170. data/app/views/catalog/_show_sidebar.html.erb +2 -2
  171. data/app/views/catalog/_show_tools.html.erb +8 -14
  172. data/app/views/catalog/_view_type_group.html.erb +1 -1
  173. data/app/views/catalog/email.html.erb +2 -2
  174. data/app/views/catalog/email_success.html.erb +5 -6
  175. data/app/views/catalog/facet.html.erb +7 -5
  176. data/app/views/catalog/index.atom.builder +12 -14
  177. data/app/views/catalog/index.html.erb +4 -1
  178. data/app/views/catalog/index.json.jbuilder +19 -19
  179. data/app/views/catalog/index.rss.builder +1 -1
  180. data/app/views/catalog/opensearch.xml.builder +1 -1
  181. data/app/views/catalog/sms.html.erb +2 -2
  182. data/app/views/catalog/sms_success.html.erb +5 -6
  183. data/app/views/catalog/suggest.html.erb +3 -0
  184. data/app/views/kaminari/blacklight/_page.html.erb +2 -1
  185. data/app/views/layouts/blacklight/base.html.erb +13 -2
  186. data/app/views/search_history/index.html.erb +6 -2
  187. data/app/views/shared/_flash_messages.html.erb +1 -1
  188. data/app/views/shared/_modal.html.erb +3 -3
  189. data/blacklight.gemspec +7 -11
  190. data/config/importmap.rb +3 -0
  191. data/config/locales/blacklight.ar.yml +0 -1
  192. data/config/locales/blacklight.ca.yml +0 -1
  193. data/config/locales/blacklight.de.yml +0 -1
  194. data/config/locales/blacklight.en.yml +0 -2
  195. data/config/locales/blacklight.es.yml +0 -1
  196. data/config/locales/blacklight.fr.yml +0 -1
  197. data/config/locales/blacklight.hu.yml +0 -1
  198. data/config/locales/blacklight.it.yml +0 -1
  199. data/config/locales/blacklight.nl.yml +0 -1
  200. data/config/locales/blacklight.pt-BR.yml +0 -1
  201. data/config/locales/blacklight.sq.yml +0 -1
  202. data/config/locales/blacklight.zh.yml +0 -1
  203. data/config/routes.rb +3 -2
  204. data/db/migrate/20140202020201_create_searches.rb +1 -0
  205. data/db/migrate/20140202020202_create_bookmarks.rb +1 -0
  206. data/db/migrate/20140320000000_add_polymorphic_type_to_bookmarks.rb +1 -0
  207. data/docker-compose.yml +3 -3
  208. data/lib/blacklight/abstract_repository.rb +1 -6
  209. data/lib/blacklight/component.rb +47 -10
  210. data/lib/blacklight/configuration/context.rb +4 -4
  211. data/lib/blacklight/configuration/display_field.rb +7 -9
  212. data/lib/blacklight/configuration/facet_field.rb +17 -11
  213. data/lib/blacklight/configuration/field.rb +1 -0
  214. data/lib/blacklight/configuration/fields.rb +12 -15
  215. data/lib/blacklight/configuration/index_field.rb +1 -0
  216. data/lib/blacklight/configuration/null_display_field.rb +17 -0
  217. data/lib/blacklight/configuration/search_field.rb +1 -0
  218. data/lib/blacklight/configuration/show_field.rb +1 -0
  219. data/lib/blacklight/configuration/sort_field.rb +1 -0
  220. data/lib/blacklight/configuration/tool_config.rb +1 -0
  221. data/lib/blacklight/configuration/view_config.rb +14 -10
  222. data/lib/blacklight/configuration.rb +310 -365
  223. data/lib/blacklight/engine.rb +8 -24
  224. data/lib/blacklight/exceptions.rb +2 -2
  225. data/lib/blacklight/nested_open_struct_with_hash_access.rb +7 -13
  226. data/lib/blacklight/open_struct_with_hash_access.rb +23 -6
  227. data/lib/blacklight/parameters.rb +7 -21
  228. data/lib/blacklight/routes/exportable.rb +1 -0
  229. data/lib/blacklight/routes/searchable.rb +2 -1
  230. data/lib/blacklight/routes.rb +1 -0
  231. data/lib/blacklight/search_builder.rb +10 -10
  232. data/lib/blacklight/search_state/filter_field.rb +8 -25
  233. data/lib/blacklight/search_state/pivot_filter_field.rb +144 -0
  234. data/lib/blacklight/search_state.rb +23 -79
  235. data/lib/blacklight/solr/document.rb +1 -0
  236. data/lib/blacklight/solr/facet_paginator.rb +1 -0
  237. data/lib/blacklight/solr/repository.rb +4 -24
  238. data/lib/blacklight/solr/request.rb +1 -0
  239. data/lib/blacklight/solr/response/facets.rb +21 -5
  240. data/lib/blacklight/solr/response/group.rb +1 -0
  241. data/lib/blacklight/solr/response/group_response.rb +1 -0
  242. data/lib/blacklight/solr/response/more_like_this.rb +1 -0
  243. data/lib/blacklight/solr/response/pagination_methods.rb +4 -3
  244. data/lib/blacklight/solr/response/params.rb +5 -4
  245. data/lib/blacklight/solr/response/response.rb +1 -0
  246. data/lib/blacklight/solr/response/spelling.rb +1 -0
  247. data/lib/blacklight/solr/response.rb +16 -3
  248. data/lib/blacklight/solr/search_builder_behavior.rb +16 -35
  249. data/lib/blacklight/solr.rb +7 -0
  250. data/lib/blacklight/version.rb +1 -0
  251. data/lib/blacklight.rb +26 -14
  252. data/lib/generators/blacklight/assets/importmap_generator.rb +55 -0
  253. data/lib/generators/blacklight/assets/propshaft_generator.rb +25 -0
  254. data/lib/generators/blacklight/assets/sprockets_generator.rb +66 -0
  255. data/lib/generators/blacklight/assets_generator.rb +13 -86
  256. data/lib/generators/blacklight/controller_generator.rb +4 -3
  257. data/lib/generators/blacklight/document_generator.rb +1 -0
  258. data/lib/generators/blacklight/install_generator.rb +4 -3
  259. data/lib/generators/blacklight/models_generator.rb +1 -0
  260. data/lib/generators/blacklight/search_builder_generator.rb +1 -0
  261. data/lib/generators/blacklight/solr_generator.rb +1 -1
  262. data/lib/generators/blacklight/templates/catalog_controller.rb +34 -8
  263. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +1 -70
  264. data/lib/generators/blacklight/test_support_generator.rb +5 -3
  265. data/lib/generators/blacklight/user_generator.rb +7 -9
  266. data/lib/railties/blacklight.rake +6 -7
  267. data/package.json +10 -13
  268. data/rollup.config.js +27 -0
  269. data/spec/components/blacklight/constraints_component_spec.rb +17 -13
  270. data/spec/components/blacklight/document/action_component_spec.rb +6 -1
  271. data/spec/components/blacklight/document_component_spec.rb +22 -131
  272. data/spec/components/blacklight/facet_component_spec.rb +3 -18
  273. data/spec/components/blacklight/facet_field_checkboxes_component_spec.rb +1 -2
  274. data/spec/components/blacklight/facet_field_list_component_spec.rb +7 -6
  275. data/spec/components/blacklight/facet_item_pivot_component_spec.rb +10 -9
  276. data/spec/components/blacklight/response/view_type_component_spec.rb +66 -0
  277. data/spec/components/blacklight/search_bar_component_spec.rb +1 -1
  278. data/spec/components/blacklight/search_context_component_spec.rb +17 -8
  279. data/spec/controllers/blacklight/catalog/component_configuration_spec.rb +1 -6
  280. data/spec/controllers/blacklight/{base_spec.rb → catalog_spec.rb} +2 -2
  281. data/spec/controllers/bookmarks_controller_spec.rb +2 -3
  282. data/spec/controllers/catalog_controller_spec.rb +13 -135
  283. data/spec/features/advanced_search_spec.rb +0 -56
  284. data/spec/features/autocomplete_spec.rb +1 -1
  285. data/spec/features/axe_spec.rb +1 -6
  286. data/spec/features/bookmarks_spec.rb +1 -1
  287. data/spec/features/facets_spec.rb +6 -4
  288. data/spec/features/search_context_spec.rb +5 -11
  289. data/spec/features/search_results_spec.rb +0 -33
  290. data/spec/features/sitelinks_search_box.rb +13 -0
  291. data/spec/helpers/blacklight/configuration_helper_behavior_spec.rb +2 -138
  292. data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +0 -387
  293. data/spec/helpers/blacklight/icon_helper_behavior_spec.rb +8 -0
  294. data/spec/helpers/blacklight/layout_helper_behavior_spec.rb +3 -20
  295. data/spec/helpers/blacklight/render_partials_helper_behavior_spec.rb +5 -7
  296. data/spec/helpers/blacklight/url_helper_behavior_spec.rb +9 -131
  297. data/spec/helpers/blacklight_helper_spec.rb +8 -252
  298. data/spec/helpers/catalog_helper_spec.rb +7 -118
  299. data/spec/i18n_spec.rb +1 -0
  300. data/spec/integration/generators/blacklight/solr_generator_spec.rb +1 -1
  301. data/spec/lib/blacklight/component_spec.rb +27 -32
  302. data/spec/lib/blacklight/configuration/facet_field_spec.rb +27 -16
  303. data/spec/lib/blacklight/configuration/field_spec.rb +1 -1
  304. data/spec/lib/blacklight/configuration/view_config_spec.rb +1 -1
  305. data/spec/lib/blacklight/open_struct_with_hash_access_spec.rb +2 -2
  306. data/spec/lib/blacklight/parameters_spec.rb +1 -4
  307. data/spec/lib/blacklight/search_state/filter_field_spec.rb +4 -4
  308. data/spec/lib/blacklight/search_state/pivot_filter_field_spec.rb +117 -0
  309. data/spec/lib/blacklight/search_state_spec.rb +80 -198
  310. data/spec/lib/tasks/blacklight_task_spec.rb +1 -0
  311. data/spec/models/blacklight/configuration_spec.rb +17 -51
  312. data/spec/models/blacklight/document/active_model_shim_spec.rb +2 -2
  313. data/spec/models/blacklight/icon_spec.rb +31 -15
  314. data/spec/models/blacklight/search_builder_spec.rb +9 -9
  315. data/spec/models/blacklight/solr/document_spec.rb +3 -3
  316. data/spec/models/blacklight/solr/repository_spec.rb +0 -45
  317. data/spec/models/blacklight/solr/response/facets_spec.rb +27 -27
  318. data/spec/models/blacklight/solr/response/group_response_spec.rb +1 -0
  319. data/spec/models/blacklight/solr/response/group_spec.rb +1 -0
  320. data/spec/models/blacklight/solr/response_spec.rb +9 -2
  321. data/spec/models/blacklight/solr/search_builder_spec.rb +24 -44
  322. data/spec/models/blacklight/user_spec.rb +22 -0
  323. data/spec/models/solr_document_spec.rb +3 -9
  324. data/spec/presenters/blacklight/clause_presenter_spec.rb +1 -0
  325. data/spec/presenters/blacklight/document_presenter_spec.rb +2 -3
  326. data/spec/presenters/blacklight/facet_field_presenter_spec.rb +85 -12
  327. data/spec/presenters/blacklight/facet_grouped_item_presenter_spec.rb +1 -0
  328. data/spec/presenters/blacklight/facet_item_presenter_spec.rb +14 -13
  329. data/spec/presenters/blacklight/field_presenter_spec.rb +0 -14
  330. data/spec/presenters/blacklight/index_presenter_spec.rb +2 -5
  331. data/spec/presenters/blacklight/json_presenter_spec.rb +1 -0
  332. data/spec/presenters/blacklight/link_alternate_presenter_spec.rb +3 -2
  333. data/spec/presenters/blacklight/show_presenter_spec.rb +20 -30
  334. data/spec/presenters/thumbnail_presenter_spec.rb +1 -1
  335. data/spec/requests/load_suggestions_spec.rb +16 -0
  336. data/spec/routing/catalog_routing_spec.rb +2 -1
  337. data/spec/services/blacklight/search_service_spec.rb +39 -76
  338. data/spec/spec_helper.rb +8 -9
  339. data/spec/support/controller_level_helpers.rb +1 -2
  340. data/spec/support/features/search_helpers.rb +39 -0
  341. data/spec/support/features/session_helpers.rb +1 -0
  342. data/spec/support/features.rb +3 -0
  343. data/spec/support/view_component_capybara_test_helpers.rb +8 -0
  344. data/spec/test_app_templates/Gemfile.extra +1 -0
  345. data/spec/test_app_templates/lib/generators/test_app_generator.rb +9 -2
  346. data/spec/views/catalog/_document.html.erb_spec.rb +3 -34
  347. data/spec/views/catalog/_facet_index_navigation.html.erb_spec.rb +1 -1
  348. data/spec/views/catalog/_paginate_compact.html.erb_spec.rb +0 -2
  349. data/spec/views/catalog/_search_header.erb_spec.rb +1 -0
  350. data/spec/views/catalog/_show_sidebar.erb_spec.rb +1 -0
  351. data/spec/views/catalog/_show_tools.html.erb_spec.rb +5 -66
  352. data/spec/views/catalog/_view_type_group.html.erb_spec.rb +17 -9
  353. data/spec/views/catalog/email_success.html.erb_spec.rb +2 -2
  354. data/spec/views/catalog/facet.html.erb_spec.rb +6 -3
  355. data/spec/views/catalog/index.atom.builder_spec.rb +17 -11
  356. data/spec/views/catalog/index.html.erb_spec.rb +5 -6
  357. data/spec/views/catalog/index.json.jbuilder_spec.rb +2 -2
  358. data/spec/views/catalog/show.html.erb_spec.rb +3 -25
  359. data/spec/views/catalog/sms_success.html.erb_spec.rb +2 -2
  360. data/tasks/blacklight.rake +11 -9
  361. data/template.demo.rb +7 -7
  362. metadata +77 -189
  363. data/.babelrc +0 -11
  364. data/.github/matrix.json +0 -62
  365. data/.github/workflows/build.yml +0 -16
  366. data/.github/workflows/lint.yml +0 -23
  367. data/.github/workflows/main.yml +0 -23
  368. data/.github/workflows/test.yml +0 -53
  369. data/app/assets/images/blacklight/list.svg +0 -1
  370. data/app/assets/images/blacklight/search.svg +0 -1
  371. data/app/assets/stylesheets/blacklight/_twitter_typeahead.scss +0 -37
  372. data/app/components/blacklight/content_areas_shim.rb +0 -13
  373. data/app/components/blacklight/search/per_page_component.html.erb +0 -2
  374. data/app/components/blacklight/search/per_page_component.rb +0 -50
  375. data/app/components/blacklight/search_context/server_item_pagination_component.html.erb +0 -10
  376. data/app/components/blacklight/search_context/server_item_pagination_component.rb +0 -15
  377. data/app/components/blacklight/system/dropdown_button_component.rb +0 -18
  378. data/app/controllers/concerns/blacklight/base.rb +0 -12
  379. data/app/controllers/concerns/blacklight/default_component_configuration.rb +0 -64
  380. data/app/controllers/concerns/blacklight/facet.rb +0 -69
  381. data/app/controllers/concerns/blacklight/search_fields.rb +0 -46
  382. data/app/helpers/blacklight/hash_as_hidden_fields_helper_behavior.rb +0 -27
  383. data/app/helpers/blacklight/render_constraints_helper_behavior.rb +0 -188
  384. data/app/helpers/blacklight/search_history_constraints_helper_behavior.rb +0 -97
  385. data/app/helpers/blacklight/suggest_helper_behavior.rb +0 -13
  386. data/app/javascript/blacklight/autocomplete.js +0 -36
  387. data/app/javascript/blacklight/facet_load.js +0 -22
  388. data/app/presenters/blacklight/search_bar_presenter.rb +0 -47
  389. data/app/views/catalog/_constraints_element.html.erb +0 -14
  390. data/app/views/catalog/_document_action.html.erb +0 -5
  391. data/app/views/catalog/_facet_group.html.erb +0 -5
  392. data/app/views/catalog/_facet_limit.html.erb +0 -3
  393. data/app/views/catalog/_index.html.erb +0 -1
  394. data/app/views/catalog/_index_header.html.erb +0 -22
  395. data/app/views/catalog/_previous_next_doc.html.erb +0 -2
  396. data/app/views/catalog/_show.html.erb +0 -6
  397. data/app/views/catalog/_show_header.html.erb +0 -2
  398. data/app/views/catalog/_thumbnail.html.erb +0 -1
  399. data/lib/blacklight/deprecations/engine_configuration.rb +0 -66
  400. data/lib/blacklight/deprecations/search_state_normalization.rb +0 -52
  401. data/spec/components/blacklight/header_component_spec.rb +0 -20
  402. data/spec/components/blacklight/icons/icon_component_spec.rb +0 -42
  403. data/spec/components/blacklight/response/pagination_component_spec.rb +0 -53
  404. data/spec/components/blacklight/search_context/server_item_pagination_component_spec.rb +0 -35
  405. data/spec/controllers/blacklight/facet_spec.rb +0 -33
  406. data/spec/controllers/blacklight/search_fields_spec.rb +0 -62
  407. data/spec/features/citation_spec.rb +0 -10
  408. data/spec/features/sitelinks_search_box_spec.rb +0 -13
  409. data/spec/features/sms_spec.rb +0 -12
  410. data/spec/helpers/blacklight/hash_as_hidden_fields_behavior_spec.rb +0 -26
  411. data/spec/helpers/blacklight/render_constraints_helper_behavior_spec.rb +0 -92
  412. data/spec/helpers/blacklight/search_history_constraints_helper_behavior_spec.rb +0 -101
  413. data/spec/helpers/blacklight/suggest_helper_behavior_spec.rb +0 -48
  414. data/spec/lib/blacklight/engine_spec.rb +0 -41
  415. data/spec/presenters/blacklight/search_bar_presenter_spec.rb +0 -94
  416. data/spec/services/blacklight/field_retriever_spec.rb +0 -17
  417. data/spec/support/view_component_test_helpers.rb +0 -35
  418. data/spec/views/catalog/_constraints.html.erb_spec.rb +0 -33
  419. data/spec/views/catalog/_facet_group.html.erb_spec.rb +0 -84
  420. data/spec/views/catalog/_facets.html.erb_spec.rb +0 -15
  421. data/spec/views/catalog/_index.html.erb_spec.rb +0 -62
  422. data/spec/views/catalog/_index_header.html.erb_spec.rb +0 -35
  423. data/spec/views/catalog/_previous_next_doc.html.erb_spec.rb +0 -22
  424. data/spec/views/catalog/_show.html.erb_spec.rb +0 -62
  425. data/spec/views/catalog/_thumbnail.html.erb_spec.rb +0 -38
data/spec/i18n_spec.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'i18n/tasks'
3
4
 
4
5
  RSpec.describe 'I18n', type: :i18n do
@@ -20,7 +20,7 @@ RSpec.describe Blacklight::SolrGenerator do
20
20
  end
21
21
 
22
22
  after do
23
- files_to_test.each { |file| File.delete(file) if File.exist?(file) }
23
+ files_to_test.each { |file| FileUtils.rm_rf(file) }
24
24
  end
25
25
 
26
26
  it "creates config files" do
@@ -1,48 +1,43 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.describe Blacklight::Component, type: :component do
4
- let(:component_class) { Blacklight::System::ModalComponent }
3
+ RSpec.describe Blacklight::Component do
4
+ let(:component_class) { Blacklight::DocumentTitleComponent }
5
5
 
6
- before do
7
- component_class.reset_compiler!
8
- ViewComponent::CompileCache.invalidate!
9
-
10
- component_class.class_eval do
11
- undef :call if method_defined?(:call)
6
+ context "subclassed" do
7
+ it "returns our Compiler implementation" do
8
+ expect(component_class.ancestors).to include described_class
9
+ expect(component_class.compiler).to be_a Blacklight::Component::EngineCompiler
12
10
  end
13
11
  end
14
12
 
15
- after do
16
- component_class.reset_compiler!
17
- ViewComponent::CompileCache.invalidate!
13
+ describe Blacklight::Component::EngineCompiler do
14
+ subject(:compiler) { described_class.new(component_class) }
18
15
 
19
- component_class.class_eval do
20
- undef :call if method_defined?(:call)
21
- end
22
- end
16
+ let(:original_compiler) { ViewComponent::Compiler.new(component_class) }
17
+ let(:original_path) { original_compiler.send(:templates).first[:path] }
18
+ let(:resolved_path) { compiler.templates.first[:path] }
23
19
 
24
- context "without overrides" do
25
- it "renders the engine template" do
26
- render_inline(component_class.new)
27
- expect(page).to have_css('.modal-header')
20
+ context "without overrides" do
21
+ it "links to engine template" do
22
+ expect(resolved_path).not_to include(".internal_test_app")
23
+ expect(resolved_path).to eql(original_path)
24
+ end
28
25
  end
29
- end
30
26
 
31
- context "with overrides" do
32
- around do |ex|
33
- FileUtils.mkdir_p(Rails.root.join('app/components/blacklight/system'))
34
- Rails.root.join("app/components/blacklight/system/modal_component.html.erb").open("w") do |f|
35
- f.puts '<div class="custom-modal">Overridden</div>'
27
+ context "with overrides" do
28
+ let(:path_match) do
29
+ Regexp.new(Regexp.escape(File.join(".internal_test_app", component_class.view_component_path)))
36
30
  end
37
31
 
38
- ex.run
39
- ensure
40
- Rails.root.join('app/components/blacklight/system/modal_component.html.erb').unlink
41
- end
32
+ before do
33
+ allow(File).to receive(:exist?).and_call_original
34
+ allow(File).to receive(:exist?).with(path_match).and_return(true)
35
+ end
42
36
 
43
- it "renders to application template" do
44
- render_inline(component_class.new)
45
- expect(page).to have_css('.custom-modal')
37
+ it "links to application template" do
38
+ expect(resolved_path).to include(".internal_test_app")
39
+ expect(resolved_path).not_to eql(original_path)
40
+ end
46
41
  end
47
42
  end
48
43
  end
@@ -1,30 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe Blacklight::Configuration::FacetField do
4
- describe 'link_to_search' do
5
- subject { described_class.new(link_to_search: true) }
6
-
7
- it 'is deprecated' do
8
- expect(Deprecation).to receive(:warn)
9
- expect(subject.normalize!)
10
- expect(subject.link_to_facet).to eq true
11
- end
12
- end
13
-
14
4
  describe '#normalize!' do
15
- it 'preserves existing properties' do
16
- expected = double
17
- subject.presenter = expected
5
+ context 'with existing properties' do
6
+ let(:expected_presenter) { double }
7
+ let(:expected_component) { double }
18
8
 
19
- subject.normalize!
9
+ before do
10
+ subject.presenter = expected_presenter
11
+ subject.component = expected_component
12
+ end
20
13
 
21
- expect(subject.presenter).to eq expected
14
+ it 'preserves existing properties' do
15
+ subject.normalize!
16
+
17
+ expect(subject.presenter).to eq expected_presenter
18
+ expect(subject.component).to eq expected_component
19
+ end
22
20
  end
23
21
 
24
- it 'adds a default presenter' do
22
+ it 'adds a default presenter and component' do
25
23
  subject.normalize!
26
24
 
27
25
  expect(subject.presenter).to eq Blacklight::FacetFieldPresenter
26
+ expect(subject.component).to eq Blacklight::FacetFieldListComponent
27
+ end
28
+
29
+ context 'when component is set to true' do
30
+ before do
31
+ subject.component = true
32
+ end
33
+
34
+ it 'casts to the default component' do
35
+ subject.normalize!
36
+
37
+ expect(subject.component).to eq Blacklight::FacetFieldListComponent
38
+ end
28
39
  end
29
40
  end
30
41
  end
@@ -8,7 +8,7 @@ RSpec.describe Blacklight::Configuration::Field do
8
8
 
9
9
  describe '#display_label' do
10
10
  it "looks up the label to display for the given document and field" do
11
- allow(I18n).to receive(:t).with(:"blacklight.search.fields.my_context.some_key", default: [:"blacklight.search.fields.some_key", label, subject.default_label]).and_return('x')
11
+ allow(I18n).to receive(:t).with(:'blacklight.search.fields.my_context.some_key', default: [:'blacklight.search.fields.some_key', label, subject.default_label]).and_return('x')
12
12
  expect(subject.display_label('my_context')).to eq 'x'
13
13
  end
14
14
  end
@@ -8,7 +8,7 @@ RSpec.describe Blacklight::Configuration::ViewConfig do
8
8
 
9
9
  describe '#display_label' do
10
10
  it "looks up the label to display for the given document and field" do
11
- allow(I18n).to receive(:t).with(:"blacklight.search.view_title.my_view", default: [:"blacklight.search.view.my_view", label, nil, "My view"]).and_return('x')
11
+ allow(I18n).to receive(:t).with(:'blacklight.search.view_title.my_view', default: [:'blacklight.search.view.my_view', label, nil, "My view"]).and_return('x')
12
12
  expect(subject.display_label).to eq 'x'
13
13
  end
14
14
  end
@@ -54,11 +54,11 @@ RSpec.describe Blacklight::OpenStructWithHashAccess do
54
54
  end
55
55
 
56
56
  it "is true if the key exists" do
57
- expect(subject.key?(:a)).to eq true
57
+ expect(subject.key?(:a)).to be true
58
58
  end
59
59
 
60
60
  it "is false if the key does not exist" do
61
- expect(subject.key?(:c)).to eq false
61
+ expect(subject.key?(:c)).to be false
62
62
  end
63
63
  end
64
64
 
@@ -72,11 +72,8 @@ RSpec.describe Blacklight::Parameters do
72
72
  context 'with filter_search_state_fields set to false' do
73
73
  let(:blacklight_config) { Blacklight::Configuration.new(filter_search_state_fields: false) }
74
74
 
75
- it 'allows all params, but warns about the behavior' do
76
- allow(Deprecation).to receive(:warn)
75
+ it 'allows all params' do
77
76
  expect(params.permit_search_params.to_h.with_indifferent_access).to include(a: 1, b: 2, c: [])
78
-
79
- expect(Deprecation).to have_received(:warn).with(described_class, /including: a, b, and c/).at_least(:once)
80
77
  end
81
78
  end
82
79
 
@@ -160,7 +160,7 @@ RSpec.describe Blacklight::SearchState::FilterField do
160
160
 
161
161
  context "With facet.missing field" do
162
162
  let(:params) do
163
- { f: { "-some_field": ["[* TO *]"] } }
163
+ { f: { '-some_field': ["[* TO *]"] } }
164
164
  end
165
165
 
166
166
  it "removes facet.missing facet params" do
@@ -190,12 +190,12 @@ RSpec.describe Blacklight::SearchState::FilterField do
190
190
 
191
191
  describe '#include?' do
192
192
  it 'checks whether the value is currently selected' do
193
- expect(search_state.filter('some_field').include?('1')).to eq true
194
- expect(search_state.filter('some_field').include?('3')).to eq false
193
+ expect(search_state.filter('some_field').include?('1')).to be true
194
+ expect(search_state.filter('some_field').include?('3')).to be false
195
195
  end
196
196
 
197
197
  it 'handles value indirection' do
198
- expect(search_state.filter('some_field').include?(OpenStruct.new(value: '1'))).to eq true
198
+ expect(search_state.filter('some_field').include?(OpenStruct.new(value: '1'))).to be true
199
199
  end
200
200
  end
201
201
  end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Blacklight::SearchState::PivotFilterField do
4
+ let(:value_class) { described_class::PivotValue }
5
+ let(:search_state) { Blacklight::SearchState.new(params.with_indifferent_access, blacklight_config, controller) }
6
+
7
+ let(:params) { { f: { some_field: %w[1 2], some_other_field: ['3'] } } }
8
+ let(:blacklight_config) do
9
+ Blacklight::Configuration.new.configure do |config|
10
+ config.add_facet_field 'pivot_field', pivot: %w[some_field some_other_field], filter_class: described_class
11
+ end
12
+ end
13
+ let(:controller) { double }
14
+
15
+ describe '#add' do
16
+ context 'with a string value' do
17
+ it 'adds the parameter to the first pivot\'s filter list' do
18
+ filter = search_state.filter('pivot_field')
19
+ new_state = filter.add('4')
20
+
21
+ expect(new_state.filter('some_field').values).to eq %w[1 2 4]
22
+ expect(new_state.filter('pivot_field').values&.map(&:value)).to eq %w[1 2 4]
23
+ end
24
+
25
+ context 'without any parameters in the url' do
26
+ let(:params) { {} }
27
+
28
+ it 'adds the necessary structure' do
29
+ filter = search_state.filter('some_field')
30
+ new_state = filter.add('1')
31
+
32
+ expect(new_state.filter('pivot_field').values&.map(&:value)).to eq %w[1]
33
+ expect(new_state.params).to include(:f)
34
+ end
35
+ end
36
+ end
37
+
38
+ context 'with a pivot facet-type item' do
39
+ it 'includes the pivot facet fqs' do
40
+ filter = search_state.filter('pivot_field')
41
+ new_state = filter.add(value_class.new(fq: { some_other_field: '5' }, value: '4'))
42
+
43
+ expect(new_state.filter('some_field').values).to eq %w[1 2 4]
44
+ expect(new_state.filter('some_other_field').values).to eq %w[3 5]
45
+ end
46
+ end
47
+
48
+ context 'with an array' do
49
+ pending 'decide how inclusive facets should work with pivots'
50
+ end
51
+ end
52
+
53
+ describe '#remove' do
54
+ it 'returns a search state without the given filter applied' do
55
+ filter = search_state.filter('some_field')
56
+ new_state = filter.remove('1')
57
+
58
+ expect(new_state.filter('pivot_field').values&.map(&:value)).to eq ['2']
59
+ end
60
+
61
+ context 'with a pivot facet-type item' do
62
+ it 'includes the pivot facet fqs' do
63
+ filter = search_state.filter('pivot_field')
64
+ new_state = filter.remove(value_class.new(fq: { some_other_field: '3' }, value: '1'))
65
+
66
+ expect(new_state.filter('some_field').values).to eq %w[2]
67
+ expect(new_state.filter('some_other_field').values).to eq []
68
+ end
69
+ end
70
+
71
+ it 'removes the whole field if there are no filter left for the field' do
72
+ filter = search_state.filter('pivot_field')
73
+ new_state = filter.remove(value_class.new(fq: { some_other_field: '3' }, value: '1'))
74
+
75
+ expect(new_state.params[:f]).not_to include :some_other_field
76
+ expect(new_state.filter('pivot_field').values&.map(&:fq)).to eql([some_other_field: nil])
77
+ end
78
+
79
+ it 'removes the filter parameter entirely if there are no filters left' do
80
+ filter = search_state.filter('pivot_field')
81
+ new_state = filter.remove(value_class.new(fq: { some_other_field: '3' }, value: '1'))
82
+ new_state = new_state.filter('pivot_field').remove(value_class.new(fq: { some_other_field: '3' }, value: '2'))
83
+
84
+ expect(new_state.filter('pivot_field').values).to eq []
85
+ expect(new_state.params).not_to include :f
86
+ end
87
+
88
+ context 'with an array' do
89
+ pending 'decide how inclusive facets should work with pivots'
90
+ end
91
+
92
+ context "With facet.missing field" do
93
+ pending 'decide how facet.missing should work with pivots'
94
+ end
95
+ end
96
+
97
+ describe '#values' do
98
+ it 'returns the currently selected values of the filter' do
99
+ expect(search_state.filter('pivot_field').values.map(&:value)).to eq %w[1 2]
100
+ end
101
+
102
+ context 'with an array' do
103
+ pending 'decide how inclusive facets should work with pivots'
104
+ end
105
+ end
106
+
107
+ describe '#include?' do
108
+ it 'checks whether the value is currently selected' do
109
+ expect(search_state.filter('some_field').include?('1')).to be true
110
+ expect(search_state.filter('some_field').include?('3')).to be false
111
+ end
112
+
113
+ it 'handles value indirection' do
114
+ expect(search_state.filter('some_field').include?(value_class.new(value: '1'))).to be true
115
+ end
116
+ end
117
+ end
@@ -3,8 +3,6 @@
3
3
  RSpec.describe Blacklight::SearchState do
4
4
  subject(:search_state) { described_class.new(params, blacklight_config, controller) }
5
5
 
6
- around { |test| Deprecation.silence(described_class) { test.call } }
7
-
8
6
  let(:blacklight_config) do
9
7
  Blacklight::Configuration.new.configure do |config|
10
8
  config.index.title_field = 'title_tsim'
@@ -81,19 +79,6 @@ RSpec.describe Blacklight::SearchState do
81
79
  end
82
80
  end
83
81
 
84
- describe 'interface compatibility with params' do
85
- let(:simple_facet_fields) { [:ff] }
86
- let(:params) { parameter_class.new f: { ff: ['xyz'] } }
87
-
88
- it 'implements param methods' do
89
- Deprecation.silence(described_class) do
90
- expect(search_state.to_unsafe_h).to eq('f' => { 'ff' => ['xyz'] })
91
- expect(search_state.fetch(:f)).to eq('ff' => ['xyz'])
92
- expect(search_state.select { |k, _v,| k == 'f' }).to eq('f' => { 'ff' => ['xyz'] })
93
- end
94
- end
95
- end
96
-
97
82
  describe '#query_param' do
98
83
  let(:params) { parameter_class.new q: 'xyz' }
99
84
 
@@ -102,25 +87,16 @@ RSpec.describe Blacklight::SearchState do
102
87
  end
103
88
  end
104
89
 
105
- describe '#filter_params' do
106
- let(:simple_facet_fields) { [:ff] }
107
- let(:params) { parameter_class.new f: { ff: ['xyz'] } }
108
-
109
- it 'returns the query param' do
110
- expect(search_state.filter_params.deep_symbolize_keys).to eq(ff: ['xyz'])
111
- end
112
- end
113
-
114
90
  describe '#has_constraints?' do
115
91
  it 'is false' do
116
- expect(search_state.has_constraints?).to eq false
92
+ expect(search_state.has_constraints?).to be false
117
93
  end
118
94
 
119
95
  context 'with a query param' do
120
96
  let(:params) { parameter_class.new q: 'xyz' }
121
97
 
122
98
  it 'is true' do
123
- expect(search_state.has_constraints?).to eq true
99
+ expect(search_state.has_constraints?).to be true
124
100
  end
125
101
  end
126
102
 
@@ -129,7 +105,7 @@ RSpec.describe Blacklight::SearchState do
129
105
  let(:params) { parameter_class.new f: { ff: ['xyz'] } }
130
106
 
131
107
  it 'is true' do
132
- expect(search_state.has_constraints?).to eq true
108
+ expect(search_state.has_constraints?).to be true
133
109
  end
134
110
  end
135
111
  end
@@ -213,112 +189,6 @@ RSpec.describe Blacklight::SearchState do
213
189
  end
214
190
  end
215
191
 
216
- describe "add_facet_params" do
217
- let(:params_no_existing_facet) do
218
- parameter_class.new q: "query",
219
- search_field: "search_field",
220
- per_page: "50"
221
- end
222
- let(:params_existing_facets) do
223
- parameter_class.new q: "query",
224
- search_field: "search_field",
225
- per_page: "50",
226
- f: { "facet_field_1" => ["value1"],
227
- "facet_field_2" => %w[value2 value2a] }
228
- end
229
-
230
- context "when there are no pre-existing facets" do
231
- let(:params) { params_no_existing_facet }
232
-
233
- it "adds facet value" do
234
- result_params = search_state.add_facet_params("facet_field", "facet_value")
235
- expect(result_params[:f]).to be_a Hash
236
- expect(result_params[:f]["facet_field"]).to be_a_kind_of(Array)
237
- expect(result_params[:f]["facet_field"]).to eq ["facet_value"]
238
- end
239
-
240
- it "leaves non-facet params alone" do
241
- result_params = search_state.add_facet_params("facet_field_2", "new_facet_value")
242
-
243
- params.each_pair do |key, _value|
244
- next if key == :f
245
-
246
- expect(result_params[key]).to eq params[key]
247
- end
248
- end
249
-
250
- it "uses the facet's key in the url" do
251
- blacklight_config.add_facet_field 'some_key', single: true, field: "a_solr_field"
252
-
253
- result_params = search_state.add_facet_params('some_key', 'my_value')
254
-
255
- expect(result_params[:f]['some_key']).to have(1).item
256
- expect(result_params[:f]['some_key'].first).to eq 'my_value'
257
- end
258
- end
259
-
260
- context "when there are pre-existing facets" do
261
- let(:params) { params_existing_facets }
262
-
263
- it "adds a facet param to existing facet constraints" do
264
- result_params = search_state.add_facet_params("facet_field_2", "new_facet_value")
265
-
266
- expect(result_params[:f]).to be_a Hash
267
-
268
- params_existing_facets[:f].each_pair do |facet_field, _value_list|
269
- expect(result_params[:f][facet_field]).to be_a_kind_of(Array)
270
- if facet_field == 'facet_field_2'
271
- expect(result_params[:f][facet_field]).to eq (params_existing_facets[:f][facet_field] | ["new_facet_value"])
272
- else
273
- expect(result_params[:f][facet_field]).to eq params_existing_facets[:f][facet_field]
274
- end
275
- end
276
- end
277
-
278
- it "leaves non-facet params alone" do
279
- result_params = search_state.add_facet_params("facet_field_2", "new_facet_value")
280
-
281
- params.each_pair do |key, _value|
282
- next if key == 'f'
283
-
284
- expect(result_params[key]).to eq params[key]
285
- end
286
- end
287
- end
288
-
289
- context "with a facet selected in the params" do
290
- let(:params) { parameter_class.new f: { 'single_value_facet_field' => 'other_value' } }
291
-
292
- it "replaces facets configured as single" do
293
- blacklight_config.add_facet_field 'single_value_facet_field', single: true
294
- result_params = search_state.add_facet_params('single_value_facet_field', 'my_value')
295
-
296
- expect(result_params[:f]['single_value_facet_field']).to have(1).item
297
- expect(result_params[:f]['single_value_facet_field'].first).to eq 'my_value'
298
- end
299
- end
300
-
301
- it "accepts a FacetItem instead of a plain facet value" do
302
- result_params = search_state.add_facet_params('facet_field_1', double(value: 123))
303
-
304
- expect(result_params[:f]['facet_field_1']).to include(123)
305
- end
306
-
307
- it "defers to the field set on a FacetItem" do
308
- result_params = search_state.add_facet_params('facet_field_1', double(field: 'facet_field_2', value: 123))
309
-
310
- expect(result_params[:f]['facet_field_1']).to be_blank
311
- expect(result_params[:f]['facet_field_2']).to include(123)
312
- end
313
-
314
- it "adds any extra fq parameters from the FacetItem" do
315
- result_params = search_state.add_facet_params('facet_field_1', double(value: 123, fq: { 'facet_field_2' => 'abc' }))
316
-
317
- expect(result_params[:f]['facet_field_1']).to include(123)
318
- expect(result_params[:f]['facet_field_2']).to include('abc')
319
- end
320
- end
321
-
322
192
  describe "add_facet_params_and_redirect" do
323
193
  let(:params) do
324
194
  parameter_class.new(
@@ -346,71 +216,6 @@ RSpec.describe Blacklight::SearchState do
346
216
  params = search_state.add_facet_params_and_redirect("facet_field_2", "facet_value")
347
217
  expect(params).not_to have_key(:page)
348
218
  end
349
-
350
- it "otherwise does the same thing as add_facet_params" do
351
- added_facet_params = search_state.add_facet_params("facet_field_2", "facet_value")
352
- added_facet_params_from_facet_action = search_state.add_facet_params_and_redirect("facet_field_2", "facet_value")
353
-
354
- expect(added_facet_params_from_facet_action).to eq added_facet_params.except(Blacklight::Solr::FacetPaginator.request_keys[:page], Blacklight::Solr::FacetPaginator.request_keys[:sort])
355
- end
356
- end
357
-
358
- describe "#remove_facet_params" do
359
- let(:simple_facet_fields) { [:some_field, :another_field] }
360
- let(:params) { parameter_class.new 'f' => facet_params }
361
- let(:facet_params) { {} }
362
-
363
- context "when the facet has multiple values" do
364
- let(:facet_params) { { 'some_field' => %w[some_value another_value] } }
365
-
366
- it "removes the facet / value tuple from the query parameters" do
367
- params = search_state.remove_facet_params('some_field', 'some_value')
368
- expect(params[:f]['some_field']).not_to include 'some_value'
369
- expect(params[:f]['some_field']).to include 'another_value'
370
- end
371
- end
372
-
373
- context "when the facet_params is a HWIA" do
374
- let(:facet_values) { { '0' => 'some_value', '1' => 'another_value' }.with_indifferent_access }
375
- let(:facet_params) { { 'some_field' => facet_values } }
376
-
377
- it "removes the facet / value tuple from the query parameters" do
378
- params = search_state.remove_facet_params('some_field', 'some_value')
379
- expect(params[:f]['some_field']).not_to include 'some_value'
380
- expect(params[:f]['some_field']).to include 'another_value'
381
- end
382
- end
383
-
384
- context "when the facet has configuration" do
385
- before do
386
- blacklight_config.facet_fields['some_field'].merge!(single: true, field: "a_solr_field", key: 'some_key')
387
- end
388
-
389
- let(:facet_params) { { 'some_key' => %w[some_value another_value] } }
390
-
391
- it "uses the facet's key configuration" do
392
- params = search_state.remove_facet_params('some_field', 'some_value')
393
- expect(params[:f]['some_key']).not_to eq 'some_value'
394
- expect(params[:f]['some_key']).to include 'another_value'
395
- end
396
- end
397
-
398
- it "removes the facet entirely when the last facet value is removed" do
399
- facet_params['another_field'] = ['some_value']
400
- facet_params['some_field'] = ['some_value']
401
-
402
- params = search_state.remove_facet_params('some_field', 'some_value')
403
-
404
- expect(params[:f]).not_to have_key 'some_field'
405
- end
406
-
407
- it "removes the 'f' parameter entirely when no facets remain" do
408
- facet_params['some_field'] = ['some_value']
409
-
410
- params = search_state.remove_facet_params('some_field', 'some_value')
411
-
412
- expect(params).not_to have_key :f
413
- end
414
219
  end
415
220
 
416
221
  describe '#reset' do
@@ -549,4 +354,81 @@ RSpec.describe Blacklight::SearchState do
549
354
  expect(search_state.facet_prefix).to eq 'A'
550
355
  end
551
356
  end
357
+
358
+ describe "#url_for_document" do
359
+ let(:controller_class) { ::CatalogController.new }
360
+ let(:doc) { SolrDocument.new }
361
+
362
+ before do
363
+ allow(search_state).to receive_messages(controller: controller_class)
364
+ allow(search_state).to receive_messages(controller_name: controller_class.controller_name)
365
+ allow(search_state).to receive_messages(params: parameter_class.new)
366
+ end
367
+
368
+ it "is a polymorphic routing-ready object" do
369
+ expect(search_state.url_for_document(doc)).to eq doc
370
+ end
371
+
372
+ it "allows for custom show routes" do
373
+ search_state.blacklight_config.show.route = { controller: 'catalog' }
374
+ expect(search_state.url_for_document(doc)).to eq(controller: 'catalog', action: :show, id: doc)
375
+ end
376
+
377
+ context "within bookmarks" do
378
+ let(:controller_class) { ::BookmarksController.new }
379
+
380
+ it "uses polymorphic routing" do
381
+ expect(search_state.url_for_document(doc)).to eq doc
382
+ end
383
+ end
384
+
385
+ context "within an alternative catalog controller" do
386
+ let(:controller_class) { ::AlternateController.new }
387
+
388
+ before do
389
+ search_state.blacklight_config.show.route = { controller: :current }
390
+ allow(search_state).to receive(:params).and_return(parameter_class.new(controller: 'alternate'))
391
+ end
392
+
393
+ it "supports the :current controller configuration" do
394
+ expect(search_state.url_for_document(doc)).to eq(controller: 'alternate', action: :show, id: doc)
395
+ end
396
+ end
397
+
398
+ it "is a polymorphic route if the solr document responds to #to_model with a non-SolrDocument" do
399
+ some_model = double
400
+ doc = SolrDocument.new
401
+ allow(doc).to receive_messages(to_model: some_model)
402
+ expect(search_state.url_for_document(doc)).to eq doc
403
+ end
404
+ end
405
+
406
+ describe '#filters' do
407
+ context 'pivot facet config but no facet params' do
408
+ it 'maps no filters' do
409
+ blacklight_config.add_facet_field 'some_key', pivot: %w[pivot_field_1 pivot_field_2]
410
+ expect(search_state.filters).to eq([])
411
+ end
412
+ end
413
+
414
+ context 'pivot facet config and some pivot facet params' do
415
+ let(:params) { { 'f' => { 'pivot_field_1' => 'foo' } } }
416
+
417
+ it 'maps the pivot matching param pivot_field' do
418
+ blacklight_config.add_facet_field 'some_key', pivot: %w[pivot_field_1 pivot_field_2]
419
+ expect(search_state.filters.count).to eq(1)
420
+ expect(search_state.filters.first.key).to eq('some_key')
421
+ end
422
+ end
423
+
424
+ context 'regular facet config with params' do
425
+ let(:params) { { 'f' => { 'some_key' => 'foo' } } }
426
+
427
+ it 'maps the field matching param facet_field' do
428
+ blacklight_config.add_facet_field 'some_key'
429
+ expect(search_state.filters.count).to eq(1)
430
+ expect(search_state.filters.first.key).to eq('some_key')
431
+ end
432
+ end
433
+ end
552
434
  end