diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 87179030c26479..7e4e57eadda73d 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -241,6 +241,7 @@ def process_poll def poll_vote? return false if replied_to_status.nil? || replied_to_status.poll.nil? || !replied_to_status.local? || !replied_to_status.poll.options.include?(@object['name']) + return true if replied_to_status.poll.expired? replied_to_status.poll.votes.create!(account: @account, choice: replied_to_status.poll.options.index(@object['name']), uri: @object['id']) end diff --git a/app/models/poll.rb b/app/models/poll.rb index 14a38026a03a8d..09f0b65ec4a169 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -28,7 +28,7 @@ class Poll < ApplicationRecord validates :options, presence: true validates :expires_at, presence: true, if: :local? - validates_with PollValidator, if: :local? + validates_with PollValidator, on: :create, if: :local? scope :attached, -> { where.not(status_id: nil) } scope :unattached, -> { where(status_id: nil) } diff --git a/app/services/vote_service.rb b/app/services/vote_service.rb index 8bab2810ea1d6f..5b80da03a3704e 100644 --- a/app/services/vote_service.rb +++ b/app/services/vote_service.rb @@ -11,6 +11,8 @@ def call(account, poll, choices) @choices = choices @votes = [] + return if @poll.expired? + ApplicationRecord.transaction do @choices.each do |choice| @votes << @poll.votes.create!(account: @account, choice: choice) diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index 56c7bfc615005f..3a1463d958f0b7 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -482,6 +482,28 @@ expect(poll.reload.cached_tallies).to eq [1, 0] end end + + context 'when a vote to an expired local poll' do + let(:poll) do + poll = Fabricate.build(:poll, options: %w(Yellow Blue), expires_at: 1.day.ago) + poll.save(validate: false) + poll + end + let!(:local_status) { Fabricate(:status, owned_poll: poll) } + + let(:object_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, + type: 'Note', + name: 'Yellow', + inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status) + } + end + + it 'does not add a vote to the poll' do + expect(poll.votes.first).to be_nil + end + end end context 'when sender is followed by local users' do