FIX: Polls with votes cannot be made public.

This commit is contained in:
Guo Xiang Tan 2016-06-09 12:10:27 +08:00
parent 8f5d3a5cbd
commit f53494f102
3 changed files with 46 additions and 2 deletions

View File

@ -41,6 +41,9 @@ en:
requires_at_least_1_valid_option: "You must select at least 1 valid option."
default_cannot_be_made_public: "Poll with votes cannot be made public."
named_cannot_be_made_public: "Poll named <strong>%{name}</strong> has votes cannot be made public."
cannot_change_polls_after_5_minutes: "You cannot add, remove or rename polls after the first 5 minutes."
op_cannot_edit_options_after_5_minutes: "You cannot add or remove poll options after the first 5 minutes. Please contact a moderator if you need to edit a poll option."
staff_cannot_add_or_remove_options_after_5_minutes: "You cannot add or remove poll options after the first 5 minutes. You should close this topic and create a new one instead."

View File

@ -41,6 +41,7 @@ module DiscoursePoll
# try to merge votes
polls.each_key do |poll_name|
next unless previous_polls.has_key?(poll_name)
return if has_votes && private_to_public_poll?(post, previous_polls, polls, poll_name)
# when the # of options has changed, reset all the votes
if polls[poll_name]["options"].size != previous_polls[poll_name]["options"].size
@ -96,5 +97,26 @@ module DiscoursePoll
def self.total_votes(polls)
polls.map { |key, value| value["voters"].to_i }.sum
end
private
def self.private_to_public_poll?(post, previous_polls, current_polls, poll_name)
previous_poll = previous_polls[poll_name]
current_poll = current_polls[poll_name]
if previous_polls["public"].nil? && current_poll["public"] == "true"
error =
if poll_name == DiscoursePoll::DEFAULT_POLL_NAME
I18n.t("poll.default_cannot_be_made_public")
else
I18n.t("poll.named_cannot_be_made_public", name: poll_name)
end
post.errors.add(:base, error)
return true
end
false
end
end
end

View File

@ -101,7 +101,7 @@ describe DiscoursePoll::PollsUpdater do
Fabricate(:post, raw: raw)
end
let(:private_poll) do
let(:private_poll_post) do
raw = <<-RAW.strip_heredoc
[poll]
- A
@ -109,7 +109,11 @@ describe DiscoursePoll::PollsUpdater do
[/poll]
RAW
DiscoursePoll::PollsValidator.new(Fabricate(:post, raw: raw)).validate_polls
Fabricate(:post, raw: raw)
end
let(:private_poll) do
DiscoursePoll::PollsValidator.new(private_poll_post).validate_polls
end
let(:public_poll) do
@ -130,6 +134,21 @@ describe DiscoursePoll::PollsUpdater do
post.reload
end
it "should not allow a private poll with votes to be made public" do
DiscoursePoll::Poll.vote(private_poll_post.id, "poll", ["5c24fc1df56d764b550ceae1b9319125"], user.id)
private_poll_post.reload
messages = MessageBus.track_publish do
described_class.update(private_poll_post, public_poll)
end
expect(messages).to eq([])
expect(private_poll_post.errors[:base]).to include(
I18n.t("poll.default_cannot_be_made_public")
)
end
it "should retain voter_ids when options have been edited" do
described_class.update(post, public_poll)