blacklight 7.13.2 → 7.15.2

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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +23 -3
  3. data/README.md +0 -2
  4. data/VERSION +1 -1
  5. data/app/assets/javascripts/blacklight/blacklight.js +4 -2
  6. data/app/assets/stylesheets/blacklight/_header.scss +0 -5
  7. data/app/assets/stylesheets/blacklight/_icons.scss +5 -1
  8. data/app/assets/stylesheets/blacklight/blacklight_defaults.scss +5 -1
  9. data/app/components/blacklight/advanced_search_form_component.html.erb +46 -0
  10. data/app/components/blacklight/advanced_search_form_component.rb +75 -0
  11. data/app/components/blacklight/constraint_component.html.erb +1 -1
  12. data/app/components/blacklight/constraint_layout_component.html.erb +1 -1
  13. data/app/components/blacklight/constraints_component.rb +42 -17
  14. data/app/components/blacklight/document/thumbnail_component.html.erb +2 -2
  15. data/app/components/blacklight/document/thumbnail_component.rb +5 -2
  16. data/app/components/blacklight/document_component.rb +7 -2
  17. data/app/components/blacklight/document_metadata_component.rb +1 -1
  18. data/app/components/blacklight/facet_field_checkboxes_component.html.erb +23 -0
  19. data/app/components/blacklight/facet_field_checkboxes_component.rb +24 -0
  20. data/app/components/blacklight/facet_field_inclusive_constraint_component.html.erb +6 -0
  21. data/app/components/blacklight/facet_field_inclusive_constraint_component.rb +29 -0
  22. data/app/components/blacklight/facet_field_list_component.html.erb +1 -0
  23. data/app/components/blacklight/facet_field_pagination_component.rb +1 -1
  24. data/app/components/blacklight/facet_item_component.rb +4 -2
  25. data/app/components/blacklight/hidden_search_state_component.rb +54 -0
  26. data/app/components/blacklight/search_bar_component.html.erb +4 -0
  27. data/app/components/blacklight/search_bar_component.rb +4 -2
  28. data/app/controllers/concerns/blacklight/bookmarks.rb +1 -1
  29. data/app/controllers/concerns/blacklight/catalog.rb +6 -0
  30. data/app/helpers/blacklight/component_helper_behavior.rb +1 -1
  31. data/app/helpers/blacklight/configuration_helper_behavior.rb +2 -2
  32. data/app/helpers/blacklight/facets_helper_behavior.rb +1 -1
  33. data/app/helpers/blacklight/hash_as_hidden_fields_helper_behavior.rb +2 -38
  34. data/app/helpers/blacklight/icon_helper_behavior.rb +1 -1
  35. data/app/helpers/blacklight/render_constraints_helper_behavior.rb +2 -2
  36. data/app/javascript/blacklight/button_focus.js +1 -0
  37. data/app/javascript/blacklight/modal.js +10 -4
  38. data/app/models/concerns/blacklight/suggest/response.rb +1 -1
  39. data/app/presenters/blacklight/clause_presenter.rb +37 -0
  40. data/app/presenters/blacklight/document_presenter.rb +5 -1
  41. data/app/presenters/blacklight/facet_field_presenter.rb +4 -0
  42. data/app/presenters/blacklight/facet_grouped_item_presenter.rb +45 -0
  43. data/app/presenters/blacklight/facet_item_presenter.rb +32 -20
  44. data/app/presenters/blacklight/field_presenter.rb +1 -1
  45. data/app/presenters/blacklight/inclusive_facet_item_presenter.rb +16 -0
  46. data/app/presenters/blacklight/rendering/helper_method.rb +4 -4
  47. data/app/presenters/blacklight/search_bar_presenter.rb +4 -0
  48. data/app/views/bookmarks/_tools.html.erb +1 -1
  49. data/app/views/catalog/_advanced_search_form.html.erb +7 -0
  50. data/app/views/catalog/_advanced_search_help.html.erb +24 -0
  51. data/app/views/catalog/_search_form.html.erb +1 -0
  52. data/app/views/catalog/_zero_results.html.erb +1 -1
  53. data/app/views/catalog/advanced_search.html.erb +17 -0
  54. data/blacklight.gemspec +5 -4
  55. data/config/i18n-tasks.yml +1 -0
  56. data/config/locales/blacklight.en.yml +17 -0
  57. data/lib/blacklight/configuration.rb +2 -1
  58. data/lib/blacklight/configuration/field.rb +1 -1
  59. data/lib/blacklight/configuration/sort_field.rb +1 -1
  60. data/lib/blacklight/open_struct_with_hash_access.rb +18 -1
  61. data/lib/blacklight/routes/searchable.rb +1 -0
  62. data/lib/blacklight/search_builder.rb +2 -0
  63. data/lib/blacklight/search_state.rb +5 -1
  64. data/lib/blacklight/search_state/filter_field.rb +17 -7
  65. data/lib/blacklight/solr/repository.rb +11 -2
  66. data/lib/blacklight/solr/search_builder_behavior.rb +87 -23
  67. data/package.json +1 -1
  68. data/spec/components/blacklight/advanced_search_form_component_spec.rb +51 -0
  69. data/spec/components/blacklight/constraint_layout_component_spec.rb +1 -1
  70. data/spec/components/blacklight/document_component_spec.rb +17 -0
  71. data/spec/components/blacklight/facet_field_checkboxes_component_spec.rb +55 -0
  72. data/spec/components/blacklight/facet_field_list_component_spec.rb +39 -4
  73. data/spec/components/blacklight/hidden_search_state_component_spec.rb +24 -0
  74. data/spec/controllers/catalog_controller_spec.rb +9 -0
  75. data/spec/features/advanced_search_spec.rb +67 -0
  76. data/spec/features/bookmarks_spec.rb +1 -9
  77. data/spec/features/facets_spec.rb +2 -17
  78. data/spec/features/search_filters_spec.rb +0 -20
  79. data/spec/helpers/blacklight/hash_as_hidden_fields_behavior_spec.rb +1 -0
  80. data/spec/helpers/blacklight/url_helper_behavior_spec.rb +1 -0
  81. data/spec/lib/blacklight/open_struct_with_hash_access_spec.rb +8 -0
  82. data/spec/lib/blacklight/search_state/filter_field_spec.rb +65 -0
  83. data/spec/models/blacklight/solr/repository_spec.rb +12 -0
  84. data/spec/models/blacklight/solr/response/facets_spec.rb +1 -1
  85. data/spec/models/blacklight/solr/search_builder_spec.rb +28 -0
  86. data/spec/presenters/blacklight/clause_presenter_spec.rb +34 -0
  87. data/spec/presenters/blacklight/document_presenter_spec.rb +13 -0
  88. data/spec/presenters/blacklight/facet_grouped_item_presenter_spec.rb +41 -0
  89. data/spec/spec_helper.rb +8 -3
  90. data/spec/test_app_templates/Gemfile.extra +1 -1
  91. data/spec/views/catalog/_document.html.erb_spec.rb +1 -0
  92. data/spec/views/catalog/_thumbnail.html.erb_spec.rb +2 -0
  93. metadata +66 -27
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe "Blacklight Advanced Search Form" do
6
+ describe "advanced search form" do
7
+ before do
8
+ visit '/catalog/advanced?hypothetical_existing_param=true&q=ignore+this+existing+query'
9
+ end
10
+
11
+ it "has field and facet blocks" do
12
+ expect(page).to have_selector('.query-criteria')
13
+ expect(page).to have_selector('.limit-criteria')
14
+ end
15
+
16
+ describe "query column" do
17
+ it "gives the user a choice between and/or queries" do
18
+ expect(page).to have_selector('#op')
19
+ within('#op') do
20
+ expect(page).to have_selector('option[value="must"]')
21
+ expect(page).to have_selector('option[value="should"]')
22
+ end
23
+ end
24
+
25
+ it "lists the configured search fields" do
26
+ expect(page).to have_field 'All Fields'
27
+ expect(page).to have_field 'Title'
28
+ expect(page).to have_field 'Author'
29
+ expect(page).to have_field 'Subject'
30
+ end
31
+ end
32
+
33
+ describe "facet column" do
34
+ it "lists facets" do
35
+ expect(page).to have_selector('.blacklight-language_ssim')
36
+
37
+ within('.blacklight-language_ssim') do
38
+ expect(page).to have_content 'Language'
39
+ end
40
+ end
41
+ end
42
+
43
+ it 'scopes searches to fields' do
44
+ fill_in 'Title', with: 'Medicine'
45
+ click_on 'advanced-search-submit'
46
+ expect(page).to have_content 'Remove constraint Title: Medicine'
47
+ expect(page).to have_content 'Strong Medicine speaks'
48
+ end
49
+ end
50
+
51
+ describe "prepopulated advanced search form" do
52
+ before do
53
+ visit '/catalog/advanced?op=must&clause[0][field]=title&clause[0]query=medicine'
54
+ end
55
+
56
+ it "does not create hidden inputs for search fields" do
57
+ expect(page).to have_field 'Title', with: 'medicine'
58
+ end
59
+
60
+ it "does not have multiple parameters for a search field" do
61
+ fill_in 'Title', with: 'bread'
62
+ click_on 'advanced-search-submit'
63
+ expect(page.current_url).to match(/bread/)
64
+ expect(page.current_url).not_to match(/medicine/)
65
+ end
66
+ end
67
+ end
@@ -57,7 +57,7 @@ RSpec.describe "Bookmarks" do
57
57
  expect(page).to have_content 'Strong Medicine speaks'
