Add search tests (#26703)
This commit is contained in:
		
							
								
								
									
										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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user