blacklight 7.6.0 → 7.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.docker/app/Dockerfile +26 -0
  3. data/.docker/app/entrypoint.sh +6 -0
  4. data/.env +5 -0
  5. data/.gitignore +1 -1
  6. data/.rubocop_todo.yml +13 -13
  7. data/.travis.yml +15 -23
  8. data/Gemfile +4 -1
  9. data/README.md +4 -0
  10. data/VERSION +1 -1
  11. data/app/assets/stylesheets/blacklight/_facets.scss +20 -4
  12. data/app/assets/stylesheets/blacklight/_pagination.scss +4 -0
  13. data/app/components/blacklight/constraint_layout_component.html.erb +23 -0
  14. data/app/components/blacklight/constraint_layout_component.rb +16 -0
  15. data/app/components/blacklight/facet_field_component.html.erb +25 -0
  16. data/app/components/blacklight/facet_field_component.rb +11 -0
  17. data/app/components/blacklight/facet_field_list_component.html.erb +18 -0
  18. data/app/components/blacklight/facet_field_list_component.rb +22 -0
  19. data/app/components/blacklight/facet_field_no_layout_component.rb +13 -0
  20. data/app/components/blacklight/facet_item_component.rb +120 -0
  21. data/app/components/blacklight/facet_item_pivot_component.rb +84 -0
  22. data/app/helpers/blacklight/catalog_helper_behavior.rb +2 -2
  23. data/app/helpers/blacklight/configuration_helper_behavior.rb +3 -2
  24. data/app/helpers/blacklight/facets_helper_behavior.rb +95 -49
  25. data/app/helpers/blacklight/render_constraints_helper_behavior.rb +64 -33
  26. data/app/javascript/blacklight/modal.js +1 -1
  27. data/app/models/blacklight/icon.rb +12 -10
  28. data/app/models/concerns/blacklight/document.rb +0 -10
  29. data/app/models/concerns/blacklight/document/extensions.rb +3 -0
  30. data/app/models/concerns/blacklight/document/semantic_fields.rb +0 -4
  31. data/app/presenters/blacklight/document_presenter.rb +2 -1
  32. data/app/presenters/blacklight/facet_field_presenter.rb +57 -0
  33. data/app/presenters/blacklight/facet_item_presenter.rb +81 -0
  34. data/app/views/catalog/_citation.html.erb +1 -1
  35. data/app/views/catalog/_constraints.html.erb +2 -2
  36. data/app/views/catalog/_constraints_element.html.erb +5 -24
  37. data/app/views/catalog/_email_form.html.erb +1 -1
  38. data/app/views/catalog/_facet_layout.html.erb +8 -17
  39. data/app/views/catalog/_facet_limit.html.erb +3 -12
  40. data/app/views/catalog/_facet_pagination.html.erb +2 -2
  41. data/app/views/catalog/_facet_pivot.html.erb +3 -18
  42. data/app/views/catalog/_previous_next_doc.html.erb +5 -5
  43. data/app/views/catalog/_search_form.html.erb +1 -1
  44. data/app/views/catalog/_sms_form.html.erb +1 -1
  45. data/app/views/layouts/blacklight/base.html.erb +1 -1
  46. data/blacklight.gemspec +1 -0
  47. data/config/locales/blacklight.ar.yml +32 -25
  48. data/config/locales/blacklight.de.yml +3 -0
  49. data/config/locales/blacklight.en.yml +3 -0
  50. data/config/locales/blacklight.es.yml +3 -0
  51. data/config/locales/blacklight.fr.yml +3 -0
  52. data/config/locales/blacklight.hu.yml +3 -0
  53. data/config/locales/blacklight.it.yml +3 -0
  54. data/config/locales/blacklight.nl.yml +3 -0
  55. data/config/locales/blacklight.pt-BR.yml +3 -0
  56. data/config/locales/blacklight.sq.yml +3 -0
  57. data/config/locales/blacklight.zh.yml +3 -0
  58. data/docker-compose.yml +35 -0
  59. data/lib/blacklight/configuration.rb +35 -8
  60. data/lib/blacklight/configuration/facet_field.rb +1 -0
  61. data/lib/blacklight/engine.rb +2 -6
  62. data/lib/blacklight/search_state.rb +52 -0
  63. data/lib/blacklight/solr/response/facets.rb +2 -0
  64. data/lib/generators/blacklight/assets_generator.rb +10 -0
  65. data/lib/generators/blacklight/templates/catalog_controller.rb +1 -1
  66. data/package.json +2 -2
  67. data/spec/{views/catalog/_constraints_element.html.erb_spec.rb → components/blacklight/constraint_layout_component_spec.rb} +22 -12
  68. data/spec/components/blacklight/facet_field_list_component_spec.rb +108 -0
  69. data/spec/components/blacklight/facet_item_component_spec.rb +50 -0
  70. data/spec/components/blacklight/facet_item_pivot_component_spec.rb +66 -0
  71. data/spec/features/facets_spec.rb +21 -1
  72. data/spec/helpers/blacklight/configuration_helper_behavior_spec.rb +3 -0
  73. data/spec/helpers/blacklight/facets_helper_behavior_spec.rb +57 -12
  74. data/spec/helpers/blacklight/render_constraints_helper_behavior_spec.rb +4 -23
  75. data/spec/lib/blacklight/search_state_spec.rb +50 -0
  76. data/spec/models/blacklight/configuration_spec.rb +4 -0
  77. data/spec/models/blacklight/icon_spec.rb +11 -10
  78. data/spec/models/blacklight/solr/response/facets_spec.rb +30 -1
  79. data/spec/presenters/blacklight/document_presenter_spec.rb +10 -1
  80. data/spec/presenters/blacklight/facet_field_presenter_spec.rb +109 -0
  81. data/spec/presenters/blacklight/facet_item_presenter_spec.rb +92 -0
  82. data/spec/spec_helper.rb +3 -0
  83. data/spec/support/presenter_test_helpers.rb +11 -0
  84. data/spec/views/catalog/_facet_group.html.erb_spec.rb +1 -0
  85. data/spec/views/catalog/_previous_next_doc.html.erb_spec.rb +18 -0
  86. data/tasks/blacklight.rake +30 -23
  87. metadata +48 -8
  88. data/Vagrantfile +0 -79
  89. data/package-lock.json +0 -2793
  90. data/provision.sh +0 -30
