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
@@ -1,8 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.describe "Blacklight::Configuration", :api do
3
+ RSpec.describe Blacklight::Configuration, :api do
4
4
  let(:config) do
5
- Blacklight::Configuration.new
5
+ described_class.new
6
+ end
7
+
8
+ describe "#repository" do
9
+ context 'when the class is configured in blacklight.yml' do
10
+ it "uses the default repository class" do
11
+ expect(config.repository).to be_a(Blacklight::Solr::Repository)
12
+ end
13
+ end
14
+
15
+ context 'when the class is set in the configuration' do
16
+ let(:custom_repository_class) { Class.new(Blacklight::Solr::Repository) }
17
+
18
+ before do
19
+ config.repository_class = custom_repository_class
20
+ end
21
+
22
+ it "uses the custom repository class" do
23
+ expect(config.repository).to be_a(custom_repository_class)
24
+ end
25
+ end
6
26
  end
7
27
 
8
28
  it "supports arbitrary configuration values" do
@@ -17,14 +37,18 @@ RSpec.describe "Blacklight::Configuration", :api do
17
37
  expect(config).to be_a Blacklight::OpenStructWithHashAccess
18
38
  end
19
39
 
20
- it "accepts a block for configuration" do
21
- config = Blacklight::Configuration.new(a: 1) { |c| c.a = 2 }
40
+ context 'when passed a block' do
41
+ let(:config) do
42
+ described_class.new(a: 1) { |c| c.a = 2 }
43
+ end
22
44
 
23
- expect(config.a).to eq 2
45
+ it "accepts a block for configuration" do
46
+ expect(config.a).to eq 2
24
47
 
25
- config.configure { |c| c.a = 3 }
48
+ config.configure { |c| c.a = 3 }
26
49
 
27
- expect(config.a).to eq 3
50
+ expect(config.a).to eq 3
51
+ end
28
52
  end
29
53
  end
30
54
 
@@ -84,11 +108,11 @@ RSpec.describe "Blacklight::Configuration", :api do
84
108
 
85
109
  describe "spell_max" do
86
110
  it "defaults to 5" do
87
- expect(Blacklight::Configuration.new.spell_max).to eq 5
111
+ expect(config.spell_max).to eq 5
88
112
  end
89
113
 
90
114
  it "accepts config'd value" do
91
- expect(Blacklight::Configuration.new(spell_max: 10).spell_max).to eq 10
115
+ expect(described_class.new(spell_max: 10).spell_max).to eq 10
92
116
  end
93
117
  end
94
118
 
@@ -181,9 +205,9 @@ RSpec.describe "Blacklight::Configuration", :api do
181
205
 
182
206
  describe "add alternative solr fields" do
183
207
  it "lets you define any arbitrary solr field" do
184
- Blacklight::Configuration.define_field_access :my_custom_field
208
+ described_class.define_field_access :my_custom_field
185
209
 
186
- config = Blacklight::Configuration.new do |config|
210
+ config = described_class.new do |config|
187
211
  config.add_my_custom_field 'qwerty', label: "asdf"
188
212
  end
189
213
 
@@ -191,9 +215,9 @@ RSpec.describe "Blacklight::Configuration", :api do
191
215
  end
192
216
 
193
217
  it "lets you define a field accessor that uses an existing field-type" do
194
- Blacklight::Configuration.define_field_access :my_custom_facet_field, class: Blacklight::Configuration::FacetField
218
+ described_class.define_field_access :my_custom_facet_field, class: Blacklight::Configuration::FacetField
195
219
 
196
- config = Blacklight::Configuration.new do |config|
220
+ config = described_class.new do |config|
197
221
  config.add_my_custom_facet_field 'qwerty', label: "asdf"
198
222
  end
199
223
 
@@ -406,13 +430,13 @@ RSpec.describe "Blacklight::Configuration", :api do
406
430
 
407
431
  describe "add_search_field" do
408
432
  it "accepts hash form" do
