blacklight 8.3.0 → 8.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +9 -5
  3. data/.rubocop.yml +3 -0
  4. data/.rubocop_todo.yml +22 -55
  5. data/Gemfile +2 -10
  6. data/README.md +2 -2
  7. data/VERSION +1 -1
  8. data/app/assets/javascripts/blacklight/blacklight.esm.js +5 -1
  9. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
  10. data/app/assets/javascripts/blacklight/blacklight.js +5 -1
  11. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
  12. data/app/assets/stylesheets/blacklight/_balanced_list.scss +1 -1
  13. data/app/assets/stylesheets/blacklight/_bookmark.scss +30 -0
  14. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +0 -4
  15. data/app/assets/stylesheets/blacklight/_constraints.scss +15 -9
  16. data/app/assets/stylesheets/blacklight/_controls.scss +0 -1
  17. data/app/assets/stylesheets/blacklight/_facets.scss +33 -37
  18. data/app/assets/stylesheets/blacklight/_header.scss +2 -35
  19. data/app/assets/stylesheets/blacklight/_icons.scss +3 -2
  20. data/app/assets/stylesheets/blacklight/_layout.scss +3 -0
  21. data/app/assets/stylesheets/blacklight/_mixins.scss +4 -4
  22. data/app/assets/stylesheets/blacklight/_search_form.scss +3 -8
  23. data/app/assets/stylesheets/blacklight/_search_history.scss +5 -5
  24. data/app/assets/stylesheets/blacklight/_search_results.scss +5 -2
  25. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +16 -10
  26. data/app/components/blacklight/advanced_search_form_component.html.erb +1 -1
  27. data/app/components/blacklight/advanced_search_form_component.rb +6 -0
  28. data/app/components/blacklight/constraint_layout_component.html.erb +2 -9
  29. data/app/components/blacklight/constraint_layout_component.rb +8 -0
  30. data/app/components/blacklight/constraints_component.rb +3 -3
  31. data/app/components/blacklight/document/action_component.rb +2 -1
  32. data/app/components/blacklight/document/bookmark_component.html.erb +2 -1
  33. data/app/components/blacklight/document/bookmark_component.rb +6 -0
  34. data/app/components/blacklight/document/page_header_component.html.erb +7 -0
  35. data/app/components/blacklight/document/page_header_component.rb +85 -0
  36. data/app/components/blacklight/document_component.rb +1 -1
  37. data/app/components/blacklight/facet_component.rb +1 -1
  38. data/app/components/blacklight/facet_field_checkboxes_component.html.erb +1 -1
  39. data/app/components/blacklight/facet_field_checkboxes_component.rb +1 -1
  40. data/app/components/blacklight/facet_field_inclusive_constraint_component.html.erb +1 -1
  41. data/app/components/blacklight/facet_field_list_component.html.erb +1 -1
  42. data/app/components/blacklight/facet_item_component.rb +1 -1
  43. data/app/components/blacklight/icons/bookmark_icon_component.rb +17 -0
  44. data/app/components/blacklight/icons/icon_component.rb +9 -4
  45. data/app/components/blacklight/icons/remove_component.rb +16 -0
  46. data/app/components/blacklight/metadata_field_component.html.erb +1 -1
  47. data/app/components/blacklight/metadata_field_component.rb +5 -0
  48. data/app/components/blacklight/response/facet_group_component.rb +1 -1
  49. data/app/components/blacklight/response/pagination_component.html.erb +1 -1
  50. data/app/components/blacklight/response/sort_component.html.erb +1 -6
  51. data/app/components/blacklight/response/sort_component.rb +15 -0
  52. data/app/components/blacklight/search/per_page_component.html.erb +2 -0
  53. data/app/components/blacklight/search/per_page_component.rb +50 -0
  54. data/app/components/blacklight/search_bar_component.html.erb +1 -1
  55. data/app/components/blacklight/search_context/server_item_pagination_component.html.erb +4 -7
  56. data/app/components/blacklight/skip_link_component.html.erb +7 -0
  57. data/app/components/blacklight/skip_link_component.rb +17 -0
  58. data/app/components/blacklight/system/dropdown_button_component.rb +18 -0
  59. data/app/components/blacklight/system/dropdown_component.rb +3 -6
  60. data/app/components/blacklight/system/flash_message_component.html.erb +1 -1
  61. data/app/components/blacklight/top_navbar_component.html.erb +2 -2
  62. data/app/components/blacklight/top_navbar_component.rb +4 -0
  63. data/app/helpers/blacklight/catalog_helper_behavior.rb +2 -0
  64. data/app/helpers/blacklight/component_helper_behavior.rb +4 -4
  65. data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -0
  66. data/app/javascript/blacklight/checkbox_submit.js +5 -1
  67. data/app/models/concerns/blacklight/document/semantic_fields.rb +1 -1
  68. data/app/presenters/blacklight/facet_checkbox_item_presenter.rb +11 -0
  69. data/app/presenters/blacklight/facet_field_presenter.rb +9 -1
  70. data/app/services/blacklight/search_service.rb +9 -1
  71. data/app/views/catalog/_per_page_widget.html.erb +1 -10
  72. data/app/views/catalog/_search_results.html.erb +1 -1
  73. data/app/views/catalog/_show_main_content.html.erb +1 -1
  74. data/app/views/catalog/show.html.erb +0 -2
  75. data/app/views/catalog/suggest.html.erb +1 -1
  76. data/app/views/kaminari/blacklight/_page.html.erb +14 -8
  77. data/app/views/layouts/blacklight/base.html.erb +3 -4
  78. data/blacklight.gemspec +4 -0
  79. data/{docker-compose.yml → compose.yaml} +1 -1
  80. data/config/locales/blacklight.ar.yml +3 -0
  81. data/config/locales/blacklight.de.yml +3 -0
  82. data/config/locales/blacklight.en.yml +216 -229
  83. data/config/locales/blacklight.es.yml +3 -0
  84. data/config/locales/blacklight.fr.yml +3 -0
  85. data/config/locales/blacklight.hu.yml +3 -0
  86. data/config/locales/blacklight.it.yml +3 -0
  87. data/config/locales/blacklight.nl.yml +3 -0
  88. data/config/locales/blacklight.pt-BR.yml +3 -0
  89. data/config/locales/blacklight.sq.yml +3 -0
  90. data/config/locales/blacklight.zh.yml +3 -0
  91. data/lib/blacklight/abstract_repository.rb +6 -0
  92. data/lib/blacklight/configuration.rb +32 -19
  93. data/lib/blacklight/parameters.rb +1 -1
  94. data/lib/blacklight/solr/repository.rb +11 -4
  95. data/lib/blacklight/solr/response/params.rb +1 -1
  96. data/lib/blacklight/solr/response.rb +0 -12
  97. data/lib/blacklight/solr/search_builder_behavior.rb +1 -1
  98. data/lib/blacklight/solr.rb +0 -6
  99. data/lib/blacklight.rb +4 -14
  100. data/lib/generators/blacklight/assets/propshaft_generator.rb +2 -2
  101. data/lib/generators/blacklight/models_generator.rb +1 -1
  102. data/package.json +1 -1
  103. data/spec/components/blacklight/document/action_component_spec.rb +1 -1
  104. data/spec/components/blacklight/document/page_header_component_spec.rb +92 -0
  105. data/spec/components/blacklight/document_component_spec.rb +20 -0
  106. data/spec/components/blacklight/icons/icon_component_spec.rb +42 -0
  107. data/spec/components/blacklight/search_context/server_item_pagination_component_spec.rb +1 -1
  108. data/spec/controllers/blacklight/catalog_spec.rb +1 -1
  109. data/spec/controllers/catalog_controller_spec.rb +5 -5
  110. data/spec/features/advanced_search_spec.rb +16 -2
  111. data/spec/features/bookmarks_spec.rb +15 -0
  112. data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +2 -2
  113. data/spec/lib/blacklight/nested_open_struct_with_hash_access_spec.rb +1 -1
  114. data/spec/lib/blacklight/open_struct_with_hash_access_spec.rb +1 -1
  115. data/spec/models/blacklight/configuration_spec.rb +12 -12
  116. data/spec/models/blacklight/solr/document_spec.rb +2 -2
  117. data/spec/models/blacklight/solr/repository_spec.rb +31 -13
  118. data/spec/models/blacklight/solr/response/facets_spec.rb +2 -2
  119. data/spec/models/blacklight/solr/response/group_spec.rb +1 -1
  120. data/spec/models/blacklight/solr/response_spec.rb +2 -2
  121. data/spec/models/blacklight/solr/search_builder_behavior_spec.rb +1 -1
  122. data/spec/models/bookmark_spec.rb +1 -1
  123. data/spec/presenters/blacklight/document_presenter_spec.rb +2 -2
  124. data/spec/presenters/blacklight/facet_checkbox_item_presenter_spec.rb +42 -0
  125. data/spec/presenters/blacklight/facet_field_presenter_spec.rb +14 -0
  126. data/spec/requests/load_suggestions_spec.rb +5 -5
  127. data/spec/services/blacklight/search_service_spec.rb +2 -2
  128. data/spec/test_app_templates/lib/generators/test_app_generator.rb +1 -1
  129. data/tasks/blacklight.rake +5 -5
  130. metadata +76 -4
