blacklight 7.17.0 → 7.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/app/components/blacklight/content_areas_shim.rb +2 -1
  4. data/app/components/blacklight/document/thumbnail_component.html.erb +3 -3
  5. data/app/components/blacklight/document/thumbnail_component.rb +11 -3
  6. data/app/components/blacklight/document_component.rb +7 -7
  7. data/app/components/blacklight/metadata_field_layout_component.rb +1 -1
  8. data/app/components/blacklight/response/view_type_button_component.rb +4 -2
  9. data/app/helpers/blacklight/catalog_helper_behavior.rb +2 -0
  10. data/app/helpers/blacklight/render_partials_helper_behavior.rb +5 -1
  11. data/app/views/catalog/_document.html.erb +4 -3
  12. data/app/views/catalog/_document_list.html.erb +3 -2
  13. data/lib/blacklight/configuration.rb +7 -1
  14. data/lib/blacklight/configuration/view_config.rb +5 -1
  15. data/lib/blacklight/nested_open_struct_with_hash_access.rb +33 -14
  16. data/lib/blacklight/open_struct_with_hash_access.rb +1 -1
  17. data/lib/blacklight/search_builder.rb +1 -0
  18. data/lib/blacklight/solr/search_builder_behavior.rb +7 -1
  19. data/lib/generators/blacklight/install_generator.rb +5 -5
  20. data/lib/generators/blacklight/solr_generator.rb +4 -2
  21. data/lib/generators/blacklight/user_generator.rb +4 -2
  22. data/spec/helpers/blacklight/configuration_helper_behavior_spec.rb +6 -7
  23. data/spec/helpers/blacklight_helper_spec.rb +20 -2
  24. data/spec/helpers/catalog_helper_spec.rb +1 -1
  25. data/spec/lib/blacklight/nested_open_struct_with_hash_access_spec.rb +36 -0
  26. data/spec/models/blacklight/configuration_spec.rb +10 -0
  27. data/spec/models/blacklight/solr/search_builder_spec.rb +9 -0
  28. data/spec/services/blacklight/search_service_spec.rb +1 -1
  29. data/spec/views/catalog/_constraints.html.erb_spec.rb +1 -1
  30. data/spec/views/catalog/_document.html.erb_spec.rb +9 -0
  31. data/spec/views/catalog/_document_list.html.erb_spec.rb +1 -1
  32. data/spec/views/catalog/_view_type_group.html.erb_spec.rb +8 -9
  33. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e26542ca54e79594290b86c0506e4bc3a26a225d84e17537893381b4ad2c421
4
- data.tar.gz: c812f19a30e663a1350888600307e7ba1b089b8794570eeadb38f89a6de57d27
3
+ metadata.gz: 3b17640ea1dd81a41048bfbb2362bf692300e228045fac8f0d42aa0fbd281a63
4
+ data.tar.gz: 6956aa4b0fd67802b24d04b0f27677ca9f84d5692bdf8a34cd21b043d3fe8df9
5
5
  SHA512:
6
- metadata.gz: 8f167c42362e5372a681777ce1cd1a72bf6ca9f5762098686bc6bb8872f59afd3f110312d15c1436320b511df272281ddb04be6cf9c10620535389aa87c91169
7
- data.tar.gz: 9ae4c4178d7eff8eb4656d03353fe4fb2cd4f66e32fffdebd8645275f213b26aadd9c8204c2feba9f6479160ad925ba220ce6e1ec59bff42f9ca298dfd7cbb5c
6
+ metadata.gz: bc71e8e6c0ee060b4303052caf0b9341c58a42c71e5f9badfe03f8013c6e3b96ba43f66d0d477c525edb58263a1993b9d9da143cf3f5f1c7fdb032568df5db87
7
+ data.tar.gz: e31975c219b1b709bdc6b765f123ffbf13978f56a26936f75d08cc7796e38703f163dc459e735f37bc36da3338e43f481d24b57d8308052509f6d19c0864bb7c
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.17.0
1
+ 7.19.0
@@ -5,7 +5,8 @@ module Blacklight
5
5
  module ContentAreasShim
6
6
  # Shim the `with` helper to write content into slots instead
7
7
  def with(slot_name, *args, **kwargs, &block)
