diff --git a/plugins/poll/plugin.rb b/plugins/poll/plugin.rb index 82d271b7a81..977be892fa6 100644 --- a/plugins/poll/plugin.rb +++ b/plugins/poll/plugin.rb @@ -61,7 +61,7 @@ after_initialize do raise StandardError.new I18n.t("poll.requires_at_least_1_valid_option") if options.empty? - poll["voters"] = 0 + poll["voters"] = poll["anonymous_voters"] || 0 all_options = Hash.new(0) post.custom_fields[VOTES_CUSTOM_FIELD] ||= {} @@ -74,7 +74,10 @@ after_initialize do poll["voters"] += 1 if (available_options & votes.to_set).size > 0 end - poll["options"].each { |o| o["votes"] = all_options[o["id"]] } + poll["options"].each do |option| + anonymous_votes = option["anonymous_votes"] || 0 + option["votes"] = all_options[option["id"]] + anonymous_votes + end post.custom_fields[POLLS_CUSTOM_FIELD] = polls post.save_custom_fields(true) @@ -327,8 +330,14 @@ after_initialize do end polls[poll_name]["voters"] = previous_polls[poll_name]["voters"] + polls[poll_name]["anonymous_voters"] = previous_polls[poll_name]["anonymous_voters"] if previous_polls[poll_name].has_key?("anonymous_voters") + for o in 0...polls[poll_name]["options"].size - polls[poll_name]["options"][o]["votes"] = previous_polls[poll_name]["options"][o]["votes"] + current_option = polls[poll_name]["options"][o] + previous_option = previous_polls[poll_name]["options"][o] + + current_option["votes"] = previous_option["votes"] + current_option["anonymous_votes"] = previous_option["anonymous_votes"] if previous_option.has_key?("anonymous_votes") end end diff --git a/plugins/poll/spec/controllers/polls_controller_spec.rb b/plugins/poll/spec/controllers/polls_controller_spec.rb index b1679d7d6ee..8a8ce7190e5 100644 --- a/plugins/poll/spec/controllers/polls_controller_spec.rb +++ b/plugins/poll/spec/controllers/polls_controller_spec.rb @@ -1,4 +1,5 @@ require "rails_helper" +require_relative "../helpers" describe ::DiscoursePoll::PollsController do routes { ::DiscoursePoll::Engine.routes } @@ -85,6 +86,18 @@ describe ::DiscoursePoll::PollsController do expect(json["errors"][0]).to eq(I18n.t("poll.poll_must_be_open_to_vote")) end + it "doesn't discard anonymous votes when someone votes" do + default_poll = poll.custom_fields["polls"]["poll"] + add_anonymous_votes(poll, default_poll, 17, {"5c24fc1df56d764b550ceae1b9319125" => 11, "e89dec30bbd9bf50fabf6a05b4324edf" => 6}) + + xhr :put, :vote, { post_id: poll.id, poll_name: "poll", options: ["5c24fc1df56d764b550ceae1b9319125"] } + expect(response).to be_success + + json = ::JSON.parse(response.body) + expect(json["poll"]["voters"]).to eq(18) + expect(json["poll"]["options"][0]["votes"]).to eq(12) + expect(json["poll"]["options"][1]["votes"]).to eq(6) + end end describe "#toggle_status" do diff --git a/plugins/poll/spec/controllers/posts_controller_spec.rb b/plugins/poll/spec/controllers/posts_controller_spec.rb index bc86459637f..990ead74d8e 100644 --- a/plugins/poll/spec/controllers/posts_controller_spec.rb +++ b/plugins/poll/spec/controllers/posts_controller_spec.rb @@ -1,4 +1,5 @@ require "rails_helper" +require_relative "../helpers" describe PostsController do let!(:user) { log_in } @@ -165,12 +166,31 @@ describe PostsController do expect(json["errors"][0]).to eq(I18n.t("poll.op_cannot_edit_options_after_5_minutes")) end - it "staff can change the options" do + it "staff can change the options and votes are merged" do log_in_user(Fabricate(:moderator)) xhr :put, :update, { id: post_id, post: { raw: new_option } } expect(response).to be_success json = ::JSON.parse(response.body) expect(json["post"]["polls"]["poll"]["options"][1]["html"]).to eq("C") + expect(json["post"]["polls"]["poll"]["voters"]).to eq(1) + expect(json["post"]["polls"]["poll"]["options"][0]["votes"]).to eq(1) + expect(json["post"]["polls"]["poll"]["options"][1]["votes"]).to eq(0) + end + + it "staff can change the options and anonymous votes are merged" do + post = Post.find_by(id: post_id) + default_poll = post.custom_fields["polls"]["poll"] + add_anonymous_votes(post, default_poll, 7, {"5c24fc1df56d764b550ceae1b9319125" => 7}) + + log_in_user(Fabricate(:moderator)) + xhr :put, :update, { id: post_id, post: { raw: new_option } } + expect(response).to be_success + + json = ::JSON.parse(response.body) + expect(json["post"]["polls"]["poll"]["options"][1]["html"]).to eq("C") + expect(json["post"]["polls"]["poll"]["voters"]).to eq(8) + expect(json["post"]["polls"]["poll"]["options"][0]["votes"]).to eq(8) + expect(json["post"]["polls"]["poll"]["options"][1]["votes"]).to eq(0) end it "support changes on the post" do diff --git a/plugins/poll/spec/helpers.rb b/plugins/poll/spec/helpers.rb new file mode 100644 index 00000000000..a0584810ab8 --- /dev/null +++ b/plugins/poll/spec/helpers.rb @@ -0,0 +1,17 @@ +module Helpers + def add_anonymous_votes(post, poll, voters, options_with_votes) + poll["voters"] += voters + poll["anonymous_voters"] = voters + + poll["options"].each do |option| + anonymous_votes = options_with_votes[option["id"]] || 0 + + if anonymous_votes > 0 + option["votes"] += anonymous_votes + option["anonymous_votes"] = anonymous_votes + end + end + + post.save_custom_fields(true) + end +end