blacklight 9.0.0.beta6 → 9.0.0.beta8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.docker/app/Dockerfile +2 -1
  3. data/.github/matrix.json +21 -3
  4. data/.solr_wrapper.yml +1 -1
  5. data/VERSION +1 -1
  6. data/app/assets/javascripts/blacklight/blacklight.esm.js +9 -5
  7. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
  8. data/app/assets/javascripts/blacklight/blacklight.js +9 -5
  9. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
  10. data/app/components/blacklight/advanced_search_form_component.rb +2 -1
  11. data/app/components/blacklight/constraints_component.html.erb +3 -8
  12. data/app/components/blacklight/constraints_component.rb +57 -14
  13. data/app/components/blacklight/document/bookmark_component.rb +1 -1
  14. data/app/components/blacklight/document/page_header_component.rb +1 -1
  15. data/app/components/blacklight/document_component.rb +20 -24
  16. data/app/components/blacklight/facet_item_pivot_component.rb +4 -0
  17. data/app/components/blacklight/facets/filters_component.rb +1 -1
  18. data/app/components/blacklight/facets/item_component.rb +3 -0
  19. data/app/components/blacklight/facets/selected_value_component.rb +1 -1
  20. data/app/components/blacklight/facets/suggest_component.rb +2 -3
  21. data/app/components/blacklight/header_component.rb +2 -2
  22. data/app/components/blacklight/metadata_field_component.html.erb +2 -2
  23. data/app/components/blacklight/metadata_field_component.rb +2 -1
  24. data/app/components/blacklight/metadata_field_layout_component.rb +9 -4
  25. data/app/components/blacklight/search_bar_component.html.erb +1 -1
  26. data/app/controllers/concerns/blacklight/catalog.rb +8 -4
  27. data/app/javascript/blacklight-frontend/facet_suggest.js +2 -1
  28. data/app/javascript/blacklight-frontend/modal.js +7 -4
  29. data/app/presenters/blacklight/constraint_presenter.rb +22 -0
  30. data/app/presenters/blacklight/document_presenter.rb +6 -5
  31. data/app/presenters/blacklight/facet_field_presenter.rb +10 -3
  32. data/app/presenters/blacklight/facet_item_pivot_presenter.rb +1 -5
  33. data/app/presenters/blacklight/facet_item_presenter.rb +0 -18
  34. data/app/presenters/blacklight/field_presenter.rb +4 -2
  35. data/app/presenters/blacklight/rendering/abstract_step.rb +7 -1
  36. data/app/presenters/blacklight/rendering/join.rb +9 -5
  37. data/app/presenters/blacklight/rendering/terminator.rb +1 -1
  38. data/app/views/catalog/_document.atom.builder +1 -1
  39. data/app/views/catalog/_document.html.erb +1 -1
  40. data/app/views/catalog/_show_main_content.html.erb +9 -5
  41. data/app/views/catalog/index.html.erb +0 -1
  42. data/app/views/catalog/show.html.erb +2 -2
  43. data/blacklight.gemspec +1 -1
  44. data/config/locales/blacklight.ar.yml +1 -2
  45. data/config/locales/blacklight.ca.yml +1 -2
  46. data/config/locales/blacklight.de.yml +1 -2
  47. data/config/locales/blacklight.en.yml +2 -3
  48. data/config/locales/blacklight.es.yml +1 -2
  49. data/config/locales/blacklight.fr.yml +1 -2
  50. data/config/locales/blacklight.hu.yml +1 -2
  51. data/config/locales/blacklight.it.yml +1 -2
  52. data/config/locales/blacklight.nl.yml +1 -2
  53. data/config/locales/blacklight.pt-BR.yml +1 -2
  54. data/config/locales/blacklight.sq.yml +1 -2
  55. data/config/locales/blacklight.zh.yml +1 -2
  56. data/lib/blacklight/component.rb +7 -1
  57. data/lib/blacklight/configuration/facet_field.rb +4 -0
  58. data/lib/blacklight/configuration/view_config.rb +30 -16
  59. data/lib/blacklight/configuration.rb +58 -5
  60. data/lib/blacklight/search_state/pivot_filter_field.rb +1 -1
  61. data/lib/blacklight/solr/field_reflection_search_builder.rb +11 -0
  62. data/lib/blacklight/solr/repository.rb +5 -5
  63. data/lib/blacklight/solr/search_builder_behavior.rb +19 -2
  64. data/lib/blacklight/solr/single_doc_search_builder.rb +25 -0
  65. data/lib/generators/blacklight/templates/.solr_wrapper.yml +1 -1
  66. data/lib/generators/blacklight/templates/catalog_controller.rb +26 -4
  67. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +0 -67
  68. data/package.json +1 -1
  69. data/spec/components/blacklight/constraints_component_spec.rb +2 -2
  70. data/spec/components/blacklight/document_component_spec.rb +8 -15
  71. data/spec/components/blacklight/facets/filters_component_spec.rb +2 -2
  72. data/spec/components/blacklight/facets/index_navigation_component_spec.rb +2 -1
  73. data/spec/components/blacklight/facets/suggest_component_spec.rb +15 -1
  74. data/spec/components/blacklight/search_bar_component_spec.rb +24 -1
  75. data/spec/controllers/blacklight/catalog_spec.rb +1 -1
  76. data/spec/features/advanced_search_spec.rb +39 -20
  77. data/spec/features/search_filters_spec.rb +3 -3
  78. data/spec/features/search_spec.rb +3 -3
  79. data/spec/models/blacklight/configuration_spec.rb +126 -0
  80. data/spec/models/blacklight/solr/repository_spec.rb +6 -0
  81. data/spec/models/blacklight/solr/search_builder_behavior_spec.rb +52 -6
  82. data/spec/presenters/blacklight/constraint_presenter_spec.rb +32 -0
  83. data/spec/presenters/blacklight/document_presenter_spec.rb +3 -3
  84. data/spec/presenters/blacklight/facet_item_presenter_spec.rb +0 -7
  85. data/spec/presenters/blacklight/field_presenter_spec.rb +103 -22
  86. data/spec/presenters/blacklight/rendering/pipeline_spec.rb +130 -14
  87. data/spec/support/presenter_test_helpers.rb +1 -1
  88. data/spec/views/catalog/index.atom.builder_spec.rb +2 -0
  89. metadata +18 -10
  90. data/app/views/shared/_sitelinks_search_box.html.erb +0 -12
  91. data/spec/features/sitelinks_search_box_spec.rb +0 -13