8
- Deprecation.warn('ViewComponents deprecated `with` and it will be removed in ViewComponents 3.0. content_areas. Use slots (https://viewcomponent.org/guide/slots.html) instead.')
8
+ Deprecation.warn(Blacklight::ContentAreasShim,
9
+ 'ViewComponents deprecated `with` and it will be removed in ViewComponents 3.0. content_areas. Use slots (https://viewcomponent.org/guide/slots.html) instead.')
9
10
  public_send(slot_name, *args, **kwargs, &block)
10
11
  end
11
12
  end
@@ -1,12 +1,12 @@
1
- <% value = @use_thumbnail_tag ? @presenter.thumbnail.thumbnail_tag(@image_options, 'aria-hidden': true, tabindex: -1, counter: @counter) : @presenter.thumbnail.render(@image_options) %>
1
+ <% value = use_thumbnail_tag_behavior? ? presenter.thumbnail.thumbnail_tag(@image_options, 'aria-hidden': true, tabindex: -1, counter: @counter) : presenter.thumbnail.render(@image_options) %>
2
2
 
3
3
  <% if value %>
4
4
  <div class="document-thumbnail">
5
- <% if @use_thumbnail_tag %>
5
+ <% if use_thumbnail_tag_behavior? %>
6
6
  <% warn_about_deprecated_behavior %>
7
7
  <%= value %>
8
8
  <% else %>
9
- <%= helpers.link_to_document(@presenter.document, value, 'aria-hidden': true, tabindex: -1, counter: @counter) %>
9
+ <%= helpers.link_to_document(presenter.document, value, 'aria-hidden': true, tabindex: -1, counter: @counter) %>
10
10
  <% end %>
11
11
  </div>
12
12
  <% end %>
@@ -9,20 +9,28 @@ module Blacklight
9
9
  # @param [Blacklight::DocumentPresenter] presenter
10
10
  # @param [Integer] counter
11
11
  # @param [Hash] image_options options for the thumbnail presenter's image tag
12
- def initialize(presenter:, counter:, image_options: {})
12
+ def initialize(presenter: nil, document: nil, counter:, image_options: {})
13
13
  @presenter = presenter
14
+ @document = presenter&.document || document
14
15
  @counter = counter
15
16
  @image_options = { alt: '' }.merge(image_options)
16
- @use_thumbnail_tag = !@presenter.thumbnail.instance_of?(Blacklight::ThumbnailPresenter)
17
17
  end
18
18
 
19
19
  def render?
20
- @presenter.thumbnail.exists?
20
+ presenter.thumbnail.exists?
21
+ end
22
+
23
+ def use_thumbnail_tag_behavior?
24
+ !presenter.thumbnail.instance_of?(Blacklight::ThumbnailPresenter)
21
25
  end
22
26
 
23
27
  def warn_about_deprecated_behavior
24
28
  Deprecation.warn(Blacklight::Document::ThumbnailComponent, 'Detected as custom thumbnail presenter; make sure it has a #render method that returns just the thumbnail image tag')
25
29
  end
30
+
31
+ def presenter
32
+ @presenter ||= @view_context.document_presenter(@document)
33
+ end
26
34
  end
27
35
  end
28
36
  end
@@ -25,7 +25,7 @@ module Blacklight
25
25
  next static_content if static_content.present?
26
26
  next unless component
27
27
 
28
- Deprecation.warn('Pass the presenter to the DocumentComponent') if @presenter.nil?
28
+ Deprecation.warn(Blacklight::DocumentComponent, 'Pass the presenter to the DocumentComponent') if @presenter.nil?
29
29
 
30
30
  component.new(*args, document: @document, presenter: @presenter, document_counter: @document_counter, **kwargs)
31
31
  end)
@@ -34,7 +34,7 @@ module Blacklight
34
34
  renders_one :metadata, (lambda do |static_content = nil, *args, component: nil, fields: nil, **kwargs|
35
35
  next static_content if static_content.present?
36
36
 
37
- Deprecation.warn('Pass the presenter to the DocumentComponent') if !fields && @presenter.nil?
37
+ Deprecation.warn(Blacklight::DocumentComponent, 'Pass the presenter to the DocumentComponent') if !fields && @presenter.nil?
38
38
 
39
39
  component ||= Blacklight::DocumentMetadataComponent
40
40
 
@@ -48,9 +48,9 @@ module Blacklight
48
48
  next image_options_or_static_content if image_options_or_static_content.is_a? String
49
49
 
50
50
  component ||= @presenter&.view_config&.thumbnail_component || Blacklight::Document::ThumbnailComponent
51
- Deprecation.warn('Pass the presenter to the DocumentComponent') if !component && @presenter.nil?
51
+ Deprecation.warn(Blacklight::DocumentComponent, 'Pass the presenter to the DocumentComponent') if !component && @presenter.nil?
52
52
 
53
- component.new(*args, presenter: @presenter, counter: @counter, image_options: image_options_or_static_content, **kwargs)
53
+ component.new(*args, document: @document, presenter: @presenter, counter: @counter, image_options: image_options_or_static_content, **kwargs)
54
54
  end)
