mirror of
https://github.com/mastodon/mastodon.git
synced 2026-03-21 18:05:23 -05:00
Fix filtering of mentions from filtered-on-their-origin-server accounts (#37583)
This commit is contained in:
parent
cd7ffb5a10
commit
73fc40993b
|
|
@ -79,9 +79,11 @@ class FanOutOnWriteService < BaseService
|
|||
end
|
||||
|
||||
def notify_mentioned_accounts!
|
||||
@status.active_mentions.where.not(id: @options[:silenced_account_ids] || []).joins(:account).merge(Account.local).select(:id, :account_id).reorder(nil).find_in_batches do |mentions|
|
||||
@status.active_mentions.joins(:account).merge(Account.local).select(:id, :account_id).reorder(nil).find_in_batches do |mentions|
|
||||
LocalNotificationWorker.push_bulk(mentions) do |mention|
|
||||
[mention.account_id, mention.id, 'Mention', 'mention']
|
||||
options = { 'silenced' => true } if @options[:silenced_account_ids]&.include?(mention.account_id)
|
||||
|
||||
[mention.account_id, mention.id, 'Mention', 'mention', options].compact
|
||||
end
|
||||
|
||||
next unless update?
|
||||
|
|
|
|||
|
|
@ -30,12 +30,13 @@ class NotifyService < BaseService
|
|||
annual_report
|
||||
).freeze
|
||||
|
||||
def initialize(notification)
|
||||
def initialize(notification, **options)
|
||||
@recipient = notification.account
|
||||
@sender = notification.from_account
|
||||
@notification = notification
|
||||
@policy = NotificationPolicy.find_or_initialize_by(account: @recipient)
|
||||
@from_staff = @sender.local? && @sender.user.present? && @sender.user_role&.bypass_block?(@recipient.user_role)
|
||||
@options = options
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -164,7 +165,7 @@ class NotifyService < BaseService
|
|||
end
|
||||
|
||||
def blocked_by_limited_accounts_policy?
|
||||
@policy.drop_limited_accounts? && @sender.silenced? && not_following?
|
||||
@policy.drop_limited_accounts? && (@options[:silenced] || @sender.silenced?) && not_following?
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -200,13 +201,14 @@ class NotifyService < BaseService
|
|||
end
|
||||
|
||||
def filtered_by_limited_accounts_policy?
|
||||
@policy.filter_limited_accounts? && @sender.silenced? && not_following?
|
||||
@policy.filter_limited_accounts? && (@options[:silenced] || @sender.silenced?) && not_following?
|
||||
end
|
||||
end
|
||||
|
||||
def call(recipient, type, activity)
|
||||
def call(recipient, type, activity, **options)
|
||||
return if recipient.user.nil?
|
||||
|
||||
@options = options
|
||||
@recipient = recipient
|
||||
@activity = activity
|
||||
@notification = Notification.new(account: @recipient, type: type, activity: @activity)
|
||||
|
|
@ -236,11 +238,11 @@ class NotifyService < BaseService
|
|||
private
|
||||
|
||||
def drop?
|
||||
DropCondition.new(@notification).drop?
|
||||
DropCondition.new(@notification, silenced: @options[:silenced]).drop?
|
||||
end
|
||||
|
||||
def filter?
|
||||
FilterCondition.new(@notification).filter?
|
||||
FilterCondition.new(@notification, silenced: @options[:silenced]).filter?
|
||||
end
|
||||
|
||||
def update_notification_request!
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
class LocalNotificationWorker
|
||||
include Sidekiq::Worker
|
||||
|
||||
def perform(receiver_account_id, activity_id = nil, activity_class_name = nil, type = nil)
|
||||
def perform(receiver_account_id, activity_id = nil, activity_class_name = nil, type = nil, options = {})
|
||||
if activity_id.nil? && activity_class_name.nil?
|
||||
activity = Mention.find(receiver_account_id)
|
||||
receiver = activity.account
|
||||
|
|
@ -23,7 +23,7 @@ class LocalNotificationWorker
|
|||
return
|
||||
end
|
||||
|
||||
NotifyService.new.call(receiver, type || activity_class_name.underscore, activity)
|
||||
NotifyService.new.call(receiver, type || activity_class_name.underscore, activity, **options.symbolize_keys)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
true
|
||||
end
|
||||
|
|
|
|||
|
|
@ -45,7 +45,9 @@ RSpec.describe FanOutOnWriteService do
|
|||
let(:visibility) { 'public' }
|
||||
|
||||
it 'adds status to home feed of author and followers and broadcasts', :inline_jobs do
|
||||
subject.call(status)
|
||||
expect { subject.call(status) }
|
||||
.to change(bob.notifications, :count).by(1)
|
||||
.and change(eve.notifications, :count).by(1)
|
||||
|
||||
expect(status.id)
|
||||
.to be_in(home_feed_of(alice))
|
||||
|
|
@ -58,6 +60,14 @@ RSpec.describe FanOutOnWriteService do
|
|||
expect(redis).to have_received(:publish).with('timeline:public:local', anything)
|
||||
expect(redis).to have_received(:publish).with('timeline:public:media', anything)
|
||||
end
|
||||
|
||||
context 'with silenced_account_ids' do
|
||||
it 'calls LocalNotificationWorker with the expected arguments' do
|
||||
expect { subject.call(status, silenced_account_ids: [eve.id]) }
|
||||
.to enqueue_sidekiq_job(LocalNotificationWorker).with(bob.id, anything, 'Mention', 'mention')
|
||||
.and enqueue_sidekiq_job(LocalNotificationWorker).with(eve.id, anything, 'Mention', 'mention', { 'silenced' => true })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when status is limited' do
|
||||
|
|
|
|||
|
|
@ -224,13 +224,25 @@ RSpec.describe NotifyService do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when sender is considered silenced through `silenced` option and recipient has a policy to ignore silenced accounts' do
|
||||
subject { described_class.new(notification, silenced: true) }
|
||||
|
||||
before do
|
||||
notification.account.create_notification_policy!(for_limited_accounts: :drop)
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
expect(subject.drop?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when sender is new and recipient has a default policy' do
|
||||
it 'returns false' do
|
||||
expect(subject.drop?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context 'when sender is new and recipient has a policy to ignore silenced accounts' do
|
||||
context 'when sender is new and recipient has a policy to ignore new accounts' do
|
||||
before do
|
||||
notification.account.create_notification_policy!(for_new_accounts: :drop)
|
||||
end
|
||||
|
|
@ -240,7 +252,7 @@ RSpec.describe NotifyService do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when sender is new and followed and recipient has a policy to ignore silenced accounts' do
|
||||
context 'when sender is new and followed and recipient has a policy to ignore new accounts' do
|
||||
before do
|
||||
notification.account.create_notification_policy!(for_new_accounts: :drop)
|
||||
notification.account.follow!(notification.from_account)
|
||||
|
|
@ -300,6 +312,34 @@ RSpec.describe NotifyService do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when sender is considered silenced through the `silenced` option' do
|
||||
subject { described_class.new(notification, silenced: true) }
|
||||
|
||||
it 'returns true' do
|
||||
expect(subject.filter?).to be true
|
||||
end
|
||||
|
||||
context 'when recipient follows sender' do
|
||||
before do
|
||||
notification.account.follow!(notification.from_account)
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
expect(subject.filter?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
context 'when recipient is allowing limited accounts' do
|
||||
before do
|
||||
notification.account.create_notification_policy!(for_limited_accounts: :accept)
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
expect(subject.filter?).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when recipient is filtering not-followed senders' do
|
||||
before do
|
||||
Fabricate(:notification_policy, account: notification.account, filter_not_following: true)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user