@@ -5,24 +5,6 @@ module Blacklight
5
5
  # Blacklight::Configuration holds the configuration for a Blacklight::Controller, including
6
6
  # fields to display, facets to show, sort options, and search fields.
7
7
  class Configuration < OpenStructWithHashAccess
8
- extend ActiveSupport::Autoload
9
- eager_autoload do
10
- autoload :Context
11
- autoload :ViewConfig
12
- autoload :ToolConfig
13
- autoload :Fields
14
- autoload :Field
15
- autoload :NullField
16
- autoload :NullDisplayField
17
- autoload :SearchField
18
- autoload :FacetField
19
- autoload :SortField
20
- autoload :DisplayField
21
- autoload :IndexField
22
- autoload :ShowField
23
- autoload :SessionTrackingConfig
24
- end
25
-
26
8
  class_attribute :default_values, default: {}
27
9
 
28
10
  # Set up Blacklight::Configuration.default_values to contain the basic, required Blacklight fields
@@ -59,6 +41,7 @@ module Blacklight
59
41
  # rubocop:disable Metrics/BlockLength
60
42
  default_configuration do
61
43
  property :logo_link, default: nil
44
+ property :skip_link_component, default: Blacklight::SkipLinkComponent
62
45
  property :header_component, default: Blacklight::HeaderComponent
