about summary refs log tree commit diff
path: root/spec/lib/activitypub/activity/create_spec.rb
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2019-02-17 03:38:25 +0100
committerGitHub <noreply@github.com>2019-02-17 03:38:25 +0100
commit147b4c2c3afacd6ad9d5c1353c072861eaca5fd2 (patch)
treef1e7cc90285e97715ab6aae25abc4e5165c3100b /spec/lib/activitypub/activity/create_spec.rb
parent041ff5fa9a45f7b8d1048a05a35611622b6f5fdb (diff)
Add logging for rejected ActivityPub payloads and add tests (#10062)
Diffstat (limited to 'spec/lib/activitypub/activity/create_spec.rb')
-rw-r--r--spec/lib/activitypub/activity/create_spec.rb710
1 files changed, 417 insertions, 293 deletions
diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb
index cd20b7c7c..26cb84871 100644
--- a/spec/lib/activitypub/activity/create_spec.rb
+++ b/spec/lib/activitypub/activity/create_spec.rb
@@ -13,8 +13,6 @@ RSpec.describe ActivityPub::Activity::Create do
     }.with_indifferent_access
   end
 
-  subject { described_class.new(json, sender) }
-
   before do
     sender.update(uri: ActivityPub::TagManager.instance.uri_for(sender))
 
@@ -23,59 +21,407 @@ RSpec.describe ActivityPub::Activity::Create do
   end
 
   describe '#perform' do
