DEV: An endpoint to check if the current user voted in a poll. (#13648)

DEV: An endpoint to check if the current user voted in a poll. (#13648)

The endpoint the existence of the poll and if the current user can see it. It will facilitate using a poll programmatically, especially if we’d like to create an external poll through a theme component.

diff --git a/plugins/poll/plugin.rb b/plugins/poll/plugin.rb
index 816b06f..fd428ab 100644
--- a/plugins/poll/plugin.rb
+++ b/plugins/poll/plugin.rb
@@ -398,6 +398,17 @@ after_initialize do
       end
     end
 
+    def current_user_voted
+      poll = Poll.includes(:post).find_by(id: params[:id])
+      raise Discourse::NotFound.new(:id) if poll.nil?
+
+      can_see_poll = Guardian.new(current_user).can_see_post?(poll.post)
+      raise Discourse::NotFound.new(:id) if !can_see_poll
+
+      presence = PollVote.where(poll: poll, user: current_user).exists?
+      render json: { voted: presence }
+    end
+
     def toggle_status
       post_id   = params.require(:post_id)
       poll_name = params.require(:poll_name)
@@ -453,6 +464,7 @@ after_initialize do
     get "/voters" => 'polls#voters'
     get "/grouped_poll_results" => 'polls#grouped_poll_results'
     get "/groupable_user_fields" => 'polls#groupable_user_fields'
+    get "/:id/votes/current_user_voted" => "polls#current_user_voted"
   end
 
   Discourse::Application.routes.append do
diff --git a/plugins/poll/spec/controllers/polls_controller_spec.rb b/plugins/poll/spec/controllers/polls_controller_spec.rb
index 9534a5c..81628c7 100644
--- a/plugins/poll/spec/controllers/polls_controller_spec.rb
+++ b/plugins/poll/spec/controllers/polls_controller_spec.rb
@@ -385,4 +385,48 @@ describe ::DiscoursePoll::PollsController do
 
   end
 
+  describe '#current_user_voted' do
+    let(:logged_user) { Fabricate(:user) }
+    let(:post_with_poll) { Fabricate(:post, raw: "[poll]\n- A\n- B\n[/poll]") }
+
+    before { log_in_user(logged_user) }
+
+    it 'returns true if the logged user already voted' do
+      poll = post_with_poll.polls.last
+      PollVote.create!(poll: poll, user: logged_user)
+
+      get :current_user_voted, params: { id: poll.id }, format: :json
+      parsed_body = JSON.parse(response.body)
+
+      expect(response.status).to eq(200)
+      expect(parsed_body['voted']).to eq(true)
+    end
+
+    it 'returns a 404 if there is no poll' do
+      unknown_poll_id = 999999
+
+      get :current_user_voted, params: { id: unknown_poll_id }, format: :json
+
+      expect(response.status).to eq(404)
+    end
+
+    it "returns a 404 if the user doesn't have access to the poll" do
+      pm_with_poll = Fabricate(:private_message_post, raw: "[poll]\n- A\n- B\n[/poll]")
+      poll = pm_with_poll.polls.last
+
+      get :current_user_voted, params: { id: poll.id }, format: :json
+
+      expect(response.status).to eq(404)
+    end
+
+    it "returns false if the user didn't vote yet" do
+      poll = post_with_poll.polls.last
+
+      get :current_user_voted, params: { id: poll.id }, format: :json
+      parsed_body = JSON.parse(response.body)
+
+      expect(response.status).to eq(200)
+      expect(parsed_body['voted']).to eq(false)
+    end
+  end
 end

GitHub sha: 7925a76d93c0f85396eb7f5d876c2258732762a0

This commit appears in #13648 which was approved by CvX. It was merged by romanrizzi.