@@ -12,20 +12,15 @@ RSpec.describe Blacklight::Rendering::Pipeline do
12
12
  let(:values) { %w[a b] }
13
13
  let(:field_config) { Blacklight::Configuration::NullField.new }
14
14
 
15
- it { is_expected.to eq "a and b" }
16
-
17
- context "when separator_options are in the config" do
18
- let(:values) { %w[c d] }
19
- let(:field_config) { Blacklight::Configuration::NullField.new(itemprop: nil, separator_options: { two_words_connector: '; ' }) }
20
-
21
- it { is_expected.to eq "c; d" }
22
- end
15
+ it { is_expected.to eq %w[a b] }
23
16
 
24
17
  context "when itemprop is in the config" do
25
18
  let(:values) { ['a'] }
26
19
  let(:field_config) { Blacklight::Configuration::NullField.new(itemprop: 'some-prop', separator_options: nil) }
27
20
 
28
- it { is_expected.to have_css("span[@itemprop='some-prop']", text: "a") }
21
+ it 'renders the expected markup' do
22
+ expect(rendered.first).to have_css("span[@itemprop='some-prop']", text: "a")
23
+ end
29
24
  end
30
25
 
31
26
  it 'sets the operations on the instance as equal to the class variable' do
@@ -37,13 +32,134 @@ RSpec.describe Blacklight::Rendering::Pipeline do
37
32
  end
38
33
 
39
34
  context 'outside of an HTML context' do
40
- let(:options) { { format: 'text' } }
35
+ context 'when options determines format' do
36
+ let(:options) { { format: 'text' } }
37
+
38
+ let(:values) { ['"blah"', "<notatag>"] }
39
+ let(:field_config) { Blacklight::Configuration::NullField.new itemprop: 'some-prop' }
40
+
41
+ it 'does not HTML escape values or inject HTML tags' do
42
+ expect(rendered).to eq ['"blah"', "<notatag>"]
43
+ end
44
+ end
45
+
46
+ context 'when context determines format' do
47
+ let(:values) { ['"blah"', "<notatag>"] }
48
+ let(:field_config) { Blacklight::Configuration::NullField.new itemprop: 'some-prop' }
49
+ let(:controller) { CatalogController.new }
50
+ let(:search_state) { Blacklight::SearchState.new({ format: 'text' }, controller.blacklight_config, controller) }
51
+
52
+ before { allow(context).to receive(:search_state).and_return(search_state) }
53
+
54
+ it 'does not HTML escape values or inject HTML tags' do
55
+ expect(rendered).to eq ['"blah"', '<notatag>']
56
+ end
57
+ end
58
+ end
59
+
60
+ context 'when link_to_facet is in the config' do
61
+ let(:values) { %w[book manuscript] }
62
+ let(:field_config) { Blacklight::Configuration::Field.new(field: 'format', key: 'format', link_to_facet: true) }
63
+ let(:controller) { CatalogController.new }
64
+ let(:search_state) { Blacklight::SearchState.new({}, controller.blacklight_config, controller) }
65
+
66
+ before do
67
+ allow(context).to receive(:search_state).and_return(search_state)
68
+ allow(context).to receive(:search_action_path) { |f| "/catalog?f[format][]=#{f['f']['format'].first}" }
69
+ allow(context).to receive(:link_to) { |value, link| ActiveSupport::SafeBuffer.new("<a href=#{link}>#{value}</a>") }
70
+ end
71
+
72
+ it 'renders html' do
73
+ expect(rendered).to eq ["<a href=/catalog?f[format][]=book>book</a>", "<a href=/catalog?f[format][]=manuscript>manuscript</a>"]
74
+ end
75
+
76
+ context 'outside html context' do
77
+ let(:values) { %w[book manuscript] }
78
+ let(:field_config) { Blacklight::Configuration::Field.new(field: 'format', link_to_facet: true) }
79
+ let(:search_state) { Blacklight::SearchState.new({ format: 'json' }, CatalogController.blacklight_config, CatalogController.new) }
80
+
81
+ it 'does not render html' do
82
+ expect(rendered).to eq %w[book manuscript]
83
+ end
84
+ end
85
+ end
86
+
87
+ context 'when joining values' do
88
+ context 'with join in the config' do
89
+ let(:field_config) { Blacklight::Configuration::NullField.new(join: true) }
90
+
91
+ it 'joins the values' do
92
+ expect(rendered).to eq ['a and b']
93
+ end
94
+ end
95
+
96
+ context 'with join is in the options' do
97
+ let(:options) { { join: true } }
98
+ let(:field_config) { Blacklight::Configuration::NullField.new }
99
+
100
+ it 'joins the values' do
101
+ expect(rendered).to eq ['a and b']
102
+ end
103
+ end
104
+
105
+ context 'with separator_options in the config' do
106
+ let(:values) { %w[c d] }
107
+ let(:field_config) { Blacklight::Configuration::NullField.new(separator_options: { two_words_connector: '; ' }) }
108
+
109
+ it { is_expected.to eq ["c; d"] }
110
+ end
111
+
112
+ context 'with a single value' do
113
+ let(:values) { [1] }
114
+ let(:field_config) { Blacklight::Configuration::NullField.new(join: true) }
115
+
116
+ it 'does not run the join step' do
117
+ expect(rendered).to eq [1]
118
+ end
119
+ end
120
+
121
+ context 'with a single html value' do
122
+ let(:values) { ['<b>value</b>'] }
123
+ let(:field_config) { Blacklight::Configuration::NullField.new(join: true) }
124
+
125
+ it 'does not escape the html' do
126
+ expect(rendered).to eq ['<b>value</b>']
127
+ end
128
+
129
+ it 'does not mark the value as html_safe' do
130
+ expect(rendered.first).not_to be_html_safe
131
+ end
132
+ end
133
+
134
+ context 'with an array of values containing unsafe characters' do
135
+ let(:values) { ['<a', 'b'] }
136
+ let(:field_config) { Blacklight::Configuration::NullField.new(join: true) }
137
+
138
+ it 'escapes the unsafe characters' do
139
+ expect(rendered).to eq ["&lt;a and b"]
140
+ end
141
+
142
+ it 'marks the joined value as html_safe' do
143
+ expect(rendered.first).to be_html_safe
144
+ end
145
+ end
146
+
147
+ context 'outside the html context' do
148
+ let(:values) { %w[a b <c] }
149
+ let(:field_config) { Blacklight::Configuration::Field.new(join: true) }
150
+ let(:options) { { format: 'json' } }
151
+
152
+ it 'does not run the join step' do
153
+ expect(rendered).to eq %w[a b <c]
154
+ end
41
155
 
