blacklight 7.18.1 → 7.20.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.env +1 -1
- data/.github/workflows/ruby.yml +19 -1
- data/.rubocop.yml +4 -0
- data/README.md +1 -1
- data/VERSION +1 -1
- data/app/assets/javascripts/blacklight/blacklight.js +8 -4
- data/app/assets/stylesheets/blacklight/_balanced_list.scss +2 -2
- data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +1 -1
- data/app/assets/stylesheets/blacklight/_constraints.scss +8 -5
- data/app/assets/stylesheets/blacklight/_controls.scss +9 -1
- data/app/assets/stylesheets/blacklight/_facets.scss +5 -3
- data/app/assets/stylesheets/blacklight/_header.scss +6 -1
- data/app/assets/stylesheets/blacklight/_pagination.scss +1 -1
- data/app/assets/stylesheets/blacklight/_twitter_typeahead.scss +1 -0
- data/app/components/blacklight/constraint_layout_component.html.erb +1 -1
- data/app/components/blacklight/constraints_component.html.erb +2 -2
- data/app/components/blacklight/constraints_component.rb +6 -2
- data/app/components/blacklight/content_areas_shim.rb +2 -1
- data/app/components/blacklight/document_component.rb +10 -10
- data/app/components/blacklight/facet_field_component.html.erb +3 -1
- data/app/components/blacklight/facet_field_no_layout_component.rb +1 -1
- data/app/components/blacklight/facet_item_component.rb +4 -4
- data/app/components/blacklight/facet_item_pivot_component.rb +2 -2
- data/app/components/blacklight/metadata_field_layout_component.rb +2 -2
- data/app/components/blacklight/response/facet_group_component.html.erb +2 -0
- data/app/components/blacklight/response/pagination_component.html.erb +1 -1
- data/app/components/blacklight/response/view_type_component.html.erb +1 -1
- data/app/components/blacklight/search_bar_component.html.erb +3 -3
- data/app/components/blacklight/system/dropdown_component.rb +1 -1
- data/app/components/blacklight/system/flash_message_component.html.erb +1 -1
- data/app/components/blacklight/system/modal_component.html.erb +1 -1
- data/app/controllers/concerns/blacklight/bookmarks.rb +0 -3
- data/app/controllers/concerns/blacklight/catalog.rb +3 -0
- data/app/controllers/concerns/blacklight/controller.rb +9 -5
- data/app/controllers/concerns/blacklight/search_context.rb +1 -1
- data/app/helpers/blacklight/catalog_helper_behavior.rb +1 -3
- data/app/helpers/blacklight/component_helper_behavior.rb +1 -1
- data/app/helpers/blacklight/render_partials_helper_behavior.rb +5 -1
- data/app/javascript/blacklight/core.js +5 -1
- data/app/javascript/blacklight/modal.js +1 -1
- data/app/javascript/blacklight/search_context.js +5 -2
- data/app/views/blacklight/nav/_bookmark.html.erb +1 -1
- data/app/views/bookmarks/index.html.erb +1 -1
- data/app/views/catalog/_constraints.html.erb +2 -2
- data/app/views/catalog/_document.html.erb +4 -3
- data/app/views/catalog/_document_list.html.erb +3 -2
- data/app/views/catalog/_home_text.html.erb +3 -3
- data/app/views/catalog/_paginate_compact.html.erb +1 -0
- data/app/views/catalog/_per_page_widget.html.erb +1 -1
- data/app/views/catalog/_search_results.html.erb +2 -2
- data/app/views/search_history/index.html.erb +1 -1
- data/app/views/shared/_header_navbar.html.erb +3 -3
- data/blacklight.gemspec +4 -2
- data/config/locales/blacklight.ar.yml +2 -2
- data/config/locales/blacklight.ca.yml +2 -2
- data/config/locales/blacklight.de.yml +6 -4
- data/config/locales/blacklight.en.yml +8 -4
- data/config/locales/blacklight.es.yml +5 -3
- data/config/locales/blacklight.fr.yml +5 -3
- data/config/locales/blacklight.hu.yml +2 -2
- data/config/locales/blacklight.it.yml +5 -3
- data/config/locales/blacklight.nl.yml +2 -2
- data/config/locales/blacklight.pt-BR.yml +1 -1
- data/config/locales/blacklight.sq.yml +2 -2
- data/config/locales/blacklight.zh.yml +2 -2
- data/lib/blacklight/configuration/view_config.rb +3 -1
- data/lib/blacklight/configuration.rb +7 -1
- data/lib/blacklight/nested_open_struct_with_hash_access.rb +14 -11
- data/lib/blacklight/open_struct_with_hash_access.rb +1 -1
- data/lib/blacklight/search_builder.rb +1 -1
- data/lib/blacklight/search_state/filter_field.rb +9 -0
- data/lib/blacklight/solr/request.rb +10 -7
- data/lib/blacklight/solr/response/group_response.rb +3 -2
- data/lib/blacklight/solr/response/pagination_methods.rb +1 -1
- data/lib/blacklight/solr/search_builder_behavior.rb +38 -18
- data/lib/blacklight.rb +5 -1
- data/lib/generators/blacklight/assets_generator.rb +4 -2
- data/lib/generators/blacklight/install_generator.rb +4 -1
- data/lib/generators/blacklight/user_generator.rb +1 -1
- data/package.json +2 -2
- data/spec/components/blacklight/constraint_layout_component_spec.rb +3 -7
- data/spec/components/blacklight/facet_field_checkboxes_component_spec.rb +3 -7
- data/spec/components/blacklight/facet_field_list_component_spec.rb +3 -7
- data/spec/components/blacklight/facet_item_component_spec.rb +8 -8
- data/spec/components/blacklight/facet_item_pivot_component_spec.rb +3 -7
- data/spec/components/blacklight/hidden_search_state_component_spec.rb +7 -8
- data/spec/components/blacklight/metadata_field_component_spec.rb +4 -8
- data/spec/features/axe_spec.rb +34 -0
- data/spec/features/facet_missing_spec.rb +59 -0
- data/spec/features/facets_spec.rb +3 -3
- data/spec/helpers/blacklight/configuration_helper_behavior_spec.rb +3 -3
- data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +2 -2
- data/spec/helpers/blacklight_helper_spec.rb +18 -0
- data/spec/lib/blacklight/nested_open_struct_with_hash_access_spec.rb +23 -1
- data/spec/lib/blacklight/search_state/filter_field_spec.rb +27 -0
- data/spec/models/blacklight/configuration_spec.rb +10 -0
- data/spec/models/blacklight/solr/request_spec.rb +0 -1
- data/spec/models/blacklight/solr/response/group_response_spec.rb +3 -2
- data/spec/models/blacklight/solr/search_builder_spec.rb +27 -1
- data/spec/spec_helper.rb +16 -9
- data/spec/support/view_component_capybara_test_helpers.rb +8 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +0 -3
- data/spec/views/catalog/_document.html.erb_spec.rb +9 -0
- data/spec/views/catalog/_document_list.html.erb_spec.rb +1 -1
- data/spec/views/catalog/_facet_layout.html.erb_spec.rb +2 -2
- metadata +45 -11
@@ -45,7 +45,7 @@ module Blacklight
|
|
45
45
|
##
|
46
46
|
# Update the :q (query) parameter
|
47
47
|
def where(conditions)
|
48
|
-
Deprecation.warn("SearchBuilder#where must be called with a hash, received #{conditions.inspect}.") unless conditions.is_a? Hash
|
48
|
+
Deprecation.warn(Blacklight::SearchBuilder, "SearchBuilder#where must be called with a hash, received #{conditions.inspect}.") unless conditions.is_a? Hash
|
49
49
|
params_will_change!
|
50
50
|
@search_state = @search_state.reset(@search_state.params.merge(q: conditions))
|
51
51
|
@blacklight_params = @search_state.params.dup
|
@@ -83,10 +83,19 @@ module Blacklight
|
|
83
83
|
Deprecation.warn(self, 'Normalizing parameters in FilterField#remove is deprecated')
|
84
84
|
collection = collection.values
|
85
85
|
end
|
86
|
+
|
86
87
|
params[param][key] = collection - Array(value)
|
87
88
|
params[param].delete(key) if params[param][key].empty?
|
88
89
|
params.delete(param) if params[param].empty?
|
89
90
|
|
91
|
+
# Handle missing field queries.
|
92
|
+
missing = I18n.t("blacklight.search.facets.missing")
|
93
|
+
if (item.respond_to?(:fq) && item.fq == "-#{key}:[* TO *]") ||
|
94
|
+
item == missing
|
95
|
+
params[param].delete("-#{key}:")
|
96
|
+
params[param].delete(key) if params[param][key] == [""]
|
97
|
+
end
|
98
|
+
|
90
99
|
new_state.reset(params)
|
91
100
|
end
|
92
101
|
|
@@ -2,7 +2,10 @@
|
|
2
2
|
class Blacklight::Solr::InvalidParameter < ArgumentError; end
|
3
3
|
|
4
4
|
class Blacklight::Solr::Request < ActiveSupport::HashWithIndifferentAccess
|
5
|
+
# @deprecated
|
5
6
|
SINGULAR_KEYS = %w(facet fl q qt rows start spellcheck spellcheck.q sort per_page wt hl group defType)
|
7
|
+
|
8
|
+
# @deprecated
|
6
9
|
ARRAY_KEYS = %w(facet.field facet.query facet.pivot fq hl.fl)
|
7
10
|
|
8
11
|
def initialize(constructor = {})
|
@@ -12,9 +15,6 @@ class Blacklight::Solr::Request < ActiveSupport::HashWithIndifferentAccess
|
|
12
15
|
else
|
13
16
|
super(constructor)
|
14
17
|
end
|
15
|
-
ARRAY_KEYS.each do |key|
|
16
|
-
self[key] ||= []
|
17
|
-
end
|
18
18
|
end
|
19
19
|
|
20
20
|
def append_query(query)
|
@@ -49,26 +49,29 @@ class Blacklight::Solr::Request < ActiveSupport::HashWithIndifferentAccess
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def append_filter_query(query)
|
52
|
+
self['fq'] ||= []
|
53
|
+
self['fq'] = Array(self['fq']) if self['fq'].is_a? String
|
54
|
+
|
52
55
|
self['fq'] << query
|
53
56
|
end
|
54
57
|
|
55
58
|
def append_facet_fields(values)
|
59
|
+
self['facet.field'] ||= []
|
56
60
|
self['facet.field'] += Array(values)
|
57
61
|
end
|
58
62
|
|
59
63
|
def append_facet_query(values)
|
64
|
+
self['facet.query'] ||= []
|
60
65
|
self['facet.query'] += Array(values)
|
61
66
|
end
|
62
67
|
|
63
68
|
def append_facet_pivot(query)
|
69
|
+
self['facet.pivot'] ||= []
|
64
70
|
self['facet.pivot'] << query
|
65
71
|
end
|
66
72
|
|
67
73
|
def append_highlight_field(query)
|
74
|
+
self['hl.fl'] ||= []
|
68
75
|
self['hl.fl'] << query
|
69
76
|
end
|
70
|
-
|
71
|
-
def to_hash
|
72
|
-
reject { |key, value| ARRAY_KEYS.include?(key) && value.blank? }
|
73
|
-
end
|
74
77
|
end
|
@@ -45,8 +45,9 @@ class Blacklight::Solr::Response::GroupResponse
|
|
45
45
|
def entry_name(options)
|
46
46
|
I18n.t(
|
47
47
|
"blacklight.entry_name.grouped.#{key}",
|
48
|
-
default: :'blacklight.entry_name.grouped.default'
|
49
|
-
|
48
|
+
default: :'blacklight.entry_name.grouped.default',
|
49
|
+
count: options[:count]
|
50
|
+
)
|
50
51
|
end
|
51
52
|
|
52
53
|
def method_missing meth, *args, &block
|
@@ -24,6 +24,6 @@ module Blacklight::Solr::Response::PaginationMethods
|
|
24
24
|
##
|
25
25
|
# Meant to have the same signature as Kaminari::PaginatableArray#entry_name
|
26
26
|
def entry_name(options)
|
27
|
-
I18n.t('blacklight.entry_name.default'
|
27
|
+
I18n.t('blacklight.entry_name.default', count: options[:count])
|
28
28
|
end
|
29
29
|
end
|
@@ -5,10 +5,12 @@ module Blacklight::Solr
|
|
5
5
|
|
6
6
|
included do
|
7
7
|
self.default_processor_chain = [
|
8
|
-
:default_solr_parameters, :
|
8
|
+
:default_solr_parameters, :add_search_field_default_parameters,
|
9
|
+
:add_query_to_solr, :add_facet_fq_to_solr,
|
9
10
|
:add_facetting_to_solr, :add_solr_fields_to_query, :add_paging_to_solr,
|
10
11
|
:add_sorting_to_solr, :add_group_config_to_solr,
|
11
12
|
:add_facet_paging_to_solr, :add_adv_search_clauses,
|
13
|
+
:add_missing_field_query,
|
12
14
|
:add_additional_filters
|
13
15
|
]
|
14
16
|
end
|
@@ -18,22 +20,17 @@ module Blacklight::Solr
|
|
18
20
|
# merge to dup values, to avoid later mutating the original by mistake.
|
19
21
|
def default_solr_parameters(solr_parameters)
|
20
22
|
blacklight_config.default_solr_params.each do |key, value|
|
21
|
-
solr_parameters[key]
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
solr_parameters[key] ||= if value.respond_to? :deep_dup
|
24
|
+
value.deep_dup
|
25
|
+
elsif value.respond_to?(:dup) && value.duplicable?
|
26
|
+
value.dup
|
27
|
+
else
|
28
|
+
value
|
29
|
+
end
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
31
|
-
|
32
|
-
# Take the user-entered query, and put it in the solr params,
|
33
|
-
# including config's "search field" params for current search field.
|
34
|
-
# also include setting spellcheck.q.
|
35
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
36
|
-
def add_query_to_solr(solr_parameters)
|
33
|
+
def add_search_field_default_parameters(solr_parameters)
|
37
34
|
###
|
38
35
|
# legacy behavior of user param :qt is passed through, but over-ridden
|
39
36
|
# by actual search field config if present. We might want to remove
|
@@ -47,10 +44,21 @@ module Blacklight::Solr
|
|
47
44
|
###
|
48
45
|
# Merge in search field configured values, if present, over-writing general
|
49
46
|
# defaults
|
50
|
-
|
51
47
|
if search_field
|
52
48
|
solr_parameters[:qt] = search_field.qt if search_field.qt
|
53
|
-
|
49
|
+
|
50
|
+
solr_parameters.deep_merge!(search_field.solr_parameters) if search_field.solr_parameters
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Take the user-entered query, and put it in the solr params,
|
56
|
+
# including config's "search field" params for current search field.
|
57
|
+
# also include setting spellcheck.q.
|
58
|
+
def add_query_to_solr(solr_parameters)
|
59
|
+
unless processor_chain.include?(:add_search_field_default_parameters)
|
60
|
+
Deprecation.warn(Blacklight::Solr::SearchBuilderBehavior, 'Please include :add_search_field_default_parameters in your process chain')
|
61
|
+
add_search_field_default_parameters(solr_parameters)
|
54
62
|
end
|
55
63
|
|
56
64
|
##
|
@@ -66,14 +74,26 @@ module Blacklight::Solr
|
|
66
74
|
add_search_field_with_local_parameters(solr_parameters)
|
67
75
|
elsif search_state.query_param.is_a? Hash
|
68
76
|
if search_state.query_param == @additional_filters && !processor_chain.include?(:add_additional_filters)
|
69
|
-
Deprecation.warn('Expecting to see the processor step add_additional_filters; falling back to legacy query handling')
|
77
|
+
Deprecation.warn(Blacklight::Solr::SearchBuilderBehavior, 'Expecting to see the processor step add_additional_filters; falling back to legacy query handling')
|
70
78
|
add_additional_filters(solr_parameters, search_state.query_param)
|
71
79
|
end
|
72
80
|
elsif search_state.query_param
|
73
81
|
solr_parameters.append_query search_state.query_param
|
74
82
|
end
|
75
83
|
end
|
76
|
-
|
84
|
+
|
85
|
+
##
|
86
|
+
# Build and append a missing field query.
|
87
|
+
##
|
88
|
+
def add_missing_field_query(solr_parameters)
|
89
|
+
return unless solr_parameters["facet.missing"]
|
90
|
+
|
91
|
+
solr_parameters[:fq] = [] if solr_parameters[:fq].blank?
|
92
|
+
|
93
|
+
solr_parameters[:fq].append(*(blacklight_params["f"] || [])
|
94
|
+
.select { |f| f.match(/^-/) }
|
95
|
+
.map { |k, _v| "#{k}[* TO *]" })
|
96
|
+
end
|
77
97
|
|
78
98
|
def add_additional_filters(solr_parameters, additional_filters = nil)
|
79
99
|
q = additional_filters || @additional_filters
|
data/lib/blacklight.rb
CHANGED
@@ -96,7 +96,11 @@ module Blacklight
|
|
96
96
|
end
|
97
97
|
|
98
98
|
begin
|
99
|
-
@blacklight_yml =
|
99
|
+
@blacklight_yml = if RUBY_VERSION > '2.6'
|
100
|
+
YAML.safe_load(blacklight_erb, aliases: true)
|
101
|
+
else
|
102
|
+
YAML.safe_load(blacklight_erb, [], [], true)
|
103
|
+
end
|
100
104
|
rescue => e
|
101
105
|
raise("#{blacklight_config_file} was found, but could not be parsed.\n#{e.inspect}")
|
102
106
|
end
|
@@ -3,9 +3,11 @@ module Blacklight
|
|
3
3
|
class Assets < Rails::Generators::Base
|
4
4
|
source_root File.expand_path('../templates', __FILE__)
|
5
5
|
|
6
|
+
class_option :'bootstrap-version', type: :string, default: ENV.fetch('BOOTSTRAP_VERSION', '~> 4.0'), desc: "Set the generated app's bootstrap version"
|
7
|
+
|
6
8
|
# This could be skipped if you want to use webpacker
|
7
9
|
def add_javascript_dependencies
|
8
|
-
gem 'bootstrap', '
|
10
|
+
gem 'bootstrap', options[:'bootstrap-version']
|
9
11
|
gem 'twitter-typeahead-rails', '0.11.1.pre.corejavascript'
|
10
12
|
end
|
11
13
|
|
@@ -15,7 +17,7 @@ module Blacklight
|
|
15
17
|
|
16
18
|
create_file 'app/assets/javascripts/application.js' do
|
17
19
|
<<~CONTENT
|
18
|
-
//= require
|
20
|
+
//= require jquery3
|
19
21
|
//= require rails-ujs
|
20
22
|
//= require turbolinks
|
21
23
|
CONTENT
|
@@ -10,6 +10,7 @@ module Blacklight
|
|
10
10
|
|
11
11
|
class_option :devise, type: :boolean, default: false, aliases: "-d", desc: "Use Devise as authentication logic."
|
12
12
|
class_option :marc, type: :boolean, default: false, aliases: "-m", desc: "Generate MARC-based demo."
|
13
|
+
class_option :'bootstrap-version', type: :string, default: nil, desc: "Set the generated app's bootstrap version"
|
13
14
|
class_option :'skip-assets', type: :boolean, default: !defined?(Sprockets), desc: "Skip generating javascript and css assets into the application"
|
14
15
|
class_option :'skip-solr', type: :boolean, default: false, desc: "Skip generating solr configurations."
|
15
16
|
|
@@ -33,7 +34,9 @@ module Blacklight
|
|
33
34
|
# Call external generator in AssetsGenerator, so we can
|
34
35
|
# leave that callable seperately too.
|
35
36
|
def copy_public_assets
|
36
|
-
|
37
|
+
generated_options = "--bootstrap-version #{options[:'bootstrap-version']}" if options[:'bootstrap-version']
|
38
|
+
|
39
|
+
generate "blacklight:assets", generated_options unless options[:'skip-assets']
|
37
40
|
end
|
38
41
|
|
39
42
|
def bundle_install
|
data/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "blacklight-frontend",
|
3
|
-
"version": "7.
|
3
|
+
"version": "7.20.0",
|
4
4
|
"description": "[![Build Status](https://travis-ci.com/projectblacklight/blacklight.png?branch=master)](https://travis-ci.com/projectblacklight/blacklight) [![Gem Version](https://badge.fury.io/rb/blacklight.png)](http://badge.fury.io/rb/blacklight) [![Coverage Status](https://coveralls.io/repos/github/projectblacklight/blacklight/badge.svg?branch=master)](https://coveralls.io/github/projectblacklight/blacklight?branch=master)",
|
5
5
|
"main": "app/assets/javascripts/blacklight",
|
6
6
|
"scripts": {
|
@@ -27,7 +27,7 @@
|
|
27
27
|
},
|
28
28
|
"dependencies": {
|
29
29
|
"bloodhound-js": "^1.2.3",
|
30
|
-
"bootstrap": "
|
30
|
+
"bootstrap": ">=4.3.1 <6.0.0",
|
31
31
|
"jquery": "^3.5.1",
|
32
32
|
"typeahead.js": "^0.11.1"
|
33
33
|
}
|
@@ -3,12 +3,8 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe Blacklight::ConstraintLayoutComponent, type: :component do
|
6
|
-
subject(:
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
let(:rendered) do
|
11
|
-
Capybara::Node::Simple.new(render)
|
6
|
+
subject(:rendered) do
|
7
|
+
render_inline_to_capybara_node(described_class.new(**params))
|
12
8
|
end
|
13
9
|
|
14
10
|
describe "for simple display" do
|
@@ -39,7 +35,7 @@ RSpec.describe Blacklight::ConstraintLayoutComponent, type: :component do
|
|
39
35
|
|
40
36
|
it "has an accessible remove label" do
|
41
37
|
expect(rendered).to have_selector(".remove") do |s|
|
42
|
-
expect(s).to have_selector('.
|
38
|
+
expect(s).to have_selector('.visually-hidden', text: 'Remove constraint my label: my value')
|
43
39
|
end
|
44
40
|
end
|
45
41
|
end
|
@@ -3,12 +3,8 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe Blacklight::FacetFieldCheckboxesComponent, type: :component do
|
6
|
-
subject(:
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
let(:rendered) do
|
11
|
-
Capybara::Node::Simple.new(render)
|
6
|
+
subject(:rendered) do
|
7
|
+
render_inline_to_capybara_node(described_class.new(facet_field: facet_field))
|
12
8
|
end
|
13
9
|
|
14
10
|
let(:facet_field) do
|
@@ -40,7 +36,7 @@ RSpec.describe Blacklight::FacetFieldCheckboxesComponent, type: :component do
|
|
40
36
|
it 'renders a collapsible card' do
|
41
37
|
expect(rendered).to have_selector '.card'
|
42
38
|
expect(rendered).to have_button 'Field'
|
43
|
-
expect(rendered).to have_selector 'button[data-target="#facet-field"]'
|
39
|
+
expect(rendered).to have_selector 'button[data-bs-target="#facet-field"]'
|
44
40
|
expect(rendered).to have_selector '#facet-field.collapse.show'
|
45
41
|
end
|
46
42
|
|
@@ -3,12 +3,8 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
|
6
|
-
subject(:
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
let(:rendered) do
|
11
|
-
Capybara::Node::Simple.new(render)
|
6
|
+
subject(:rendered) do
|
7
|
+
render_inline_to_capybara_node(described_class.new(facet_field: facet_field))
|
12
8
|
end
|
13
9
|
|
14
10
|
let(:facet_field) do
|
@@ -35,7 +31,7 @@ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
|
|
35
31
|
it 'renders a collapsible card' do
|
36
32
|
expect(rendered).to have_selector '.card'
|
37
33
|
expect(rendered).to have_button 'Field'
|
38
|
-
expect(rendered).to have_selector 'button[data-target="#facet-field"]'
|
34
|
+
expect(rendered).to have_selector 'button[data-bs-target="#facet-field"]'
|
39
35
|
expect(rendered).to have_selector '#facet-field.collapse.show'
|
40
36
|
end
|
41
37
|
|
@@ -3,12 +3,8 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe Blacklight::FacetItemComponent, type: :component do
|
6
|
-
subject(:
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
let(:rendered) do
|
11
|
-
Capybara::Node::Simple.new(render)
|
6
|
+
subject(:rendered) do
|
7
|
+
render_inline_to_capybara_node(described_class.new(facet_item: facet_item))
|
12
8
|
end
|
13
9
|
|
14
10
|
let(:facet_item) do
|
@@ -24,7 +20,9 @@ RSpec.describe Blacklight::FacetItemComponent, type: :component do
|
|
24
20
|
|
25
21
|
it 'links to the facet and shows the number of hits' do
|
26
22
|
expect(rendered).to have_selector 'li'
|
27
|
-
expect(rendered).to have_link 'x', href: '/catalog?f=x'
|
23
|
+
expect(rendered).to have_link 'x', href: '/catalog?f=x' do |link|
|
24
|
+
link['rel'] == 'nofollow'
|
25
|
+
end
|
28
26
|
expect(rendered).to have_selector '.facet-count', text: '10'
|
29
27
|
end
|
30
28
|
|
@@ -43,7 +41,9 @@ RSpec.describe Blacklight::FacetItemComponent, type: :component do
|
|
43
41
|
it 'links to the facet and shows the number of hits' do
|
44
42
|
expect(rendered).to have_selector 'li'
|
45
43
|
expect(rendered).to have_selector '.selected', text: 'x'
|
46
|
-
expect(rendered).to have_link '[remove]', href: '/catalog'
|
44
|
+
expect(rendered).to have_link '[remove]', href: '/catalog' do |link|
|
45
|
+
link['rel'] == 'nofollow'
|
46
|
+
end
|
47
47
|
expect(rendered).to have_selector '.selected.facet-count', text: '10'
|
48
48
|
end
|
49
49
|
end
|
@@ -3,12 +3,8 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe Blacklight::FacetItemPivotComponent, type: :component do
|
6
|
-
subject(:
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
let(:rendered) do
|
11
|
-
Capybara::Node::Simple.new(render)
|
6
|
+
subject(:rendered) do
|
7
|
+
render_inline_to_capybara_node(described_class.new(facet_item: facet_item))
|
12
8
|
end
|
13
9
|
|
14
10
|
let(:search_state) do
|
@@ -31,7 +27,7 @@ RSpec.describe Blacklight::FacetItemPivotComponent, type: :component do
|
|
31
27
|
|
32
28
|
it 'links to the facet and shows the number of hits' do
|
33
29
|
expect(rendered).to have_selector 'li'
|
34
|
-
expect(rendered).to have_link 'x', href: '/catalog?f
|
30
|
+
expect(rendered).to have_link 'x', href: '/catalog?f%5Bz%5D=x'
|
35
31
|
expect(rendered).to have_selector '.facet-count', text: '10'
|
36
32
|
end
|
37
33
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe Blacklight::HiddenSearchStateComponent, type: :component do
|
4
|
-
subject(:
|
4
|
+
subject(:rendered) { render_inline_to_capybara_node(instance) }
|
5
5
|
|
6
6
|
let(:params) do
|
7
7
|
{ q: "query",
|
@@ -11,14 +11,13 @@ RSpec.describe Blacklight::HiddenSearchStateComponent, type: :component do
|
|
11
11
|
f: { field1: %w[a b], field2: ["z"] } }
|
12
12
|
end
|
13
13
|
let(:instance) { described_class.new(params: params) }
|
14
|
-
let(:generated) { Capybara::Node::Simple.new("<div>#{render.to_html}</div>") }
|
15
14
|
|
16
15
|
it "converts a hash with nested complex data to Rails-style hidden form fields" do
|
17
|
-
expect(
|
18
|
-
expect(
|
19
|
-
expect(
|
20
|
-
expect(
|
21
|
-
expect(
|
22
|
-
expect(
|
16
|
+
expect(rendered).to have_selector("input[type='hidden'][name='q'][value='query']", visible: :hidden)
|
17
|
+
expect(rendered).to have_selector("input[type='hidden'][name='per_page'][value='10']", visible: :hidden)
|
18
|
+
expect(rendered).to have_selector("input[type='hidden'][name='extra_arbitrary_key'][value='arbitrary_value']", visible: :hidden)
|
19
|
+
expect(rendered).to have_selector("input[type='hidden'][name='f[field2][]'][value='z']", visible: :hidden)
|
20
|
+
expect(rendered).to have_selector("input[type='hidden'][name='f[field1][]'][value='a']", visible: :hidden)
|
21
|
+
expect(rendered).to have_selector("input[type='hidden'][name='f[field1][]'][value='b']", visible: :hidden)
|
23
22
|
end
|
24
23
|
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe Blacklight::MetadataFieldComponent, type: :component do
|
6
|
-
subject(:
|
7
|
-
|
6
|
+
subject(:rendered) do
|
7
|
+
render_inline_to_capybara_node(described_class.new(field: field))
|
8
8
|
end
|
9
9
|
|
10
10
|
let(:view_context) { controller.view_context }
|
@@ -15,10 +15,6 @@ RSpec.describe Blacklight::MetadataFieldComponent, type: :component do
|
|
15
15
|
Blacklight::FieldPresenter.new(view_context, document, field_config)
|
16
16
|
end
|
17
17
|
|
18
|
-
let(:rendered) do
|
19
|
-
Capybara::Node::Simple.new(render)
|
20
|
-
end
|
21
|
-
|
22
18
|
it 'renders the field label' do
|
23
19
|
expect(rendered).to have_selector 'dt.blacklight-field', text: 'Field label'
|
24
20
|
end
|
@@ -28,8 +24,8 @@ RSpec.describe Blacklight::MetadataFieldComponent, type: :component do
|
|
28
24
|
end
|
29
25
|
|
30
26
|
context 'from a show view' do
|
31
|
-
subject(:
|
32
|
-
|
27
|
+
subject(:rendered) do
|
28
|
+
render_inline_to_capybara_node(described_class.new(field: field, show: true))
|
33
29
|
end
|
34
30
|
|
35
31
|
it 'renders the right field label' do
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe 'Accessibility testing', api: false, js: true do
|
4
|
+
xit 'validates the home page' do
|
5
|
+
visit root_path
|
6
|
+
expect(page).to be_accessible
|
7
|
+
end
|
8
|
+
|
9
|
+
xit 'validates the catalog page' do
|
10
|
+
visit root_path
|
11
|
+
fill_in "q", with: 'history'
|
12
|
+
click_button 'search'
|
13
|
+
|
14
|
+
# aria-allowed-role doesn't like nav[role="region"]
|
15
|
+
expect(page).to be_accessible(skipping: ['aria-allowed-role'])
|
16
|
+
|
17
|
+
within '.card.blacklight-language_ssim' do
|
18
|
+
click_button 'Language'
|
19
|
+
click_link "Tibetan"
|
20
|
+
end
|
21
|
+
|
22
|
+
expect(page).to be_accessible(skipping: ['aria-allowed-role'])
|
23
|
+
end
|
24
|
+
|
25
|
+
xit 'validates the single results page' do
|
26
|
+
visit solr_document_path('2007020969')
|
27
|
+
expect(page).to be_accessible
|
28
|
+
end
|
29
|
+
|
30
|
+
def be_accessible(skipping: [])
|
31
|
+
# typeahead does funny things with the search bar
|
32
|
+
be_axe_clean.excluding('.tt-hint').skipping(skipping + [('color-contrast' if Bootstrap::VERSION < '5')])
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe "Facet missing" do
|
4
|
+
before do
|
5
|
+
CatalogController.blacklight_config[:default_solr_params]["facet.missing"] = true
|
6
|
+
end
|
7
|
+
|
8
|
+
after do
|
9
|
+
CatalogController.blacklight_config[:default_solr_params].delete("facet.missing")
|
10
|
+
end
|
11
|
+
|
12
|
+
context "selecting missing field in facets" do
|
13
|
+
it "adds facet missing query and constraints" do
|
14
|
+
visit root_path
|
15
|
+
|
16
|
+
within "#facet-subject_geo_ssim" do
|
17
|
+
click_link "[Missing]"
|
18
|
+
end
|
19
|
+
|
20
|
+
within "#facet-subject_geo_ssim" do
|
21
|
+
expect(page).to have_selector("span.selected", text: "[Missing")
|
22
|
+
expect(page).to have_selector("span.facet-count.selected", text: "13")
|
23
|
+
end
|
24
|
+
|
25
|
+
within "#sortAndPerPage" do
|
26
|
+
expect(page).to have_content "1 - 10 of 13"
|
27
|
+
end
|
28
|
+
|
29
|
+
expect(page).to have_css(".constraint-value", text: "Region")
|
30
|
+
expect(page).to have_css(".constraint-value", text: "[Missing]")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "unselecting the facet missing facet" do
|
35
|
+
it "unselects the missig field facet" do
|
36
|
+
visit root_path + "?f[-subject_geo_ssim:[* TO *]][]=&f[subject_geo_ssim][]="
|
37
|
+
|
38
|
+
within "#facet-subject_geo_ssim" do
|
39
|
+
click_link "remove"
|
40
|
+
end
|
41
|
+
|
42
|
+
expect(page).not_to have_link "remove"
|
43
|
+
expect(page).to have_content("Welcome!")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "unselecting the facet missing constraint" do
|
48
|
+
it "unselects the missig field facet" do
|
49
|
+
visit root_path + "?f[-subject_geo_ssim:[* TO *]][]=&f[subject_geo_ssim][]="
|
50
|
+
|
51
|
+
within ".filter-subject_geo_ssim" do
|
52
|
+
click_link "Remove constraint Region: [Missing]"
|
53
|
+
end
|
54
|
+
|
55
|
+
expect(page).not_to have_link "remove"
|
56
|
+
expect(page).to have_content("Welcome!")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -69,7 +69,7 @@ RSpec.describe "Facets" do
|
|
69
69
|
page.find('h3.facet-field-heading button', text: 'Pivot Field').click
|
70
70
|
|
71
71
|
within '#facet-example_pivot_field' do
|
72
|
-
expect(page).to have_css('.facet-leaf-node', text: "Book
|
72
|
+
expect(page).to have_css('.facet-leaf-node', text: "Book 30")
|
73
73
|
expect(page).not_to have_css('.facet-select', text: 'Tibetan')
|
74
74
|
page.find('.facet-toggle-handle').click
|
75
75
|
click_link 'Tibetan'
|
@@ -84,13 +84,13 @@ RSpec.describe "Facets" do
|
|
84
84
|
pending 'Capybara::NotSupportedByDriverError: Capybara::Driver::Base#evaluate_script'
|
85
85
|
visit root_path
|
86
86
|
page.find('h3.facet-field-heading button', text: 'Format').click
|
87
|
-
focused_element_data_target = page.evaluate_script("document.activeElement")['data-target']
|
87
|
+
focused_element_data_target = page.evaluate_script("document.activeElement")['data-bs-target']
|
88
88
|
expect(focused_element_data_target).to eq '#facet-format'
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
92
|
describe '"More" links' do
|
93
|
-
it 'has default more link with
|
93
|
+
it 'has default more link with visually-hidden text' do
|
94
94
|
visit root_path
|
95
95
|
within '#facet-language_ssim' do
|
96
96
|
expect(page).to have_css 'div.more_facets', text: 'more Language'
|
@@ -194,9 +194,9 @@ RSpec.describe Blacklight::ConfigurationHelperBehavior do
|
|
194
194
|
describe "#per_page_options_for_select" do
|
195
195
|
it "is the per-page values formatted as options_for_select" do
|
196
196
|
allow(helper).to receive_messages(blacklight_config: double(per_page: [11, 22, 33]))
|
197
|
-
expect(helper.per_page_options_for_select).to include ["11<span class=\"sr-only\"> per page</span>", 11]
|
198
|
-
expect(helper.per_page_options_for_select).to include ["22<span class=\"sr-only\"> per page</span>", 22]
|
199
|
-
expect(helper.per_page_options_for_select).to include ["33<span class=\"sr-only\"> per page</span>", 33]
|
197
|
+
expect(helper.per_page_options_for_select).to include ["11<span class=\"sr-only visually-hidden\"> per page</span>", 11]
|
198
|
+
expect(helper.per_page_options_for_select).to include ["22<span class=\"sr-only visually-hidden\"> per page</span>", 22]
|
199
|
+
expect(helper.per_page_options_for_select).to include ["33<span class=\"sr-only visually-hidden\"> per page</span>", 33]
|
200
200
|
end
|
201
201
|
end
|
202
202
|
|
@@ -314,7 +314,7 @@ RSpec.describe Blacklight::FacetsHelperBehavior do
|
|
314
314
|
end
|
315
315
|
|
316
316
|
describe "simple case" do
|
317
|
-
let(:expected_html) { '<span class="facet-label"><a class="facet-select" href="/catalog">Z</a></span><span class="facet-count">10</span>' }
|
317
|
+
let(:expected_html) { '<span class="facet-label"><a class="facet-select" rel="nofollow" href="/catalog">Z</a></span><span class="facet-count">10</span>' }
|
318
318
|
|
319
319
|
it "uses facet_display_value" do
|
320
320
|
result = helper.render_facet_value('simple_field', item)
|
@@ -323,7 +323,7 @@ RSpec.describe Blacklight::FacetsHelperBehavior do
|
|
323
323
|
end
|
324
324
|
|
325
325
|
describe "when :url_method is set" do
|
326
|
-
let(:expected_html) { '<span class="facet-label"><a class="facet-select" href="/blabla">Z</a></span><span class="facet-count">10</span>' }
|
326
|
+
let(:expected_html) { '<span class="facet-label"><a class="facet-select" rel="nofollow" href="/blabla">Z</a></span><span class="facet-count">10</span>' }
|
327
327
|
|
328
328
|
it "uses that method" do
|
329
329
|
allow(helper).to receive(:facet_configuration_for_field).with('simple_field').and_return(Blacklight::Configuration::FacetField.new(key: 'simple_field', query: nil, date: nil, helper_method: nil, single: false, url_method: :test_method))
|