summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsgoldstein <jakegoldstein95@gmail.com>2023-09-08 10:17:55 -0400
committerGitHub <noreply@github.com>2023-09-08 16:17:55 +0200
commit4d9186a48c494bdd098f7a6273c3f0bf4dc5e19a (patch)
treee18158e06539a3bcb94cf6b3bd8094f29a90b727
parent3a679844e499df026be7d5b3a9e80e5bf3ad585a (diff)
Add search tests (#26703)
-rw-r--r--.github/workflows/test-ruby.yml113
-rw-r--r--Vagrantfile3
-rw-r--r--lib/tasks/spec.rake10
-rw-r--r--spec/rails_helper.rb29
-rw-r--r--spec/search/models/concerns/account_search_spec.rb51
-rw-r--r--spec/search/models/concerns/account_statuses_search_spec.rb53
-rw-r--r--spec/spec_helper.rb42
7 files changed, 299 insertions, 2 deletions
diff --git a/.github/workflows/test-ruby.yml b/.github/workflows/test-ruby.yml
index ff135867f93..ecded2cc2fa 100644
--- a/.github/workflows/test-ruby.yml
+++ b/.github/workflows/test-ruby.yml
@@ -250,3 +250,116 @@ jobs:
with:
name: e2e-screenshots
path: tmp/screenshots/
+
+ test-search:
+ name: Testing search
+ runs-on: ubuntu-latest
+
+ needs:
+ - build
+
+ services:
+ postgres:
+ image: postgres:14-alpine
+ env:
+ POSTGRES_PASSWORD: postgres
+ POSTGRES_USER: postgres
+ options: >-
+ --health-cmd pg_isready
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 5
+ ports:
+ - 5432:5432
+
+ redis:
+ image: redis:7-alpine
+ options: >-
+ --health-cmd "redis-cli ping"
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 5
+ ports:
+ - 6379:6379
+
+ elasticsearch:
+ image: docker.elastic.co/elasticsearch/elasticsearch:7.17.9
+ env:
+ discovery.type: single-node
+ xpack.security.enabled: false
+ options: >-
+ --health-cmd "curl http://localhost:9200/_cluster/health"
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 10
+ ports:
+ - 9200:9200
+
+ env:
+ DB_HOST: localhost
+ DB_USER: postgres
+ DB_PASS: postgres
+ DISABLE_SIMPLECOV: true
+ RAILS_ENV: test
+ BUNDLE_WITH: test
+ ES_ENABLED: true
+ ES_HOST: localhost
+ ES_PORT: 9200
+
+ strategy:
+ fail-fast: false
+ matrix:
+ ruby-version:
+ - '3.0'
+ - '3.1'
+ - '.ruby-version'
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - uses: actions/download-artifact@v3
+ with:
+ path: './public'
+ name: ${{ github.sha }}
+
+ - name: Update package index
+ run: sudo apt-get update
+
+ - name: Set up Node.js
+ uses: actions/setup-node@v3
+ with:
+ cache: yarn
+ node-version-file: '.nvmrc'
+
+ - name: Install native Ruby dependencies
+ run: sudo apt-get install -y libicu-dev libidn11-dev
+
+ - name: Install additional system dependencies
+ run: sudo apt-get install -y ffmpeg imagemagick
+
+ - name: Set up bundler cache
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: ${{ matrix.ruby-version}}
+ bundler-cache: true
+
+ - run: yarn --frozen-lockfile
+
+ - name: Load database schema
+ run: './bin/rails db:create db:schema:load db:seed'
+
+ - run: bundle exec rake spec:search
+
+ - name: Archive logs
+ uses: actions/upload-artifact@v3
+ if: failure()
+ with:
+ name: test-search-logs-${{ matrix.ruby-version }}
+ path: log/
+
+ - name: Archive test screenshots
+ uses: actions/upload-artifact@v3
+ if: failure()
+ with:
+ name: test-search-screenshots
+ path: tmp/screenshots/
diff --git a/Vagrantfile b/Vagrantfile
index 1117d62fff2..4303f8e067c 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -76,7 +76,8 @@ path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["localhost"]
-cluster.initial_master_nodes: ["node-1"]' > /etc/elasticsearch/elasticsearch.yml
+cluster.initial_master_nodes: ["node-1"]
+xpack.security.enabled: false' > /etc/elasticsearch/elasticsearch.yml
sudo systemctl restart elasticsearch
diff --git a/lib/tasks/spec.rake b/lib/tasks/spec.rake
index 8f2cbeea358..ec4cd39bf4c 100644
--- a/lib/tasks/spec.rake
+++ b/lib/tasks/spec.rake
@@ -9,3 +9,13 @@ if Rake::Task.task_defined?('spec:system')
Rake::Task['spec:system'].enhance ['spec:enable_system_specs']
end
+
+if Rake::Task.task_defined?('spec:search')
+ namespace :spec do
+ task :enable_search_specs do # rubocop:disable Rails/RakeEnvironment
+ ENV['RUN_SEARCH_SPECS'] = 'true'
+ end
+ end
+
+ Rake::Task['spec:search'].enhance ['spec:enable_search_specs']
+end
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index d4ff79c51c9..7b8dccb6a0b 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -4,11 +4,17 @@ ENV['RAILS_ENV'] ||= 'test'
# This needs to be defined before Rails is initialized
RUN_SYSTEM_SPECS = ENV.fetch('RUN_SYSTEM_SPECS', false)
+RUN_SEARCH_SPECS = ENV.fetch('RUN_SEARCH_SPECS', false)
if RUN_SYSTEM_SPECS
STREAMING_PORT = ENV.fetch('TEST_STREAMING_PORT', '4020')
ENV['STREAMING_API_BASE_URL'] = "http://localhost:#{STREAMING_PORT}"
end
+
+if RUN_SEARCH_SPECS
+ # Include any configuration or setups specific to search tests here
+end
+
require File.expand_path('../config/environment', __dir__)
abort('The Rails environment is running in production mode!') if Rails.env.production?
@@ -30,6 +36,7 @@ Sidekiq.logger = nil
# System tests config
DatabaseCleaner.strategy = [:deletion]
streaming_server_manager = StreamingServerManager.new
+search_data_manager = SearchDataManager.new
Devise::Test::ControllerHelpers.module_eval do
alias_method :original_sign_in, :sign_in
@@ -69,7 +76,14 @@ end
RSpec.configure do |config|
# This is set before running spec:system, see lib/tasks/tests.rake
- config.filter_run_excluding type: :system unless RUN_SYSTEM_SPECS
+ config.filter_run_excluding type: lambda { |type|
+ case type
+ when :system
+ !RUN_SYSTEM_SPECS
+ when :search
+ !RUN_SEARCH_SPECS
+ end
+ }
config.fixture_path = Rails.root.join('spec', 'fixtures')
config.use_transactional_fixtures = true
config.order = 'random'
@@ -113,10 +127,17 @@ RSpec.configure do |config|
Webpacker.compile
streaming_server_manager.start(port: STREAMING_PORT)
end
+
+ if RUN_SEARCH_SPECS
+ Chewy.strategy(:urgent)
+ search_data_manager.prepare_test_data
+ end
end
config.after :suite do
streaming_server_manager.stop
+
+ search_data_manager.cleanup_test_data if RUN_SEARCH_SPECS
end
config.around :each, type: :system do |example|
@@ -137,6 +158,12 @@ RSpec.configure do |config|
self.use_transactional_tests = true
end
+ config.around :each, type: :search do |example|
+ search_data_manager.populate_indexes
+ example.run
+ search_data_manager.remove_indexes
+ end
+
config.before(:each) do |example|
unless example.metadata[:paperclip_processing]
allow_any_instance_of(Paperclip::Attachment).to receive(:post_process).and_return(true) # rubocop:disable RSpec/AnyInstance
diff --git a/spec/search/models/concerns/account_search_spec.rb b/spec/search/models/concerns/account_search_spec.rb
new file mode 100644
index 00000000000..65e1e4de1c9
--- /dev/null
+++ b/spec/search/models/concerns/account_search_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe AccountSearch do
+ describe 'a non-discoverable account becoming discoverable' do
+ let(:account) { Account.find_by(username: 'search_test_account_1') }
+
+ context 'when picking a non-discoverable account' do
+ it 'its bio is not in the AccountsIndex' do
+ results = AccountsIndex.filter(term: { username: account.username })
+ expect(results.count).to eq(1)
+ expect(results.first.text).to be_nil
+ end
+ end
+
+ context 'when the non-discoverable account becomes discoverable' do
+ it 'its bio is added to the AccountsIndex' do
+ account.discoverable = true
+ account.save!
+
+ results = AccountsIndex.filter(term: { username: account.username })
+ expect(results.count).to eq(1)
+ expect(results.first.text).to eq(account.note)
+ end
+ end
+ end
+
+ describe 'a discoverable account becoming non-discoverable' do
+ let(:account) { Account.find_by(username: 'search_test_account_0') }
+
+ context 'when picking an discoverable account' do
+ it 'has its bio in the AccountsIndex' do
+ results = AccountsIndex.filter(term: { username: account.username })
+ expect(results.count).to eq(1)
+ expect(results.first.text).to eq(account.note)
+ end
+ end
+
+ context 'when the discoverable account becomes non-discoverable' do
+ it 'its bio is removed from the AccountsIndex' do
+ account.discoverable = false
+ account.save!
+
+ results = AccountsIndex.filter(term: { username: account.username })
+ expect(results.count).to eq(1)
+ expect(results.first.text).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/search/models/concerns/account_statuses_search_spec.rb b/spec/search/models/concerns/account_statuses_search_spec.rb
new file mode 100644
index 00000000000..d35cfa56392
--- /dev/null
+++ b/spec/search/models/concerns/account_statuses_search_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe AccountStatusesSearch do
+ describe 'a non-indexable account becoming indexable' do
+ let(:account) { Account.find_by(username: 'search_test_account_1') }
+
+ context 'when picking a non-indexable account' do
+ it 'has no statuses in the PublicStatusesIndex' do
+ expect(PublicStatusesIndex.filter(term: { account_id: account.id }).count).to eq(0)
+ end
+
+ it 'has statuses in the StatusesIndex' do
+ expect(StatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.count)
+ end
+ end
+
+ context 'when the non-indexable account becomes indexable' do
+ it 'adds the public statuses to the PublicStatusesIndex' do
+ account.indexable = true
+ account.save!
+
+ expect(PublicStatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.where(visibility: :public).count)
+ expect(StatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.count)
+ end
+ end
+ end
+
+ describe 'an indexable account becoming non-indexable' do
+ let(:account) { Account.find_by(username: 'search_test_account_0') }
+
+ context 'when picking an indexable account' do
+ it 'has statuses in the PublicStatusesIndex' do
+ expect(PublicStatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.where(visibility: :public).count)
+ end
+
+ it 'has statuses in the StatusesIndex' do
+ expect(StatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.count)
+ end
+ end
+
+ context 'when the indexable account becomes non-indexable' do
+ it 'removes the statuses from the PublicStatusesIndex' do
+ account.indexable = false
+ account.save!
+
+ expect(PublicStatusesIndex.filter(term: { account_id: account.id }).count).to eq(0)
+ expect(StatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.count)
+ end
+ end
+ end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index dcbcad48e6f..b4c20545f54 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -129,3 +129,45 @@ class StreamingServerManager
@running_thread.join
end
end
+
+class SearchDataManager
+ def prepare_test_data
+ 4.times do |i|
+ username = "search_test_account_#{i}"
+ account = Fabricate.create(:account, username: username, indexable: i.even?, discoverable: i.even?, note: "Lover of #{i}.")
+ 2.times do |j|
+ Fabricate.create(:status, account: account, text: "#{username}'s #{j} post", visibility: j.even? ? :public : :private)
+ end
+ end
+
+ 3.times do |i|
+ Fabricate.create(:tag, name: "search_test_tag_#{i}")
+ end
+ end
+
+ def indexes
+ [
+ AccountsIndex,
+ PublicStatusesIndex,
+ StatusesIndex,
+ TagsIndex,
+ ]
+ end
+
+ def populate_indexes
+ indexes.each do |index_class|
+ index_class.purge!
+ index_class.import!
+ end
+ end
+
+ def remove_indexes
+ indexes.each(&:delete!)
+ end
+
+ def cleanup_test_data
+ Status.destroy_all
+ Account.destroy_all
+ Tag.destroy_all
+ end
+end