blacklight 9.0.0.beta1 → 9.0.0.beta2

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 (203) hide show
  1. checksums.yaml +4 -4
  2. data/.github/matrix.json +47 -0
  3. data/.github/workflows/build.yml +16 -0
  4. data/.github/workflows/lint.yml +25 -0
  5. data/.github/workflows/main.yml +22 -0
  6. data/.github/workflows/release_7_x_scheduled.yml +39 -0
  7. data/.github/workflows/release_8_x_scheduled.yml +39 -0
  8. data/.github/workflows/test.yml +53 -0
  9. data/.rubocop.yml +70 -2
  10. data/.rubocop_todo.yml +43 -67
  11. data/.solr_wrapper.yml +2 -0
  12. data/VERSION +1 -1
  13. data/app/assets/builds/blacklight.css +19 -15
  14. data/app/assets/javascripts/blacklight/blacklight.esm.js +31 -69
  15. data/app/assets/javascripts/blacklight/blacklight.esm.js.map +1 -1
  16. data/app/assets/javascripts/blacklight/blacklight.js +31 -69
  17. data/app/assets/javascripts/blacklight/blacklight.js.map +1 -1
  18. data/app/assets/stylesheets/blacklight/_bootstrap_overrides.scss +4 -0
  19. data/app/assets/stylesheets/blacklight/_facets.scss +2 -2
  20. data/app/assets/stylesheets/blacklight/_header.scss +4 -0
  21. data/app/assets/stylesheets/blacklight/_modal.scss +9 -8
  22. data/app/assets/stylesheets/blacklight/_pagination.scss +1 -3
  23. data/app/assets/stylesheets/blacklight/_search_history.scss +0 -4
  24. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +3 -0
  25. data/app/components/blacklight/advanced_search_form_component.rb +2 -2
  26. data/app/components/blacklight/constraints_component.rb +2 -2
  27. data/app/components/blacklight/document/action_component.rb +1 -3
  28. data/app/components/blacklight/document/bookmark_component.rb +2 -2
  29. data/app/components/blacklight/document/more_like_this_component.rb +2 -2
  30. data/app/components/blacklight/document/page_header_component.rb +2 -2
  31. data/app/components/blacklight/document/thumbnail_component.html.erb +3 -7
  32. data/app/components/blacklight/document/thumbnail_component.rb +7 -6
  33. data/app/components/blacklight/document_component.rb +3 -3
  34. data/app/components/blacklight/document_title_component.rb +3 -10
  35. data/app/components/blacklight/facet_field_checkboxes_component.rb +2 -20
  36. data/app/components/blacklight/facet_field_component.rb +2 -17
  37. data/app/components/blacklight/facet_field_filter_component.rb +2 -21
  38. data/app/components/blacklight/facet_field_inclusive_constraint_component.rb +4 -25
  39. data/app/components/blacklight/facet_field_list_component.rb +2 -32
  40. data/app/components/blacklight/facet_field_no_layout_component.rb +2 -10
  41. data/app/components/blacklight/facet_field_pagination_component.html.erb +2 -2
  42. data/app/components/blacklight/facet_item_component.rb +2 -74
  43. data/app/components/blacklight/facet_item_pivot_component.rb +1 -1
  44. data/app/components/blacklight/facets/checkboxes_component.rb +26 -0
  45. data/app/components/blacklight/facets/count_component.rb +23 -0
  46. data/app/components/blacklight/{facet_field_component.html.erb → facets/field_component.html.erb} +1 -1
  47. data/app/components/blacklight/facets/field_component.rb +23 -0
  48. data/app/components/blacklight/facets/filters_component.html.erb +4 -0
  49. data/app/components/blacklight/facets/filters_component.rb +27 -0
  50. data/app/components/blacklight/{facet_field_inclusive_constraint_component.html.erb → facets/inclusive_constraint_component.html.erb} +1 -1
  51. data/app/components/blacklight/facets/inclusive_constraint_component.rb +31 -0
  52. data/app/components/blacklight/{facet_field_filter_component.html.erb → facets/index_navigation_component.html.erb} +1 -1
  53. data/app/components/blacklight/facets/index_navigation_component.rb +32 -0
  54. data/app/components/blacklight/facets/item_component.rb +73 -0
  55. data/app/components/blacklight/facets/list_component.html.erb +11 -0
  56. data/app/components/blacklight/facets/list_component.rb +38 -0
  57. data/app/components/blacklight/facets/no_layout_component.rb +16 -0
  58. data/app/components/blacklight/facets/selected_value_component.rb +29 -0
  59. data/app/components/blacklight/facets/suggest_component.html.erb +12 -0
  60. data/app/components/blacklight/facets/suggest_component.rb +22 -0
  61. data/app/components/blacklight/metadata_field_plain_text_layout_component.rb +2 -2
  62. data/app/components/blacklight/response/facet_group_component.html.erb +1 -1
  63. data/app/components/blacklight/response/facet_group_component.rb +5 -1
  64. data/app/components/blacklight/system/dropdown_component.html.erb +1 -1
  65. data/app/components/blacklight/system/dropdown_component.rb +1 -1
  66. data/app/components/blacklight/top_navbar_component.html.erb +1 -1
  67. data/app/controllers/concerns/blacklight/bookmarks.rb +3 -3
  68. data/app/controllers/concerns/blacklight/catalog.rb +10 -25
  69. data/app/controllers/concerns/blacklight/controller.rb +1 -1
  70. data/app/controllers/concerns/blacklight/facetable.rb +34 -0
  71. data/app/controllers/concerns/blacklight/search_context.rb +1 -1
  72. data/app/controllers/concerns/blacklight/searchable.rb +1 -1
  73. data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -2
  74. data/app/helpers/blacklight/document_helper_behavior.rb +3 -1
  75. data/app/helpers/blacklight/facets_helper_behavior.rb +9 -0
  76. data/app/helpers/blacklight/icon_helper_behavior.rb +2 -2
  77. data/app/javascript/blacklight-frontend/checkbox_submit.js +3 -0
  78. data/app/javascript/blacklight-frontend/debounce.js +1 -1
  79. data/app/javascript/blacklight-frontend/facet_suggest.js +23 -3
  80. data/app/javascript/blacklight-frontend/index.js +0 -2
  81. data/app/javascript/blacklight-frontend/modal.js +1 -4
  82. data/app/javascript/blacklight-frontend/search_context.js +3 -2
  83. data/app/models/facet_search_builder.rb +5 -0
  84. data/app/presenters/blacklight/facet_field_presenter.rb +1 -1
  85. data/app/presenters/blacklight/json_presenter.rb +1 -3
  86. data/app/presenters/blacklight/rendering/helper_method.rb +4 -4
  87. data/app/presenters/blacklight/rendering/join.rb +2 -2
  88. data/app/services/blacklight/facet_search_service.rb +44 -0
  89. data/app/services/blacklight/field_retriever.rb +1 -1
  90. data/app/services/blacklight/search_service.rb +6 -6
  91. data/app/values/blacklight/types.rb +2 -2
  92. data/app/views/catalog/_facet_pivot.html.erb +1 -1
  93. data/app/views/catalog/_home_text.html.erb +2 -2
  94. data/app/views/catalog/_sort_and_per_page.html.erb +1 -1
  95. data/app/views/catalog/facet.html.erb +8 -10
  96. data/config/locales/blacklight.ar.yml +2 -2
  97. data/config/locales/blacklight.es.yml +2 -2
  98. data/config/locales/blacklight.fr.yml +2 -2
  99. data/config/locales/blacklight.hu.yml +2 -2
  100. data/config/locales/blacklight.it.yml +2 -2
  101. data/config/locales/blacklight.nl.yml +1 -1
  102. data/config/locales/blacklight.pt-BR.yml +2 -2
  103. data/config/locales/blacklight.sq.yml +2 -2
  104. data/config/locales/blacklight.zh.yml +2 -2
  105. data/lib/blacklight/abstract_repository.rb +2 -2
  106. data/lib/blacklight/abstract_search_builder.rb +154 -0
  107. data/lib/blacklight/configuration/context.rb +3 -3
  108. data/lib/blacklight/configuration/facet_field.rb +6 -6
  109. data/lib/blacklight/configuration/field.rb +4 -4
  110. data/lib/blacklight/configuration/fields.rb +0 -1
  111. data/lib/blacklight/configuration/search_field.rb +1 -1
  112. data/lib/blacklight/configuration/view_config.rb +2 -2
  113. data/lib/blacklight/configuration.rb +6 -7
  114. data/lib/blacklight/facet_search_builder.rb +18 -0
  115. data/lib/blacklight/nested_open_struct_with_hash_access.rb +1 -1
  116. data/lib/blacklight/open_struct_with_hash_access.rb +2 -2
  117. data/lib/blacklight/search_builder.rb +1 -159
  118. data/lib/blacklight/search_state/filter_field.rb +4 -4
  119. data/lib/blacklight/search_state/pivot_filter_field.rb +4 -4
  120. data/lib/blacklight/solr/abstract_filter_query_builder.rb +77 -0
  121. data/lib/blacklight/solr/default_filter_query_builder.rb +20 -0
  122. data/lib/blacklight/solr/facet_search_builder_behavior.rb +62 -0
  123. data/lib/blacklight/solr/repository.rb +8 -9
  124. data/lib/blacklight/solr/response/facets.rb +2 -2
  125. data/lib/blacklight/solr/response/params.rb +0 -4
  126. data/lib/blacklight/solr/response.rb +5 -1
  127. data/lib/blacklight/solr/search_builder_behavior.rb +17 -132
  128. data/lib/blacklight.rb +1 -1
  129. data/lib/generators/blacklight/assets/importmap_generator.rb +3 -5
  130. data/lib/generators/blacklight/assets_generator.rb +1 -1
  131. data/lib/generators/blacklight/search_builder_generator.rb +1 -1
  132. data/lib/generators/blacklight/templates/.solr_wrapper.yml +2 -0
  133. data/lib/generators/blacklight/templates/catalog_controller.rb +3 -1
  134. data/lib/generators/blacklight/templates/solr/conf/solrconfig.xml +0 -4
  135. data/package.json +3 -3
  136. data/spec/components/blacklight/advanced_search_form_component_spec.rb +18 -22
  137. data/spec/components/blacklight/constraint_layout_component_spec.rb +8 -8
  138. data/spec/components/blacklight/constraints_component_spec.rb +11 -11
  139. data/spec/components/blacklight/document/action_component_spec.rb +23 -15
  140. data/spec/components/blacklight/document/group_component_spec.rb +10 -15
  141. data/spec/components/blacklight/document/page_header_component_spec.rb +35 -28
  142. data/spec/components/blacklight/document/sidebar_component_spec.rb +5 -11
  143. data/spec/components/blacklight/document_component_spec.rb +98 -65
  144. data/spec/components/blacklight/facet_component_spec.rb +12 -8
  145. data/spec/components/blacklight/facet_item_pivot_component_spec.rb +12 -12
  146. data/spec/components/blacklight/{facet_field_checkboxes_component_spec.rb → facets/checkboxes_component_spec.rb} +13 -13
  147. data/spec/components/blacklight/facets/filters_component_spec.rb +36 -0
  148. data/spec/components/blacklight/facets/index_navigation_component_spec.rb +40 -0
  149. data/spec/components/blacklight/{facet_item_component_spec.rb → facets/item_component_spec.rb} +10 -10
  150. data/spec/components/blacklight/{facet_field_list_component_spec.rb → facets/list_component_spec.rb} +23 -23
  151. data/spec/components/blacklight/facets/suggest_component_spec.rb +68 -0
  152. data/spec/components/blacklight/header_component_spec.rb +2 -4
  153. data/spec/components/blacklight/hidden_search_state_component_spec.rb +7 -7
  154. data/spec/components/blacklight/metadata_field_component_spec.rb +17 -15
  155. data/spec/components/blacklight/response/facet_group_component_spec.rb +37 -0
  156. data/spec/components/blacklight/response/pagination_component_spec.rb +1 -1
  157. data/spec/components/blacklight/response/spellcheck_component_spec.rb +1 -1
  158. data/spec/components/blacklight/search_bar_component_spec.rb +4 -4
  159. data/spec/components/blacklight/search_context/server_applied_params_component_spec.rb +2 -2
  160. data/spec/components/blacklight/search_context/server_item_pagination_component_spec.rb +3 -5
  161. data/spec/components/blacklight/skip_link_component_spec.rb +8 -11
  162. data/spec/components/blacklight/start_over_button_component_spec.rb +4 -4
  163. data/spec/components/blacklight/system/dropdown_component_spec.rb +26 -0
  164. data/spec/components/blacklight/system/flash_message_component_spec.rb +7 -11
  165. data/spec/controllers/catalog_controller_spec.rb +12 -20
  166. data/spec/features/facets_spec.rb +70 -7
  167. data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +10 -0
  168. data/spec/lib/blacklight/configuration/facet_field_spec.rb +2 -2
  169. data/spec/lib/blacklight/parameters_spec.rb +12 -1
  170. data/spec/lib/blacklight/search_state/filter_field_spec.rb +18 -0
  171. data/spec/models/blacklight/configuration_spec.rb +32 -28
  172. data/spec/models/blacklight/facet_search_builder_spec.rb +19 -0
  173. data/spec/models/blacklight/search_builder_spec.rb +1 -11
  174. data/spec/models/blacklight/solr/default_filter_query_builder_spec.rb +72 -0
  175. data/spec/models/blacklight/solr/document_spec.rb +0 -4
  176. data/spec/models/blacklight/solr/facet_search_builder_behavior_spec.rb +929 -0
  177. data/spec/models/blacklight/solr/repository_spec.rb +31 -29
  178. data/spec/models/blacklight/solr/response/facets_spec.rb +86 -40
  179. data/spec/models/blacklight/solr/response/group_response_spec.rb +8 -5
  180. data/spec/models/blacklight/solr/response/group_spec.rb +9 -5
  181. data/spec/models/blacklight/solr/response_spec.rb +96 -64
  182. data/spec/models/blacklight/solr/search_builder_behavior_spec.rb +2 -227
  183. data/spec/models/solr_document_spec.rb +5 -1
  184. data/spec/services/blacklight/search_service_spec.rb +6 -27
  185. data/spec/spec_helper.rb +0 -1
  186. data/spec/support/view_component_test_helpers.rb +0 -18
  187. data/spec/views/catalog/facet.html.erb_spec.rb +10 -3
  188. data/spec/views/catalog/index.atom.builder_spec.rb +6 -3
  189. data/spec/views/catalog/index.html.erb_spec.rb +3 -1
  190. metadata +58 -29
  191. data/.github/workflows/ruby.yml +0 -98
  192. data/app/components/blacklight/facet_field_list_component.html.erb +0 -19
  193. data/app/components/blacklight/search/facet_suggest_input.html.erb +0 -9
  194. data/app/components/blacklight/search/facet_suggest_input.rb +0 -16
  195. data/app/javascript/blacklight-frontend/modalForm.js +0 -60
  196. data/app/views/catalog/_facet_index_navigation.html.erb +0 -1
  197. data/app/views/catalog/_facet_layout.html.erb +0 -8
  198. data/app/views/catalog/_facet_pagination.html.erb +0 -1
  199. data/spec/components/blacklight/document_metadata_component_spec.rb +0 -0
  200. data/spec/components/blacklight/search/facet_suggest_input_spec.rb +0 -33
  201. data/spec/views/catalog/_facet_index_navigation.html.erb_spec.rb +0 -43
  202. data/spec/views/catalog/_facet_layout.html.erb_spec.rb +0 -41
  203. /data/app/components/blacklight/{facet_field_checkboxes_component.html.erb → facets/checkboxes_component.html.erb} +0 -0
