blacklight 9.0.0.beta1 → 9.0.0.beta3

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 (220) hide show
  1. checksums.yaml +4 -4
  2. data/.github/matrix.json +47 -0
  3. data/.github/workflows/build.yml +16 -0
  4. data/.github/workflows/lint.yml +25 -0
  5. data/.github/workflows/main.yml +22 -0
  6. data/.github/workflows/release_7_x_scheduled.yml +39 -0
  7. data/.github/workflows/release_8_x_scheduled.yml +39 -0
  8. data/.github/workflows/test.yml +53 -0
  9. data/.rubocop.yml +81 -3
  10. data/.rubocop_todo.yml +43 -67
  11. data/.solr_wrapper.yml +2 -0
  12. data/VERSION +1 -1
  13. data/app/assets/builds/blacklight.css +17 -18
  14. data/app/assets/javascripts/blacklight/blacklight.esm.js +43 -73
  15. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
  16. data/app/assets/javascripts/blacklight/blacklight.js +43 -73
  17. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
  18. data/app/assets/stylesheets/blacklight/_blacklight_base.scss +0 -1
  19. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +4 -0
  20. data/app/assets/stylesheets/blacklight/_facets.scss +2 -2
  21. data/app/assets/stylesheets/blacklight/_header.scss +4 -0
  22. data/app/assets/stylesheets/blacklight/_modal.scss +9 -8
  23. data/app/assets/stylesheets/blacklight/_pagination.scss +1 -3
  24. data/app/assets/stylesheets/blacklight/_search_history.scss +0 -4
  25. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +3 -0
  26. data/app/components/blacklight/advanced_search_form_component.rb +2 -2
  27. data/app/components/blacklight/constraint_layout_component.html.erb +1 -6
  28. data/app/components/blacklight/constraint_layout_component.rb +9 -0
  29. data/app/components/blacklight/constraints_component.rb +2 -2
  30. data/app/components/blacklight/document/action_component.rb +1 -3
  31. data/app/components/blacklight/document/bookmark_component.html.erb +2 -2
  32. data/app/components/blacklight/document/bookmark_component.rb +2 -2
  33. data/app/components/blacklight/document/more_like_this_component.rb +2 -2
  34. data/app/components/blacklight/document/page_header_component.rb +2 -2
  35. data/app/components/blacklight/document/thumbnail_component.html.erb +3 -7
  36. data/app/components/blacklight/document/thumbnail_component.rb +7 -6
  37. data/app/components/blacklight/document_component.html.erb +3 -3
  38. data/app/components/blacklight/document_component.rb +5 -5
  39. data/app/components/blacklight/document_title_component.rb +6 -10
  40. data/app/components/blacklight/facet_field_checkboxes_component.rb +4 -18
  41. data/app/components/blacklight/facet_field_component.rb +4 -15
  42. data/app/components/blacklight/facet_field_filter_component.rb +4 -19
  43. data/app/components/blacklight/facet_field_inclusive_constraint_component.rb +4 -23
  44. data/app/components/blacklight/facet_field_list_component.rb +4 -30
  45. data/app/components/blacklight/facet_field_no_layout_component.rb +4 -8
  46. data/app/components/blacklight/facet_field_pagination_component.html.erb +2 -2
  47. data/app/components/blacklight/facet_item_component.rb +4 -72
  48. data/app/components/blacklight/facet_item_pivot_component.rb +1 -1
  49. data/app/components/blacklight/facets/checkboxes_component.rb +26 -0
  50. data/app/components/blacklight/facets/count_component.rb +23 -0
  51. data/app/components/blacklight/{facet_field_component.html.erb → facets/field_component.html.erb} +1 -1
  52. data/app/components/blacklight/facets/field_component.rb +23 -0
  53. data/app/components/blacklight/facets/filters_component.html.erb +4 -0
  54. data/app/components/blacklight/facets/filters_component.rb +39 -0
  55. data/app/components/blacklight/{facet_field_inclusive_constraint_component.html.erb → facets/inclusive_constraint_component.html.erb} +1 -1
  56. data/app/components/blacklight/facets/inclusive_constraint_component.rb +31 -0
  57. data/app/components/blacklight/{facet_field_filter_component.html.erb → facets/index_navigation_component.html.erb} +1 -1
  58. data/app/components/blacklight/facets/index_navigation_component.rb +32 -0
  59. data/app/components/blacklight/facets/item_component.rb +73 -0
  60. data/app/components/blacklight/facets/list_component.html.erb +11 -0
  61. data/app/components/blacklight/facets/list_component.rb +40 -0
  62. data/app/components/blacklight/facets/no_layout_component.rb +16 -0
  63. data/app/components/blacklight/facets/selected_value_component.rb +29 -0
  64. data/app/components/blacklight/facets/suggest_component.html.erb +12 -0
  65. data/app/components/blacklight/facets/suggest_component.rb +22 -0
  66. data/app/components/blacklight/icons/remove_component.rb +2 -2
  67. data/app/components/blacklight/metadata_field_plain_text_layout_component.rb +2 -2
  68. data/app/components/blacklight/response/facet_group_component.html.erb +3 -3
  69. data/app/components/blacklight/response/facet_group_component.rb +9 -1
  70. data/app/components/blacklight/system/dropdown_component.html.erb +1 -1
  71. data/app/components/blacklight/system/dropdown_component.rb +1 -1
  72. data/app/components/blacklight/system/flash_message_component.html.erb +1 -1
  73. data/app/components/blacklight/system/flash_message_component.rb +0 -9
  74. data/app/components/blacklight/system/modal_component.html.erb +1 -2
  75. data/app/components/blacklight/top_navbar_component.html.erb +1 -1
  76. data/app/controllers/concerns/blacklight/bookmarks.rb +3 -3
  77. data/app/controllers/concerns/blacklight/catalog.rb +16 -27
  78. data/app/controllers/concerns/blacklight/controller.rb +1 -1
  79. data/app/controllers/concerns/blacklight/facetable.rb +34 -0
  80. data/app/controllers/concerns/blacklight/search_context.rb +1 -1
  81. data/app/controllers/concerns/blacklight/searchable.rb +1 -1
  82. data/app/helpers/blacklight/catalog_helper_behavior.rb +1 -1
  83. data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -2
  84. data/app/helpers/blacklight/document_helper_behavior.rb +3 -1
  85. data/app/helpers/blacklight/facets_helper_behavior.rb +9 -0
  86. data/app/helpers/blacklight/icon_helper_behavior.rb +2 -2
  87. data/app/javascript/blacklight-frontend/bookmark_toggle.js +7 -2
  88. data/app/javascript/blacklight-frontend/checkbox_submit.js +8 -1
  89. data/app/javascript/blacklight-frontend/debounce.js +1 -1
  90. data/app/javascript/blacklight-frontend/facet_suggest.js +23 -3
  91. data/app/javascript/blacklight-frontend/index.js +0 -2
  92. data/app/javascript/blacklight-frontend/modal.js +2 -6
  93. data/app/javascript/blacklight-frontend/search_context.js +3 -2
  94. data/app/models/facet_search_builder.rb +5 -0
  95. data/app/presenters/blacklight/facet_field_presenter.rb +1 -1
  96. data/app/presenters/blacklight/json_presenter.rb +8 -4
  97. data/app/presenters/blacklight/rendering/helper_method.rb +4 -4
  98. data/app/presenters/blacklight/rendering/join.rb +2 -2
  99. data/app/services/blacklight/facet_search_service.rb +44 -0
  100. data/app/services/blacklight/field_retriever.rb +1 -1
  101. data/app/services/blacklight/search_service.rb +6 -6
  102. data/app/values/blacklight/types.rb +2 -2
  103. data/app/views/catalog/_facet_pivot.html.erb +1 -1
  104. data/app/views/catalog/_home_text.html.erb +2 -2
  105. data/app/views/catalog/_sort_and_per_page.html.erb +1 -1
  106. data/app/views/catalog/facet.html.erb +8 -10
  107. data/config/locales/blacklight.ar.yml +14 -13
  108. data/config/locales/blacklight.ca.yml +1 -0
  109. data/config/locales/blacklight.de.yml +13 -12
  110. data/config/locales/blacklight.en.yml +1 -0
  111. data/config/locales/blacklight.es.yml +13 -12
  112. data/config/locales/blacklight.fr.yml +14 -13
  113. data/config/locales/blacklight.hu.yml +15 -14
  114. data/config/locales/blacklight.it.yml +15 -14
  115. data/config/locales/blacklight.nl.yml +13 -12
  116. data/config/locales/blacklight.pt-BR.yml +15 -14
  117. data/config/locales/blacklight.sq.yml +14 -13
  118. data/config/locales/blacklight.zh.yml +11 -10
  119. data/lib/blacklight/abstract_repository.rb +2 -2
  120. data/lib/blacklight/abstract_search_builder.rb +154 -0
  121. data/lib/blacklight/configuration/context.rb +3 -3
  122. data/lib/blacklight/configuration/facet_field.rb +6 -6
  123. data/lib/blacklight/configuration/field.rb +4 -4
  124. data/lib/blacklight/configuration/fields.rb +0 -1
  125. data/lib/blacklight/configuration/search_field.rb +1 -1
  126. data/lib/blacklight/configuration/view_config.rb +2 -2
  127. data/lib/blacklight/configuration.rb +9 -4
  128. data/lib/blacklight/facet_search_builder.rb +18 -0
  129. data/lib/blacklight/nested_open_struct_with_hash_access.rb +1 -1
  130. data/lib/blacklight/open_struct_with_hash_access.rb +2 -2
  131. data/lib/blacklight/search_builder.rb +1 -159
  132. data/lib/blacklight/search_state/filter_field.rb +4 -4
  133. data/lib/blacklight/search_state/pivot_filter_field.rb +4 -4
  134. data/lib/blacklight/solr/abstract_filter_query_builder.rb +77 -0
  135. data/lib/blacklight/solr/default_filter_query_builder.rb +20 -0
  136. data/lib/blacklight/solr/facet_search_builder_behavior.rb +62 -0
  137. data/lib/blacklight/solr/repository.rb +12 -10
  138. data/lib/blacklight/solr/response/facets.rb +2 -2
  139. data/lib/blacklight/solr/response/params.rb +0 -4
  140. data/lib/blacklight/solr/response.rb +5 -1
  141. data/lib/blacklight/solr/search_builder_behavior.rb +17 -132
  142. data/lib/blacklight.rb +6 -4
  143. data/lib/generators/blacklight/assets/importmap_generator.rb +3 -5
  144. data/lib/generators/blacklight/assets_generator.rb +1 -1
  145. data/lib/generators/blacklight/search_builder_generator.rb +1 -1
  146. data/lib/generators/blacklight/templates/.solr_wrapper.yml +2 -0
  147. data/lib/generators/blacklight/templates/catalog_controller.rb +5 -3
  148. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +0 -4
  149. data/package.json +3 -3
  150. data/spec/components/blacklight/advanced_search_form_component_spec.rb +18 -22
  151. data/spec/components/blacklight/constraint_layout_component_spec.rb +8 -8
  152. data/spec/components/blacklight/constraints_component_spec.rb +11 -11
  153. data/spec/components/blacklight/document/action_component_spec.rb +23 -15
  154. data/spec/components/blacklight/document/group_component_spec.rb +10 -15
  155. data/spec/components/blacklight/document/page_header_component_spec.rb +35 -28
  156. data/spec/components/blacklight/document/sidebar_component_spec.rb +5 -11
  157. data/spec/components/blacklight/document_component_spec.rb +98 -65
  158. data/spec/components/blacklight/facet_component_spec.rb +12 -8
  159. data/spec/components/blacklight/facet_item_pivot_component_spec.rb +12 -12
  160. data/spec/components/blacklight/{facet_field_checkboxes_component_spec.rb → facets/checkboxes_component_spec.rb} +13 -13
  161. data/spec/components/blacklight/facets/filters_component_spec.rb +36 -0
  162. data/spec/components/blacklight/facets/index_navigation_component_spec.rb +40 -0
  163. data/spec/components/blacklight/{facet_item_component_spec.rb → facets/item_component_spec.rb} +10 -10
  164. data/spec/components/blacklight/{facet_field_list_component_spec.rb → facets/list_component_spec.rb} +23 -23
  165. data/spec/components/blacklight/facets/suggest_component_spec.rb +68 -0
  166. data/spec/components/blacklight/header_component_spec.rb +2 -4
  167. data/spec/components/blacklight/hidden_search_state_component_spec.rb +7 -7
  168. data/spec/components/blacklight/metadata_field_component_spec.rb +17 -15
  169. data/spec/components/blacklight/response/facet_group_component_spec.rb +37 -0
  170. data/spec/components/blacklight/response/pagination_component_spec.rb +1 -1
  171. data/spec/components/blacklight/response/spellcheck_component_spec.rb +1 -1
  172. data/spec/components/blacklight/search_bar_component_spec.rb +4 -4
  173. data/spec/components/blacklight/search_context/server_applied_params_component_spec.rb +2 -2
  174. data/spec/components/blacklight/search_context/server_item_pagination_component_spec.rb +3 -5
  175. data/spec/components/blacklight/skip_link_component_spec.rb +8 -11
  176. data/spec/components/blacklight/start_over_button_component_spec.rb +4 -4
  177. data/spec/components/blacklight/system/dropdown_component_spec.rb +26 -0
  178. data/spec/components/blacklight/system/flash_message_component_spec.rb +7 -11
  179. data/spec/controllers/catalog_controller_spec.rb +12 -20
  180. data/spec/features/facets_spec.rb +70 -7
  181. data/spec/features/modal_spec.rb +1 -1
  182. data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +10 -0
  183. data/spec/lib/blacklight/configuration/facet_field_spec.rb +2 -2
  184. data/spec/lib/blacklight/parameters_spec.rb +12 -1
  185. data/spec/lib/blacklight/search_state/filter_field_spec.rb +18 -0
  186. data/spec/models/blacklight/configuration_spec.rb +52 -28
  187. data/spec/models/blacklight/facet_search_builder_spec.rb +19 -0
  188. data/spec/models/blacklight/search_builder_spec.rb +1 -11
  189. data/spec/models/blacklight/solr/default_filter_query_builder_spec.rb +72 -0
  190. data/spec/models/blacklight/solr/document_spec.rb +0 -4
  191. data/spec/models/blacklight/solr/facet_search_builder_behavior_spec.rb +929 -0
  192. data/spec/models/blacklight/solr/repository_spec.rb +31 -29
  193. data/spec/models/blacklight/solr/response/facets_spec.rb +86 -40
  194. data/spec/models/blacklight/solr/response/group_response_spec.rb +8 -5
  195. data/spec/models/blacklight/solr/response/group_spec.rb +9 -5
  196. data/spec/models/blacklight/solr/response_spec.rb +96 -64
  197. data/spec/models/blacklight/solr/search_builder_behavior_spec.rb +2 -227
  198. data/spec/models/solr_document_spec.rb +5 -1
  199. data/spec/presenters/blacklight/json_presenter_spec.rb +17 -0
  200. data/spec/services/blacklight/search_service_spec.rb +6 -27
  201. data/spec/spec_helper.rb +0 -1
  202. data/spec/support/view_component_test_helpers.rb +0 -18
  203. data/spec/views/catalog/facet.html.erb_spec.rb +10 -3
  204. data/spec/views/catalog/index.atom.builder_spec.rb +6 -3
  205. data/spec/views/catalog/index.html.erb_spec.rb +3 -1
  206. metadata +57 -29
  207. data/.github/workflows/ruby.yml +0 -98
  208. data/app/assets/stylesheets/blacklight/_icons.scss +0 -4
  209. data/app/components/blacklight/facet_field_list_component.html.erb +0 -19
  210. data/app/components/blacklight/search/facet_suggest_input.html.erb +0 -9
  211. data/app/components/blacklight/search/facet_suggest_input.rb +0 -16
  212. data/app/javascript/blacklight-frontend/modalForm.js +0 -60
  213. data/app/views/catalog/_facet_index_navigation.html.erb +0 -1
  214. data/app/views/catalog/_facet_layout.html.erb +0 -8
  215. data/app/views/catalog/_facet_pagination.html.erb +0 -1
  216. data/spec/components/blacklight/document_metadata_component_spec.rb +0 -0
  217. data/spec/components/blacklight/search/facet_suggest_input_spec.rb +0 -33
  218. data/spec/views/catalog/_facet_index_navigation.html.erb_spec.rb +0 -43
  219. data/spec/views/catalog/_facet_layout.html.erb_spec.rb +0 -41
  220. /data/app/components/blacklight/{facet_field_checkboxes_component.html.erb → facets/checkboxes_component.html.erb} +0 -0
