blacklight_range_limit 9.0.0.beta1 → 9.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f262cbfeff305e3cd1567ffcd35b90e647d3afd3558b95cf9a2f739381b20ff
4
- data.tar.gz: ddfa401cafc2c1dac75d06c13a2214c7abf2f96fce4dd1421bc0c4a343e0ad8f
3
+ metadata.gz: bfe80b379721a4e19e01ecb97a0f1ca6335e2e85ae3914abec0f2ae9ee9546b6
4
+ data.tar.gz: cdc7468b2f1e7f649f72a9f4200948cbc543d9f1e6a86bcac03b467c65b18ba2
5
5
  SHA512:
6
- metadata.gz: 914a2910f0b99f6a9223cbdb32779c7a862d19a4d0d0c3ca973383c90e45e05fcf04fdc928ed3a7f7c0222ee87924071ae2af9cd4f219479adabd2601634d2f0
7
- data.tar.gz: 8a11a84d0c57be9a3036518d284bd2f698e70303fbfcde30ad2d3ee66c4018ae15543df19c6d010423b724fb1452998faa3129682a6ce13f7300746e0a68e5b8
6
+ metadata.gz: df819d6ceb0f782c612d1eb83648a178ed2f555b599df666240cfa2cc7a75d0b3554ff29ff12ada5bdf3766bb74be88b76d054a95fd233d41309d2737bcb6cf2
7
+ data.tar.gz: 269df83223ddbed2fa371c9b0aa1ebc6d5afff775d5a313a6482ba8948412456b59bbe7b1b438e51143fe2941c3e643b3ba98f5a918287ce32b4867542871c69
@@ -11,7 +11,7 @@ on:
11
11
  push:
12
12
  branches: [main]
13
13
  pull_request:
14
- branches: [main]
14
+ branches: ['**']
15
15
 
16
16
  jobs:
17
17
  test:
data/README.md CHANGED
@@ -19,7 +19,7 @@ Decimal numbers and Dates are NOT supported; they theoretically could be in the
19
19
 
20
20
  * Javascript requires you to be using either rails-importmaps or a package.json-based builder like jsbundling-rails or vite-ruby. Legacy "sprockets-only" is not supported, however propshaft or sprockets can be used as your base asset pipeline.
21
21
 
22
- * Blaklight 7.0+. Rails 7.0+
22
+ * Blacklight 7.0+. Rails 7.0+
23
23
 
24
24
 
25
25
  # Installation
@@ -34,7 +34,10 @@ Run `rails generate blacklight_range_limit:install`
34
34
 
35
35
  ### Manual Javascript setup is not hard
36
36
 