@@ -2,9 +2,9 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
6
- subject(:rendered) do
7
- render_inline_to_capybara_node(described_class.new(facet_field: facet_field))
5
+ RSpec.describe Blacklight::Facets::ListComponent, type: :component do
6
+ before do
7
+ render_inline(described_class.new(facet_field: facet_field))
8
8
  end
9
9
 
10
10
  let(:facet_field) do
@@ -21,7 +21,7 @@ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
21
21
  )
22
22
  end
23
23
 
24
- let(:facet_config) { Blacklight::Configuration::NullField.new(key: 'field', item_component: Blacklight::FacetItemComponent, item_presenter: Blacklight::FacetItemPresenter) }
24
+ let(:facet_config) { Blacklight::Configuration::NullField.new(key: 'field', item_component: Blacklight::Facets::ItemComponent, item_presenter: Blacklight::FacetItemPresenter) }
25
25
 
26
26
  let(:paginator) do
27
27
  instance_double(Blacklight::FacetPaginator, items: [
@@ -31,15 +31,15 @@ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
31
31
  end
32
32
 
33
33
  it 'renders an accordion item' do
34
- expect(rendered).to have_css '.accordion-item'
35
- expect(rendered).to have_button 'Field'
36
- expect(rendered).to have_css 'button[data-bs-target="#facet-field"]'
37
- expect(rendered).to have_css '#facet-field.collapse.show'
34
+ expect(page).to have_css '.accordion-item'
35
+ expect(page).to have_button 'Field'
36
+ expect(page).to have_css 'button[data-bs-target="#facet-field"]'
37
+ expect(page).to have_css '#facet-field.collapse.show'
38
38
  end
39
39
 
40
40
  it 'renders the facet items' do
41
- expect(rendered).to have_css 'ul.facet-values'
42
- expect(rendered).to have_css 'li', count: 2
41
+ expect(page).to have_css 'ul.facet-values'
42
+ expect(page).to have_css 'li', count: 2
43
43
  end
44
44
 
45
45
  context 'with an active facet' do
@@ -58,7 +58,7 @@ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
58
58
  end
59
59
 
60
60
  it 'adds the facet-limit-active class' do
61
- expect(rendered).to have_css 'div.facet-limit-active'
61
+ expect(page).to have_css 'div.facet-limit-active'
62
62
  end
63
63
  end
64
64
 
@@ -78,13 +78,13 @@ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
78
78
  end
79
79
 
80
80
  it 'renders a collapsed facet' do
81
- expect(rendered).to have_css '.facet-content.collapse'
82
- expect(rendered).to have_no_css '.facet-content.collapse.show'
81
+ expect(page).to have_css '.facet-content.collapse'
82
+ expect(page).to have_no_css '.facet-content.collapse.show'
83
83
  end
84
84
 
85
85
  it 'renders the toggle button in the collapsed state' do
86
- expect(rendered).to have_css '.btn.collapsed'
87
- expect(rendered).to have_css '.btn[aria-expanded="false"]'
86
+ expect(page).to have_css '.btn.collapsed'
87
+ expect(page).to have_css '.btn[aria-expanded="false"]'
88
88
  end
89
89
  end
90
90
 
@@ -104,7 +104,7 @@ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
104
104
  end
105
105
 
106
106
  it 'renders a link to the modal' do
107
- expect(rendered).to have_link 'more Field', href: '/catalog/facet/modal'
107
+ expect(page).to have_link 'more Field', href: '/catalog/facet/modal'
108
108
  end
109
109
  end
110
110
 
@@ -133,13 +133,13 @@ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
133
133
  let(:params) { { f_inclusive: { field: %w[a b c] } } }
134
134
 
135
135
  it 'displays the constraint above the list' do
136
- expect(rendered).to have_content 'Any of:'
137
- expect(rendered).to have_css '.inclusive_or .facet-label', text: 'a'
138
- expect(rendered).to have_link '[remove]', href: 'http://test.host/catalog?f_inclusive%5Bfield%5D%5B%5D=b&f_inclusive%5Bfield%5D%5B%5D=c'
139
- expect(rendered).to have_css '.inclusive_or .facet-label', text: 'b'
140
- expect(rendered).to have_link '[remove]', href: 'http://test.host/catalog?f_inclusive%5Bfield%5D%5B%5D=a&f_inclusive%5Bfield%5D%5B%5D=c'
141
- expect(rendered).to have_css '.inclusive_or .facet-label', text: 'c'
142
- expect(rendered).to have_link '[remove]', href: 'http://test.host/catalog?f_inclusive%5Bfield%5D%5B%5D=a&f_inclusive%5Bfield%5D%5B%5D=b'
136
+ expect(page).to have_content 'Any of:'
137
+ expect(page).to have_css '.inclusive_or .facet-label', text: 'a'
138
+ expect(page).to have_link '[remove]', href: 'http://test.host/catalog?f_inclusive%5Bfield%5D%5B%5D=b&f_inclusive%5Bfield%5D%5B%5D=c'
139
+ expect(page).to have_css '.inclusive_or .facet-label', text: 'b'
140
+ expect(page).to have_link '[remove]', href: 'http://test.host/catalog?f_inclusive%5Bfield%5D%5B%5D=a&f_inclusive%5Bfield%5D%5B%5D=c'
141
+ expect(page).to have_css '.inclusive_or .facet-label', text: 'c'
142
+ expect(page).to have_link '[remove]', href: 'http://test.host/catalog?f_inclusive%5Bfield%5D%5B%5D=a&f_inclusive%5Bfield%5D%5B%5D=b'
143
143
  end
144
144
  end
145
145
  end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::Facets::SuggestComponent, type: :component do
6
+ let(:facet) { Blacklight::Configuration::FacetField.new key: 'language_facet', suggest: true }
7
+ let(:presenter) { Blacklight::FacetFieldPresenter.new(facet, nil, nil, nil) }
8
+ let(:component) { described_class.new(presenter: presenter) }
9
+
10
+ before do
11
+ allow(presenter).to receive_messages(label: 'Language')
12
+ end
13
+
14
+ it 'has an input with the facet-suggest class, which the javascript needs to find it' do
15
+ with_request_url "/catalog/facet/language_facet" do
16
+ rendered = render_inline component
17
+ expect(rendered.css("input.facet-suggest").count).to eq 1
18
+ end
19
+ end
20
+
21
+ it 'has an input with the data-facet-field attribute, which the javascript needs to determine the correct query' do
22
+ with_request_url "/catalog/facet/language_facet" do
23
+ rendered = render_inline component
24
+ expect(rendered.css('input[data-facet-field="language_facet"]').count).to eq 1
25
+ end
26
+ end
27
+
28
+ it 'has an input with the data-facet-search-context attribute, which the javascript needs to determine the current search context' do
29
+ with_request_url "/catalog/facet/language_facet?f%5Bformat%5D%5B%5D=Book&facet.prefix=R&facet.sort=index&q=tibet&search_field=all_fields" do
30
+ rendered = render_inline component
31
+ expect(rendered.css('input[data-facet-search-context="/catalog/facet/language_facet.html?f%5Bformat%5D%5B%5D=Book&facet.prefix=R&facet.sort=index&q=tibet&search_field=all_fields"]').count).to eq 1
32
+ end
33
+ end
34
+
35
+ it 'has a visible label that is associated with the input' do
36
+ with_request_url "/catalog/facet/language_facet" do
37
+ rendered = render_inline component
38
+ label = rendered.css('label').first
39
+ expect(label.text.strip).to eq 'Filter Language'
40
+
41
+ id_in_label_for = label.attribute('for').text
42
+ expect(id_in_label_for).to eq('facet_suggest_language_facet')
43
+
44
+ expect(rendered.css('input').first.attribute('id').text).to eq id_in_label_for
45
+ end
46
+ end
47
+
48
+ context 'when the facet is explicitly configured to suggest: false' do
49
+ let(:facet) { Blacklight::Configuration::FacetField.new key: 'language_facet', suggest: false }
50
+
51
+ it 'does not display' do
52
+ with_request_url "/catalog/facet/language_facet" do
53
+ expect(render_inline(component).to_s).to eq ''
54
+ end
55
+ end
56
+ end
57
+
58
+ context 'when the facet is not explicitly configured with a suggest key' do
59
+ let(:facet) { Blacklight::Configuration::FacetField.new key: 'language_facet' }
60
+
61
+ it 'displays' do
62
+ with_request_url "/catalog/facet/language_facet" do
63
+ rendered = render_inline component
64
+ expect(rendered.css("input.facet-suggest").count).to eq 1
65
+ end
66
+ end
67
+ end
68
+ end
@@ -3,14 +3,12 @@
3
3
  RSpec.describe Blacklight::HeaderComponent, type: :component do
4
4
  before do
5
5
  with_controller_class(CatalogController) do
6
- allow(controller).to receive_messages(current_user: nil, search_action_url: '/search')
7
- render
6
+ allow(vc_test_controller).to receive_messages(current_user: nil, search_action_url: '/search')
7
+ render_inline described_class.new(blacklight_config: CatalogController.blacklight_config)
8
8
  end
9
9
  end
10
10
 
11
11
  context 'with no slots' do
12
- let(:render) { render_inline(described_class.new(blacklight_config: CatalogController.blacklight_config)) }
13
-
14
12
  it 'draws the topbar' do
15
13
  expect(page).to have_css 'nav.topbar'
16
14
  expect(page).to have_link 'Blacklight', href: '/'
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe Blacklight::HiddenSearchStateComponent, type: :component do
4
- subject(:rendered) { render_inline_to_capybara_node(instance) }
4
+ before { render_inline(instance) }
5
5
 
6
6
  let(:params) do
7
7
  { q: "query",
@@ -13,11 +13,11 @@ RSpec.describe Blacklight::HiddenSearchStateComponent, type: :component do
13
13
  let(:instance) { described_class.new(params: params) }
14
14
 
15
15
  it "converts a hash with nested complex data to Rails-style hidden form fields" do
16
- expect(rendered).to have_css("input[type='hidden'][name='q'][value='query']", visible: :hidden)
17
- expect(rendered).to have_css("input[type='hidden'][name='per_page'][value='10']", visible: :hidden)
18
- expect(rendered).to have_css("input[type='hidden'][name='extra_arbitrary_key'][value='arbitrary_value']", visible: :hidden)
19
- expect(rendered).to have_css("input[type='hidden'][name='f[field2][]'][value='z']", visible: :hidden)
20
- expect(rendered).to have_css("input[type='hidden'][name='f[field1][]'][value='a']", visible: :hidden)
21
- expect(rendered).to have_css("input[type='hidden'][name='f[field1][]'][value='b']", visible: :hidden)
16
+ expect(page).to have_css("input[type='hidden'][name='q'][value='query']", visible: :hidden)
17
+ expect(page).to have_css("input[type='hidden'][name='per_page'][value='10']", visible: :hidden)
18
+ expect(page).to have_css("input[type='hidden'][name='extra_arbitrary_key'][value='arbitrary_value']", visible: :hidden)
19
+ expect(page).to have_css("input[type='hidden'][name='f[field2][]'][value='z']", visible: :hidden)
20
+ expect(page).to have_css("input[type='hidden'][name='f[field1][]'][value='a']", visible: :hidden)
21
+ expect(page).to have_css("input[type='hidden'][name='f[field1][]'][value='b']", visible: :hidden)
22
22
  end
23
23
  end
@@ -3,11 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Blacklight::MetadataFieldComponent, type: :component do
6
- subject(:rendered) do
7
- render_inline_to_capybara_node(described_class.new(field: field))
8
- end
9
-
10
- let(:view_context) { controller.view_context }
6
+ let(:view_context) { vc_test_controller.view_context }
11
7
  let(:document) { SolrDocument.new('field' => ['Value']) }
12
8
  let(:field_config) { Blacklight::Configuration::Field.new(key: 'field', field: 'field', label: 'Field label') }
13
9
 
@@ -15,23 +11,29 @@ RSpec.describe Blacklight::MetadataFieldComponent, type: :component do
15
11
  Blacklight::FieldPresenter.new(view_context, document, field_config)
16
12
  end
17
13
 
18
- it 'renders the field label' do
19
- expect(rendered).to have_css 'dt.blacklight-field', text: 'Field label'
20
- end
14
+ context "from index view" do
15
+ before do
16
+ render_inline(described_class.new(field: field))
17
+ end
18
+
19
+ it 'renders the field label' do
20
+ expect(page).to have_css 'dt.blacklight-field', text: 'Field label'
21
+ end
21
22
 
22
- it 'renders the field value' do
23
- expect(rendered).to have_css 'dd.blacklight-field', text: 'Value'
23
+ it 'renders the field value' do
24
+ expect(page).to have_css 'dd.blacklight-field', text: 'Value'
25
+ end
24
26
  end
25
27
 
26
28
  context 'from a show view' do
27
- subject(:rendered) do
28
- render_inline_to_capybara_node(described_class.new(field: field, show: true))
29
+ before do
30
+ allow(field).to receive(:label).with('show').and_return('custom label')
31
+
32
+ render_inline(described_class.new(field: field, show: true))
29
33
  end
30
34
 
31
35
  it 'renders the right field label' do
32
- allow(field).to receive(:label).with('show').and_return('custom label')
33
-
34
- expect(rendered).to have_css 'dt.blacklight-field', text: 'custom label'
36
+ expect(page).to have_css 'dt.blacklight-field', text: 'custom label'
35
37
  end
36
38
  end
37
39
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::Response::FacetGroupComponent, type: :component do
6
+ before do
7
+ render_inline(instance)
8
+ end
9
+
10
+ context 'when classes are passed in' do
11
+ let(:instance) do
12
+ described_class.new(id: 'foo', title: 'bar', body_classes: 'custom-class').tap do |component|
13
+ component.with_body { 'body' }
14
+ end
15
+ end
16
+
17
+ it "uses them" do
18
+ within '.facets' do
19
+ expect(page).to have_css 'div.custom-class'
20
+ end
21
+ end
22
+ end
23
+
24
+ context 'when classes are not passed in' do
25
+ let(:instance) do
26
+ described_class.new(id: 'foo', title: 'bar').tap do |component|
27
+ component.with_body { 'body' }
28
+ end
29
+ end
30
+
31
+ it "uses default classes them" do
32
+ within '.facets' do
33
+ expect(page).to have_css 'div.facets-collapse.d-lg-block.collapse.accordion'
34
+ end
35
+ end
36
+ end
37
+ end
@@ -38,7 +38,7 @@ RSpec.describe Blacklight::Response::PaginationComponent, type: :component do
38
38
 
39
39
  context 'when a different configuration that removes deep links is configured in the controller' do
40
40
  before do
41
- allow(controller.blacklight_config.index)
41
+ allow(vc_test_controller.blacklight_config.index)
42
42
  .to receive(:pagination_options)
43
43
  .and_return(theme: 'blacklight', left: 5, right: 0)
44
44
  render
@@ -14,7 +14,7 @@ RSpec.describe Blacklight::Response::SpellcheckComponent, type: :component do
14
14
  end
15
15
 
16
16
  before do
17
- allow(controller).to receive(:blacklight_config).and_return(config)
17
+ allow(vc_test_controller).to receive(:blacklight_config).and_return(config)
18
18
  end
19
19
 
20
20
  context 'when there are many results' do
@@ -15,7 +15,7 @@ RSpec.describe Blacklight::SearchBarComponent, type: :component do
15
15
  end
16
16
 
17
17
  before do
18
- allow(controller).to receive(:blacklight_config).and_return(blacklight_config)
18
+ allow(vc_test_controller).to receive(:blacklight_config).and_return(blacklight_config)
19
19
  end
20
20
 
21
21
  context 'with the default button' do
@@ -31,7 +31,7 @@ RSpec.describe Blacklight::SearchBarComponent, type: :component do
31
31
  subject(:render) do
32
32
  render_inline(instance) do |c|
33
33
  c.with_search_button do
34
- controller.view_context.tag.button "hello", id: 'custom_search'
34
+ vc_test_controller.view_context.tag.button "hello", id: 'custom_search'
35
35
  end
36
36
  end
37
37
  end
@@ -70,8 +70,8 @@ RSpec.describe Blacklight::SearchBarComponent, type: :component do
70
70
  context 'with extra inputs' do
71
71
  subject(:render) do
72
72
  render_inline(instance) do |c|
73
- c.with_before_input_group { controller.view_context.tag.input name: 'foo' }
74
- c.with_before_input_group { controller.view_context.tag.input name: 'bar' }
73
+ c.with_before_input_group { vc_test_controller.view_context.tag.input name: 'foo' }
74
+ c.with_before_input_group { vc_test_controller.view_context.tag.input name: 'bar' }
75
75
  end
76
76
  end
77
77
 
@@ -7,7 +7,7 @@ RSpec.describe Blacklight::SearchContext::ServerAppliedParamsComponent, type: :c
7
7
 
8
8
  let(:instance) { described_class.new }
9
9
  let(:current_search_session) { nil }
10
- let(:view_context) { controller.view_context }
10
+ let(:view_context) { vc_test_controller.view_context }
11
11
 
12
12
  before do
13
13
  # Not sure why we need to re-implement rspec's stub_template, but
@@ -16,7 +16,7 @@ RSpec.describe Blacklight::SearchContext::ServerAppliedParamsComponent, type: :c
16
16
  # https://github.com/rspec/rspec-rails/issues/2696
17
17
  replace_hash = { 'application/_start_over.html.erb' => 'start over' }
18
18
  if Rails.version.to_f >= 7.1
19
- controller.prepend_view_path(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
19
+ vc_test_controller.prepend_view_path(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
20
20
  else
21
21
  view_context.view_paths.unshift(RSpec::Rails::ViewExampleGroup::StubResolverCache.resolver_for(replace_hash))
22
22
  end
@@ -11,8 +11,8 @@ RSpec.describe Blacklight::SearchContext::ServerItemPaginationComponent, type: :
11
11
  let(:instance) { described_class.new(search_context: search_context, search_session: search_session, current_document: current_document) }
12
12
 
13
13
  before do
14
- allow(controller).to receive(:current_search_session).and_return(double(id: current_document_id))
15
- controller.class.helper_method :current_search_session
14
+ allow(vc_test_controller).to receive(:current_search_session).and_return(double(id: current_document_id))
15
+ vc_test_controller.class.helper_method :current_search_session
16
16
  end
17
17
 
18
18
  context 'when there is no next or previous' do
@@ -40,9 +40,7 @@ RSpec.describe Blacklight::SearchContext::ServerItemPaginationComponent, type: :
40
40
  let(:next_doc) { SolrDocument.new(id: '888') }
41
41
 
42
42
  before do
43
- # allow(controller).to receive(:controller_tracking_method).and_return('track_catalog_path')
44
-
45
- allow(controller).to receive_messages(controller_name: 'catalog', link_to_previous_document: '', link_to_next_document: '')
43
+ allow(vc_test_controller).to receive_messages(controller_name: 'catalog', link_to_previous_document: '', link_to_next_document: '')
46
44
  end
47
45
 
48
46
  it "renders content" do
@@ -3,12 +3,9 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Blacklight::SkipLinkComponent, type: :component do
6
- subject(:rendered) do
7
- render_inline_to_capybara_node(described_class.new)
8
- end
9
-
10
6
  before do
11
- allow(controller).to receive(:blacklight_config).and_return(blacklight_config)
7
+ allow(vc_test_controller).to receive(:blacklight_config).and_return(blacklight_config)
8
+ render_inline(described_class.new)
12
9
  end
13
10
 
14
11
  context 'with no search fields' do
@@ -19,8 +16,8 @@ RSpec.describe Blacklight::SkipLinkComponent, type: :component do
19
16
  end
20
17
 
21
18
  it 'renders skip links with correct link to search' do
22
- expect(rendered).to have_link("Skip to main content", href: '#main-container')
23
- expect(rendered).to have_link("Skip to search", href: "#q")
19
+ expect(page).to have_link("Skip to main content", href: '#main-container')
20
+ expect(page).to have_link("Skip to search", href: "#q")
24
21
  end
25
22
  end
26
23
 
@@ -32,8 +29,8 @@ RSpec.describe Blacklight::SkipLinkComponent, type: :component do
32
29
  end
33
30
 
34
31
  it 'renders skip links with correct link to search' do
35
- expect(rendered).to have_link("Skip to main content", href: "#main-container")
36
- expect(rendered).to have_link("Skip to search", href: "#q")
32
+ expect(page).to have_link("Skip to main content", href: "#main-container")
33
+ expect(page).to have_link("Skip to search", href: "#q")
37
34
  end
38
35
  end
39
36
 
@@ -45,8 +42,8 @@ RSpec.describe Blacklight::SkipLinkComponent, type: :component do
45
42
  end
46
43
 
47
44
  it 'renders skip links with correct link to search' do
48
- expect(rendered).to have_link("Skip to main content", href: "#main-container")
49
- expect(rendered).to have_link("Skip to search", href: "#search_field")
45
+ expect(page).to have_link("Skip to main content", href: "#main-container")
46
+ expect(page).to have_link("Skip to search", href: "#search_field")
50
47
  end
51
48
  end
52
49
  end
@@ -3,7 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Blacklight::StartOverButtonComponent, type: :component do
6
- subject(:render) { render_inline(instance) }
6
+ subject(:render) { render_inline instance }
7
7
 
8
8
  let(:instance) { described_class.new }
9
9
  let(:blacklight_config) do
@@ -13,12 +13,12 @@ RSpec.describe Blacklight::StartOverButtonComponent, type: :component do
13
13
  end
14
14
 
15
15
  before do
16
- allow(controller).to receive(:blacklight_config).and_return(blacklight_config)
16
+ allow(vc_test_controller).to receive(:blacklight_config).and_return(blacklight_config)
17
17
  end
18
18
 
19
19
  context 'with the current view type' do
20
20
  before do
21
- controller.params[:view] = 'abc'
21
+ vc_test_controller.params[:view] = 'abc'
22
22
  end
23
23
 
24
24
  it 'is the catalog path' do
@@ -28,7 +28,7 @@ RSpec.describe Blacklight::StartOverButtonComponent, type: :component do
28
28
 
29
29
  context 'when the current view type is the default' do
30
30
  before do
31
- controller.params[:view] = 'list'
31
+ vc_test_controller.params[:view] = 'list'
32
32
  end
33
33
 
34
34
  it 'does not include the current view type' do
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::System::DropdownComponent, type: :component do
6
+ it 'includes a link for each choice' do
7
+ search_state = double(Blacklight::SearchState)
8
+ allow(search_state).to receive(:params_for_search).and_return('http://example.com')
9
+ rendered = render_inline(described_class.new(
10
+ param: :per_page,
11
+ choices: [
12
+ ['10 per page', 10],
13
+ ['20 per page', 20]
14
+ ],
15
+ search_state: search_state,
16
+ selected: 20,
17
+ interpolation: :count
18
+ ))
19
+
20
+ expect(rendered.css('a').length).to eq 2
21
+ expect(rendered.css('a')[0].text).to eq '10 per page'
22
+ expect(rendered.css('a')[0].attributes).not_to have_key 'aria-current'
23
+ expect(rendered.css('a')[1].text).to eq '20 per page'
24
+ expect(rendered.css('a')[1].attributes).to have_key 'aria-current'
25
+ end
26
+ end
@@ -5,26 +5,22 @@ require 'spec_helper'
5
5
  RSpec.describe Blacklight::System::FlashMessageComponent, type: :component do
6
6
  subject(:component) { described_class.new(message: message, type: type) }
7
7
 
8
- let(:view_context) { controller.view_context }
9
- let(:render) do
10
- component.render_in(view_context)
8
+ before do
9
+ render_inline(component)
11
10
  end
12
11
 
13
- let(:rendered) do
14
- Capybara::Node::Simple.new(render)
15
- end
16
12
  let(:message) { 'This is an important message' }
17
13
  let(:type) { 'whatever' }
18
14
 
19
15
  it 'renders a message inside an alert' do
20
- expect(rendered).to have_css 'div.alert.alert-whatever', text: message
16
+ expect(page).to have_css 'div.alert.alert-whatever', text: message
21
17
  end
22
18
 
23
19
  context 'with a success message' do
24
20
  let(:type) { 'success' }
25
21
 
26
22
  it 'adds some styling' do
27
- expect(rendered).to have_css 'div.alert-success'
23
+ expect(page).to have_css 'div.alert-success'
28
24
  end
29
25
  end
30
26
 
@@ -32,7 +28,7 @@ RSpec.describe Blacklight::System::FlashMessageComponent, type: :component do
32
28
  let(:type) { 'notice' }
33
29
 
34
30
  it 'adds some styling' do
35
- expect(rendered).to have_css 'div.alert-info'
31
+ expect(page).to have_css 'div.alert-info'
36
32
  end
37
33
  end
38
34
 
@@ -40,7 +36,7 @@ RSpec.describe Blacklight::System::FlashMessageComponent, type: :component do
40
36
  let(:type) { 'alert' }
41
37
 
42
38
  it 'adds some styling' do
43
- expect(rendered).to have_css 'div.alert-warning'
39
+ expect(page).to have_css 'div.alert-warning'
44
40
  end
45
41
  end
46
42
 
@@ -48,7 +44,7 @@ RSpec.describe Blacklight::System::FlashMessageComponent, type: :component do
48
44
  let(:type) { 'error' }
49
45
 
50
46
  it 'adds some styling' do
51
- expect(rendered).to have_css 'div.alert-danger'
47
+ expect(page).to have_css 'div.alert-danger'
52
48
  end
53
49
  end
54
50
  end
@@ -499,13 +499,14 @@ RSpec.describe CatalogController, :api do
499
499
  expect(request.flash[:error]).to be_nil
500
500
  end
501
501
 
502
- it "redirects back to the record upon success" do
503
- allow(RecordMailer).to receive(:email_record)
504
- .with(anything, { to: 'test_email@projectblacklight.org', message: 'xyz', config: config }, hash_including(host: 'test.host'))
505
- .and_return double(deliver: nil)
506
- post :email, params: { id: doc_id, to: 'test_email@projectblacklight.org', message: 'xyz' }
507
- expect(request.flash[:error]).to be_nil
508
- expect(request).to redirect_to(solr_document_path(doc_id))
502
+ context 'when message is provided' do
503
+ it "sends email and redirects back to the record" do
504
+ expect do
505
+ post :email, params: { id: doc_id, to: 'test_email@projectblacklight.org', message: 'xyz' }
506
+ end.to send_email(to: 'test_email@projectblacklight.org')
507
+ expect(request.flash[:error]).to be_nil
508
+ expect(request).to redirect_to(solr_document_path(doc_id))
509
+ end
509
510
  end
510
511
 
511
512
  it "renders email_success for XHR requests" do
@@ -549,11 +550,9 @@ RSpec.describe CatalogController, :api do
549
550
  end
550
551
 
551
552
  it "sends to the appropriate carrier email address" do
552
- expect(RecordMailer)
553
- .to receive(:sms_record)
554
- .with(anything, { to: '5555555555@txt.att.net', config: config }, hash_including(host: 'test.host'))
555
- .and_return double(deliver: nil)
556
- post :sms, params: { id: doc_id, to: '5555555555', carrier: 'txt.att.net' }
553
+ expect do
554
+ post :sms, params: { id: doc_id, to: '5555555555', carrier: 'txt.att.net' }
555
+ end.to send_email(to: '5555555555@txt.att.net')
557
556
  end
558
557
 
559
558
  it "redirects back to the record upon success" do
@@ -786,13 +785,6 @@ RSpec.describe CatalogController, :api do
786
785
  end
787
786
  end
788
787
 
789
- describe "search_facet_path" do
790
- it "is the same as the catalog path" do
791
- get :index, params: { page: 1 }
792
- expect(controller.send(:search_facet_path, id: "some_facet", page: 5)).to eq facet_catalog_path(id: "some_facet")
793
- end
794
- end
795
-
796
788
  describe "page_links" do
797
789
  it "has prev/next docs and result set data for non-empty result sets", :integration do
798
790
  get :page_links, params: { f: { "format" => 'Book' }, counter: 2 }
@@ -803,7 +795,7 @@ RSpec.describe CatalogController, :api do
803
795
  end
804
796
 
805
797
  it "is empty for empty result sets", :integration do
806
- get :page_links, params: { f: { "format" => 'empty-result-set' }, counter: 1 }
798
+ get :page_links, params: { f: { "format" => ['empty-result-set'] }, counter: 1 }
807
799
  expect(assigns(:page_link_data)).to be_empty
808
800
  end
809
801
  end