58
58
  end
59
59
 
60
- it "cites items in current bookmarks page" do
60
+ it "cites all items in current bookmarks" do
61
61
  visit solr_document_path('2009373513') # Ci an zhou bian
62
62
  click_button 'Bookmark'
63
63
 
@@ -70,14 +70,6 @@ RSpec.describe "Bookmarks" do
70
70
 
71
71
  click_link 'Cite'
72
72
  expect(page).to have_content 'Strong Medicine speaks'
73
- expect(page).not_to have_content 'Ci an zhou bian'
74
-
75
- visit "/bookmarks?per_page=1"
76
- click_link "2"
77
- expect(page).to have_content 'Ci an zhou bian'
78
-
79
- click_link 'Cite'
80
- expect(page).not_to have_content 'Strong Medicine speaks'
81
73
  expect(page).to have_content 'Ci an zhou bian'
82
74
  end
83
75
  end
@@ -56,10 +56,6 @@ RSpec.describe "Facets" do
56
56
 
57
57
  expect(page).to have_css('#facet-format', visible: false)
58
58
 
59
- within('#facets .facets-header') do
60
- page.find('button.navbar-toggler').click
61
- end
62
-
63
59
  page.find('h3.facet-field-heading button', text: 'Format').click
64
60
 
65
61
  sleep(1) # let facet animation finish and wait for it to potentially re-collapse
