diff options
author | alpaca-tc <alpaca-tc@alpaca.tc> | 2017-05-16 19:06:38 +0900 |
---|---|---|
committer | Eugen Rochko <eugen@zeonfederated.com> | 2017-05-16 12:06:38 +0200 |
commit | 682b68438e7b9c1755151777bbb6849c00ca98e4 (patch) | |
tree | 4139bb574a23ce5c98a81bf3880b14e3f0538faa | |
parent | 09ec6e504be96a8bef72c9d988099191501dde67 (diff) |
Improve Account#triadic_closures (#3079)
-rw-r--r-- | app/models/account.rb | 20 | ||||
-rw-r--r-- | spec/models/account_spec.rb | 38 |
2 files changed, 44 insertions, 14 deletions
diff --git a/app/models/account.rb b/app/models/account.rb index bf3d92a51..bd47ce8a9 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -259,24 +259,30 @@ class Account < ApplicationRecord nil end - def triadic_closures(account, limit = 5) + def triadic_closures(account, limit: 5, offset: 0) sql = <<-SQL.squish WITH first_degree AS ( - SELECT target_account_id - FROM follows - WHERE account_id = :account_id - ) + SELECT target_account_id + FROM follows + WHERE account_id = :account_id + ) SELECT accounts.* FROM follows INNER JOIN accounts ON follows.target_account_id = accounts.id - WHERE account_id IN (SELECT * FROM first_degree) AND target_account_id NOT IN (SELECT * FROM first_degree) AND target_account_id <> :account_id + WHERE + account_id IN (SELECT * FROM first_degree) + AND target_account_id NOT IN (SELECT * FROM first_degree) + AND target_account_id NOT IN (:excluded_account_ids) GROUP BY target_account_id, accounts.id ORDER BY count(account_id) DESC + OFFSET :offset LIMIT :limit SQL + excluded_account_ids = account.excluded_from_timeline_account_ids + [account.id] + find_by_sql( - [sql, { account_id: account.id, limit: limit }] + [sql, { account_id: account.id, excluded_account_ids: excluded_account_ids, limit: limit, offset: offset }] ) end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index efd87e871..08098854b 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -261,19 +261,43 @@ RSpec.describe Account, type: :model do end describe '.triadic_closures' do - it 'finds accounts you dont follow which are followed by accounts you do follow' do - me = Fabricate(:account) - friend = Fabricate(:account) - friends_friend = Fabricate(:account) + subject { described_class.triadic_closures(me) } + + let!(:me) { Fabricate(:account) } + let!(:friend) { Fabricate(:account) } + let!(:friends_friend) { Fabricate(:account) } + let!(:both_follow) { Fabricate(:account) } + + before do me.follow!(friend) friend.follow!(friends_friend) - both_follow = Fabricate(:account) me.follow!(both_follow) friend.follow!(both_follow) + end + + it 'finds accounts you dont follow which are followed by accounts you do follow' do + is_expected.to eq [friends_friend] + end + + context 'when you block account' do + before do + me.block!(friends_friend) + end + + it 'rejects blocked accounts' do + is_expected.to be_empty + end + end - results = Account.triadic_closures(me) - expect(results).to eq [friends_friend] + context 'when you mute account' do + before do + me.mute!(friends_friend) + end + + it 'rejects muted accounts' do + is_expected.to be_empty + end end end |