blacklight 9.0.0.beta1 → 9.0.0

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 (263) hide show
  1. checksums.yaml +4 -4
  2. data/.docker/app/Dockerfile +2 -1
  3. data/.github/matrix.json +55 -0
  4. data/.github/workflows/build.yml +16 -0
  5. data/.github/workflows/lint.yml +25 -0
  6. data/.github/workflows/main.yml +22 -0
  7. data/.github/workflows/release_7_x_scheduled.yml +39 -0
  8. data/.github/workflows/release_8_x_scheduled.yml +39 -0
  9. data/.github/workflows/test.yml +53 -0
  10. data/.rubocop.yml +81 -3
  11. data/.rubocop_todo.yml +46 -71
  12. data/.solr_wrapper.yml +3 -1
  13. data/README.md +2 -2
  14. data/VERSION +1 -1
  15. data/app/assets/builds/blacklight.css +51 -38
  16. data/app/assets/javascripts/blacklight/blacklight.esm.js +62 -77
  17. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
  18. data/app/assets/javascripts/blacklight/blacklight.js +62 -77
  19. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
  20. data/app/assets/stylesheets/blacklight/_blacklight_base.scss +0 -1
  21. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +4 -0
  22. data/app/assets/stylesheets/blacklight/_facets.scss +37 -29
  23. data/app/assets/stylesheets/blacklight/_header.scss +4 -0
  24. data/app/assets/stylesheets/blacklight/_modal.scss +9 -8
  25. data/app/assets/stylesheets/blacklight/_pagination.scss +1 -3
  26. data/app/assets/stylesheets/blacklight/_search_history.scss +0 -4
  27. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +3 -0
  28. data/app/components/blacklight/advanced_search_form_component.html.erb +4 -4
  29. data/app/components/blacklight/advanced_search_form_component.rb +6 -5
  30. data/app/components/blacklight/constraint_component.html.erb +1 -5
  31. data/app/components/blacklight/constraint_component.rb +11 -0
  32. data/app/components/blacklight/constraint_layout_component.html.erb +1 -6
  33. data/app/components/blacklight/constraint_layout_component.rb +9 -0
  34. data/app/components/blacklight/constraints_component.html.erb +3 -8
  35. data/app/components/blacklight/constraints_component.rb +59 -14
  36. data/app/components/blacklight/document/action_component.rb +1 -3
  37. data/app/components/blacklight/document/bookmark_component.html.erb +3 -3
  38. data/app/components/blacklight/document/bookmark_component.rb +10 -4
  39. data/app/components/blacklight/document/group_component.html.erb +1 -1
  40. data/app/components/blacklight/document/more_like_this_component.rb +2 -2
  41. data/app/components/blacklight/document/page_header_component.rb +3 -3
  42. data/app/components/blacklight/document/thumbnail_component.html.erb +3 -7
  43. data/app/components/blacklight/document/thumbnail_component.rb +7 -6
  44. data/app/components/blacklight/document_component.html.erb +3 -3
  45. data/app/components/blacklight/document_component.rb +22 -26
  46. data/app/components/blacklight/document_title_component.rb +6 -10
  47. data/app/components/blacklight/facet_field_checkboxes_component.rb +4 -18
  48. data/app/components/blacklight/facet_field_component.rb +4 -15
  49. data/app/components/blacklight/facet_field_filter_component.rb +4 -19
  50. data/app/components/blacklight/facet_field_inclusive_constraint_component.rb +4 -23
  51. data/app/components/blacklight/facet_field_list_component.rb +4 -30
  52. data/app/components/blacklight/facet_field_no_layout_component.rb +4 -8
  53. data/app/components/blacklight/facet_field_pagination_component.html.erb +2 -2
  54. data/app/components/blacklight/facet_item_component.rb +4 -72
  55. data/app/components/blacklight/facet_item_pivot_component.rb +8 -4
  56. data/app/components/blacklight/{facet_field_checkboxes_component.html.erb → facets/checkboxes_component.html.erb} +4 -4
  57. data/app/components/blacklight/facets/checkboxes_component.rb +26 -0
  58. data/app/components/blacklight/facets/count_component.rb +23 -0
  59. data/app/components/blacklight/{facet_field_component.html.erb → facets/field_component.html.erb} +1 -3
  60. data/app/components/blacklight/facets/field_component.rb +23 -0
  61. data/app/components/blacklight/facets/filters_component.html.erb +4 -0
  62. data/app/components/blacklight/facets/filters_component.rb +39 -0
  63. data/app/components/blacklight/{facet_field_inclusive_constraint_component.html.erb → facets/inclusive_constraint_component.html.erb} +1 -1
  64. data/app/components/blacklight/facets/inclusive_constraint_component.rb +31 -0
  65. data/app/components/blacklight/{facet_field_filter_component.html.erb → facets/index_navigation_component.html.erb} +1 -1
  66. data/app/components/blacklight/facets/index_navigation_component.rb +32 -0
  67. data/app/components/blacklight/facets/item_component.rb +76 -0
  68. data/app/components/blacklight/facets/list_component.html.erb +11 -0
  69. data/app/components/blacklight/facets/list_component.rb +46 -0
  70. data/app/components/blacklight/facets/no_layout_component.rb +16 -0
  71. data/app/components/blacklight/facets/pivot_list_component.rb +14 -0
  72. data/app/components/blacklight/facets/selected_value_component.rb +29 -0
  73. data/app/components/blacklight/facets/suggest_component.html.erb +17 -0
  74. data/app/components/blacklight/facets/suggest_component.rb +21 -0
  75. data/app/components/blacklight/header_component.rb +2 -2
  76. data/app/components/blacklight/icons/remove_component.rb +2 -2
  77. data/app/components/blacklight/metadata_field_component.html.erb +2 -2
  78. data/app/components/blacklight/metadata_field_component.rb +2 -1
  79. data/app/components/blacklight/metadata_field_layout_component.rb +9 -4
  80. data/app/components/blacklight/metadata_field_plain_text_layout_component.rb +2 -2
  81. data/app/components/blacklight/response/facet_group_component.html.erb +3 -3
  82. data/app/components/blacklight/response/facet_group_component.rb +9 -1
  83. data/app/components/blacklight/search_bar_component.html.erb +2 -2
  84. data/app/components/blacklight/system/dropdown_component.html.erb +1 -1
  85. data/app/components/blacklight/system/dropdown_component.rb +1 -1
  86. data/app/components/blacklight/system/flash_message_component.html.erb +1 -1
  87. data/app/components/blacklight/system/flash_message_component.rb +0 -9
  88. data/app/components/blacklight/system/modal_component.html.erb +1 -2
  89. data/app/components/blacklight/top_navbar_component.html.erb +2 -2
  90. data/app/controllers/concerns/blacklight/bookmarks.rb +13 -3
  91. data/app/controllers/concerns/blacklight/catalog.rb +27 -30
  92. data/app/controllers/concerns/blacklight/controller.rb +1 -1
  93. data/app/controllers/concerns/blacklight/search_context.rb +1 -1
  94. data/app/controllers/concerns/blacklight/searchable.rb +1 -1
  95. data/app/helpers/blacklight/catalog_helper_behavior.rb +5 -3
  96. data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -2
  97. data/app/helpers/blacklight/document_helper_behavior.rb +3 -1
  98. data/app/helpers/blacklight/facets_helper_behavior.rb +7 -12
  99. data/app/helpers/blacklight/icon_helper_behavior.rb +2 -2
  100. data/app/javascript/blacklight-frontend/bookmark_toggle.js +7 -2
  101. data/app/javascript/blacklight-frontend/button_focus.js +1 -1
  102. data/app/javascript/blacklight-frontend/checkbox_submit.js +9 -2
  103. data/app/javascript/blacklight-frontend/debounce.js +1 -1
  104. data/app/javascript/blacklight-frontend/facet_suggest.js +27 -3
  105. data/app/javascript/blacklight-frontend/index.js +0 -2
  106. data/app/javascript/blacklight-frontend/modal.js +15 -8
  107. data/app/javascript/blacklight-frontend/search_context.js +3 -2
  108. data/app/presenters/blacklight/constraint_presenter.rb +22 -0
  109. data/app/presenters/blacklight/document_presenter.rb +6 -5
  110. data/app/presenters/blacklight/facet_field_presenter.rb +18 -2
  111. data/app/presenters/blacklight/facet_grouped_item_presenter.rb +6 -0
  112. data/app/presenters/blacklight/facet_item_pivot_presenter.rb +1 -5
  113. data/app/presenters/blacklight/facet_item_presenter.rb +5 -18
  114. data/app/presenters/blacklight/field_presenter.rb +4 -2
  115. data/app/presenters/blacklight/json_presenter.rb +8 -4
  116. data/app/presenters/blacklight/rendering/abstract_step.rb +7 -1
  117. data/app/presenters/blacklight/rendering/helper_method.rb +4 -4
  118. data/app/presenters/blacklight/rendering/join.rb +11 -7
  119. data/app/presenters/blacklight/rendering/terminator.rb +1 -1
  120. data/app/services/blacklight/field_retriever.rb +1 -1
  121. data/app/services/blacklight/search_service.rb +10 -8
  122. data/app/values/blacklight/types.rb +2 -2
  123. data/app/views/blacklight/nav/_bookmark.html.erb +1 -1
  124. data/app/views/catalog/_document.atom.builder +1 -1
  125. data/app/views/catalog/_document.html.erb +1 -1
  126. data/app/views/catalog/_email_form.html.erb +4 -4
  127. data/app/views/catalog/_home_text.html.erb +2 -2
  128. data/app/views/catalog/_show_main_content.html.erb +9 -5
  129. data/app/views/catalog/_sms_form.html.erb +4 -4
  130. data/app/views/catalog/_sort_and_per_page.html.erb +1 -1
  131. data/app/views/catalog/advanced_search.html.erb +1 -1
  132. data/app/views/catalog/facet.html.erb +8 -10
  133. data/app/views/catalog/index.html.erb +0 -1
  134. data/app/views/catalog/index.json.jbuilder +5 -3
  135. data/app/views/catalog/show.html.erb +2 -2
  136. data/app/views/layouts/blacklight/base.html.erb +1 -1
  137. data/blacklight.gemspec +1 -1
  138. data/config/locales/blacklight.ar.yml +14 -14
  139. data/config/locales/blacklight.ca.yml +2 -2
  140. data/config/locales/blacklight.de.yml +13 -13
  141. data/config/locales/blacklight.en.yml +3 -3
  142. data/config/locales/blacklight.es.yml +13 -13
  143. data/config/locales/blacklight.fr.yml +14 -14
  144. data/config/locales/blacklight.hu.yml +15 -15
  145. data/config/locales/blacklight.it.yml +16 -16
  146. data/config/locales/blacklight.nl.yml +13 -13
  147. data/config/locales/blacklight.pt-BR.yml +15 -15
  148. data/config/locales/blacklight.sq.yml +14 -14
  149. data/config/locales/blacklight.zh.yml +12 -12
  150. data/lib/blacklight/abstract_repository.rb +2 -2
  151. data/lib/blacklight/component.rb +7 -1
  152. data/lib/blacklight/configuration/context.rb +3 -3
  153. data/lib/blacklight/configuration/facet_field.rb +11 -6
  154. data/lib/blacklight/configuration/field.rb +4 -4
  155. data/lib/blacklight/configuration/fields.rb +0 -1
  156. data/lib/blacklight/configuration/search_field.rb +1 -1
  157. data/lib/blacklight/configuration/view_config.rb +32 -18
  158. data/lib/blacklight/configuration.rb +64 -10
  159. data/lib/blacklight/nested_open_struct_with_hash_access.rb +1 -1
  160. data/lib/blacklight/open_struct_with_hash_access.rb +2 -2
  161. data/lib/blacklight/routes/searchable.rb +1 -1
  162. data/lib/blacklight/search_builder.rb +2 -1
  163. data/lib/blacklight/search_state/filter_field.rb +4 -4
  164. data/lib/blacklight/search_state/pivot_filter_field.rb +5 -5
  165. data/lib/blacklight/search_state.rb +2 -0
  166. data/lib/blacklight/solr/abstract_filter_query_builder.rb +77 -0
  167. data/lib/blacklight/solr/default_filter_query_builder.rb +20 -0
  168. data/lib/blacklight/solr/field_reflection_search_builder.rb +11 -0
  169. data/lib/blacklight/solr/repository.rb +17 -15
  170. data/lib/blacklight/solr/response/facets.rb +2 -2
  171. data/lib/blacklight/solr/response/params.rb +0 -4
  172. data/lib/blacklight/solr/response.rb +5 -1
  173. data/lib/blacklight/solr/search_builder_behavior.rb +48 -97
  174. data/lib/blacklight/solr/single_doc_search_builder.rb +25 -0
  175. data/lib/blacklight.rb +6 -4
  176. data/lib/generators/blacklight/assets/importmap_generator.rb +3 -5
  177. data/lib/generators/blacklight/assets_generator.rb +1 -1
  178. data/lib/generators/blacklight/search_builder_generator.rb +1 -1
  179. data/lib/generators/blacklight/templates/.solr_wrapper.yml +3 -1
  180. data/lib/generators/blacklight/templates/catalog_controller.rb +34 -8
  181. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +0 -71
  182. data/package.json +3 -3
  183. data/spec/components/blacklight/advanced_search_form_component_spec.rb +18 -22
  184. data/spec/components/blacklight/constraint_layout_component_spec.rb +8 -8
  185. data/spec/components/blacklight/constraints_component_spec.rb +11 -11
  186. data/spec/components/blacklight/document/action_component_spec.rb +23 -15
  187. data/spec/components/blacklight/document/group_component_spec.rb +10 -15
  188. data/spec/components/blacklight/document/page_header_component_spec.rb +35 -28
  189. data/spec/components/blacklight/document/sidebar_component_spec.rb +5 -11
  190. data/spec/components/blacklight/document_component_spec.rb +105 -79
  191. data/spec/components/blacklight/facet_component_spec.rb +12 -8
  192. data/spec/components/blacklight/facet_item_pivot_component_spec.rb +12 -12
  193. data/spec/components/blacklight/{facet_field_checkboxes_component_spec.rb → facets/checkboxes_component_spec.rb} +13 -13
  194. data/spec/components/blacklight/facets/filters_component_spec.rb +36 -0
  195. data/spec/components/blacklight/facets/index_navigation_component_spec.rb +41 -0
  196. data/spec/components/blacklight/{facet_item_component_spec.rb → facets/item_component_spec.rb} +10 -10
  197. data/spec/components/blacklight/{facet_field_list_component_spec.rb → facets/list_component_spec.rb} +34 -23
  198. data/spec/components/blacklight/facets/pivot_list_component_spec.rb +53 -0
  199. data/spec/components/blacklight/facets/suggest_component_spec.rb +82 -0
  200. data/spec/components/blacklight/header_component_spec.rb +2 -4
  201. data/spec/components/blacklight/hidden_search_state_component_spec.rb +7 -7
  202. data/spec/components/blacklight/metadata_field_component_spec.rb +17 -15
  203. data/spec/components/blacklight/response/facet_group_component_spec.rb +37 -0
  204. data/spec/components/blacklight/response/pagination_component_spec.rb +1 -1
  205. data/spec/components/blacklight/response/spellcheck_component_spec.rb +1 -1
  206. data/spec/components/blacklight/search_bar_component_spec.rb +28 -5
  207. data/spec/components/blacklight/search_context/server_applied_params_component_spec.rb +2 -2
  208. data/spec/components/blacklight/search_context/server_item_pagination_component_spec.rb +3 -5
  209. data/spec/components/blacklight/skip_link_component_spec.rb +8 -11
  210. data/spec/components/blacklight/start_over_button_component_spec.rb +4 -4
  211. data/spec/components/blacklight/system/dropdown_component_spec.rb +26 -0
  212. data/spec/components/blacklight/system/flash_message_component_spec.rb +7 -11
  213. data/spec/controllers/blacklight/catalog_spec.rb +1 -1
  214. data/spec/controllers/catalog_controller_spec.rb +12 -20
  215. data/spec/features/advanced_search_spec.rb +42 -21
  216. data/spec/features/facets_spec.rb +84 -12
  217. data/spec/features/modal_spec.rb +1 -1
  218. data/spec/features/search_filters_spec.rb +6 -4
  219. data/spec/features/search_spec.rb +3 -3
  220. data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +10 -0
  221. data/spec/lib/blacklight/configuration/facet_field_spec.rb +2 -2
  222. data/spec/lib/blacklight/parameters_spec.rb +12 -1
  223. data/spec/lib/blacklight/search_state/filter_field_spec.rb +18 -0
  224. data/spec/models/blacklight/configuration_spec.rb +178 -28
  225. data/spec/models/blacklight/solr/default_filter_query_builder_spec.rb +72 -0
  226. data/spec/models/blacklight/solr/document_spec.rb +0 -4
  227. data/spec/models/blacklight/solr/repository_spec.rb +37 -29
  228. data/spec/models/blacklight/solr/response/facets_spec.rb +86 -40
  229. data/spec/models/blacklight/solr/response/group_response_spec.rb +8 -5
  230. data/spec/models/blacklight/solr/response/group_spec.rb +9 -5
  231. data/spec/models/blacklight/solr/response_spec.rb +96 -64
  232. data/spec/models/blacklight/solr/search_builder_behavior_spec.rb +38 -57
  233. data/spec/models/solr_document_spec.rb +5 -1
  234. data/spec/presenters/blacklight/constraint_presenter_spec.rb +32 -0
  235. data/spec/presenters/blacklight/document_presenter_spec.rb +3 -3
  236. data/spec/presenters/blacklight/facet_item_presenter_spec.rb +0 -7
  237. data/spec/presenters/blacklight/field_presenter_spec.rb +103 -22
  238. data/spec/presenters/blacklight/json_presenter_spec.rb +17 -0
  239. data/spec/presenters/blacklight/rendering/pipeline_spec.rb +130 -14
  240. data/spec/services/blacklight/search_service_spec.rb +6 -27
  241. data/spec/spec_helper.rb +0 -1
  242. data/spec/support/presenter_test_helpers.rb +1 -1
  243. data/spec/support/view_component_test_helpers.rb +0 -18
  244. data/spec/views/catalog/facet.html.erb_spec.rb +10 -3
  245. data/spec/views/catalog/index.atom.builder_spec.rb +8 -3
  246. data/spec/views/catalog/index.html.erb_spec.rb +3 -1
  247. metadata +69 -38
  248. data/.github/workflows/ruby.yml +0 -98
  249. data/app/assets/stylesheets/blacklight/_icons.scss +0 -4
  250. data/app/components/blacklight/facet_field_list_component.html.erb +0 -19
  251. data/app/components/blacklight/search/facet_suggest_input.html.erb +0 -9
  252. data/app/components/blacklight/search/facet_suggest_input.rb +0 -16
  253. data/app/javascript/blacklight-frontend/modalForm.js +0 -60
  254. data/app/views/catalog/_facet_index_navigation.html.erb +0 -1
  255. data/app/views/catalog/_facet_layout.html.erb +0 -8
  256. data/app/views/catalog/_facet_pagination.html.erb +0 -1
  257. data/app/views/catalog/_facet_pivot.html.erb +0 -3
  258. data/app/views/shared/_sitelinks_search_box.html.erb +0 -12
  259. data/spec/components/blacklight/document_metadata_component_spec.rb +0 -0
  260. data/spec/components/blacklight/search/facet_suggest_input_spec.rb +0 -33
  261. data/spec/features/sitelinks_search_box_spec.rb +0 -13
  262. data/spec/views/catalog/_facet_index_navigation.html.erb_spec.rb +0 -43
  263. data/spec/views/catalog/_facet_layout.html.erb_spec.rb +0 -41