@@ -70,14 +66,10 @@ RSpec.describe "Facets" do
70
66
  it 'is able to expand pivot facets when javascript is enabled', js: true do
71
67
  visit root_path
72
68
 
73
- within('#facets .facets-header') do
74
- page.find('button.navbar-toggler').click
75
- end
76
-
77
69
  page.find('h3.facet-field-heading button', text: 'Pivot Field').click
78
70
 
79
71
  within '#facet-example_pivot_field' do
80
- expect(page).to have_css('.facet-leaf-node', text: 'Book 30')
72
+ expect(page).to have_css('.facet-leaf-node', text: "Book\t30")
81
73
  expect(page).not_to have_css('.facet-select', text: 'Tibetan')
82
74
  page.find('.facet-toggle-handle').click
83
75
  click_link 'Tibetan'
@@ -88,15 +80,8 @@ RSpec.describe "Facets" do
88
80
  end
89
81
 
90
82
  describe 'heading button focus with Firefox' do
91
- before do
92
- Capybara.current_driver = :selenium_headless
93
- end
94
-
95
- after do
96
- Capybara.current_driver = :rack_test
97
- end
98
-
99
83
  it 'changes to the button on button click in Firefox' do
84
+ pending 'Capybara::NotSupportedByDriverError: Capybara::Driver::Base#evaluate_script'
100
85
  visit root_path
101
86
  page.find('h3.facet-field-heading button', text: 'Format').click
102
87
  focused_element_data_target = page.evaluate_script("document.activeElement")['data-target']
@@ -168,26 +168,16 @@ RSpec.describe "Facets" do
168
168
  end
169
169
 
170
170
  it "is collapsed when not selected", js: true do
171
- skip("Test passes locally but not on Travis.") if ENV['TRAVIS']
172
171
  visit root_path
173
172
 
174
- within('#facets .facets-header') do
175
- page.find('button.navbar-toggler').click
176
- end
177
-
178
173
  within(".blacklight-subject_ssim") do
179
174
  expect(page).not_to have_selector(".card-body", visible: true)
180
175
  end
181
176
  end
182
177
 
183
178
  it "expands when the heading button is clicked", js: true do
184
- skip("Test passes locally but not on Travis.") if ENV['TRAVIS']
185
179
  visit root_path
186
180
 
187
- within('#facets .facets-header') do
188
- page.find('button.navbar-toggler').click
189
- end
190
-
191
181
  within(".blacklight-subject_ssim") do
