blacklight 8.0.1 → 8.1.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.env +1 -1
  3. data/.github/workflows/ruby.yml +11 -0
  4. data/.rubocop.yml +4 -0
  5. data/.rubocop_todo.yml +67 -73
  6. data/VERSION +1 -1
  7. data/app/builders/blacklight/action_builder.rb +1 -1
  8. data/app/components/blacklight/advanced_search_form_component.html.erb +1 -1
  9. data/app/components/blacklight/advanced_search_form_component.rb +2 -2
  10. data/app/components/blacklight/response/pagination_component.html.erb +1 -1
  11. data/app/components/blacklight/response/pagination_component.rb +6 -1
  12. data/app/components/blacklight/search_bar_component.html.erb +1 -1
  13. data/app/controllers/concerns/blacklight/bookmarks.rb +1 -1
  14. data/app/models/concerns/blacklight/document/active_model_shim.rb +10 -0
  15. data/app/models/search.rb +6 -1
  16. data/app/services/blacklight/field_retriever.rb +13 -11
  17. data/app/views/catalog/_show_tools.html.erb +1 -1
  18. data/blacklight.gemspec +1 -2
  19. data/config/locales/blacklight.en.yml +1 -0
  20. data/lib/blacklight/component.rb +1 -1
  21. data/lib/blacklight/configuration.rb +7 -1
  22. data/lib/blacklight/engine.rb +12 -0
  23. data/lib/blacklight/solr/repository.rb +14 -2
  24. data/lib/blacklight/solr/search_builder_behavior.rb +2 -1
  25. data/lib/generators/blacklight/assets_generator.rb +1 -3
  26. data/lib/generators/blacklight/install_generator.rb +1 -3
  27. data/lib/generators/blacklight/templates/catalog_controller.rb +1 -0
  28. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +69 -0
  29. data/spec/components/blacklight/facet_component_spec.rb +11 -1
  30. data/spec/components/blacklight/facet_item_pivot_component_spec.rb +2 -2
  31. data/spec/components/blacklight/response/pagination_component_spec.rb +53 -0
  32. data/spec/components/blacklight/search_context/server_applied_params_component_spec.rb +11 -1
  33. data/spec/features/advanced_search_spec.rb +55 -0
  34. data/spec/features/axe_spec.rb +5 -0
  35. data/spec/helpers/blacklight_helper_spec.rb +10 -5
  36. data/spec/models/blacklight/configurable_spec.rb +1 -1
  37. data/spec/models/blacklight/solr/repository_spec.rb +27 -0
  38. data/spec/models/blacklight/solr/search_builder_spec.rb +8 -0
  39. data/spec/services/blacklight/field_retriever_spec.rb +17 -0
  40. data/spec/spec_helper.rb +29 -2
  41. data/spec/support/view_component_test_helpers.rb +14 -0
  42. data/spec/views/catalog/_paginate_compact.html.erb_spec.rb +2 -0
  43. metadata +9 -19
@@ -6,6 +6,18 @@ module Blacklight
6
6
  class Engine < Rails::Engine
7
7
  engine_name "blacklight"
8
8
 
9
+ config.before_configuration do
10
+ # see https://github.com/fxn/zeitwerk#for_gem
11
+ # Blacklight puts a generator into LOCAL APP lib/generators, so tell
12
+ # zeitwerk to ignore the whole directory? If we're using a recent
13
+ # enough version of Rails to have zeitwerk config
14
+ #
15
+ # See: https://github.com/cbeer/engine_cart/issues/117
16
+ if Rails.try(:autoloaders).try(:main).respond_to?(:ignore)
17
+ Rails.autoloaders.main.ignore(Rails.root.join('lib/generators'))
18
+ end
19
+ end
20
+
9
21
  config.after_initialize do
10
22
  Blacklight::Configuration.initialize_default_configuration
11
23
  end
@@ -21,7 +21,7 @@ module Blacklight::Solr
21
21
  # Execute a search query against solr
22
22
  # @param [Hash] params solr query parameters
23
23
  def search params = {}