@@ -99,7 +99,7 @@ RSpec.describe "Facets" do
99
99
  end
100
100
  end
101
101
 
102
- describe 'Facet modal' do
102
+ describe 'Facet modal content' do
103
103
  it 'allows the user to filter a long list of facet values', :js do
104
104
  visit '/catalog/facet/subject_ssim'
105
105
  expect(page).to have_no_link 'Old age' # This is on the second page of facet values
@@ -107,6 +107,7 @@ RSpec.describe "Facets" do
107
107
 
108
108
  fill_in 'facet_suggest_subject_ssim', with: "ag"
109
109
 
110
+ expect(page).to have_css '.facet-suggestions'
110
111
  expect(page).to have_link 'Old age'
111
112
  expect(page).to have_css 'a.facet-select', count: 2
112
113
  end
@@ -115,19 +116,81 @@ RSpec.describe "Facets" do
115
116
  visit '/catalog/facet/subject_ssim?q=tibet&search_field=all_fields'
116
117
  fill_in 'facet_suggest_subject_ssim', with: 'la'
117
118
 
119
+ expect(page).to have_css '.facet-suggestions'
118
120
  expect(page).to have_link 'Tibetan language'
121
+ expect(page).to have_no_link 'Law'
119
122
  expect(page).to have_css 'a.facet-select', count: 1