37
- The installer could have trouble figuring out how to add Javascript to your particular setup. In the end, all you need is `blacklight-range-limit` either importmap-pinned (with it's chart.js dependency), or added to your package.json, and then, in a file that has access to the `Blacklight` import:
37
+ The installer could have trouble figuring out how to add Javascript to your particular setup. If it's not working right and you want the installer to skip asset generation, you can execute as `rails generate blacklight_range_limit:install --skip-assets`.
38
+
39
+
40
+ In the end, all you need is `blacklight-range-limit` either importmap-pinned (with its chart.js dependency), or added to your package.json, and then, in a file that has access to the `Blacklight` import:
38
41
 
39
42
  import BlacklightRangeLimit from "blacklight-range-limit";
40
43
  BlacklightRangeLimit.init({ onLoadHandler: Blacklight.onLoad });
@@ -59,7 +62,7 @@ For import map pins, note:
59
62
 
60
63
  ### Unreleased version?
61
64
 
62
- If you'd like to use an unrelased version from git, just add that to your Gemfile in the usual way.
65
+ If you'd like to use an unreleased version from git, just add that to your Gemfile in the usual way.
63
66
 
64
67
  importmap-rails use should then Just Work.
65
68
 
@@ -99,11 +102,11 @@ config.add_facet_field 'pub_date', label: 'Publication Year', range_config: {
99
102
  chart_js: true,
100
103
  textual_facets: true,
101
104
  textual_facets_collapsible: true,
105
+ show_missing_link: true,
102
106
  chart_segment_border_color: "rgba(0,0,0, 0.5)",
103
107
  chart_segment_bg_color: "#ccddcc",
104
108
  chart_aspect_ratio: "2"
105
- }
106
- )
109
+ }
107
110
  ```
108
111
 
109
112
  * **:num_segments** :
@@ -112,19 +115,23 @@ config.add_facet_field 'pub_date', label: 'Publication Year', range_config: {
112
115
  * Default null. For a result set that has not yet been limited, instead of taking boundaries from results and making a second AJAX request to fetch segments, just assume these given boundaries. If you'd like to avoid this second AJAX Solr call, you can set :assumed_boundaries to a two-element array of integers instead, and the assumed boundaries will always be used. Note this is live ruby code, you can put calculations in there like Time.now.year + 2.
113
116
  * **chart_js**:
114
117
  * Default true. If false, the Javascript chart is not loaded, you can still get textual facets for bucket with `textual_facets` config.
115
- * **textual_facets**: Default true. Should we show textual facet list too? Universal design
118
+ * **textual_facets**:
119
+ * Default true. Should we show textual facet list too? Universal design
116
120
  for accessibility, may have accessibilty concerns to turn off.
117
- * **textual_facets_collapsible**: Put the textual facets in a collapse/expand
121
+ * **textual_facets_collapsible**:
122
+ * Put the textual facets in a collapse/expand
118
123
  disclosure. If you set chart_js to false, may make sense to set this to false too, to have
119
124
  textual facets only instead of chart?
120
- * **chart_segment_border_color** / **chart_segment_bg_color** :
125
+ * **show_missing_link**:
126
+ * Default true. Display a link (with count) to results that are _missing_ a value for the range field.
127
+ * **chart_segment_border_color** / **chart_segment_bg_color**:
121
128
  * Set colors for the edge and fill of the segment bars in the histogram.
122
- * chart_aspect_ratio: for chart.js, will fill available width then this determines size of chart. defaults to 2
123
-
129
+ * **chart_aspect_ratio**:
130
+ * Defaults to 2. For chart.js, will fill available width then this determines size of chart.
124
131
 
125
132
  ## Javascript dependencies
126
133
 
127
- We use [chart.js](https://www.chartjs.org/) to draw the chart. It has one dependency of it's own. These need to be either pinned with importmap-rails, or used via the chart.js npm package and an npm-package-based bundler.
134
+ We use [chart.js](https://www.chartjs.org/) to draw the chart. It has one dependency of its own. These need to be either pinned with importmap-rails, or used via the chart.js npm package and an npm-package-based bundler.
128
135
 
129
136
  There is **no CSS** needed.
130
137
 
@@ -169,4 +176,3 @@ Once you are done iterating on your test you will need to stop the application s
169
176
  # Publishing Javascript
170
177
 
171
178
  run `npm publish` to push the javascript package to https://npmjs.org/package/blacklight-range-limit
172
-
data/Rakefile CHANGED
@@ -25,6 +25,44 @@ task ci: ['engine_cart:generate'] do
25
25
  end
26
26
  end
27
27
 
28
+ desc "check npm and gem versions match before release"
29
+ task :guard_version_match do
30
+ gem_version = File.read(__dir__ + "/VERSION").chomp
31
+ npm_version = JSON.parse(File.read(__dir__ + "/package.json"))["version"]
32
+
33
+ # 9.0.0.beta1 in gem becomes 9.0.0-beta1 in npm
34
+ gem_version_parts = gem_version.split(".")
35
+ npm_version_required = [
36
+ gem_version_parts.slice(0, 3).join("."),
37
+ gem_version_parts.slice(3, gem_version_parts.length).join(".")
38
+ ].join("-")
39
+
40
+ if npm_version != npm_version_required
41
+ raise <<~EOS
42
+ You should not publish without npm version in package.json matching gem version
43
+
44
+ gem version: #{gem_version}
45
+ package.json version: #{npm_version}
46
+
47
+ expected package.json version: #{npm_version_required}
48
+
49
+ EOS
50
+ end
51
+ end
52
+
53
+ # Get our guard to run before `rake release`'s, and warning afterwards
54
+ task "release:guard_clean" => :guard_version_match
55
+ Rake::Task["guard_version_match"].enhance do
56
+ puts <<~EOS
57
+
58
+ ⚠️ Please remember to run `npm publish` the npm package too! ⚠️
59
+
60
+ If you don't have permission, please ask someone who does for help.
61
+ https://www.npmjs.com/package/blacklight-range-limit
62
+
63
+ EOS
64
+ end
65
+
28
66
 
29
67
  namespace :test do
30
68
  namespace :spec do
data/VERSION CHANGED
@@ -1 +1 @@
1
- 9.0.0.beta1
1
+ 9.0.0.beta2
@@ -19,7 +19,7 @@
19
19
  <!-- no results profile if missing is selected -->
20
20
  <% unless @facet_field.missing_selected? %>
21
21
  <%# this has to be on page if you want calculated facets to show up, JS sniffs it.
22
- it was very hard to get chart.js to be succesfully resonsive, required this wrapper!
22
+ it was very hard to get chart.js to be successfully responsive, required this wrapper!
23
23
  https://github.com/chartjs/Chart.js/issues/11005 -%>
24
24
  <div class="chart-wrapper mb-3" data-chart-wrapper="true" style="display: none; position: relative; width: 100%; aspect-ratio: <%= range_config[:chart_aspect_ratio] %>;">
25
25
  </div>
@@ -30,18 +30,18 @@
30
30
  (min = @facet_field.min) &&
31
31
  (max = @facet_field.max) %>
32
32
  <div class="distribution <%= 'chart_js' unless range_config[:chart_js] == false %>">
33
- <!-- if we already fetched segments from solr, display them
33
+ <!-- if we already fetched segments from solr, display them
34
34
  here. Otherwise, display a link to fetch them, which JS
35
35
  will AJAX fetch. -->
36
36
  <% if @facet_field.range_queries.any? %>
37
37
  <%= render BlacklightRangeLimit::RangeSegmentsComponent.new(facet_field: @facet_field) %>
38
38
  <% else %>
39
- <%= link_to(t('blacklight.range_limit.view_distribution'), range_limit_url(range_start: min, range_end: max), class: "load_distribution", "data-loading-message-html": t('blacklight.range_limit.loading_html')) %>
39
+ <%= link_to(t('blacklight.range_limit.view_distribution'), load_distribution_link, class: "load_distribution", "data-loading-message-html": t('blacklight.range_limit.loading_html')) %>
40
40
  <% end %>
41
41
  </div>
42
42
  <% end %>
43
43
 
44
- <% if @facet_field.missing_facet_item && !request.xhr? && uses_distribution? %>
44
+ <% if range_config[:show_missing_link] && @facet_field.missing_facet_item && !request.xhr? && uses_distribution? %>
45
45
  <%= render BlacklightRangeLimit::RangeSegmentsComponent.new(facet_field: @facet_field, facet_items: [@facet_field.missing_facet_item], classes: ['missing', 'mt-3']) %>
46
46
  <% end %>
47
47
  <% end %>
@@ -31,5 +31,17 @@ module BlacklightRangeLimit
31
31
  def uses_distribution?
32
32
  range_config[:chart_js] || range_config[:textual_facets]
33
33
  end
34
+
35
+ # URL that will return the distribution list of range seguments
36
+ def load_distribution_link
37
+ # For open-ended ranges, the selected range should take priority for the boundary
38
+ # over actual response min/max. Matters for multi-valued fields.
39
+ min = @facet_field.selected_range_facet_item&.value&.begin || @facet_field.min
40
+ max = @facet_field.selected_range_facet_item&.value&.end || @facet_field.max
41
+
42
+ return nil unless (min && max)
43
+
44
+ range_limit_url(range_start: min, range_end: max)
45
+ end
34
46
  end
35
47
  end
@@ -5,12 +5,22 @@
5
5
  <div class="d-flex justify-content-between align-items-end">
6
6
  <div class="d-flex flex-column mr-1 me-1">
7
7
  <%= label_tag(begin_input_name, t("blacklight.range_limit.range_begin_short"), class: 'text-muted small mb-1') %>
8
- <%= number_field_tag(begin_input_name, begin_value_default, class: "form-control form-control-sm range_begin") %>
8
+ <%= number_field_tag(begin_input_name,
9
+ begin_value_default,
10
+ min: range_config[:min_value],
11
+ max: range_config[:max_value],
12
+ class: "form-control form-control-sm range_begin")
13
+ %>
9
14
  </div>
10
15
 
11
16
  <div class="d-flex flex-column ml-1 ms-1">
12
17
  <%= label_tag(end_input_name, t("blacklight.range_limit.range_end_short"), class: 'text-muted small mb-1') %>
13
- <%= number_field_tag(end_input_name, end_value_default, class: "form-control form-control-sm range_end") %>
18
+ <%= number_field_tag(end_input_name,
19
+ end_value_default,
20
+ min: range_config[:min_value],
21
+ max: range_config[:max_value],
22
+ class: "form-control form-control-sm range_end")
23
+ %>
14
24
  </div>
15
25
  </div>
16
26
  <div class="d-flex justify-content-end mt-2">
@@ -8,6 +8,15 @@ module BlacklightRangeLimit
8
8
  label_for_range || super
9
9
  end
10
10
 
11
+ # Very hacky way to keep params used for ajax query for segments out
12
+ # of our generated facet links. Sorry this seems to be the best way!
13
+ #
14
+ # https://github.com/projectblacklight/blacklight_range_limit/issues/296
15
+ def href(path_options = {})
16
+ override_to_nil = BlacklightRangeLimit::ControllerOverride::RANGE_LIMIT_FIELDS.collect { |f| [f, nil] }.to_h
17
+ super(path_options.merge(override_to_nil))
18
+ end
19
+
11
20
  private
12
21
 
13
22
  def label_for_range
@@ -50,7 +50,13 @@ module BlacklightRangeLimit
50
50
  def values(except: [])
51
51
  params = search_state.params
52
52
  param_key = filters_key
53
- range = if params.dig(param_key, config.key).is_a? Range
53
+ range = if !params.try(:dig, param_key).respond_to?(:dig)
54
+ # bad data, not a hash at all, correct it. Yes, it's bad form to mutate
55
+ # params here, but we found no better solution -- this only necessary in BL
56
+ # prior to 8.x, not sure why, but this branch can be omitted in BL 8.
57
+ params.delete(param_key)
58
+ nil
59
+ elsif params.dig(param_key, config.key).is_a? Range
54
60
  params.dig(param_key, config.key)
55
61
  elsif params.dig(param_key, config.key).is_a? Hash
56
62
  b_bound = params.dig(param_key, config.key, :begin).presence
Binary file
@@ -8,21 +8,18 @@ module BlacklightRangeLimit
8
8
 
9
9
  RANGE_LIMIT_FIELDS = [:range_end, :range_field, :range_start].freeze
10
10
 
11
- included do
12
- before_action do
13
- # Blacklight 7.25+: Allow range limit params if necessary
14
- if blacklight_config.search_state_fields
15
- missing_keys = RANGE_LIMIT_FIELDS - blacklight_config.search_state_fields
16
- blacklight_config.search_state_fields.concat(missing_keys)
17
- end
18
- end
19
- end
20
-
21
11
  # Action method of our own!
22
12
  # Delivers a _partial_ that's a display of a single fields range facets.
23
13
  # Used when we need a second Solr query to get range facets, after the
24
14
  # first found min/max from result set.
25
15
  def range_limit
16
+ # The builder in this action will need our special range_limit fields, so we
17
+ # must allow them.
18
+ if blacklight_config.search_state_fields
19
+ missing_keys = RANGE_LIMIT_FIELDS - blacklight_config.search_state_fields
20
+ blacklight_config.search_state_fields.concat(missing_keys)
21
+ end
22
+
26
23
  @facet = blacklight_config.facet_fields[params[:range_field]]
27
24
  raise ActionController::RoutingError, 'Not Found' unless @facet&.range
28
25
 
@@ -26,13 +26,7 @@ module BlacklightRangeLimit
26
26
 
27
27
  selected_value = search_state.filter(config.key).values.first
28
28
 
29
- range = if selected_value.is_a? Range
30
- selected_value
31
- elsif range_config[:assumed_boundaries]
32
- Range.new(*range_config[:assumed_boundaries])
33
- else
34
- nil
35
- end
29
+ range = bl_create_selected_range_value(selected_value, config)
36
30
 
37
31
  # If we have both ends of a range
38
32
  add_range_segments_to_solr!(solr_params, field_key, range.begin, range.end) if range && range.count != Float::INFINITY
@@ -98,5 +92,32 @@ module BlacklightRangeLimit
98
92
  end
99
93
  end
100
94
 
95
+ # @returns Range or nil
96
+ #
97
+ # Range created from a range value or from assumed boundaries if present, and clamped between min and max
98
+ def bl_create_selected_range_value(selected_value, field_config)
99
+ range_config = field_config.range_config
100
+
101
+ range = if selected_value.is_a? Range
102
+ selected_value
103
+ elsif range_config[:assumed_boundaries].is_a?(Range)
104
+ range_config[:assumed_boundaries]
105
+ elsif range_config[:assumed_boundaries] # Array of two things please
106
+ Range.new(*range_config[:assumed_boundaries])
107
+ else
108
+ nil
109
+ end
110
+
111
+ # clamp between config'd min and max
112
+ min = range_config[:min_value]
113
+ max = range_config[:max_value]
114
+
115
+ range = Range.new(
116
+ (range.begin.clamp(min, max) if range.begin),
117
+ (range.end.clamp(min, max) if range.end),
118
+ ) if range
119
+
120
+ range
121
+ end
101
122
  end
102
123
  end
@@ -27,10 +27,13 @@ module BlacklightRangeLimit
27
27
  chart_js: true,
28
28
  textual_facets: true,
29
29
  textual_facets_collapsible: true,
30
+ show_missing_link: true,
30
31
  chart_segment_border_color: 'rgb(54, 162, 235)',
31
32
  chart_segment_bg_color: 'rgba(54, 162, 235, 0.5)',
32
33
  chart_aspect_ratio: 2,
33
- assumed_boundaries: nil
34
+ assumed_boundaries: nil,
35
+ min_value: -2_147_483_648, # solr intfield min and max
36
+ max_value: 2_147_483_648
34
37
  },
35
38
  filter_class: BlacklightRangeLimit::FilterField,
36
39
  presenter: BlacklightRangeLimit::FacetFieldPresenter,
@@ -4,10 +4,13 @@ module BlacklightRangeLimit
4
4
  class InstallGenerator < Rails::Generators::Base
5
5
  source_root File.expand_path('../templates', __FILE__)
6
6
 
7
+ class_option :'skip-assets', type: :boolean, default: false, desc: "Skip generation of assets into app"
7
8
  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
9
 
9
10
  def generate_assets
10
- generate 'blacklight_range_limit:assets'
11
+ unless options[:'skip-assets']
12
+ generate 'blacklight_range_limit:assets'
13
+ end
11
14
  end
12
15
 
13
16
  def install_catalog_controller_mixin
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blacklight-range-limit",
3
- "version": "9.0.0.beta1",
3
+ "version": "9.0.0-beta2",
4
4
  "description": "A range facet UI component plugin for blacklight",
5
5
  "type": "module",
6
6
 
@@ -106,7 +106,67 @@ RSpec.describe BlacklightRangeLimit::RangeFacetComponent, type: :component do
106
106
  it "renders a link to fetch distribution info" do
107
107
  # need request_url for routing of links generated
108
108
  with_request_url '/catalog' do
109
- expect(rendered).to have_selector(".distribution a.load_distribution[href]")
109
+ load_link = rendered.find(".distribution a.load_distribution[href]")
110
+ expect(load_link).to be_present
111
+
112
+ expect(load_link["href"]).to be_present
113
+ params = Rack::Utils.parse_nested_query(load_link["href"].split("?").try(:last))
114
+ expect(params["range_field"]).to eq facet_field.key
115
+ expect(params["range_start"]).to eq facet_field_params[:min].to_s
116
+ expect(params["range_end"]).to eq facet_field_params[:max].to_s
117
+ end
118
+ end
119
+ end
120
+
121
+ context 'with open-ended query' do
122
+ let(:selected_max) { 200 }
123
+ let(:data_max) { 300 }
124
+
125
+ let(:facet_field) do
126
+ instance_double(
127
+ BlacklightRangeLimit::FacetFieldPresenter,
128
+ key: 'key',
129
+ active?: false,
130
+ collapsed?: false,
131
+ in_modal?: false,
132
+ label: 'My facet field',
133
+ selected_range: nil,
134
+ selected_range_facet_item: Blacklight::Solr::Response::Facets::FacetItem.new(..selected_max),
135
+ missing_facet_item: nil,
136
+ missing_selected?: false,
137
+ min: nil,
138
+ max: nil,
139
+ search_state: Blacklight::SearchState.new({}, nil),
140
+ range_config: BlacklightRangeLimit.default_range_config[:range_config],
141
+ modal_path: nil,
142
+ facet_field: facet_config,
143
+ **facet_field_params,
144
+ **extra_facet_field_params
145
+ )
146
+ end
147
+
148
+ let(:facet_field_params) do
149
+ {
150
+ range_queries: [],
151
+ min: 100,
152
+ max: data_max
153
+ }
154
+ end
155
+
156
+ # This can be relevant in multi-valued queries, where even though you limited to
157
+ # < 200, some items in search can ALSO have additional values greater than 200, but
158
+ # we don't want to include them in our range buckets.
159
+ it "renders fetch distribution with expressed boundaries taking priority" do
160
+ # need request_url for routing of links generated
161
+ with_request_url '/catalog' do
162
+ load_link = rendered.find(".distribution a.load_distribution[href]")
163
+ expect(load_link).to be_present
164
+
165
+ expect(load_link["href"]).to be_present
166
+ params = Rack::Utils.parse_nested_query(load_link["href"].split("?").try(:last))
167
+ expect(params["range_field"]).to eq facet_field.key
168
+ expect(params["range_start"]).to eq facet_field_params[:min].to_s
169
+ expect(params["range_end"]).to eq selected_max.to_s
110
170
  end
111
171
  end
112
172
  end
@@ -136,14 +136,15 @@ describe 'Run through with javascript', js: true do
136
136
  end
137
137
 
138
138
  context 'when assumed boundaries configured' do
139
- before do
140
- CatalogController.blacklight_config.facet_fields['pub_date_si'].range_config = {
141
- assumed_boundaries: start_range.to_i...end_range.to_i
142
- }
143
- end
139
+ around do |example|
140
+ original = CatalogController.blacklight_config.facet_fields['pub_date_si'].range_config
141
+ CatalogController.blacklight_config.facet_fields['pub_date_si'].range_config = original.merge({
142
+ :assumed_boundaries=>1900...2100,
143
+ })
144
+
145
+ example.run
144
146
 
145
- after do
146
- CatalogController.blacklight_config.facet_fields['pub_date_si'].range_config = {}
147
+ CatalogController.blacklight_config.facet_fields['pub_date_si'].range_config = original
147
148
  end
148
149
 
149
150
  it 'should show the range limit with set boundaries' do
@@ -154,4 +155,56 @@ describe 'Run through with javascript', js: true do
154
155
  expect(find("input#range_pub_date_si_end").value).to be_present
155
156
  end
156
157
  end
158
+
159
+ context 'when missing facet item is configured not to show' do
160
+ around do |example|
161
+ original = CatalogController.blacklight_config.facet_fields['pub_date_si'].range_config
162
+ CatalogController.blacklight_config.facet_fields['pub_date_si'].range_config = original.merge({
163
+ show_missing_link: false
164
+ })
165
+
166
+ example.run
167
+
168
+ CatalogController.blacklight_config.facet_fields['pub_date_si'].range_config = original
169
+ end
170
+
171
+ it 'should not show the missing facet item' do
172
+ visit search_catalog_path
173
+
174
+ within ".facet-limit.blacklight-pub_date_si" do
175
+ expect(page).not_to have_css("ul.missing")
176
+ end
177
+ end
178
+ end
179
+
180
+ context "Range Limit text facets" do
181
+ # Make sure it works with strict permitted params
182
+ around do |example|
183
+ original = ActionController::Parameters.action_on_unpermitted_parameters
184
+ ActionController::Parameters.action_on_unpermitted_parameters = :raise
185
+
186
+ example.run
187
+
188
+ ActionController::Parameters.action_on_unpermitted_parameters = original
189
+ end
190
+
191
+ it "work with strict permitted params" do
192
+ visit search_catalog_path
193
+
194
+ click_button 'Publication Date Sort'
195
+
196
+ from_val, to_val = nil, nil
197
+ within ".facet-limit.blacklight-pub_date_si" do
198
+ find("summary", text: "Range List").click
199
+
200
+ facet_link = first(".facet-values li a")
201
+ from_val = facet_link.find("span[data-blrl-begin]")["data-blrl-begin"]
202
+ to_val = facet_link.find("span[data-blrl-end]")["data-blrl-end"]
203
+
204
+ facet_link.click
205
+ end
206
+
207
+ expect(page).to have_css(".applied-filter", text: /Publication Date Sort.*#{from_val} to #{to_val}/)
208
+ end
209
+ end
157
210
  end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe CatalogController, type: :request do
4
+ let(:range_facet_field) { "pub_date_si" }
5
+
6
+ let(:parsed_body) { Nokogiri::HTML(response.body) }
7
+
8
+ describe "bad params should not produce uncaught exception when" do
9
+ it "bad root range" do
10
+ get "/catalog?range=bad"
11
+
12
+ expect(response.code).to eq("200")
13
+ expect(parsed_body.css("span.applied-filter")).not_to be_present
14
+ end
15
+
16
+ it "facet params are ill structured" do
17
+ get "/catalog?#{ {"f" => { range_facet_field => [{"=Library&q="=>""}] } }.to_param }"
18
+
19
+ expect(response.code).to eq("200")
20
+ expect(parsed_body.css("span.applied-filter")).not_to be_present
21
+ end
22
+
23
+ it "newline in range facet does not interupt facet" do
24
+ get "/catalog?#{ {"range"=>{ range_facet_field => {"begin"=>"1588\n", "end"=>"2020\n"}}}.to_param }"
25
+
26
+ expect(response.code).to eq("200")
27
+ expect(parsed_body.css("span.applied-filter")).to be_present
28
+ expect(parsed_body.css("span.applied-filter").collect(&:text)).to include(/1588.*to.*2020/)
29
+ end
30
+
31
+ it "weird attack in range value is ignored" do
32
+ param_hash = {"range"=>{"year_facet_isim"=>{"begin"=>"1989',(;))#- --", "end"=>"1989',(;))#- --"}}}
33
+ get "/catalog?#{ param_hash.to_param }"
34
+
35
+ expect(response.code).to eq("200")
36
+ expect(parsed_body.css("span.applied-filter")).not_to be_present
37
+ end
38
+
39
+ it "empty range param is ignored" do
40
+ get "/catalog?#{ { "range" => { "year_facet_isim" => nil } }.to_param }"
41
+
42
+ expect(response.code).to eq("200")
43
+ expect(parsed_body.css("span.applied-filter")).not_to be_present
44
+ end
45
+
46
+ describe "out of bounds range config" do
47
+ let(:max) { BlacklightRangeLimit.default_range_config[:range_config][:max_value] }
48
+ let(:min) { BlacklightRangeLimit.default_range_config[:range_config][:min_value] }
49
+
50
+ let(:too_high) { max.abs * 2 }
51
+ let(:too_low) { min.abs * -2 }
52
+
53
+ it "does not error" do
54
+ get "/catalog?#{ {"range"=>{ range_facet_field => {"begin"=> too_low, "end"=> too_high }}}.to_param }"
55
+
56
+ expect(response.code).to eq("200")
57
+ expect(parsed_body.css("span.applied-filter")).to be_present
58
+ end
59
+ end
60
+ end
61
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blacklight_range_limit
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.0.0.beta1
4
+ version: 9.0.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Rochkind
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-11-14 00:00:00.000000000 Z
12
+ date: 2024-12-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: blacklight
@@ -258,6 +258,7 @@ files:
258
258
  - spec/presenters/facet_field_presenter_spec.rb
259
259
  - spec/presenters/facet_item_presenter_spec.rb
260
260
  - spec/presenters/filter_field_spec.rb
261
+ - spec/requests/bad_param_requests_spec.rb
261
262
  - spec/spec_helper.rb
262
263
  - spec/support/presenter_test_helpers.rb
263
264
  - spec/test_app_templates/Gemfile.extra
@@ -297,6 +298,7 @@ test_files:
297
298
  - spec/presenters/facet_field_presenter_spec.rb
298
299
  - spec/presenters/facet_item_presenter_spec.rb
299
300
  - spec/presenters/filter_field_spec.rb
301
+ - spec/requests/bad_param_requests_spec.rb
300
302
  - spec/spec_helper.rb
301
303
  - spec/support/presenter_test_helpers.rb
302
304
  - spec/test_app_templates/Gemfile.extra