63
46
  property :full_width_layout, default: false
64
47
 
@@ -99,6 +82,10 @@ module Blacklight
99
82
  # @!attribute default_document_solr_params
100
83
  # @return [Hash] Default values of parameters to send with every single-document request
101
84
  property :default_document_solr_params, default: {}
85
+ # @!attribute fetch_many_documents_path
86
+ # @since v8.4.0
87
+ # @return [String] The url path (relative to the solr base url) to use when requesting multiple documents by id
88
+ property :fetch_many_documents_path, default: nil
102
89
  # @!attribute fetch_many_document_params
103
90
  # @since v7.0.0
104
91
  # @return [Hash] Default values of parameters to send with every multi-document request
@@ -146,6 +133,12 @@ module Blacklight
146
133
  # @return [#partials]
147
134
  property :navbar, default: OpenStructWithHashAccess.new(partials: {})
148
135
 
136
+ # @!attribute bookmark_icon_component
137
+ # @since v8.3.1
138
+ # component class used to render a document
139
+ # set to Blacklight::Icons::BookmarkIconComponent to replace checkbox with icon
140
+ property :bookmark_icon_component, default: nil
141
+
149
142
  # @!attribute index
150
143
  # General configuration for all views
151
144
  # @return [Blacklight::Configuration::ViewConfig::Index]
@@ -155,6 +148,7 @@ module Blacklight
155
148
  # component class used to render a document
156
149
  document_component: Blacklight::DocumentComponent,
157
150
  sidebar_component: Blacklight::Search::SidebarComponent,
151
+ dropdown_component: Blacklight::System::DropdownComponent,
158
152
  # solr field to use to render a document title
159
153
  title_field: nil,
160
154
  # solr field to use to render format-specific partials
@@ -191,6 +185,8 @@ module Blacklight
191
185
  # in Blacklight 9, the default show_tools_component configuration will
192
186
  # be Blacklight::Document::ShowToolsComponent
193
187
  show_tools_component: nil,
188
+ show_header_tools_component: nil,
189
+ document_header_component: Blacklight::Document::PageHeaderComponent,
194
190
  sidebar_component: Blacklight::Document::SidebarComponent,
195
191
  display_type_field: nil,
196
192
  # the "field access" key to use to look up the document display fields
@@ -201,7 +197,8 @@ module Blacklight
201
197
  route: nil,
202
198
  # partials to render for each document(see #render_document_partials)
203
199
  partials: [],
204
- document_actions: NestedOpenStructWithHashAccess.new(ToolConfig)
200
+ document_actions: NestedOpenStructWithHashAccess.new(ToolConfig),
201
+ header_actions: NestedOpenStructWithHashAccess.new(ToolConfig)
205
202
  )
206
203
 
207
204
  # @!attribute action_mapping
@@ -548,6 +545,22 @@ module Blacklight
548
545
  add_action(show.document_actions, name, opts)
549
546
  klass && ActionBuilder.new(klass, name, opts).build
550
547
  end
548
+
549
+ # Add a partial to the show page header when rendering a document.
550
+ # @!macro partial_if_unless
551
+ # @param name [String] the name of the document partial
552
+ # @param opts [Hash]
553
+ # @option opts [Class] :component draw a component
554
+ # @option opts [String] :partial partial to draw if component is false
555
+ # @option opts [Symbol,Proc] :if render this action if the method identified by the symbol or the proc evaluates to true. The proc will receive the action configuration and the document or documents for the action.
556
+ # @option opts [Symbol,Proc] :unless render this action unless the method identified by the symbol or the proc evaluates to true. The proc will receive the action configuration and the document or documents for the action.
557
+ def add_show_header_tools_partial(name, opts = {})
558
+ opts[:partial] ||= 'document_action'
559
+
560
+ add_action(show.header_actions, name, opts)
561
+ klass && ActionBuilder.new(klass, name, opts).build
562
+ end
563
+
551
564
  # rubocop:enable Layout/LineLength
