blacklight 9.0.0.beta8 → 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.
- checksums.yaml +4 -4
- data/.github/matrix.json +16 -26
- data/README.md +2 -2
- data/VERSION +1 -1
- data/app/assets/javascripts/blacklight/blacklight.esm.js +6 -3
- data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
- data/app/assets/javascripts/blacklight/blacklight.js +6 -3
- data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
- data/app/components/blacklight/facets/filters_component.rb +1 -1
- data/app/components/blacklight/facets/suggest_component.html.erb +17 -12
- data/app/controllers/concerns/blacklight/catalog.rb +3 -4
- data/app/javascript/blacklight-frontend/checkbox_submit.js +2 -2
- data/app/javascript/blacklight-frontend/facet_suggest.js +4 -1
- data/app/services/blacklight/search_service.rb +4 -2
- data/lib/blacklight/configuration.rb +0 -4
- data/lib/blacklight/routes/searchable.rb +1 -1
- data/lib/blacklight/search_builder.rb +160 -1
- data/lib/blacklight/solr/search_builder_behavior.rb +56 -7
- data/lib/generators/blacklight/templates/catalog_controller.rb +1 -1
- data/package.json +1 -1
- data/spec/components/blacklight/facets/filters_component_spec.rb +1 -1
- data/spec/components/blacklight/facets/suggest_component_spec.rb +1 -1
- data/spec/features/facets_spec.rb +9 -0
- data/spec/models/blacklight/search_builder_spec.rb +11 -1
- data/spec/models/blacklight/solr/search_builder_behavior_spec.rb +162 -2
- metadata +6 -13
- data/app/controllers/concerns/blacklight/facetable.rb +0 -34
- data/app/models/facet_search_builder.rb +0 -5
- data/app/services/blacklight/facet_search_service.rb +0 -44
- data/lib/blacklight/abstract_search_builder.rb +0 -154
- data/lib/blacklight/facet_search_builder.rb +0 -18
- data/lib/blacklight/solr/facet_search_builder_behavior.rb +0 -62
- data/spec/models/blacklight/facet_search_builder_spec.rb +0 -19
- data/spec/models/blacklight/solr/facet_search_builder_behavior_spec.rb +0 -929
|
@@ -22,8 +22,10 @@ module Blacklight
|
|
|
22
22
|
@search_state.class
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
#
|
|
26
|
-
# @yield [search_builder] optional block yields configured SearchBuilder,
|
|
25
|
+
# Fetch query results from solr
|
|
26
|
+
# @yield [search_builder] optional block yields configured SearchBuilder, caller can modify or create new
|
|
27
|
+
# SearchBuilder to be used. Block should return SearchBuilder to be used.
|
|
28
|
+
# This is used in blacklight_range_limit
|
|
27
29
|
# @return [Blacklight::Solr::Response] the solr response object
|
|
28
30
|
def search_results
|
|
29
31
|
builder = search_builder.with(search_state)
|
|
@@ -47,7 +47,6 @@ module Blacklight
|
|
|
47
47
|
property :header_component, default: Blacklight::HeaderComponent
|
|
48
48
|
property :full_width_layout, default: false
|
|
49
49
|
|
|
50
|
-
# bootstrap_version may be set to 4 or 5
|
|
51
50
|
bootstrap_version = ENV['BOOTSTRAP_VERSION'].presence || "5"
|
|
52
51
|
property :bootstrap_version, default: /(\d)(?:\.\d){0,2}/.match(bootstrap_version)[1].to_i
|
|
53
52
|
|
|
@@ -104,9 +103,6 @@ module Blacklight
|
|
|
104
103
|
# @!attribute search_builder_class
|
|
105
104
|
# @return [Class] class for converting Blacklight parameters to request parameters for the repository_class
|
|
106
105
|
property :search_builder_class, default: ::SearchBuilder
|
|
107
|
-
# @!attribute search_builder_class
|
|
108
|
-
# @return [Class] class for converting Blacklight parameters to request parameters for the repository_class
|
|
109
|
-
property :facet_search_builder_class, default: ::FacetSearchBuilder
|
|
110
106
|
# @!attribute response_model
|
|
111
107
|
# model that maps index responses to the blacklight response model
|
|
112
108
|
# @return [Class]
|
|
@@ -18,7 +18,7 @@ module Blacklight
|
|
|
18
18
|
mapper.get "opensearch"
|
|
19
19
|
mapper.get 'suggest', as: 'suggest_index'
|
|
20
20
|
mapper.get "facet/:id", action: 'facet', as: 'facet'
|
|
21
|
-
mapper.get "facet_suggest/:id
|
|
21
|
+
mapper.get "facet_suggest/:id", action: 'facet', as: 'facet_suggest', defaults: { only_values: true }
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
end
|
|
@@ -5,7 +5,45 @@ module Blacklight
|
|
|
5
5
|
# Blacklight's SearchBuilder converts blacklight request parameters into
|
|
6
6
|
# query parameters appropriate for search index. It does so by evaluating a
|
|
7
7
|
# chain of processing methods to populate a result hash (see {#to_hash}).
|
|
8
|
-
class SearchBuilder
|
|
8
|
+
class SearchBuilder
|
|
9
|
+
class_attribute :default_processor_chain
|
|
10
|
+
self.default_processor_chain = []
|
|
11
|
+
|
|
12
|
+
attr_reader :processor_chain, :search_state, :blacklight_params
|
|
13
|
+
|
|
14
|
+
# @overload initialize(scope)
|
|
15
|
+
# @param [Object] scope the scope where the filter methods reside in.
|
|
16
|
+
# @overload initialize(processor_chain, scope)
|
|
17
|
+
# @param [List<Symbol>,TrueClass] processor_chain options a list of filter methods to run or true, to use the default methods
|
|
18
|
+
# @param [Object] scope the scope where the filter methods reside in.
|
|
19
|
+
def initialize(*options)
|
|
20
|
+
case options.size
|
|
21
|
+
when 1
|
|
22
|
+
@processor_chain = default_processor_chain.dup
|
|
23
|
+
@scope = options.first
|
|
24
|
+
when 2
|
|
25
|
+
@processor_chain, @scope = options
|
|
26
|
+
else
|
|
27
|
+
raise ArgumentError, "wrong number of arguments. (#{options.size} for 1..2)"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
@blacklight_params = {}
|
|
31
|
+
search_state_class = @scope.try(:search_state_class) || Blacklight::SearchState
|
|
32
|
+
@search_state = search_state_class.new(@blacklight_params, @scope&.blacklight_config, @scope)
|
|
33
|
+
@additional_filters = {}
|
|
34
|
+
@merged_params = {}
|
|
35
|
+
@reverse_merged_params = {}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
##
|
|
39
|
+
# Set the parameters to pass through the processor chain
|
|
40
|
+
def with(blacklight_params_or_search_state = {})
|
|
41
|
+
params_will_change!
|
|
42
|
+
@search_state = blacklight_params_or_search_state.is_a?(Blacklight::SearchState) ? blacklight_params_or_search_state : @search_state.reset(blacklight_params_or_search_state)
|
|
43
|
+
@blacklight_params = @search_state.params.dup
|
|
44
|
+
self
|
|
45
|
+
end
|
|
46
|
+
|
|
9
47
|
##
|
|
10
48
|
# Update the :q (query) parameter
|
|
11
49
|
# @param [Hash<Symbol,Object>] conditions the field and values to query on
|
|
@@ -21,6 +59,7 @@ module Blacklight
|
|
|
21
59
|
|
|
22
60
|
##
|
|
23
61
|
# Append additional processor chain directives
|
|
62
|
+
# This is used in blacklight_range_limit
|
|
24
63
|
def append(*addl_processor_chain)
|
|
25
64
|
params_will_change!
|
|
26
65
|
builder = self.class.new(processor_chain + addl_processor_chain, scope)
|
|
@@ -55,6 +94,68 @@ module Blacklight
|
|
|
55
94
|
builder
|
|
56
95
|
end
|
|
57
96
|
|
|
97
|
+
##
|
|
98
|
+
# Merge additional, repository-specific parameters
|
|
99
|
+
def merge(extra_params, &)
|
|
100
|
+
if extra_params
|
|
101
|
+
params_will_change!
|
|
102
|
+
@merged_params.merge!(extra_params.to_hash, &)
|
|
103
|
+
end
|
|
104
|
+
self
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
##
|
|
108
|
+
# "Reverse merge" additional, repository-specific parameters
|
|
109
|
+
def reverse_merge(extra_params, &)
|
|
110
|
+
if extra_params
|
|
111
|
+
params_will_change!
|
|
112
|
+
@reverse_merged_params.reverse_merge!(extra_params.to_hash, &)
|
|
113
|
+
end
|
|
114
|
+
self
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
delegate :[], :key?, to: :to_hash
|
|
118
|
+
|
|
119
|
+
# a solr query method
|
|
120
|
+
# @return [Blacklight::Solr::Response] the solr response object
|
|
121
|
+
def to_hash
|
|
122
|
+
return @params unless params_need_update?
|
|
123
|
+
|
|
124
|
+
@params = processed_parameters
|
|
125
|
+
.reverse_merge(@reverse_merged_params)
|
|
126
|
+
.merge(@merged_params)
|
|
127
|
+
.tap { clear_changes }
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
alias_method :query, :to_hash
|
|
131
|
+
alias_method :to_h, :to_hash
|
|
132
|
+
|
|
133
|
+
# The CatalogController #index action uses this.
|
|
134
|
+
# Solr parameters can come from a number of places. From lowest
|
|
135
|
+
# precedence to highest:
|
|
136
|
+
# 1. General defaults in blacklight config (are trumped by)
|
|
137
|
+
# 2. defaults for the particular search field identified by params[:search_field] (are trumped by)
|
|
138
|
+
# 3. certain parameters directly on input HTTP query params
|
|
139
|
+
# * not just any parameter is grabbed willy nilly, only certain ones are allowed by HTTP input)
|
|
140
|
+
# * for legacy reasons, qt in http query does not over-ride qt in search field definition default.
|
|
141
|
+
# 4. extra parameters passed in as argument.
|
|
142
|
+
#
|
|
143
|
+
# spellcheck.q will be supplied with the [:q] value unless specifically
|
|
144
|
+
# specified otherwise.
|
|
145
|
+
#
|
|
146
|
+
# Incoming parameter :f is mapped to :fq solr parameter.
|
|
147
|
+
#
|
|
148
|
+
# @return a params hash for searching solr.
|
|
149
|
+
def processed_parameters
|
|
150
|
+
request.tap do |request_parameters|
|
|
151
|
+
processor_chain.each do |method_name|
|
|
152
|
+
send(method_name, request_parameters)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
delegate :blacklight_config, to: :scope
|
|
158
|
+
|
|
58
159
|
def start=(value)
|
|
59
160
|
params_will_change!
|
|
60
161
|
@start = value.to_i
|
|
@@ -109,6 +210,34 @@ module Blacklight
|
|
|
109
210
|
|
|
110
211
|
alias per rows
|
|
111
212
|
|
|
213
|
+
# sets the facet that this query pertains to, for the purpose of facet pagination
|
|
214
|
+
def facet=(value)
|
|
215
|
+
params_will_change!
|
|
216
|
+
@facet = value
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# @param [Object] value
|
|
220
|
+
def facet(value = nil)
|
|
221
|
+
if value
|
|
222
|
+
self.facet = value
|
|
223
|
+
return self
|
|
224
|
+
end
|
|
225
|
+
@facet
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def facet_suggestion_query=(value)
|
|
229
|
+
params_will_change!
|
|
230
|
+
@facet_suggestion_query = value
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def facet_suggestion_query(value = nil)
|
|
234
|
+
if value
|
|
235
|
+
self.facet_suggestion_query = value
|
|
236
|
+
return self
|
|
237
|
+
end
|
|
238
|
+
@facet_suggestion_query
|
|
239
|
+
end
|
|
240
|
+
|
|
112
241
|
# Decode the user provided 'sort' parameter into a sort string that can be
|
|
113
242
|
# passed to the search. This sanitizes the input by ensuring only
|
|
114
243
|
# configured search values are passed through to the search.
|
|
@@ -116,5 +245,35 @@ module Blacklight
|
|
|
116
245
|
def sort
|
|
117
246
|
search_state.sort_field&.sort
|
|
118
247
|
end
|
|
248
|
+
|
|
249
|
+
delegate :search_field, to: :search_state
|
|
250
|
+
|
|
251
|
+
private
|
|
252
|
+
|
|
253
|
+
def request
|
|
254
|
+
Blacklight::Solr::Request.new
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def should_add_field_to_request? _field_name, field
|
|
258
|
+
field.include_in_request || (field.include_in_request.nil? && blacklight_config.add_field_configuration_to_solr_request)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
attr_reader :scope
|
|
262
|
+
|
|
263
|
+
def params_will_change!
|
|
264
|
+
@dirty = true
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def params_changed?
|
|
268
|
+
!!@dirty
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def params_need_update?
|
|
272
|
+
params_changed? || @params.nil?
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def clear_changes
|
|
276
|
+
@dirty = false
|
|
277
|
+
end
|
|
119
278
|
end
|
|
120
279
|
end
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Blacklight::Solr
|
|
4
|
+
# This depends on being imported into a class that extends AbstractSearchBuilder
|
|
4
5
|
module SearchBuilderBehavior
|
|
5
6
|
extend ActiveSupport::Concern
|
|
6
7
|
|
|
7
8
|
included do
|
|
8
9
|
self.default_processor_chain = [
|
|
9
|
-
:default_solr_parameters,
|
|
10
|
-
:
|
|
11
|
-
:
|
|
12
|
-
:
|
|
13
|
-
:
|
|
10
|
+
:default_solr_parameters,
|
|
11
|
+
:add_search_field_default_parameters,
|
|
12
|
+
:add_query_to_solr,
|
|
13
|
+
:add_facet_fq_to_solr,
|
|
14
|
+
:add_facetting_to_solr,
|
|
15
|
+
:add_solr_fields_to_query,
|
|
16
|
+
:add_paging_to_solr,
|
|
17
|
+
:add_sorting_to_solr,
|
|
18
|
+
:add_group_config_to_solr,
|
|
19
|
+
:add_adv_search_clauses,
|
|
20
|
+
:add_facets_for_advanced_search_form,
|
|
21
|
+
:add_facet_paging_to_solr,
|
|
22
|
+
:add_facet_suggestion_parameters,
|
|
14
23
|
:add_additional_filters
|
|
15
24
|
]
|
|
16
25
|
end
|
|
@@ -232,8 +241,6 @@ module Blacklight::Solr
|
|
|
232
241
|
# copy paging params from BL app over to solr, changing
|
|
233
242
|
# app level per_page and page to Solr rows and start.
|
|
234
243
|
def add_paging_to_solr(solr_params)
|
|
235
|
-
rows(solr_params[:rows] || 10) if rows.nil?
|
|
236
|
-
|
|
237
244
|
solr_params[:rows] = rows
|
|
238
245
|
|
|
239
246
|
solr_params[:start] = start if start.nonzero?
|
|
@@ -250,6 +257,48 @@ module Blacklight::Solr
|
|
|
250
257
|
solr_parameters[:group] = false if search_state.filter(grouped_key_for_results).any?
|
|
251
258
|
end
|
|
252
259
|
|
|
260
|
+
def add_facet_paging_to_solr(solr_params)
|
|
261
|
+
return if facet.blank?
|
|
262
|
+
|
|
263
|
+
facet_config = blacklight_config.facet_fields[facet]
|
|
264
|
+
|
|
265
|
+
solr_params[:rows] = 0
|
|
266
|
+
|
|
267
|
+
limit = if solr_params["facet.limit"]
|
|
268
|
+
solr_params["facet.limit"].to_i
|
|
269
|
+
else
|
|
270
|
+
facet_config.fetch(:more_limit, blacklight_config.default_more_limit)
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
page = search_state.facet_page
|
|
274
|
+
sort = search_state.facet_sort
|
|
275
|
+
prefix = search_state.facet_prefix
|
|
276
|
+
offset = (page - 1) * limit
|
|
277
|
+
|
|
278
|
+
if facet_config.json
|
|
279
|
+
add_solr_facet_json_params(solr_parameters, facet, facet_config, limit: limit + 1, offset: offset, sort: sort, prefix: prefix)
|
|
280
|
+
return
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
# Now override with our specific things for fetching facet values
|
|
284
|
+
facet_ex = facet_config.respond_to?(:ex) ? facet_config.ex : nil
|
|
285
|
+
solr_params[:'facet.field'] = with_ex_local_param(facet_ex, facet_config.field)
|
|
286
|
+
|
|
287
|
+
# Need to set as f.facet_field.facet.* to make sure we
|
|
288
|
+
# override any field-specific default in the solr request handler.
|
|
289
|
+
solr_params[:"f.#{facet_config.field}.facet.limit"] = limit + 1
|
|
290
|
+
solr_params[:"f.#{facet_config.field}.facet.offset"] = offset
|
|
291
|
+
solr_params[:"f.#{facet_config.field}.facet.sort"] = sort if sort
|
|
292
|
+
solr_params[:"f.#{facet_config.field}.facet.prefix"] = prefix if prefix
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def add_facet_suggestion_parameters(solr_params)
|
|
296
|
+
return if facet.blank? || facet_suggestion_query.blank?
|
|
297
|
+
|
|
298
|
+
solr_params[:'facet.contains'] = facet_suggestion_query[0..50]
|
|
299
|
+
solr_params[:'facet.contains.ignoreCase'] = true
|
|
300
|
+
end
|
|
301
|
+
|
|
253
302
|
def with_ex_local_param(ex, value)
|
|
254
303
|
if ex
|
|
255
304
|
"{!ex=#{ex}}#{value}"
|
|
@@ -12,7 +12,7 @@ class <%= controller_name.classify %>Controller < ApplicationController
|
|
|
12
12
|
# rescue_from Blacklight::Exceptions::InvalidRequest, with: :my_handling_method
|
|
13
13
|
|
|
14
14
|
configure_blacklight do |config|
|
|
15
|
-
## Specify the style of markup to be generated
|
|
15
|
+
## Specify the style of markup to be generated
|
|
16
16
|
# config.bootstrap_version = 5
|
|
17
17
|
#
|
|
18
18
|
## Class for sending and receiving requests from a search index
|
data/package.json
CHANGED
|
@@ -22,7 +22,7 @@ RSpec.describe Blacklight::Facets::FiltersComponent, type: :component do
|
|
|
22
22
|
let(:component) { described_class.new(presenter: presenter) }
|
|
23
23
|
|
|
24
24
|
it 'draws default classes' do
|
|
25
|
-
expect(page).to have_css(".facet-filters.
|
|
25
|
+
expect(page).to have_css(".facet-filters.mt-1.mb-3")
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
@@ -37,7 +37,7 @@ RSpec.describe Blacklight::Facets::SuggestComponent, type: :component do
|
|
|
37
37
|
with_request_url "/catalog/facet/language_facet" do
|
|
38
38
|
rendered = render_inline component
|
|
39
39
|
label = rendered.css('label').first
|
|
40
|
-
expect(label.text.strip).to eq 'Filter
|
|
40
|
+
expect(label.text.strip).to eq 'Filter languages'
|
|
41
41
|
|
|
42
42
|
id_in_label_for = label.attribute('for').text
|
|
43
43
|
expect(id_in_label_for).to eq('facet_suggest_language_facet')
|
|
@@ -112,6 +112,15 @@ RSpec.describe "Facets" do
|
|
|
112
112
|
expect(page).to have_css 'a.facet-select', count: 2
|
|
113
113
|
end
|
|
114
114
|
|
|
115
|
+
it 'can show suggestions including a period', :js do
|
|
116
|
+
visit '/catalog/facet/subject_ssim'
|
|
117
|
+
fill_in 'facet_suggest_subject_ssim', with: 'iran.'
|
|
118
|
+
|
|
119
|
+
expect(page).to have_css '.facet-suggestions'
|
|
120
|
+
expect(page).to have_link 'Iran. Vizārat-i Kishvar'
|
|
121
|
+
expect(page).to have_css 'a.facet-select', count: 1
|
|
122
|
+
end
|
|
123
|
+
|
|
115
124
|
it 'shows the user facet suggestions that are relevant to their q param', :js do
|
|
116
125
|
visit '/catalog/facet/subject_ssim?q=tibet&search_field=all_fields'
|
|
117
126
|
fill_in 'facet_suggest_subject_ssim', with: 'la'
|
|
@@ -125,7 +125,7 @@ RSpec.describe Blacklight::SearchBuilder, :api do
|
|
|
125
125
|
end
|
|
126
126
|
|
|
127
127
|
subject.with(a: 1)
|
|
128
|
-
expect(subject.
|
|
128
|
+
expect(subject.processed_parameters).to include step_1: 'builder'
|
|
129
129
|
end
|
|
130
130
|
end
|
|
131
131
|
|
|
@@ -225,6 +225,16 @@ 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
|
+
|
|
228
238
|
describe "#search_field" do
|
|
229
239
|
it "uses the requested search field" do
|
|
230
240
|
blacklight_config.add_search_field 'x'
|
|
@@ -43,7 +43,7 @@ RSpec.describe Blacklight::Solr::SearchBuilderBehavior, :api do
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
context "with a complex parameter environment" do
|
|
46
|
-
subject { search_builder.with(user_params).
|
|
46
|
+
subject { search_builder.with(user_params).processed_parameters }
|
|
47
47
|
|
|
48
48
|
let(:user_params) do
|
|
49
49
|
{ :search_field => "test_field", :q => "test query", "facet.field" => "extra_facet" }
|
|
@@ -90,7 +90,7 @@ RSpec.describe Blacklight::Solr::SearchBuilderBehavior, :api do
|
|
|
90
90
|
# SPECS for actual search parameter generation
|
|
91
91
|
describe "#processed_parameters" do
|
|
92
92
|
subject do
|
|
93
|
-
search_builder.with(user_params).
|
|
93
|
+
search_builder.with(user_params).processed_parameters
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
context "when search_params_logic is customized" do
|
|
@@ -718,6 +718,166 @@ RSpec.describe Blacklight::Solr::SearchBuilderBehavior, :api do
|
|
|
718
718
|
end
|
|
719
719
|
end
|
|
720
720
|
|
|
721
|
+
describe "#add_facet_paging_to_solr" do
|
|
722
|
+
let(:facet_field) { 'format' }
|
|
723
|
+
let(:sort_key) { Blacklight::Solr::FacetPaginator.request_keys[:sort] }
|
|
724
|
+
let(:page_key) { Blacklight::Solr::FacetPaginator.request_keys[:page] }
|
|
725
|
+
let(:prefix_key) { Blacklight::Solr::FacetPaginator.request_keys[:prefix] }
|
|
726
|
+
|
|
727
|
+
let(:blacklight_config) do
|
|
728
|
+
Blacklight::Configuration.new do |config|
|
|
729
|
+
config.add_facet_fields_to_solr_request!
|
|
730
|
+
config.add_facet_field 'format'
|
|
731
|
+
config.add_facet_field 'format_ordered', sort: :count
|
|
732
|
+
config.add_facet_field 'format_limited', limit: 5
|
|
733
|
+
config.add_facet_field 'format_more_limited', limit: 5, more_limit: 50
|
|
734
|
+
end
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
let(:solr_parameters) do
|
|
738
|
+
solr_parameters = Blacklight::Solr::Request.new
|
|
739
|
+
subject.facet(facet_field).add_facet_paging_to_solr(solr_parameters)
|
|
740
|
+
solr_parameters
|
|
741
|
+
end
|
|
742
|
+
|
|
743
|
+
it 'sets rows to 0' do
|
|
744
|
+
expect(solr_parameters[:rows]).to eq 0
|
|
745
|
+
end
|
|
746
|
+
|
|
747
|
+
it 'sets facets requested to facet_field argument' do
|
|
748
|
+
expect(solr_parameters[:'facet.field']).to eq facet_field
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
it 'defaults offset to 0' do
|
|
752
|
+
expect(solr_parameters[:"f.#{facet_field}.facet.offset"]).to eq 0
|
|
753
|
+
end
|
|
754
|
+
|
|
755
|
+
context 'when offset is manually set' do
|
|
756
|
+
let(:user_params) { { page_key => 2 } }
|
|
757
|
+
|
|
758
|
+
it 'uses offset manually set, and converts it to an integer' do
|
|
759
|
+
expect(solr_parameters[:"f.#{facet_field}.facet.offset"]).to eq 20
|
|
760
|
+
end
|
|
761
|
+
end
|
|
762
|
+
|
|
763
|
+
context 'for a field with a configured more_limit' do
|
|
764
|
+
let(:facet_field) { 'format_more_limited' }
|
|
765
|
+
|
|
766
|
+
it 'uses the more_limit configuration' do
|
|
767
|
+
expect(solr_parameters[:"f.#{facet_field}.facet.limit"]).to eq 51
|
|
768
|
+
end
|
|
769
|
+
end
|
|
770
|
+
|
|
771
|
+
context 'for a field with a param key different from the field name' do
|
|
772
|
+
let(:user_params) { { page_key => 2, 'facet.sort': 'index', 'facet.prefix': 'x' } }
|
|
773
|
+
let(:facet_field) { 'param_key' }
|
|
774
|
+
|
|
775
|
+
let(:blacklight_config) do
|
|
776
|
+
Blacklight::Configuration.new.tap do |config|
|
|
777
|
+
config.add_facet_field key: 'param_key', field: 'solr_field', more_limit: 50, ex: 'other'
|
|
778
|
+
|
|
779
|
+
config.add_facet_fields_to_solr_request!
|
|
780
|
+
end
|
|
781
|
+
end
|
|
782
|
+
|
|
783
|
+
it "uses the configured solr field name in queries" do
|
|
784
|
+
expect(solr_parameters).to include 'f.solr_field.facet.limit': 51,
|
|
785
|
+
'f.solr_field.facet.offset': 50,
|
|
786
|
+
'f.solr_field.facet.sort': 'index',
|
|
787
|
+
'f.solr_field.facet.prefix': 'x',
|
|
788
|
+
'facet.field': '{!ex=other}solr_field'
|
|
789
|
+
end
|
|
790
|
+
end
|
|
791
|
+
|
|
792
|
+
it 'defaults limit to 20' do
|
|
793
|
+
expect(solr_parameters[:"f.#{facet_field}.facet.limit"]).to eq 21
|
|
794
|
+
end
|
|
795
|
+
|
|
796
|
+
it 'uses the default sort' do
|
|
797
|
+
expect(solr_parameters[:"f.#{facet_field}.facet.sort"]).to be_blank
|
|
798
|
+
end
|
|
799
|
+
|
|
800
|
+
context 'when sort is provided' do
|
|
801
|
+
let(:user_params) { { sort_key => 'index' } }
|
|
802
|
+
|
|
803
|
+
it 'uses sort provided in the parameters' do
|
|
804
|
+
expect(solr_parameters[:"f.#{facet_field}.facet.sort"]).to eq 'index'
|
|
805
|
+
end
|
|
806
|
+
end
|
|
807
|
+
|
|
808
|
+
context 'when a prefix is provided' do
|
|
809
|
+
let(:user_params) { { prefix_key => 'A' } }
|
|
810
|
+
|
|
811
|
+
it 'includes the prefix in the query' do
|
|
812
|
+
expect(solr_parameters[:"f.#{facet_field}.facet.prefix"]).to eq 'A'
|
|
813
|
+
end
|
|
814
|
+
end
|
|
815
|
+
end
|
|
816
|
+
|
|
817
|
+
describe "#add_facet_suggestion_parameters" do
|
|
818
|
+
it "does not add anything when the builder has no facet_suggestion_query and no facet" do
|
|
819
|
+
expect(subject.facet).to be_nil
|
|
820
|
+
expect(subject.facet_suggestion_query).to be_nil
|
|
821
|
+
solr_params = Blacklight::Solr::Request.new
|
|
822
|
+
|
|
823
|
+
expect do
|
|
824
|
+
subject.add_facet_suggestion_parameters(solr_params)
|
|
825
|
+
end.not_to(change { solr_params })
|
|
826
|
+
end
|
|
827
|
+
|
|
828
|
+
it "does not add anything when the builder has a facet_suggestion_query but no facet" do
|
|
829
|
+
subject.facet_suggestion_query = 'artic'
|
|
830
|
+
expect(subject.facet_suggestion_query).to eq 'artic'
|
|
831
|
+
expect(subject.facet).to be_nil
|
|
832
|
+
solr_params = Blacklight::Solr::Request.new
|
|
833
|
+
|
|
834
|
+
expect do
|
|
835
|
+
subject.add_facet_suggestion_parameters(solr_params)
|
|
836
|
+
end.not_to(change { solr_params })
|
|
837
|
+
end
|
|
838
|
+
|
|
839
|
+
it "does not add anything when the builder has a facet but no facet_suggestion_query" do
|
|
840
|
+
subject.facet = 'subject_facet'
|
|
841
|
+
expect(subject.facet_suggestion_query).to be_nil
|
|
842
|
+
expect(subject.facet).to eq 'subject_facet'
|
|
843
|
+
solr_params = Blacklight::Solr::Request.new
|
|
844
|
+
|
|
845
|
+
expect do
|
|
846
|
+
subject.add_facet_suggestion_parameters(solr_params)
|
|
847
|
+
end.not_to(change { solr_params })
|
|
848
|
+
end
|
|
849
|
+
|
|
850
|
+
it "adds the facet_suggestion_query to facet.contains" do
|
|
851
|
+
subject.facet = 'subject_facet'
|
|
852
|
+
subject.facet_suggestion_query = 'artic'
|
|
853
|
+
solr_params = Blacklight::Solr::Request.new
|
|
854
|
+
|
|
855
|
+
subject.add_facet_suggestion_parameters(solr_params)
|
|
856
|
+
|
|
857
|
+
expect(solr_params[:'facet.contains']).to eq 'artic'
|
|
858
|
+
end
|
|
859
|
+
|
|
860
|
+
it "adds the first part of facet_suggestion_query to facet.contains if it is extremely long" do
|
|
861
|
+
subject.facet = 'subject_facet'
|
|
862
|
+
subject.facet_suggestion_query = 'Call me Ishmael. Some years ago—never mind how long precisely'
|
|
863
|
+
solr_params = Blacklight::Solr::Request.new
|
|
864
|
+
|
|
865
|
+
subject.add_facet_suggestion_parameters(solr_params)
|
|
866
|
+
|
|
867
|
+
expect(solr_params[:'facet.contains']).to eq 'Call me Ishmael. Some years ago—never mind how long'
|
|
868
|
+
end
|
|
869
|
+
|
|
870
|
+
it "adds facet.contains.ignoreCase" do
|
|
871
|
+
subject.facet = 'subject_facet'
|
|
872
|
+
subject.facet_suggestion_query = 'artic'
|
|
873
|
+
solr_params = Blacklight::Solr::Request.new
|
|
874
|
+
|
|
875
|
+
subject.add_facet_suggestion_parameters(solr_params)
|
|
876
|
+
|
|
877
|
+
expect(solr_params[:'facet.contains.ignoreCase']).to be true
|
|
878
|
+
end
|
|
879
|
+
end
|
|
880
|
+
|
|
721
881
|
describe "#with_tag_ex" do
|
|
722
882
|
it "adds an !ex local parameter if the facet configuration requests it" do
|
|
723
883
|
expect(subject.with_ex_local_param("xyz", "some-value")).to eq "{!ex=xyz}some-value"
|