diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index dfd127750..c96a6fd82 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -8,6 +8,7 @@ class SearchController < ApplicationController :classified_listing_search, :page, :per_page, + :tag_boolean_mode, { tags: [] }, diff --git a/app/javascript/listings/listings.jsx b/app/javascript/listings/listings.jsx index 0a7c821c2..21998b65b 100644 --- a/app/javascript/listings/listings.jsx +++ b/app/javascript/listings/listings.jsx @@ -331,6 +331,7 @@ export class Listings extends Component { page, per_page: LISTING_PAGE_SIZE, tags, + tag_boolean_mode: 'all', }; const responsePromise = fetchSearch('classified_listings', dataHash); diff --git a/app/services/search/query_builders/classified_listing.rb b/app/services/search/query_builders/classified_listing.rb index 09359e3c3..8cc5c91cf 100644 --- a/app/services/search/query_builders/classified_listing.rb +++ b/app/services/search/query_builders/classified_listing.rb @@ -60,10 +60,16 @@ module Search end def term_keys - TERM_KEYS.map do |term_key| + TERM_KEYS.flat_map do |term_key| next unless @params.key? term_key - { terms: { term_key => Array.wrap(@params[term_key]) } } + values = Array.wrap(@params[term_key]) + + if params[:tag_boolean_mode] == "all" && term_key == :tags + values.map { |tag| { terms: { term_key => Array.wrap(tag) } } } + else + { terms: { term_key => values } } + end end.compact end diff --git a/spec/services/search/query_builders/classified_listing_spec.rb b/spec/services/search/query_builders/classified_listing_spec.rb index ea3147d50..f3390e159 100644 --- a/spec/services/search/query_builders/classified_listing_spec.rb +++ b/spec/services/search/query_builders/classified_listing_spec.rb @@ -16,11 +16,25 @@ RSpec.describe Search::QueryBuilders::ClassifiedListing, type: :service do describe "#as_hash" do it "applies TERM_KEYS from params" do - params = { category: "cfp", tags: ["beginner"], contact_via_connect: false } + params = { category: "cfp", tags: %w[beginner intermediate professional], contact_via_connect: false } + filter = described_class.new(params: params) + exepcted_filters = [ + { "terms" => { "category" => ["cfp"] } }, + { "terms" => { "tags" => %w[beginner intermediate professional] } }, + { "terms" => { "contact_via_connect" => [false] } }, + { "terms" => { "published" => [true] } }, + ] + expect(filter.as_hash.dig("query", "bool", "filter")).to match_array(exepcted_filters) + end + + it "applies TERM_KEYS from params with boolean mode" do + params = { category: "cfp", tags: %w[beginner intermediate professional], contact_via_connect: false, tag_boolean_mode: "all" } filter = described_class.new(params: params) exepcted_filters = [ { "terms" => { "category" => ["cfp"] } }, { "terms" => { "tags" => ["beginner"] } }, + { "terms" => { "tags" => ["intermediate"] } }, + { "terms" => { "tags" => ["professional"] } }, { "terms" => { "contact_via_connect" => [false] } }, { "terms" => { "published" => [true] } }, ]