269 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			269 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| RSpec.shared_examples 'Account::Search' do
 | |
|   describe '.search_for' do
 | |
|     before do
 | |
|       _missing = Fabricate(
 | |
|         :account,
 | |
|         display_name: 'Missing',
 | |
|         username: 'missing',
 | |
|         domain: 'missing.com'
 | |
|       )
 | |
|     end
 | |
| 
 | |
|     it 'does not return suspended users' do
 | |
|       Fabricate(
 | |
|         :account,
 | |
|         display_name: 'Display Name',
 | |
|         username: 'username',
 | |
|         domain: 'example.com',
 | |
|         suspended: true
 | |
|       )
 | |
| 
 | |
|       results = described_class.search_for('username')
 | |
|       expect(results).to eq []
 | |
|     end
 | |
| 
 | |
|     it 'does not return unapproved users' do
 | |
|       match = Fabricate(
 | |
|         :account,
 | |
|         display_name: 'Display Name',
 | |
|         username: 'username'
 | |
|       )
 | |
| 
 | |
|       match.user.update(approved: false)
 | |
| 
 | |
|       results = described_class.search_for('username')
 | |
|       expect(results).to eq []
 | |
|     end
 | |
| 
 | |
|     it 'does not return unconfirmed users' do
 | |
|       match = Fabricate(
 | |
|         :account,
 | |
|         display_name: 'Display Name',
 | |
|         username: 'username'
 | |
|       )
 | |
| 
 | |
|       match.user.update(confirmed_at: nil)
 | |
| 
 | |
|       results = described_class.search_for('username')
 | |
|       expect(results).to eq []
 | |
|     end
 | |
| 
 | |
|     it 'accepts ?, \, : and space as delimiter' do
 | |
|       match = Fabricate(
 | |
|         :account,
 | |
|         display_name: 'A & l & i & c & e',
 | |
|         username: 'username',
 | |
|         domain: 'example.com'
 | |
|       )
 | |
| 
 | |
|       results = described_class.search_for('A?l\i:c e')
 | |
|       expect(results).to eq [match]
 | |
|     end
 | |
| 
 | |
|     it 'finds accounts with matching display_name' do
 | |
|       match = Fabricate(
 | |
|         :account,
 | |
|         display_name: 'Display Name',
 | |
|         username: 'username',
 | |
|         domain: 'example.com'
 | |
|       )
 | |
| 
 | |
|       results = described_class.search_for('display')
 | |
|       expect(results).to eq [match]
 | |
|     end
 | |
| 
 | |
|     it 'finds accounts with matching username' do
 | |
|       match = Fabricate(
 | |
|         :account,
 | |
|         display_name: 'Display Name',
 | |
|         username: 'username',
 | |
|         domain: 'example.com'
 | |
|       )
 | |
| 
 | |
|       results = described_class.search_for('username')
 | |
|       expect(results).to eq [match]
 | |
|     end
 | |
| 
 | |
|     it 'finds accounts with matching domain' do
 | |
|       match = Fabricate(
 | |
|         :account,
 | |
|         display_name: 'Display Name',
 | |
|         username: 'username',
 | |
|         domain: 'example.com'
 | |
|       )
 | |
| 
 | |
|       results = described_class.search_for('example')
 | |
|       expect(results).to eq [match]
 | |
|     end
 | |
| 
 | |
|     it 'limits via constant by default' do
 | |
|       stub_const('Account::Search::DEFAULT_LIMIT', 1)
 | |
|       2.times.each { Fabricate(:account, display_name: 'Display Name') }
 | |
|       results = described_class.search_for('display')
 | |
|       expect(results.size).to eq 1
 | |
|     end
 | |
| 
 | |
|     it 'accepts arbitrary limits' do
 | |
|       2.times.each { Fabricate(:account, display_name: 'Display Name') }
 | |
|       results = described_class.search_for('display', limit: 1)
 | |
|       expect(results.size).to eq 1
 | |
|     end
 | |
| 
 | |
|     it 'ranks multiple matches higher' do
 | |
|       matches = [
 | |
|         { username: 'username', display_name: 'username' },
 | |
|         { display_name: 'Display Name', username: 'username', domain: 'example.com' },
 | |
|       ].map(&method(:Fabricate).curry(2).call(:account))
 | |
| 
 | |
|       results = described_class.search_for('username')
 | |
|       expect(results).to eq matches
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   describe '.advanced_search_for' do
 | |
|     let(:account) { Fabricate(:account) }
 | |
| 
 | |
|     context 'when limiting search to followed accounts' do
 | |
|       it 'accepts ?, \, : and space as delimiter' do
 | |
|         match = Fabricate(
 | |
|           :account,
 | |
|           display_name: 'A & l & i & c & e',
 | |
|           username: 'username',
 | |
|           domain: 'example.com'
 | |
|         )
 | |
|         account.follow!(match)
 | |
| 
 | |
