Maintenance: Added test coverage for public Knowledge Base search.
This commit is contained in:
parent
5e38ca46fc
commit
21c3b31c97
10 changed files with 175 additions and 7 deletions
|
@ -215,18 +215,21 @@ test:integration:clearbit:
|
||||||
|
|
||||||
### Elasticsearch
|
### Elasticsearch
|
||||||
|
|
||||||
|
.script_integration_es_variables: &script_integration_es_variables
|
||||||
|
ES_INDEX_RAND: "true"
|
||||||
|
ES_URL: "http://elasticsearch:9200"
|
||||||
|
|
||||||
.script_integration_es_template: &script_integration_es_definition
|
.script_integration_es_template: &script_integration_es_definition
|
||||||
<<: *base_env
|
<<: *base_env
|
||||||
stage: test
|
stage: test
|
||||||
variables:
|
variables:
|
||||||
|
<<: *script_integration_es_variables
|
||||||
RAILS_ENV: "test"
|
RAILS_ENV: "test"
|
||||||
ES_INDEX_RAND: "true"
|
|
||||||
ES_URL: "http://elasticsearch:9200"
|
|
||||||
script:
|
script:
|
||||||
- bundle exec rake zammad:db:unseeded
|
- bundle exec rake zammad:db:unseeded
|
||||||
- bundle exec rails test test/integration/elasticsearch_active_test.rb
|
- bundle exec rails test test/integration/elasticsearch_active_test.rb
|
||||||
- bundle exec rails test test/integration/elasticsearch_test.rb
|
- bundle exec rails test test/integration/elasticsearch_test.rb
|
||||||
- bundle exec rspec --tag searchindex
|
- bundle exec rspec --tag searchindex --tag ~type:system
|
||||||
- bundle exec rails test test/integration/report_test.rb
|
- bundle exec rails test test/integration/report_test.rb
|
||||||
|
|
||||||
test:integration:es:5.6:
|
test:integration:es:5.6:
|
||||||
|
@ -375,12 +378,14 @@ browser:build:
|
||||||
.variables_capybara_chrome_template: &variables_capybara_chrome_definition
|
.variables_capybara_chrome_template: &variables_capybara_chrome_definition
|
||||||
<<: *test_capybara_definition
|
<<: *test_capybara_definition
|
||||||
variables:
|
variables:
|
||||||
|
<<: *script_integration_es_variables
|
||||||
RAILS_ENV: "test"
|
RAILS_ENV: "test"
|
||||||
BROWSER: "chrome"
|
BROWSER: "chrome"
|
||||||
|
|
||||||
.variables_capybara_ff_template: &variables_capybara_ff_definition
|
.variables_capybara_ff_template: &variables_capybara_ff_definition
|
||||||
<<: *test_capybara_definition
|
<<: *test_capybara_definition
|
||||||
variables:
|
variables:
|
||||||
|
<<: *script_integration_es_variables
|
||||||
RAILS_ENV: "test"
|
RAILS_ENV: "test"
|
||||||
BROWSER: "firefox"
|
BROWSER: "firefox"
|
||||||
|
|
||||||
|
|
|
@ -868,4 +868,42 @@ return true if backend is configured
|
||||||
data
|
data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
refreshes all indexes to make previous request data visible in future requests
|
||||||
|
|
||||||
|
SearchIndexBackend.refresh
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.refresh
|
||||||
|
return if !enabled?
|
||||||
|
|
||||||
|
url = "#{Setting.get('es_url')}/_all/_refresh"
|
||||||
|
|
||||||
|
Rails.logger.info "# curl -X POST \"#{url}\" "
|
||||||
|
|
||||||
|
response = UserAgent.post(
|
||||||
|
url,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
open_timeout: 8,
|
||||||
|
read_timeout: 60,
|
||||||
|
open_socket_tries: 3,
|
||||||
|
user: Setting.get('es_user'),
|
||||||
|
password: Setting.get('es_password'),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
Rails.logger.info "# #{response.code}"
|
||||||
|
|
||||||
|
return true if response.success?
|
||||||
|
|
||||||
|
raise humanized_error(
|
||||||
|
verb: 'POST',
|
||||||
|
url: url,
|
||||||
|
response: response,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -147,6 +147,12 @@ namespace :searchindex do
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
task :refresh, [:opts] => :environment do |_t, _args|
|
||||||
|
print 'refresh all indexes...'
|
||||||
|
|
||||||
|
SearchIndexBackend.refresh
|
||||||
|
end
|
||||||
|
|
||||||
task :rebuild, [:opts] => :environment do |_t, _args|
|
task :rebuild, [:opts] => :environment do |_t, _args|
|
||||||
Rake::Task['searchindex:drop'].execute
|
Rake::Task['searchindex:drop'].execute
|
||||||
Rake::Task['searchindex:create'].execute
|
Rake::Task['searchindex:create'].execute
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
FactoryBot.define do
|
FactoryBot.define do
|
||||||
factory 'knowledge_base/answer', aliases: %i[knowledge_base_answer] do
|
factory 'knowledge_base/answer', aliases: %i[knowledge_base_answer] do
|
||||||
|
transient do
|
||||||
|
add_translation { true }
|
||||||
|
end
|
||||||
|
|
||||||
category { create(:knowledge_base_category) }
|
category { create(:knowledge_base_category) }
|
||||||
|
|
||||||
before(:create) do |answer|
|
before(:create) do |answer|
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
FactoryBot.define do
|
FactoryBot.define do
|
||||||
factory 'knowledge_base/category', aliases: %i[knowledge_base_category] do
|
factory 'knowledge_base/category', aliases: %i[knowledge_base_category] do
|
||||||
|
transient do
|
||||||
|
add_translation { true }
|
||||||
|
end
|
||||||
|
|
||||||
knowledge_base { parent&.knowledge_base || create(:knowledge_base) }
|
knowledge_base { parent&.knowledge_base || create(:knowledge_base) }
|
||||||
category_icon { 'f04b' }
|
category_icon { 'f04b' }
|
||||||
|
|
||||||
|
|
20
spec/support/capybara/kb_matchers.rb
Normal file
20
spec/support/capybara/kb_matchers.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
RSpec::Matchers.define :allow_to_search_for do |expected|
|
||||||
|
match do |actual|
|
||||||
|
search_string = expected.translation.title
|
||||||
|
|
||||||
|
actual.find('.js-search-input').fill_in with: search_string
|
||||||
|
actual.find('.search-results').has_text? search_string
|
||||||
|
end
|
||||||
|
|
||||||
|
description do
|
||||||
|
"allows to search for \"#{expected.translation.title}\""
|
||||||
|
end
|
||||||
|
|
||||||
|
failure_message do
|
||||||
|
"could not search for \"#{expected.translation.title}\""
|
||||||
|
end
|
||||||
|
|
||||||
|
failure_message do
|
||||||
|
"\"#{expected.translation.title}\" showed up in search results"
|
||||||
|
end
|
||||||
|
end
|
|
@ -16,7 +16,17 @@ module SearchindexBackendHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def configure_elasticsearch(required: false)
|
=begin
|
||||||
|
|
||||||
|
prepares elasticsearch
|
||||||
|
|
||||||
|
@param required [Boolean] raises error if ES is not configured. Recommended to avoid mysterious errors in CI.
|
||||||
|
@param rebuild [Boolean] rebuilds indexes and sleeps for 1 second after given yield block is executed
|
||||||
|
|
||||||
|
@yield given block run after ES is setup, but before index rebuilding
|
||||||
|
|
||||||
|
=end
|
||||||
|
def configure_elasticsearch(required: false, rebuild: false)
|
||||||
if ENV['ES_URL'].blank?
|
if ENV['ES_URL'].blank?
|
||||||
return if !required
|
return if !required
|
||||||
|
|
||||||
|
@ -33,7 +43,7 @@ module SearchindexBackendHelper
|
||||||
if ENV['ES_INDEX_RAND'].present?
|
if ENV['ES_INDEX_RAND'].present?
|
||||||
rand_id = ENV.fetch('CI_JOB_ID', "r#{rand(999)}")
|
rand_id = ENV.fetch('CI_JOB_ID', "r#{rand(999)}")
|
||||||
test_method_name = self.class.description.gsub(/[^\w]/, '_')
|
test_method_name = self.class.description.gsub(/[^\w]/, '_')
|
||||||
ENV['ES_INDEX'] = "es_index_#{test_method_name}_#{rand_id}_#{rand(999_999_999)}"
|
ENV['ES_INDEX'] = "es_index_#{test_method_name.downcase}_#{rand_id}_#{rand(999_999_999)}"
|
||||||
end
|
end
|
||||||
if ENV['ES_INDEX'].blank?
|
if ENV['ES_INDEX'].blank?
|
||||||
raise "ERROR: Need ES_INDEX - hint ES_INDEX='estest.local_zammad'"
|
raise "ERROR: Need ES_INDEX - hint ES_INDEX='estest.local_zammad'"
|
||||||
|
@ -45,16 +55,22 @@ module SearchindexBackendHelper
|
||||||
Setting.set('es_attachment_max_size_in_mb', 1)
|
Setting.set('es_attachment_max_size_in_mb', 1)
|
||||||
|
|
||||||
yield if block_given?
|
yield if block_given?
|
||||||
|
|
||||||
|
return if !rebuild
|
||||||
|
|
||||||
|
rebuild_searchindex
|
||||||
end
|
end
|
||||||
|
|
||||||
def rebuild_searchindex
|
def rebuild_searchindex
|
||||||
Rake::Task.clear
|
Rake::Task.clear
|
||||||
Zammad::Application.load_tasks
|
Zammad::Application.load_tasks
|
||||||
Rake::Task['searchindex:rebuild'].execute
|
Rake::Task['searchindex:rebuild'].execute
|
||||||
|
Rake::Task['searchindex:refresh'].execute
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# configure_elasticsearch has to be executed manually!!!
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
config.include SearchindexBackendHelper, searchindex: true
|
config.include SearchindexBackendHelper, searchindex: true
|
||||||
end
|
end
|
||||||
|
|
30
spec/system/knowledge_base_public/editor_search_spec.rb
Normal file
30
spec/system/knowledge_base_public/editor_search_spec.rb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Public Knowledge Base for guest search', type: :system, authenticated: true, searchindex: true do
|
||||||
|
include_context 'basic Knowledge Base'
|
||||||
|
|
||||||
|
before do
|
||||||
|
configure_elasticsearch(required: true, rebuild: true) do
|
||||||
|
published_answer && answer && internal_answer
|
||||||
|
end
|
||||||
|
|
||||||
|
visit help_no_locale_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows no results notification for gibberish search' do
|
||||||
|
find('.js-search-input').fill_in with: 'Asdasdasdasdasd'
|
||||||
|
expect(page).to have_text 'No results were found'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'list published article' do
|
||||||
|
expect(page).to allow_to_search_for published_answer
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'list draft article' do
|
||||||
|
expect(page).to allow_to_search_for answer
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'list internal article' do
|
||||||
|
expect(page).to allow_to_search_for internal_answer
|
||||||
|
end
|
||||||
|
end
|
30
spec/system/knowledge_base_public/guest_search_spec.rb
Normal file
30
spec/system/knowledge_base_public/guest_search_spec.rb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Public Knowledge Base for guest search', type: :system, authenticated: false, searchindex: true do
|
||||||
|
include_context 'basic Knowledge Base'
|
||||||
|
|
||||||
|
before do
|
||||||
|
configure_elasticsearch(required: true, rebuild: true) do
|
||||||
|
published_answer && answer && internal_answer
|
||||||
|
end
|
||||||
|
|
||||||
|
visit help_no_locale_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows no results notification for gibberish search' do
|
||||||
|
find('.js-search-input').fill_in with: 'Asdasdasdasdasd'
|
||||||
|
expect(page).to have_text 'No results were found'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'list published article' do
|
||||||
|
expect(page).to allow_to_search_for published_answer
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'not list draft article' do
|
||||||
|
expect(page).not_to allow_to_search_for answer
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'not list internal article' do
|
||||||
|
expect(page).not_to allow_to_search_for internal_answer
|
||||||
|
end
|
||||||
|
end
|
|
@ -13,7 +13,17 @@ module SearchindexHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def configure_elasticsearch(required: false)
|
=begin
|
||||||
|
|
||||||
|
prepares elasticsearch
|
||||||
|
|
||||||
|
@param required [Boolean] raises error if ES is not configured. Recommended to avoid mysterious errors in CI.
|
||||||
|
@param rebuild [Boolean] rebuilds indexes and sleeps for 1 second after given yield block is executed
|
||||||
|
|
||||||
|
@yield given block run after ES is setup, but before index rebuilding
|
||||||
|
|
||||||
|
=end
|
||||||
|
def configure_elasticsearch(required: false, rebuild: false)
|
||||||
if ENV['ES_URL'].blank?
|
if ENV['ES_URL'].blank?
|
||||||
return if !required
|
return if !required
|
||||||
|
|
||||||
|
@ -30,7 +40,7 @@ module SearchindexHelper
|
||||||
if ENV['ES_INDEX_RAND'].present?
|
if ENV['ES_INDEX_RAND'].present?
|
||||||
rand_id = ENV.fetch('CI_JOB_ID', "r#{rand(999)}")
|
rand_id = ENV.fetch('CI_JOB_ID', "r#{rand(999)}")
|
||||||
test_method_name = method_name.gsub(/[^\w]/, '_')
|
test_method_name = method_name.gsub(/[^\w]/, '_')
|
||||||
ENV['ES_INDEX'] = "es_index_#{test_method_name}_#{rand_id}_#{rand(999_999_999)}"
|
ENV['ES_INDEX'] = "es_index_#{test_method_name.downcase}_#{rand_id}_#{rand(999_999_999)}"
|
||||||
end
|
end
|
||||||
if ENV['ES_INDEX'].blank?
|
if ENV['ES_INDEX'].blank?
|
||||||
raise "ERROR: Need ES_INDEX - hint ES_INDEX='estest.local_zammad'"
|
raise "ERROR: Need ES_INDEX - hint ES_INDEX='estest.local_zammad'"
|
||||||
|
@ -42,12 +52,17 @@ module SearchindexHelper
|
||||||
Setting.set('es_attachment_max_size_in_mb', 1)
|
Setting.set('es_attachment_max_size_in_mb', 1)
|
||||||
|
|
||||||
yield if block_given?
|
yield if block_given?
|
||||||
|
|
||||||
|
return if !rebuild
|
||||||
|
|
||||||
|
rebuild_searchindex
|
||||||
end
|
end
|
||||||
|
|
||||||
def rebuild_searchindex
|
def rebuild_searchindex
|
||||||
Rake::Task.clear
|
Rake::Task.clear
|
||||||
Zammad::Application.load_tasks
|
Zammad::Application.load_tasks
|
||||||
Rake::Task['searchindex:rebuild'].execute
|
Rake::Task['searchindex:rebuild'].execute
|
||||||
|
Rake::Task['searchindex:refresh'].execute
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue