diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index 3d52c9a56..43c7bb1fe 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true
class ActivityPub::Activity::Create < ActivityPub::Activity
- include FormattingHelper
-
def perform
@account.schedule_refresh_if_stale!
@@ -99,9 +97,9 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
uri: @status_parser.uri,
url: @status_parser.url || @status_parser.uri,
account: @account,
- text: converted_object_type? ? converted_text : (@status_parser.text || ''),
+ text: @status_parser.processed_text,
language: @status_parser.language,
- spoiler_text: converted_object_type? ? '' : (@status_parser.spoiler_text || ''),
+ spoiler_text: @status_parser.processed_spoiler_text,
created_at: @status_parser.created_at,
edited_at: @status_parser.edited_at && @status_parser.edited_at != @status_parser.created_at ? @status_parser.edited_at : nil,
override_timestamps: @options[:override_timestamps],
@@ -405,18 +403,6 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
value_or_id(@object['inReplyTo'])
end
- def converted_text
- [formatted_title, @status_parser.spoiler_text.presence, formatted_url].compact.join("\n\n")
- end
-
- def formatted_title
- "
#{@status_parser.title}
" if @status_parser.title.present?
- end
-
- def formatted_url
- linkify(@status_parser.url || @status_parser.uri)
- end
-
def unsupported_media_type?(mime_type)
mime_type.present? && !MediaAttachment.supported_mime_types.include?(mime_type)
end
diff --git a/app/lib/activitypub/activity/update.rb b/app/lib/activitypub/activity/update.rb
index 15025ca5e..f158626db 100644
--- a/app/lib/activitypub/activity/update.rb
+++ b/app/lib/activitypub/activity/update.rb
@@ -8,10 +8,8 @@ class ActivityPub::Activity::Update < ActivityPub::Activity
if equals_or_includes_any?(@object['type'], %w(Application Group Organization Person Service))
update_account
- elsif equals_or_includes_any?(@object['type'], %w(Note Question))
+ elsif supported_object_type? || converted_object_type?
update_status
- elsif converted_object_type?
- Status.find_by(uri: object_uri, account_id: @account.id)
end
end
diff --git a/app/lib/activitypub/parser/status_parser.rb b/app/lib/activitypub/parser/status_parser.rb
index 57e6cb926..83f03756e 100644
--- a/app/lib/activitypub/parser/status_parser.rb
+++ b/app/lib/activitypub/parser/status_parser.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
class ActivityPub::Parser::StatusParser
+ include FormattingHelper
include JsonLdHelper
NORMALIZED_LOCALE_NAMES = LanguagesHelper::SUPPORTED_LOCALES.keys.index_by(&:downcase).freeze
@@ -44,6 +45,16 @@ class ActivityPub::Parser::StatusParser
end
end
+ def processed_text
+ return text || '' unless converted_object_type?
+
+ [
+ title.presence && "#{title}
",
+ spoiler_text.presence,
+ linkify(url || uri),
+ ].compact.join("\n\n")
+ end
+
def spoiler_text
if @object['summary'].present?
@object['summary']
@@ -52,6 +63,12 @@ class ActivityPub::Parser::StatusParser
end
end
+ def processed_spoiler_text
+ return '' if converted_object_type?
+
+ spoiler_text || ''
+ end
+
def title
if @object['name'].present?
@object['name']
@@ -145,6 +162,10 @@ class ActivityPub::Parser::StatusParser
as_array(@object['quoteAuthorization']).first
end
+ def converted_object_type?
+ equals_or_includes_any?(@object['type'], ActivityPub::Activity::CONVERTED_TYPES)
+ end
+
private
def quote_subpolicy(subpolicy)
diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb
index 7e2673425..1cdf0b483 100644
--- a/app/services/activitypub/process_status_update_service.rb
+++ b/app/services/activitypub/process_status_update_service.rb
@@ -20,7 +20,6 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
@request_id = request_id
@quote = nil
- # Only native types can be updated at the moment
return @status if !expected_type? || already_updated_more_recently?
if @status_parser.edited_at.present? && (@status.edited_at.nil? || @status_parser.edited_at > @status.edited_at)
@@ -170,8 +169,8 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
end
def update_immediate_attributes!
- @status.text = @status_parser.text || ''
- @status.spoiler_text = @status_parser.spoiler_text || ''
+ @status.text = @status_parser.processed_text
+ @status.spoiler_text = @status_parser.processed_spoiler_text
@status.sensitive = @account.sensitized? || @status_parser.sensitive || false
@status.language = @status_parser.language
@@ -351,7 +350,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
end
def expected_type?
- equals_or_includes_any?(@json['type'], %w(Note Question))
+ equals_or_includes_any?(@json['type'], ActivityPub::Activity::SUPPORTED_TYPES) || equals_or_includes_any?(@json['type'], ActivityPub::Activity::CONVERTED_TYPES)
end
def record_previous_edit!
diff --git a/spec/lib/activitypub/activity/update_spec.rb b/spec/lib/activitypub/activity/update_spec.rb
index b829f3a5a..d905f68d8 100644
--- a/spec/lib/activitypub/activity/update_spec.rb
+++ b/spec/lib/activitypub/activity/update_spec.rb
@@ -149,18 +149,17 @@ RSpec.describe ActivityPub::Activity::Update do
shared_examples 'updates counts' do
it 'updates the reblog count' do
- expect(status.untrusted_reblogs_count).to eq reblogs
+ expect { subject.perform }.to change { status.reload.untrusted_reblogs_count }.to(reblogs)
end
it 'updates the favourites count' do
- expect(status.untrusted_favourites_count).to eq favourites
+ expect { subject.perform }.to change { status.reload.untrusted_favourites_count }.to(favourites)
end
end
context 'with an implicit update' do
before do
status.update!(uri: ActivityPub::TagManager.instance.uri_for(status))
- subject.perform
end
it_behaves_like 'updates counts'
@@ -173,11 +172,89 @@ RSpec.describe ActivityPub::Activity::Update do
before do
status.update!(uri: ActivityPub::TagManager.instance.uri_for(status))
- subject.perform
end
it_behaves_like 'updates counts'
end
end
+
+ context 'with an Article object' do
+ let(:updated) { nil }
+ let(:favourites) { 50 }
+ let(:reblogs) { 100 }
+
+ let!(:status) do
+ Fabricate(
+ :status,
+ uri: 'https://example.com/statuses/article',
+ account: sender,
+ text: "Future of the Fediverse
\n\nGuest article by John Mastodon
The fediverse is great reading this you will find out why!
"
+ )
+ end
+
+ let(:json) do
+ {
+ '@context': 'https://www.w3.org/ns/activitystreams',
+ id: 'foo',
+ type: 'Update',
+ actor: sender.uri,
+ object: {
+ type: 'Article',
+ id: status.uri,
+ name: 'Future of the Fediverse',
+ summary: 'Guest article by Jane Mastodon
The fediverse is great reading this you will find out why!
',
+ content: 'Foo',
+ updated: updated,
+ likes: {
+ id: "#{status.uri}/likes",
+ type: 'Collection',
+ totalItems: favourites,
+ },
+ shares: {
+ id: "#{status.uri}/shares",
+ type: 'Collection',
+ totalItems: reblogs,
+ },
+ },
+ }.with_indifferent_access
+ end
+
+ shared_examples 'updates counts' do
+ it 'updates the reblog count' do
+ expect { subject.perform }.to change { status.reload.untrusted_reblogs_count }.to(reblogs)
+ end
+
+ it 'updates the favourites count' do
+ expect { subject.perform }.to change { status.reload.untrusted_favourites_count }.to(favourites)
+ end
+ end
+
+ context 'with an implicit update' do
+ before do
+ status.update!(uri: ActivityPub::TagManager.instance.uri_for(status))
+ end
+
+ it_behaves_like 'updates counts'
+ end
+
+ context 'with an explicit update' do
+ let(:favourites) { 150 }
+ let(:reblogs) { 200 }
+ let(:updated) { Time.now.utc.iso8601 }
+
+ before do
+ status.update!(uri: ActivityPub::TagManager.instance.uri_for(status))
+ end
+
+ it_behaves_like 'updates counts'
+
+ it 'changes the contents as expected' do
+ expect { subject.perform }
+ .to(change { status.reload.text })
+
+ expect(status.text).to start_with("Future of the Fediverse
\n\nGuest article by Jane Mastodon
The fediverse is great reading this you will find out why!
")
+ end
+ end
+ end
end
end