@@ -2,9 +2,15 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
6
- subject(:rendered) do
7
- render_inline_to_capybara_node(described_class.new(facet_field: facet_field))
5
+ RSpec.describe Blacklight::Facets::ListComponent, type: :component do
6
+ before do
7
+ allow(facet_field).to receive(:item_presenter).and_return(item_presenter)
8
+
9
+ render_inline(described_class.new(facet_field: facet_field))
10
+ end
11
+
12
+ let(:item_presenter) do
13
+ facet_config.item_presenter.new('stuff', facet_config, vc_test_controller.view_context, facet_field.key)
8
14
  end
9
15
 
10
16
  let(:facet_field) do
@@ -21,7 +27,7 @@ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
21
27
  )
22
28
  end
23
29
 
24
- let(:facet_config) { Blacklight::Configuration::NullField.new(key: 'field', item_component: Blacklight::FacetItemComponent, item_presenter: Blacklight::FacetItemPresenter) }
30
+ let(:facet_config) { Blacklight::Configuration::NullField.new(key: 'field', item_component: Blacklight::Facets::ItemComponent, item_presenter: Blacklight::FacetItemPresenter) }
25
31
 
26
32
  let(:paginator) do
27
33
  instance_double(Blacklight::FacetPaginator, items: [
@@ -31,15 +37,20 @@ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
31
37
  end
32
38
 
33
39
  it 'renders an accordion item' do
34
- expect(rendered).to have_css '.accordion-item'
35
- expect(rendered).to have_button 'Field'
36
- expect(rendered).to have_css 'button[data-bs-target="#facet-field"]'
37
- expect(rendered).to have_css '#facet-field.collapse.show'
40
+ expect(page).to have_css '.accordion-item'
41
+ expect(page).to have_button 'Field'
42
+ expect(page).to have_css 'button[data-bs-target="#facet-field"]'
43
+ expect(page).to have_css '#facet-field.collapse.show'
38
44
  end
39
45
 
40
46
  it 'renders the facet items' do
41
- expect(rendered).to have_css 'ul.facet-values'
42
- expect(rendered).to have_css 'li', count: 2
47
+ expect(page).to have_css 'ul.facet-values'
48
+ expect(page).to have_css 'li', count: 2
49
+ end
50
+
51
+ it 'does not add a role attribute by default' do
52
+ expect(page).to have_css 'ul.facet-values'
53
+ expect(page).to have_no_css 'ul.facet-values[role]'
43
54
  end
44
55
 
45
56
  context 'with an active facet' do
@@ -58,7 +69,7 @@ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
58
69
  end
59
70
 
60
71
  it 'adds the facet-limit-active class' do
61
- expect(rendered).to have_css 'div.facet-limit-active'
72
+ expect(page).to have_css 'div.facet-limit-active'
62
73
  end
63
74
  end
64
75
 
@@ -78,13 +89,13 @@ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
78
89
  end
79
90
 
80
91
  it 'renders a collapsed facet' do
81
- expect(rendered).to have_css '.facet-content.collapse'
82
- expect(rendered).to have_no_css '.facet-content.collapse.show'
92
+ expect(page).to have_css '.facet-content.collapse'
93
+ expect(page).to have_no_css '.facet-content.collapse.show'
83
94
  end
84
95
 
85
96
  it 'renders the toggle button in the collapsed state' do
86
- expect(rendered).to have_css '.btn.collapsed'
87
- expect(rendered).to have_css '.btn[aria-expanded="false"]'
97
+ expect(page).to have_css '.btn.collapsed'
98
+ expect(page).to have_css '.btn[aria-expanded="false"]'
88
99
  end
89
100
  end
90
101
 
@@ -104,7 +115,7 @@ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
104
115
  end
105
116
 
106
117
  it 'renders a link to the modal' do
107
- expect(rendered).to have_link 'more Field', href: '/catalog/facet/modal'
118
+ expect(page).to have_link 'more Field', href: '/catalog/facet/modal'
108
119
  end
109
120
  end
110
121
 
@@ -133,13 +144,13 @@ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
133
144
  let(:params) { { f_inclusive: { field: %w[a b c] } } }
134
145
 
135
146
  it 'displays the constraint above the list' do
136
- expect(rendered).to have_content 'Any of:'
137
- expect(rendered).to have_css '.inclusive_or .facet-label', text: 'a'
138
- expect(rendered).to have_link '[remove]', href: 'http://test.host/catalog?f_inclusive%5Bfield%5D%5B%5D=b&f_inclusive%5Bfield%5D%5B%5D=c'
139
- expect(rendered).to have_css '.inclusive_or .facet-label', text: 'b'
140
- expect(rendered).to have_link '[remove]', href: 'http://test.host/catalog?f_inclusive%5Bfield%5D%5B%5D=a&f_inclusive%5Bfield%5D%5B%5D=c'
141
- expect(rendered).to have_css '.inclusive_or .facet-label', text: 'c'
142
- expect(rendered).to have_link '[remove]', href: 'http://test.host/catalog?f_inclusive%5Bfield%5D%5B%5D=a&f_inclusive%5Bfield%5D%5B%5D=b'
147
+ expect(page).to have_content 'Any of:'
148
+ expect(page).to have_css '.inclusive_or .facet-label', text: 'a'
149
+ expect(page).to have_link '[remove]', href: 'http://test.host/catalog?f_inclusive%5Bfield%5D%5B%5D=b&f_inclusive%5Bfield%5D%5B%5D=c'
150
+ expect(page).to have_css '.inclusive_or .facet-label', text: 'b'
151
+ expect(page).to have_link '[remove]', href: 'http://test.host/catalog?f_inclusive%5Bfield%5D%5B%5D=a&f_inclusive%5Bfield%5D%5B%5D=c'
152
+ expect(page).to have_css '.inclusive_or .facet-label', text: 'c'
153
+ expect(page).to have_link '[remove]', href: 'http://test.host/catalog?f_inclusive%5Bfield%5D%5B%5D=a&f_inclusive%5Bfield%5D%5B%5D=b'
143
154
  end
144
155
  end
145
156
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::Facets::PivotListComponent, type: :component do
6
+ before do
7
+ allow(facet_field).to receive(:item_presenter).and_return(item_presenter)
8
+
9
+ render_inline(described_class.new(facet_field: facet_field))
10
+ end
11
+
12
+ let(:item_presenter) do
13
+ facet_config.item_presenter.new('stuff', facet_config, vc_test_controller.view_context, facet_field.key)
14
+ end
15
+
16
+ let(:facet_field) do
17
+ instance_double(
18
+ Blacklight::FacetFieldPresenter,
19
+ paginator: paginator,
20
+ facet_field: facet_config,
21
+ key: 'pivot_field',
22
+ label: 'Pivot Field',
23
+ active?: false,
24
+ collapsed?: false,
25
+ modal_path: nil,
26
+ values: []
27
+ )
28
+ end
29
+
30
+ let(:facet_config) do
31
+ Blacklight::Configuration::NullField.new(
32
+ key: 'pivot_field',
33
+ item_component: Blacklight::FacetItemPivotComponent,
34
+ item_presenter: Blacklight::FacetItemPivotPresenter,
35
+ pivot: %w[field_a field_b]
36
+ )
37
+ end
38
+
39
+ let(:paginator) do
40
+ instance_double(Blacklight::FacetPaginator, items: [
41
+ double(value: 'x', hits: 10),
42
+ double(value: 'y', hits: 33)
43
+ ])
44
+ end
45
+
46
+ it 'renders the facet items top ul with "pivot-facet" class' do
47
+ expect(page).to have_css 'ul.pivot-facet'
48
+ end
49
+
50
+ it 'renders the facet items with role="tree"' do
51
+ expect(page).to have_css 'ul.facet-values[role="tree"]'
52
+ end
53
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::Facets::SuggestComponent, type: :component do
6
+ let(:facet) { Blacklight::Configuration::FacetField.new key: 'language_facet', suggest: true }
7
+ let(:presenter) { Blacklight::FacetFieldPresenter.new(facet, nil, nil, nil) }
8
+ let(:component) { described_class.new(presenter: presenter) }
9
+
10
+ before do
11
+ allow(presenter).to receive_messages(label: 'Language')
12
+ end
13
+
14
+ it 'has an input with the facet-suggest class, which the javascript needs to find it' do
15
+ with_request_url "/catalog/facet/language_facet" do
16
+ rendered = render_inline component
17
+ expect(rendered.css("input.facet-suggest").count).to eq 1
18
+ end
19
+ end
20
+
21
+ it 'has an input with the data-facet-field attribute, which the javascript needs to determine the correct query' do
22
+ with_request_url "/catalog/facet/language_facet" do
23
+ rendered = render_inline component
24
+ expect(rendered.css('input[data-facet-field="language_facet"]').count).to eq 1
25
+ end
26
+ end
27
+
28
+ it 'has an input with the data-facet-search-context attribute, which the javascript needs to determine the current search context' do
29
+ with_request_url "/catalog/facet/language_facet?f%5Bformat%5D%5B%5D=Book&facet.prefix=R&facet.sort=index&q=tibet&search_field=all_fields" do
30
+ rendered = render_inline component
31
+ facet_path = ViewComponent::VERSION::MAJOR == 3 ? '/catalog/facet/language_facet.html' : '/catalog/facet/language_facet'
32
+ expect(rendered.css("input[data-facet-search-context=\"#{facet_path}?f%5Bformat%5D%5B%5D=Book&facet.prefix=R&facet.sort=index&q=tibet&search_field=all_fields\"]").count).to eq 1
33
+ end
34
+ end
35
+
36
+ it 'has a visible label that is associated with the input' do
37
+ with_request_url "/catalog/facet/language_facet" do
38
+ rendered = render_inline component
39
+ label = rendered.css('label').first
40
+ expect(label.text.strip).to eq 'Filter languages'
41
+
42
+ id_in_label_for = label.attribute('for').text
43
+ expect(id_in_label_for).to eq('facet_suggest_language_facet')
44
+
45
+ expect(rendered.css('input').first.attribute('id').text).to eq id_in_label_for
46
+ end
47
+ end
48
+
49
+ context 'when the facet is explicitly configured to suggest: false' do
50
+ let(:facet) { Blacklight::Configuration::FacetField.new key: 'language_facet', suggest: false }
51
+
52
+ it 'does not display' do
53
+ with_request_url "/catalog/facet/language_facet" do
54
+ expect(render_inline(component).to_s).to eq ''
55
+ end
56
+ end
57
+ end
58
+
59
+ context 'when the facet is not explicitly configured with a suggest key' do
60
+ let(:facet) { Blacklight::Configuration::FacetField.new key: 'language_facet' }
61
+ let(:presenter) { Blacklight::FacetFieldPresenter.new(facet, nil, vc_test_controller.view_context, nil) }
62
+
63
+ it 'displays' do
64
+ with_request_url "/catalog/facet/language_facet" do
65
+ rendered = render_inline component
66
+ expect(rendered.css("input.facet-suggest").count).to eq 1
67
+ end
68
+ end
69
+
70
+ context "with blacklight_config.default_facet_suggest = false" do
71
+ before do
72
+ allow(vc_test_controller.view_context.blacklight_config).to receive(:default_facet_suggest).and_return(false)
73
+ end
74
+
75
+ it 'does not display' do
76
+ with_request_url "/catalog/facet/language_facet" do
77
+ expect(render_inline(component).to_s).to eq ''
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -3,14 +3,12 @@
3
3
  RSpec.describe Blacklight::HeaderComponent, type: :component do
4
4
  before do
5
5
  with_controller_class(CatalogController) do
6
- allow(controller).to receive_messages(current_user: nil, search_action_url: '/search')
7
- render
6
+ allow(vc_test_controller).to receive_messages(current_user: nil, search_action_url: '/search')
7
+ render_inline described_class.new(blacklight_config: CatalogController.blacklight_config)
8
8
  end
9
9
  end
10
10
 
11
11
  context 'with no slots' do
12
- let(:render) { render_inline(described_class.new(blacklight_config: CatalogController.blacklight_config)) }
13
-
14
12
  it 'draws the topbar' do
15
13
  expect(page).to have_css 'nav.topbar'
16
14
  expect(page).to have_link 'Blacklight', href: '/'
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe Blacklight::HiddenSearchStateComponent, type: :component do
4
- subject(:rendered) { render_inline_to_capybara_node(instance) }
4
+ before { render_inline(instance) }
5
5
 
6
6
  let(:params) do
7
7
  { q: "query",
@@ -13,11 +13,11 @@ RSpec.describe Blacklight::HiddenSearchStateComponent, type: :component do
13
13
  let(:instance) { described_class.new(params: params) }
14
14
 
15
15
  it "converts a hash with nested complex data to Rails-style hidden form fields" do
16
- expect(rendered).to have_css("input[type='hidden'][name='q'][value='query']", visible: :hidden)
17
- expect(rendered).to have_css("input[type='hidden'][name='per_page'][value='10']", visible: :hidden)
18
- expect(rendered).to have_css("input[type='hidden'][name='extra_arbitrary_key'][value='arbitrary_value']", visible: :hidden)
19
- expect(rendered).to have_css("input[type='hidden'][name='f[field2][]'][value='z']", visible: :hidden)
20
- expect(rendered).to have_css("input[type='hidden'][name='f[field1][]'][value='a']", visible: :hidden)
21
- expect(rendered).to have_css("input[type='hidden'][name='f[field1][]'][value='b']", visible: :hidden)
16
+ expect(page).to have_css("input[type='hidden'][name='q'][value='query']", visible: :hidden)
17
+ expect(page).to have_css("input[type='hidden'][name='per_page'][value='10']", visible: :hidden)
18
+ expect(page).to have_css("input[type='hidden'][name='extra_arbitrary_key'][value='arbitrary_value']", visible: :hidden)
19
+ expect(page).to have_css("input[type='hidden'][name='f[field2][]'][value='z']", visible: :hidden)
20
+ expect(page).to have_css("input[type='hidden'][name='f[field1][]'][value='a']", visible: :hidden)
21
+ expect(page).to have_css("input[type='hidden'][name='f[field1][]'][value='b']", visible: :hidden)
22
22
  end
23
23
  end
@@ -3,11 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Blacklight::MetadataFieldComponent, type: :component do
6
- subject(:rendered) do
7
- render_inline_to_capybara_node(described_class.new(field: field))
8
- end
9
-
10
- let(:view_context) { controller.view_context }
6
+ let(:view_context) { vc_test_controller.view_context }
11
7
  let(:document) { SolrDocument.new('field' => ['Value']) }
12
8
  let(:field_config) { Blacklight::Configuration::Field.new(key: 'field', field: 'field', label: 'Field label') }
13
9
 
@@ -15,23 +11,29 @@ RSpec.describe Blacklight::MetadataFieldComponent, type: :component do
15
11
  Blacklight::FieldPresenter.new(view_context, document, field_config)
16
12
  end
17
13
 
18
- it 'renders the field label' do
19
- expect(rendered).to have_css 'dt.blacklight-field', text: 'Field label'
20
- end
14
+ context "from index view" do
15
+ before do
16
+ render_inline(described_class.new(field: field))
17
+ end
18
+
19
+ it 'renders the field label' do
20
+ expect(page).to have_css 'dt.blacklight-field', text: 'Field label'
21
+ end
21
22
 
22
- it 'renders the field value' do
23
- expect(rendered).to have_css 'dd.blacklight-field', text: 'Value'
23
+ it 'renders the field value' do
24
+ expect(page).to have_css 'dd.blacklight-field', text: 'Value'
25
+ end
24
26
  end
25
27
 
26
28
  context 'from a show view' do
27
- subject(:rendered) do
28
- render_inline_to_capybara_node(described_class.new(field: field, show: true))
29
+ before do
30
+ allow(field).to receive(:label).with('show').and_return('custom label')
31
+
32
+ render_inline(described_class.new(field: field, show: true))
29
33
  end
30
34
 
31
35
  it 'renders the right field label' do
32
- allow(field).to receive(:label).with('show').and_return('custom label')
33
-
34
- expect(rendered).to have_css 'dt.blacklight-field', text: 'custom label'
36
+ expect(page).to have_css 'dt.blacklight-field', text: 'custom label'
35
37
  end
36
38
  end
37
39
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::Response::FacetGroupComponent, type: :component do
6
+ before do
7
+ render_inline(instance)
8
+ end
9
+
10
+ context 'when classes are passed in' do
11
+ let(:instance) do
12
+ described_class.new(id: 'foo', title: 'bar', body_classes: 'custom-class').tap do |component|
13
+ component.with_body { 'body' }
14
+ end
15
+ end
16
+
17
+ it "uses them" do
18
+ within '.facets' do
19
+ expect(page).to have_css 'div.custom-class'
20
+ end
21
+ end
22
+ end
23
+
24
+ context 'when classes are not passed in' do
25
+ let(:instance) do
26
+ described_class.new(id: 'foo', title: 'bar').tap do |component|
27
+ component.with_body { 'body' }
28
+ end
29
+ end
30
+
31
+ it "uses default classes them" do
32
+ within '.facets' do
33
+ expect(page).to have_css 'div.facets-collapse.d-lg-block.collapse.accordion'
34
+ end
35
+ end
36
+ end
37
+ end
@@ -38,7 +38,7 @@ RSpec.describe Blacklight::Response::PaginationComponent, type: :component do
38
38
 
39
39
  context 'when a different configuration that removes deep links is configured in the controller' do
40
40
  before do
41
- allow(controller.blacklight_config.index)
41
+ allow(vc_test_controller.blacklight_config.index)
42
42
  .to receive(:pagination_options)
43
43
  .and_return(theme: 'blacklight', left: 5, right: 0)
44
44
  render
@@ -14,7 +14,7 @@ RSpec.describe Blacklight::Response::SpellcheckComponent, type: :component do
14
14
  end
15
15
 
16
16
  before do
17
- allow(controller).to receive(:blacklight_config).and_return(config)
17
+ allow(vc_test_controller).to receive(:blacklight_config).and_return(config)
18
18
  end
19
19
 
20
20
  context 'when there are many results' do
@@ -3,7 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Blacklight::SearchBarComponent, type: :component do
6
- let(:instance) { described_class.new(url: search_action_url, params: params_for_search) }
6
+ let(:instance) { described_class.new(url: search_action_url, params: params_for_search, advanced_search_url: '/advanced') }
7
7
 
8
8
  let(:search_action_url) { '/catalog' }
9
9
  let(:params_for_search) { { q: 'testParamValue' } }
@@ -15,7 +15,7 @@ RSpec.describe Blacklight::SearchBarComponent, type: :component do
15
15
  end
16
16
 
17
17
  before do
18
- allow(controller).to receive(:blacklight_config).and_return(blacklight_config)
18
+ allow(vc_test_controller).to receive(:blacklight_config).and_return(blacklight_config)
19
19
  end
20
20
 
21
21
  context 'with the default button' do
@@ -31,7 +31,7 @@ RSpec.describe Blacklight::SearchBarComponent, type: :component do
31
31
  subject(:render) do
32
32
  render_inline(instance) do |c|
33
33
  c.with_search_button do
34
- controller.view_context.tag.button "hello", id: 'custom_search'
34
+ vc_test_controller.view_context.tag.button "hello", id: 'custom_search'
35
35
  end
36
36
  end
37
37
  end
@@ -70,8 +70,8 @@ RSpec.describe Blacklight::SearchBarComponent, type: :component do
70
70
  context 'with extra inputs' do
71
71
  subject(:render) do
72
72
  render_inline(instance) do |c|
73
- c.with_before_input_group { controller.view_context.tag.input name: 'foo' }
74
- c.with_before_input_group { controller.view_context.tag.input name: 'bar' }
73
+ c.with_before_input_group { vc_test_controller.view_context.tag.input name: 'foo' }
74
+ c.with_before_input_group { vc_test_controller.view_context.tag.input name: 'bar' }
75
75
  end
76
76
  end
77
77
 
@@ -104,4 +104,27 @@ RSpec.describe Blacklight::SearchBarComponent, type: :component do
104
104
  expect(render.css('.rounded-0')).to be_present
105
105
  end
106
106
  end
107
+
108
+ context 'advanced search link' do
109
+ subject(:render) { render_inline(instance) }
110
+
111
+ context 'when enabled (default)' do
112
+ it 'renders the advanced search link' do
113
+ expect(render.css("a.advanced_search.btn.btn-link[href='/advanced']")).to be_present
114
+ expect(render.css("a.advanced_search").text).to eq('Advanced search')
115
+ end
116
+ end
117
+
118
+ context 'when disabled via configuration' do
119
+ let(:blacklight_config) do
120
+ Blacklight::Configuration.new.configure do |config|
121
+ config.advanced_search.enabled = false
122
+ end
123
+ end
124
+
125
+ it 'does not render the advanced search link' do
126
+ expect(render.css("a.advanced_search")).not_to be_present
127
+ end
128
+ end
129
+ end
107
130
  end
@@ -7,7 +7,7 @@ RSpec.describe Blacklight::SearchContext::ServerAppliedParamsComponent, type: :c
7
7
 
8
8
  let(:instance) { described_class.new }
9
9
  let(:current_search_session) { nil }
10
- let(:view_context) { controller.view_context }
10
+ let(:view_context) { vc_test_controller.view_context }
11
11
 
12
12
  before do
13
13
  # Not sure why we need to re-implement rspec's stub_template, but
@@ -16,7 +16,7 @@ RSpec.describe Blacklight::SearchContext::ServerAppliedParamsComponent, type: :c
16
16
  # https://github.com/rspec/rspec-rails/issues/2696
17
17
  replace_hash = { 'application/_start_over.html.erb' => 'start over' }
18
18
  if Rails.version.to_f >= 7.1
19
- controller.prepend_view_path(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
19
+ vc_test_controller.prepend_view_path(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
20
20
  else
21
21
  view_context.view_paths.unshift(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
22
22
  end
@@ -11,8 +11,8 @@ RSpec.describe Blacklight::SearchContext::ServerItemPaginationComponent, type: :
11
11
  let(:instance) { described_class.new(search_context: search_context, search_session: search_session, current_document: current_document) }
12
12
 
13
13
  before do
14
- allow(controller).to receive(:current_search_session).and_return(double(id: current_document_id))
15
- controller.class.helper_method :current_search_session
14
+ allow(vc_test_controller).to receive(:current_search_session).and_return(double(id: current_document_id))
15
+ vc_test_controller.class.helper_method :current_search_session
16
16
  end
17
17
 
18
18
  context 'when there is no next or previous' do
@@ -40,9 +40,7 @@ RSpec.describe Blacklight::SearchContext::ServerItemPaginationComponent, type: :
40
40
  let(:next_doc) { SolrDocument.new(id: '888') }
41
41
 
42
42
  before do
43
- # allow(controller).to receive(:controller_tracking_method).and_return('track_catalog_path')
44
-
45
- allow(controller).to receive_messages(controller_name: 'catalog', link_to_previous_document: '', link_to_next_document: '')
43
+ allow(vc_test_controller).to receive_messages(controller_name: 'catalog', link_to_previous_document: '', link_to_next_document: '')
46
44
  end
47
45
 
48
46
  it "renders content" do
@@ -3,12 +3,9 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Blacklight::SkipLinkComponent, type: :component do
6
- subject(:rendered) do
7
- render_inline_to_capybara_node(described_class.new)
8
- end
9
-
10
6
  before do
11
- allow(controller).to receive(:blacklight_config).and_return(blacklight_config)
7
+ allow(vc_test_controller).to receive(:blacklight_config).and_return(blacklight_config)
8
+ render_inline(described_class.new)
12
9
  end
13
10
 
14
11
  context 'with no search fields' do
@@ -19,8 +16,8 @@ RSpec.describe Blacklight::SkipLinkComponent, type: :component do
19
16
  end
20
17
 
21
18
  it 'renders skip links with correct link to search' do
22
- expect(rendered).to have_link("Skip to main content", href: '#main-container')
23
- expect(rendered).to have_link("Skip to search", href: "#q")
19
+ expect(page).to have_link("Skip to main content", href: '#main-container')
20
+ expect(page).to have_link("Skip to search", href: "#q")
24
21
  end
25
22
  end
26
23
 
@@ -32,8 +29,8 @@ RSpec.describe Blacklight::SkipLinkComponent, type: :component do
32
29
  end
33
30
 
34
31
  it 'renders skip links with correct link to search' do
35
- expect(rendered).to have_link("Skip to main content", href: "#main-container")
36
- expect(rendered).to have_link("Skip to search", href: "#q")
32
+ expect(page).to have_link("Skip to main content", href: "#main-container")
33
+ expect(page).to have_link("Skip to search", href: "#q")
37
34
  end
38
35
  end
39
36
 
@@ -45,8 +42,8 @@ RSpec.describe Blacklight::SkipLinkComponent, type: :component do
45
42
  end
46
43
 
47
44
  it 'renders skip links with correct link to search' do
48
- expect(rendered).to have_link("Skip to main content", href: "#main-container")
49
- expect(rendered).to have_link("Skip to search", href: "#search_field")
45
+ expect(page).to have_link("Skip to main content", href: "#main-container")
46
+ expect(page).to have_link("Skip to search", href: "#search_field")
50
47
  end
51
48
  end
52
49
  end
@@ -3,7 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Blacklight::StartOverButtonComponent, type: :component do
6
- subject(:render) { render_inline(instance) }
6
+ subject(:render) { render_inline instance }
7
7
 
8
8
  let(:instance) { described_class.new }
9
9
  let(:blacklight_config) do
@@ -13,12 +13,12 @@ RSpec.describe Blacklight::StartOverButtonComponent, type: :component do
13
13
  end
14
14
 
15
15
  before do
16
- allow(controller).to receive(:blacklight_config).and_return(blacklight_config)
16
+ allow(vc_test_controller).to receive(:blacklight_config).and_return(blacklight_config)
17
17
  end
18
18
 
19
19
  context 'with the current view type' do
20
20
  before do
21
- controller.params[:view] = 'abc'
21
+ vc_test_controller.params[:view] = 'abc'
22
22
  end
23
23
 
24
24
  it 'is the catalog path' do
@@ -28,7 +28,7 @@ RSpec.describe Blacklight::StartOverButtonComponent, type: :component do
28
28
 
29
29
  context 'when the current view type is the default' do
30
30
  before do
31
- controller.params[:view] = 'list'
31
+ vc_test_controller.params[:view] = 'list'
32
32
  end
33
33
 
34
34
  it 'does not include the current view type' do
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::System::DropdownComponent, type: :component do
6
+ it 'includes a link for each choice' do
7
+ search_state = double(Blacklight::SearchState)
8
+ allow(search_state).to receive(:params_for_search).and_return('http://example.com')
9
+ rendered = render_inline(described_class.new(
10
+ param: :per_page,
11
+ choices: [
12
+ ['10 per page', 10],
13
+ ['20 per page', 20]
14
+ ],
15
+ search_state: search_state,
16
+ selected: 20,
17
+ interpolation: :count
18
+ ))
19
+
20
+ expect(rendered.css('a').length).to eq 2
21
+ expect(rendered.css('a')[0].text).to eq '10 per page'
22
+ expect(rendered.css('a')[0].attributes).not_to have_key 'aria-current'
23
+ expect(rendered.css('a')[1].text).to eq '20 per page'
24
+ expect(rendered.css('a')[1].attributes).to have_key 'aria-current'
25
+ end
26
+ end