blacklight 7.24.0 → 7.25.0
Sign up to get free protection for your applications and to get access to all the features.
- 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": "[![Build Status](https://travis-ci.com/projectblacklight/blacklight.png?branch=main)](https://travis-ci.com/projectblacklight/blacklight) [![Gem Version](https://badge.fury.io/rb/blacklight.png)](http://badge.fury.io/rb/blacklight) [![Coverage Status](https://coveralls.io/repos/github/projectblacklight/blacklight/badge.svg?branch=main)](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
|
|