Add logging for rejected ActivityPub payloads and add tests (#10062)
This commit is contained in:
		@@ -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,11 +21,402 @@ RSpec.describe ActivityPub::Activity::Create do
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe '#perform' do
 | 
			
		||||
    before do
 | 
			
		||||
      subject.perform
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
        it 'creates status' do
 | 
			
		||||
          status = sender.statuses.first
 | 
			
		||||
          expect(status).to_not be_nil
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context 'standalone' do
 | 
			
		||||
    context 'when sender is followed by local users' do
 | 
			
		||||
      subject { described_class.new(json, sender, delivery: true) }
 | 
			
		||||
 | 
			
		||||
      before do
 | 
			
		||||
        Fabricate(:account).follow!(sender)
 | 
			
		||||
        subject.perform
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      let(:object_json) do
 | 
			
		||||
        {
 | 
			
		||||
          id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
 | 
			
		||||
@@ -42,78 +431,23 @@ RSpec.describe ActivityPub::Activity::Create do
 | 
			
		||||
        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',
 | 
			
		||||
        }
 | 
			
		||||
    context 'when sender replies to local status' do
 | 
			
		||||
      let!(:local_status) { Fabricate(:status) }
 | 
			
		||||
 | 
			
		||||
      subject { described_class.new(json, sender, delivery: true) }
 | 
			
		||||
 | 
			
		||||
      before do
 | 
			
		||||
        subject.perform
 | 
			
		||||
      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),
 | 
			
		||||
          inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status),
 | 
			
		||||
        }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
@@ -121,28 +455,25 @@ RSpec.describe ActivityPub::Activity::Create 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
 | 
			
		||||
        expect(status.text).to eq 'Lorem ipsum'
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context 'direct' do
 | 
			
		||||
      let(:recipient) { Fabricate(:account) }
 | 
			
		||||
    context 'when sender targets a local user' do
 | 
			
		||||
      let!(:local_account) { Fabricate(:account) }
 | 
			
		||||
 | 
			
		||||
      subject { described_class.new(json, sender, delivery: true) }
 | 
			
		||||
 | 
			
		||||
      before do
 | 
			
		||||
        subject.perform
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      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),
 | 
			
		||||
          },
 | 
			
		||||
          to: ActivityPub::TagManager.instance.uri_for(local_account),
 | 
			
		||||
        }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
@@ -150,19 +481,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 cc\'s a local user' do
 | 
			
		||||
      let!(:local_account) { Fabricate(:account) }
 | 
			
		||||
 | 
			
		||||
      subject { described_class.new(json, sender, delivery: true) }
 | 
			
		||||
 | 
			
		||||
      before do
 | 
			
		||||
        subject.perform
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      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),
 | 
			
		||||
          cc: ActivityPub::TagManager.instance.uri_for(local_account),
 | 
			
		||||
        }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
@@ -170,240 +507,27 @@ RSpec.describe ActivityPub::Activity::Create 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
 | 
			
		||||
        expect(status.text).to eq 'Lorem ipsum'
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    context 'with mentions' do
 | 
			
		||||
      let(:recipient) { Fabricate(:account) }
 | 
			
		||||
    context 'when the sender has no relevance to local activity' do
 | 
			
		||||
      subject { described_class.new(json, sender, delivery: true) }
 | 
			
		||||
 | 
			
		||||
      before do
 | 
			
		||||
        subject.perform
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      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
 | 
			
		||||
 | 
			
		||||
      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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user