55
55
 
56
56
  # A container for partials rendered using the view config partials configuration. Its use is discouraged, but necessary until
@@ -93,13 +93,13 @@ module Blacklight
93
93
  @id = id || ('document' if show)
94
94
  @classes = classes
95
95
 
96
- Deprecation.warn('Passing embed_component is deprecated') if @embed_component.present?
96
+ Deprecation.warn(Blacklight::DocumentComponent, 'Passing embed_component is deprecated') if @embed_component.present?
97
97
  @embed_component = embed_component
98
98
 
99
- Deprecation.warn('Passing metadata_component is deprecated') if @metadata_component.present?
99
+ Deprecation.warn(Blacklight::DocumentComponent, 'Passing metadata_component is deprecated') if @metadata_component.present?
100
100
  @metadata_component = metadata_component || Blacklight::DocumentMetadataComponent
101
101
 
102
- Deprecation.warn('Passing thumbnail_component is deprecated') if @thumbnail_component.present?
102
+ Deprecation.warn(Blacklight::DocumentComponent, 'Passing thumbnail_component is deprecated') if @thumbnail_component.present?
103
103
  @thumbnail_component = thumbnail_component || Blacklight::Document::ThumbnailComponent
104
104
 
105
105
  @document_counter = document_counter
@@ -25,7 +25,7 @@ module Blacklight
25
25
  def value(*args, **kwargs, &block)
26
26
  return set_slot(:values, *args, **kwargs, &block) if block_given?
27
27
 
28
- Deprecation.warn('The `value` content area is deprecated; render from the values slot instead')
28
+ Deprecation.warn(Blacklight::MetadataFieldLayoutComponent, 'The `value` content area is deprecated; render from the values slot instead')
29
29
 
30
30
  values.first
31
31
  end
@@ -15,12 +15,14 @@ module Blacklight
15
15
  end
16
16
 
17
17
  def icon
18
- @view_context.render_view_type_group_icon(@view)
18
+ Deprecation.silence(Blacklight::CatalogHelperBehavior) do
19
+ @view_context.render_view_type_group_icon(@view.icon || @key)
20
+ end
19
21
  end
20
22
 
21
23
  def label
22
24
  Deprecation.silence(Blacklight::ConfigurationHelperBehavior) do
23
- @view_context.view_label(@view)
25
+ @view_context.view_label(@key)
24
26
  end
25
27
  end
26
28
 
@@ -253,11 +253,13 @@ module Blacklight::CatalogHelperBehavior
253
253
  ##
254
254
  # Render the view type icon for the results view picker
255
255
  #
256
+ # @deprecated
256
257
  # @param [String] view
257
258
  # @return [String]
258
259
  def render_view_type_group_icon view
259
260
  blacklight_icon(view)
260
261
  end
262
+ deprecation_deprecate render_view_type_group_icon: 'call blacklight_icon instead'
261
263
 
262
264
  ##
263
265
  # Get the default view type classes for a view in the results view picker
@@ -84,12 +84,16 @@ module Blacklight::RenderPartialsHelperBehavior
84
84
  # @param [Hash] locals to pass to the render call
85
85
  # @return [String]
86
86
  def render_document_index_with_view view, documents, locals = {}
87
+ view_config = blacklight_config&.view_config(view)
88
+
89
+ return render partial: view_config.template, locals: locals.merge(documents: documents, view_config: view_config) if view_config&.template
90
+
87
91
  template = cached_view ['index', view].join('_') do
88
92
  find_document_index_template_with_view(view, locals)
89
93
  end
90
94
 
91
95
  if template
92
- template.render(self, locals.merge(documents: documents))
96
+ template.render(self, locals.merge(documents: documents, view_config: view_config))
93
97
  else
94
98
  ''
95
99
  end
@@ -1,6 +1,7 @@
1
1
  <% # container for a single doc -%>