120
123
  end
121
124
 
122
- it 'allows the user to filter more than once', :js do
125
+ it 'allows the user to toggle the sort, then filter', :js do
123
126
  visit '/catalog/facet/subject_ssim'
124
- expect(page).to have_no_link 'Old age' # This is on the second page of facet values
125
- expect(page).to have_css 'a.facet-select', count: 20
126
127
 
127
- fill_in 'facet_suggest_subject_ssim', with: "ag"
128
+ fill_in 'facet_suggest_subject_ssim', with: 'po'
128
129
 
129
- expect(page).to have_link 'Old age'
130
- expect(page).to have_link('Old age', href: '/?f%5Bsubject_ssim%5D%5B%5D=Old+age')
130
+ expect(page).to have_css '.facet-suggestions'
131
+ expect(page).to have_css('.facet-values li:nth-child(1)', text: 'Political plays, Japanese')
132
+ expect(page).to have_css('.facet-values li:nth-child(2)', text: 'Military weapons')
133
+ expect(page).to have_css('.facet-values li:nth-child(3)', text: 'Political science')
134
+
135
+ first(:link, 'A-Z Sort').click
136
+
137
+ expect(page).to have_css('.facet-suggest[data-facet-search-context*="facet.sort=index"]')
138
+
139
+ fill_in 'facet_suggest_subject_ssim', with: 'po'
140
+
141
+ expect(page).to have_css '.facet-suggestions'
142
+ expect(page).to have_css('.facet-values li:nth-child(1)', text: 'Military weapons')
143
+ expect(page).to have_css('.facet-values li:nth-child(2)', text: 'Political plays, Japanese')
144
+ expect(page).to have_css('.facet-values li:nth-child(3)', text: 'Political science')
145
+ end
146
+
147
+ it 'allows the user to choose a starting letter, then filter', :js do
148
+ visit '/catalog/facet/subject_ssim'
149
+
150
+ first(:link, 'A-Z Sort').click
151
+ expect(page).to have_css('.facet-suggest[data-facet-search-context*="facet.sort=index"]')
152
+
153
+ click_on 'M'
154
+ expect(page).to have_css('.facet-suggest[data-facet-search-context*="facet.prefix=M"]')
155
+
156
+ fill_in 'facet_suggest_subject_ssim', with: 'te'
157
+
158
+ expect(page).to have_css '.facet-suggestions'
159
+ expect(page).to have_link 'Maternity insurance'
160
+ expect(page).to have_no_link 'Teaching'
161
+ end
162
+
163
+ it 'hides previous/next links when filtering', :js do
164
+ visit '/catalog/facet/subject_ssim'
165
+ expect(page).to have_link 'Next »'
166
+
167
+ fill_in 'facet_suggest_subject_ssim', with: 'te'
168
+ expect(page).to have_css '.facet-suggestions'
169
+ expect(page).to have_no_link 'Next »'
170
+
171
+ fill_in 'facet_suggest_subject_ssim', with: ''
172
+ expect(page).to have_no_css '.facet-suggestions'
173
+ expect(page).to have_link 'Next »'
174
+ end
175
+
176
+ context 'when facet is configured with suggest: false' do
177
+ before do
178
+ enabled = CatalogController.blacklight_config.dup
179
+ enabled.facet_fields[:subject_ssim].merge!({ suggest: false })
180
+ allow(CatalogController).to receive(:blacklight_config).and_return enabled
181
+ end
182
+
183
+ it 'does not offer the user a way to filter the list of facet values' do
184
+ visit '/catalog/facet/subject_ssim'
185
+ expect(page).to have_no_field 'facet_suggest_subject_ssim'
186
+ end
187
+ end
188
+ end
189
+
190
+ describe 'facebook-style facet parameters' do
191
+ it 'can perform a search' do
192
+ visit '/?f[subject_ssim][0]=Iran.+Viza%CC%84rat-i+Kishvar'
193
+ expect(page).to have_text 'Naqdī barā-yi tamām-i fuṣūl'
131
194
  end
