]> cat aescling's git repositories - mastodon.git/commitdiff
Improve Account#triadic_closures (#3079)
authoralpaca-tc <alpaca-tc@alpaca.tc>
Tue, 16 May 2017 10:06:38 +0000 (19:06 +0900)
committerEugen Rochko <eugen@zeonfederated.com>
Tue, 16 May 2017 10:06:38 +0000 (12:06 +0200)
app/models/account.rb
spec/models/account_spec.rb

index bf3d92a5109a439a2536b7912b576c467ba98a0c..bd47ce8a9ac81d7f80e266b1cd9f9c21ef69006d 100644 (file)
@@ -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
 
index efd87e87170ede77cfdc1326abdc4afbcf831e05..08098854b11f0fc26566ce2a178bf0ce64e978c9 100644 (file)
@@ -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