2
- <%= render (blacklight_config.view_config(document_index_view_type).document_component || Blacklight::DocumentComponent).new(presenter: document_presenter(document), counter: document_counter_with_offset(document_counter)) do |component| %>
3
- <% component.public_send(blacklight_config.view_config(document_index_view_type).document_component.blank? && blacklight_config.view_config(document_index_view_type).partials.any? ? :body : :partial) do %>
4
- <%= render_document_partials document, blacklight_config.view_config(document_index_view_type).partials, component: component, document_counter: document_counter %>
2
+ <% view_config = local_assigns[:view_config] || blacklight_config.view_config(document_index_view_type) %>
3
+ <%= render (view_config.document_component || Blacklight::DocumentComponent).new(presenter: document_presenter(document), counter: document_counter_with_offset(document_counter)) do |component| %>
4
+ <% component.public_send(view_config.document_component.blank? && view_config.partials.any? ? :body : :partial) do %>
5
+ <%= render_document_partials document, view_config.partials, component: component, document_counter: document_counter %>
5
6
  <% end %>
6
7
  <% end %>
@@ -1,4 +1,5 @@
1
1
  <% # container for all documents in index list view -%>
2
- <div id="documents" class="documents-<%= document_index_view_type %>">
3
- <%= render documents, :as => :document %>
2
+ <% view_config = local_assigns[:view_config] || blacklight_config&.view_config(document_index_view_type) %>
3
+ <div id="documents" class="documents-<%= view_config&.key || document_index_view_type %>">
4
+ <%= render documents, as: :document, view_config: view_config %>
4
5
  </div>
@@ -170,6 +170,8 @@ module Blacklight
170
170
  def initialize(hash = {})
171
171
  super(self.class.default_values.deep_dup.merge(hash))
172
172
  yield(self) if block_given?
173
+
174
+ @view_config ||= {}
173
175
  end
174
176
 
175
177
  def document_model
@@ -333,7 +335,6 @@ module Blacklight
333
335
  view_type = nil
334
336
  end
335
337
 
336
- @view_config ||= {}
337
338
  @view_config[[view_type, action_name]] ||= begin
338
339
  if view_type.nil?
339
340
  action_config(action_name)
@@ -428,6 +429,11 @@ module Blacklight
428
429
  fields.merge(show_fields)
429
430
  end
430
431
 
432
+ def freeze
433
+ each { |_k, v| v.is_a?(OpenStruct) && v.freeze }
434
+ super
435
+ end
436
+
431
437
  private
432
438
 
433
439
  def add_action(config_hash, name, opts)
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
  class Blacklight::Configuration
3
3
  class ViewConfig < Blacklight::OpenStructWithHashAccess
4
+ # @!attribute template
5
+ # @return [String] partial to render around the documents
4
6
  # @!attribute partials
5
7
  # @return [Array<String>] partials to render for each document(see #render_document_partials)
6
8
  # @!attribute document_presenter_class
@@ -11,6 +13,8 @@ class Blacklight::Configuration
11
13
  # @return [String, Symbol] solr field to use to render a document title
12
14
  # @!attribute display_type_field
13
15
  # @return [String, Symbol] solr field to use to render format-specific partials
16
+ # @!attribute icon
17
+ # @return [String, Symbol] icon file to use in the view picker
14
18
  # @!attribute document_actions
15
19
  # @return [NestedOpenStructWithHashAccess{Symbol => Blacklight::Configuration::ToolConfig}] 'tools' to render for each document
16
20
  def search_bar_presenter_class
@@ -18,7 +22,7 @@ class Blacklight::Configuration
18
22
  end
19
23
 
20
24
  def display_label(deprecated_key = nil, **options)
21
- Deprecation.warn('Passing the key argument to ViewConfig#display_label is deprecated') if deprecated_key.present?
25
+ Deprecation.warn(Blacklight::Configuration::ViewConfig, 'Passing the key argument to ViewConfig#display_label is deprecated') if deprecated_key.present?
22
26
 