192
182
  expect(page).not_to have_selector(".card-body", visible: true)
193
183
  find(".card-header button").click
@@ -196,13 +186,8 @@ RSpec.describe "Facets" do
196
186
  end
197
187
 
198
188
  it "expands when the button is clicked", js: true do
199
- skip("Test passes locally but not on Travis.") if ENV['TRAVIS']
200
189
  visit root_path
201
190
 
202
- within('#facets .facets-header') do
203
- page.find('button.navbar-toggler').click
204
- end
205
-
206
191
  within(".blacklight-subject_ssim") do
207
192
  expect(page).not_to have_selector(".card-body", visible: true)
208
193
  find(".card-header").click
@@ -211,13 +196,8 @@ RSpec.describe "Facets" do
211
196
  end
212
197
 
213
198
  it "keeps selected facets expanded on page load", js: true do
214
- skip("Test passes locally but not on Travis.") if ENV['TRAVIS']
215
199
  visit root_path
216
200
 
217
- within('#facets .facets-header') do
218
- page.find('button.navbar-toggler').click
219
- end
220
-
221
201
  within(".blacklight-subject_ssim") do
222
202
  page.find('h3.facet-field-heading', text: 'Topic').click
223
203
  expect(page).to have_selector(".panel-collapse", visible: true)
@@ -14,6 +14,7 @@ RSpec.describe Blacklight::HashAsHiddenFieldsHelperBehavior do
14
14
  let(:generated) { helper.render_hash_as_hidden_fields(params) }
15
15
 
16
16
  it "converts a hash with nested complex data to Rails-style hidden form fields" do
17
+ allow(Deprecation).to receive(:warn)
17
18
  expect(generated).to have_selector("input[type='hidden'][name='q'][value='query']", visible: false)
18
19
  expect(generated).to have_selector("input[type='hidden'][name='per_page'][value='10']", visible: false)
19
20
  expect(generated).to have_selector("input[type='hidden'][name='page'][value='5']", visible: false)
@@ -13,6 +13,7 @@ RSpec.describe Blacklight::UrlHelperBehavior do
13
13
  let(:parameter_class) { ActionController::Parameters }
14
14
 
15
15
  before do
16
+ allow(controller).to receive(:controller_name).and_return('test')
16
17
  allow(helper).to receive(:search_action_path) do |*args|
17
18
  search_catalog_url *args
18
19
  end
@@ -145,4 +145,12 @@ RSpec.describe Blacklight::OpenStructWithHashAccess do
145
145
  expect(copy.b[:c]).to eq 2
146
146
  end
147
147
  end
148
+
149
+ describe "#try" do
150
+ subject { described_class.new a: 1 }
151
+
152
+ it "works (and doesn't throw a stack error...)" do
153
+ expect(subject.try(:a)).to eq 1
154
+ end
155
+ end
148
156
  end
@@ -72,6 +72,33 @@ RSpec.describe Blacklight::SearchState::FilterField do
72
72
  expect(new_state.filter('some_field').values).to eq %w[1 2 4]
73
73
  end
74
74
  end
75
+
76
+ context 'with an array' do
77
+ let(:params) do
78
+ { f: { another_field: ['3'] }, f_inclusive: { some_field: %w[a b c] } }
79
+ end
80
+
81
+ it 'creates a new group with the new values' do
82
+ filter = search_state.filter('new_field')
83
+ new_state = filter.add(%w[x y z])
84
+
85
+ expect(new_state.filter('new_field').values).to eq [%w[x y z]]
86
+ end
87
+
88
+ it 'updates any existing groups with the new values' do
89
+ filter = search_state.filter('some_field')
90
+ new_state = filter.add(%w[x y z])
91
+
92
+ expect(new_state.filter('some_field').values).to eq [%w[x y z]]
93
+ end
94
+
95
+ it 'leaves existing filters alone' do
96
+ filter = search_state.filter('another_field')
97
+ new_state = filter.add(%w[x y z])
98
+
99
+ expect(new_state.filter('another_field').values).to eq ['3', %w[x y z]]
100
+ end
101
+ end
75
102
  end
76
103
 
77
104
  describe '#remove' do
@@ -104,12 +131,50 @@ RSpec.describe Blacklight::SearchState::FilterField do
104
131
 
105
132
  expect(new_state.filter('some_field').values).to eq ['2']
106
133
  end