24
- send_and_receive blacklight_config.solr_path, params.reverse_merge(qt: blacklight_config.qt)
24
+ send_and_receive search_path(params), params.reverse_merge(qt: blacklight_config.qt)
25
25
  end
26
26
 
27
27
  # @param [Hash] request_params
@@ -78,7 +78,7 @@ module Blacklight::Solr
78
78
  # @return [Hash]
79
79
  # @!visibility private
80
80
  def build_solr_request(solr_params)
81
- if solr_params[:json].present?
81
+ if uses_json_query_dsl?(solr_params)
82
82
  {
83
83
  data: { params: solr_params.to_hash.except(:json) }.merge(solr_params[:json]).to_json,
84
84
  method: :post,
@@ -122,5 +122,17 @@ module Blacklight::Solr
122
122
  []
123
123
  end
124
124
  end
125
+
126
+ # @return [String]
127
+ def search_path(solr_params)
128
+ return blacklight_config.json_solr_path if blacklight_config.json_solr_path && uses_json_query_dsl?(solr_params)
129
+
130
+ blacklight_config.solr_path
131
+ end
132
+
133
+ # @return [Boolean]
134
+ def uses_json_query_dsl?(solr_params)
135
+ solr_params[:json].present?
136
+ end
125
137
  end
126
138
  end
@@ -83,8 +83,9 @@ module Blacklight::Solr
83
83
  end
84
84
 
85
85
  def add_search_field_with_json_query_parameters(solr_parameters)
86
- bool_query = search_field.clause_params.transform_values { |v| v.merge(query: search_state.query_param) }
86
+ return unless search_state.query_param
87
87
 
88
+ bool_query = search_field.clause_params.transform_values { |v| v.merge(query: search_state.query_param) }
88
89
  solr_parameters.append_boolean_query(:must, bool_query)
89
90
  end
90
91
 
@@ -1,13 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'shellwords'
4
-
5
3
  module Blacklight
6
4
  class AssetsGenerator < Rails::Generators::Base
7
5
  class_option :'bootstrap-version', type: :string, default: ENV.fetch('BOOTSTRAP_VERSION', '~> 5.1'), desc: "Set the generated app's bootstrap version"
8
6
 
9
7
  def run_asset_pipeline_specific_generator
10
- generated_options = "--bootstrap-version='#{Shellwords.escape(options[:'bootstrap-version'])}'" if options[:'bootstrap-version']
8
+ generated_options = "--bootstrap-version='#{options[:'bootstrap-version']}'" if options[:'bootstrap-version']
11
9
 
12
10
  generator = if defined?(Propshaft)
13
11
  'blacklight:assets:propshaft'
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'shellwords'
4
-
5
3
  module Blacklight
6
4
  class Install < Rails::Generators::Base
7
5
  source_root File.expand_path('../templates', __FILE__)
@@ -37,7 +35,7 @@ module Blacklight
37
35
  # Call external generator in AssetsGenerator, so we can
38
36
  # leave that callable seperately too.
39
37
  def copy_public_assets
40
- generated_options = "--bootstrap-version='#{Shellwords.escape(options[:'bootstrap-version'])}'" if options[:'bootstrap-version']
38
+ generated_options = "--bootstrap-version='#{options[:'bootstrap-version']}'" if options[:'bootstrap-version']
41
39
 
42
40
  generate "blacklight:assets", generated_options unless options[:'skip-assets']
43
41
  end
@@ -38,6 +38,7 @@ class <%= controller_name.classify %>Controller < ApplicationController
38
38
  # solr path which will be added to solr base url before the other solr params.
39
39
  #config.solr_path = 'select'
40
40
  #config.document_solr_path = 'get'
41
+ #config.json_solr_path = 'advanced'
41
42
 
42
43
  # items to show per page, each number in the array represent another option to choose from.
43
44
  #config.per_page = [10,20,50,100]
@@ -100,6 +100,75 @@
100
100
  </arr>
101
101
  </requestHandler>
102
102
 
103
+ <requestHandler name="/advanced" class="solr.SearchHandler">
104
+ <!-- a lucene request handler for using the JSON Query DSL,
105
+ specifically for advanced search.
106
+ Using a separate requestHandler is a workaround to
107
+ https://issues.apache.org/jira/browse/SOLR-16916, although
108
+ it could be desirable for other reasons as well.
109
+ -->
110
+ <lst name="defaults">
111
+ <str name="defType">lucene</str>
112
+ <str name="echoParams">explicit</str>
113
+ <str name="df">title_tsim</str>
114
+ <str name="qf">
115
+ id
116
+ full_title_tsim
117
+ short_title_tsim
118
+ alternative_title_tsim
119
+ active_fedora_model_ssi
120
+ title_tsim
121
+ author_tsim
122
+ subject_tsim
123
+ all_text_timv
124
+ </str>
125
+ <str name="pf">
126
+ all_text_timv^10
127
+ </str>
128
+
129
+ <str name="author_qf">
130
+ author_tsim
131
+ </str>
132
+ <str name="author_pf">
133
+ </str>
134
+ <str name="title_qf">
135
+ title_tsim
136
+ full_title_tsim
137
+ short_title_tsim
138
+ alternative_title_tsim
139
+ </str>
140
+ <str name="title_pf">
141
+ </str>
142
+ <str name="subject_qf">
143
+ subject_tsim
144
+ </str>
145
+ <str name="subject_pf">
146
+ </str>
147
+
148
+ <str name="fl">
149
+ *,
150
+ score
151
+ </str>
152
+
153
+ <str name="facet">true</str>
154
+ <str name="facet.mincount">1</str>
155
+ <str name="facet.limit">10</str>
156
+ <str name="facet.field">active_fedora_model_ssi</str>
157
+ <str name="facet.field">subject_ssim</str>
158
+
159
+ <str name="spellcheck">true</str>
160
+ <str name="spellcheck.dictionary">default</str>
161
+ <str name="spellcheck.onlyMorePopular">true</str>
162
+ <str name="spellcheck.extendedResults">true</str>
163
+ <str name="spellcheck.collate">false</str>
164
+ <str name="spellcheck.count">5</str>
165
+
166
+ </lst>
167
+ <arr name="last-components">
168
+ <str>spellcheck</str>
169
+ </arr>
170
+ </requestHandler>
171
+
103
172
  <requestHandler name="permissions" class="solr.SearchHandler" >
104
173
  <lst name="defaults">
105
174
  <str name="facet">off</str>
@@ -45,8 +45,18 @@ RSpec.describe Blacklight::FacetComponent, type: :component do
45
45
  Blacklight::Configuration::FacetField.new(key: 'field', partial: 'catalog/facet_partial').normalize!
46
46
  end
47
47
 
48
+ # Not sure why we need to re-implement rspec's stub_template, but
49
+ # we already were, and need a Rails 7.1+ safe alternate too
50
+ # https://github.com/rspec/rspec-rails/commit/4d65bea0619955acb15023b9c3f57a3a53183da8
51
+ # https://github.com/rspec/rspec-rails/issues/2696
48
52
  before do
49
- controller.view_context.view_paths.unshift(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for('catalog/_facet_partial.html.erb' => 'facet partial'))
53
+ replace_hash = { 'catalog/_facet_partial.html.erb' => 'facet partial' }
54
+
55
+ if ::Rails.version.to_f >= 7.1
56
+ controller.prepend_view_path(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
57
+ else
58
+ controller.view_context.view_paths.unshift(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
59
+ end
50
60
  end
51
61
 
52
62
  it 'renders the partial' do
@@ -35,13 +35,13 @@ RSpec.describe Blacklight::FacetItemPivotComponent, type: :component do
35
35
 
36
36
  it 'links to the facet and shows the number of hits' do
37
37
  expect(rendered).to have_selector 'li'
38
- expect(rendered).to have_link 'x', href: '/catalog?f%5Bz%5D=x'
38
+ expect(rendered).to have_link 'x', href: nokogiri_mediated_href(facet_item.href)
39
39
  expect(rendered).to have_selector '.facet-count', text: '10'
40
40
  end
41
41
 
42
42
  it 'has the facet hierarchy' do
43
43
  expect(rendered).to have_selector 'li ul.pivot-facet'
44
- expect(rendered).to have_link 'x:1', href: /f%5Bz%5D%5B%5D=x:1/
44
+ expect(rendered).to have_link 'x:1', href: nokogiri_mediated_href(facet_item.facet_item_presenters.first.href)
45
45
  end
46
46
 
47
47
  context 'with a selected facet' do
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::Response::PaginationComponent, type: :component do
6
+ let(:render) do
7
+ with_request_url '/catalog?q=foo' do
8
+ render_inline(instance)
9
+ end
10
+ end
11
+
12
+ let(:instance) { described_class.new(response: response) }
13
+
14
+ context 'when there are many results' do
15
+ let(:response) { instance_double(Blacklight::Solr::Response, total: 10, current_page: 5, limit_value: 10_000, total_pages: 100) }
16
+
17
+ context 'with default config' do
18
+ before { render }
19
+
20
+ it "has links to deep pages" do
21
+ expect(page).not_to have_link '98'
22
+ expect(page).to have_link '99'
23
+ expect(page).to have_link '100'
24
+ expect(page).not_to have_link '101'
25
+ end
26
+ end
27
+
28
+ context 'when a different configuration that removes deep links is passed as a parameter' do
29
+ let(:instance) { described_class.new(response: response, left: 5, right: 0, outer_window: nil) }
30
+
31
+ before { render }
32
+
33
+ it "does not link to deep pages" do
34
+ expect(page).to have_link '1'
35
+ expect(page).not_to have_link '100'
36
+ end
37
+ end
38
+
39
+ context 'when a different configuration that removes deep links is configured in the controller' do
40
+ before do
41
+ allow(controller.blacklight_config.index)
42
+ .to receive(:pagination_options)
43
+ .and_return(theme: 'blacklight', left: 5, right: 0)
44
+ render
45
+ end
46
+
47
+ it "does not link to deep pages" do
48
+ expect(page).to have_link '1'
49
+ expect(page).not_to have_link '100'
50
+ end
51
+ end
52
+ end
53
+ end
@@ -10,7 +10,17 @@ RSpec.describe Blacklight::SearchContext::ServerAppliedParamsComponent, type: :c
10
10
  let(:view_context) { controller.view_context }
11
11
 
12
12
  before do
13
- view_context.view_paths.unshift(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for('application/_start_over.html.erb' => 'start over'))
13
+ # Not sure why we need to re-implement rspec's stub_template, but
14
+ # we already were, and need a Rails 7.1+ safe alternate too
15
+ # https://github.com/rspec/rspec-rails/commit/4d65bea0619955acb15023b9c3f57a3a53183da8
16
+ # https://github.com/rspec/rspec-rails/issues/2696
17
+ replace_hash = { 'application/_start_over.html.erb' => 'start over' }
18
+ if ::Rails.version.to_f >= 7.1
19
+ controller.prepend_view_path(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
20
+ else
21
+ view_context.view_paths.unshift(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
22
+ end
23
+
14
24
  allow(view_context).to receive(:current_search_session).and_return current_search_session
15
25
  allow(view_context).to receive(:link_back_to_catalog).with(any_args)
16
26
  end
@@ -5,9 +5,27 @@ require 'spec_helper'
5
5
  RSpec.describe "Blacklight Advanced Search Form" do
6
6
  describe "advanced search form" do
7
7
  before do
8
+ CatalogController.blacklight_config.search_fields['all_fields']['clause_params'] = {
9
+ edismax: {}
10
+ }
11
+ CatalogController.blacklight_config.search_fields['author']['clause_params'] = {
12
+ edismax: { qf: '${author_qf}' }
13
+ }
14
+ CatalogController.blacklight_config.search_fields['title']['clause_params'] = {
15
+ edismax: { qf: '${title_qf}' }
16
+ }
17
+ CatalogController.blacklight_config.search_fields['subject']['clause_params'] = {
18
+ edismax: { qf: '${subject_qf}' }
19
+ }
8
20
  visit '/catalog/advanced?hypothetical_existing_param=true&q=ignore+this+existing+query'
9
21
  end
10
22
 
23
+ after do
24
+ %w[all_fields author title subject].each do |field|
25
+ CatalogController.blacklight_config.search_fields[field].delete(:clause_params)
26
+ end
27
+ end
28
+
11
29
  it "has field and facet blocks" do
12
30
  expect(page).to have_selector('.query-criteria')
13
31
  expect(page).to have_selector('.limit-criteria')
@@ -45,6 +63,43 @@ RSpec.describe "Blacklight Advanced Search Form" do
45
63
  click_on 'advanced-search-submit'
46
64
  expect(page).to have_content 'Remove constraint Title: Medicine'
47
65
  expect(page).to have_content 'Strong Medicine speaks'
66
+ expect(page).to have_selector('article.document', count: 1)
67
+ end
68
+
69
+ it 'can limit to facets' do
70
+ fill_in 'Subject', with: 'Women'
71
+ click_on 'Language'
72
+ check 'Urdu 3'
73
+ click_on 'advanced-search-submit'
74
+ expect(page).to have_content 'Pākistānī ʻaurat dorāhe par'
75
+ expect(page).not_to have_content 'Ajikto kŭrŏk chŏrŏk sasimnikka : and 아직도 그럭 저럭 사십니까'
76
+ expect(page).to have_selector('article.document', count: 1)
77
+ end
78
+
79
+ it 'handles boolean queries' do
80
+ fill_in 'All Fields', with: 'history NOT strong'
81
+ click_on 'advanced-search-submit'
82
+ expect(page).to have_content('Ci an zhou bian')
83
+ expect(page).not_to have_content('Strong Medicine speaks')
84
+ expect(page).to have_selector('article.document', count: 10)
85
+ end
86
+
87
+ it 'handles queries in multiple fields with the ALL operator' do
88
+ fill_in 'All Fields', with: 'history'
89
+ fill_in 'Author', with: 'hearth'
90
+ click_on 'advanced-search-submit'
91
+ expect(page).to have_content('Strong Medicine speaks')
92
+ expect(page).to have_selector('article.document', count: 1)
93
+ end
94
+
95
+ it 'handles queries in multiple fields with the ANY operator' do
96
+ select 'any', from: 'op'
97
+ fill_in 'All Fields', with: 'history'
98
+ fill_in 'Subject', with: 'women'
99
+ click_on 'advanced-search-submit'
100
+ expect(page).to have_content('Ci an zhou bian')
101
+ expect(page).to have_content('Pākistānī ʻaurat dorāhe par')
102
+ expect(page).to have_selector('article.document', count: 10)
48
103
  end
49
104
  end
50
105
 
@@ -21,6 +21,11 @@ RSpec.describe 'Accessibility testing', api: false, js: true do
21
21
  expect(page).to be_accessible
22
22
  end
23
23
 
24
+ it 'validates the advanced search form' do
25
+ visit advanced_search_catalog_path
26
+ expect(page).to be_accessible
27
+ end
28
+
24
29
  it 'validates the single results page' do
25
30
  visit solr_document_path('2007020969')
26
31
  expect(page).to be_accessible
@@ -185,12 +185,17 @@ RSpec.describe BlacklightHelper do
185
185
  blacklight_config.view.gallery(template: '/my/partial')
186
186
  end
187
187
 
188
- def stub_template(hash)
189
- view.view_paths.unshift(ActionView::FixtureResolver.new(hash))
190
- end
191
-
192
188
  it 'renders that template' do
193
- stub_template 'my/_partial.html.erb' => 'some content'
189
+ # Not sure why we need to re-implement rspec's stub_template, but
190
+ # we already were, and need a Rails 7.1+ safe alternate too
191
+ # https://github.com/rspec/rspec-rails/commit/4d65bea0619955acb15023b9c3f57a3a53183da8
192
+ # https://github.com/rspec/rspec-rails/issues/2696
193
+ replace_hash = { 'my/_partial.html.erb' => 'some content' }
194
+ if ::Rails.version.to_f >= 7.1
195
+ controller.prepend_view_path(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
196
+ else
197
+ view.view_paths.unshift(ActionView::FixtureResolver.new(replace_hash))
198
+ end
194
199
 
195
200
  response = helper.render_document_index_with_view :gallery, [obj1, obj1]
196
201
 
@@ -93,7 +93,7 @@ RSpec.describe "Blacklight::Configurable", api: true do
93
93
  instance.blacklight_config.bar << "123"
94
94
  expect(instance.blacklight_config).not_to eq klass.blacklight_config
95
95
  expect(klass.blacklight_config.foo).to eq "bar"
96
- expect(instance.blacklight_config.foo).to eq "bar"
96
+ expect(instance.blacklight_config.foo).to eq "bar"
97
97
  expect(klass.blacklight_config.bar).not_to include("123")
98
98
  expect(instance.blacklight_config.bar).to include("asd", "123")
99
99
  end
@@ -153,6 +153,33 @@ RSpec.describe Blacklight::Solr::Repository, api: true do
153
153
  expect(JSON.parse(actual_params[:data]).with_indifferent_access).to include(query: { bool: {} })
154
154
  expect(actual_params[:headers]).to include({ 'Content-Type' => 'application/json' })
155
155
  end
156
+
157
+ context "without a json solr path configured" do
158
+ before do
159
+ blacklight_config.json_solr_path = nil
160
+ end
161
+
162
+ it "uses the default solr path" do
163
+ blacklight_config.solr_path = 'xyz'
164
+ allow(subject.connection).to receive(:send_and_receive) do |path|
165
+ expect(path).to eq 'xyz'
166
+ end
167
+ subject.search(input_params)
168
+ end
169
+ end
170
+
171
+ context "with a json solr path configured" do
172
+ before do
173
+ blacklight_config.json_solr_path = 'my-great-json'
174
+ end
175
+
176
+ it "uses the configured json_solr_path" do
177
+ allow(subject.connection).to receive(:send_and_receive) do |path|
178
+ expect(path).to eq 'my-great-json'
179
+ end
180
+ subject.search(input_params)
181
+ end
182
+ end
156
183
  end
157
184
  end
158
185
 
@@ -406,6 +406,14 @@ RSpec.describe Blacklight::Solr::SearchBuilderBehavior, api: true do
406
406
  it 'includes addtional clause parameters for the field' do
407
407
  expect(subject.dig(:json, :query, :bool, :must, 0, :edismax)).to include another: :parameter
408
408
  end
409
+
410
+ context 'with an empty search' do
411
+ let(:subject_search_params) { { commit: "search", search_field: "subject", action: "index", controller: "catalog", rows: "10", q: nil } }
412
+
413
+ it 'does not add nil query value clauses to json query' do
414
+ expect(subject).not_to have_key :json
415
+ end
416
+ end
409
417
  end
410
418
 
411
419
  describe "sorting" do
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Blacklight::FieldRetriever, api: true do
4
+ let(:service) { described_class.new(document, blacklight_field_config) }
5
+
6
+ let(:blacklight_field_config) { Blacklight::Configuration::Field.new(field: 'author_field', highlight: true) }
7
+ let(:document) { SolrDocument.new({ 'id' => 'doc1', 'title_field' => 'doc1 title', 'author_field' => 'author_someone' }, 'highlighting' => { 'doc1' => { 'title_tsimext' => ['doc <em>1</em>'] } }) }
8
+ let(:view_context) { {} }
9
+
10
+ context "highlighting" do
11
+ describe '#fetch' do
12
+ it "retrieves an author even if it's not highlighted" do
13
+ expect(service.fetch).to eq(['author_someone'])
14
+ end
15
+ end
16
+ end
17
+ end
data/spec/spec_helper.rb CHANGED
@@ -17,7 +17,6 @@ EngineCart.load_application!
17
17
  require 'rspec/rails'
18
18
  require 'rspec/collection_matchers'
19
19
  require 'capybara/rails'
20
- require 'webdrivers'
21
20
  require 'selenium-webdriver'
22
21
  require 'equivalent-xml'
23
22
  require 'axe-rspec'
@@ -35,7 +34,7 @@ Capybara.register_driver :headless_chrome do |app|
35
34
  opts.args << '--no-sandbox'
36
35
  opts.args << '--window-size=1280,1696'
37
36
  end
38
- Capybara::Selenium::Driver.new(app, browser: :chrome, capabilities: capabilities)
37
+ Capybara::Selenium::Driver.new(app, browser: :chrome, options: capabilities)
39
38
  end
40
39
 
41
40
  # Requires supporting ruby files with custom matchers and macros, etc,
@@ -119,3 +118,31 @@ RSpec.configure do |config|
119
118
  # as the one that triggered the failure.
120
119
  Kernel.srand config.seed
121
120
  end
121
+
122
+ # RSpec's stub_template method needs a differnet implementation for Rails 7.1, that
123
+ # isn't yet in an rspec-rails release.
124
+ #
125
+ # First rspec-rails tried this:
126
+ # https://github.com/rspec/rspec-rails/commit/4d65bea0619955acb15023b9c3f57a3a53183da8
127
+ #
128
+ # But it was subject to this problem:
129
+ # https://github.com/rspec/rspec-rails/issues/2696
130
+ #
131
+ # Below implementation appears to work for our purposes here, so we will patch it in
132
+ # if we are on Rails 7.1+, and not yet rspec-rails 6.1 which we expect to have it.
133
+
134
+ if ::Rails.version.to_f >= 7.1 && Gem.loaded_specs["rspec-rails"].version.release < Gem::Version.new('6.1')
135
+
136
+ module RSpec
137
+ module Rails
138
+ module ViewExampleGroup
139
+ module ExampleMethods
140
+ def stub_template(hash)
141
+ controller.prepend_view_path(StubResolverCache.resolver_for(hash))
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+
148
+ end
@@ -18,4 +18,18 @@ module ViewComponentTestHelpers
18
18
 
19
19
  ApplicationController.new.extend(Rails.application.routes.url_helpers)
20
20
  end
21
+
22
+ # Nokogiri 1.15.0 upgrades the vendored libxml2 from v2.10.4 to v2.11.3
23
+ # libxml2 v2.11.0 introduces a change to parsing HTML href attributes
24
+ # in nokogiri < 1.15, brackets in href attributes are escaped:
25
+ # - <a class="facet-select" rel="nofollow" href="/catalog?f%5Bz%5D%5B%5D=x:1">x:1</a>
26
+ # in nokogiri >= 1.15, brackets in href attributes are not escaped:
27
+ # - <a class="facet-select" rel="nofollow" href="/catalog?f[z][]=x:1">x:1</a>
28
+ # until we can spec a minimum nokogiri version of 1.15.0, we need to see how
29
+ # the installed version parsed the html
30
+ def nokogiri_mediated_href(href)
31
+ start = "<a href=\"".length
32
+ stop = -"\"></a>".length
33
+ Nokogiri::HTML.fragment("<a href=\"#{href}\"></a>").to_s[start...stop]
34
+ end
21
35
  end
@@ -2,9 +2,11 @@
2
2
 
3
3
  RSpec.describe "catalog/_paginate_compact.html.erb" do
4
4
  let(:user) { User.new { |u| u.save(validate: false) } }
5
+ let(:blacklight_config) { Blacklight::Configuration.new }
5
6
 
6
7
  before do
7
8
  controller.request.path_parameters[:action] = 'index'
9
+ allow(controller).to receive(:blacklight_config).and_return(blacklight_config)
8
10
  end
9
11
 
10
12
  it "renders paginatable arrays" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blacklight
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.1
4
+ version: 8.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Rochkind
@@ -17,7 +17,7 @@ authors:
17
17
  autorequire:
18
18
  bindir: exe
19
19
  cert_chain: []
20
- date: 2023-05-01 00:00:00.000000000 Z
20
+ date: 2023-11-09 00:00:00.000000000 Z
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
23
  name: rails
@@ -118,7 +118,7 @@ dependencies:
118
118
  version: '2.66'
119
119
  - - "<"
120
120
  - !ruby/object:Gem::Version
121
- version: '3.1'
121
+ version: '4'
122
122
  type: :runtime
123
123
  prerelease: false
124
124
  version_requirements: !ruby/object:Gem::Requirement
@@ -128,7 +128,7 @@ dependencies:
128
128
  version: '2.66'
129
129
  - - "<"
130
130
  - !ruby/object:Gem::Version
131
- version: '3.1'
131
+ version: '4'
132
132
  - !ruby/object:Gem::Dependency
133
133
  name: rsolr
134
134
  requirement: !ruby/object:Gem::Requirement
@@ -205,20 +205,6 @@ dependencies:
205
205
  - - "~>"
206
206
  - !ruby/object:Gem::Version
207
207
  version: '3'
208
- - !ruby/object:Gem::Dependency
209
- name: webdrivers
210
- requirement: !ruby/object:Gem::Requirement
211
- requirements:
212
- - - ">="
213
- - !ruby/object:Gem::Version
214
- version: '0'
215
- type: :development
216
- prerelease: false
217
- version_requirements: !ruby/object:Gem::Requirement
218
- requirements:
219
- - - ">="
220
- - !ruby/object:Gem::Version
221
- version: '0'
222
208
  - !ruby/object:Gem::Dependency
223
209
  name: selenium-webdriver
224
210
  requirement: !ruby/object:Gem::Requirement
@@ -782,6 +768,7 @@ files:
782
768
  - spec/components/blacklight/header_component_spec.rb
783
769
  - spec/components/blacklight/hidden_search_state_component_spec.rb
784
770
  - spec/components/blacklight/metadata_field_component_spec.rb
771
+ - spec/components/blacklight/response/pagination_component_spec.rb
785
772
  - spec/components/blacklight/response/spellcheck_component_spec.rb
786
773
  - spec/components/blacklight/response/view_type_component_spec.rb
787
774
  - spec/components/blacklight/search_bar_component_spec.rb
@@ -882,6 +869,7 @@ files:
882
869
  - spec/requests/load_suggestions_spec.rb
883
870
  - spec/routing/catalog_routing_spec.rb
884
871
  - spec/routing/search_history_spec.rb
872
+ - spec/services/blacklight/field_retriever_spec.rb
885
873
  - spec/services/blacklight/search_service_spec.rb
886
874
  - spec/spec_helper.rb
887
875
  - spec/support/controller_level_helpers.rb
@@ -935,7 +923,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
935
923
  - !ruby/object:Gem::Version
936
924
  version: '0'
937
925
  requirements: []
938
- rubygems_version: 3.4.12
926
+ rubygems_version: 3.4.21
939
927
  signing_key:
940
928
  specification_version: 4
941
929
  summary: Blacklight provides a discovery interface for any Solr (http://lucene.apache.org/solr)
@@ -957,6 +945,7 @@ test_files:
957
945
  - spec/components/blacklight/header_component_spec.rb
958
946
  - spec/components/blacklight/hidden_search_state_component_spec.rb
959
947
  - spec/components/blacklight/metadata_field_component_spec.rb
948
+ - spec/components/blacklight/response/pagination_component_spec.rb
960
949
  - spec/components/blacklight/response/spellcheck_component_spec.rb
961
950
  - spec/components/blacklight/response/view_type_component_spec.rb
962
951
  - spec/components/blacklight/search_bar_component_spec.rb
@@ -1057,6 +1046,7 @@ test_files:
1057
1046
  - spec/requests/load_suggestions_spec.rb
1058
1047
  - spec/routing/catalog_routing_spec.rb
1059
1048
  - spec/routing/search_history_spec.rb
1049
+ - spec/services/blacklight/field_retriever_spec.rb
1060
1050
  - spec/services/blacklight/search_service_spec.rb
1061
1051
  - spec/spec_helper.rb
1062
1052
  - spec/support/controller_level_helpers.rb