From 054bbb3da21b2c76374eb921cba862adb8d5a0b3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 7 Mar 2019 22:53:47 +0100 Subject: Immediately display poll results to poll author (#10187) * Immediately display poll results to poll author * Refactor Poll#loaded_options and add Poll#voted? to improve DRYness --- app/models/poll.rb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'app/models/poll.rb') diff --git a/app/models/poll.rb b/app/models/poll.rb index da2e25e71..14a38026a 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -41,17 +41,17 @@ class Poll < ApplicationRecord after_commit :reset_parent_cache, on: :update def loaded_options - options.map.with_index { |title, key| Option.new(self, key.to_s, title, cached_tallies[key]) } - end - - def unloaded_options - options.map.with_index { |title, key| Option.new(self, key.to_s, title, nil) } + options.map.with_index { |title, key| Option.new(self, key.to_s, title, show_totals_now? ? cached_tallies[key] : nil) } end def possibly_stale? remote? && last_fetched_before_expiration? && time_passed_since_last_fetch? end + def voted?(account) + account.id == account_id || votes.where(account: account).exists? + end + delegate :local?, to: :account def remote? @@ -95,4 +95,8 @@ class Poll < ApplicationRecord def time_passed_since_last_fetch? last_fetched_at.nil? || last_fetched_at < 1.minute.ago end + + def show_totals_now? + expired? || !hide_totals? + end end -- cgit From 3aaac4f134eb092baeb0ba5979bdb3abd702a4ee Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 8 Mar 2019 00:54:50 +0100 Subject: Do not allow adding votes to expired polls (#10214) * Do not allow adding votes to expired polls * Only validate expires_at on create --- app/lib/activitypub/activity/create.rb | 1 + app/models/poll.rb | 2 +- app/services/vote_service.rb | 2 ++ spec/lib/activitypub/activity/create_spec.rb | 22 ++++++++++++++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) (limited to 'app/models/poll.rb') diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 87179030c..7e4e57ead 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -241,6 +241,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity 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 14a38026a..09f0b65ec 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 8bab2810e..5b80da03a 100644 --- a/app/services/vote_service.rb +++ b/app/services/vote_service.rb @@ -11,6 +11,8 @@ class VoteService < BaseService @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 56c7bfc61..3a1463d95 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -482,6 +482,28 @@ RSpec.describe ActivityPub::Activity::Create do 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 -- cgit