@@ -210,6 +210,8 @@ module Blacklight::Solr::Response::Facets
210
210
  Blacklight::Solr::Response::Facets::FacetItem.new(value: key, hits: hits, label: facet_field.query[key][:label])
211
211
  end
212
212
 
213
+ items = items.sort_by(&:hits).reverse if facet_field.sort && facet_field.sort.to_sym == :count
214
+
213
215
  hash[field_name] = Blacklight::Solr::Response::Facets::FacetField.new field_name, items
214
216
  end
215
217
  end
@@ -22,6 +22,16 @@ module Blacklight
22
22
  end
23
23
  end
24
24
 
25
+ ##
26
+ # Remove the empty generated app/assets/images directory. Without doing this,
27
+ # the default Sprockets 4 manifest will raise an exception.
28
+ def appease_sprockets4
29
+ return if !defined?(Sprockets::VERSION) || Sprockets::VERSION < '4'
30
+
31
+ append_to_file 'app/assets/config/manifest.js', "\n//= link application.js"
32
+ empty_directory 'app/assets/images'
33
+ end
34
+
25
35
  def assets
26
36
  copy_file "blacklight.scss", "app/assets/stylesheets/blacklight.scss"
27
37
 
@@ -84,7 +84,7 @@ class <%= controller_name.classify %>Controller < ApplicationController
84
84
  config.add_facet_field 'subject_geo_ssim', label: 'Region'
85
85
  config.add_facet_field 'subject_era_ssim', label: 'Era'
86
86
 
87
- config.add_facet_field 'example_pivot_field', label: 'Pivot Field', :pivot => ['format', 'language_ssim']
87
+ config.add_facet_field 'example_pivot_field', label: 'Pivot Field', pivot: ['format', 'language_ssim'], collapsing: true
88
88
 