|         results = described_class.advanced_search_for('A?l\i:c e', account, limit: 10, following: true)
 | |
|         expect(results).to eq [match]
 | |
|       end
 | |
| 
 | |
|       it 'does not return non-followed accounts' do
 | |
|         Fabricate(
 | |
|           :account,
 | |
|           display_name: 'A & l & i & c & e',
 | |
|           username: 'username',
 | |
|           domain: 'example.com'
 | |
|         )
 | |
| 
 | |
|         results = described_class.advanced_search_for('A?l\i:c e', account, limit: 10, following: true)
 | |
|         expect(results).to eq []
 | |
|       end
 | |
| 
 | |
|       it 'does not return suspended users' do
 | |
|         Fabricate(
 | |
|           :account,
 | |
|           display_name: 'Display Name',
 | |
|           username: 'username',
 | |
|           domain: 'example.com',
 | |
|           suspended: true
 | |
|         )
 | |
| 
 | |
|         results = described_class.advanced_search_for('username', account, limit: 10, following: true)
 | |
|         expect(results).to eq []
 | |
|       end
 | |
| 
 | |
|       it 'does not return unapproved users' do
 | |
|         match = Fabricate(
 | |
|           :account,
 | |
|           display_name: 'Display Name',
 | |
|           username: 'username'
 | |
|         )
 | |
| 
 | |
|         match.user.update(approved: false)
 | |
| 
 | |
|         results = described_class.advanced_search_for('username', account, limit: 10, following: true)
 | |
|         expect(results).to eq []
 | |
|       end
 | |
| 
 | |
|       it 'does not return unconfirmed users' do
 | |
|         match = Fabricate(
 | |
|           :account,
 | |
|           display_name: 'Display Name',
 | |
|           username: 'username'
 | |
|         )
 | |
| 
 | |
|         match.user.update(confirmed_at: nil)
 | |
| 
 | |
|         results = described_class.advanced_search_for('username', account, limit: 10, following: true)
 | |
|         expect(results).to eq []
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     it 'does not return suspended users' do
 | |
|       Fabricate(
 | |
|         :account,
 | |
|         display_name: 'Display Name',
 | |
|         username: 'username',
 | |
|         domain: 'example.com',
 | |
|         suspended: true
 | |
|       )
 | |
| 
 | |
|       results = described_class.advanced_search_for('username', account)
 | |
|       expect(results).to eq []
 | |
|     end
 | |
| 
 | |
|     it 'does not return unapproved users' do
 | |
|       match = Fabricate(
 | |
|         :account,
 | |
|         display_name: 'Display Name',
 | |
|         username: 'username'
 | |
|       )
 | |
| 
 | |
|       match.user.update(approved: false)
 | |
| 
 | |
|       results = described_class.advanced_search_for('username', account)
 | |
|       expect(results).to eq []
 | |
|     end
 | |
| 
 | |
|     it 'does not return unconfirmed users' do
 | |
|       match = Fabricate(
 | |
|         :account,
 | |
|         display_name: 'Display Name',
 | |
|         username: 'username'
 | |
|       )
 | |
| 
 | |
|       match.user.update(confirmed_at: nil)
 | |
| 
 | |
|       results = described_class.advanced_search_for('username', account)
 | |
|       expect(results).to eq []
 | |
|     end
 | |
| 
 | |
|     it 'accepts ?, \, : and space as delimiter' do
 | |
|       match = Fabricate(
 | |
|         :account,
 | |
|         display_name: 'A & l & i & c & e',
 | |
|         username: 'username',
 | |
|         domain: 'example.com'
 | |
|       )
 | |
| 
 | |
|       results = described_class.advanced_search_for('A?l\i:c e', account)
 | |
|       expect(results).to eq [match]
 | |
|     end
 | |
| 
 | |
|     it 'limits result count by default value' do
 | |
|       stub_const('Account::Search::DEFAULT_LIMIT', 1)
 | |
|       2.times { Fabricate(:account, display_name: 'Display Name') }
 | |
|       results = described_class.advanced_search_for('display', account)
 | |
|       expect(results.size).to eq 1
 | |
|     end
 | |
| 
 | |
|     it 'accepts arbitrary limits' do
 | |
|       2.times { Fabricate(:account, display_name: 'Display Name') }
 | |
|       results = described_class.advanced_search_for('display', account, limit: 1)
 | |
|       expect(results.size).to eq 1
 | |
|     end
 | |
| 
 | |
|     it 'ranks followed accounts higher' do
 | |
|       match = Fabricate(:account, username: 'Matching')
 | |
|       followed_match = Fabricate(:account, username: 'Matcher')
 | |
|       Fabricate(:follow, account: account, target_account: followed_match)
 | |
| 
 | |
|       results = described_class.advanced_search_for('match', account)
 | |
|       expect(results).to eq [followed_match, match]
 | |
|       expect(results.first.rank).to be > results.last.rank
 | |
|     end
 | |
|   end
 | |
| end
 |