134
+
135
+ context 'with an array' do
136
+ let(:params) do
137
+ { f: { another_field: ['3'] }, f_inclusive: { some_field: %w[a b c], another_field: %w[x y z] } }
138
+ end
139
+
140
+ it 'removes groups of values' do
141
+ filter = search_state.filter('some_field')
142
+ new_state = filter.remove(%w[a b c])
143
+
144
+ expect(new_state.params[:f_inclusive]).not_to include :some_field
145
+ expect(new_state.filter('some_field').values).to eq []
146
+ end
147
+
148
+ it 'can remove single values' do
149
+ filter = search_state.filter('some_field')
150
+ new_state = filter.remove(%w[a])
151
+
152
+ expect(new_state.filter('some_field').values).to eq [%w[b c]]
153
+ end
154
+
155
+ it 'leaves existing filters alone' do
156
+ filter = search_state.filter('another_field')
157
+ new_state = filter.remove(%w[x y z])
158
+
159
+ expect(new_state.filter('another_field').values).to eq ['3']
160
+ end
161
+ end
107
162
  end
108
163
 
109
164
  describe '#values' do
110
165
  it 'returns the currently selected values of the filter' do
111
166
  expect(search_state.filter('some_field').values).to eq %w[1 2]
112
167
  end
168
+
169
+ context 'with an array' do
170
+ let(:params) do
171
+ { f: { some_field: ['3'] }, f_inclusive: { some_field: %w[a b c] } }
172
+ end
173
+
174
+ it 'combines the exclusive and inclusive values' do
175
+ expect(search_state.filter('some_field').values).to eq ['3', %w[a b c]]
176
+ end
177
+ end
113
178
  end
114
179
 
115
180
  describe '#include?' do
@@ -134,6 +134,18 @@ RSpec.describe Blacklight::Solr::Repository, api: true do
134
134
  end
135
135
  end
136
136
  end
137
+
138
+ context 'with json parameters' do
139
+ it 'sends a post request with some json' do
140
+ allow(subject.connection).to receive(:send_and_receive) do |path, params|
141
+ expect(path).to eq 'select'
142
+ expect(params[:method]).to eq :post
143
+ expect(JSON.parse(params[:data]).with_indifferent_access).to include(query: { bool: {} })
144
+ expect(params[:headers]).to include({ 'Content-Type' => 'application/json' })
145
+ end.and_return('response' => { 'docs' => [] })
146
+ subject.search(json: { query: { bool: {} } })
147
+ end
148
+ end
137
149
  end
138
150
 
139
151
  describe "http_method configuration", integration: true do
@@ -109,7 +109,7 @@ RSpec.describe Blacklight::Solr::Response::Facets, api: true do
109
109
  let(:facet) { { name: "foo", value: "bar", hits: 1 } }
110
110
 
111
111
  before do
112
- response.merge_facet(facet)
112
+ response.merge_facet(**facet)
113
113
  end
114
114
 
115
115
  context "facet does not already exist" do
@@ -259,6 +259,17 @@ RSpec.describe Blacklight::Solr::SearchBuilderBehavior, api: true do
259
259
  end
260
260
  end
261
261
 
262
+ describe 'with multi-valued facets' do
263
+ let(:user_params) { { f_inclusive: { format: %w[Book Movie CD] } } }
264
+
265
+ it "has proper solr parameters" do
266
+ expect(subject[:fq]).to include('{!lucene}{!query v=$f_inclusive.format.0} OR {!query v=$f_inclusive.format.1} OR {!query v=$f_inclusive.format.2}')
267
+ expect(subject['f_inclusive.format.0']).to eq '{!term f=format}Book'
268
+ expect(subject['f_inclusive.format.1']).to eq '{!term f=format}Movie'
269
+ expect(subject['f_inclusive.format.2']).to eq '{!term f=format}CD'
270
+ end
271
+ end
272
+
262
273
  describe "solr parameters for a field search from config (subject)" do
263
274
  let(:user_params) { subject_search_params }
264
275
 
@@ -723,4 +734,21 @@ RSpec.describe Blacklight::Solr::SearchBuilderBehavior, api: true do
723
734
  expect(subject.with_ex_local_param(nil, "some-value")).to eq "some-value"
724
735
  end
725
736
  end