132
195
  end
133
196
  end
@@ -6,7 +6,7 @@ RSpec.describe 'Modal' do
6
6
  expect(page).to have_no_selector 'dialog#blacklight-modal'
7
7
  click_on 'Email'
8
8
  expect(page).to have_css 'dialog#blacklight-modal'
9
- click_on '×'
9
+ find('button[aria-label=Close]').click
10
10
  expect(page).to have_no_selector 'dialog#blacklight-modal'
11
11
  end
12
12
  end
@@ -26,4 +26,14 @@ RSpec.describe Blacklight::FacetsHelperBehavior do
26
26
  expect(presenter).to be_a SomePresenter
27
27
  end
28
28
  end
29
+
30
+ describe "#search_facet_path" do
31
+ before do
32
+ params[:controller] = 'catalog'
33
+ end
34
+
35
+ it "is the same as the catalog path" do
36
+ expect(helper.search_facet_path(id: "some_facet", page: 5)).to eq facet_catalog_path(id: "some_facet")
37
+ end
38
+ end
29
39
  end
@@ -23,7 +23,7 @@ RSpec.describe Blacklight::Configuration::FacetField do
23
23
  subject.normalize!
24
24
 
25
25
  expect(subject.presenter).to eq Blacklight::FacetFieldPresenter
