From f83638c154ce93d3ce9a46f5d4119ad9d4c758aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Hanol?= Date: Fri, 1 May 2015 16:33:24 +0200 Subject: [PATCH] FIX: check the selected options when casting a vote --- plugins/poll/config/locales/server.en.yml | 1 + plugins/poll/plugin.rb | 7 +++++++ .../poll/spec/controllers/polls_controller_spec.rb | 12 ++++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/plugins/poll/config/locales/server.en.yml b/plugins/poll/config/locales/server.en.yml index ad9009284cc..3434059bc5b 100644 --- a/plugins/poll/config/locales/server.en.yml +++ b/plugins/poll/config/locales/server.en.yml @@ -19,6 +19,7 @@ en: default_poll_must_have_different_options: "Poll must have different options." named_poll_must_have_different_options: "Poll name %{name} must have different options." + requires_at_least_1_valid_option: "You must select at least 1 valid option." cannot_change_polls_after_5_minutes: "Polls cannot be changed after the first 5 minutes. Contact a moderator if you need to change them." staff_cannot_add_or_remove_options_after_5_minutes: "After the first 5 minutes, poll options can only be edited, not added or removed. If you need to add or remove options, you should close this topic and create a new one." diff --git a/plugins/poll/plugin.rb b/plugins/poll/plugin.rb index 530307c4178..514ef785a5e 100644 --- a/plugins/poll/plugin.rb +++ b/plugins/poll/plugin.rb @@ -47,9 +47,16 @@ after_initialize do raise StandardError.new I18n.t("poll.no_poll_with_this_name", name: poll_name) if poll.blank? raise StandardError.new I18n.t("poll.poll_must_be_open_to_vote") if poll["status"] != "open" + # remove options that aren't available in the poll + available_options = poll["options"].map { |o| o["id"] }.to_set + options.select! { |o| available_options.include?(o) } + + raise StandardError.new I18n.t("poll.requires_at_least_1_valid_option") if options.empty? + votes = post.custom_fields["#{VOTES_CUSTOM_FIELD}-#{user_id}"] || {} vote = votes[poll_name] || [] + # increment counters only when the user hasn't casted a vote yet poll["total_votes"] += 1 if vote.size == 0 poll["options"].each do |option| diff --git a/plugins/poll/spec/controllers/polls_controller_spec.rb b/plugins/poll/spec/controllers/polls_controller_spec.rb index 391f06648fa..3e79ab7cd99 100644 --- a/plugins/poll/spec/controllers/polls_controller_spec.rb +++ b/plugins/poll/spec/controllers/polls_controller_spec.rb @@ -12,13 +12,21 @@ describe ::DiscoursePoll::PollsController do it "works" do DiscourseBus.expects(:publish) - xhr :put, :vote, { post_id: poll.id, poll_name: "poll", options: ["A"] } + 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"]["name"]).to eq("poll") expect(json["poll"]["total_votes"]).to eq(1) - expect(json["vote"]).to eq(["A"]) + expect(json["vote"]).to eq(["5c24fc1df56d764b550ceae1b9319125"]) + end + + it "requires at least 1 valid option" do + xhr :put, :vote, { post_id: poll.id, poll_name: "poll", options: ["A", "B"] } + + expect(response).not_to be_success + json = ::JSON.parse(response.body) + expect(json["errors"][0]).to eq(I18n.t("poll.requires_at_least_1_valid_option")) end it "supports vote changes" do