552
565
 
553
566
  # Add a tool for the search result list itself
@@ -7,7 +7,7 @@ module Blacklight
7
7
  # from the provided parameters.
8
8
  # @param [Hash] params parameters
9
9
  def self.sanitize params
10
- params.reject { |_k, v| v.nil? } # rubocop:disable Style/CollectionCompact not available in Rails 6.0
10
+ params.reject { |_k, v| v.nil? } # not available in Rails 6.0
11
11
  .except(:action, :controller, :id, :commit, :utf8)
12
12
  end
13
13
 
@@ -17,13 +17,20 @@ module Blacklight::Solr
17
17
  solr_response
18
18
  end
19
19
 
20
+ # Find multiple documents by their ids
21
+ # @param [Hash] _params query parameters
22
+ def find_many(params)
23
+ search(params: params, path: blacklight_config.fetch_many_documents_path)
24
+ end
25
+
20
26
  ##
21
27
  # Execute a search query against solr
22
28
  # @param [Hash] params solr query parameters
23
- def search params = {}
24
- request_params = params.reverse_merge({ qt: blacklight_config.qt })
29
+ # @param [String] path solr request handler path
30
+ def search pos_params = {}, path: nil, params: nil, **kwargs
31
+ request_params = (params || pos_params).reverse_merge(kwargs).reverse_merge({ qt: blacklight_config.qt })
25
32
 
26
- send_and_receive search_path(request_params), request_params
33
+ send_and_receive(path || default_search_path(request_params), request_params)
27
34
  end
28
35
 
29
36
  # @param [Hash] request_params
@@ -126,7 +133,7 @@ module Blacklight::Solr
126
133
  end
127
134
 
128
135
  # @return [String]
129
- def search_path(solr_params)
136
+ def default_search_path(solr_params)
130
137
  return blacklight_config.json_solr_path if blacklight_config.json_solr_path && uses_json_query_dsl?(solr_params)
131
138
 
132
139
  blacklight_config.solr_path
@@ -98,7 +98,7 @@ module Blacklight::Solr::Response::Params
98
98
  json_params[json_key || key],
99
99
  json_params.dig(:params, key),
100
100
  json_params.dig(:params, "json.#{key}")
101
- ].select(&:present?).inject([]) do |memo, arr|
101
+ ].compact_blank.inject([]) do |memo, arr|
102
102
  memo.concat(Array.wrap(arr))
103
103
  end
104
104
  end
@@ -1,18 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Blacklight::Solr::Response < ActiveSupport::HashWithIndifferentAccess
4
- extend ActiveSupport::Autoload
5
- eager_autoload do
6
- autoload :PaginationMethods
7
- autoload :Response
8
- autoload :Spelling
9
- autoload :Facets
10
- autoload :MoreLikeThis
11
- autoload :GroupResponse
12
- autoload :Group
13
- autoload :Params
14
- end
15
-
16
4
  include PaginationMethods
17
5
  include Spelling
18
6
  include Facets
@@ -161,7 +161,7 @@ module Blacklight::Solr
161
161
  limit: facet_limit_with_pagination(field_name)
162
162
  ).merge(additional_parameters)
163
163
 
164
- solr_parameters[:json][:facet][field_name] = field_config.select { |_k, v| v.present? }
164
+ solr_parameters[:json][:facet][field_name] = field_config.compact_blank
165
165
  end
166
166
 
167
167
  ##
@@ -2,11 +2,5 @@
2
2
 
3
3
  module Blacklight
4
4
  module Solr
5
- autoload :Document, 'blacklight/solr/document'
6
- autoload :FacetPaginator, 'blacklight/solr/facet_paginator'
7
- autoload :Repository, 'blacklight/solr/repository'
8
- autoload :Request, 'blacklight/solr/request'
9
- autoload :Response, 'blacklight/solr/response'
10
- autoload :SearchBuilderBehavior, 'blacklight/solr/search_builder_behavior'
11
5
  end
12
6
  end
data/lib/blacklight.rb CHANGED
@@ -1,23 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'kaminari'
4
- require 'blacklight/open_struct_with_hash_access'
5
- require 'blacklight/nested_open_struct_with_hash_access'
6
4
  require 'jbuilder'
5
+ require "zeitwerk"
6
+ loader = Zeitwerk::Loader.for_gem
7
+ loader.ignore("#{__dir__}/generators")
8
+ loader.setup
7
9
 
8
10
  module Blacklight