26
- expect(subject.component).to eq Blacklight::FacetFieldListComponent
26
+ expect(subject.component).to eq Blacklight::Facets::ListComponent
27
27
  end
28
28
 
29
29
  context 'when component is set to true' do
@@ -34,7 +34,7 @@ RSpec.describe Blacklight::Configuration::FacetField do
34
34
  it 'casts to the default component' do
35
35
  subject.normalize!
36
36
 
37
- expect(subject.component).to eq Blacklight::FacetFieldListComponent
37
+ expect(subject.component).to eq Blacklight::Facets::ListComponent
38
38
  end
39
39
  end
40
40
  end
@@ -52,7 +52,7 @@ RSpec.describe Blacklight::Parameters do
52
52
  let(:search_state) { Blacklight::SearchState.new(query_params, blacklight_config) }
53
53
  let(:blacklight_config) { Blacklight::Configuration.new }
54
54
 
55
- context 'with facebooks badly mangled query parameters' do
55
+ context 'with facebook\'s badly mangled query parameters' do
56
56
  let(:query_params) do
57
57
  ActionController::Parameters.new(
58
58
  f: { field: { '0': 'first', '1': 'second' } },
@@ -67,6 +67,17 @@ RSpec.describe Blacklight::Parameters do
67
67
  it 'normalizes the facets to the expected format' do
68
68
  expect(params.permit_search_params.to_h.with_indifferent_access).to include f: { field: %w[first second] }, f_inclusive: { field: %w[first second] }
69
69
  end
70
+
71
+ context 'when several fields are configured' do
72
+ before do
73
+ blacklight_config.add_facet_field 'other_field'
74
+ blacklight_config.add_facet_field 'some_other_pivot_field', pivot: %w[abc def]
75
+ end
76
+
77
+ it 'normalizes the facets to the expected format' do
78
+ expect(params.permit_search_params.to_h.with_indifferent_access).to include f: { field: %w[first second] }, f_inclusive: { field: %w[first second] }
79
+ end
80
+ end
70
81
  end
71
82
 
72
83
  context 'with filter_search_state_fields set to false' do
@@ -198,4 +198,22 @@ RSpec.describe Blacklight::SearchState::FilterField do
198
198
  expect(search_state.filter('some_field').include?(OpenStruct.new(value: '1'))).to be true
199
199
  end
200
200
  end
201
+
202
+ describe '#permitted_params' do
203
+ context 'with a pivot facet' do
204
+ let(:blacklight_config) do
205
+ Blacklight::Configuration.new.configure do |config|
206
+ config.add_facet_field 'my_pivot', pivot: %w[format language_ssim]
207
+ end
208
+ end
209
+
210
+ it 'marks all the pivot fields as permitted' do
211
+ field = described_class.new blacklight_config.facet_fields['my_pivot'], search_state
212
+ expect(field.permitted_params).to eq({
213
+ f: { "-format" => [], "-language_ssim" => [], "format" => [], "language_ssim" => [] },
214
+ f_inclusive: { "format" => [], "language_ssim" => [] }
215
+ })
216
+ end
217
+ end
218
+ end
201
219
  end
@@ -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,23 @@ 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)
709
733
 
