catstodon/app/services/activitypub/process_poll_service.rb
ThibG 00c219aa45 Fix empty poll options not being filtered on remote poll update (#12484)
If a poll contains empty options (which is apparently possible on Pleroma),
it is created without them. However, the poll update code doesn't filter
empty options, and thus:
1. Clear known votes, as it assumes the set of options has changed
2. Errors out because it tries adding empty options, which fails validation

This commit fixes that by filtering them out the same way they are filtered
out at poll creation time.
2019-11-26 22:46:31 +01:00

64 lines
1.6 KiB
Ruby

# frozen_string_literal: true
class ActivityPub::ProcessPollService < BaseService
include JsonLdHelper
def call(poll, json)
@json = json
return unless expected_type?
previous_expires_at = poll.expires_at
expires_at = begin
if @json['closed'].is_a?(String)
@json['closed']
elsif !@json['closed'].nil? && !@json['closed'].is_a?(FalseClass)
Time.now.utc
else
@json['endTime']
end
end
items = begin
if @json['anyOf'].is_a?(Array)
@json['anyOf']
else
@json['oneOf']
end
end
voters_count = @json['votersCount']
latest_options = items.map { |item| item['name'].presence || item['content'] }.compact
# If for some reasons the options were changed, it invalidates all previous
# votes, so we need to remove them
poll.votes.delete_all if latest_options != poll.options
begin
poll.update!(
last_fetched_at: Time.now.utc,
expires_at: expires_at,
options: latest_options,
cached_tallies: items.map { |item| item.dig('replies', 'totalItems') || 0 },
voters_count: voters_count
)
rescue ActiveRecord::StaleObjectError
poll.reload
retry
end
# If the poll had no expiration date set but now has, and people have voted,
# schedule a notification.
if previous_expires_at.nil? && poll.expires_at.present? && poll.votes.exists?
PollExpirationNotifyWorker.perform_at(poll.expires_at + 5.minutes, poll.id)
end
end
private
def expected_type?
equals_or_includes_any?(@json['type'], %w(Question))
end
end