Add collections to Flag activities (#38817)

This commit is contained in:
David Roetzel 2026-04-28 13:09:43 +02:00 committed by GitHub
parent 2dd630bc58
commit d5f8b08d69
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 80 additions and 2 deletions

View File

@ -75,6 +75,10 @@ class ActivityPub::Activity
ActivityPub::TagManager.instance.uri_to_resource(uri, Account)
end
def collection_from_uri(uri)
ActivityPub::TagManager.instance.uri_to_resource(uri, Collection)
end
def object_uri
@object_uri ||= uri_from_bearcap(value_or_id(@object))
end

View File

@ -8,9 +8,11 @@ class ActivityPub::Activity::Flag < ActivityPub::Activity
target_accounts = object_uris.filter_map { |uri| account_from_uri(uri) }
target_statuses_by_account = object_uris.filter_map { |uri| status_from_uri(uri) }.group_by(&:account_id)
target_collections_by_account = object_uris.filter_map { |uri| collection_from_uri(uri) }.group_by(&:account_id)
target_accounts.each do |target_account|
target_statuses = target_statuses_by_account[target_account.id]
target_collections = target_collections_by_account.fetch(target_account.id, [])
replied_to_accounts = target_statuses.nil? ? [] : Account.local.where(id: target_statuses.filter_map(&:in_reply_to_account_id))
next if target_account.suspended? || (!target_account.local? && replied_to_accounts.none?)
@ -19,6 +21,7 @@ class ActivityPub::Activity::Flag < ActivityPub::Activity
@account,
target_account,
status_ids: target_statuses.nil? ? [] : target_statuses.map(&:id),
collection_ids: target_collections.map(&:id),
comment: report_comment,
uri: report_uri
)

View File

@ -17,10 +17,24 @@ class ActivityPub::FlagSerializer < ActivityPub::Serializer
end
def virtual_object
[ActivityPub::TagManager.instance.uri_for(object.target_account)] + object.statuses.map { |s| ActivityPub::TagManager.instance.uri_for(s) }
target_account_uris + status_uris + collection_uris
end
def content
object.comment
end
private
def target_account_uris
[ActivityPub::TagManager.instance.uri_for(object.target_account)]
end
def status_uris
object.statuses.map { |s| ActivityPub::TagManager.instance.uri_for(s) }
end
def collection_uris
object.collections.map { |c| ActivityPub::TagManager.instance.uri_for(c) }
end
end

View File

@ -143,7 +143,34 @@ RSpec.describe ActivityPub::Activity::Flag do
end
end
context 'when an account is passed but no status' do
context 'when the activity includes and account and a collection' do
let(:collection) { Fabricate(:collection, account: flagged) }
let(:json) do
{
'@context' => 'https://www.w3.org/ns/activitystreams',
'id' => flag_id,
'type' => 'Flag',
'content' => 'Boo!!',
'actor' => ActivityPub::TagManager.instance.uri_for(sender),
'object' => [
ActivityPub::TagManager.instance.uri_for(flagged),
ActivityPub::TagManager.instance.uri_for(collection),
],
}
end
it 'creates a report with an attached collection' do
subject.perform
report = Report.find_by(account: sender, target_account: flagged)
expect(report).to_not be_nil
expect(report.comment).to eq 'Boo!!'
expect(report.collections).to contain_exactly(collection)
end
end
context 'when an account is passed but no status or collection' do
let(:mentioned) { Fabricate(:account) }
let(:json) do

View File

@ -22,4 +22,34 @@ RSpec.describe ActivityPub::FlagSerializer do
expect(subject).to_not have_key('cc')
expect(subject).to_not have_key('target')
end
context 'with status' do
let(:target_account) { Fabricate(:account) }
let(:status) { Fabricate(:status, account: target_account) }
let(:report) { Fabricate(:report, target_account:, status_ids: [status.id]) }
it 'includes the status URI in `object`' do
expect(subject).to include({
'object' => [
tag_manager.uri_for(target_account),
tag_manager.uri_for(status),
],
})
end
end
context 'with collection', feature: :collections do
let(:target_account) { Fabricate(:account) }
let(:collection) { Fabricate(:collection, account: target_account) }
let(:report) { Fabricate(:report, target_account:, collections: [collection]) }
it 'includes the collection URI in `object`' do
expect(subject).to include({
'object' => [
tag_manager.uri_for(target_account),
tag_manager.uri_for(collection),
],
})
end
end
end