89
89
  config.add_facet_field 'example_query_facet_field', label: 'Publish Date', :query => {
90
90
  :years_5 => { label: 'within 5 Years', fq: "pub_date_ssim:[#{Time.zone.now.year - 5 } TO *]" },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blacklight-frontend",
3
- "version": "7.5.1",
3
+ "version": "7.7.0",
4
4
  "description": "[![Build Status](https://travis-ci.org/projectblacklight/blacklight.png?branch=master)](https://travis-ci.org/projectblacklight/blacklight) [![Gem Version](https://badge.fury.io/rb/blacklight.png)](http://badge.fury.io/rb/blacklight) [![Coverage Status](https://coveralls.io/repos/github/projectblacklight/blacklight/badge.svg?branch=master)](https://coveralls.io/github/projectblacklight/blacklight?branch=master)",
5
5
  "main": "app/assets/javascripts/blacklight",
6
6
  "scripts": {
@@ -24,7 +24,7 @@
24
24
  "dependencies": {
25
25
  "bloodhound-js": "^1.2.3",
26
26
  "bootstrap": "^4.3.1",
27
- "jquery": "^3.4.1",
27
+ "jquery": "^3.5.1",
28
28
  "typeahead.js": "^0.11.1"
29
29
  }
30
30
  }
@@ -1,24 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.describe "catalog/_constraints_element.html.erb" do
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::ConstraintLayoutComponent, type: :component do
6
+ subject(:render) do
7
+ render_inline(described_class.new(params))
8
+ end
9
+
10
+ let(:rendered) do
11
+ Capybara::Node::Simple.new(render)
12
+ end
13
+
4
14
  describe "for simple display" do
5
- before do
6
- render partial: "catalog/constraints_element", locals: { label: "my label", value: "my value" }
15
+ let(:params) do
16
+ { label: "my label", value: "my value" }
7
17
  end
8
18
 
9
19
  it "renders label and value" do
10
20
  expect(rendered).to have_selector("span.applied-filter.constraint") do |s|
11
21
  expect(s).to have_css("span.constraint-value")
12
22
  expect(s).not_to have_css("a.constraint-value")
13
- expect(s).to have_selector "span.filter-name", content: "my label"
14
- expect(s).to have_selector "span.filter-value", content: "my value"
23
+ expect(s).to have_selector "span.filter-name", text: "my label"
24
+ expect(s).to have_selector "span.filter-value", text: "my value"
15
25
  end
16
26
  end
17
27
  end
18
28
 
19
29
  describe "with remove link" do
20
- before do
21
- render partial: "catalog/constraints_element", locals: { label: "my label", value: "my value", options: { remove: "http://remove" } }
30
+ let(:params) do
31
+ { label: "my label", value: "my value", remove_path: "http://remove" }
22
32
  end
23
33
 
24
34
  it "includes remove link" do
@@ -28,14 +38,14 @@ RSpec.describe "catalog/_constraints_element.html.erb" do
28
38
  end
29
39
  it "has an accessible remove label" do
30
40
  expect(rendered).to have_selector(".remove") do |s|
31
- expect(s).to have_content("Remove constraint my label: my value")
41
+ expect(s).to have_selector('.sr-only', text: 'Remove constraint my label: my value')
32
42
  end
33
43
  end
34
44
  end
35
45
 
36
46
  describe "with custom classes" do
37
- before do
38
- render partial: "catalog/constraints_element", locals: { label: "my label", value: "my value", options: { classes: %w[class1 class2] } }
47
+ let(:params) do
48
+ { label: "my label", value: "my value", classes: %w[class1 class2] }
39
49
  end
40
50
 
41
51
  it "includes them" do
@@ -44,8 +54,8 @@ RSpec.describe "catalog/_constraints_element.html.erb" do
44
54
  end
45
55
 
46
56
  describe "with no escaping" do
47
- before do
48
- render(partial: "catalog/constraints_element", locals: { label: "<span class='custom_label'>my label</span>".html_safe, value: "<span class='custom_value'>my value</span>".html_safe })
57
+ let(:params) do
58
+ { label: "<span class='custom_label'>my label</span>".html_safe, value: "<span class='custom_value'>my value</span>".html_safe }
49
59
  end
50
60
 
51
61
  it "does not escape key and value" do
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::FacetFieldListComponent, type: :component do
6
+ subject(:render) do
7
+ render_inline(described_class.new(facet_field: facet_field))
8
+ end
9
+
10
+ let(:rendered) do
11
+ Capybara::Node::Simple.new(render)
12
+ end
13
+
14
+ let(:facet_field) do
15
+ instance_double(
16
+ Blacklight::FacetFieldPresenter,
17
+ paginator: paginator,
18
+ key: 'field',
19
+ label: 'Field',
20
+ active?: false,
21
+ collapsed?: false,
22
+ modal_path: nil,
23
+ html_id: 'facet-field'
24
+ )
25
+ end
26
+
27
+ let(:paginator) do
28
+ instance_double(Blacklight::FacetPaginator, items: [
29
+ double(label: 'x', hits: 10),
30
+ double(label: 'y', hits: 33)
31
+ ])
32
+ end
33
+
34
+ it 'renders a collapsible card' do
35
+ expect(rendered).to have_selector '.card'
36
+ expect(rendered).to have_button 'Field'
37
+ expect(rendered).to have_selector 'button[data-target="#facet-field"]'
38
+ expect(rendered).to have_selector '#facet-field.collapse.show'
39
+ end
40
+
41
+ it 'renders the facet items' do
42
+ expect(rendered).to have_selector 'ul.facet-values'
43
+ expect(rendered).to have_selector 'li', count: 2
44
+ end
45
+
46
+ context 'with an active facet' do
47
+ let(:facet_field) do
48
+ instance_double(
49
+ Blacklight::FacetFieldPresenter,
50
+ paginator: paginator,
51
+ key: 'field',
52
+ label: 'Field',
53
+ active?: true,
54
+ collapsed?: false,
55
+ modal_path: nil,
56
+ html_id: 'facet-field'
57
+ )
58
+ end
59
+
60
+ it 'adds the facet-limit-active class' do
61
+ expect(rendered).to have_selector 'div.facet-limit-active'
62
+ end
63
+ end
64
+
65
+ context 'with a collapsed facet' do
66
+ let(:facet_field) do
67
+ instance_double(
68
+ Blacklight::FacetFieldPresenter,
69
+ paginator: paginator,
70
+ key: 'field',
71
+ label: 'Field',
72
+ active?: false,
73
+ collapsed?: true,
74
+ modal_path: nil,
75
+ html_id: 'facet-field'
76
+ )
77
+ end
78
+
79
+ it 'renders a collapsed facet' do
80
+ expect(rendered).to have_selector '.facet-content.collapse'
81
+ expect(rendered).not_to have_selector '.facet-content.collapse.show'
82
+ end
83
+
84
+ it 'renders the toggle button in the collapsed state' do
85
+ expect(rendered).to have_selector '.btn.collapsed'
86
+ expect(rendered).to have_selector '.btn[aria-expanded="false"]'
87
+ end
88
+ end
89
+
90
+ context 'with a modal_path' do
91
+ let(:facet_field) do
92
+ instance_double(
93
+ Blacklight::FacetFieldPresenter,
94
+ paginator: paginator,
95
+ key: 'field',
96
+ label: 'Field',
97
+ active?: false,
98
+ collapsed?: false,
99
+ modal_path: '/catalog/facet/modal',
100
+ html_id: 'facet-field'
101
+ )
102
+ end
103
+
104
+ it 'renders a link to the modal' do
105
+ expect(rendered).to have_link 'more Field', href: '/catalog/facet/modal'
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::FacetItemComponent, type: :component do
6
+ subject(:render) do
7
+ render_inline(described_class.new(facet_item: facet_item))
8
+ end
9
+
10
+ let(:rendered) do
11
+ Capybara::Node::Simple.new(render)
12
+ end
13
+
14
+ let(:facet_item) do
15
+ instance_double(
16
+ Blacklight::FacetItemPresenter,
17
+ facet_config: Blacklight::Configuration::FacetField.new,
18
+ label: 'x',
19
+ hits: 10,
20
+ href: '/catalog?f=x',
21
+ selected?: false
22
+ )
23
+ end
24
+
25
+ it 'links to the facet and shows the number of hits' do
26
+ expect(rendered).to have_selector 'li'
27
+ expect(rendered).to have_link 'x', href: '/catalog?f=x'
28
+ expect(rendered).to have_selector '.facet-count', text: '10'
29
+ end
30
+
31
+ context 'with a selected facet' do
32
+ let(:facet_item) do
33
+ instance_double(
34
+ Blacklight::FacetItemPresenter,
35
+ facet_config: Blacklight::Configuration::FacetField.new,
36
+ label: 'x',
37
+ hits: 10,
38
+ href: '/catalog',
39
+ selected?: true
40
+ )
41
+ end
42
+
43
+ it 'links to the facet and shows the number of hits' do
44
+ expect(rendered).to have_selector 'li'
45
+ expect(rendered).to have_selector '.selected', text: 'x'
46
+ expect(rendered).to have_link '[remove]', href: '/catalog'
47
+ expect(rendered).to have_selector '.selected.facet-count', text: '10'
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Blacklight::FacetItemPivotComponent, type: :component do
6
+ subject(:render) do
7
+ render_inline(described_class.new(facet_item: facet_item))
8
+ end
9
+
10
+ let(:rendered) do
11
+ Capybara::Node::Simple.new(render)
12
+ end
13
+
14
+ let(:search_state) do
15
+ Blacklight::SearchState.new({}, Blacklight::Configuration.new)
16
+ end
17
+
18
+ let(:facet_item) do
19
+ instance_double(
20
+ Blacklight::FacetItemPresenter,
21
+ facet_config: Blacklight::Configuration::FacetField.new(key: 'z'),
22
+ facet_field: 'z',
23
+ label: 'x',
24
+ hits: 10,
25
+ href: '/catalog?f[z]=x',
26
+ selected?: false,
27
+ search_state: search_state,
28
+ items: [OpenStruct.new(value: 'x:1', hits: 5)]
29
+ )
30
+ end
31
+
32
+ it 'links to the facet and shows the number of hits' do
33
+ expect(rendered).to have_selector 'li'
34
+ expect(rendered).to have_link 'x', href: '/catalog?f[z]=x'
35
+ expect(rendered).to have_selector '.facet-count', text: '10'
36
+ end
37
+
38
+ it 'has the facet hierarchy' do
39
+ puts render
40
+ expect(rendered).to have_selector 'li ul.pivot-facet'
41
+ expect(rendered).to have_link 'x:1', href: /f%5Bz%5D%5B%5D=x%3A1/
42
+ end
43
+
44
+ context 'with a selected facet' do
45
+ let(:facet_item) do
46
+ instance_double(
47
+ Blacklight::FacetItemPresenter,
48
+ facet_config: Blacklight::Configuration::FacetField.new,
49
+ facet_field: 'z',
50
+ label: 'x',
51
+ hits: 10,
52
+ href: '/catalog',
53
+ selected?: true,
54
+ search_state: search_state,
55
+ items: []
56
+ )
57
+ end
58
+
59
+ it 'links to the facet and shows the number of hits' do
60
+ expect(rendered).to have_selector 'li'
61
+ expect(rendered).to have_selector '.selected', text: 'x'
62
+ expect(rendered).to have_link '[remove]', href: '/catalog'
63
+ expect(rendered).to have_selector '.selected.facet-count', text: '10'
64
+ end
65
+ end
66
+ end
@@ -67,6 +67,26 @@ RSpec.describe "Facets" do
67
67
  expect(page).to have_css('#facet-format', visible: true) # assert that it didn't re-collapse
68
68
  end
69
69
 
70
+ it 'is able to expand pivot facets when javascript is enabled', js: true do
71
+ visit root_path
72
+
73
+ within('#facets .facets-header') do
74
+ page.find('button.navbar-toggler').click
75
+ end
76
+
77
+ page.find('h3.facet-field-heading button', text: 'Pivot Field').click
78
+
79
+ within '#facet-example_pivot_field' do
80
+ expect(page).to have_css('.facet-leaf-node', text: 'Book 30')
81
+ expect(page).not_to have_css('.facet-select', text: 'Tibetan')
82
+ page.find('.facet-toggle-handle').click
83
+ click_link 'Tibetan'
84
+ end
85
+
86
+ expect(page).to have_css('.constraint-value', text: 'Format Book')
87
+ expect(page).to have_css('.constraint-value', text: 'Language Tibetan')
88
+ end
89
+
70
90
  describe 'heading button focus with Firefox' do
71
91
  before do
72
92
  Capybara.current_driver = :selenium_headless
@@ -88,7 +108,7 @@ RSpec.describe "Facets" do
88
108
  it 'has default more link with sr-only text' do
89
109
  visit root_path
90
110
  within '#facet-language_ssim' do
91
- expect(page).to have_css 'li.more_facets', text: 'more Language'
111
+ expect(page).to have_css 'div.more_facets', text: 'more Language'
92
112
  end
93
113
  end
94
114
  end
@@ -274,6 +274,9 @@ RSpec.describe Blacklight::ConfigurationHelperBehavior do
274
274
  it 'handles a missing key' do
275
275
  expect(helper.label_for_search_field('not-found')).to eq 'Not Found'
276
276
  end
277
+ it 'handles a missing field' do
278
+ expect(helper.label_for_search_field(nil)).to eq nil
279
+ end
277
280
  end
278
281
 
279
282
  describe '#sort_field_label' do
@@ -141,6 +141,8 @@ RSpec.describe Blacklight::FacetsHelperBehavior do
141
141
  let(:blacklight_config) do
142
142
  Blacklight::Configuration.new do |config|
143
143
  config.add_facet_field 'basic_field'
144
+ config.add_facet_field 'component_field', component: true
145
+ config.add_facet_field 'non_rendering_component_field', component: true, if: false
144
146
  config.add_facet_field 'pivot_facet_field', pivot: %w[a b]
145
147
  config.add_facet_field 'my_pivot_facet_field_with_custom_partial', partial: 'custom_facet_partial', pivot: %w[a b]
146
148
  config.add_facet_field 'my_facet_field_with_custom_partial', partial: 'custom_facet_partial'
@@ -191,6 +193,17 @@ RSpec.describe Blacklight::FacetsHelperBehavior do
191
193
  expect(helper).to receive(:render).with(hash_including(partial: 'custom_facet_partial'))
192
194
  helper.render_facet_limit(mock_facet)
193
195
  end
196
+
197
+ it "lets you override the rendered partial for pivot facets" do
198
+ mock_facet = double(name: 'component_field')
199
+ expect(helper).to receive(:render).with(an_instance_of(Blacklight::FacetFieldListComponent))
200
+ helper.render_facet_limit(mock_facet)
201
+ end
202
+
203
+ it "lets you override the rendered partial for pivot facets" do
204
+ mock_facet = double(name: 'non_rendering_component_field')
205
+ expect(helper.render_facet_limit(mock_facet)).to be_blank
206
+ end
194
207
  end
195
208
 
196
209
  describe "render_facet_limit_list" do
@@ -214,7 +227,11 @@ RSpec.describe Blacklight::FacetsHelperBehavior do
214
227
 
215
228
  context "when one of the facet items is rendered as nil" do
216
229
  # An app may override render_facet_item to filter out some undesired facet items by returning nil.
217
- before { allow(helper).to receive(:render_facet_item).and_return('<a class="facet-select">Book</a>'.html_safe, nil) }
230
+ before do
231
+ allow(helper.method(:render_facet_item)).to receive(:owner).and_return(self.class)
232
+ # allow_any_instance_of(Blacklight::FacetItemComponent).to receive(:overridden_helper_methods?).and_return(true)
233
+ allow(helper).to receive(:render_facet_item).and_return('<a class="facet-select">Book</a>'.html_safe, nil)
234
+ end
218
235
 
219
236
  it "draws a list of elements" do
220
237
  expect(subject).to have_selector 'li', count: 1
@@ -246,36 +263,44 @@ RSpec.describe Blacklight::FacetsHelperBehavior do
246
263
  end
247
264
 
248
265
  describe "facet_field_in_params?" do
266
+ let(:search_state) { double }
267
+
268
+ before do
269
+ allow(helper).to receive_messages(search_state: search_state)
270
+ end
271
+
249
272
  it "checks if any value is selected for a given facet" do
250
- allow(helper).to receive_messages(facet_params: ["x"])
273
+ allow(search_state).to receive(:has_facet?).with(having_attributes(key: 'some-facet')).and_return(true)
251
274
  expect(helper.facet_field_in_params?("some-facet")).to eq true
252
275
  end
253
276
 
254
277
  it "is false if no value for facet is selected" do
255
- allow(helper).to receive_messages(facet_params: nil)
278
+ allow(search_state).to receive(:has_facet?).with(having_attributes(key: 'some-facet')).and_return(false)
256
279
  expect(helper.facet_field_in_params?("some-facet")).to eq false
257
280
  end
258
281
  end
259
282
 
260
283
  describe "facet_in_params?" do
284
+ let(:search_state) { double }
285
+
286
+ before do
287
+ allow(helper).to receive_messages(search_state: search_state)
288
+ allow(search_state).to receive(:has_facet?).with(having_attributes(key: 'some-facet'), value: 'x').and_return(true)
289
+ allow(search_state).to receive(:has_facet?).with(having_attributes(key: 'some-facet'), value: 'y').and_return(false)
290
+ end
291
+
261
292
  it "checks if a particular value is set in the facet params" do
262
- allow(helper).to receive_messages(facet_params: ["x"])
263
293
  expect(helper.facet_in_params?("some-facet", "x")).to eq true
264
294
  expect(helper.facet_in_params?("some-facet", "y")).to eq false
265
295
  end
266
-
267
- it "is false if no value for facet is selected" do
268
- allow(helper).to receive_messages(facet_params: nil)
269
- expect(helper.facet_in_params?("some-facet", "x")).to eq false
270
- end
271
296
  end
272
297
 
273
298
  describe "render_facet_value" do
274
299
  let(:item) { double(value: 'A', hits: 10) }
275
- let(:search_state) { double(add_facet_params_and_redirect: { controller: 'catalog' }) }
300
+ let(:search_state) { double(has_facet?: false, add_facet_params_and_redirect: { controller: 'catalog' }) }
276
301
 
277
302
  before do
278
- allow(helper).to receive(:facet_configuration_for_field).with('simple_field').and_return(double(query: nil, date: nil, helper_method: nil, single: false, url_method: nil))
303
+ allow(helper).to receive(:facet_configuration_for_field).with('simple_field').and_return(Blacklight::Configuration::FacetField.new(key: 'simple_field', query: nil, date: nil, helper_method: nil, single: false, url_method: nil))
279
304
  allow(helper).to receive(:facet_display_value).and_return('Z')
280
305
  allow(helper).to receive(:search_state).and_return(search_state)
281
306
  allow(helper).to receive(:search_action_path) do |*args|
@@ -296,7 +321,7 @@ RSpec.describe Blacklight::FacetsHelperBehavior do
296
321
  let(:expected_html) { '<span class="facet-label"><a class="facet-select" href="/blabla">Z</a></span><span class="facet-count">10</span>' }
297
322
 
298
323
  it "uses that method" do
299
- allow(helper).to receive(:facet_configuration_for_field).with('simple_field').and_return(double(query: nil, date: nil, helper_method: nil, single: false, url_method: :test_method))
324
+ allow(helper).to receive(:facet_configuration_for_field).with('simple_field').and_return(Blacklight::Configuration::FacetField.new(key: 'simple_field', query: nil, date: nil, helper_method: nil, single: false, url_method: :test_method))
300
325
  allow(helper).to receive(:test_method).with('simple_field', item).and_return('/blabla')
301
326
  result = helper.render_facet_value('simple_field', item)
302
327
  expect(result).to be_equivalent_to(expected_html).respecting_element_order
@@ -346,4 +371,24 @@ RSpec.describe Blacklight::FacetsHelperBehavior do
346
371
  expect(helper.facet_field_id(double(key: 'some field'))).to eq "facet-some-field"
347
372
  end
348
373
  end
374
+
375
+ describe '#facet_field_presenter' do
376
+ let(:facet_config) { Blacklight::Configuration::FacetField.new(key: 'x').normalize! }
377
+ let(:display_facet) { double }
378
+
379
+ it 'wraps the facet data in a presenter' do
380
+ presenter = helper.facet_field_presenter(facet_config, display_facet)
381
+ expect(presenter).to be_a_kind_of Blacklight::FacetFieldPresenter
382
+ expect(presenter.facet_field).to eq facet_config
383
+ expect(presenter.display_facet).to eq display_facet
384
+ expect(presenter.view_context).to eq helper
385
+ end
386
+
387
+ it 'uses the facet config to determine the presenter class' do
388
+ stub_const('SomePresenter', Class.new(Blacklight::FacetFieldPresenter))
389
+ facet_config.presenter = SomePresenter
390
+ presenter = helper.facet_field_presenter(facet_config, display_facet)
391
+ expect(presenter).to be_a_kind_of SomePresenter
392
+ end
393
+ end
349
394
  end