42
- let(:values) { ['"blah"', "<notatag>"] }
43
- let(:field_config) { Blacklight::Configuration::NullField.new itemprop: 'some-prop' }
156
+ it 'does not escape unsafe html characters' do
157
+ expect(rendered.last).to eq '<c'
158
+ end
44
159
 
45
- it 'does not HTML escape values or inject HTML tags' do
46
- expect(rendered).to eq '"blah" and <notatag>'
160
+ it 'does not mark the values as html_safe' do
161
+ expect(rendered.none?(&:html_safe?)).to be true
162
+ end
47
163
  end
48
164
  end
49
165
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module PresenterTestHelpers
4
4
  def controller
5
- @controller ||= ViewComponent::Base.test_controller.constantize.new.tap { |c| c.request = request }.extend(Rails.application.routes.url_helpers)
5
+ @controller ||= ApplicationController.new.tap { |c| c.request = request }.extend(Rails.application.routes.url_helpers)
6
6
  end
7
7
 
8
8
  def request
@@ -96,6 +96,8 @@ RSpec.describe "catalog/index" do
96
96
  context 'with a custom template' do
97
97
  before do
98
98
  my_template = Class.new(ViewComponent::Base) do
99
+ def initialize(**); end
100
+
99
101
  def call
100
102
  'whatever content'.html_safe
101
103
  end
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: 9.0.0.beta6
4
+ version: 9.0.0.beta8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Rochkind
@@ -16,7 +16,7 @@ authors:
16
16
  - Justin Coyne
17
17
  bindir: exe
18
18
  cert_chain: []
19
- date: 2025-07-23 00:00:00.000000000 Z
19
+ date: 1980-01-02 00:00:00.000000000 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: rails
@@ -112,16 +112,22 @@ dependencies:
112
112
  name: view_component
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '3.0'
118
+ - - "<"
116
119
  - !ruby/object:Gem::Version
117
- version: '3.9'
120
+ version: '5.0'
118
121
  type: :runtime
119
122
  prerelease: false
120
123
  version_requirements: !ruby/object:Gem::Requirement
121
124
  requirements:
122
- - - "~>"
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '3.0'
128
+ - - "<"
123
129
  - !ruby/object:Gem::Version
124
- version: '3.9'
130
+ version: '5.0'
125
131
  - !ruby/object:Gem::Dependency
126
132
  name: zeitwerk
127
133
  requirement: !ruby/object:Gem::Requirement
@@ -632,6 +638,7 @@ files:
632
638
  - app/models/search_builder.rb
633
639
  - app/models/solr_document.rb
634
640
  - app/presenters/blacklight/clause_presenter.rb
641
+ - app/presenters/blacklight/constraint_presenter.rb
635
642
  - app/presenters/blacklight/document_presenter.rb
636
643
  - app/presenters/blacklight/facet_checkbox_item_presenter.rb
637
644
  - app/presenters/blacklight/facet_field_presenter.rb
@@ -731,7 +738,6 @@ files:
731
738
  - app/views/shared/_flash_msg.html.erb
732
739
  - app/views/shared/_footer.html.erb
733
740
  - app/views/shared/_modal.html.erb
734
- - app/views/shared/_sitelinks_search_box.html.erb
735
741
  - app/views/shared/_user_util_links.html.erb
736
742
  - blacklight.gemspec
737
743
  - compose.yaml
@@ -792,6 +798,7 @@ files:
792
798
  - lib/blacklight/solr/document.rb
793
799
  - lib/blacklight/solr/facet_paginator.rb
794
800
  - lib/blacklight/solr/facet_search_builder_behavior.rb