-    before do
-      subject.perform
-    end
-
-    context 'standalone' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
-
-        expect(status).to_not be_nil
-        expect(status.text).to eq 'Lorem ipsum'
-      end
-
-      it 'missing to/cc defaults to direct privacy' do
-        status = sender.statuses.first
+    context 'when fetching' do
+      subject { described_class.new(json, sender) }
+
+      before do
+        subject.perform
+      end
+
+      context 'standalone' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.text).to eq 'Lorem ipsum'
+        end
+
+        it 'missing to/cc defaults to direct privacy' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.visibility).to eq 'direct'
+        end
+      end
+
+      context 'public' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            to: 'https://www.w3.org/ns/activitystreams#Public',
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.visibility).to eq 'public'
+        end
+      end
+
+      context 'unlisted' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            cc: 'https://www.w3.org/ns/activitystreams#Public',
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.visibility).to eq 'unlisted'
+        end
+      end
+
+      context 'private' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            to: 'http://example.com/followers',
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.visibility).to eq 'private'
+        end
+      end
+
+      context 'limited' do
+        let(:recipient) { Fabricate(:account) }
+
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            to: ActivityPub::TagManager.instance.uri_for(recipient),
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.visibility).to eq 'limited'
+        end
+
+        it 'creates silent mention' do
+          status = sender.statuses.first
+          expect(status.mentions.first).to be_silent
+        end
+      end
+
+      context 'direct' do
+        let(:recipient) { Fabricate(:account) }
+
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            to: ActivityPub::TagManager.instance.uri_for(recipient),
+            tag: {
+              type: 'Mention',
+              href: ActivityPub::TagManager.instance.uri_for(recipient),
+            },
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.visibility).to eq 'direct'
+        end
+      end
+
+      context 'as a reply' do
+        let(:original_status) { Fabricate(:status) }
+
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            inReplyTo: ActivityPub::TagManager.instance.uri_for(original_status),
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.thread).to eq original_status
+          expect(status.reply?).to be true
+          expect(status.in_reply_to_account).to eq original_status.account
+          expect(status.conversation).to eq original_status.conversation
+        end
+      end
+
+      context 'with mentions' do
+        let(:recipient) { Fabricate(:account) }
+
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            tag: [
+              {
+                type: 'Mention',
+                href: ActivityPub::TagManager.instance.uri_for(recipient),
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.mentions.map(&:account)).to include(recipient)
+        end
+      end
+
+      context 'with mentions missing href' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            tag: [
+              {
+                type: 'Mention',
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+          expect(status).to_not be_nil
+        end
+      end
+
+      context 'with media attachments' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            attachment: [
+              {
+                type: 'Document',
+                mediaType: 'image/png',
+                url: 'http://example.com/attachment.png',
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.media_attachments.map(&:remote_url)).to include('http://example.com/attachment.png')
+        end
+      end
+
+      context 'with media attachments with focal points' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            attachment: [
+              {
+                type: 'Document',
+                mediaType: 'image/png',
+                url: 'http://example.com/attachment.png',
+                focalPoint: [0.5, -0.7],
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.media_attachments.map(&:focus)).to include('0.5,-0.7')
+        end
+      end
+
+      context 'with media attachments missing url' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            attachment: [
+              {
+                type: 'Document',
+                mediaType: 'image/png',
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+          expect(status).to_not be_nil
+        end
+      end
+
+      context 'with hashtags' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            tag: [
+              {
+                type: 'Hashtag',
+                href: 'http://example.com/blah',
+                name: '#test',
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.tags.map(&:name)).to include('test')
+        end
+      end
+
+      context 'with hashtags missing name' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum',
+            tag: [
+              {
+                type: 'Hashtag',
+                href: 'http://example.com/blah',
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+          expect(status).to_not be_nil
+        end
+      end
+
+      context 'with emojis' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum :tinking:',
+            tag: [
+              {
+                type: 'Emoji',
+                icon: {
+                  url: 'http://example.com/emoji.png',
+                },
+                name: 'tinking',
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+
+          expect(status).to_not be_nil
+          expect(status.emojis.map(&:shortcode)).to include('tinking')
+        end
+      end
+
+      context 'with emojis missing name' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum :tinking:',
+            tag: [
+              {
+                type: 'Emoji',
+                icon: {
+                  url: 'http://example.com/emoji.png',
+                },
+              },
+            ],
+          }
+        end
+
+        it 'creates status' do
+          status = sender.statuses.first
+          expect(status).to_not be_nil
+        end
+      end
+
+      context 'with emojis missing icon' do
+        let(:object_json) do
+          {
+            id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
+            type: 'Note',
+            content: 'Lorem ipsum :tinking:',
+            tag: [
+              {
+                type: 'Emoji',
+                name: 'tinking',
+              },
+            ],
+          }
+        end
 
-        expect(status).to_not be_nil
-        expect(status.visibility).to eq 'direct'
+        it 'creates status' do
+          status = sender.statuses.first
+          expect(status).to_not be_nil
+        end
       end
     end
 
-    context 'public' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          to: 'https://www.w3.org/ns/activitystreams#Public',
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
+    context 'when sender is followed by local users' do
+      subject { described_class.new(json, sender, delivery: true) }
 
-        expect(status).to_not be_nil
-        expect(status.visibility).to eq 'public'
+      before do
+        Fabricate(:account).follow!(sender)
+        subject.perform
       end
-    end
 
-    context 'unlisted' do
       let(:object_json) do
         {
           id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
           type: 'Note',
           content: 'Lorem ipsum',
-          cc: 'https://www.w3.org/ns/activitystreams#Public',
         }
       end
 
@@ -83,66 +429,25 @@ RSpec.describe ActivityPub::Activity::Create do
         status = sender.statuses.first
 
         expect(status).to_not be_nil
-        expect(status.visibility).to eq 'unlisted'
-      end
-    end
-
-    context 'private' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          to: 'http://example.com/followers',
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
-
-        expect(status).to_not be_nil
-        expect(status.visibility).to eq 'private'
+        expect(status.text).to eq 'Lorem ipsum'
       end
     end
 
-    context 'limited' do
-      let(:recipient) { Fabricate(:account) }
+    context 'when sender replies to local status' do
+      let!(:local_status) { Fabricate(:status) }
 
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          to: ActivityPub::TagManager.instance.uri_for(recipient),
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
-
-        expect(status).to_not be_nil
-        expect(status.visibility).to eq 'limited'
-      end
+      subject { described_class.new(json, sender, delivery: true) }
 
-      it 'creates silent mention' do
-        status = sender.statuses.first
-        expect(status.mentions.first).to be_silent
+      before do
+        subject.perform
       end
-    end
-
-    context 'direct' do
-      let(:recipient) { Fabricate(:account) }
 
       let(:object_json) do
         {
           id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
           type: 'Note',
           content: 'Lorem ipsum',
-          to: ActivityPub::TagManager.instance.uri_for(recipient),
-          tag: {
-            type: 'Mention',
-            href: ActivityPub::TagManager.instance.uri_for(recipient),
-          },
+          inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status),
         }
       end
 
@@ -150,47 +455,25 @@ RSpec.describe ActivityPub::Activity::Create do
         status = sender.statuses.first
 
         expect(status).to_not be_nil
-        expect(status.visibility).to eq 'direct'
+        expect(status.text).to eq 'Lorem ipsum'
       end
     end
 
-    context 'as a reply' do
-      let(:original_status) { Fabricate(:status) }
+    context 'when sender targets a local user' do
+      let!(:local_account) { Fabricate(:account) }
 
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          inReplyTo: ActivityPub::TagManager.instance.uri_for(original_status),
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
+      subject { described_class.new(json, sender, delivery: true) }
 
-        expect(status).to_not be_nil
-        expect(status.thread).to eq original_status
-        expect(status.reply?).to be true
-        expect(status.in_reply_to_account).to eq original_status.account
-        expect(status.conversation).to eq original_status.conversation
+      before do
+        subject.perform
       end
-    end
-
-    context 'with mentions' do
-      let(:recipient) { Fabricate(:account) }
 
       let(:object_json) do
         {
           id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
           type: 'Note',
           content: 'Lorem ipsum',
-          tag: [
-            {
-              type: 'Mention',
-              href: ActivityPub::TagManager.instance.uri_for(recipient),
-            },
-          ],
+          to: ActivityPub::TagManager.instance.uri_for(local_account),
         }
       end
 
@@ -198,68 +481,25 @@ RSpec.describe ActivityPub::Activity::Create do
         status = sender.statuses.first
 
         expect(status).to_not be_nil
-        expect(status.mentions.map(&:account)).to include(recipient)
-      end
-    end
-
-    context 'with mentions missing href' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          tag: [
-            {
-              type: 'Mention',
-            },
-          ],
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
-        expect(status).to_not be_nil
+        expect(status.text).to eq 'Lorem ipsum'
       end
     end
 
-    context 'with media attachments' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          attachment: [
-            {
-              type: 'Document',
-              mediaType: 'image/png',
-              url: 'http://example.com/attachment.png',
-            },
-          ],
-        }
-      end
+    context 'when sender cc\'s a local user' do
+      let!(:local_account) { Fabricate(:account) }
 
-      it 'creates status' do
-        status = sender.statuses.first
+      subject { described_class.new(json, sender, delivery: true) }
 
-        expect(status).to_not be_nil
-        expect(status.media_attachments.map(&:remote_url)).to include('http://example.com/attachment.png')
+      before do
+        subject.perform
       end
-    end
 
-    context 'with media attachments with focal points' do
       let(:object_json) do
         {
           id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
           type: 'Note',
           content: 'Lorem ipsum',
-          attachment: [
-            {
-              type: 'Document',
-              mediaType: 'image/png',
-              url: 'http://example.com/attachment.png',
-              focalPoint: [0.5, -0.7],
-            },
-          ],
+          cc: ActivityPub::TagManager.instance.uri_for(local_account),
         }
       end
 
@@ -267,143 +507,27 @@ RSpec.describe ActivityPub::Activity::Create do
         status = sender.statuses.first
 
         expect(status).to_not be_nil
-        expect(status.media_attachments.map(&:focus)).to include('0.5,-0.7')
+        expect(status.text).to eq 'Lorem ipsum'
       end
     end
 
-    context 'with media attachments missing url' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          attachment: [
-            {
-              type: 'Document',
-              mediaType: 'image/png',
-            },
-          ],
-        }
-      end
+    context 'when the sender has no relevance to local activity' do
+      subject { described_class.new(json, sender, delivery: true) }
 
-      it 'creates status' do
-        status = sender.statuses.first
-        expect(status).to_not be_nil
+      before do
+        subject.perform
       end
-    end
 
-    context 'with hashtags' do
       let(:object_json) do
         {
           id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
           type: 'Note',
           content: 'Lorem ipsum',
-          tag: [
-            {
-              type: 'Hashtag',
-              href: 'http://example.com/blah',
-              name: '#test',
-            },
-          ],
         }
       end
 
-      it 'creates status' do
-        status = sender.statuses.first
-
-        expect(status).to_not be_nil
-        expect(status.tags.map(&:name)).to include('test')
-      end
-    end
-
-    context 'with hashtags missing name' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum',
-          tag: [
-            {
-              type: 'Hashtag',
-              href: 'http://example.com/blah',
-            },
-          ],
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
-        expect(status).to_not be_nil
-      end
-    end
-
-    context 'with emojis' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum :tinking:',
-          tag: [
-            {
-              type: 'Emoji',
-              icon: {
-                url: 'http://example.com/emoji.png',
-              },
-              name: 'tinking',
-            },
-          ],
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
-
-        expect(status).to_not be_nil
-        expect(status.emojis.map(&:shortcode)).to include('tinking')
-      end
-    end
-
-    context 'with emojis missing name' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum :tinking:',
-          tag: [
-            {
-              type: 'Emoji',
-              icon: {
-                url: 'http://example.com/emoji.png',
-              },
-            },
-          ],
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
-        expect(status).to_not be_nil
-      end
-    end
-
-    context 'with emojis missing icon' do
-      let(:object_json) do
-        {
-          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
-          type: 'Note',
-          content: 'Lorem ipsum :tinking:',
-          tag: [
-            {
-              type: 'Emoji',
-              name: 'tinking',
-            },
-          ],
-        }
-      end
-
-      it 'creates status' do
-        status = sender.statuses.first
-        expect(status).to_not be_nil
+      it 'does not create anything' do
+        expect(sender.statuses.count).to eq 0
       end
     end
   end