blacklight 7.24.0 → 7.25.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/workflows/ruby.yml +4 -4
- data/VERSION +1 -1
- data/app/assets/javascripts/blacklight/blacklight.js +2 -2
- data/app/components/blacklight/constraint_component.rb +1 -1
- data/app/components/blacklight/constraint_layout_component.rb +1 -1
- data/app/components/blacklight/constraints_component.rb +1 -1
- data/app/components/blacklight/document/action_component.rb +1 -1
- data/app/components/blacklight/document/actions_component.rb +1 -1
- data/app/components/blacklight/document/bookmark_component.rb +1 -1
- data/app/components/blacklight/document/citation_component.rb +2 -2
- data/app/components/blacklight/document/group_component.rb +3 -2
- data/app/components/blacklight/document/more_like_this_component.rb +1 -1
- data/app/components/blacklight/document/thumbnail_component.rb +1 -1
- data/app/components/blacklight/document_component.rb +1 -2
- data/app/components/blacklight/document_metadata_component.rb +1 -1
- data/app/components/blacklight/document_title_component.rb +1 -1
- data/app/components/blacklight/facet_field_checkboxes_component.rb +1 -1
- data/app/components/blacklight/facet_field_component.rb +1 -1
- data/app/components/blacklight/facet_field_filter_component.rb +1 -1
- data/app/components/blacklight/facet_field_inclusive_constraint_component.rb +1 -1
- data/app/components/blacklight/facet_field_list_component.rb +1 -1
- data/app/components/blacklight/facet_field_no_layout_component.rb +1 -1
- data/app/components/blacklight/facet_field_pagination_component.rb +1 -1
- data/app/components/blacklight/facet_item_component.rb +1 -1
- data/app/components/blacklight/facet_item_pivot_component.rb +1 -1
- data/app/components/blacklight/hidden_search_state_component.rb +2 -2
- data/app/components/blacklight/metadata_field_component.rb +1 -1
- data/app/components/blacklight/metadata_field_layout_component.rb +1 -1
- data/app/components/blacklight/response/facet_group_component.rb +1 -1
- data/app/components/blacklight/response/pagination_component.rb +1 -1
- data/app/components/blacklight/search_bar_component.html.erb +7 -7
- data/app/components/blacklight/search_bar_component.rb +18 -13
- data/app/components/blacklight/search_context_component.rb +1 -1
- data/app/components/blacklight/start_over_button_component.rb +1 -1
- data/app/helpers/blacklight/blacklight_helper_behavior.rb +3 -1
- data/app/helpers/blacklight/catalog_helper_behavior.rb +1 -1
- data/app/helpers/blacklight/render_constraints_helper_behavior.rb +5 -7
- data/app/javascript/blacklight/modal.js +2 -2
- data/app/presenters/blacklight/search_bar_presenter.rb +2 -0
- data/app/services/blacklight/field_retriever.rb +1 -1
- data/app/views/catalog/_constraints.html.erb +2 -2
- data/app/views/catalog/_facet_group.html.erb +1 -1
- data/app/views/catalog/_search_form.html.erb +2 -2
- data/app/views/shared/_header_navbar.html.erb +5 -1
- data/lib/blacklight/component.rb +40 -0
- data/lib/blacklight/configuration/facet_field.rb +1 -1
- data/lib/blacklight/configuration/fields.rb +10 -11
- data/lib/blacklight/configuration/view_config.rb +6 -0
- data/lib/blacklight/configuration.rb +320 -179
- data/lib/blacklight/deprecations/search_state_normalization.rb +52 -0
- data/lib/blacklight/search_state/filter_field.rb +44 -16
- data/lib/blacklight/search_state.rb +55 -31
- data/lib/blacklight/solr/search_builder_behavior.rb +3 -1
- data/lib/blacklight.rb +1 -0
- data/package.json +1 -1
- data/spec/components/blacklight/constraints_component_spec.rb +14 -1
- data/spec/components/blacklight/facet_field_list_component_spec.rb +6 -1
- data/spec/components/blacklight/facet_item_pivot_component_spec.rb +7 -1
- data/spec/controllers/blacklight/base_spec.rb +4 -1
- data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +23 -6
- data/spec/helpers/blacklight/url_helper_behavior_spec.rb +7 -0
- data/spec/lib/blacklight/component_spec.rb +43 -0
- data/spec/lib/blacklight/search_state/filter_field_spec.rb +12 -1
- data/spec/lib/blacklight/search_state_spec.rb +17 -3
- data/spec/models/blacklight/configuration_spec.rb +2 -2
- data/spec/models/blacklight/solr/search_builder_spec.rb +15 -0
- data/spec/presenters/blacklight/facet_field_presenter_spec.rb +10 -4
- data/spec/presenters/blacklight/facet_grouped_item_presenter_spec.rb +6 -1
- data/spec/presenters/blacklight/field_presenter_spec.rb +2 -0
- data/spec/views/catalog/index.json.jbuilder_spec.rb +1 -0
- metadata +7 -3
@@ -6,12 +6,22 @@ module Blacklight
|
|
6
6
|
class FilterField
|
7
7
|
MISSING = { missing: true }.freeze
|
8
8
|
|
9
|
-
#
|
9
|
+
# @!attribute config
|
10
|
+
# @return [Blacklight::Configuration::FacetField]
|
10
11
|
attr_reader :config
|
11
12
|
|
12
|
-
#
|
13
|
+
# @!attribute search_state
|
14
|
+
# @return [Blacklight::SearchState]
|
13
15
|
attr_reader :search_state
|
14
16
|
|
17
|
+
# @!attribute param
|
18
|
+
# @return [String,Symbol]
|
19
|
+
attr_reader :filters_key
|
20
|
+
|
21
|
+
# @!attribute inclusive_param
|
22
|
+
# @return [String,Symbol]
|
23
|
+
attr_reader :inclusive_filters_key
|
24
|
+
|
15
25
|
# @return [String,Symbol]
|
16
26
|
delegate :key, to: :config
|
17
27
|
|
@@ -20,9 +30,11 @@ module Blacklight
|
|
20
30
|
def initialize(config, search_state)
|
21
31
|
@config = config
|
22
32
|
@search_state = search_state
|
33
|
+
@filters_key = :f
|
34
|
+
@inclusive_filters_key = :f_inclusive
|
23
35
|
end
|
24
36
|
|
25
|
-
# @param [String,#value] a filter item to add to the url
|
37
|
+
# @param [String,#value] item a filter item to add to the url
|
26
38
|
# @return [Blacklight::SearchState] new state
|
27
39
|
def add(item)
|
28
40
|
new_state = search_state.reset_search
|
@@ -41,7 +53,7 @@ module Blacklight
|
|
41
53
|
|
42
54
|
url_key = key
|
43
55
|
params = new_state.params
|
44
|
-
param =
|
56
|
+
param = filters_key
|
45
57
|
value = as_url_parameter(item)
|
46
58
|
|
47
59
|
if value == Blacklight::SearchState::FilterField::MISSING
|
@@ -49,7 +61,7 @@ module Blacklight
|
|
49
61
|
value = Blacklight::Engine.config.blacklight.facet_missing_param
|
50
62
|
end
|
51
63
|
|
52
|
-
param =
|
64
|
+
param = inclusive_filters_key if value.is_a?(Array)
|
53
65
|
|
54
66
|
# value could be a string
|
55
67
|
params[param] = (params[param] || {}).dup
|
@@ -66,7 +78,7 @@ module Blacklight
|
|
66
78
|
new_state.reset(params)
|
67
79
|
end
|
68
80
|
|
69
|
-
# @param [String,#value] a filter to remove from the url
|
81
|
+
# @param [String,#value] item a filter to remove from the url
|
70
82
|
# @return [Blacklight::SearchState] new state
|
71
83
|
def remove(item)
|
72
84
|
new_state = search_state.reset_search
|
@@ -77,7 +89,7 @@ module Blacklight
|
|
77
89
|
url_key = config.key
|
78
90
|
params = new_state.params
|
79
91
|
|
80
|
-
param =
|
92
|
+
param = filters_key
|
81
93
|
value = as_url_parameter(item)
|
82
94
|
|
83
95
|
if value == Blacklight::SearchState::FilterField::MISSING
|
@@ -85,7 +97,7 @@ module Blacklight
|
|
85
97
|
value = Blacklight::Engine.config.blacklight.facet_missing_param
|
86
98
|
end
|
87
99
|
|
88
|
-
param =
|
100
|
+
param = inclusive_filters_key if value.is_a?(Array)
|
89
101
|
|
90
102
|
# need to dup the facet values too,
|
91
103
|
# if the values aren't dup'd, then the values
|
@@ -110,17 +122,25 @@ module Blacklight
|
|
110
122
|
end
|
111
123
|
|
112
124
|
# @return [Array] an array of applied filters
|
113
|
-
def values
|
125
|
+
def values(except: [])
|
114
126
|
params = search_state.params
|
115
|
-
|
116
|
-
|
117
|
-
|
127
|
+
return [] if params.blank?
|
128
|
+
|
129
|
+
f = except.include?(:filters) ? [] : [params.dig(filters_key, key)].flatten.compact
|
130
|
+
f_inclusive = [params.dig(:f_inclusive, key)] unless params.dig(inclusive_filters_key, key).blank? || except.include?(:inclusive_filters)
|
131
|
+
f_missing = [Blacklight::SearchState::FilterField::MISSING] if params.dig(filters_key, "-#{key}")&.any? { |v| v == Blacklight::Engine.config.blacklight.facet_missing_param }
|
132
|
+
f_missing = [] if except.include?(:missing)
|
118
133
|
|
119
134
|
f + (f_inclusive || []) + (f_missing || [])
|
120
135
|
end
|
121
136
|
delegate :any?, to: :values
|
122
137
|
|
123
|
-
#
|
138
|
+
# Appease rubocop rules by implementing #each_value
|
139
|
+
def each_value(except: [], &block)
|
140
|
+
values(except: except).each(&block)
|
141
|
+
end
|
142
|
+
|
143
|
+
# @param [String,#value] item a filter to remove from the url
|
124
144
|
# @return [Boolean] whether the provided filter is currently applied/selected
|
125
145
|
def include?(item)
|
126
146
|
if item.respond_to?(:field) && item.field != key
|
@@ -131,14 +151,22 @@ module Blacklight
|
|
131
151
|
params = search_state.params
|
132
152
|
|
133
153
|
if value.is_a?(Array)
|
134
|
-
(params.dig(
|
154
|
+
(params.dig(inclusive_filters_key, key) || []).to_set == value.to_set
|
135
155
|
elsif value == Blacklight::SearchState::FilterField::MISSING
|
136
|
-
(params.dig(
|
156
|
+
(params.dig(filters_key, "-#{key}") || []).include?(Blacklight::Engine.config.blacklight.facet_missing_param)
|
137
157
|
else
|
138
|
-
(params.dig(
|
158
|
+
(params.dig(filters_key, key) || []).include?(value)
|
139
159
|
end
|
140
160
|
end
|
141
161
|
|
162
|
+
def needs_normalization?(value_params)
|
163
|
+
value_params&.is_a?(Hash) && value_params != Blacklight::SearchState::FilterField::MISSING
|
164
|
+
end
|
165
|
+
|
166
|
+
def normalize(value_params)
|
167
|
+
needs_normalization?(value_params) ? value_params.values : value_params
|
168
|
+
end
|
169
|
+
|
142
170
|
private
|
143
171
|
|
144
172
|
# TODO: this code is duplicated in Blacklight::FacetsHelperBehavior
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'blacklight/deprecations/search_state_normalization'
|
3
4
|
require 'blacklight/search_state/filter_field'
|
4
5
|
|
5
6
|
module Blacklight
|
@@ -7,6 +8,7 @@ module Blacklight
|
|
7
8
|
# parameters namely: :f, :q, :page, :per_page and, :sort
|
8
9
|
class SearchState
|
9
10
|
extend Deprecation
|
11
|
+
include Blacklight::Deprecations::SearchStateNormalization
|
10
12
|
|
11
13
|
attr_reader :blacklight_config # Must be called blacklight_config, because Blacklight::Facet calls blacklight_config.
|
12
14
|
attr_reader :params
|
@@ -17,18 +19,7 @@ module Blacklight
|
|
17
19
|
|
18
20
|
delegate :facet_configuration_for_field, to: :blacklight_config
|
19
21
|
|
20
|
-
|
21
|
-
# @param [Blacklight::Config] blacklight_config
|
22
|
-
# @param [ApplicationController] controller used for the routing helpers
|
23
|
-
def initialize(params, blacklight_config, controller = nil)
|
24
|
-
@params = self.class.normalize_params(params)
|
25
|
-
@blacklight_config = blacklight_config
|
26
|
-
@controller = controller
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.normalize_params(untrusted_params = {})
|
30
|
-
params = untrusted_params
|
31
|
-
|
22
|
+
def self.modifiable_params(params)
|
32
23
|
if params.respond_to?(:to_unsafe_h)
|
33
24
|
# This is the typical (not-ActionView::TestCase) code path.
|
34
25
|
params = params.to_unsafe_h
|
@@ -40,12 +31,55 @@ module Blacklight
|
|
40
31
|
else
|
41
32
|
params = params.dup.to_h.with_indifferent_access
|
42
33
|
end
|
34
|
+
params
|
35
|
+
end
|
43
36
|
|
44
|
-
|
45
|
-
|
46
|
-
|
37
|
+
# @param [ActionController::Parameters] params
|
38
|
+
# @param [Blacklight::Config] blacklight_config
|
39
|
+
# @param [ApplicationController] controller used for the routing helpers
|
40
|
+
def initialize(params, blacklight_config, controller = nil)
|
41
|
+
@blacklight_config = blacklight_config
|
42
|
+
@controller = controller
|
43
|
+
@params = SearchState.modifiable_params(params)
|
44
|
+
normalize_params! if needs_normalization?
|
45
|
+
end
|
47
46
|
|
48
|
-
|
47
|
+
def needs_normalization?
|
48
|
+
return false if params.blank?
|
49
|
+
return true if (params.keys.map(&:to_s) - permitted_fields.map(&:to_s)).present?
|
50
|
+
|
51
|
+
!!filters.detect { |filter| filter.values.detect { |value| filter.needs_normalization?(value) } }
|
52
|
+
end
|
53
|
+
|
54
|
+
def normalize_params!
|
55
|
+
@params = normalize_params
|
56
|
+
end
|
57
|
+
|
58
|
+
def normalize_params
|
59
|
+
return params unless needs_normalization?
|
60
|
+
|
61
|
+
base_params = params.slice(*blacklight_config.search_state_fields)
|
62
|
+
normal_state = blacklight_config.facet_fields.each_value.inject(reset(base_params)) do |working_state, filter_key|
|
63
|
+
f = filter(filter_key)
|
64
|
+
next working_state unless f.any?
|
65
|
+
|
66
|
+
filter_values = f.values(except: [:inclusive_filters]).inject([]) do |memo, filter_value|
|
67
|
+
# flatten arrays that had been mangled into integer-indexed hashes
|
68
|
+
memo.concat([f.normalize(filter_value)].flatten)
|
69
|
+
end
|
70
|
+
filter_values = f.values(except: [:filters, :missing]).inject(filter_values) do |memo, filter_value|
|
71
|
+
memo << f.normalize(filter_value)
|
72
|
+
end
|
73
|
+
filter_values.inject(working_state) do |memo, filter_value|
|
74
|
+
memo.filter(filter_key).add(filter_value)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
normal_state.params
|
78
|
+
end
|
79
|
+
|
80
|
+
def permitted_fields
|
81
|
+
filter_keys = filter_fields.inject(Set.new) { |memo, filter| memo.merge [filter.filters_key, filter.inclusive_filters_key] }
|
82
|
+
blacklight_config.search_state_fields + filter_keys.subtract([nil, '']).to_a
|
49
83
|
end
|
50
84
|
|
51
85
|
def to_hash
|
@@ -129,11 +163,7 @@ module Blacklight
|
|
129
163
|
end
|
130
164
|
|
131
165
|
def filters
|
132
|
-
@filters ||=
|
133
|
-
f = filter(value)
|
134
|
-
|
135
|
-
f if f.any?
|
136
|
-
end.compact
|
166
|
+
@filters ||= filter_fields.select(&:any?)
|
137
167
|
end
|
138
168
|
|
139
169
|
def filter(field_key_or_field)
|
@@ -248,16 +278,6 @@ module Blacklight
|
|
248
278
|
params[facet_request_keys[:prefix]]
|
249
279
|
end
|
250
280
|
|
251
|
-
def self.facet_params_need_normalization(facet_params)
|
252
|
-
facet_params.is_a?(Hash) && facet_params.values.any? { |x| x.is_a?(Hash) }
|
253
|
-
end
|
254
|
-
|
255
|
-
def self.normalize_facet_params(facet_params)
|
256
|
-
facet_params.transform_values do |value|
|
257
|
-
value.is_a?(Hash) ? value.values : value
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
281
|
private
|
262
282
|
|
263
283
|
def search_field_key
|
@@ -279,5 +299,9 @@ module Blacklight
|
|
279
299
|
def reset_search_params
|
280
300
|
Parameters.sanitize(params).except(:page, :counter)
|
281
301
|
end
|
302
|
+
|
303
|
+
def filter_fields
|
304
|
+
blacklight_config.facet_fields.each_value.map { |value| filter(value) }
|
305
|
+
end
|
282
306
|
end
|
283
307
|
end
|
@@ -146,7 +146,9 @@ module Blacklight::Solr
|
|
146
146
|
if filter.config.filter_query_builder
|
147
147
|
filter_query, subqueries = filter.config.filter_query_builder.call(self, filter, solr_parameters)
|
148
148
|
|
149
|
-
|
149
|
+
Array(filter_query).each do |fq|
|
150
|
+
solr_parameters.append_filter_query(fq)
|
151
|
+
end
|
150
152
|
solr_parameters.merge!(subqueries) if subqueries
|
151
153
|
else
|
152
154
|
filter.values.reject(&:blank?).each do |value|
|
data/lib/blacklight.rb
CHANGED
@@ -7,6 +7,7 @@ require 'jbuilder'
|
|
7
7
|
|
8
8
|
module Blacklight
|
9
9
|
autoload :AbstractRepository, 'blacklight/abstract_repository'
|
10
|
+
autoload :Component, 'blacklight/component'
|
10
11
|
autoload :Configuration, 'blacklight/configuration'
|
11
12
|
autoload :Exceptions, 'blacklight/exceptions'
|
12
13
|
autoload :Parameters, 'blacklight/parameters'
|
data/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "blacklight-frontend",
|
3
|
-
"version": "7.
|
3
|
+
"version": "7.25.0",
|
4
4
|
"description": "[](https://travis-ci.com/projectblacklight/blacklight) [](http://badge.fury.io/rb/blacklight) [](https://coveralls.io/github/projectblacklight/blacklight?branch=main)",
|
5
5
|
"main": "app/assets/javascripts/blacklight",
|
6
6
|
"scripts": {
|
@@ -12,7 +12,7 @@ RSpec.describe Blacklight::ConstraintsComponent, type: :component do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
let(:blacklight_config) do
|
15
|
-
Blacklight::Configuration.new.
|
15
|
+
Blacklight::Configuration.new.configure do |config|
|
16
16
|
config.add_facet_field 'some_facet'
|
17
17
|
end
|
18
18
|
end
|
@@ -43,6 +43,19 @@ RSpec.describe Blacklight::ConstraintsComponent, type: :component do
|
|
43
43
|
context 'with a facet' do
|
44
44
|
let(:query_params) { { f: { some_facet: ['some value'] } } }
|
45
45
|
|
46
|
+
before do
|
47
|
+
controller.blacklight_config.configure do |config|
|
48
|
+
config.add_facet_field :some_facet
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# this has to be cleaned up to prevent leaking class configuration
|
53
|
+
after do
|
54
|
+
controller.blacklight_config.configure do |config|
|
55
|
+
config['facet_fields'].delete('some_facet')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
46
59
|
it 'renders the query' do
|
47
60
|
expect(rendered).to have_selector('.constraint-value > .filter-name', text: 'Some Facet').and(have_selector('.constraint-value > .filter-value', text: 'some value'))
|
48
61
|
end
|
@@ -123,7 +123,12 @@ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
|
|
123
123
|
)
|
124
124
|
end
|
125
125
|
|
126
|
-
let(:
|
126
|
+
let(:blacklight_config) do
|
127
|
+
Blacklight::Configuration.new.configure do |config|
|
128
|
+
config.add_facet_field :field
|
129
|
+
end
|
130
|
+
end
|
131
|
+
let(:search_state) { Blacklight::SearchState.new(params.with_indifferent_access, blacklight_config) }
|
127
132
|
let(:params) { { f_inclusive: { field: %w[a b c] } } }
|
128
133
|
|
129
134
|
it 'displays the constraint above the list' do
|
@@ -7,8 +7,14 @@ RSpec.describe Blacklight::FacetItemPivotComponent, type: :component do
|
|
7
7
|
render_inline_to_capybara_node(described_class.new(facet_item: facet_item))
|
8
8
|
end
|
9
9
|
|
10
|
+
let(:blacklight_config) do
|
11
|
+
Blacklight::Configuration.new.configure do |config|
|
12
|
+
config.add_facet_field :z
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
10
16
|
let(:search_state) do
|
11
|
-
Blacklight::SearchState.new({},
|
17
|
+
Blacklight::SearchState.new({}, blacklight_config)
|
12
18
|
end
|
13
19
|
|
14
20
|
let(:facet_item) do
|
@@ -11,7 +11,10 @@ RSpec.describe Blacklight::Base do
|
|
11
11
|
let(:raw_params) { HashWithIndifferentAccess.new a: 1 }
|
12
12
|
let(:params) { ActionController::Parameters.new raw_params }
|
13
13
|
|
14
|
-
before
|
14
|
+
before do
|
15
|
+
controller.blacklight_config.search_state_fields << :a
|
16
|
+
allow(controller).to receive_messages(params: params)
|
17
|
+
end
|
15
18
|
|
16
19
|
it "creates a path object" do
|
17
20
|
expect(subject).to be_kind_of Blacklight::SearchState
|
@@ -246,6 +246,10 @@ RSpec.describe Blacklight::FacetsHelperBehavior do
|
|
246
246
|
end
|
247
247
|
|
248
248
|
describe "facet_field_in_params?" do
|
249
|
+
before do
|
250
|
+
blacklight_config.add_facet_field "some-field"
|
251
|
+
end
|
252
|
+
|
249
253
|
it "checks if the facet field is selected in the user params" do
|
250
254
|
allow(helper).to receive_messages(params: { f: { "some-field" => ["x"] } })
|
251
255
|
expect(helper).to be_facet_field_in_params("some-field")
|
@@ -254,16 +258,29 @@ RSpec.describe Blacklight::FacetsHelperBehavior do
|
|
254
258
|
end
|
255
259
|
|
256
260
|
describe "facet_params" do
|
261
|
+
let(:facet_config) { ["some-field"] }
|
262
|
+
let(:params) { { f: { "some-field" => ["x"] } } }
|
263
|
+
|
264
|
+
before do
|
265
|
+
blacklight_config.add_facet_field *facet_config
|
266
|
+
allow(helper).to receive_messages(params: params)
|
267
|
+
end
|
268
|
+
|
257
269
|
it "extracts the facet parameters for a field" do
|
258
|
-
allow(helper).to receive_messages(params: { f: { "some-field" => ["x"] } })
|
259
270
|
expect(helper.facet_params("some-field")).to match_array ["x"]
|
260
271
|
end
|
261
272
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
273
|
+
context "a facet is not keyed by the field name" do
|
274
|
+
let(:facet_config) { ["some-key", { field: "some-field" }] }
|
275
|
+
let(:params) { { f: { "some-key" => ["x"] } } }
|
276
|
+
|
277
|
+
it "uses the blacklight key to extract the right fields" do
|
278
|
+
expect(helper.facet_params("some-key")).to match_array ["x"]
|
279
|
+
end
|
280
|
+
|
281
|
+
it "looks up facet params by configured field or key values" do
|
282
|
+
expect(helper.facet_params("some-field")).to match_array ["x"]
|
283
|
+
end
|
267
284
|
end
|
268
285
|
end
|
269
286
|
|
@@ -75,6 +75,13 @@ RSpec.describe Blacklight::UrlHelperBehavior do
|
|
75
75
|
let(:query_params) { { q: "query", f: "facets", controller: 'catalog' } }
|
76
76
|
let(:bookmarks_query_params) { { controller: 'bookmarks' } }
|
77
77
|
|
78
|
+
before do
|
79
|
+
# this is bad data but the legacy test exercises search fields, not filters
|
80
|
+
blacklight_config.configure do |config|
|
81
|
+
config.search_state_fields << :f
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
78
85
|
it "builds a link tag to catalog using session[:search] for query params" do
|
79
86
|
allow(helper).to receive(:current_search_session).and_return double(query_params: query_params)
|
80
87
|
tag = helper.link_back_to_catalog
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Blacklight::Component do
|
4
|
+
let(:component_class) { Blacklight::DocumentTitleComponent }
|
5
|
+
|
6
|
+
context "subclassed" do
|
7
|
+
it "returns our Compiler implementation" do
|
8
|
+
expect(component_class.ancestors).to include described_class
|
9
|
+
expect(component_class.compiler).to be_a Blacklight::Component::EngineCompiler
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Blacklight::Component::EngineCompiler do
|
14
|
+
subject(:compiler) { described_class.new(component_class) }
|
15
|
+
|
16
|
+
let(:original_compiler) { ViewComponent::Compiler.new(component_class) }
|
17
|
+
let(:original_path) { original_compiler.send(:templates).first[:path] }
|
18
|
+
let(:resolved_path) { compiler.templates.first[:path] }
|
19
|
+
|
20
|
+
context "without overrides" do
|
21
|
+
it "links to engine template" do
|
22
|
+
expect(resolved_path).not_to include(".internal_test_app")
|
23
|
+
expect(resolved_path).to eql(original_path)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "with overrides" do
|
28
|
+
let(:path_match) do
|
29
|
+
Regexp.new(Regexp.escape(File.join(".internal_test_app", component_class.view_component_path)))
|
30
|
+
end
|
31
|
+
|
32
|
+
before do
|
33
|
+
allow(File).to receive(:exist?).and_call_original
|
34
|
+
allow(File).to receive(:exist?).with(path_match).and_return(true)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "links to application template" do
|
38
|
+
expect(resolved_path).to include(".internal_test_app")
|
39
|
+
expect(resolved_path).not_to eql(original_path)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -6,10 +6,13 @@ RSpec.describe Blacklight::SearchState::FilterField do
|
|
6
6
|
let(:params) { { f: { some_field: %w[1 2], another_field: ['3'] } } }
|
7
7
|
let(:blacklight_config) do
|
8
8
|
Blacklight::Configuration.new.configure do |config|
|
9
|
-
config.add_facet_field 'some_field'
|
10
9
|
config.add_facet_field 'another_field', single: true
|
10
|
+
simple_facet_fields.each { |simple_facet_field| config.add_facet_field simple_facet_field }
|
11
|
+
config.search_state_fields = config.search_state_fields + additional_search_fields
|
11
12
|
end
|
12
13
|
end
|
14
|
+
let(:simple_facet_fields) { [:some_field] }
|
15
|
+
let(:additional_search_fields) { [] }
|
13
16
|
let(:controller) { double }
|
14
17
|
|
15
18
|
describe '#add' do
|
@@ -50,6 +53,8 @@ RSpec.describe Blacklight::SearchState::FilterField do
|
|
50
53
|
end
|
51
54
|
|
52
55
|
context 'with a pivot facet-type item' do
|
56
|
+
let(:simple_facet_fields) { [:some_field, :some_other_field] }
|
57
|
+
|
53
58
|
it 'includes the pivot facet fqs' do
|
54
59
|
filter = search_state.filter('some_field')
|
55
60
|
new_state = filter.add(OpenStruct.new(fq: { some_other_field: '5' }, value: '4'))
|
@@ -200,4 +205,10 @@ RSpec.describe Blacklight::SearchState::FilterField do
|
|
200
205
|
expect(search_state.filter('some_field').include?(OpenStruct.new(value: '1'))).to eq true
|
201
206
|
end
|
202
207
|
end
|
208
|
+
|
209
|
+
describe '#needs_normalization?' do
|
210
|
+
it 'returns false for Blacklight::SearchState::FilterField::MISSING' do
|
211
|
+
expect(search_state.filter('some_field').needs_normalization?(Blacklight::SearchState::FilterField::MISSING)).to be false
|
212
|
+
end
|
213
|
+
end
|
203
214
|
end
|
@@ -9,14 +9,19 @@ RSpec.describe Blacklight::SearchState do
|
|
9
9
|
Blacklight::Configuration.new.configure do |config|
|
10
10
|
config.index.title_field = 'title_tsim'
|
11
11
|
config.index.display_type_field = 'format'
|
12
|
+
simple_facet_fields.each { |simple_facet_field| config.add_facet_field simple_facet_field }
|
13
|
+
config.search_state_fields = config.search_state_fields + additional_search_fields
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
15
17
|
let(:parameter_class) { ActionController::Parameters }
|
16
18
|
let(:controller) { double }
|
17
19
|
let(:params) { parameter_class.new }
|
20
|
+
let(:simple_facet_fields) { [:facet_field_1, :facet_field_2] }
|
21
|
+
let(:additional_search_fields) { [] }
|
18
22
|
|
19
23
|
describe '#to_h' do
|
24
|
+
let(:additional_search_fields) { [:a] }
|
20
25
|
let(:data) { { a: '1' } }
|
21
26
|
let(:params) { parameter_class.new data }
|
22
27
|
|
@@ -50,6 +55,7 @@ RSpec.describe Blacklight::SearchState do
|
|
50
55
|
end
|
51
56
|
|
52
57
|
context 'with facebooks badly mangled query parameters' do
|
58
|
+
let(:simple_facet_fields) { [:field] }
|
53
59
|
let(:params) do
|
54
60
|
{ f: { field: { '0': 'first', '1': 'second' } },
|
55
61
|
f_inclusive: { field: { '0': 'first', '1': 'second' } } }
|
@@ -62,6 +68,7 @@ RSpec.describe Blacklight::SearchState do
|
|
62
68
|
end
|
63
69
|
|
64
70
|
context 'deleting item from to_h' do
|
71
|
+
let(:additional_search_fields) { [:q_1] }
|
65
72
|
let(:params) { { q: 'foo', q_1: 'bar' } }
|
66
73
|
|
67
74
|
it 'does not mutate search_state to mutate search_state.to_h' do
|
@@ -74,6 +81,7 @@ RSpec.describe Blacklight::SearchState do
|
|
74
81
|
end
|
75
82
|
|
76
83
|
context 'deleting deep item from to_h' do
|
84
|
+
let(:additional_search_fields) { [:foo] }
|
77
85
|
let(:params) { { foo: { bar: [] } } }
|
78
86
|
|
79
87
|
it 'does not mutate search_state to deep mutate search_state.to_h' do
|
@@ -87,6 +95,7 @@ RSpec.describe Blacklight::SearchState do
|
|
87
95
|
end
|
88
96
|
|
89
97
|
describe 'interface compatibility with params' do
|
98
|
+
let(:simple_facet_fields) { [:ff] }
|
90
99
|
let(:params) { parameter_class.new f: { ff: ['xyz'] } }
|
91
100
|
|
92
101
|
it 'implements param methods' do
|
@@ -107,6 +116,7 @@ RSpec.describe Blacklight::SearchState do
|
|
107
116
|
end
|
108
117
|
|
109
118
|
describe '#filter_params' do
|
119
|
+
let(:simple_facet_fields) { [:ff] }
|
110
120
|
let(:params) { parameter_class.new f: { ff: ['xyz'] } }
|
111
121
|
|
112
122
|
it 'returns the query param' do
|
@@ -128,6 +138,7 @@ RSpec.describe Blacklight::SearchState do
|
|
128
138
|
end
|
129
139
|
|
130
140
|
context 'with a facet param' do
|
141
|
+
let(:simple_facet_fields) { [:ff] }
|
131
142
|
let(:params) { parameter_class.new f: { ff: ['xyz'] } }
|
132
143
|
|
133
144
|
it 'is true' do
|
@@ -137,6 +148,7 @@ RSpec.describe Blacklight::SearchState do
|
|
137
148
|
end
|
138
149
|
|
139
150
|
describe "params_for_search" do
|
151
|
+
let(:additional_search_fields) { [:default] }
|
140
152
|
let(:params) { parameter_class.new 'default' => 'params' }
|
141
153
|
|
142
154
|
it "takes original params" do
|
@@ -198,6 +210,7 @@ RSpec.describe Blacklight::SearchState do
|
|
198
210
|
end
|
199
211
|
|
200
212
|
context "with a block" do
|
213
|
+
let(:additional_search_fields) { [:a, :b, :c, :d] }
|
201
214
|
let(:params) { parameter_class.new a: 1, b: 2 }
|
202
215
|
|
203
216
|
it "evalutes the block and allow it to add or remove keys" do
|
@@ -356,6 +369,7 @@ RSpec.describe Blacklight::SearchState do
|
|
356
369
|
end
|
357
370
|
|
358
371
|
describe "#remove_facet_params" do
|
372
|
+
let(:simple_facet_fields) { [:some_field, :another_field] }
|
359
373
|
let(:params) { parameter_class.new 'f' => facet_params }
|
360
374
|
let(:facet_params) { {} }
|
361
375
|
|
@@ -382,9 +396,7 @@ RSpec.describe Blacklight::SearchState do
|
|
382
396
|
|
383
397
|
context "when the facet has configuration" do
|
384
398
|
before do
|
385
|
-
|
386
|
-
double(single: true, field: "a_solr_field", key: "some_key")
|
387
|
-
)
|
399
|
+
blacklight_config.facet_fields['some_field'].merge!(single: true, field: "a_solr_field", key: 'some_key')
|
388
400
|
end
|
389
401
|
|
390
402
|
let(:facet_params) { { 'some_key' => %w[some_value another_value] } }
|
@@ -415,6 +427,8 @@ RSpec.describe Blacklight::SearchState do
|
|
415
427
|
end
|
416
428
|
|
417
429
|
describe '#reset' do
|
430
|
+
let(:additional_search_fields) { [:a] }
|
431
|
+
|
418
432
|
it 'returns a search state with the given parameters' do
|
419
433
|
new_state = search_state.reset('a' => 1)
|
420
434
|
|
@@ -552,7 +552,7 @@ RSpec.describe "Blacklight::Configuration", api: true do
|
|
552
552
|
end
|
553
553
|
|
554
554
|
it "takes ShowField argument" do
|
555
|
-
config.add_sms_field("title_tsim", Blacklight::Configuration::
|
555
|
+
config.add_sms_field("title_tsim", Blacklight::Configuration::DisplayField.new(field: "title_display", label: "Title"))
|
556
556
|
|
557
557
|
expect(config.sms_fields["title_tsim"]).not_to be_nil
|
558
558
|
expect(config.sms_fields["title_tsim"].label).to eq "Title"
|
@@ -598,7 +598,7 @@ RSpec.describe "Blacklight::Configuration", api: true do
|
|
598
598
|
end
|
599
599
|
|
600
600
|
it "takes ShowField argument" do
|
601
|
-
config.add_email_field("title_tsim", Blacklight::Configuration::
|
601
|
+
config.add_email_field("title_tsim", Blacklight::Configuration::DisplayField.new(field: "title_display", label: "Title"))
|
602
602
|
|
603
603
|
expect(config.email_fields["title_tsim"]).not_to be_nil
|
604
604
|
expect(config.email_fields["title_tsim"].label).to eq "Title"
|
@@ -273,6 +273,21 @@ RSpec.describe Blacklight::Solr::SearchBuilderBehavior, api: true do
|
|
273
273
|
end
|
274
274
|
end
|
275
275
|
|
276
|
+
context 'with a facet with a custom filter query builder that returns multiple values' do
|
277
|
+
let(:user_params) { { f: { some: ['value'] } }.with_indifferent_access }
|
278
|
+
|
279
|
+
before do
|
280
|
+
blacklight_config.add_facet_field 'some', filter_query_builder: (lambda do |*_args|
|
281
|
+
[['some:filter', 'another:filter'], { qq1: 'abc' }]
|
282
|
+
end)
|
283
|
+
end
|
284
|
+
|
285
|
+
it "has proper solr parameters" do
|
286
|
+
expect(subject[:fq]).to include('some:filter', 'another:filter')
|
287
|
+
expect(subject[:qq1]).to include('abc')
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
276
291
|
describe 'with a json facet' do
|
277
292
|
let(:user_params) { { f: { json_facet: ['value'] } }.with_indifferent_access }
|
278
293
|
|