737
+
738
+ context 'with advanced search clause parameters' do
739
+ before do
740
+ blacklight_config.search_fields.each_value do |v|
741
+ v.clause_params = { edismax: v.solr_parameters.dup }
742
+ end
743
+ end
744
+
745
+ let(:user_params) { { op: 'must', clause: { '0': { field: 'title', query: 'the book' }, '1': { field: 'author', query: 'the person' } } } }
746
+
747
+ it "has proper solr parameters" do
748
+ expect(subject.to_hash.with_indifferent_access.dig(:json, :query, :bool, :must, 0, :edismax, :query)).to eq 'the book'
749
+ expect(subject.to_hash.with_indifferent_access.dig(:json, :query, :bool, :must, 0, :edismax, :qf)).to eq '${title_qf}'
750
+ expect(subject.to_hash.with_indifferent_access.dig(:json, :query, :bool, :must, 1, :edismax, :query)).to eq 'the person'
751
+ expect(subject.to_hash.with_indifferent_access.dig(:json, :query, :bool, :must, 1, :edismax, :qf)).to eq '${author_qf}'
752
+ end
753
+ end
726
754
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe Blacklight::ClausePresenter, type: :presenter do
5
+ subject(:presenter) do
6
+ described_class.new('0', params.with_indifferent_access.dig(:clause, '0'), field_config, controller.view_context, search_state)
7
+ end
8
+
9
+ let(:field_config) { Blacklight::Configuration::NullField.new key: 'some_field' }
10
+ let(:search_state) { Blacklight::SearchState.new(params.with_indifferent_access, Blacklight::Configuration.new) }
11
+ let(:params) { {} }
12
+
13
+ describe '#field_label' do
14
+ it 'returns a label for the field' do
15
+ expect(subject.field_label).to eq 'Some Field'
16
+ end
17
+ end
18
+
19
+ describe '#label' do
20
+ let(:params) { { clause: { '0' => { query: 'some search string' } } } }
21
+
22
+ it 'returns the query value for the clause' do
23
+ expect(subject.label).to eq 'some search string'
24
+ end
25
+ end
26
+
27
+ describe '#remove_href' do
28
+ let(:params) { { clause: { '0' => { query: 'some_search_string' } } } }
29
+
30
+ it 'returns the href to remove the search clause' do
31
+ expect(subject.remove_href).not_to include 'some_search_string'
32
+ end
33
+ end
34
+ end
@@ -47,4 +47,17 @@ RSpec.describe Blacklight::DocumentPresenter do
47
47
  expect(presenter.field_value(field_config, options)).to eq 'abc'
48
48
  end
49
49
  end
50
+
51
+ describe '#thumbnail' do
52
+ it 'returns a thumbnail presenter' do
53
+ expect(presenter.thumbnail).to be_a_kind_of(Blacklight::ThumbnailPresenter)
54
+ end
55
+
56
+ it 'use the configured thumbnail presenter' do
57
+ custom_presenter_class = Class.new(Blacklight::ThumbnailPresenter)
58
+ blacklight_config.index.thumbnail_presenter = custom_presenter_class
59
+
60
+ expect(presenter.thumbnail).to be_a_kind_of custom_presenter_class
61
+ end
62
+ end
50
63
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe Blacklight::FacetGroupedItemPresenter, type: :presenter do
5
+ subject(:presenter) do
6
+ described_class.new(group, facet_item, facet_config, view_context, facet_field, search_state)
7
+ end
8
+
9
+ let(:facet_config) { Blacklight::Configuration::FacetField.new(key: 'key') }
10
+ let(:facet_field) { instance_double(Blacklight::Solr::Response::Facets::FacetField) }
11
+ let(:view_context) { controller.view_context }
12
+
13
+ let(:facet_item) { 'a' }
14
+ let(:group) { %w[a b c] }
15
+ let(:search_state) { Blacklight::SearchState.new(params, Blacklight::Configuration.new) }
16
+ let(:params) { { f_inclusive: { key: group } } }
17
+
18
+ describe '#selected' do
19
+ it { is_expected.to be_selected }
20
+
21
+ context 'when the item is not in the group' do
22
+ let(:facet_item) { 'd' }
23
+
24
+ it { is_expected.not_to be_selected }
25
+ end
26
+
27
+ describe '#href' do
28
+ it 'removes the item from the "group" of filters' do
29
+ expect(Rack::Utils.parse_query(URI(presenter.href).query)).to include 'f_inclusive[key][]' => %w[b c]
30
+ end
31
+
32
+ context 'when the item is not in the group' do
33
+ let(:facet_item) { 'd' }
34
+
35
+ it 'adds the item to the "group" of filters' do
36
+ expect(Rack::Utils.parse_query(URI(presenter.href).query)).to include 'f_inclusive[key][]' => %w[a b c d]
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end