From 46452d2a973eedb8dcfbea08c11a5d15eddef8a6 Mon Sep 17 00:00:00 2001 From: Jane Sandberg Date: Wed, 16 Oct 2024 09:49:24 -0700 Subject: [PATCH] Add a way to filter facets in the facets "more" modal (#3367) * Facet typeahead: back end This creates a new endpoint at /catalog/facet// Co-authored-by: Isha Sinha * Facet typeahead: front end Co-authored-by: Christina Chortaria * bundle exec i18n-tasks add-missing * Incorporate feedback from review Rather than two very similar controller actions for facets vs. facet_suggest, this commit combines them into a single controller action. --------- Co-authored-by: Isha Sinha Co-authored-by: Christina Chortaria --- .rubocop.yml | 1 + .../search/facet_suggest_input.html.erb | 9 +++ .../blacklight/search/facet_suggest_input.rb | 16 +++++ .../concerns/blacklight/catalog.rb | 9 ++- app/javascript/blacklight/debounce.js | 15 +++++ app/javascript/blacklight/facet_suggest.js | 26 ++++++++ app/javascript/blacklight/index.js | 2 + .../blacklight/facet_field_presenter.rb | 3 +- app/services/blacklight/search_service.rb | 5 ++ app/views/catalog/facet.html.erb | 1 + app/views/catalog/facet_values.erb | 3 + config/locales/blacklight.ar.yml | 3 + config/locales/blacklight.de.yml | 3 + config/locales/blacklight.en.yml | 3 + config/locales/blacklight.es.yml | 3 + config/locales/blacklight.fr.yml | 3 + config/locales/blacklight.hu.yml | 3 + config/locales/blacklight.it.yml | 3 + config/locales/blacklight.nl.yml | 3 + config/locales/blacklight.pt-BR.yml | 3 + config/locales/blacklight.sq.yml | 3 + config/locales/blacklight.zh.yml | 3 + lib/blacklight/configuration.rb | 3 +- lib/blacklight/routes/searchable.rb | 1 + lib/blacklight/search_builder.rb | 13 ++++ .../solr/search_builder_behavior.rb | 10 ++- .../search/facet_suggest_input_spec.rb | 33 ++++++++++ spec/features/facets_spec.rb | 13 ++++ spec/models/blacklight/search_builder_spec.rb | 10 +++ .../solr/search_builder_behavior_spec.rb | 64 +++++++++++++++++++ .../blacklight/facet_field_presenter_spec.rb | 12 +++- 31 files changed, 277 insertions(+), 5 deletions(-) create mode 100644 app/components/blacklight/search/facet_suggest_input.html.erb create mode 100644 app/components/blacklight/search/facet_suggest_input.rb create mode 100644 app/javascript/blacklight/debounce.js create mode 100644 app/javascript/blacklight/facet_suggest.js create mode 100644 app/views/catalog/facet_values.erb create mode 100644 spec/components/blacklight/search/facet_suggest_input_spec.rb diff --git a/.rubocop.yml b/.rubocop.yml index 8ffedb887a..cd592b0700 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -43,6 +43,7 @@ Metrics/BlockLength: Metrics/ClassLength: Exclude: + - "app/services/blacklight/search_service.rb" - "lib/blacklight/configuration.rb" - "lib/blacklight/search_builder.rb" - "lib/blacklight/search_state.rb" diff --git a/app/components/blacklight/search/facet_suggest_input.html.erb b/app/components/blacklight/search/facet_suggest_input.html.erb new file mode 100644 index 0000000000..a947961186 --- /dev/null +++ b/app/components/blacklight/search/facet_suggest_input.html.erb @@ -0,0 +1,9 @@ + + + diff --git a/app/components/blacklight/search/facet_suggest_input.rb b/app/components/blacklight/search/facet_suggest_input.rb new file mode 100644 index 0000000000..c82e939b18 --- /dev/null +++ b/app/components/blacklight/search/facet_suggest_input.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Blacklight + module Search + class FacetSuggestInput < Blacklight::Component + def initialize(facet:, presenter:) + @facet = facet + @presenter = presenter + end + + private + + attr_accessor :facet, :presenter + end + end +end diff --git a/app/controllers/concerns/blacklight/catalog.rb b/app/controllers/concerns/blacklight/catalog.rb index f299c0502d..f62c51fd97 100644 --- a/app/controllers/concerns/blacklight/catalog.rb +++ b/app/controllers/concerns/blacklight/catalog.rb @@ -83,7 +83,12 @@ def facet @facet = blacklight_config.facet_fields[params[:id]] raise ActionController::RoutingError, 'Not Found' unless @facet - @response = search_service.facet_field_response(@facet.key) + query_fragment = params[:query_fragment] || '' + @response = if query_fragment.present? + search_service.facet_suggest_response(@facet.key, params[:query_fragment]) + else + @response = search_service.facet_field_response(@facet.key) + end @display_facet = @response.aggregations[@facet.field] @presenter = @facet.presenter.new(@facet, @display_facet, view_context) @@ -92,6 +97,8 @@ def facet format.html do # Draw the partial for the "more" facet modal window: return render layout: false if request.xhr? + # Only show the facet names and their values: + return render 'facet_values', layout: false if params[:only_values] # Otherwise draw the facet selector for users who have javascript disabled. end format.json diff --git a/app/javascript/blacklight/debounce.js b/app/javascript/blacklight/debounce.js new file mode 100644 index 0000000000..9af1254abe --- /dev/null +++ b/app/javascript/blacklight/debounce.js @@ -0,0 +1,15 @@ +// Usage: +// ``` +// const basicFunction = (entry) => console.log(entry) +// const debounced = debounce(basicFunction("I should only be called once")); +// +// debounced // does NOT print to the screen becase it is invoked again less than 200 milliseconds later +// debounced // does print to the screen +// ``` +export default function debounce(func, timeout = 200) { + let timer; + return (...args) => { + clearTimeout(timer); + timer = setTimeout(() => { func.apply(this, args); }, timeout); + }; +} diff --git a/app/javascript/blacklight/facet_suggest.js b/app/javascript/blacklight/facet_suggest.js new file mode 100644 index 0000000000..3cbb7844c4 --- /dev/null +++ b/app/javascript/blacklight/facet_suggest.js @@ -0,0 +1,26 @@ +import debounce from "blacklight/debounce"; + +const FacetSuggest = async (e) => { + if (e.target.matches('.facet-suggest')) { + const queryFragment = e.target.value?.trim(); + const facetField = e.target.dataset.facetField; + if (!facetField) { return; } + + const urlToFetch = `/catalog/facet_suggest/${facetField}/${queryFragment}` + const response = await fetch(urlToFetch); + if (response.ok) { + const blob = await response.blob() + const text = await blob.text() + + const facetArea = document.querySelector('.facet-extended-list'); + + if (text && facetArea) { + facetArea.innerHTML = text + } + } + } +}; + +document.addEventListener('input', debounce(FacetSuggest)); + +export default FacetSuggest diff --git a/app/javascript/blacklight/index.js b/app/javascript/blacklight/index.js index 0fe8e22724..9c5c0f96bc 100644 --- a/app/javascript/blacklight/index.js +++ b/app/javascript/blacklight/index.js @@ -1,5 +1,6 @@ import BookmarkToggle from 'blacklight/bookmark_toggle' import ButtonFocus from 'blacklight/button_focus' +import FacetSuggest from 'blacklight/facet_suggest' import Modal from 'blacklight/modal' import SearchContext from 'blacklight/search_context' import Core from 'blacklight/core' @@ -7,6 +8,7 @@ import Core from 'blacklight/core' export default { BookmarkToggle, ButtonFocus, + FacetSuggest, Modal, SearchContext, Core, diff --git a/app/presenters/blacklight/facet_field_presenter.rb b/app/presenters/blacklight/facet_field_presenter.rb index df26234a85..62e17dcbde 100644 --- a/app/presenters/blacklight/facet_field_presenter.rb +++ b/app/presenters/blacklight/facet_field_presenter.rb @@ -31,7 +31,8 @@ def in_advanced_search? end def in_modal? - search_state.params[:action] == "facet" + modal_like_actions = %w[facet facet_suggest] + modal_like_actions.include? search_state.params[:action] end def modal_path diff --git a/app/services/blacklight/search_service.rb b/app/services/blacklight/search_service.rb index d81b12a756..5fa2d05051 100644 --- a/app/services/blacklight/search_service.rb +++ b/app/services/blacklight/search_service.rb @@ -62,6 +62,11 @@ def facet_field_response(facet_field, extra_controller_params = {}) repository.search(query.merge(extra_controller_params)) end + def facet_suggest_response(facet_field, facet_suggestion_query, extra_controller_params = {}) + query = search_builder.with(search_state).facet(facet_field).facet_suggestion_query(facet_suggestion_query) + repository.search(query.merge(extra_controller_params)) + end + # Get the previous and next document from a search result # @return [Blacklight::Solr::Response, Array] the solr response and a list of the first and last document def previous_and_next_documents_for_search(index, request_params, extra_controller_params = {}) diff --git a/app/views/catalog/facet.html.erb b/app/views/catalog/facet.html.erb index 0d0745c83e..331082efea 100644 --- a/app/views/catalog/facet.html.erb +++ b/app/views/catalog/facet.html.erb @@ -6,6 +6,7 @@ <% end %> <% component.with_title { facet_field_label(@facet.key) } %> + <%= render Blacklight::Search::FacetSuggestInput.new(facet: @facet, presenter: @presenter) %> <%= render partial: 'facet_index_navigation' if @facet.index_range && @display_facet.index? %> diff --git a/app/views/catalog/facet_values.erb b/app/views/catalog/facet_values.erb new file mode 100644 index 0000000000..6784d904d4 --- /dev/null +++ b/app/views/catalog/facet_values.erb @@ -0,0 +1,3 @@ +<%= render Blacklight::FacetComponent.new(display_facet: @display_facet, + blacklight_config: blacklight_config, + layout: false) %> diff --git a/config/locales/blacklight.ar.yml b/config/locales/blacklight.ar.yml index e5ebc60769..c23455853d 100644 --- a/config/locales/blacklight.ar.yml +++ b/config/locales/blacklight.ar.yml @@ -111,6 +111,9 @@ ar: sort: count: ترتيب رقمي index: ترتيب أبجدي + suggest: + label: Filter %{field_label} + placeholder: Filter... title: تحديد نطاق البحث filters: label: "%{label}:" diff --git a/config/locales/blacklight.de.yml b/config/locales/blacklight.de.yml index 3838f11010..14cf9cb563 100644 --- a/config/locales/blacklight.de.yml +++ b/config/locales/blacklight.de.yml @@ -102,6 +102,9 @@ de: sort: count: Numerisch ordnen index: A-Z Ordnen + suggest: + label: Filter %{field_label} + placeholder: Filter... title: Suche beschränken filters: label: "%{label}:" diff --git a/config/locales/blacklight.en.yml b/config/locales/blacklight.en.yml index ab427c6e05..a560fb60bc 100644 --- a/config/locales/blacklight.en.yml +++ b/config/locales/blacklight.en.yml @@ -120,6 +120,9 @@ en: sort: count: Numerical Sort index: A-Z Sort + suggest: + label: "Filter %{field_label}" + placeholder: Filter... title: Limit your search filters: label: "%{label}:" diff --git a/config/locales/blacklight.es.yml b/config/locales/blacklight.es.yml index 604d8cce97..71e0a7206f 100644 --- a/config/locales/blacklight.es.yml +++ b/config/locales/blacklight.es.yml @@ -101,6 +101,9 @@ es: sort: count: Ordenación numérica index: Ordenación A-Z + suggest: + label: Filter %{field_label} + placeholder: Filter... title: Limite su búsqueda filters: label: "%{label}:" diff --git a/config/locales/blacklight.fr.yml b/config/locales/blacklight.fr.yml index 30c60603b5..4831bd4cb5 100755 --- a/config/locales/blacklight.fr.yml +++ b/config/locales/blacklight.fr.yml @@ -101,6 +101,9 @@ fr: sort: count: Du + au - fréquent index: Tri de A à Z + suggest: + label: Filter %{field_label} + placeholder: Filter... title: Limiter votre recherche filters: label: "%{label}:" diff --git a/config/locales/blacklight.hu.yml b/config/locales/blacklight.hu.yml index dadba8cfdb..0556b8c2d6 100644 --- a/config/locales/blacklight.hu.yml +++ b/config/locales/blacklight.hu.yml @@ -99,6 +99,9 @@ hu: sort: count: Numerikus rendezés index: A-Z rendezés + suggest: + label: Filter %{field_label} + placeholder: Filter... title: Szűrje tovább a keresését filters: label: "%{label}:" diff --git a/config/locales/blacklight.it.yml b/config/locales/blacklight.it.yml index e71637b08f..eafd35cb8e 100644 --- a/config/locales/blacklight.it.yml +++ b/config/locales/blacklight.it.yml @@ -102,6 +102,9 @@ it: sort: count: Ordina per numero index: Ordina A-Z + suggest: + label: Filter %{field_label} + placeholder: Filter... title: Affina la ricerca filters: label: "%{label}:" diff --git a/config/locales/blacklight.nl.yml b/config/locales/blacklight.nl.yml index 8e8d829b76..4757fbce3f 100644 --- a/config/locales/blacklight.nl.yml +++ b/config/locales/blacklight.nl.yml @@ -99,6 +99,9 @@ nl: sort: count: Numeriek sorteren index: A-Z Sorteren + suggest: + label: Filter %{field_label} + placeholder: Filter... title: Verfijn uw zoekopdracht filters: label: "%{label}:" diff --git a/config/locales/blacklight.pt-BR.yml b/config/locales/blacklight.pt-BR.yml index aea5b6a6c4..40d5b7c481 100644 --- a/config/locales/blacklight.pt-BR.yml +++ b/config/locales/blacklight.pt-BR.yml @@ -100,6 +100,9 @@ pt-BR: sort: count: Ordenar por Número index: Ordem Alfabética A-Z + suggest: + label: Filter %{field_label} + placeholder: Filter... title: Filtre sua busca filters: label: "%{label}:" diff --git a/config/locales/blacklight.sq.yml b/config/locales/blacklight.sq.yml index 9ced9ef28d..76bdca3321 100644 --- a/config/locales/blacklight.sq.yml +++ b/config/locales/blacklight.sq.yml @@ -99,6 +99,9 @@ sq: sort: count: Renditja numerike index: A-Z Renditja + suggest: + label: Filter %{field_label} + placeholder: Filter... title: Kufizo këkimin filters: label: "%{label}:" diff --git a/config/locales/blacklight.zh.yml b/config/locales/blacklight.zh.yml index 327a4c9369..80393a6c98 100644 --- a/config/locales/blacklight.zh.yml +++ b/config/locales/blacklight.zh.yml @@ -99,6 +99,9 @@ zh: sort: count: 按数量排序 index: 按字母排序 + suggest: + label: Filter %{field_label} + placeholder: Filter... title: 限定搜索 filters: label: "%{label}:" diff --git a/lib/blacklight/configuration.rb b/lib/blacklight/configuration.rb index 9570d741a6..eb15146c19 100644 --- a/lib/blacklight/configuration.rb +++ b/lib/blacklight/configuration.rb @@ -35,7 +35,8 @@ def initialized_default_configuration? end end - BASIC_SEARCH_PARAMETERS = [:q, :qt, :page, :per_page, :search_field, :sort, :controller, :action, :'facet.page', :'facet.prefix', :'facet.sort', :rows, :format, :view].freeze + BASIC_SEARCH_PARAMETERS = [:q, :qt, :page, :per_page, :search_field, :sort, :controller, :action, :'facet.page', :'facet.prefix', :'facet.sort', :rows, :format, :view, :id, :facet_id, + :query_fragment, :only_values].freeze ADVANCED_SEARCH_PARAMETERS = [{ clause: {} }, :op].freeze # rubocop:disable Metrics/BlockLength diff --git a/lib/blacklight/routes/searchable.rb b/lib/blacklight/routes/searchable.rb index bab55b888a..dfe5cddfe4 100644 --- a/lib/blacklight/routes/searchable.rb +++ b/lib/blacklight/routes/searchable.rb @@ -18,6 +18,7 @@ def call(mapper, _options = {}) mapper.get "opensearch" mapper.get 'suggest', as: 'suggest_index' mapper.get "facet/:id", action: 'facet', as: 'facet' + mapper.get "facet_suggest/:id/(:query_fragment)", action: 'facet', as: 'facet_suggest', defaults: { only_values: true } end end end diff --git a/lib/blacklight/search_builder.rb b/lib/blacklight/search_builder.rb index 19b4ed5213..18d9acd940 100644 --- a/lib/blacklight/search_builder.rb +++ b/lib/blacklight/search_builder.rb @@ -224,6 +224,19 @@ def facet(value = nil) @facet end + def facet_suggestion_query=(value) + params_will_change! + @facet_suggestion_query = value + end + + def facet_suggestion_query(value = nil) + if value + self.facet_suggestion_query = value + return self + end + @facet_suggestion_query + end + # Decode the user provided 'sort' parameter into a sort string that can be # passed to the search. This sanitizes the input by ensuring only # configured search values are passed through to the search. diff --git a/lib/blacklight/solr/search_builder_behavior.rb b/lib/blacklight/solr/search_builder_behavior.rb index ca320ae55c..1e5f009b5e 100644 --- a/lib/blacklight/solr/search_builder_behavior.rb +++ b/lib/blacklight/solr/search_builder_behavior.rb @@ -10,7 +10,8 @@ module SearchBuilderBehavior :add_query_to_solr, :add_facet_fq_to_solr, :add_facetting_to_solr, :add_solr_fields_to_query, :add_paging_to_solr, :add_sorting_to_solr, :add_group_config_to_solr, - :add_facet_paging_to_solr, :add_adv_search_clauses, + :add_facet_paging_to_solr, :add_facet_suggestion_parameters, + :add_adv_search_clauses, :add_additional_filters ] end @@ -276,6 +277,13 @@ def add_facet_paging_to_solr(solr_params) solr_params[:"f.#{facet_config.field}.facet.prefix"] = prefix if prefix end + def add_facet_suggestion_parameters(solr_params) + return if facet.blank? || facet_suggestion_query.blank? + + solr_params[:'facet.contains'] = facet_suggestion_query[0..50] + solr_params[:'facet.contains.ignoreCase'] = true + end + def with_ex_local_param(ex, value) if ex "{!ex=#{ex}}#{value}" diff --git a/spec/components/blacklight/search/facet_suggest_input_spec.rb b/spec/components/blacklight/search/facet_suggest_input_spec.rb new file mode 100644 index 0000000000..fcc7a5ae62 --- /dev/null +++ b/spec/components/blacklight/search/facet_suggest_input_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Blacklight::Search::FacetSuggestInput, type: :component do + let(:facet) { Blacklight::Configuration::FacetField.new key: 'language_facet' } + let(:presenter) { instance_double(Blacklight::FacetFieldPresenter) } + + before do + allow(presenter).to receive(:label).and_return 'Language' + end + + it 'has an input with the facet-suggest class, which the javascript needs to find it' do + rendered = render_inline(described_class.new(facet: facet, presenter: presenter)) + expect(rendered.css("input.facet-suggest").count).to eq 1 + end + + it 'has an input with the data-facet-field attribute, which the javascript needs to determine the correct query' do + rendered = render_inline(described_class.new(facet: facet, presenter: presenter)) + expect(rendered.css('input[data-facet-field="language_facet"]').count).to eq 1 + end + + it 'has a visible label that is associated with the input' do + rendered = render_inline(described_class.new(facet: facet, presenter: presenter)) + label = rendered.css('label').first + expect(label.text.strip).to eq 'Filter Language' + + id_in_label_for = label.attribute('for').text + expect(id_in_label_for).to eq('facet-suggest-language_facet') + + expect(rendered.css('input').first.attribute('id').text).to eq id_in_label_for + end +end diff --git a/spec/features/facets_spec.rb b/spec/features/facets_spec.rb index 4f78d8c3ea..912f82082d 100644 --- a/spec/features/facets_spec.rb +++ b/spec/features/facets_spec.rb @@ -98,4 +98,17 @@ end end end + + describe 'Facet modal' do + it 'allows the user to filter a long list of facet values', :js do + visit '/catalog/facet/subject_ssim' + expect(page).to have_no_link 'Old age' # This is on the second page of facet values + expect(page).to have_css 'a.facet-select', count: 20 + + fill_in 'facet_suggest_subject_ssim', with: "ag" + + expect(page).to have_link 'Old age' + expect(page).to have_css 'a.facet-select', count: 2 + end + end end diff --git a/spec/models/blacklight/search_builder_spec.rb b/spec/models/blacklight/search_builder_spec.rb index 343a64d5bf..819368b2fa 100644 --- a/spec/models/blacklight/search_builder_spec.rb +++ b/spec/models/blacklight/search_builder_spec.rb @@ -225,6 +225,16 @@ end end + describe "#facet_suggestion_query" do + it "is nil if no value is set" do + expect(subject.facet_suggestion_query).to be_nil + end + + it "sets facet_suggestion_query value" do + expect(subject.facet_suggestion_query('antel').facet_suggestion_query).to eq 'antel' + end + end + describe "#search_field" do it "uses the requested search field" do blacklight_config.add_search_field 'x' diff --git a/spec/models/blacklight/solr/search_builder_behavior_spec.rb b/spec/models/blacklight/solr/search_builder_behavior_spec.rb index 7f2e574965..e3bd368fb9 100644 --- a/spec/models/blacklight/solr/search_builder_behavior_spec.rb +++ b/spec/models/blacklight/solr/search_builder_behavior_spec.rb @@ -824,6 +824,70 @@ end end + describe "#add_facet_suggestion_parameters" do + it "does not add anything when the builder has no facet_suggestion_query and no facet" do + expect(subject.facet).to be_nil + expect(subject.facet_suggestion_query).to be_nil + solr_params = Blacklight::Solr::Request.new + + expect do + subject.add_facet_suggestion_parameters(solr_params) + end.not_to(change { solr_params }) + end + + it "does not add anything when the builder has a facet_suggestion_query but no facet" do + subject.facet_suggestion_query = 'artic' + expect(subject.facet_suggestion_query).to eq 'artic' + expect(subject.facet).to be_nil + solr_params = Blacklight::Solr::Request.new + + expect do + subject.add_facet_suggestion_parameters(solr_params) + end.not_to(change { solr_params }) + end + + it "does not add anything when the builder has a facet but no facet_suggestion_query" do + subject.facet = 'subject_facet' + expect(subject.facet_suggestion_query).to be_nil + expect(subject.facet).to eq 'subject_facet' + solr_params = Blacklight::Solr::Request.new + + expect do + subject.add_facet_suggestion_parameters(solr_params) + end.not_to(change { solr_params }) + end + + it "adds the facet_suggestion_query to facet.contains" do + subject.facet = 'subject_facet' + subject.facet_suggestion_query = 'artic' + solr_params = Blacklight::Solr::Request.new + + subject.add_facet_suggestion_parameters(solr_params) + + expect(solr_params[:'facet.contains']).to eq 'artic' + end + + it "adds the first part of facet_suggestion_query to facet.contains if it is extremely long" do + subject.facet = 'subject_facet' + subject.facet_suggestion_query = 'Call me Ishmael. Some years ago—never mind how long precisely' + solr_params = Blacklight::Solr::Request.new + + subject.add_facet_suggestion_parameters(solr_params) + + expect(solr_params[:'facet.contains']).to eq 'Call me Ishmael. Some years ago—never mind how long' + end + + it "adds facet.contains.ignoreCase" do + subject.facet = 'subject_facet' + subject.facet_suggestion_query = 'artic' + solr_params = Blacklight::Solr::Request.new + + subject.add_facet_suggestion_parameters(solr_params) + + expect(solr_params[:'facet.contains.ignoreCase']).to be true + end + end + describe "#with_tag_ex" do it "adds an !ex local parameter if the facet configuration requests it" do expect(subject.with_ex_local_param("xyz", "some-value")).to eq "{!ex=xyz}some-value" diff --git a/spec/presenters/blacklight/facet_field_presenter_spec.rb b/spec/presenters/blacklight/facet_field_presenter_spec.rb index 6d48315c31..f9cc2e9364 100644 --- a/spec/presenters/blacklight/facet_field_presenter_spec.rb +++ b/spec/presenters/blacklight/facet_field_presenter_spec.rb @@ -68,7 +68,7 @@ end describe '#in_modal?' do - context 'for a modal-like action' do + context 'for action #facet, which is a modal-like action' do before do controller.params[:action] = 'facet' end @@ -78,6 +78,16 @@ end end + context 'for action #facet_suggest, which is a modal-like action' do + before do + controller.params[:action] = 'facet_suggest' + end + + it 'is true' do + expect(presenter.in_modal?).to be true + end + end + it 'is false' do expect(presenter.in_modal?).to be false end