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." 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." 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." 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." 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 # try to merge votes
polls.each_key do |poll_name| polls.each_key do |poll_name|
next unless previous_polls.has_key?(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 # when the # of options has changed, reset all the votes
if polls[poll_name]["options"].size != previous_polls[poll_name]["options"].size if polls[poll_name]["options"].size != previous_polls[poll_name]["options"].size
@ -96,5 +97,26 @@ module DiscoursePoll
def self.total_votes(polls) def self.total_votes(polls)
polls.map { |key, value| value["voters"].to_i }.sum polls.map { |key, value| value["voters"].to_i }.sum
end 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
end end

View File

@ -101,7 +101,7 @@ describe DiscoursePoll::PollsUpdater do
Fabricate(:post, raw: raw) Fabricate(:post, raw: raw)
end end
let(:private_poll) do let(:private_poll_post) do
raw = <<-RAW.strip_heredoc raw = <<-RAW.strip_heredoc
[poll] [poll]
- A - A
@ -109,7 +109,11 @@ describe DiscoursePoll::PollsUpdater do
[/poll] [/poll]
RAW 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 end
let(:public_poll) do let(:public_poll) do
@ -130,6 +134,21 @@ describe DiscoursePoll::PollsUpdater do
post.reload post.reload
end 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 it "should retain voter_ids when options have been edited" do
described_class.update(post, public_poll) described_class.update(post, public_poll)