blacklight_range_limit 8.1.0 → 8.2.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 +14 -46
- data/README.md +4 -4
- data/VERSION +1 -1
- data/app/assets/javascripts/blacklight_range_limit/range_limit_distro_facets.js +1 -1
- data/app/assets/javascripts/blacklight_range_limit/range_limit_plotting.js +27 -15
- data/app/assets/javascripts/blacklight_range_limit/range_limit_slider.js +29 -9
- data/app/components/blacklight_range_limit/range_facet_component.html.erb +48 -0
- data/app/components/blacklight_range_limit/range_facet_component.rb +29 -0
- data/app/components/blacklight_range_limit/range_form_component.html.erb +12 -0
- data/app/components/blacklight_range_limit/range_form_component.rb +46 -0
- data/app/components/blacklight_range_limit/range_segments_component.html.erb +3 -0
- data/app/components/blacklight_range_limit/range_segments_component.rb +26 -0
- data/app/helpers/range_limit_helper.rb +70 -79
- data/app/presenters/blacklight_range_limit/facet_field_presenter.rb +85 -0
- data/app/presenters/blacklight_range_limit/facet_item_presenter.rb +45 -0
- data/app/presenters/blacklight_range_limit/filter_field.rb +85 -0
- data/app/views/blacklight_range_limit/_range_segments.html.erb +7 -21
- data/app/views/blacklight_range_limit/range_segments.html.erb +1 -1
- data/app/views/catalog/range_limit_panel.html.erb +1 -0
- data/blacklight_range_limit.gemspec +1 -1
- data/config/locales/blacklight_range_limit.de.yml +13 -0
- data/config/locales/blacklight_range_limit.it.yml +13 -0
- data/lib/blacklight_range_limit/controller_override.rb +41 -24
- data/lib/blacklight_range_limit/engine.rb +4 -0
- data/lib/blacklight_range_limit/facet_field_config_override.rb +25 -0
- data/lib/blacklight_range_limit/range_limit_builder.rb +15 -39
- data/lib/blacklight_range_limit/segment_calculation.rb +2 -2
- data/lib/blacklight_range_limit.rb +31 -12
- data/lib/generators/blacklight_range_limit/install_generator.rb +3 -17
- data/solr/conf/schema.xml +0 -13
- data/solr/conf/solrconfig.xml +1 -0
- data/spec/components/range_facet_component_spec.rb +111 -0
- data/spec/features/a_javascript_spec.rb +4 -4
- data/spec/features/blacklight_range_limit_spec.rb +7 -6
- data/spec/helpers/blacklight_range_limit_helper_spec.rb +7 -7
- data/spec/presenters/facet_field_presenter_spec.rb +144 -0
- data/spec/presenters/facet_item_presenter_spec.rb +47 -0
- data/spec/presenters/filter_field_spec.rb +70 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/support/presenter_test_helpers.rb +11 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +1 -1
- metadata +40 -17
- data/app/views/blacklight_range_limit/_range_limit_panel.html.erb +0 -90
- data/app/views/blacklight_range_limit/range_limit_panel.html.erb +0 -10
- data/lib/blacklight_range_limit/view_helper_override.rb +0 -100
- data/lib/generators/blacklight_range_limit/templates/search_history_controller.rb +0 -7
- data/spec/lib/blacklight_range_limit/view_helper_override_helper_spec.rb +0 -137
@@ -12,59 +12,35 @@ module BlacklightRangeLimit
|
|
12
12
|
|
13
13
|
# Method added to to fetch proper things for date ranges.
|
14
14
|
def add_range_limit_params(solr_params)
|
15
|
-
|
16
|
-
|
17
|
-
# In ruby 1.8, hash.select returns an array of pairs, in ruby 1.9
|
18
|
-
# it returns a hash. Turn it into a hash either way.
|
19
|
-
ranged_facet_configs = Hash[ ranged_facet_configs ] unless ranged_facet_configs.kind_of?(Hash)
|
20
|
-
|
21
|
-
ranged_facet_configs.each_pair do |field_key, config|
|
22
|
-
solr_params["stats"] = "true"
|
23
|
-
solr_params["stats.field"] ||= []
|
24
|
-
solr_params["stats.field"] << config.field
|
25
|
-
|
26
|
-
range_config = BlacklightRangeLimit.range_config(blacklight_config, config.field)
|
27
|
-
|
28
|
-
hash = blacklight_params["range"] && blacklight_params["range"][field_key] ?
|
29
|
-
blacklight_params["range"][field_key] :
|
30
|
-
{}
|
15
|
+
ranged_facet_configs = blacklight_config.facet_fields.select { |_key, config| config.range }
|
16
|
+
return solr_params unless ranged_facet_configs.any?
|
31
17
|
|
32
|
-
|
33
|
-
|
34
|
-
solr_params[:fq] ||= []
|
35
|
-
solr_params[:fq] << "-#{config.field}:[* TO *]"
|
18
|
+
solr_params["stats"] = "true"
|
19
|
+
solr_params["stats.field"] ||= []
|
36
20
|
|
37
|
-
|
38
|
-
|
39
|
-
start = hash["begin"].blank? ? "*" : hash["begin"]
|
40
|
-
finish = hash["end"].blank? ? "*" : hash["end"]
|
21
|
+
ranged_facet_configs.each do |field_key, config|
|
22
|
+
solr_params["stats.field"] << config.field
|
41
23
|
|
42
|
-
|
43
|
-
|
24
|
+
range_config = config.range_config
|
25
|
+
next if range_config[:segments] == false
|
44
26
|
|
45
|
-
|
46
|
-
|
47
|
-
add_range_segments_to_solr!(solr_params, field_key, start.to_i, finish.to_i)
|
48
|
-
end
|
27
|
+
selected_value = search_state.filter(config.key).values.first
|
28
|
+
range = (selected_value if selected_value.is_a? Range) || range_config[:assumed_boundaries]
|
49
29
|
|
50
|
-
|
51
|
-
boundaries = range_config[:assumed_boundaries])
|
52
|
-
# assumed_boundaries in config
|
53
|
-
add_range_segments_to_solr!(solr_params, field_key, boundaries[0], boundaries[1])
|
54
|
-
end
|
30
|
+
add_range_segments_to_solr!(solr_params, field_key, range.first, range.last) if range.present?
|
55
31
|
end
|
56
32
|
|
57
|
-
|
33
|
+
solr_params
|
58
34
|
end
|
59
35
|
|
60
36
|
|
61
37
|
# Another processing method, this one is NOT included in default processing chain,
|
62
38
|
# it is specifically swapped in *instead of* add_range_limit_params for
|
63
39
|
# certain ajax requests that only want to fetch range limit segments for
|
64
|
-
# ONE field.
|
40
|
+
# ONE field.
|
65
41
|
#
|
66
42
|
# It turns off facetting and sets rows to 0 as well, only results for
|
67
|
-
# single specified field are needed.
|
43
|
+
# single specified field are needed.
|
68
44
|
#
|
69
45
|
# Specified field and parameters are specified in incoming parameters
|
70
46
|
# range_field, range_start, range_end
|
@@ -80,7 +56,7 @@ module BlacklightRangeLimit
|
|
80
56
|
solr_params.delete("facet.field".to_sym)
|
81
57
|
|
82
58
|
# We don't need any actual rows either
|
83
|
-
solr_params[:rows] = 0
|
59
|
+
solr_params[:rows] = 0
|
84
60
|
|
85
61
|
return solr_params
|
86
62
|
end
|
@@ -17,11 +17,11 @@ module BlacklightRangeLimit
|
|
17
17
|
|
18
18
|
return solr_params unless field_config
|
19
19
|
|
20
|
-
range_config =
|
20
|
+
range_config = field_config.range_config
|
21
21
|
|
22
22
|
solr_params[:"facet.query"] ||= []
|
23
23
|
|
24
|
-
boundaries = boundaries_for_range_facets(min, max,
|
24
|
+
boundaries = boundaries_for_range_facets(min, max, range_config[:num_segments] || 10)
|
25
25
|
|
26
26
|
# Now make the boundaries into actual filter.queries.
|
27
27
|
0.upto(boundaries.length - 2) do |index|
|
@@ -1,9 +1,12 @@
|
|
1
1
|
# BlacklightRangeLimit
|
2
|
+
require 'deprecation'
|
2
3
|
|
3
4
|
module BlacklightRangeLimit
|
5
|
+
extend Deprecation
|
6
|
+
|
7
|
+
require 'blacklight_range_limit/facet_field_config_override'
|
4
8
|
require 'blacklight_range_limit/range_limit_builder'
|
5
9
|
require 'blacklight_range_limit/controller_override'
|
6
|
-
require 'blacklight_range_limit/view_helper_override'
|
7
10
|
|
8
11
|
require 'blacklight_range_limit/version'
|
9
12
|
require 'blacklight_range_limit/engine'
|
@@ -22,24 +25,40 @@ module BlacklightRangeLimit
|
|
22
25
|
|
23
26
|
# Add element to array only if it's not already there
|
24
27
|
def self.safe_arr_add(array, element)
|
28
|
+
Deprecation.warn(BlacklightRangeLimit, 'BlacklightRangeLimit.safe_arr_add is deprecated without replacement')
|
25
29
|
array << element unless array.include?(element)
|
26
30
|
end
|
27
31
|
|
28
|
-
# Convenience method for returning range config hash from
|
29
|
-
# blacklight config, for a specific solr field, in a normalized
|
30
|
-
# way.
|
31
|
-
#
|
32
|
-
# Returns false if range limiting not configured.
|
33
|
-
# Returns hash even if configured to 'true'
|
34
|
-
# for consistency.
|
35
32
|
def self.range_config(blacklight_config, solr_field)
|
33
|
+
Deprecation.warn(BlacklightRangeLimit, 'BlacklightRangeLimit.range_config is deprecated without replacement')
|
36
34
|
field = blacklight_config.facet_fields[solr_field.to_s]
|
37
35
|
|
38
|
-
return false unless field
|
36
|
+
return false unless field&.range
|
39
37
|
|
40
|
-
|
41
|
-
|
38
|
+
if field.range == true
|
39
|
+
default_range_config
|
40
|
+
else
|
41
|
+
field.range.merge(partial: field.partial)
|
42
|
+
end
|
43
|
+
end
|
42
44
|
|
43
|
-
|
45
|
+
def self.default_range_config
|
46
|
+
{
|
47
|
+
range: true,
|
48
|
+
range_config: {
|
49
|
+
num_segments: 10,
|
50
|
+
chart_js: true,
|
51
|
+
slider_js: true,
|
52
|
+
segments: true,
|
53
|
+
assumed_boundaries: nil,
|
54
|
+
maxlength: nil,
|
55
|
+
input_label_range_begin: nil,
|
56
|
+
input_label_range_end: nil
|
57
|
+
},
|
58
|
+
filter_class: BlacklightRangeLimit::FilterField,
|
59
|
+
presenter: BlacklightRangeLimit::FacetFieldPresenter,
|
60
|
+
item_presenter: BlacklightRangeLimit::FacetItemPresenter,
|
61
|
+
component: BlacklightRangeLimit::RangeFacetComponent
|
62
|
+
}
|
44
63
|
end
|
45
64
|
end
|
@@ -4,6 +4,8 @@ module BlacklightRangeLimit
|
|
4
4
|
class InstallGenerator < Rails::Generators::Base
|
5
5
|
source_root File.expand_path('../templates', __FILE__)
|
6
6
|
|
7
|
+
class_option :'builder-path', type: :string, default: 'app/models/search_builder.rb', aliases: "-b", desc: "Set the path, relative to Rails root, to the Blacklight app's search builder class"
|
8
|
+
|
7
9
|
def copy_public_assets
|
8
10
|
generate 'blacklight_range_limit:assets'
|
9
11
|
end
|
@@ -15,7 +17,7 @@ module BlacklightRangeLimit
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def install_search_builder
|
18
|
-
path = '
|
20
|
+
path = options[:'builder-path']
|
19
21
|
if File.exist? path
|
20
22
|
inject_into_file path, after: /include Blacklight::Solr::SearchBuilderBehavior.*$/ do
|
21
23
|
"\n include BlacklightRangeLimit::RangeLimitBuilder\n"
|
@@ -25,22 +27,6 @@ module BlacklightRangeLimit
|
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
28
|
-
# Adds range limit behavior to search history controller
|
29
|
-
def install_search_history_controller
|
30
|
-
path = 'app/controllers/search_history_controller.rb'
|
31
|
-
|
32
|
-
# If local copy of search history controller exists, add range limit helpers
|
33
|
-
if File.exist? path
|
34
|
-
inject_into_file path, after: /include Blacklight::SearchHistory.*$/ do
|
35
|
-
"\n helper BlacklightRangeLimit::ViewHelperOverride"\
|
36
|
-
"\n helper RangeLimitHelper"
|
37
|
-
end
|
38
|
-
# Otherwise copies search history controller to application
|
39
|
-
else
|
40
|
-
copy_file 'search_history_controller.rb', path
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
30
|
def install_routing_concern
|
45
31
|
route('concern :range_searchable, BlacklightRangeLimit::Routes::RangeSearchable.new')
|
46
32
|
end
|
data/solr/conf/schema.xml
CHANGED
@@ -175,16 +175,6 @@
|
|
175
175
|
<dynamicField name="*_coordinate" type="tdouble" indexed="true" stored="false" />
|
176
176
|
|
177
177
|
|
178
|
-
<!-- location (_ll...) -->
|
179
|
-
|
180
|
-
<dynamicField name="*_lli" type="location" stored="false" indexed="true" multiValued="false"/>
|
181
|
-
<dynamicField name="*_llim" type="location" stored="false" indexed="true" multiValued="true"/>
|
182
|
-
|
183
|
-
<dynamicField name="*_lls" type="location" stored="true" indexed="false" multiValued="false"/>
|
184
|
-
<dynamicField name="*_llsm" type="location" stored="true" indexed="false" multiValued="true"/>
|
185
|
-
<dynamicField name="*_llsi" type="location" stored="true" indexed="true" multiValued="false"/>
|
186
|
-
<dynamicField name="*_llsim" type="location" stored="true" indexed="true" multiValued="true"/>
|
187
|
-
|
188
178
|
<dynamicField name="*_srpt" type="location_rpt" stored="true" indexed="true" multiValued="true" />
|
189
179
|
<dynamicField name="*_bbox" type="bbox" stored="true" indexed="true" />
|
190
180
|
|
@@ -263,9 +253,6 @@
|
|
263
253
|
-->
|
264
254
|
<fieldType name="point" class="solr.PointType" dimension="2" subFieldSuffix="_d"/>
|
265
255
|
|
266
|
-
<!-- A specialized field for geospatial search. If indexed, this fieldType must not be multivalued. -->
|
267
|
-
<fieldType name="location" class="solr.LatLonType" subFieldSuffix="_coordinate"/>
|
268
|
-
|
269
256
|
<!-- An alternative geospatial field type new to Solr 4. It supports multiValued and polygon shapes.
|
270
257
|
For more information about this and other Spatial fields new to Solr 4, see:
|
271
258
|
http://wiki.apache.org/solr/SolrAdaptersForLuceneSpatial4
|
data/solr/conf/solrconfig.xml
CHANGED
@@ -19,6 +19,7 @@
|
|
19
19
|
<!-- solr lib dirs -->
|
20
20
|
<lib dir="${solr.install.dir:../../../..}/contrib/analysis-extras/lib" />
|
21
21
|
<lib dir="${solr.install.dir:../../../..}/contrib/analysis-extras/lucene-libs" />
|
22
|
+
<lib dir="${solr.install.dir:../../../..}/modules/analysis-extras/lib" />
|
22
23
|
|
23
24
|
<dataDir>${solr.data.dir:}</dataDir>
|
24
25
|
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe BlacklightRangeLimit::RangeFacetComponent, type: :component do
|
6
|
+
subject(:component) do
|
7
|
+
described_class.new(facet_field: facet_field)
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:rendered) do
|
11
|
+
Capybara::Node::Simple.new(render_inline(component))
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:facet_field) do
|
15
|
+
instance_double(
|
16
|
+
BlacklightRangeLimit::FacetFieldPresenter,
|
17
|
+
key: 'key',
|
18
|
+
html_id: 'id',
|
19
|
+
active?: false,
|
20
|
+
collapsed?: false,
|
21
|
+
in_modal?: false,
|
22
|
+
label: 'My facet field',
|
23
|
+
selected_range: nil,
|
24
|
+
selected_range_facet_item: nil,
|
25
|
+
missing_facet_item: nil,
|
26
|
+
missing_selected?: false,
|
27
|
+
min: nil,
|
28
|
+
max: nil,
|
29
|
+
search_state: Blacklight::SearchState.new({}, nil),
|
30
|
+
range_config: {},
|
31
|
+
modal_path: nil,
|
32
|
+
facet_field: facet_config,
|
33
|
+
**facet_field_params
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:facet_config) do
|
38
|
+
Blacklight::Configuration::FacetField.new(key: 'key', item_presenter: BlacklightRangeLimit::FacetItemPresenter)
|
39
|
+
end
|
40
|
+
|
41
|
+
let(:facet_field_params) { {} }
|
42
|
+
|
43
|
+
before do
|
44
|
+
allow(component).to receive(:search_facet_path).and_return('/range/key')
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'renders into the default facet layout' do
|
48
|
+
expect(rendered).to have_selector('h3', text: 'My facet field')
|
49
|
+
.and have_selector('div.collapse')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'renders a placeholder profile area' do
|
53
|
+
expect(rendered).to have_selector('div.profile', text: '')
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'with range data' do
|
57
|
+
let(:facet_field_params) do
|
58
|
+
{
|
59
|
+
range_queries: [
|
60
|
+
OpenStruct.new(value: 100..199, hits: 5),
|
61
|
+
OpenStruct.new(value: 200..300, hits: 3)
|
62
|
+
],
|
63
|
+
min: 100,
|
64
|
+
max: 300
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'renders the range data into the profile' do
|
69
|
+
expect(rendered).to have_selector('.profile li', count: 2)
|
70
|
+
.and have_selector('.profile li', text: '100 to 199')
|
71
|
+
.and have_selector('.profile li', text: '200 to 300')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'renders a form for the range' do
|
76
|
+
expect(rendered).to have_selector('form[action="http://test.host/catalog"][method="get"]')
|
77
|
+
.and have_field('range[key][begin]')
|
78
|
+
.and have_field('range[key][end]')
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'renders a link to the modal' do
|
82
|
+
expect(rendered).to have_link 'View larger', href: '/range/key'
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'within a modal' do
|
86
|
+
let(:facet_field_params) { { in_modal?: true } }
|
87
|
+
|
88
|
+
it 'does not link to the modal' do
|
89
|
+
expect(rendered).not_to have_link 'View larger'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'does not render the missing link if there are no matching documents' do
|
94
|
+
expect(rendered).not_to have_link '[Missing]'
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'with missing documents' do
|
98
|
+
let(:facet_field_params) { { missing_facet_item: facet_item } }
|
99
|
+
let(:facet_item) do
|
100
|
+
Blacklight::Solr::Response::Facets::FacetItem.new(
|
101
|
+
value: Blacklight::SearchState::FilterField::MISSING,
|
102
|
+
hits: 50
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'renders a facet value for the documents that are missing the field data' do
|
107
|
+
expected_facet_query_param = Regexp.new(Regexp.escape({ f: { '-key': ['[* TO *]'] } }.to_param))
|
108
|
+
expect(rendered).to have_link '[Missing]', href: expected_facet_query_param
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -23,13 +23,13 @@ describe 'JavaScript', js: true do
|
|
23
23
|
|
24
24
|
context 'when assumed boundaries configured' do
|
25
25
|
before do
|
26
|
-
CatalogController.blacklight_config.facet_fields['pub_date_si'].
|
27
|
-
assumed_boundaries:
|
26
|
+
CatalogController.blacklight_config.facet_fields['pub_date_si'].range_config = {
|
27
|
+
assumed_boundaries: 1990...2000
|
28
28
|
}
|
29
29
|
end
|
30
30
|
|
31
31
|
after do
|
32
|
-
CatalogController.blacklight_config.facet_fields['pub_date_si'].
|
32
|
+
CatalogController.blacklight_config.facet_fields['pub_date_si'].range_config = {}
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'should show the range limit with set boundaries' do
|
@@ -48,7 +48,7 @@ describe 'JavaScript', js: true do
|
|
48
48
|
click_button 'Publication Date Sort'
|
49
49
|
|
50
50
|
within 'ul.subsection.missing' do
|
51
|
-
expect(page).to have_link '
|
51
|
+
expect(page).to have_link '[Missing]'
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
@@ -14,9 +14,10 @@ describe "Blacklight Range Limit" do
|
|
14
14
|
it "should provide distribution information" do
|
15
15
|
visit search_catalog_path
|
16
16
|
click_link 'View distribution'
|
17
|
-
|
18
|
-
expect(page
|
19
|
-
expect(page).to
|
17
|
+
expect(page).to have_selector('a.facet-select', text: "1500 to 1599")
|
18
|
+
expect(page.find('a.facet-select', text: "1500 to 1599").ancestor('li')).to have_selector('span.facet-count', text: "0")
|
19
|
+
expect(page).to have_selector('a.facet-select', text: "2000 to 2008")
|
20
|
+
expect(page.find('a.facet-select', text: "2000 to 2008").ancestor('li')).to have_selector('span.facet-count', text: "12")
|
20
21
|
end
|
21
22
|
|
22
23
|
it "should limit appropriately" do
|
@@ -25,7 +26,7 @@ describe "Blacklight Range Limit" do
|
|
25
26
|
click_link '2000 to 2008'
|
26
27
|
|
27
28
|
within '.blacklight-pub_date_si' do
|
28
|
-
expect(page).to have_content "2000 to 2008
|
29
|
+
expect(page).to have_content "2000 to 2008✖[remove]12"
|
29
30
|
end
|
30
31
|
|
31
32
|
within '.constraints-container' do
|
@@ -39,7 +40,7 @@ describe "Blacklight Range Limit" do
|
|
39
40
|
visit search_catalog_path(page: 2)
|
40
41
|
click_link 'View distribution'
|
41
42
|
click_link '2000 to 2008'
|
42
|
-
click_button 'Apply'
|
43
|
+
click_button 'Apply', match: :first
|
43
44
|
expect(page.current_url).not_to include('page')
|
44
45
|
end
|
45
46
|
|
@@ -67,7 +68,7 @@ describe "Blacklight Range Limit with configured input labels" do
|
|
67
68
|
before do
|
68
69
|
CatalogController.blacklight_config = Blacklight::Configuration.new
|
69
70
|
CatalogController.configure_blacklight do |config|
|
70
|
-
config.add_facet_field 'pub_date_si',
|
71
|
+
config.add_facet_field 'pub_date_si', **CatalogController.default_range_config, range_config: {
|
71
72
|
input_label_range_begin: 'from publication date',
|
72
73
|
input_label_range_end: 'to publication date',
|
73
74
|
maxlength: 6
|
@@ -1,6 +1,11 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe "Blacklight Range Limit Helper" do
|
4
|
+
let(:config) { Blacklight::Configuration.new }
|
5
|
+
before do
|
6
|
+
allow(helper).to receive(:blacklight_config).and_return(config)
|
7
|
+
allow(helper).to receive(:search_state).and_return(Blacklight::SearchState.new({}, config))
|
8
|
+
end
|
4
9
|
|
5
10
|
it "should render range text fields with/without labels" do
|
6
11
|
begin_html = Capybara.string(helper.render_range_input('pub_date', 'begin'))
|
@@ -17,21 +22,16 @@ describe "Blacklight Range Limit Helper" do
|
|
17
22
|
end
|
18
23
|
|
19
24
|
context "when building requests" do
|
20
|
-
let(:config) { Blacklight::Configuration.new }
|
21
|
-
before do
|
22
|
-
allow(helper).to receive(:blacklight_config).and_return(config)
|
23
|
-
end
|
24
|
-
|
25
25
|
it "should exclude page when adding a range" do
|
26
26
|
params = { q: '', page: '2' }
|
27
27
|
updated_params = helper.add_range('test', '1900', '1995', params)
|
28
|
-
expect(updated_params).not_to include(:page)
|
28
|
+
expect(updated_params.to_h).not_to include(:page)
|
29
29
|
end
|
30
30
|
|
31
31
|
it "should exclude page when adding a missing range" do
|
32
32
|
params = { q: '', page: '2' }
|
33
33
|
updated_params = helper.add_range_missing('test', params)
|
34
|
-
expect(updated_params).not_to include(:page)
|
34
|
+
expect(updated_params.to_h).not_to include(:page)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe BlacklightRangeLimit::FacetFieldPresenter, type: :presenter do
|
6
|
+
subject(:presenter) do
|
7
|
+
described_class.new(facet_field, display_facet, view_context, search_state)
|
8
|
+
end
|
9
|
+
let(:view_context) { controller.view_context }
|
10
|
+
let(:search_state) { Blacklight::SearchState.new(params, blacklight_config, view_context) }
|
11
|
+
|
12
|
+
let(:facet_field) do
|
13
|
+
Blacklight::Configuration::FacetField.new(
|
14
|
+
key: 'field_key',
|
15
|
+
field: 'some_field',
|
16
|
+
filter_class: BlacklightRangeLimit::FilterField
|
17
|
+
)
|
18
|
+
end
|
19
|
+
let(:blacklight_config) do
|
20
|
+
Blacklight::Configuration.new.tap { |x| x.facet_fields['field_key'] = facet_field }
|
21
|
+
end
|
22
|
+
let(:params) { {} }
|
23
|
+
|
24
|
+
let(:display_facet) do
|
25
|
+
instance_double(Blacklight::Solr::Response::Facets::FacetField, items: [], response: response)
|
26
|
+
end
|
27
|
+
let(:response) do
|
28
|
+
Blacklight::Solr::Response.new(
|
29
|
+
{
|
30
|
+
response: { numFound: 5 },
|
31
|
+
stats: {
|
32
|
+
stats_fields: {
|
33
|
+
some_field: some_field_stats
|
34
|
+
}
|
35
|
+
}
|
36
|
+
},
|
37
|
+
nil
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
let(:some_field_stats) { {} }
|
42
|
+
|
43
|
+
describe '#range_queries' do
|
44
|
+
let(:response) do
|
45
|
+
{
|
46
|
+
'facet_counts' => {
|
47
|
+
'facet_queries' => {
|
48
|
+
'some_field:[150 TO 199]' => 15,
|
49
|
+
'some_field:[100 TO 149]' => 5,
|
50
|
+
'some_field:[200 TO 249]' => 4,
|
51
|
+
'irrelevant_field:[A TO C]' => 18
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'extracts range data from the facet queries response' do
|
58
|
+
expect(presenter.range_queries.count).to eq 3
|
59
|
+
expect(presenter.range_queries.map(&:value)).to eq [100..149, 150..199, 200..249]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#min' do
|
64
|
+
let(:some_field_stats) do
|
65
|
+
{
|
66
|
+
max: 999.00,
|
67
|
+
min: 700.0000,
|
68
|
+
missing: 0
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'extracts the min stat, stringifies it (for some reason), and truncates it' do
|
73
|
+
expect(presenter.min).to eq '700'
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'when all documents in the response are missing data' do
|
77
|
+
let(:some_field_stats) do
|
78
|
+
{
|
79
|
+
max: -345,
|
80
|
+
min: -999,
|
81
|
+
missing: 5
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'returns nil' do
|
86
|
+
expect(presenter.min).to be_nil
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#max' do
|
92
|
+
let(:some_field_stats) do
|
93
|
+
{
|
94
|
+
max: 999.00,
|
95
|
+
min: 700.0000,
|
96
|
+
missing: 0
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'extracts the ,ax stat, stringifies it (for some reason), and truncates it' do
|
101
|
+
expect(presenter.max).to eq '999'
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'when all documents in the response are missing data' do
|
105
|
+
let(:some_field_stats) do
|
106
|
+
{
|
107
|
+
max: -345,
|
108
|
+
min: -999,
|
109
|
+
missing: 5
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'returns nil' do
|
114
|
+
expect(presenter.max).to be_nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe '#missing_facet_item' do
|
120
|
+
let(:some_field_stats) do
|
121
|
+
{
|
122
|
+
missing: 5
|
123
|
+
}
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'extracts the missing stat' do
|
127
|
+
expect(presenter.missing_facet_item.hits).to eq 5
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe '#selected_range' do
|
132
|
+
it 'returns nil if no range is selected' do
|
133
|
+
expect(presenter.selected_range).to eq nil
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'with a user-selected range' do
|
137
|
+
let(:params) { { range: { field_key: { begin: 100, end: 250 } } } }
|
138
|
+
|
139
|
+
it 'returns the selected range' do
|
140
|
+
expect(presenter.selected_range).to eq 100..250
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe BlacklightRangeLimit::FacetItemPresenter, type: :presenter do
|
6
|
+
subject(:presenter) do
|
7
|
+
described_class.new(facet_item, facet_config, view_context, facet_field, search_state)
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:facet_item) { instance_double(Blacklight::Solr::Response::Facets::FacetItem) }
|
11
|
+
let(:filter_field) { instance_double(Blacklight::SearchState::FilterField, include?: true) }
|
12
|
+
let(:facet_config) { Blacklight::Configuration::FacetField.new(key: 'key') }
|
13
|
+
let(:facet_field) { instance_double(Blacklight::Solr::Response::Facets::FacetField) }
|
14
|
+
let(:view_context) { controller.view_context }
|
15
|
+
let(:search_state) { instance_double(Blacklight::SearchState, filter: filter_field) }
|
16
|
+
|
17
|
+
describe '#label' do
|
18
|
+
context 'with a single value' do
|
19
|
+
let(:facet_item) { 'blah' }
|
20
|
+
|
21
|
+
it 'uses the normal logic for item values' do
|
22
|
+
expect(presenter.label).to eq 'blah'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with a range' do
|
27
|
+
let(:facet_item) { 1234..2345 }
|
28
|
+
|
29
|
+
it 'translates the range into some nice, human-readable html' do
|
30
|
+
expect(Capybara.string(presenter.label))
|
31
|
+
.to have_text('1234 to 2345')
|
32
|
+
.and have_css('span.from[data-blrl-begin=1234]', text: '1234')
|
33
|
+
.and have_css('span.to[data-blrl-end=2345]', text: '2345')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with a range that has the same start + end values' do
|
38
|
+
let(:facet_item) { 2021..2021 }
|
39
|
+
|
40
|
+
it 'translates the range into some nice, human-readable html' do
|
41
|
+
expect(Capybara.string(presenter.label))
|
42
|
+
.to have_text('2021')
|
43
|
+
.and have_css('span.single[data-blrl-single=2021]', text: '2021')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|