Browse Source

Maintenance: Search works if multiple KBs are present in database.

Mantas Masalskis 4 years ago
parent
commit
5bb948d87f

+ 2 - 2
app/models/knowledge_base/answer/translation.rb

@@ -96,7 +96,7 @@ class KnowledgeBase::Answer::Translation < ApplicationModel
       }
     end
 
-    def search_es_filter(es_response, _query, kb_locale, options)
+    def search_es_filter(es_response, _query, kb_locales, options)
       return es_response if options[:user]&.permissions?('knowledge_base.editor')
 
       answer_translations_id = es_response.pluck(:id)
@@ -104,7 +104,7 @@ class KnowledgeBase::Answer::Translation < ApplicationModel
       allowed_answer_translation_ids = KnowledgeBase::Answer
         .internal
         .joins(:translations)
-        .where(knowledge_base_answer_translations: { id: answer_translations_id, kb_locale_id: kb_locale.id })
+        .where(knowledge_base_answer_translations: { id: answer_translations_id, kb_locale_id: kb_locales.map(&:id) })
         .pluck('knowledge_base_answer_translations.id')
 
       es_response.filter { |elem| allowed_answer_translation_ids.include? elem[:id].to_i }

+ 8 - 8
app/models/knowledge_base/search.rb

@@ -20,27 +20,27 @@ class KnowledgeBase
           user:     current_user
         }
 
-        kb_locale = KnowledgeBase::Locale.preferred(current_user, KnowledgeBase.first)
+        kb_locales = KnowledgeBase.active.map { |elem| KnowledgeBase::Locale.preferred(current_user, elem) }
 
         # try search index backend
         if SearchIndexBackend.enabled?
-          search_es(params[:query], kb_locale, options)
+          search_es(params[:query], kb_locales, options)
         else
           # fallback do sql query
-          search_sql(params[:query], kb_locale, options)
+          search_sql(params[:query], kb_locales, options)
         end
       end
 
-      def search_es(query, kb_locale, options)
-        options[:query_extension] = { bool: { filter: { term: { kb_locale_id: kb_locale.id } } } }
+      def search_es(query, kb_locales, options)
+        options[:query_extension] = { bool: { filter: { terms: { kb_locale_id: kb_locales.map(&:id) } } } }
 
         es_response = SearchIndexBackend.search(query, name, options)
-        es_response = search_es_filter(es_response, query, kb_locale, options) if defined? :search_es_filter
+        es_response = search_es_filter(es_response, query, kb_locales, options) if defined? :search_es_filter
 
         es_response.map { |item| lookup(id: item[:id]) }.compact
       end
 
-      def search_sql(query, kb_locale, options)
+      def search_sql(query, kb_locales, options)
         table_name       = arel_table.name
         order_sql        = search_get_order_sql(options[:sort_by], options[:order_by], "#{table_name}.updated_at ASC")
 
@@ -48,7 +48,7 @@ class KnowledgeBase
         query.delete! '*'
 
         search_fallback("%#{query}%", options: options)
-          .where(kb_locale: kb_locale)
+          .where(kb_locale: kb_locales)
           .order(Arel.sql(order_sql))
           .offset(options[:from])
           .limit(options[:limit])

+ 2 - 1
spec/factories/knowledge_base/answer.rb

@@ -3,6 +3,7 @@ FactoryBot.define do
     transient do
       add_translation { true }
       translation_traits { [] }
+      translation_attributes { {} }
       knowledge_base { nil }
     end
 
@@ -11,7 +12,7 @@ FactoryBot.define do
     before(:create) do |answer, context|
       next if answer.translations.present?
 
-      answer.translations << build('knowledge_base/answer/translation', *context.translation_traits, answer: answer)
+      answer.translations << build('knowledge_base/answer/translation', *context.translation_traits, answer: answer, **context.translation_attributes)
     end
 
     trait :draft # empty placeholder for better readability

+ 15 - 0
spec/models/knowledge_base/answer/translation_spec.rb

@@ -43,5 +43,20 @@ RSpec.describe KnowledgeBase::Answer::Translation, type: :model, current_user_id
     include_examples 'verify given permissions', trait: :internal,  admin: true, agent: true,  customer: false
     include_examples 'verify given permissions', trait: :draft,     admin: true, agent: false, customer: false
     include_examples 'verify given permissions', trait: :archived,  admin: true, agent: false, customer: false
+
+    shared_examples 'verify multiple KBs support' do |elasticsearch:|
+      it 'searches in multiple KBs', searchindex: elasticsearch do
+        title = Faker::Appliance.equipment
+        user  = create(:admin)
+
+        create_list(:knowledge_base_answer, 2, :published, translation_attributes: { title: title })
+
+        configure_elasticsearch(required: true, rebuild: true) if elasticsearch
+        expect(described_class.search({ query: title, current_user: user }).count).to be 2
+      end
+    end
+
+    include_examples 'verify multiple KBs support', elasticsearch: true
+    include_examples 'verify multiple KBs support', elasticsearch: false
   end
 end