about summary refs log tree commit diff
path: root/spec/lib/activitypub/activity/follow_spec.rb
diff options
context:
space:
mode:
authorClaire <claire.github-309c@sitedethib.com>2021-02-11 01:53:44 +0100
committerGitHub <noreply@github.com>2021-02-11 01:53:44 +0100
commitbe3b9f81518196f73f2b9636137732659df8cc5b (patch)
treec3313f525f9d153459e0a164bb40f8a8a9dcfb81 /spec/lib/activitypub/activity/follow_spec.rb
parentf5fefdc11aee24626d78480766fda878911f58b7 (diff)
Fix URI of repeat follow requests not being recorded (#15662)
* Fix URI of repeat follow requests not being recorded

In case we receive a “repeat” or “duplicate” follow request, we automatically
fast-forward the accept with the latest received Activity `id`, but we don't
record it.

In general, a “repeat” or “duplicate” follow request may happen if for some
reason (e.g. inconsistent handling of Block or Undo Accept activities, an
instance being brought back up from the dead, etc.) the local instance thought
the remote actor were following them while the remote actor thought otherwise.

In those cases, the remote instance does not know about the older Follow
activity `id`, so keeping that record serves no purpose, but knowing the most
recent one is useful if the remote implementation at some point refers to it
by `id` without inlining it.

* Add tests
Diffstat (limited to 'spec/lib/activitypub/activity/follow_spec.rb')
-rw-r--r--spec/lib/activitypub/activity/follow_spec.rb171
1 files changed, 140 insertions, 31 deletions
diff --git a/spec/lib/activitypub/activity/follow_spec.rb b/spec/lib/activitypub/activity/follow_spec.rb
index 05112cc18..fd4ede82b 100644
--- a/spec/lib/activitypub/activity/follow_spec.rb
+++ b/spec/lib/activitypub/activity/follow_spec.rb
@@ -17,62 +17,171 @@ RSpec.describe ActivityPub::Activity::Follow do
   describe '#perform' do
     subject { described_class.new(json, sender) }
 
-    context 'unlocked account' do
-      before do
-        subject.perform
+    context 'with no prior follow' do
+      context 'unlocked account' do
+        before do
+          subject.perform
+        end
+
+        it 'creates a follow from sender to recipient' do
+          expect(sender.following?(recipient)).to be true
+          expect(sender.active_relationships.find_by(target_account: recipient).uri).to eq 'foo'
+        end
+
+        it 'does not create a follow request' do
+          expect(sender.requested?(recipient)).to be false
+        end
       end
 
-      it 'creates a follow from sender to recipient' do
-        expect(sender.following?(recipient)).to be true
+      context 'silenced account following an unlocked account' do
+        before do
+          sender.touch(:silenced_at)
+          subject.perform
+        end
+
+        it 'does not create a follow from sender to recipient' do
+          expect(sender.following?(recipient)).to be false
+        end
+
+        it 'creates a follow request' do
+          expect(sender.requested?(recipient)).to be true
+          expect(sender.follow_requests.find_by(target_account: recipient).uri).to eq 'foo'
+        end
       end
 
-      it 'does not create a follow request' do
-        expect(sender.requested?(recipient)).to be false
+      context 'unlocked account muting the sender' do
+        before do
+          recipient.mute!(sender)
+          subject.perform
+        end
+
+        it 'creates a follow from sender to recipient' do
+          expect(sender.following?(recipient)).to be true
+          expect(sender.active_relationships.find_by(target_account: recipient).uri).to eq 'foo'
+        end
+
+        it 'does not create a follow request' do
+          expect(sender.requested?(recipient)).to be false
+        end
+      end
+
+      context 'locked account' do
+        before do
+          recipient.update(locked: true)
+          subject.perform
+        end
+
+        it 'does not create a follow from sender to recipient' do
+          expect(sender.following?(recipient)).to be false
+        end
+
+        it 'creates a follow request' do
+          expect(sender.requested?(recipient)).to be true
+          expect(sender.follow_requests.find_by(target_account: recipient).uri).to eq 'foo'
+        end
       end
     end
 
-    context 'silenced account following an unlocked account' do
+    context 'when a follow relationship already exists' do
       before do
-        sender.touch(:silenced_at)
-        subject.perform
+        sender.active_relationships.create!(target_account: recipient, uri: 'bar')
       end
 
-      it 'does not create a follow from sender to recipient' do
-        expect(sender.following?(recipient)).to be false
-      end
+      context 'unlocked account' do
+        before do
+          subject.perform
+        end
+
+        it 'correctly sets the new URI' do
+          expect(sender.active_relationships.find_by(target_account: recipient).uri).to eq 'foo'
+        end
 
-      it 'creates a follow request' do
-        expect(sender.requested?(recipient)).to be true
+        it 'does not create a follow request' do
+          expect(sender.requested?(recipient)).to be false
+        end
       end
-    end
 
-    context 'unlocked account muting the sender' do
-      before do
-        recipient.mute!(sender)
-        subject.perform
+      context 'silenced account following an unlocked account' do
+        before do
+          sender.touch(:silenced_at)
+          subject.perform
+        end
+
+        it 'correctly sets the new URI' do
+          expect(sender.active_relationships.find_by(target_account: recipient).uri).to eq 'foo'
+        end
+
+        it 'does not create a follow request' do
+          expect(sender.requested?(recipient)).to be false
+        end
       end
 
-      it 'creates a follow from sender to recipient' do
-        expect(sender.following?(recipient)).to be true
+      context 'unlocked account muting the sender' do
+        before do
+          recipient.mute!(sender)
+          subject.perform
+        end
+
+        it 'correctly sets the new URI' do
+          expect(sender.active_relationships.find_by(target_account: recipient).uri).to eq 'foo'
+        end
+
+        it 'does not create a follow request' do
+          expect(sender.requested?(recipient)).to be false
+        end
       end
 
-      it 'does not create a follow request' do
-        expect(sender.requested?(recipient)).to be false
+      context 'locked account' do
+        before do
+          recipient.update(locked: true)
+          subject.perform
+        end
+
+        it 'correctly sets the new URI' do
+          expect(sender.active_relationships.find_by(target_account: recipient).uri).to eq 'foo'
+        end
+
+        it 'does not create a follow request' do
+          expect(sender.requested?(recipient)).to be false
+        end
       end
     end
 
-    context 'locked account' do
+    context 'when a follow request already exists' do
       before do
-        recipient.update(locked: true)
-        subject.perform
+        sender.follow_requests.create!(target_account: recipient, uri: 'bar')
       end
 
-      it 'does not create a follow from sender to recipient' do
-        expect(sender.following?(recipient)).to be false
+      context 'silenced account following an unlocked account' do
+        before do
+          sender.touch(:silenced_at)
+          subject.perform
+        end
+
+        it 'does not create a follow from sender to recipient' do
+          expect(sender.following?(recipient)).to be false
+        end
+
+        it 'correctly sets the new URI' do
+          expect(sender.requested?(recipient)).to be true
+          expect(sender.follow_requests.find_by(target_account: recipient).uri).to eq 'foo'
+        end
       end
 
-      it 'creates a follow request' do
-        expect(sender.requested?(recipient)).to be true
+      context 'locked account' do
+        before do
+          recipient.update(locked: true)
+          subject.perform
+        end
+
+        it 'does not create a follow from sender to recipient' do
+          expect(sender.following?(recipient)).to be false
+        end
+
+        it 'correctly sets the new URI' do
+          expect(sender.requested?(recipient)).to be true
+          expect(sender.follow_requests.find_by(target_account: recipient).uri).to eq 'foo'
+        end
       end
     end
   end