Skip to content
Extraits de code Groupes Projets
Non vérifiée Valider 43961035 rédigé par ThibG's avatar ThibG Validation de GitHub
Parcourir les fichiers

Fix some notifications not being deleted on poll/status deletion (#15402)


* Fix deleting polls not deleting notifications

* Fix fav notification deletion when deleting a toot

* Refactor DeleteAccountService spec

* Add DeleteAccountService tests for other associations and notifications

* Add favourite handling spec in status removal

Co-authored-by: default avatarClaire <claire.github-309c@sitedethib.com>
parent 6f51fd74
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -56,7 +56,7 @@ class Status < ApplicationRecord ...@@ -56,7 +56,7 @@ class Status < ApplicationRecord
belongs_to :thread, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :replies, optional: true belongs_to :thread, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :replies, optional: true
belongs_to :reblog, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblogs, optional: true belongs_to :reblog, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblogs, optional: true
has_many :favourites, inverse_of: :status, dependent: :delete_all has_many :favourites, inverse_of: :status, dependent: :destroy
has_many :bookmarks, inverse_of: :status, dependent: :destroy has_many :bookmarks, inverse_of: :status, dependent: :destroy
has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblog, dependent: :destroy has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblog, dependent: :destroy
has_many :replies, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :thread has_many :replies, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :thread
......
...@@ -123,7 +123,9 @@ class DeleteAccountService < BaseService ...@@ -123,7 +123,9 @@ class DeleteAccountService < BaseService
next if @options[:reserve_username] && reported_status_ids.include?(poll.status_id) next if @options[:reserve_username] && reported_status_ids.include?(poll.status_id)
# We can safely delete the poll rather than destroy it, as any non-reported # We can safely delete the poll rather than destroy it, as any non-reported
# status should have been deleted already # status should have been deleted already, as long as we take care of
# notifications.
Notification.where(poll: poll).delete_all
poll.delete poll.delete
end end
......
require 'rails_helper' require 'rails_helper'
RSpec.describe DeleteAccountService, type: :service do RSpec.describe DeleteAccountService, type: :service do
describe '#call on local account' do shared_examples 'common behavior' do
before do let!(:status) { Fabricate(:status, account: account) }
stub_request(:post, "https://alice.com/inbox").to_return(status: 201) let!(:mention) { Fabricate(:mention, account: local_follower) }
stub_request(:post, "https://bob.com/inbox").to_return(status: 201) let!(:status_with_mention) { Fabricate(:status, account: account, mentions: [mention]) }
end let!(:media_attachment) { Fabricate(:media_attachment, account: account) }
let!(:notification) { Fabricate(:notification, account: account) }
let!(:favourite) { Fabricate(:favourite, account: account, status: Fabricate(:status, account: local_follower)) }
let!(:poll) { Fabricate(:poll, account: account) }
let!(:poll_vote) { Fabricate(:poll_vote, account: local_follower, poll: poll) }
let!(:active_relationship) { Fabricate(:follow, account: account, target_account: local_follower) }
let!(:passive_relationship) { Fabricate(:follow, account: local_follower, target_account: account) }
let!(:endorsement) { Fabricate(:account_pin, account: local_follower, target_account: account) }
let!(:mention_notification) { Fabricate(:notification, account: local_follower, activity: mention, type: :mention) }
let!(:status_notification) { Fabricate(:notification, account: local_follower, activity: status, type: :status) }
let!(:poll_notification) { Fabricate(:notification, account: local_follower, activity: poll, type: :poll) }
let!(:favourite_notification) { Fabricate(:notification, account: local_follower, activity: favourite, type: :favourite) }
let!(:follow_notification) { Fabricate(:notification, account: local_follower, activity: active_relationship, type: :follow) }
subject do subject do
-> { described_class.new.call(account) } -> { described_class.new.call(account) }
end end
let!(:account) { Fabricate(:account) } it 'deletes associated owned records' do
let!(:status) { Fabricate(:status, account: account) }
let!(:media_attachment) { Fabricate(:media_attachment, account: account) }
let!(:notification) { Fabricate(:notification, account: account) }
let!(:favourite) { Fabricate(:favourite, account: account) }
let!(:active_relationship) { Fabricate(:follow, account: account) }
let!(:passive_relationship) { Fabricate(:follow, target_account: account) }
let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox', protocol: :activitypub) }
let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', protocol: :activitypub) }
let!(:endorsment) { Fabricate(:account_pin, account: passive_relationship.account, target_account: account) }
it 'deletes associated records' do
is_expected.to change { is_expected.to change {
[ [
account.statuses, account.statuses,
...@@ -31,54 +34,63 @@ RSpec.describe DeleteAccountService, type: :service do ...@@ -31,54 +34,63 @@ RSpec.describe DeleteAccountService, type: :service do
account.favourites, account.favourites,
account.active_relationships, account.active_relationships,
account.passive_relationships, account.passive_relationships,
account.polls,
].map(&:count)
}.from([2, 1, 1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0, 0, 0])
end
it 'deletes associated target records' do
is_expected.to change {
[
AccountPin.where(target_account: account), AccountPin.where(target_account: account),
].map(&:count) ].map(&:count)
}.from([1, 1, 1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0, 0, 0]) }.from([1]).to([0])
end end
it 'sends a delete actor activity to all known inboxes' do it 'deletes associated target notifications' do
subject.call is_expected.to change {
expect(a_request(:post, "https://alice.com/inbox")).to have_been_made.once [
expect(a_request(:post, "https://bob.com/inbox")).to have_been_made.once 'poll', 'favourite', 'status', 'mention', 'follow'
].map { |type| Notification.where(type: type).count }
}.from([1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0])
end end
end end
describe '#call on remote account' do describe '#call on local account' do
before do before do
stub_request(:post, "https://alice.com/inbox").to_return(status: 201) stub_request(:post, "https://alice.com/inbox").to_return(status: 201)
stub_request(:post, "https://bob.com/inbox").to_return(status: 201) stub_request(:post, "https://bob.com/inbox").to_return(status: 201)
end end
subject do
-> { described_class.new.call(remote_bob) }
end
let!(:account) { Fabricate(:account) }
let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox', protocol: :activitypub) } let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox', protocol: :activitypub) }
let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', protocol: :activitypub) } let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', protocol: :activitypub) }
let!(:status) { Fabricate(:status, account: remote_bob) }
let!(:media_attachment) { Fabricate(:media_attachment, account: remote_bob) }
let!(:notification) { Fabricate(:notification, account: remote_bob) }
let!(:favourite) { Fabricate(:favourite, account: remote_bob) }
let!(:active_relationship) { Fabricate(:follow, account: remote_bob, target_account: account) }
let!(:passive_relationship) { Fabricate(:follow, target_account: remote_bob) }
it 'deletes associated records' do include_examples 'common behavior' do
is_expected.to change { let!(:account) { Fabricate(:account) }
[ let!(:local_follower) { Fabricate(:account) }
remote_bob.statuses,
remote_bob.media_attachments, it 'sends a delete actor activity to all known inboxes' do
remote_bob.notifications, subject.call
remote_bob.favourites, expect(a_request(:post, "https://alice.com/inbox")).to have_been_made.once
remote_bob.active_relationships, expect(a_request(:post, "https://bob.com/inbox")).to have_been_made.once
remote_bob.passive_relationships, end
].map(&:count) end
}.from([1, 1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0, 0]) end
describe '#call on remote account' do
before do
stub_request(:post, "https://alice.com/inbox").to_return(status: 201)
stub_request(:post, "https://bob.com/inbox").to_return(status: 201)
end end
it 'sends a reject follow to follwer inboxes' do include_examples 'common behavior' do
subject.call let!(:account) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', protocol: :activitypub) }
expect(a_request(:post, remote_bob.inbox_url)).to have_been_made.once let!(:local_follower) { Fabricate(:account) }
it 'sends a reject follow to follwer inboxes' do
subject.call
expect(a_request(:post, account.inbox_url)).to have_been_made.once
end
end end
end end
end end
...@@ -3,7 +3,7 @@ require 'rails_helper' ...@@ -3,7 +3,7 @@ require 'rails_helper'
RSpec.describe RemoveStatusService, type: :service do RSpec.describe RemoveStatusService, type: :service do
subject { RemoveStatusService.new } subject { RemoveStatusService.new }
let!(:alice) { Fabricate(:account) } let!(:alice) { Fabricate(:account, user: Fabricate(:user)) }
let!(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com', salmon_url: 'http://example.com/salmon') } let!(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com', salmon_url: 'http://example.com/salmon') }
let!(:jeff) { Fabricate(:account) } let!(:jeff) { Fabricate(:account) }
let!(:hank) { Fabricate(:account, username: 'hank', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } let!(:hank) { Fabricate(:account, username: 'hank', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') }
...@@ -17,23 +17,33 @@ RSpec.describe RemoveStatusService, type: :service do ...@@ -17,23 +17,33 @@ RSpec.describe RemoveStatusService, type: :service do
hank.follow!(alice) hank.follow!(alice)
@status = PostStatusService.new.call(alice, text: 'Hello @bob@example.com') @status = PostStatusService.new.call(alice, text: 'Hello @bob@example.com')
FavouriteService.new.call(jeff, @status)
Fabricate(:status, account: bill, reblog: @status, uri: 'hoge') Fabricate(:status, account: bill, reblog: @status, uri: 'hoge')
subject.call(@status)
end end
it 'removes status from author\'s home feed' do it 'removes status from author\'s home feed' do
subject.call(@status)
expect(HomeFeed.new(alice).get(10)).to_not include(@status.id) expect(HomeFeed.new(alice).get(10)).to_not include(@status.id)
end end
it 'removes status from local follower\'s home feed' do it 'removes status from local follower\'s home feed' do
subject.call(@status)
expect(HomeFeed.new(jeff).get(10)).to_not include(@status.id) expect(HomeFeed.new(jeff).get(10)).to_not include(@status.id)
end end
it 'sends delete activity to followers' do it 'sends delete activity to followers' do
subject.call(@status)
expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.twice expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.twice
end end
it 'sends delete activity to rebloggers' do it 'sends delete activity to rebloggers' do
subject.call(@status)
expect(a_request(:post, 'http://example2.com/inbox')).to have_been_made expect(a_request(:post, 'http://example2.com/inbox')).to have_been_made
end end
it 'remove status from notifications' do
expect { subject.call(@status) }.to change {
Notification.where(activity_type: 'Favourite', from_account: jeff, account: alice).count
}.from(1).to(0)
end
end end
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter