Add search tests (#26703)
This commit is contained in:
		
					parent
					
						
							
								3a679844e4
							
						
					
				
			
			
				commit
				
					
						4d9186a48c
					
				
			
		
					 7 changed files with 299 additions and 2 deletions
				
			
		
							
								
								
									
										113
									
								
								.github/workflows/test-ruby.yml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										113
									
								
								.github/workflows/test-ruby.yml
									
										
									
									
										vendored
									
									
								
							|  | @ -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/ | ||||
|  |  | |||
							
								
								
									
										3
									
								
								Vagrantfile
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								Vagrantfile
									
										
									
									
										vendored
									
									
								
							|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
							
								
								
									
										51
									
								
								spec/search/models/concerns/account_search_spec.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								spec/search/models/concerns/account_search_spec.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 | ||||
							
								
								
									
										53
									
								
								spec/search/models/concerns/account_statuses_search_spec.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								spec/search/models/concerns/account_statuses_search_spec.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 | ||||
|  | @ -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 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue