diff --git a/app/components/polls/questions/answers_component.html.erb b/app/components/polls/questions/answers_component.html.erb index 053a514ad..de84bcd7f 100644 --- a/app/components/polls/questions/answers_component.html.erb +++ b/app/components/polls/questions/answers_component.html.erb @@ -2,15 +2,20 @@ <% if can?(:answer, question) && !question.poll.voted_in_booth?(current_user) %> <% question_answers.each do |question_answer| %> <% if already_answered?(question_answer) %> - "> + <%= button_to question_answer_path(question, user_answer(question_answer)), + method: :delete, + remote: true, + title: t("poll_questions.show.voted", answer: question_answer.title), + class: "button answered", + "aria-pressed": true do %> <%= question_answer.title %> - + <% end %> <% else %> <%= button_to answer_question_path(question, answer: question_answer.title), remote: true, title: t("poll_questions.show.vote_answer", answer: question_answer.title), - class: "button secondary hollow" do %> + class: "button secondary hollow", + "aria-pressed": false do %> <%= question_answer.title %> <% end %> <% end %> diff --git a/app/components/polls/questions/answers_component.rb b/app/components/polls/questions/answers_component.rb index e007dd1c2..b21459a97 100644 --- a/app/components/polls/questions/answers_component.rb +++ b/app/components/polls/questions/answers_component.rb @@ -7,13 +7,17 @@ class Polls::Questions::AnswersComponent < ApplicationComponent end def already_answered?(question_answer) - user_answers.find_by(answer: question_answer.title).present? + user_answer(question_answer).present? end def question_answers question.question_answers end + def user_answer(question_answer) + user_answers.find_by(answer: question_answer.title) + end + private def user_answers diff --git a/app/controllers/polls/answers_controller.rb b/app/controllers/polls/answers_controller.rb new file mode 100644 index 000000000..46a40185d --- /dev/null +++ b/app/controllers/polls/answers_controller.rb @@ -0,0 +1,19 @@ +class Polls::AnswersController < ApplicationController + load_and_authorize_resource :question, class: "::Poll::Question" + load_and_authorize_resource :answer, class: "::Poll::Answer", + through: :question, + through_association: :answers + + def destroy + @answer.destroy! + + respond_to do |format| + format.html do + redirect_to request.referer + end + format.js do + render "polls/questions/answers" + end + end + end +end diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index 2da9a057d..6c8d6cdd2 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -112,6 +112,9 @@ module Abilities can :answer, Poll::Question do |question| question.answerable_by?(user) end + can :destroy, Poll::Answer do |answer| + answer.author == user && answer.question.answerable_by?(user) + end end can [:create, :show], ProposalNotification, proposal: { author_id: user.id } diff --git a/config/routes/poll.rb b/config/routes/poll.rb index 5b3c03c7a..94cf504b4 100644 --- a/config/routes/poll.rb +++ b/config/routes/poll.rb @@ -6,6 +6,7 @@ resources :polls, only: [:show, :index] do resources :questions, controller: "polls/questions", shallow: true do post :answer, on: :member + resources :answers, controller: "polls/answers", only: :destroy, shallow: false end end diff --git a/spec/components/polls/questions/answers_component_spec.rb b/spec/components/polls/questions/answers_component_spec.rb index 6fadded57..0b05953c2 100644 --- a/spec/components/polls/questions/answers_component_spec.rb +++ b/spec/components/polls/questions/answers_component_spec.rb @@ -18,18 +18,19 @@ describe Polls::Questions::AnswersComponent do expect(page).to have_button "Yes" expect(page).to have_button "No" + expect(page).to have_css "button[aria-pressed='false']", count: 2 end - it "renders a span instead of a button for existing user answers" do + it "renders button to destroy current user answers" do user = create(:user, :verified) create(:poll_answer, author: user, question: question, answer: "Yes") sign_in(user) render_inline Polls::Questions::AnswersComponent.new(question) - expect(page).to have_selector "span", text: "Yes" - expect(page).not_to have_button "Yes" - expect(page).to have_button "No" + expect(page).to have_button "You have voted Yes" + expect(page).to have_button "Vote No" + expect(page).to have_css "button[aria-pressed='true']", text: "Yes" end it "when user is not signed in, renders answers links pointing to user sign in path" do diff --git a/spec/models/abilities/common_spec.rb b/spec/models/abilities/common_spec.rb index 42194209a..81eb67e38 100644 --- a/spec/models/abilities/common_spec.rb +++ b/spec/models/abilities/common_spec.rb @@ -232,6 +232,18 @@ describe Abilities::Common do it { should_not be_able_to(:answer, expired_poll_question_from_all_geozones) } it { should_not be_able_to(:answer, expired_poll_question_from_other_geozone) } + context "Poll::Answer" do + let(:own_answer) { create(:poll_answer, author: user) } + let(:other_user_answer) { create(:poll_answer) } + let(:expired_poll) { create(:poll, :expired) } + let(:question) { create(:poll_question, :yes_no, poll: expired_poll) } + let(:expired_poll_answer) { create(:poll_answer, author: user, question: question, answer: "Yes") } + + it { should be_able_to(:destroy, own_answer) } + it { should_not be_able_to(:destroy, other_user_answer) } + it { should_not be_able_to(:destroy, expired_poll_answer) } + end + context "without geozone" do before { user.geozone = nil } diff --git a/spec/support/common_actions/polls.rb b/spec/support/common_actions/polls.rb index b571472c4..68cc1c6c0 100644 --- a/spec/support/common_actions/polls.rb +++ b/spec/support/common_actions/polls.rb @@ -5,8 +5,8 @@ module Polls within("#poll_question_#{question.id}_answers") do click_button answer - expect(page).to have_css("span.answered", text: answer) - expect(page).not_to have_button(answer) + expect(page).to have_button("You have voted #{answer}") + expect(page).not_to have_button("Vote #{answer}") end end diff --git a/spec/system/polls/polls_spec.rb b/spec/system/polls/polls_spec.rb index 59ee5b319..6d15c2d78 100644 --- a/spec/system/polls/polls_spec.rb +++ b/spec/system/polls/polls_spec.rb @@ -246,10 +246,10 @@ describe "Polls" do visit poll_path(poll) within("#poll_question_#{question.id}_answers") do - click_button "Yes" + click_button "Vote Yes" - expect(page).not_to have_button "Yes" - expect(page).to have_button "No" + expect(page).to have_button "You have voted Yes" + expect(page).to have_button "Vote No" end end @@ -266,13 +266,13 @@ describe "Polls" do within("#poll_question_#{question.id}_answers") do click_button "Yes" - expect(page).not_to have_button "Yes" - expect(page).to have_button "No" + expect(page).to have_button "You have voted Yes" + expect(page).to have_button "Vote No" click_button "No" - expect(page).not_to have_button "No" - expect(page).to have_button "Yes" + expect(page).to have_button "Vote Yes" + expect(page).to have_button "You have voted No" end end @@ -309,7 +309,7 @@ describe "Polls" do within("#poll_question_#{question.id}_answers") do click_button "Yes" - expect(page).not_to have_button "Yes" + expect(page).to have_button "You have voted Yes" expect(page).to have_button "No" end end diff --git a/spec/system/polls/voter_spec.rb b/spec/system/polls/voter_spec.rb index 5d8daef34..30cc577fd 100644 --- a/spec/system/polls/voter_spec.rb +++ b/spec/system/polls/voter_spec.rb @@ -23,8 +23,10 @@ describe "Voter" do visit poll_path(poll) within("#poll_question_#{question.id}_answers") do - click_button answer_yes.title - expect(page).not_to have_button(answer_yes.title) + click_button "Vote Yes" + + expect(page).to have_button("You have voted Yes") + expect(page).not_to have_button("Vote Yes") end expect(Poll::Voter.count).to eq(1)