9
- autoload :AbstractRepository, 'blacklight/abstract_repository'
10
- autoload :Component, 'blacklight/component'
11
- autoload :Configuration, 'blacklight/configuration'
12
- autoload :Exceptions, 'blacklight/exceptions'
13
- autoload :Parameters, 'blacklight/parameters'
14
- autoload :Routes, 'blacklight/routes'
15
- autoload :RuntimeRegistry, 'blacklight/runtime_registry'
16
- autoload :SearchBuilder, 'blacklight/search_builder'
17
- autoload :SearchState, 'blacklight/search_state'
18
- autoload :Solr, 'blacklight/solr'
19
-
20
- require 'blacklight/version'
21
11
  require 'blacklight/engine' if defined?(Rails)
22
12
 
23
13
  def self.blacklight_config_file
@@ -5,9 +5,9 @@ module Blacklight
5
5
  class PropshaftGenerator < Rails::Generators::Base
6
6
  def add_package
7
7
  if ENV['CI']
8
- run "yarn add blacklight-frontend:#{Blacklight::Engine.root}"
8
+ run "yarn add file:#{Blacklight::Engine.root}"
9
9
  else
10
- run 'yarn add blacklight-frontend'
10
+ run "yarn add blacklight-frontend@#{Blacklight::VERSION}"
11
11
  end
12
12
  end
13
13
 
@@ -36,7 +36,7 @@ module Blacklight
36
36
  concerns :exportable
37
37
  end
38
38
 
39
- resources :bookmarks do
39
+ resources :bookmarks, only: [:index, :update, :create, :destroy] do
40
40
  concerns :exportable
41
41
 
42
42
  collection do
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blacklight-frontend",
3
- "version": "8.3.0",
3
+ "version": "8.4.0",
4
4
  "description": "The frontend code and styles for Blacklight",
5
5
  "main": "app/assets/javascripts/blacklight",
6
6
  "module": "app/assets/javascripts/blacklight/blacklight.esm.js",
@@ -36,7 +36,7 @@ RSpec.describe Blacklight::Document::ActionComponent, type: :component do
36
36
  let(:action) { Blacklight::Configuration::ToolConfig.new(name: '', partial: '/some/tool') }
37
37
 
38
38
  it 'render the partial' do
39
- allow(view_context).to receive(:render).with(hash_including(partial: '/some/tool')).and_return('tool')
39
+ allow(view_context).to receive(:render).with(hash_including(partial: '/some/tool'), {}).and_return('tool')
40
40
 
41
41
  expect(rendered).to have_content 'tool'
42
42
  end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::Document::PageHeaderComponent, type: :component do