23
27
  I18n.t(
24
28
  :"blacklight.search.view_title.#{deprecated_key || key}",
@@ -5,18 +5,21 @@ module Blacklight
5
5
  # An OpenStruct refinement that converts any hash-keys into
6
6
  # additional instances of NestedOpenStructWithHashAccess
7
7
  class NestedOpenStructWithHashAccess < OpenStructWithHashAccess
8
+ extend Deprecation
9
+ self.deprecation_horizon = 'blacklight 8.0'
10
+
8
11
  attr_reader :nested_class
9
12
 
10
13
  delegate :default_proc=, to: :to_h
11
14
 
12
15
  def initialize(klass, hash = {})
13
16
  @nested_class = klass
14
- value = hash.transform_values do |v|
15
- if v.is_a? Hash
16
- nested_class.new(v)
17
- else
18
- v
19
- end
17
+ value = hash.each_with_object({}) do |(k, v), h|
18
+ h[k] = if v.is_a? Hash
19
+ nested_class.new({ key: k.to_sym }.merge(v))
20
+ else
21
+ v
22
+ end
20
23
  end
21
24
 
22
25
  super value
@@ -34,7 +37,7 @@ module Blacklight
34
37
  # into another NestedOpenStructWithHashAccess
35
38
  def []=(key, value)
36
39
  if value.is_a? Hash
37
- send "#{key}=", nested_class.new(value)
40
+ send "#{key}=", nested_class.new({ key: key.to_sym }.merge(value))
38
41
  else
39
42
  super
40
43
  end
@@ -86,15 +89,31 @@ module Blacklight
86
89
  ##
87
90
  # Override #method_missing from OpenStruct to ensure the default_proc logic
88
91
  # gets triggered.
89
- def method_missing(mid, *args)
92
+ def method_missing(mid, *args, **kwargs, &block)
90
93
  len = args.length
91
94
 
92
- if len.zero?
93
- new_ostruct_member!(mid)
94
- @table[mid]
95
- else
96
- super
97
- end
95
+ res = if mid.to_s.end_with?('!')
96
+ m = mid[0...-1].to_sym
97
+ new_ostruct_member!(m)
98
+ @table[m]
99
+ elsif mid.to_s.end_with?('=')
100
+ m = mid[0...-1].to_sym
101
+ new_ostruct_member!(m)
102
+ @table[m] = args.first
103
+ elsif len.zero? && kwargs.blank? && !block
104
+ Deprecation.warn(Blacklight::NestedOpenStructWithHashAccess,
105
+ "Initializing a #{nested_class} implicitly (by calling #{mid}) is deprecated. Call it as #{mid}! or pass initialize arguments")
106
+
107
+ new_ostruct_member!(mid)
108
+ @table[mid]
109
+ else
110
+ new_ostruct_member!(mid)
111
+ @table[mid] = nested_class.new(key: mid, **(args.first || {}), **kwargs)
112
+ end
113
+
114
+ block&.call(res)
115
+
116
+ res
98
117
  end
99
118
 
100
119
  private
@@ -6,7 +6,7 @@ module Blacklight
6
6
  class OpenStructWithHashAccess < OpenStruct
7
7
  delegate :keys, :each, :map, :has_key?, :key?, :include?, :empty?,
8
8
  :length, :delete, :delete_if, :keep_if, :clear, :reject!, :select!,
9
- :replace, :fetch, :to_json, :as_json, :any?, to: :to_h
9
+ :replace, :fetch, :to_json, :as_json, :any?, :freeze, :unfreeze, :frozen?, to: :to_h
10
10
 
11
11
  ##
12
12
  # Expose the internal hash
@@ -45,6 +45,7 @@ module Blacklight
45
45
  ##
46
46
  # Update the :q (query) parameter
47
47
  def where(conditions)
48
+ Deprecation.warn(Blacklight::SearchBuilder, "SearchBuilder#where must be called with a hash, received #{conditions.inspect}.") unless conditions.is_a? Hash
48
49
  params_will_change!
49
50
  @search_state = @search_state.reset(@search_state.params.merge(q: conditions))
50
51
  @blacklight_params = @search_state.params.dup
@@ -32,6 +32,7 @@ module Blacklight::Solr
32
32
  # Take the user-entered query, and put it in the solr params,
33
33
  # including config's "search field" params for current search field.
34
34
  # also include setting spellcheck.q.
35
+ # rubocop:disable Metrics/CyclomaticComplexity
35
36
  def add_query_to_solr(solr_parameters)
36
37
  ###
37
38
  # legacy behavior of user param :qt is passed through, but over-ridden
@@ -64,11 +65,15 @@ module Blacklight::Solr
64
65
  elsif search_field&.solr_local_parameters.present?
65
66
  add_search_field_with_local_parameters(solr_parameters)
66
67
  elsif search_state.query_param.is_a? Hash
67
- add_additional_filters(solr_parameters, search_state.query_param)
68
+ if search_state.query_param == @additional_filters && !processor_chain.include?(:add_additional_filters)
69
+ Deprecation.warn(Blacklight::Solr::SearchBuilderBehavior, 'Expecting to see the processor step add_additional_filters; falling back to legacy query handling')
70
+ add_additional_filters(solr_parameters, search_state.query_param)
71
+ end
68
72
  elsif search_state.query_param
69
73
  solr_parameters.append_query search_state.query_param
70
74
  end
71
75
  end
76
+ # rubocop:enable Metrics/CyclomaticComplexity
72
77
 
73
78
  def add_additional_filters(solr_parameters, additional_filters = nil)
74
79
  q = additional_filters || @additional_filters
@@ -322,6 +327,7 @@ module Blacklight::Solr
322
327
  # around the term unless it's a bare-word. Escape internal quotes
323
328
  # if needed.
324
329
  def solr_param_quote(val, options = {})
330
+ val = val.to_s
325
331
  options[:quote] ||= '"'
326
332
  unless val =~ /^[a-zA-Z0-9$_\-\^]+$/
327
333
  val = options[:quote] +
@@ -37,8 +37,10 @@ module Blacklight
37
37
  end
38
38
 
39
39
  def bundle_install
40
- Bundler.with_clean_env do
41
- run "bundle install"
40
+ inside destination_root do
41
+ Bundler.with_clean_env do
42
+ run "bundle install"
43
+ end
42
44
  end
43
45
  end
44
46
 
@@ -81,9 +83,7 @@ module Blacklight
81
83
  blacklight_marc = String.new('blacklight-marc')
82
84
  gem blacklight_marc, '>= 7.0.0.rc1', '< 8'
83
85
 
84
- Bundler.with_clean_env do
85
- run "bundle install"
86
- end
86
+ bundle_install
87
87
 
88
88
  generate 'blacklight:marc:install'
89
89
  end
@@ -35,8 +35,10 @@ module Blacklight
35
35
  end
36
36
 
37
37
  def bundle_install
38
- Bundler.with_clean_env do
39
- run "bundle install"
38
+ inside destination_root do
39
+ Bundler.with_clean_env do
40
+ run "bundle install"
41
+ end
40
42
  end
41
43
  end
42
44
  end
@@ -24,8 +24,10 @@ module Blacklight
24
24
  gem "devise"
25
25
  gem "devise-guests", "~> 0.6"
26
26
 
27
- Bundler.with_clean_env do
28
- run "bundle install"
27
+ inside destination_root do
28
+ Bundler.with_clean_env do
29
+ run "bundle install"
30
+ end
29
31
  end
30
32
 
31
33
  generate "devise:install"
@@ -33,9 +33,8 @@ RSpec.describe Blacklight::ConfigurationHelperBehavior do
33
33
 
34
34
  describe "#default_document_index_view_type" do
35
35
  it "uses the first view with default set to true" do
36
- blacklight_config.view.a
37
- blacklight_config.view.b
38
- blacklight_config.view.b.default = true
36
+ blacklight_config.view.a({})
37
+ blacklight_config.view.b(default: true)
39
38
  expect(helper.default_document_index_view_type).to eq :b
40
39
  end
41
40
 
@@ -48,8 +47,8 @@ RSpec.describe Blacklight::ConfigurationHelperBehavior do
48
47
  describe "#document_index_views" do
49
48
  before do
50
49
  blacklight_config.view.abc = false
51
- blacklight_config.view.def.if = false
52
- blacklight_config.view.xyz.unless = true
50
+ blacklight_config.view.def(if: false)
51
+ blacklight_config.view.xyz(unless: true)
53
52
  end
54
53
 
55
54
  it "filters views using :if/:unless configuration" do
@@ -62,8 +61,8 @@ RSpec.describe Blacklight::ConfigurationHelperBehavior do
62
61
 
63
62
  describe '#document_index_view_controls' do
64
63
  before do
65
- blacklight_config.view.a
66
- blacklight_config.view.b.display_control = false
64
+ blacklight_config.view.a({})
65
+ blacklight_config.view.b(display_control: false)
67
66
  end
68
67
 
69
68
  it "filters index views to those set to display controls" do
@@ -127,7 +127,7 @@ RSpec.describe BlacklightHelper do
127
127
 
128
128
  it "renders view type specific actions" do
129
129
  allow(helper).to receive(:document_index_view_type).and_return(:custom)
130
- config.view.custom.document_actions = []
130
+ config.view.custom(document_actions: [])
131
131
  expect(helper.render_index_doc_actions(document)).to be_blank
132
132
  end
133
133
  end
@@ -315,11 +315,29 @@ RSpec.describe BlacklightHelper do
315
315
  end
316
316
 
317
317
  it "ignores missing templates" do
318
- blacklight_config.view.view_type.partials = %w[index_header a b]
318
+ blacklight_config.view.view_type(partials: %w[index_header a b])
319
319
 
320
320
  response = helper.render_document_index_with_view :view_type, [obj1, obj1]
321
321
  expect(response).to have_selector "div#documents"
322
322
  end
323
+
324
+ context 'with a template partial provided by the view config' do
325
+ before do
326
+ blacklight_config.view.gallery(template: '/my/partial')
327
+ end
328
+
329
+ def stub_template(hash)
330
+ view.view_paths.unshift(ActionView::FixtureResolver.new(hash))
331
+ end
332
+
333
+ it 'renders that template' do
334
+ stub_template 'my/_partial.html.erb' => 'some content'
335
+
336
+ response = helper.render_document_index_with_view :gallery, [obj1, obj1]
337
+
338
+ expect(response).to eq 'some content'
339
+ end
340
+ end
323
341
  end
324
342
 
325
343
  describe "#document_index_view_type" do
@@ -323,7 +323,7 @@ RSpec.describe CatalogHelper do
323
323
 
324
324
  it "supports view-specific field configuration" do
325
325
  allow(helper).to receive(:document_index_view_type).and_return(:some_view_type)
326
- blacklight_config.view.some_view_type.display_type_field = :other_type
326
+ blacklight_config.view.some_view_type(display_type_field: :other_type)
327
327
  doc = { other_type: "document" }
328
328
  expect(helper.render_document_class(doc)).to eq "blacklight-document"
329
329
  end
@@ -1,6 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe Blacklight::NestedOpenStructWithHashAccess do
4
+ subject { described_class.new(Blacklight::OpenStructWithHashAccess) }
5
+
6
+ describe '#key' do
7
+ context 'for an object provided by the initializer' do
8
+ subject { described_class.new(Blacklight::OpenStructWithHashAccess, a: { b: 1 }) }
9
+
10
+ it 'copies the key to the initialized value' do
11
+ expect(subject.a).to have_attributes key: :a, b: 1
12
+ end
13
+ end
14
+
15
+ context 'for an object provided through assignment' do
16
+ it 'copies the key to the initialized value' do
17
+ subject.a!
18
+
19
+ expect(subject.a).to have_attributes key: :a
20
+ end
21
+ end
22
+ end
23
+
4
24
  describe "#deep_dup" do
5
25
  it "preserves the current class" do
6
26
  expect(described_class.new(described_class).deep_dup).to be_a_kind_of described_class
@@ -23,4 +43,20 @@ RSpec.describe Blacklight::NestedOpenStructWithHashAccess do
23
43
  expect(subject.blah).to have_attributes(key: :blah)
24
44
  end
25
45
  end
46
+
47
+ describe 'adding new parameters' do
48
+ subject { described_class.new(Blacklight::Configuration::Field) }
49
+
50
+ it 'strips the trailing !' do
51
+ subject.blah!
52
+ expect(subject.blah).to have_attributes(key: :blah)
53
+ expect(subject.keys).to eq [:blah]
54
+ end
55
+
56
+ it 'supports direct assignment' do
57
+ subject.blah = '123'
58
+ expect(subject.blah).to eq '123'
59
+ expect(subject.keys).to eq [:blah]
60
+ end
61
+ end
26
62
  end
@@ -621,4 +621,14 @@ RSpec.describe "Blacklight::Configuration", api: true do
621
621
  end
622
622
  end
623
623
  end
624
+
625
+ describe '#freeze' do
626
+ it 'freezes the configuration' do
627
+ config.freeze
628
+
629
+ expect(config.a).to be_nil
630
+ expect { config.a = '123' }.to raise_error(FrozenError)
631
+ expect { config.view.a = '123' }.to raise_error(FrozenError)
632
+ end
633
+ end
624
634
  end
@@ -800,4 +800,13 @@ RSpec.describe Blacklight::Solr::SearchBuilderBehavior, api: true do
800
800
  expect(subject.to_hash.with_indifferent_access.dig(:json, :query, :bool, :must, 1, :edismax, :qf)).to eq '${author_qf}'
801
801
  end
802
802
  end
803
+
804
+ describe '#where' do
805
+ let(:user_params) { {} }
806
+
807
+ it 'adds additional query filters on the search' do
808
+ subject.where(id: [1, 2, 3])
809
+ expect(subject.to_hash).to include q: '{!lucene}id:(1 OR 2 OR 3)'
810
+ end
811
+ end
803
812
  end
@@ -477,7 +477,7 @@ RSpec.describe Blacklight::SearchService, api: true do
477
477
  end
478
478
 
479
479
  before do
480
- blacklight_config.view.opensearch.title_field = :field
480
+ blacklight_config.view.opensearch(title_field: :field)
481
481
  allow(repository).to receive(:search).and_return(mock_response)
482
482
  end
483
483
 
@@ -3,7 +3,7 @@
3
3
  RSpec.describe "catalog/constraints" do
4
4
  let :blacklight_config do
5
5
  Blacklight::Configuration.new do |config|
6
- config.view.xyz
6
+ config.view.xyz({})
7
7
  end
8
8
  end
9
9
 
@@ -46,4 +46,13 @@ RSpec.describe "catalog/_document" do
46
46
  expect(rendered).to have_selector 'article.document header', text: '22. xyz'
47
47
  expect(rendered).not_to match(/partial/)
48
48
  end
49
+
50
+ it 'renders the partial using a provided view config' do
51
+ view_config = Blacklight::Configuration::ViewConfig.new partials: %w[a]
52
+ stub_template "catalog/_a_default.html.erb" => "partial"
53
+
54
+ render partial: "catalog/document", locals: { document: document, document_counter: 1, view_config: view_config }
55
+
56
+ expect(rendered).to match(/partial/)
57
+ end
49
58
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  RSpec.describe "catalog/_document_list", type: :view do
4
4
  before do
5
- allow(view).to receive_messages(document_index_view_type: "some-view", documents: [])
5
+ allow(view).to receive_messages(document_index_view_type: "some-view", documents: [], blacklight_config: nil)
6
6
  end
7
7
 
8
8
  it "includes a class for the current view" do
@@ -3,13 +3,9 @@
3
3
  RSpec.describe "catalog/_view_type_group" do
4
4
  let(:blacklight_config) { Blacklight::Configuration.new }
5
5
  let(:response) { instance_double(Blacklight::Solr::Response, empty?: false) }
6
- let(:icon_instance) { instance_double(Blacklight::Icon) }
7
6
 
8
7
  before do
9
8
  allow(view).to receive(:view_label), &:to_s
10
- allow(Blacklight::Icon).to receive(:new).and_return icon_instance
11
- allow(icon_instance).to receive(:svg).and_return '<svg></svg>'
12
- allow(icon_instance).to receive(:options).and_return({})
13
9
  allow(view).to receive_messages(how_sort_and_per_page?: true, blacklight_config: blacklight_config)
14
10
  controller.request.path_parameters[:action] = 'index'
15
11
  assign(:response, response)
@@ -24,13 +20,16 @@ RSpec.describe "catalog/_view_type_group" do
24
20
  it "displays the group" do
25
21
  blacklight_config.configure do |config|
26
22
  config.view.delete(:list)
27
- config.view.a
28
- config.view.b
29
- config.view.c
23
+ config.view.a(icon: :list)
24
+ config.view.b(icon: :list)
25
+ config.view.c(icon: :list)
30
26
  end
31
27
  render partial: 'catalog/view_type_group'
32
28
  expect(rendered).to have_selector('.btn-group.view-type-group')
33
29
  expect(rendered).to have_selector('.view-type-a', text: 'a')
30
+ within '.view-type-a' do
31
+ expect(rendered).to have_selector 'svg'
32
+ end
34
33
  expect(rendered).to have_selector('.view-type-b', text: 'b')
35
34
  expect(rendered).to have_selector('.view-type-c', text: 'c')
36
35
  end
@@ -38,8 +37,8 @@ RSpec.describe "catalog/_view_type_group" do
38
37
  it "sets the current view to 'active'" do
39
38
  blacklight_config.configure do |config|
40
39
  config.view.delete(:list)
41
- config.view.a
42
- config.view.b
40
+ config.view.a(icon: :list)
41
+ config.view.b(icon: :list)
43
42
  end
44
43
  render partial: 'catalog/view_type_group'
45
44
  expect(rendered).to have_selector('.active', text: 'a')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blacklight
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.17.0
4
+ version: 7.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Rochkind
@@ -17,7 +17,7 @@ authors:
17
17
  autorequire:
18
18
  bindir: exe
19
19
  cert_chain: []
20
- date: 2021-04-21 00:00:00.000000000 Z
20
+ date: 2021-05-01 00:00:00.000000000 Z
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
23
  name: rails