blacklight 7.22.2 → 7.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +29 -8
- data/VERSION +1 -1
- data/app/assets/stylesheets/blacklight/_facets.scss +6 -0
- data/app/components/blacklight/advanced_search_form_component.rb +5 -5
- data/app/components/blacklight/constraints_component.html.erb +8 -4
- data/app/components/blacklight/constraints_component.rb +43 -18
- data/app/components/blacklight/document/action_component.html.erb +1 -1
- data/app/components/blacklight/document/action_component.rb +10 -3
- data/app/components/blacklight/document/bookmark_component.rb +2 -2
- data/app/components/blacklight/document/citation_component.rb +1 -1
- data/app/components/blacklight/document/group_component.html.erb +1 -1
- data/app/components/blacklight/document/group_component.rb +2 -2
- data/app/components/blacklight/document/more_like_this_component.html.erb +1 -1
- 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 +2 -2
- data/app/components/blacklight/document_title_component.rb +3 -3
- data/app/components/blacklight/facet_field_checkboxes_component.rb +1 -1
- data/app/components/blacklight/facet_field_inclusive_constraint_component.html.erb +1 -1
- data/app/components/blacklight/facet_field_inclusive_constraint_component.rb +1 -1
- data/app/components/blacklight/facet_field_list_component.html.erb +1 -1
- data/app/components/blacklight/facet_field_list_component.rb +1 -1
- data/app/components/blacklight/facet_field_pagination_component.html.erb +4 -4
- data/app/components/blacklight/facet_item_component.rb +2 -2
- data/app/components/blacklight/facet_item_pivot_component.rb +2 -2
- data/app/components/blacklight/metadata_field_component.rb +2 -2
- data/app/components/blacklight/response/facet_group_component.html.erb +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/response/sort_component.html.erb +1 -1
- data/app/components/blacklight/response/spellcheck_component.rb +14 -3
- data/app/components/blacklight/response/view_type_button_component.rb +3 -3
- data/app/components/blacklight/response/view_type_component.rb +1 -1
- data/app/components/blacklight/search_bar_component.rb +2 -2
- data/app/components/blacklight/search_context_component.rb +3 -3
- data/app/components/blacklight/search_history_constraint_layout_component.rb +14 -0
- data/app/components/blacklight/start_over_button_component.rb +20 -0
- data/app/components/blacklight/system/dropdown_component.rb +1 -1
- data/app/controllers/concerns/blacklight/bookmarks.rb +1 -1
- data/app/controllers/concerns/blacklight/catalog.rb +2 -2
- data/app/controllers/concerns/blacklight/search_context.rb +1 -1
- data/app/helpers/blacklight/blacklight_helper_behavior.rb +12 -4
- data/app/helpers/blacklight/catalog_helper_behavior.rb +18 -7
- data/app/helpers/blacklight/render_partials_helper_behavior.rb +12 -1
- data/app/helpers/blacklight/search_history_constraints_helper_behavior.rb +30 -2
- data/app/helpers/blacklight/url_helper_behavior.rb +3 -1
- data/app/javascript/blacklight/modal.js +2 -2
- data/app/models/concerns/blacklight/configurable.rb +1 -1
- data/app/models/concerns/blacklight/document/active_model_shim.rb +1 -1
- data/app/models/concerns/blacklight/document/extensions.rb +1 -1
- data/app/models/concerns/blacklight/document/semantic_fields.rb +1 -1
- data/app/models/concerns/blacklight/document.rb +1 -1
- data/app/views/catalog/_email_form.html.erb +1 -1
- data/app/views/catalog/_search_results.html.erb +1 -1
- data/app/views/catalog/_sms_form.html.erb +3 -3
- data/app/views/catalog/_start_over.html.erb +1 -1
- data/app/views/layouts/blacklight/base.html.erb +1 -0
- data/blacklight.gemspec +3 -4
- data/lib/blacklight/configuration/fields.rb +1 -1
- data/lib/blacklight/configuration.rb +2 -1
- data/lib/blacklight/deprecations/engine_configuration.rb +66 -0
- data/lib/blacklight/engine.rb +21 -10
- data/lib/blacklight/exceptions.rb +3 -0
- data/lib/blacklight/search_state/filter_field.rb +4 -4
- data/lib/blacklight/solr/repository.rb +36 -12
- data/lib/blacklight/solr/search_builder_behavior.rb +1 -4
- data/lib/generators/blacklight/assets_generator.rb +14 -10
- data/spec/components/blacklight/constraints_component_spec.rb +68 -0
- data/spec/components/blacklight/document/action_component_spec.rb +2 -1
- data/spec/components/blacklight/document_component_spec.rb +1 -1
- data/spec/components/blacklight/response/spellcheck_component_spec.rb +73 -0
- data/spec/components/blacklight/start_over_button_component_spec.rb +38 -0
- data/spec/controllers/catalog_controller_spec.rb +1 -1
- data/spec/features/did_you_mean_spec.rb +21 -0
- data/spec/features/search_context_spec.rb +3 -1
- data/spec/helpers/blacklight/search_history_constraints_helper_behavior_spec.rb +2 -0
- data/spec/helpers/blacklight/url_helper_behavior_spec.rb +3 -3
- data/spec/helpers/blacklight_helper_spec.rb +8 -3
- data/spec/helpers/catalog_helper_spec.rb +6 -2
- data/spec/lib/blacklight/engine_spec.rb +41 -0
- data/spec/models/blacklight/facet_paginator_spec.rb +60 -15
- data/spec/models/blacklight/solr/repository_spec.rb +29 -21
- data/spec/models/blacklight/solr/response/facets_spec.rb +48 -10
- data/spec/presenters/blacklight/facet_item_presenter_spec.rb +1 -1
- data/spec/presenters/blacklight/field_presenter_spec.rb +2 -2
- data/spec/routing/search_history_spec.rb +9 -0
- data/spec/services/blacklight/search_service_spec.rb +8 -0
- data/spec/spec_helper.rb +2 -3
- data/spec/support/controller_level_helpers.rb +8 -0
- data/spec/views/catalog/_constraints.html.erb_spec.rb +1 -1
- data/spec/views/catalog/_index.html.erb_spec.rb +1 -1
- data/spec/views/catalog/_show.html.erb_spec.rb +1 -1
- data/spec/views/catalog/_show_sidebar.erb_spec.rb +1 -1
- data/spec/views/catalog/facet.json.jbuilder_spec.rb +1 -1
- data/spec/views/catalog/index.atom.builder_spec.rb +1 -0
- data/spec/views/catalog/index.html.erb_spec.rb +1 -0
- data/spec/views/catalog/index.json.jbuilder_spec.rb +1 -1
- data/spec/views/catalog/show.json.jbuilder_spec.rb +1 -1
- metadata +21 -22
data/lib/blacklight/engine.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
require '
|
|
2
|
+
require 'blacklight/deprecations/engine_configuration'
|
|
3
|
+
require 'view_component'
|
|
3
4
|
|
|
4
5
|
module Blacklight
|
|
5
6
|
class Engine < Rails::Engine
|
|
@@ -22,14 +23,18 @@ module Blacklight
|
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
25
|
|
|
25
|
-
initializer "blacklight.assets.precompile" do
|
|
26
|
+
initializer "blacklight.assets.precompile" do
|
|
27
|
+
PRECOMPILE_ASSETS = %w(favicon.ico blacklight/blacklight.js blacklight/blacklight.js.map).freeze
|
|
28
|
+
|
|
26
29
|
# When Rails has been generated in API mode, it does not have sprockets available
|
|
27
|
-
if
|
|
28
|
-
|
|
30
|
+
if Rails.application.config.respond_to?(:assets)
|
|
31
|
+
Rails.application.config.assets.precompile += PRECOMPILE_ASSETS
|
|
29
32
|
end
|
|
30
33
|
end
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
bl_global_config = OpenStructWithHashAccess.new
|
|
36
|
+
|
|
37
|
+
bl_global_config.sms_mappings = {
|
|
33
38
|
'Virgin' => 'vmobl.com',
|
|
34
39
|
'AT&T' => 'txt.att.net',
|
|
35
40
|
'Verizon' => 'vtext.com',
|
|
@@ -41,14 +46,20 @@ module Blacklight
|
|
|
41
46
|
'Google Fi' => 'msg.fi.google.com'
|
|
42
47
|
}
|
|
43
48
|
|
|
44
|
-
|
|
49
|
+
bl_global_config.bookmarks_http_method = :post
|
|
45
50
|
|
|
46
|
-
|
|
51
|
+
bl_global_config.email_regexp = defined?(Devise) ? Devise.email_regexp : /\A[^@\s]+@[^@\s]+\z/
|
|
47
52
|
|
|
48
|
-
|
|
53
|
+
bl_global_config.facet_missing_param = '[* TO *]'
|
|
49
54
|
|
|
50
|
-
config
|
|
55
|
+
# Anything that goes into Blacklight::Engine.config is stored as a class
|
|
56
|
+
# variable on Railtie::Configuration. we're going to encapsulate all the
|
|
57
|
+
# Blacklight specific stuff in this single struct:
|
|
58
|
+
Blacklight::Engine.config.blacklight = bl_global_config
|
|
51
59
|
|
|
52
|
-
|
|
60
|
+
# Deprecate top-level access to legacy engine configuration
|
|
61
|
+
Blacklight::Deprecations::EngineConfiguration.deprecate_in(Blacklight::Engine.config)
|
|
62
|
+
|
|
63
|
+
config.action_dispatch.rescue_responses["Blacklight::Exceptions::RecordNotFound"] = :not_found
|
|
53
64
|
end
|
|
54
65
|
end
|
|
@@ -46,7 +46,7 @@ module Blacklight
|
|
|
46
46
|
|
|
47
47
|
if value == Blacklight::SearchState::FilterField::MISSING
|
|
48
48
|
url_key = "-#{key}"
|
|
49
|
-
value = Blacklight::Engine.config.facet_missing_param
|
|
49
|
+
value = Blacklight::Engine.config.blacklight.facet_missing_param
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
param = :f_inclusive if value.is_a?(Array)
|
|
@@ -82,7 +82,7 @@ module Blacklight
|
|
|
82
82
|
|
|
83
83
|
if value == Blacklight::SearchState::FilterField::MISSING
|
|
84
84
|
url_key = "-#{key}"
|
|
85
|
-
value = Blacklight::Engine.config.facet_missing_param
|
|
85
|
+
value = Blacklight::Engine.config.blacklight.facet_missing_param
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
param = :f_inclusive if value.is_a?(Array)
|
|
@@ -114,7 +114,7 @@ module Blacklight
|
|
|
114
114
|
params = search_state.params
|
|
115
115
|
f = Array(params.dig(:f, key))
|
|
116
116
|
f_inclusive = [params.dig(:f_inclusive, key)] if params.dig(:f_inclusive, key).present?
|
|
117
|
-
f_missing = [Blacklight::SearchState::FilterField::MISSING] if params.dig(:f, "-#{key}")&.any? { |v| v == Blacklight::Engine.config.facet_missing_param }
|
|
117
|
+
f_missing = [Blacklight::SearchState::FilterField::MISSING] if params.dig(:f, "-#{key}")&.any? { |v| v == Blacklight::Engine.config.blacklight.facet_missing_param }
|
|
118
118
|
|
|
119
119
|
f + (f_inclusive || []) + (f_missing || [])
|
|
120
120
|
end
|
|
@@ -133,7 +133,7 @@ module Blacklight
|
|
|
133
133
|
if value.is_a?(Array)
|
|
134
134
|
(params.dig(:f_inclusive, key) || []).to_set == value.to_set
|
|
135
135
|
elsif value == Blacklight::SearchState::FilterField::MISSING
|
|
136
|
-
(params.dig(:f, "-#{key}") || []).include?(Blacklight::Engine.config.facet_missing_param)
|
|
136
|
+
(params.dig(:f, "-#{key}") || []).include?(Blacklight::Engine.config.blacklight.facet_missing_param)
|
|
137
137
|
else
|
|
138
138
|
(params.dig(:f, key) || []).include?(value)
|
|
139
139
|
end
|
|
@@ -58,30 +58,40 @@ module Blacklight::Solr
|
|
|
58
58
|
# @return [Blacklight::Solr::Response] the solr response object
|
|
59
59
|
def send_and_receive(path, solr_params = {})
|
|
60
60
|
benchmark("Solr fetch", level: :debug) do
|
|
61
|
-
res =
|
|
62
|
-
connection.send_and_receive(
|
|
63
|
-
path,
|
|
64
|
-
data: { params: solr_params.to_hash.except(:json) }.merge(solr_params[:json]).to_json,
|
|
65
|
-
method: :post,
|
|
66
|
-
headers: { 'Content-Type' => 'application/json' }
|
|
67
|
-
)
|
|
68
|
-
else
|
|
69
|
-
key = blacklight_config.http_method == :post ? :data : :params
|
|
70
|
-
connection.send_and_receive(path, { key => solr_params.to_hash, method: blacklight_config.http_method })
|
|
71
|
-
end
|
|
72
|
-
|
|
61
|
+
res = connection.send_and_receive(path, build_solr_request(solr_params))
|
|
73
62
|
solr_response = blacklight_config.response_model.new(res, solr_params, document_model: blacklight_config.document_model, blacklight_config: blacklight_config)
|
|
74
63
|
|
|
75
64
|
Blacklight.logger&.debug("Solr query: #{blacklight_config.http_method} #{path} #{solr_params.to_hash.inspect}")
|
|
76
65
|
Blacklight.logger&.debug("Solr response: #{solr_response.inspect}") if defined?(::BLACKLIGHT_VERBOSE_LOGGING) && ::BLACKLIGHT_VERBOSE_LOGGING
|
|
77
66
|
solr_response
|
|
78
67
|
end
|
|
68
|
+
rescue *defined_rsolr_timeout_exceptions => e
|
|
69
|
+
raise Blacklight::Exceptions::RepositoryTimeout, "Timeout connecting to Solr instance using #{connection.inspect}: #{e.inspect}"
|
|
79
70
|
rescue Errno::ECONNREFUSED => e
|
|
71
|
+
# intended for and likely to be a RSolr::Error:ConnectionRefused, specifically.
|
|
80
72
|
raise Blacklight::Exceptions::ECONNREFUSED, "Unable to connect to Solr instance using #{connection.inspect}: #{e.inspect}"
|
|
81
73
|
rescue RSolr::Error::Http => e
|
|
82
74
|
raise Blacklight::Exceptions::InvalidRequest, e.message
|
|
83
75
|
end
|
|
84
76
|
|
|
77
|
+
# @return [Hash]
|
|
78
|
+
# @!visibility private
|
|
79
|
+
def build_solr_request(solr_params)
|
|
80
|
+
if solr_params[:json].present?
|
|
81
|
+
{
|
|
82
|
+
data: { params: solr_params.to_hash.except(:json) }.merge(solr_params[:json]).to_json,
|
|
83
|
+
method: :post,
|
|
84
|
+
headers: { 'Content-Type' => 'application/json' }
|
|
85
|
+
}
|
|
86
|
+
else
|
|
87
|
+
key = blacklight_config.http_method == :post ? :data : :params
|
|
88
|
+
{
|
|
89
|
+
key => solr_params.to_hash,
|
|
90
|
+
method: blacklight_config.http_method
|
|
91
|
+
}
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
85
95
|
private
|
|
86
96
|
|
|
87
97
|
##
|
|
@@ -97,5 +107,19 @@ module Blacklight::Solr
|
|
|
97
107
|
def build_connection
|
|
98
108
|
RSolr.connect(connection_config.merge(adapter: connection_config[:http_adapter]))
|
|
99
109
|
end
|
|
110
|
+
|
|
111
|
+
# RSolr 2.4.0+ has a RSolr::Error::Timeout that we'd like to treat specially
|
|
112
|
+
# instead of lumping into RSolr::Error::Http. Before that we can not rescue
|
|
113
|
+
# specially, so return an empty array.
|
|
114
|
+
#
|
|
115
|
+
# @return [Array<Exception>] that can be used, with a splat, as argument
|
|
116
|
+
# to a ruby rescue
|
|
117
|
+
def defined_rsolr_timeout_exceptions
|
|
118
|
+
if defined?(RSolr::Error::Timeout)
|
|
119
|
+
[RSolr::Error::Timeout]
|
|
120
|
+
else
|
|
121
|
+
[]
|
|
122
|
+
end
|
|
123
|
+
end
|
|
100
124
|
end
|
|
101
125
|
end
|
|
@@ -355,10 +355,7 @@ module Blacklight::Solr
|
|
|
355
355
|
solr_field ||= facet_field
|
|
356
356
|
|
|
357
357
|
local_params = []
|
|
358
|
-
|
|
359
|
-
if use_local_params
|
|
360
|
-
local_params << "tag=#{facet_config.tag}" if facet_config && facet_config.tag
|
|
361
|
-
end
|
|
358
|
+
local_params << "tag=#{facet_config.tag}" if use_local_params && facet_config && facet_config.tag
|
|
362
359
|
|
|
363
360
|
if facet_config && facet_config.query
|
|
364
361
|
if facet_config.query[value]
|
|
@@ -11,15 +11,21 @@ module Blacklight
|
|
|
11
11
|
gem 'twitter-typeahead-rails', '0.11.1.pre.corejavascript'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
def appease_rails7
|
|
15
|
+
return unless Rails.version > '7'
|
|
16
|
+
|
|
17
|
+
gem "sassc-rails", "~> 2.1"
|
|
17
18
|
|
|
19
|
+
remove_file 'app/javascript/application.js'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Add sprockets javascript
|
|
23
|
+
def create_sprockets_javascript
|
|
18
24
|
create_file 'app/assets/javascripts/application.js' do
|
|
19
25
|
<<~CONTENT
|
|
20
26
|
//= require jquery3
|
|
21
27
|
//= require rails-ujs
|
|
22
|
-
//= require turbolinks
|
|
28
|
+
#{'//= require turbolinks' if Rails.version < '7'}
|
|
23
29
|
CONTENT
|
|
24
30
|
end
|
|
25
31
|
end
|
|
@@ -40,6 +46,7 @@ module Blacklight
|
|
|
40
46
|
# Ensure this method is idempotent
|
|
41
47
|
return if has_blacklight_assets?
|
|
42
48
|
|
|
49
|
+
gem 'jquery-rails'
|
|
43
50
|
contents = "\n//\n// Required by Blacklight\n"
|
|
44
51
|
contents += "//= require popper\n"
|
|
45
52
|
contents += "// Twitter Typeahead for autocomplete\n"
|
|
@@ -62,11 +69,6 @@ module Blacklight
|
|
|
62
69
|
end
|
|
63
70
|
end
|
|
64
71
|
|
|
65
|
-
# This is not a default in Rails 5.1+
|
|
66
|
-
def add_jquery
|
|
67
|
-
gem 'jquery-rails'
|
|
68
|
-
end
|
|
69
|
-
|
|
70
72
|
private
|
|
71
73
|
|
|
72
74
|
def turbolinks?
|
|
@@ -78,7 +80,9 @@ module Blacklight
|
|
|
78
80
|
end
|
|
79
81
|
|
|
80
82
|
def application_js
|
|
81
|
-
|
|
83
|
+
path = File.expand_path("app/assets/javascripts/application.js", destination_root)
|
|
84
|
+
|
|
85
|
+
File.exist?(path) ? File.read(path) : ''
|
|
82
86
|
end
|
|
83
87
|
end
|
|
84
88
|
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe Blacklight::ConstraintsComponent, type: :component do
|
|
6
|
+
subject(:component) { described_class.new(**params) }
|
|
7
|
+
|
|
8
|
+
let(:rendered) { render_inline_to_capybara_node(component) }
|
|
9
|
+
|
|
10
|
+
let(:params) do
|
|
11
|
+
{ search_state: search_state }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
let(:blacklight_config) do
|
|
15
|
+
Blacklight::Configuration.new.tap do |config|
|
|
16
|
+
config.add_facet_field 'some_facet'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
let(:search_state) { Blacklight::SearchState.new(query_params.with_indifferent_access, blacklight_config) }
|
|
21
|
+
let(:query_params) { {} }
|
|
22
|
+
|
|
23
|
+
context 'with a query' do
|
|
24
|
+
let(:query_params) { { q: 'some query' } }
|
|
25
|
+
|
|
26
|
+
it 'renders a start-over link' do
|
|
27
|
+
expect(rendered).to have_link 'Start Over', href: '/catalog'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'has a header' do
|
|
31
|
+
expect(rendered).to have_selector('h2', text: 'Search Constraints')
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'wraps the output in a div' do
|
|
35
|
+
expect(rendered).to have_selector('div#appliedParams')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'renders the query' do
|
|
39
|
+
expect(rendered).to have_selector('.applied-filter.constraint', text: 'some query')
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context 'with a facet' do
|
|
44
|
+
let(:query_params) { { f: { some_facet: ['some value'] } } }
|
|
45
|
+
|
|
46
|
+
it 'renders the query' do
|
|
47
|
+
expect(rendered).to have_selector('.constraint-value > .filter-name', text: 'Some Facet').and(have_selector('.constraint-value > .filter-value', text: 'some value'))
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe '.for_search_history' do
|
|
52
|
+
subject(:component) { described_class.for_search_history(**params) }
|
|
53
|
+
|
|
54
|
+
let(:query_params) { { q: 'some query', f: { some_facet: ['some value'] } } }
|
|
55
|
+
|
|
56
|
+
it 'wraps the output in a span' do
|
|
57
|
+
expect(rendered).to have_selector('span .constraint')
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'renders the search state as lightly-decorated text' do
|
|
61
|
+
expect(rendered).to have_selector('.constraint > .filter-values', text: 'some query').and(have_selector('.constraint', text: 'Some Facet:some value'))
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'omits the headers' do
|
|
65
|
+
expect(rendered).not_to have_selector('h2', text: 'Search Constraints')
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -24,10 +24,11 @@ RSpec.describe Blacklight::Document::ActionComponent, type: :component do
|
|
|
24
24
|
|
|
25
25
|
it 'renders an action link' do
|
|
26
26
|
if Rails.version >= '6'
|
|
27
|
-
allow(view_context).to receive(:some_tool_solr_document_path).with(document, only_path: true).and_return('/asdf')
|
|
27
|
+
allow(view_context).to receive(:some_tool_solr_document_path).with(document, { only_path: true }).and_return('/asdf')
|
|
28
28
|
else
|
|
29
29
|
allow(view_context).to receive(:some_tool_solr_document_path).with(document).and_return('/asdf')
|
|
30
30
|
end
|
|
31
|
+
|
|
31
32
|
expect(rendered).to have_link 'Some tool', href: '/asdf'
|
|
32
33
|
end
|
|
33
34
|
|
|
@@ -28,7 +28,7 @@ RSpec.describe Blacklight::DocumentComponent, type: :component do
|
|
|
28
28
|
CatalogController.blacklight_config.deep_copy.tap do |config|
|
|
29
29
|
config.track_search_session = false
|
|
30
30
|
config.index.thumbnail_field = 'thumbnail_path_ss'
|
|
31
|
-
config.index.document_actions[:bookmark].partial = '/catalog/bookmark_control
|
|
31
|
+
config.index.document_actions[:bookmark].partial = '/catalog/bookmark_control'
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe Blacklight::Response::SpellcheckComponent, type: :component do
|
|
6
|
+
subject(:render) { render_inline(instance) }
|
|
7
|
+
|
|
8
|
+
let(:spellcheck_options) { nil }
|
|
9
|
+
let(:instance) { described_class.new(response: response, options: spellcheck_options) }
|
|
10
|
+
let(:config) do
|
|
11
|
+
Blacklight::Configuration.new do |config|
|
|
12
|
+
config.spell_max = 5
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
before do
|
|
17
|
+
allow(controller).to receive(:blacklight_config).and_return(config)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'when there are many results' do
|
|
21
|
+
let(:response) { instance_double(Blacklight::Solr::Response, total: 10, spelling: double(words: [1], collation: nil)) }
|
|
22
|
+
|
|
23
|
+
it "does not show suggestions" do
|
|
24
|
+
expect(render.to_html).to be_blank
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context 'when there are only a few results' do
|
|
29
|
+
let(:word_suggestion) { 'yoshida' }
|
|
30
|
+
let(:response) { instance_double(Blacklight::Solr::Response, total: 4, spelling: double(words: [word_suggestion], collation: nil)) }
|
|
31
|
+
|
|
32
|
+
it "shows suggestions" do
|
|
33
|
+
expect(render.to_html).to include(word_suggestion)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context 'and explicit spellcheck options' do
|
|
37
|
+
let(:explicit_option) { 'explicit option' }
|
|
38
|
+
let(:spellcheck_options) { [explicit_option] }
|
|
39
|
+
|
|
40
|
+
it "shows only explicit suggestions" do
|
|
41
|
+
expect(render.to_html).to include(explicit_option)
|
|
42
|
+
expect(render.to_html).not_to include(word_suggestion)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context 'and collations are present' do
|
|
47
|
+
let(:word_suggestion) { 'donotuse' }
|
|
48
|
+
let(:collated_suggestion) { 'yoshida Hajime' }
|
|
49
|
+
let(:response) { instance_double(Blacklight::Solr::Response, total: 4, spelling: double(words: [word_suggestion], collation: collated_suggestion)) }
|
|
50
|
+
|
|
51
|
+
it "shows only collated suggestions" do
|
|
52
|
+
expect(render.to_html).to include(collated_suggestion)
|
|
53
|
+
expect(render.to_html).not_to include(word_suggestion)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context 'when there are no spelling suggestions' do
|
|
59
|
+
let(:response) { instance_double(Blacklight::Solr::Response, total: 4, spelling: double(words: [], collation: nil)) }
|
|
60
|
+
|
|
61
|
+
it "does not show suggestions" do
|
|
62
|
+
expect(render.to_html).to be_blank
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
context 'when spelling is not available' do
|
|
67
|
+
let(:response) { instance_double(Blacklight::Solr::Response, total: 4, spelling: nil) }
|
|
68
|
+
|
|
69
|
+
it "does not show suggestions" do
|
|
70
|
+
expect(render.to_html).to be_blank
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe Blacklight::StartOverButtonComponent, type: :component do
|
|
6
|
+
subject(:render) { render_inline(instance) }
|
|
7
|
+
|
|
8
|
+
let(:instance) { described_class.new }
|
|
9
|
+
let(:blacklight_config) do
|
|
10
|
+
Blacklight::Configuration.new.configure do |config|
|
|
11
|
+
config.view = { list: nil, abc: nil }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
before do
|
|
16
|
+
allow(controller).to receive(:blacklight_config).and_return(blacklight_config)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context 'with the current view type' do
|
|
20
|
+
before do
|
|
21
|
+
controller.params[:view] = 'abc'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'is the catalog path' do
|
|
25
|
+
expect(render.css('a').first['href']).to eq '/catalog?view=abc'
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'when the current view type is the default' do
|
|
30
|
+
before do
|
|
31
|
+
controller.params[:view] = 'list'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'does not include the current view type' do
|
|
35
|
+
expect(render.css('a').first['href']).to eq '/catalog'
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -788,7 +788,7 @@ RSpec.describe CatalogController, api: true do
|
|
|
788
788
|
describe "#add_show_tools_partial", api: false do
|
|
789
789
|
before do
|
|
790
790
|
described_class.blacklight_config.add_show_tools_partial(:like, callback: :perform_like, validator: :validate_like_params)
|
|
791
|
-
allow(controller).to receive(:solr_document_url).and_return('catalog/1')
|
|
791
|
+
allow(controller).to receive(:solr_document_url).and_return('http://test.host/catalog/1')
|
|
792
792
|
allow(controller).to receive(:action_documents).and_return(1)
|
|
793
793
|
Rails.application.routes.draw do
|
|
794
794
|
get 'catalog/like', as: :catalog_like
|
|
@@ -127,4 +127,25 @@ RSpec.describe "Did You Mean" do
|
|
|
127
127
|
click_button 'search'
|
|
128
128
|
expect(page).to have_content("Did you mean")
|
|
129
129
|
end
|
|
130
|
+
|
|
131
|
+
context 'spellcheck collations are enabled' do
|
|
132
|
+
before do
|
|
133
|
+
CatalogController.blacklight_config[:default_solr_params]["spellcheck.collate"] = true
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
after do
|
|
137
|
+
CatalogController.blacklight_config[:default_solr_params].delete("spellcheck.collate")
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it "shows suggestions if there aren't many hits" do
|
|
141
|
+
fill_in "q", with: 'Yoshido Hajime'
|
|
142
|
+
click_button 'search'
|
|
143
|
+
|
|
144
|
+
expect(page).to have_content("Did you mean")
|
|
145
|
+
click_link 'yoshida Hajime'
|
|
146
|
+
within ("#sortAndPerPage") do
|
|
147
|
+
expect(page).to have_content "1 - 2 of 2"
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
130
151
|
end
|
|
@@ -3,13 +3,14 @@
|
|
|
3
3
|
RSpec.describe "Search Results context", js: true do
|
|
4
4
|
it "passes the current search id through" do
|
|
5
5
|
search_for ''
|
|
6
|
-
search_id = Search.last.id.to_s
|
|
7
6
|
click_on 'Pluvial nectar of blessings'
|
|
7
|
+
search_id = Search.last.id.to_s
|
|
8
8
|
expect(page).to have_content "« Previous | 10 of 30 | Next »"
|
|
9
9
|
prev = page.find(".pagination-search-widgets .previous")
|
|
10
10
|
expect(prev['data-context-href']).to eq "/catalog/2003546302/track?counter=9&document_id=2003546302&search_id=#{search_id}"
|
|
11
11
|
|
|
12
12
|
click_on "« Previous"
|
|
13
|
+
expect(page).to have_content "U21.2 .W85 2003"
|
|
13
14
|
|
|
14
15
|
prev = page.find(".pagination-search-widgets .previous")
|
|
15
16
|
expect(prev['data-context-href']).to eq "/catalog/2004310986/track?counter=8&document_id=2004310986&search_id=#{search_id}"
|
|
@@ -48,6 +49,7 @@ RSpec.describe "Search Results context", js: true do
|
|
|
48
49
|
find_all('.index_title a').last.click
|
|
49
50
|
click_on "Next »"
|
|
50
51
|
|
|
52
|
+
expect(page).to have_content "Naqdī barā-yi tamām-i"
|
|
51
53
|
click_on "Back to Search"
|
|
52
54
|
expect(page).to have_content "11 - 20"
|
|
53
55
|
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
RSpec.describe Blacklight::SearchHistoryConstraintsHelperBehavior do
|
|
4
|
+
around { |test| Deprecation.silence(described_class) { test.call } }
|
|
5
|
+
|
|
4
6
|
before(:all) do
|
|
5
7
|
@config = Blacklight::Configuration.new do |config|
|
|
6
8
|
config.add_search_field 'default_search_field', label: 'Default'
|
|
@@ -133,7 +133,7 @@ RSpec.describe Blacklight::UrlHelperBehavior do
|
|
|
133
133
|
|
|
134
134
|
it "calls url_for on the engine scope" do
|
|
135
135
|
expect(my_engine).to receive(:url_for)
|
|
136
|
-
.with(q: "query", f: "facets", controller: "catalog")
|
|
136
|
+
.with({ q: "query", f: "facets", controller: "catalog" })
|
|
137
137
|
.and_return('link-url')
|
|
138
138
|
expect(tag).to match /Back to Search/
|
|
139
139
|
expect(tag).to match /link-url/
|
|
@@ -292,12 +292,12 @@ RSpec.describe Blacklight::UrlHelperBehavior do
|
|
|
292
292
|
let(:document) { SolrDocument.new(id: 1) }
|
|
293
293
|
|
|
294
294
|
it "determines the correct route for the document class" do
|
|
295
|
-
allow(helper.main_app).to receive(:track_test_path).with(id: have_attributes(id: 1)).and_return('x')
|
|
295
|
+
allow(helper.main_app).to receive(:track_test_path).with({ id: have_attributes(id: 1) }).and_return('x')
|
|
296
296
|
expect(helper.session_tracking_path(document)).to eq 'x'
|
|
297
297
|
end
|
|
298
298
|
|
|
299
299
|
it "passes through tracking parameters" do
|
|
300
|
-
allow(helper.main_app).to receive(:track_test_path).with(id: have_attributes(id: 1), x: 1).and_return('x')
|
|
300
|
+
allow(helper.main_app).to receive(:track_test_path).with({ id: have_attributes(id: 1), x: 1 }).and_return('x')
|
|
301
301
|
expect(helper.session_tracking_path(document, x: 1)).to eq 'x'
|
|
302
302
|
end
|
|
303
303
|
|
|
@@ -82,7 +82,7 @@ RSpec.describe BlacklightHelper do
|
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
it "sends parameters" do
|
|
85
|
-
expect(presenter).to receive(:link_rel_alternates).with(unique: true).and_return(result)
|
|
85
|
+
expect(presenter).to receive(:link_rel_alternates).with({ unique: true }).and_return(result)
|
|
86
86
|
expect(helper.render_link_rel_alternates(document, unique: true)).to eq result
|
|
87
87
|
end
|
|
88
88
|
end
|
|
@@ -264,8 +264,13 @@ RSpec.describe BlacklightHelper do
|
|
|
264
264
|
expect(helper.should_show_spellcheck_suggestions?(response)).to be true
|
|
265
265
|
end
|
|
266
266
|
|
|
267
|
+
it "only shows suggestions from collations" do
|
|
268
|
+
response = double(total: 4, spelling: double(words: [], collation: { blah: 1 }))
|
|
269
|
+
expect(helper.should_show_spellcheck_suggestions?(response)).to be true
|
|
270
|
+
end
|
|
271
|
+
|
|
267
272
|
it "shows suggestions only if there are spelling suggestions available" do
|
|
268
|
-
response = double(total: 4, spelling: double(words: []))
|
|
273
|
+
response = double(total: 4, spelling: double(words: [], collation: nil))
|
|
269
274
|
expect(helper.should_show_spellcheck_suggestions?(response)).to be false
|
|
270
275
|
end
|
|
271
276
|
|
|
@@ -298,7 +303,7 @@ RSpec.describe BlacklightHelper do
|
|
|
298
303
|
describe "#render_document_index" do
|
|
299
304
|
it "renders the document index with the current view type" do
|
|
300
305
|
allow(helper).to receive_messages(document_index_view_type: :current_view)
|
|
301
|
-
allow(helper).to receive(:render_document_index_with_view).with(:current_view, [], a: 1, b: 2)
|
|
306
|
+
allow(helper).to receive(:render_document_index_with_view).with(:current_view, [], { a: 1, b: 2 })
|
|
302
307
|
helper.render_document_index [], a: 1, b: 2
|
|
303
308
|
end
|
|
304
309
|
end
|
|
@@ -369,7 +369,7 @@ RSpec.describe CatalogHelper do
|
|
|
369
369
|
end
|
|
370
370
|
|
|
371
371
|
describe "#render_search_to_page_title" do
|
|
372
|
-
subject { helper.render_search_to_page_title(params) }
|
|
372
|
+
subject { helper.render_search_to_page_title(Blacklight::SearchState.new(params, blacklight_config)) }
|
|
373
373
|
|
|
374
374
|
before do
|
|
375
375
|
allow(helper).to receive(:blacklight_config).and_return(blacklight_config)
|
|
@@ -377,7 +377,11 @@ RSpec.describe CatalogHelper do
|
|
|
377
377
|
allow(helper).to receive(:label_for_search_field).with(nil).and_return('')
|
|
378
378
|
end
|
|
379
379
|
|
|
380
|
-
let(:blacklight_config)
|
|
380
|
+
let(:blacklight_config) do
|
|
381
|
+
Blacklight::Configuration.new.tap do |config|
|
|
382
|
+
config.add_facet_field 'format'
|
|
383
|
+
end
|
|
384
|
+
end
|
|
381
385
|
|
|
382
386
|
context 'when the f param is an array' do
|
|
383
387
|
let(:params) { ActionController::Parameters.new(q: 'foobar', f: { format: ["Book"] }) }
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe Blacklight::Engine do
|
|
4
|
+
[:bookmarks_http_method, :email_regexp, :facet_missing_param, :sms_mappings].each do |dep_key|
|
|
5
|
+
describe "config.#{dep_key}" do
|
|
6
|
+
subject { described_class.config }
|
|
7
|
+
|
|
8
|
+
let(:unlikely_value) { 'unlikely value' }
|
|
9
|
+
|
|
10
|
+
it 'is deprecated' do
|
|
11
|
+
allow(Deprecation).to receive(:warn)
|
|
12
|
+
subject.send(dep_key)
|
|
13
|
+
expect(Deprecation).to have_received(:warn)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'delegates to config.blacklight' do
|
|
17
|
+
allow(subject.blacklight).to receive(dep_key).and_return(unlikely_value)
|
|
18
|
+
expect(subject.send(dep_key)).to eql(unlikely_value)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "config.#{dep_key}=" do
|
|
23
|
+
subject { described_class.config }
|
|
24
|
+
|
|
25
|
+
let(:unlikely_value) { 'unlikely value' }
|
|
26
|
+
|
|
27
|
+
it 'is deprecated' do
|
|
28
|
+
allow(Deprecation).to receive(:warn)
|
|
29
|
+
allow(subject.blacklight).to receive(:"#{dep_key}=").with(unlikely_value)
|
|
30
|
+
subject.send(:"#{dep_key}=", unlikely_value)
|
|
31
|
+
expect(Deprecation).to have_received(:warn)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'delegates to config.blacklight' do
|
|
35
|
+
allow(subject.blacklight).to receive(:"#{dep_key}=").with(unlikely_value)
|
|
36
|
+
subject.send(:"#{dep_key}=", unlikely_value)
|
|
37
|
+
expect(subject.blacklight).to have_received(:"#{dep_key}=").with(unlikely_value)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|