6
+ subject(:component) { described_class.new(document: document, search_context: search_context, search_session: current_search_session) }
7
+
8
+ let(:show_header_tools_component) { Class.new(Blacklight::Document::ShowToolsComponent) }
9
+
10
+ let(:view_context) { controller.view_context }
11
+ let(:render) do
12
+ component.render_in(view_context)
13
+ end
14
+
15
+ let(:rendered) do
16
+ Capybara::Node::Simple.new(render)
17
+ end
18
+
19
+ let(:document) { SolrDocument.new(id: 'x', title_tsim: 'Title') }
20
+
21
+ let(:blacklight_config) do
22
+ CatalogController.blacklight_config.deep_copy
23
+ end
24
+
25
+ # rubocop:disable RSpec/SubjectStub
26
+ before do
27
+ # Every call to view_context returns a different object. This ensures it stays stable.
28
+ allow(controller).to receive_messages(blacklight_config: blacklight_config)
29
+ allow(controller).to receive(:current_search_session).and_return(double(id: document.id))
30
+ controller.class.helper_method :current_search_session
31
+ allow(controller).to receive_messages(controller_name: 'catalog', link_to_previous_document: '', link_to_next_document: '')
32
+ allow(view_context).to receive_messages(search_context: search_context, search_session: current_search_session, current_search_session: current_search_session)
33
+ allow(component).to receive(:render).and_call_original
34
+ allow(component).to receive(:render).with(an_instance_of(show_header_tools_component)).and_return('tool component content')
35
+ replace_hash = { 'application/_start_over.html.erb' => 'Start Over' }
36
+ if Rails.version.to_f >= 7.1
37
+ controller.prepend_view_path(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
38
+ else
39
+ view_context.view_paths.unshift(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
40
+ end
41
+ end
42
+ # rubocop:enable RSpec/SubjectStub
43
+
44
+ context "all variables are empty" do
45
+ let(:search_context) { nil }
46
+ let(:current_search_session) { {} }
47
+
48
+ it 'does not render' do
49
+ expect(rendered.native.inner_html).to be_blank
50
+ end
51
+
52
+ context 'has header tools' do
53
+ before do
54
+ blacklight_config.show.show_header_tools_component = show_header_tools_component
55
+ end
56
+
57
+ it 'renders the tools' do
58
+ expect(rendered).to have_text 'tool component content'
59
+ expect(rendered).to have_css '.row'
60
+ end
61
+ end
62
+ end
63
+
64
+ context "has pagination" do
65
+ let(:search_context) { { next: next_doc, prev: prev_doc } }
66
+ let(:prev_doc) { SolrDocument.new(id: '777') }
67
+ let(:next_doc) { SolrDocument.new(id: '888') }
68
+ let(:current_search_session) { { query_params: { q: 'abc' }, 'id' => '123', 'document_id' => document.id } }
69
+
70
+ it 'renders pagination' do
71
+ expect(rendered).to have_text 'Previous'
72
+ expect(rendered).to have_text 'Next'
73
+ expect(rendered).to have_text 'Start Over'
74
+ expect(rendered).to have_text 'Back to Search'
75
+ end
76
+
77
+ context 'has header tools' do
78
+ before do
79
+ blacklight_config.show.show_header_tools_component = show_header_tools_component
80
+ end
81
+
82
+ it 'renders the tools and pagination' do
83
+ expect(rendered).to have_text 'Previous'
84
+ expect(rendered).to have_text 'Next'
85
+ expect(rendered).to have_text 'Start Over'
86
+ expect(rendered).to have_text 'Back to Search'
87
+ expect(rendered).to have_text 'tool component content'
88
+ expect(rendered).to have_css '.row'
89
+ end
90
+ end
91
+ end
92
+ end
@@ -158,6 +158,26 @@ RSpec.describe Blacklight::DocumentComponent, type: :component do
158
158
  expect(rendered).to have_content 'embed'
159
159
  end
160
160
 
161
+ context 'show view with custom translation' do
162
+ let!(:original_translations) { I18n.backend.send(:translations).deep_dup }
163
+
164
+ before do
165
+ controller.action_name = "show"
166
+ I18n.backend.store_translations(:en, blacklight: { search: { show: { label: "testing:%{label}" } } })
167
+ end
168
+
169
+ after do
170
+ I18n.backend.reload!
171
+ I18n.backend.store_translations(:en, original_translations[:en])
172
+ end
173
+
174
+ it 'renders with show-specific metadata with correct translation' do
175
+ expect(rendered).to have_css 'dl.document-metadata'
176
+ expect(rendered).to have_css 'dt', text: 'testing:ISBN'
177
+ expect(rendered).to have_css 'dd', text: 'Value'
178
+ end
179
+ end
180
+
161
181
  context 'with configured metadata component' do
162
182
  let(:custom_component_class) do
163
183
  Class.new(Blacklight::DocumentMetadataComponent) do
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::Icons::IconComponent, type: :component do
6
+ subject(:component) { sub_component.new }
7
+
8
+ let(:sub_component) do
9
+ Class.new(described_class) do
10
+ def self.name
11
+ 'TestIconComponent'
12
+ end
13
+ end
14
+ end
15
+
16
+ context 'when no classes are passed in' do
17
+ subject(:component) { sub_component.new }
18
+
19
+ it "renders component" do
20
+ render_inline(component)
21
+ expect(page).to have_css "span[class='blacklight-icons blacklight-icons-test_icon']"
22
+ end
23
+ end
24
+
25
+ context 'when classes are passed in' do
26
+ subject(:component) { sub_component.new(classes: 'my-icon') }
27
+
28
+ it "renders component" do
29
+ render_inline(component)
30
+ expect(page).to have_css "span[class='my-icon blacklight-icons blacklight-icons-test_icon']"
31
+ end
32
+ end
33
+
34
+ context 'when name is passed in' do
35
+ subject(:component) { sub_component.new(name: 'my-icon') }
36
+
37
+ it "renders component" do
38
+ render_inline(component)
39
+ expect(page).to have_css "span[class='blacklight-icons blacklight-icons-my-icon']"
40
+ end
41
+ end
42
+ end
@@ -35,7 +35,7 @@ RSpec.describe Blacklight::SearchContext::ServerItemPaginationComponent, type: :
35
35
  end
36
36
 
37
37
  it "renders content" do
38
- expect(render.css('.pagination-search-widgets').to_html).not_to be_blank
38
+ expect(render.css('.search-context.page-links').to_html).not_to be_blank
39
39
  end
40
40
 
41
41
  context "session and document are out of sync" do
@@ -17,7 +17,7 @@ RSpec.describe Blacklight::Catalog do
17
17
  end
18
18
 
19
19
  it "creates a path object" do
20
- expect(subject).to be_kind_of Blacklight::SearchState
20
+ expect(subject).to be_a Blacklight::SearchState
21
21
  expect(subject.params).to eq raw_params
22
22
  end
23
23
  end
@@ -611,10 +611,10 @@ RSpec.describe CatalogController, :api do
611
611
  it "is successful" do
612
612
  get :facet, params: { id: 'format' }
613
613
  expect(response).to be_successful
614
- expect(assigns[:response]).to be_kind_of Blacklight::Solr::Response
615
- expect(assigns[:facet]).to be_kind_of Blacklight::Configuration::FacetField
616
- expect(assigns[:display_facet]).to be_kind_of Blacklight::Solr::Response::Facets::FacetField
617
- expect(assigns[:pagination]).to be_kind_of Blacklight::Solr::FacetPaginator
614
+ expect(assigns[:response]).to be_a Blacklight::Solr::Response
615
+ expect(assigns[:facet]).to be_a Blacklight::Configuration::FacetField
616
+ expect(assigns[:display_facet]).to be_a Blacklight::Solr::Response::Facets::FacetField
617
+ expect(assigns[:pagination]).to be_a Blacklight::Solr::FacetPaginator
618
618
  end
619
619
  end
620
620
 
@@ -638,7 +638,7 @@ RSpec.describe CatalogController, :api do
638
638
 
639
639
  expect(response).to be_successful
640
640
 
641
- expect(assigns[:facet]).to be_kind_of Blacklight::Configuration::FacetField
641
+ expect(assigns[:facet]).to be_a Blacklight::Configuration::FacetField
642
642
  expect(assigns[:facet].key).to eq 'params_key'
643
643
  expect(assigns[:facet].field).to eq 'format'
644
644
 
@@ -105,11 +105,23 @@ RSpec.describe "Blacklight Advanced Search Form" do
105
105
 
106
106
  describe "prepopulated advanced search form" do
107
107
  before do
108
- visit '/catalog/advanced?op=must&clause[0][field]=title&clause[0]query=medicine'
108
+ visit '/catalog/advanced?op=must&clause[1][field]=title&clause[1]query=medicine&f_inclusive[language_ssim][]=Tibetan&sort=author'
109
109
  end
110
110
 
111
- it "does not create hidden inputs for search fields" do
111
+ it 'prepopulates the expected fields' do
112
112
  expect(page).to have_field 'Title', with: 'medicine'
113
+ expect(page).to have_field 'Tibetan', checked: true
114
+ expect(page).to have_select 'op', selected: 'all'
115
+ expect(page).to have_select 'sort', selected: 'author'
116
+ end
117
+
118
+ it "does not create hidden inputs for fields included in adv search form" do
119
+ within('form.advanced') do
120
+ expect(page).to have_no_field('clause[1][query]', type: :hidden, with: 'medicine')
121
+ expect(page).to have_no_field('f_inclusive[language_ssim][]', type: :hidden, with: 'Tibetan')
122
+ expect(page).to have_no_field('op', type: :hidden, with: 'must')
123
+ expect(page).to have_no_field('sort', type: :hidden, with: 'author')
124
+ end
113
125
  end
114
126
 
115
127
  it "does not have multiple parameters for a search field" do
@@ -121,8 +133,10 @@ RSpec.describe "Blacklight Advanced Search Form" do
121
133
 
122
134
  it "clears the prepopulated fields when the Start Over button is pressed" do
123
135
  expect(page).to have_field 'Title', with: 'medicine'
136
+ expect(page).to have_field 'Tibetan', checked: true
124
137
  click_on 'Start over'
125
138
  expect(page).to have_no_field 'Title', with: 'medicine'
139
+ expect(page).to have_no_field 'Tibetan', checked: true
126
140
  end
127
141
  end
128
142
  end
@@ -81,4 +81,19 @@ RSpec.describe "Bookmarks" do
81
81
  expect(page).to have_content 'Strong Medicine speaks'
82
82
  expect(page).to have_content 'Ci an zhou bian'
83
83
  end
84
+
85
+ context "has bookmark icon" do
86
+ before do
87
+ CatalogController.blacklight_config.bookmark_icon_component = Blacklight::Icons::BookmarkIconComponent
88
+ end
89
+
90
+ it 'shows bookmark icon instead of checkbox', :js do
91
+ visit solr_document_path('2007020969')
92
+ expect(page).to have_css('.blacklight-icons-bookmark')
93
+ find('.blacklight-icons-bookmark').click
94
+
95
+ expect(find('.toggle-bookmark[type="checkbox"]', visible: false)).to be_checked
96
+ find('.blacklight-icons-bookmark').click
97
+ end
98
+ end
84
99
  end
@@ -13,7 +13,7 @@ RSpec.describe Blacklight::FacetsHelperBehavior do
13
13
 
14
14
  it 'wraps the facet data in a presenter' do
15
15
  presenter = helper.facet_field_presenter(facet_config, display_facet)
16
- expect(presenter).to be_a_kind_of Blacklight::FacetFieldPresenter
16
+ expect(presenter).to be_a Blacklight::FacetFieldPresenter
17
17
  expect(presenter.facet_field).to eq facet_config
18
18
  expect(presenter.display_facet).to eq display_facet
19
19
  expect(presenter.view_context).to eq helper
@@ -23,7 +23,7 @@ RSpec.describe Blacklight::FacetsHelperBehavior do
23
23
  stub_const('SomePresenter', Class.new(Blacklight::FacetFieldPresenter))
24
24
  facet_config.presenter = SomePresenter
25
25
  presenter = helper.facet_field_presenter(facet_config, display_facet)
26
- expect(presenter).to be_a_kind_of SomePresenter
26
+ expect(presenter).to be_a SomePresenter
27
27
  end
28
28
  end
29
29
  end
@@ -23,7 +23,7 @@ RSpec.describe Blacklight::NestedOpenStructWithHashAccess do
23
23
 
24
24
  describe "#deep_dup" do
25
25
  it "preserves the current class" do
26
- expect(described_class.new(described_class).deep_dup).to be_a_kind_of described_class
26
+ expect(described_class.new(described_class).deep_dup).to be_a described_class
27
27
  end
28
28
 
29
29
  it "preserves the default proc" do
@@ -36,7 +36,7 @@ RSpec.describe Blacklight::OpenStructWithHashAccess do
36
36
  end
37
37
 
38
38
  it "exposes the internal hash table" do
39
- expect(@h.to_h).to be_a_kind_of(Hash)
39
+ expect(@h.to_h).to be_a(Hash)
40
40
  expect(@h.to_h[:a]).to eq 1
41
41
  end
42
42
 
@@ -14,7 +14,7 @@ RSpec.describe "Blacklight::Configuration", :api do
14
14
 
15
15
  describe "initialization" do
16
16
  it "is an OpenStructWithHashAccess" do
17
- expect(config).to be_a_kind_of Blacklight::OpenStructWithHashAccess
17
+ expect(config).to be_a Blacklight::OpenStructWithHashAccess
18
18
  end
19
19
 
20
20
  it "accepts a block for configuration" do
@@ -30,22 +30,22 @@ RSpec.describe "Blacklight::Configuration", :api do
30
30
 
31
31
  describe "defaults" do
32
32
  it "has a hash of default rsolr query parameters" do
33
- expect(config.default_solr_params).to be_a_kind_of Hash
33
+ expect(config.default_solr_params).to be_a Hash
34
34
  end
35
35
 
36
36
  it "has openstruct values for show and index parameters" do
37
- expect(config.show).to be_a_kind_of OpenStruct
38
- expect(config.index).to be_a_kind_of OpenStruct
37
+ expect(config.show).to be_a OpenStruct
38
+ expect(config.index).to be_a OpenStruct
39
39
  end
40
40
 
41
41
  it "has ordered hashes for field configuration" do
42
- expect(config.facet_fields).to be_a_kind_of Hash
43
- expect(config.index_fields).to be_a_kind_of Hash
44
- expect(config.show_fields).to be_a_kind_of Hash
45
- expect(config.search_fields).to be_a_kind_of Hash
46
- expect(config.show_fields).to be_a_kind_of Hash
47
- expect(config.search_fields).to be_a_kind_of Hash
48
- expect(config.sort_fields).to be_a_kind_of Hash
42
+ expect(config.facet_fields).to be_a Hash
43
+ expect(config.index_fields).to be_a Hash
44
+ expect(config.show_fields).to be_a Hash
45
+ expect(config.search_fields).to be_a Hash
46
+ expect(config.show_fields).to be_a Hash
47
+ expect(config.search_fields).to be_a Hash
48
+ expect(config.sort_fields).to be_a Hash
49
49
  end
50
50
  end
51
51
 
@@ -197,7 +197,7 @@ RSpec.describe "Blacklight::Configuration", :api do
197
197
  config.add_my_custom_facet_field 'qwerty', label: "asdf"
198
198
  end
199
199
 
200
- expect(config.my_custom_facet_fields['qwerty']).to be_a_kind_of(Blacklight::Configuration::FacetField)
200
+ expect(config.my_custom_facet_fields['qwerty']).to be_a(Blacklight::Configuration::FacetField)
201
201
  end
202
202
  end
203
203
 
@@ -231,7 +231,7 @@ RSpec.describe "Blacklight::Solr::Document", :api do
231
231
  end
232
232
 
233
233
  it "returns an array even for a single-value field" do
234
- expect(@doc1.to_semantic_values[:title]).to be_kind_of(Array)
234
+ expect(@doc1.to_semantic_values[:title]).to be_a(Array)
235
235
  end
236
236
 
237
237
  it "returns complete array for a multi-value field" do
@@ -290,7 +290,7 @@ RSpec.describe "Blacklight::Solr::Document", :api do
290
290
 
291
291
  it "plucks the MoreLikeThis results from the Solr Response" do
292
292
  expect(result).to have(1).item
293
- expect(result.first).to be_a_kind_of(MockDocument)
293
+ expect(result.first).to be_a(MockDocument)
294
294
  expect(result.first.id).to eq 'abc'
295
295
  expect(result.first.solr_response).to eq response
296
296
  end