end
def triadic_closures(account, limit = 5)
- sql = <<SQL
+ sql = <<-SQL.squish
WITH first_degree AS (
SELECT target_account_id
FROM follows
GROUP BY target_account_id, accounts.id
ORDER BY count(account_id) DESC
LIMIT ?
-SQL
+ SQL
Account.find_by_sql([sql, account.id, account.id, limit])
end
textsearch = '(setweight(to_tsvector(\'simple\', accounts.display_name), \'A\') || setweight(to_tsvector(\'simple\', accounts.username), \'B\') || setweight(to_tsvector(\'simple\', coalesce(accounts.domain, \'\')), \'C\'))'
query = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')'
- sql = <<SQL
+ sql = <<-SQL.squish
SELECT
accounts.*,
ts_rank_cd(#{textsearch}, #{query}, 32) AS rank
WHERE #{query} @@ #{textsearch}
ORDER BY rank DESC
LIMIT ?
-SQL
+ SQL
Account.find_by_sql([sql, limit])
end
textsearch = '(setweight(to_tsvector(\'simple\', accounts.display_name), \'A\') || setweight(to_tsvector(\'simple\', accounts.username), \'B\') || setweight(to_tsvector(\'simple\', coalesce(accounts.domain, \'\')), \'C\'))'
query = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')'
- sql = <<SQL
+ sql = <<-SQL.squish
SELECT
accounts.*,
(count(f.id) + 1) * ts_rank_cd(#{textsearch}, #{query}, 32) AS rank
GROUP BY accounts.id
ORDER BY rank DESC
LIMIT ?
-SQL
+ SQL
Account.find_by_sql([sql, account.id, account.id, limit])
end
textsearch = 'to_tsvector(\'simple\', tags.name)'
query = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')'
- sql = <<SQL
+ sql = <<-SQL.squish
SELECT
tags.*,
ts_rank_cd(#{textsearch}, #{query}) AS rank
WHERE #{query} @@ #{textsearch}
ORDER BY rank DESC
LIMIT ?
-SQL
+ SQL
Tag.find_by_sql([sql, limit])
end
end
end
+ describe '.search_for' do
+ before do
+ @match = Fabricate(
+ :account,
+ display_name: "Display Name",
+ username: "username",
+ domain: "example.com"
+ )
+ _missing = Fabricate(
+ :account,
+ display_name: "Missing",
+ username: "missing",
+ domain: "missing.com"
+ )
+ end
+
+ it 'finds accounts with matching display_name' do
+ results = Account.search_for("display")
+ expect(results).to eq [@match]
+ end
+
+ it 'finds accounts with matching username' do
+ results = Account.search_for("username")
+ expect(results).to eq [@match]
+ end
+
+ it 'finds accounts with matching domain' do
+ results = Account.search_for("example")
+ expect(results).to eq [@match]
+ end
+
+ it 'ranks multiple matches higher' do
+ account = Fabricate(
+ :account,
+ username: "username",
+ display_name: "username"
+ )
+ results = Account.search_for("username")
+ expect(results).to eq [account, @match]
+ end
+ end
+
+ describe '.advanced_search_for' do
+ it 'ranks followed accounts higher' do
+ account = Fabricate(:account)
+ match = Fabricate(:account, username: "Matching")
+ followed_match = Fabricate(:account, username: "Matcher")
+ Fabricate(:follow, account: account, target_account: followed_match)
+
+ results = Account.advanced_search_for("match", account)
+ expect(results).to eq [followed_match, match]
+ expect(results.first.rank).to be > results.last.rank
+ end
+ end
+
describe '.find_local' do
before do
Fabricate(:account, username: 'Alice')
expect(subject.match('https://en.wikipedia.org/wiki/Ghostbusters_(song)#Lawsuit')).to be_nil
end
end
+
+ describe '.search_for' do
+ it 'finds tag records with matching names' do
+ tag = Fabricate(:tag, name: "match")
+ _miss_tag = Fabricate(:tag, name: "miss")
+
+ results = Tag.search_for("match")
+
+ expect(results).to eq [tag]
+ end
+ end
end