409
- c = Blacklight::Configuration.new
433
+ c = described_class.new
410
434
  c.add_search_field(key: "my_search_key")
411
435
  expect(c.search_fields["my_search_key"]).not_to be_nil
412
436
  end
413
437
 
414
438
  it "accepts two-arg hash form" do
415
- c = Blacklight::Configuration.new
439
+ c = described_class.new
416
440
 
417
441
  c.add_search_field("my_search_type",
418
442
  key: "my_search_type",
@@ -428,7 +452,7 @@ RSpec.describe "Blacklight::Configuration", :api do
428
452
  end
429
453
 
430
454
  it "accepts block form" do
431
- c = Blacklight::Configuration.new
455
+ c = described_class.new
432
456
 
433
457
  c.add_search_field("some_field") do |field|
434
458
  field.solr_parameters = { qf: "solr_field^10" }
@@ -443,7 +467,7 @@ RSpec.describe "Blacklight::Configuration", :api do
443
467
  end
444
468
 
445
469
  it "accepts SearchField object" do
446
- c = Blacklight::Configuration.new
470
+ c = described_class.new
447
471
 
448
472
  f = Blacklight::Configuration::SearchField.new(foo: "bar")
449
473
 
@@ -481,7 +505,7 @@ RSpec.describe "Blacklight::Configuration", :api do
481
505
 
482
506
  describe "add_sort_field" do
483
507
  it "takes a hash" do
484
- c = Blacklight::Configuration.new
508
+ c = described_class.new
485
509
  c.add_sort_field(key: "my_sort_key", sort: "score desc")
486
510
  expect(c.sort_fields["my_sort_key"]).not_to be_nil
487
511
  end
@@ -692,23 +716,149 @@ RSpec.describe "Blacklight::Configuration", :api do
692
716
 
693
717
  describe '.default_configuration' do
694
718
  it 'adds additional default configuration properties' do
695
- Blacklight::Configuration.default_configuration do
696
- Blacklight::Configuration.default_values[:a] = '123'
719
+ described_class.default_configuration do
720
+ described_class.default_values[:a] = '123'
697
721
  end
698
722
 
699
- Blacklight::Configuration.default_configuration do
700
- Blacklight::Configuration.default_values[:b] = 'abc'
723
+ described_class.default_configuration do
724
+ described_class.default_values[:b] = 'abc'
701
725
  end
702
726
 
703
- expect(Blacklight::Configuration.default_values[:a]).to eq '123'
704
- expect(Blacklight::Configuration.default_values[:b]).to eq 'abc'
727
+ expect(described_class.default_values[:a]).to eq '123'
728
+ expect(described_class.default_values[:b]).to eq 'abc'
705
729
  ensure
706
730
  # reset the default configuration
707
- Blacklight::Configuration.default_values.delete(:a)
708
- Blacklight::Configuration.default_values.delete(:b)
731
+ described_class.default_values.delete(:a)
732
+ described_class.default_values.delete(:b)
733
+
734
+ described_class.default_configuration.delete_at(1)
735
+ described_class.default_configuration.delete_at(2)
736
+ end
737
+ end
738
+
739
+ describe "#copy_search_field_config_to_advanced!" do
740
+ let(:config) { described_class.new }
741
+
742
+ before do
743
+ config.add_search_field('title',
744
+ solr_parameters: {
745
+ 'spellcheck.dictionary': 'title',
746
+ qf: '${title_qf}',
747
+ pf: '${title_pf}'
748
+ })
749
+ config.add_search_field('excluded_field',
750
+ solr_parameters: { qf: '${excluded_qf}' },
751
+ include_in_advanced_search: false)
752
+ config.add_search_field('already_configured',
753
+ solr_parameters: { qf: '${configured_qf}' },
754
+ clause_params: { edismax: { existing_custom: 'params' } })
755
+ end
756
+
757
+ it "copies solr_parameters to clause_params for eligible search fields" do
758
+ config.copy_search_field_config_to_advanced!
759
+
760
+ title_field = config.search_fields['title']
761
+ expect(title_field.clause_params).to be_present
762
+ expect(title_field.clause_params[:edismax]).to eq({ 'spellcheck.dictionary': 'title', qf: '${title_qf}', pf: '${title_pf}' })
763
+ end
764
+
765
+ it "skips fields with include_in_advanced_search set to false" do
766
+ config.copy_search_field_config_to_advanced!
767
+
768
+ excluded_field = config.search_fields['excluded_field']
769
+ expect(excluded_field.clause_params).to be_nil
770
+ end
771
+
772
+ it "skips fields that already have a clause_params config" do
773
+ config.copy_search_field_config_to_advanced!
774
+
775
+ already_configured_field = config.search_fields['already_configured']
776
+ expect(already_configured_field.clause_params).to eq({ edismax: { existing_custom: 'params' } })
777
+ end
778
+
779
+ it "handles fields with nil solr_parameters" do
780
+ config.add_search_field('no_solr_params')
781
+
782
+ expect { config.copy_search_field_config_to_advanced! }.not_to raise_error
709
783
 
710
- Blacklight::Configuration.default_configuration.delete_at(1)
711
- Blacklight::Configuration.default_configuration.delete_at(2)
784
+ field = config.search_fields['no_solr_params']
785
+ expect(field.clause_params).to be_present
786
+ expect(field.clause_params[:edismax]).to eq({})
787
+ end
788
+ end
789
+
790
+ describe "#copy_facet_field_config_to_advanced!" do
791
+ let(:config) { described_class.new }
792
+
793
+ before do
794
+ config.add_facet_field('format',
795
+ field: 'format')
796
+ config.add_facet_field('subject_ssim')
797
+ config.add_facet_field('excluded_facet',
798
+ field: 'excluded_field',
799
+ include_in_advanced_search: false)
800
+ config.add_facet_field('query_facet',
801
+ query: { 'recent' => { fq: 'pub_date_ssim:[2020 TO *]' } })
802
+ config.add_facet_field('pivot_facet',
803
+ pivot: %w[author_ssim subject_ssim])
804
+ config.add_facet_field('range_facet',
805
+ range: true,
806
+ field: 'pub_date_ssim')
807
+ end
808
+
809
+ it "sets default facet.sort to 'count'" do
810
+ config.copy_facet_field_config_to_advanced!
811
+
812
+ expect(config.advanced_search.form_solr_parameters['facet.sort']).to eq 'count'
813
+ end
814
+
815
+ it "adds eligible facet fields to facet.field array" do
816
+ config.copy_facet_field_config_to_advanced!
817
+
818
+ facet_fields = config.advanced_search.form_solr_parameters['facet.field']
819
+ expect(facet_fields).to eq(%w[format subject_ssim])
820
+ end
821
+
822
+ it "skips fields with include_in_advanced_search set to false" do
823
+ config.copy_facet_field_config_to_advanced!
824
+
825
+ facet_fields = config.advanced_search.form_solr_parameters['facet.field']
826
+ expect(facet_fields).not_to include('excluded_field')
827
+ end
828
+
829
+ it "skips fields that are query, pivot, or range facets" do
830
+ config.copy_facet_field_config_to_advanced!
831
+
832
+ facet_fields = config.advanced_search.form_solr_parameters['facet.field']
833
+ expect(facet_fields).not_to include('query_facet', 'pivot_facet', 'range_facet')
834
+ end
835
+
836
+ it "sets facet limit to -1 to show all values for eligible fields" do
837
+ config.copy_facet_field_config_to_advanced!
838
+
839
+ expect(config.advanced_search.form_solr_parameters['f.format.facet.limit']).to eq(-1)
840
+ expect(config.advanced_search.form_solr_parameters['f.subject_ssim.facet.limit']).to eq(-1)
841
+ end
842
+
843
+ context "preserving existing advanced search config if present" do
844
+ before do
845
+ config.advanced_search.form_solr_parameters = {
846
+ 'facet.sort' => 'index',
847
+ 'f.subject_ssim.facet.limit' => 50
848
+ }
849
+ end
850
+
851
+ it "preserves existing facet.limit configuration if set" do
852
+ config.copy_facet_field_config_to_advanced!
853
+
854
+ expect(config.advanced_search.form_solr_parameters['f.subject_ssim.facet.limit']).to eq(50)
855
+ end
856
+
857
+ it "preserves existing default facet.sort configuration if set" do
858
+ config.copy_facet_field_config_to_advanced!
859
+
860
+ expect(config.advanced_search.form_solr_parameters['facet.sort']).to eq('index')
861
+ end
712
862
  end
713
863
  end
714
864
  end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Blacklight::Solr::DefaultFilterQueryBuilder do
4
+ subject { described_class.new(blacklight_config: blacklight_config) }
5
+
6
+ let(:blacklight_config) { CatalogController.blacklight_config.deep_copy }
7
+
8
+ describe "#facet_value_to_fq_string" do
9
+ it "uses the configured field name" do
10
+ blacklight_config.add_facet_field :facet_key, field: "facet_name"
11
+ expect(subject.send(:facet_value_to_fq_string, "facet_key", "my value")).to eq "{!term f=facet_name}my value"
12
+ end
13
+
14
+ it "uses the raw handler for strings" do
15
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", "my value")).to eq "{!term f=facet_name}my value"
16
+ end
17
+
18
+ it "passes booleans through" do
19
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", true)).to eq '{!term f=facet_name}true'
20
+ end
21
+
22
+ it "passes boolean-like strings through" do
23
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", "true")).to eq '{!term f=facet_name}true'
24
+ end
25
+
26
+ it "passes integers through" do
27
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", 1)).to eq '{!term f=facet_name}1'
28
+ end
29
+
30
+ it "passes integer-like strings through" do
31
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", "1")).to eq '{!term f=facet_name}1'
32
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", -1)).to eq '{!term f=facet_name}-1'
33
+ end
34
+
35
+ it "passes floats through" do
36
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", 1.11)).to eq '{!term f=facet_name}1.11'
37
+ end
38
+
39
+ it "passes floats in strings through" do
40
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", "1.11")).to eq '{!term f=facet_name}1.11'
41
+ end
42
+
43
+ context 'date handling' do
44
+ before { allow(blacklight_config.facet_fields).to receive(:[]).with('facet_name').and_return(double(date: true, query: nil, tag: nil, field: 'facet_name')) }
45
+
46
+ it "passes date-type fields through" do
47
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", "2012-01-01")).to eq '{!term f=facet_name}2012-01-01'
48
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", "2003-04-09T00:00:00Z")).to eq '{!term f=facet_name}2003-04-09T00:00:00Z'
49
+ end
50
+
51
+ it "formats Date objects correctly" do
52
+ allow(blacklight_config.facet_fields).to receive(:[]).with('facet_name').and_return(double(date: nil, query: nil, tag: nil, field: 'facet_name'))
53
+ d = DateTime.parse("2003-04-09T00:00:00")
54
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", d)).to eq '{!term f=facet_name}2003-04-09T00:00:00Z'
55
+ end
56
+ end
57
+
58
+ it "handles range requests" do
59
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", 1..5)).to eq "facet_name:[1 TO 5]"
60
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", 1..nil)).to eq "facet_name:[1 TO *]"
61
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", nil..5)).to eq "facet_name:[* TO 5]"
62
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", nil..nil)).to eq "facet_name:[* TO *]"
63
+ end
64
+
65
+ it "adds tag local parameters" do
66
+ allow(blacklight_config.facet_fields).to receive(:[]).with('facet_name').and_return(double(query: nil, tag: 'asdf', date: nil, field: 'facet_name'))
67
+
68
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", true)).to eq "{!term f=facet_name tag=asdf}true"
69
+ expect(subject.send(:facet_value_to_fq_string, "facet_name", "my value")).to eq "{!term f=facet_name tag=asdf}my value"
70
+ end
71
+ end
72
+ end
@@ -179,10 +179,6 @@ RSpec.describe "Blacklight::Solr::Document", :api do
179
179
  # registration in an after, sorry.
180
180
  end
181
181
 
182
- it "registers format" do
183
- expect(defined?("Mime::MOCK2")).to be_truthy
184
- end
185
-
186
182
  it "registers as alias only" do
187
183
  expect(Mime::Type.lookup("application/mock2")).not_to equal Mime::Type.lookup_by_extension("mock2")
188
184
  end
@@ -44,26 +44,6 @@ RSpec.describe Blacklight::Solr::Repository, :api do
44
44
  end
45
45
  end
46
46
 
47
- context "with legacy request handler-based configuration" do
48
- before do
49
- blacklight_config.document_solr_path = 'select'
50
- blacklight_config.document_unique_id_param = :id
51
- end
52
-
53
- it "uses the provided :qt param" do
54
- blacklight_config.document_solr_request_handler = 'xyz'
55
- allow(subject.connection).to receive(:send_and_receive).with('select', hash_including(params: { id: '123', qt: 'abc' })).and_return(mock_response)
56
- expect(subject.find("123", qt: 'abc')).to be_a Blacklight::Solr::Response
57
- end
58
-
59
- it "uses the :qt parameter from the default_document_solr_params" do
60
- blacklight_config.default_document_solr_params[:qt] = 'abc'
61
- blacklight_config.document_solr_request_handler = 'xyz'
62
- allow(subject.connection).to receive(:send_and_receive).with('select', hash_including(params: { id: '123', qt: 'abc' })).and_return(mock_response)
63
- expect(subject.find("123")).to be_a Blacklight::Solr::Response
64
- end
65
- end
66
-
67
47
  it "preserves the class of the incoming params" do
68
48
  doc_params = ActiveSupport::HashWithIndifferentAccess.new
69
49
  allow(subject.connection).to receive(:send_and_receive).with('get', anything).and_return(mock_response)
@@ -92,27 +72,42 @@ RSpec.describe Blacklight::Solr::Repository, :api do
92
72
  end
93
73
 
94
74
  describe "#search" do
75
+ context 'with positional params' do
76
+ it "uses the search-specific solr path" do
77
+ blacklight_config.solr_path = 'xyz'
78
+ allow(subject.connection).to receive(:send_and_receive).with('xyz', anything).and_return(mock_response)
79
+ allow(Blacklight.deprecation).to receive(:warn)
80
+ expect(subject.search({})).to be_a Blacklight::Solr::Response
81
+ end
82
+ end
83
+
95
84
  it "uses the search-specific solr path" do
96
85
  blacklight_config.solr_path = 'xyz'
97
86
  allow(subject.connection).to receive(:send_and_receive).with('xyz', anything).and_return(mock_response)
98
- expect(subject.search({})).to be_a Blacklight::Solr::Response
87
+ expect(subject.search(params: {})).to be_a Blacklight::Solr::Response
88
+ end
89
+
90
+ it "can be called with no args" do
91
+ blacklight_config.solr_path = 'xyz'
92
+ allow(subject.connection).to receive(:send_and_receive).with('xyz', anything).and_return(mock_response)
93
+ expect(subject.search).to be_a Blacklight::Solr::Response
99
94
  end
100
95
 
101
96
  it "uses the default solr path" do
102
97
  allow(subject.connection).to receive(:send_and_receive).with('select', anything).and_return(mock_response)
103
- expect(subject.search({})).to be_a Blacklight::Solr::Response
98
+ expect(subject.search(params: {})).to be_a Blacklight::Solr::Response
104
99
  end
105
100
 
106
101
  it "uses a default :qt param" do
107
102
  blacklight_config.qt = 'xyz'
108
103
  allow(subject.connection).to receive(:send_and_receive).with('select', hash_including(params: { qt: 'xyz' })).and_return(mock_response)
109
- expect(subject.search({})).to be_a Blacklight::Solr::Response
104
+ expect(subject.search(params: {})).to be_a Blacklight::Solr::Response
110
105
  end
111
106
 
112
107
  it "uses the provided :qt param" do
113
108
  blacklight_config.qt = 'xyz'
114
109
  allow(subject.connection).to receive(:send_and_receive).with('select', hash_including(params: { qt: 'abc' })).and_return(mock_response)
115
- expect(subject.search(qt: 'abc')).to be_a Blacklight::Solr::Response
110
+ expect(subject.search(params: { qt: 'abc' })).to be_a Blacklight::Solr::Response
116
111
  end
117
112
 
118
113
  it "preserves the class of the incoming params" do
@@ -120,7 +115,7 @@ RSpec.describe Blacklight::Solr::Repository, :api do
120
115
  search_params[:q] = "query"
121
116
  allow(subject.connection).to receive(:send_and_receive).with('select', anything).and_return(mock_response)
122
117
 
123
- response = subject.search(search_params)
118
+ response = subject.search(params: search_params)
124
119
  expect(response).to be_a Blacklight::Solr::Response
125
120
  expect(response.params).to be_a ActiveSupport::HashWithIndifferentAccess
126
121
  end
@@ -133,7 +128,20 @@ RSpec.describe Blacklight::Solr::Repository, :api do
133
128
  expect(params[:method]).to eq :get
134
129
  expect(params[:params]).to include input_params
135
130
  end.and_return('response' => { 'docs' => [] })
136
- subject.search(input_params)
131
+ subject.search(params: input_params)
132
+ end
133
+
134
+ it "raises a Blacklight exception if RSolr can't connect to the Solr instance" do
135
+ allow(repository.connection).to receive(:send_and_receive).and_raise(Errno::ECONNREFUSED)
136
+ expect { subject.search(params: {}) }.to raise_exception(/Unable to connect to Solr instance/)
137
+ end
138
+
139
+ it "raises a Blacklight exception if RSolr raises a timeout error connecting to Solr instance" do
140
+ rsolr_timeout = RSolr::Error::Timeout.new(nil, nil)
141
+ allow(rsolr_timeout).to receive(:to_s).and_return("mocked RSolr timeout")
142
+
143
+ allow(repository.connection).to receive(:send_and_receive).and_raise(rsolr_timeout)
144
+ expect { subject.search(params: {}) }.to raise_exception(Blacklight::Exceptions::RepositoryTimeout, /Timeout connecting to Solr instance/)
137
145
  end
138
146
  end
139
147
 
@@ -182,7 +190,7 @@ RSpec.describe Blacklight::Solr::Repository, :api do
182
190
  allow(subject.connection).to receive(:send_and_receive) do |path|
183
191
  expect(path).to eq 'xyz'
184
192
  end
185
- subject.search(input_params)
193
+ subject.search(params: input_params)
186
194
  end
187
195
  end
188
196
 
@@ -195,7 +203,7 @@ RSpec.describe Blacklight::Solr::Repository, :api do
195
203
  allow(subject.connection).to receive(:send_and_receive) do |path|
196
204
  expect(path).to eq 'my-great-json'
197
205
  end
198
- subject.search(input_params)
206
+ subject.search(params: input_params)
199
207
  end
200
208
  end
201
209
  end
@@ -205,7 +213,7 @@ RSpec.describe Blacklight::Solr::Repository, :api do
205
213
  let (:blacklight_config) { config = Blacklight::Configuration.new; config.http_method = :post; config }
206
214
 
207
215
  it "sends a post request to solr and get a response back" do
208
- response = subject.search(q: all_docs_query)
216
+ response = subject.search(params: { q: all_docs_query })
209
217
  expect(response.docs.length).to be >= 1
210
218
  end
211
219
  end