801
+ - lib/blacklight/solr/field_reflection_search_builder.rb
795
802
  - lib/blacklight/solr/repository.rb
796
803
  - lib/blacklight/solr/request.rb
797
804
  - lib/blacklight/solr/response.rb
@@ -804,6 +811,7 @@ files:
804
811
  - lib/blacklight/solr/response/response.rb
805
812
  - lib/blacklight/solr/response/spelling.rb
806
813
  - lib/blacklight/solr/search_builder_behavior.rb
814
+ - lib/blacklight/solr/single_doc_search_builder.rb
807
815
  - lib/blacklight/version.rb
808
816
  - lib/generators/blacklight/assets/importmap_generator.rb
809
817
  - lib/generators/blacklight/assets/propshaft_generator.rb
@@ -904,7 +912,6 @@ files:
904
912
  - spec/features/search_results_spec.rb
905
913
  - spec/features/search_sort_spec.rb
906
914
  - spec/features/search_spec.rb
907
- - spec/features/sitelinks_search_box_spec.rb
908
915
  - spec/features/sms_spec.rb
909
916
  - spec/fixtures/sample_solr_documents.yml
910
917
  - spec/helpers/blacklight/configuration_helper_behavior_spec.rb
@@ -960,6 +967,7 @@ files:
960
967
  - spec/models/search_spec.rb
961
968
  - spec/models/solr_document_spec.rb
962
969
  - spec/presenters/blacklight/clause_presenter_spec.rb
970
+ - spec/presenters/blacklight/constraint_presenter_spec.rb
963
971
  - spec/presenters/blacklight/document_presenter_spec.rb
964
972
  - spec/presenters/blacklight/facet_checkbox_item_presenter_spec.rb
965
973
  - spec/presenters/blacklight/facet_field_presenter_spec.rb
@@ -1023,7 +1031,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1023
1031
  - !ruby/object:Gem::Version
1024
1032
  version: '0'
1025
1033
  requirements: []
1026
- rubygems_version: 3.6.3
1034
+ rubygems_version: 3.7.1
1027
1035
  specification_version: 4
1028
1036
  summary: Blacklight provides a discovery interface for any Solr (http://lucene.apache.org/solr)
1029
1037
  index.
@@ -1088,7 +1096,6 @@ test_files:
1088
1096
  - spec/features/search_results_spec.rb
1089
1097
  - spec/features/search_sort_spec.rb
1090
1098
  - spec/features/search_spec.rb
1091
- - spec/features/sitelinks_search_box_spec.rb
1092
1099
  - spec/features/sms_spec.rb
1093
1100
  - spec/fixtures/sample_solr_documents.yml
1094
1101
  - spec/helpers/blacklight/configuration_helper_behavior_spec.rb
@@ -1144,6 +1151,7 @@ test_files:
1144
1151
  - spec/models/search_spec.rb
1145
1152
  - spec/models/solr_document_spec.rb
1146
1153
  - spec/presenters/blacklight/clause_presenter_spec.rb
1154
+ - spec/presenters/blacklight/constraint_presenter_spec.rb
1147
1155
  - spec/presenters/blacklight/document_presenter_spec.rb
1148
1156
  - spec/presenters/blacklight/facet_checkbox_item_presenter_spec.rb
1149
1157
  - spec/presenters/blacklight/facet_field_presenter_spec.rb
@@ -1,12 +0,0 @@
1
- <script type="application/ld+json">
2
- {
3
- "@context": "http://schema.org",
4
- "@type": "WebSite",
5
- "url": "<%= root_url %>",
6
- "potentialAction": {
7
- "@type": "SearchAction",
8
- "target": "<%= root_url %>?q={search_term_string}",
9
- "query-input": "required name=search_term_string"
10
- }
11
- }
12
- </script>
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe 'Sitelinks search box' do
4
- it 'is home page' do
5
- visit root_path
6
- expect(page).to have_css 'script[type="application/ld+json"]', visible: :hidden
7
- end
8
-
9
- it 'on search page' do
10
- visit search_catalog_path q: 'book'
11
- expect(page).to have_no_css 'script[type="application/ld+json"]', visible: :hidden
12
- end
13
- end