diff --git a/app/models/concerns/spotlight/browse_category_search_builder.rb b/app/models/concerns/spotlight/browse_category_search_builder.rb index c1fe41fc3..bcb30dc8c 100644 --- a/app/models/concerns/spotlight/browse_category_search_builder.rb +++ b/app/models/concerns/spotlight/browse_category_search_builder.rb @@ -31,12 +31,21 @@ def fix_up_browse_category_queries(solr_params) solr_params.append_query(query) if query.present? + # for a browse category formed from a saved search, the query syntax reads as two "must" values + # e.g. "json"=>{"query"=>{"bool"=>{"must"=>["savedsearchterm", "browsecategorysearchterm"]}}}} + must_values = solr_params.dig(:json, :query, :bool, :must) + + return unless must_values&.any? + + # this type of query must be parsed by lucene to function + solr_params[:defType] = 'lucene' + # This replicates existing spotlight 2.x search behavior, more or less. It # doesn't take into account the possibility that the browse category query # could use a different search field (which.. doesn't have an existing UI # control.. and may require additional upstream work to properly encapsulate # the two query parameters) - solr_params.dig(:json, :query, :bool, :must)&.map! do |q| + must_values.map! do |q| q.is_a?(String) ? { edismax: { query: q } } : q end end diff --git a/spec/factories/searches.rb b/spec/factories/searches.rb index 56b2a26b7..24210dc80 100644 --- a/spec/factories/searches.rb +++ b/spec/factories/searches.rb @@ -30,4 +30,16 @@ after(:build) { |search| search.thumbnail = FactoryBot.create(:featured_image) } end + + factory :search_field_search, class: 'Spotlight::Search' do + exhibit + title { 'Based on a search field' } + query_params { { 'search_field' => 'search', 'q' => 'model' } } + end + + factory :facet_search, class: 'Spotlight::Search' do + exhibit + title { 'Based on a facet' } + query_params { { 'f' => { 'language_ssim' => 'Latin' } } } + end end diff --git a/spec/features/browse_category_spec.rb b/spec/features/browse_category_spec.rb index fd9f0ff30..966da8b40 100644 --- a/spec/features/browse_category_spec.rb +++ b/spec/features/browse_category_spec.rb @@ -156,4 +156,30 @@ expect(page).to have_css "meta[property='og:title'][content='#{search.title}']", visible: false end end + + context 'with a search field based browse category' do + let(:search) { FactoryBot.create(:search_field_search, title: 'Search field search', exhibit: exhibit, published: true, search_box: true) } + + it 'conducts a search within the browse category' do + visit spotlight.exhibit_browse_path(exhibit, search) + expect(search.documents.count).to eq 6 + + fill_in 'Search within this browse category', with: 'azimuthal' + click_button 'Search within browse category' + expect(page).to have_text('Your search matched 1 of 6 items in this browse category.') + end + end + + context 'with a facet based browse category' do + let(:search) { FactoryBot.create(:facet_search, title: 'Facet search', exhibit: exhibit, published: true, search_box: true) } + + it 'conducts a search within the browse category' do + visit spotlight.exhibit_browse_path(exhibit, search) + expect(search.documents.count).to eq 3 + + fill_in 'Search within this browse category', with: 'Stopendael' + click_button 'Search within browse category' + expect(page).to have_text('Your search matched 1 of 3 items in this browse category.') + end + end end diff --git a/spec/models/spotlight/browse_category_search_builder_spec.rb b/spec/models/spotlight/browse_category_search_builder_spec.rb index fda7d9662..8bd4c5808 100644 --- a/spec/models/spotlight/browse_category_search_builder_spec.rb +++ b/spec/models/spotlight/browse_category_search_builder_spec.rb @@ -14,37 +14,65 @@ class BrowseCategoryMockSearchBuilder < Blacklight::SearchBuilder end let(:solr_request) { Blacklight::Solr::Request.new } let(:blacklight_params) { { browse_category_id: search.id } } - let(:search) { FactoryBot.create(:search, exhibit: exhibit, query_params: { sort: 'type', f: { genre_ssim: ['term'] }, q: 'search query' }) } - describe '#restrict_to_browse_category' do - it 'adds the search query parameters from the browse category' do - params = subject.to_hash.with_indifferent_access + context 'with a facet as the basis of the browse category (no search query present)' do + let(:search) { FactoryBot.create(:search, exhibit: exhibit, query_params: { sort: 'type', f: { genre_ssim: ['genre facet'] } }) } - expect(params).to include( - q: 'search query', - fq: ['{!term f=genre_ssim}term'], - sort: 'sort_type_ssi asc' - ) + describe 'constructs params properly' do + it 'adds facet to the solr params' do + params = subject.to_hash.with_indifferent_access + + expect(params).to include( + fq: ['{!term f=genre_ssim}genre facet'], + sort: 'sort_type_ssi asc' + ) + end + + it 'does not override the default query parser' do + params = subject.to_hash.with_indifferent_access + expect(params).not_to include(:defType) + end end + end - context 'with a user-provided query' do - let(:blacklight_params) { { browse_category_id: search.id, q: 'cats' } } + context 'with a search query as part of the construction of the browse category' do + let(:search) { FactoryBot.create(:search, exhibit: exhibit, query_params: { sort: 'type', f: { genre_ssim: ['term'] }, q: 'search query' }) } - it 'uses the user-provided query to further restrict the search' do + describe 'constructs params properly' do + it 'includes the facet and the seach term information in the params' do params = subject.to_hash.with_indifferent_access - expect(params).not_to include(:q) + expect(params).to include( - json: { - query: { - bool: { - must: [ - { edismax: { query: 'search query' } }, - { edismax: { query: 'cats' } } - ] + q: 'search query', + fq: ['{!term f=genre_ssim}term'], + sort: 'sort_type_ssi asc' + ) + end + + context 'with a search term present' do + let(:blacklight_params) { { browse_category_id: search.id, q: 'cats' } } + + it 'manipulates the solr query as expected into json syntax' do + params = subject.to_hash.with_indifferent_access + expect(params).not_to include(:q) + expect(params).to include( + json: { + query: { + bool: { + must: [ + { edismax: { query: 'search query' } }, + { edismax: { query: 'cats' } } + ] + } } } - } - ) + ) + end + + it 'overrides the default query parser' do + params = subject.to_hash.with_indifferent_access + expect(params).to include(defType: 'lucene') + end end end end