Fix poll expiration notification being re-triggered on implicit updates (#38078)
This commit is contained in:
@@ -410,6 +410,11 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
|
|||||||
|
|
||||||
return unless poll.present? && poll.expires_at.present? && poll.votes.exists?
|
return unless poll.present? && poll.expires_at.present? && poll.votes.exists?
|
||||||
|
|
||||||
|
# If the poll had previously expired, notifications should have already been sent out (or scheduled),
|
||||||
|
# and re-scheduling them would cause duplicate notifications for people who had already dismissed them
|
||||||
|
# (see #37948)
|
||||||
|
return if @previous_expires_at&.past?
|
||||||
|
|
||||||
PollExpirationNotifyWorker.remove_from_scheduled(poll.id) if @previous_expires_at.present? && @previous_expires_at > poll.expires_at
|
PollExpirationNotifyWorker.remove_from_scheduled(poll.id) if @previous_expires_at.present? && @previous_expires_at > poll.expires_at
|
||||||
PollExpirationNotifyWorker.perform_at(poll.expires_at + 5.minutes, poll.id)
|
PollExpirationNotifyWorker.perform_at(poll.expires_at + 5.minutes, poll.id)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -136,6 +136,48 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with an implicit update of a poll that has already expired' do
|
||||||
|
let(:account) { Fabricate(:account, domain: 'example.com') }
|
||||||
|
let!(:expiration) { 10.days.ago.utc }
|
||||||
|
let!(:status) do
|
||||||
|
Fabricate(:status,
|
||||||
|
text: 'Hello world',
|
||||||
|
account: account,
|
||||||
|
poll_attributes: {
|
||||||
|
options: %w(Foo Bar),
|
||||||
|
account: account,
|
||||||
|
multiple: false,
|
||||||
|
hide_totals: false,
|
||||||
|
expires_at: expiration,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:payload) do
|
||||||
|
{
|
||||||
|
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||||
|
id: 'https://example.com/foo',
|
||||||
|
type: 'Question',
|
||||||
|
content: 'Hello world',
|
||||||
|
endTime: expiration.iso8601,
|
||||||
|
oneOf: [
|
||||||
|
poll_option_json('Foo', 4),
|
||||||
|
poll_option_json('Bar', 3),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
travel_to(expiration - 1.day) do
|
||||||
|
Fabricate(:poll_vote, poll: status.poll)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not re-trigger notifications' do
|
||||||
|
expect { subject.call(status, json, json) }
|
||||||
|
.to_not enqueue_sidekiq_job(PollExpirationNotifyWorker)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when the status changes a poll despite being not explicitly marked as updated' do
|
context 'when the status changes a poll despite being not explicitly marked as updated' do
|
||||||
let(:account) { Fabricate(:account, domain: 'example.com') }
|
let(:account) { Fabricate(:account, domain: 'example.com') }
|
||||||
let!(:expiration) { 10.days.from_now.utc }
|
let!(:expiration) { 10.days.from_now.utc }
|
||||||
|
|||||||
Reference in New Issue
Block a user