710
- Blacklight::Configuration.default_configuration.delete_at(1)
711
- Blacklight::Configuration.default_configuration.delete_at(2)
734
+ described_class.default_configuration.delete_at(1)
735
+ described_class.default_configuration.delete_at(2)
712
736
  end
713
737
  end
714
738
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Blacklight::FacetSearchBuilder, :api do
4
+ subject(:builder) { described_class.new processor_chain, scope }
5
+
6
+ let(:processor_chain) { [] }
7
+ let(:blacklight_config) { Blacklight::Configuration.new }
8
+ let(:scope) { double blacklight_config: blacklight_config, search_state_class: nil }
9
+
10
+ describe "#facet_suggestion_query" do
11
+ it "is nil if no value is set" do
12
+ expect(subject.facet_suggestion_query).to be_nil
13
+ end
14
+
15
+ it "sets facet_suggestion_query value" do
16
+ expect(subject.facet_suggestion_query('antel').facet_suggestion_query).to eq 'antel'
17
+ end
18
+ end
19
+ end
@@ -125,7 +125,7 @@ RSpec.describe Blacklight::SearchBuilder, :api do
125
125
  end
126
126
 
127
127
  subject.with(a: 1)
128
- expect(subject.processed_parameters).to include step_1: 'builder'
128
+ expect(subject.send(:processed_parameters)).to include step_1: 'builder'
129
129
  end
130
130
  end
131
131
 
@@ -225,16 +225,6 @@ RSpec.describe Blacklight::SearchBuilder, :api do
225
225
  end
226
226
  end
227
227
 
228
- describe "#facet_suggestion_query" do
229
- it "is nil if no value is set" do
230
- expect(subject.facet_suggestion_query).to be_nil
231
- end
232
-
233
- it "sets facet_suggestion_query value" do
234
- expect(subject.facet_suggestion_query('antel').facet_suggestion_query).to eq 'antel'
235
- end
236
- end
237
-
238
228
  describe "#search_field" do
239
229
  it "uses the requested search field" do
240
230
  blacklight_config.add_search_field 'x'
@@ -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