Allow to remove poll answers

This commit is contained in:
Senén Rodero Rodríguez
2022-09-30 18:09:24 +02:00
parent f90d0d9c4d
commit 7df0e9a961
10 changed files with 68 additions and 21 deletions

View File

@@ -2,15 +2,20 @@
<% if can?(:answer, question) && !question.poll.voted_in_booth?(current_user) %> <% if can?(:answer, question) && !question.poll.voted_in_booth?(current_user) %>
<% question_answers.each do |question_answer| %> <% question_answers.each do |question_answer| %>
<% if already_answered?(question_answer) %> <% if already_answered?(question_answer) %>
<span class="button answered" <%= button_to question_answer_path(question, user_answer(question_answer)),
title="<%= t("poll_questions.show.voted", answer: question_answer.title) %>"> method: :delete,
remote: true,
title: t("poll_questions.show.voted", answer: question_answer.title),
class: "button answered",
"aria-pressed": true do %>
<%= question_answer.title %> <%= question_answer.title %>
</span> <% end %>
<% else %> <% else %>
<%= button_to answer_question_path(question, answer: question_answer.title), <%= button_to answer_question_path(question, answer: question_answer.title),
remote: true, remote: true,
title: t("poll_questions.show.vote_answer", answer: question_answer.title), 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 %> <%= question_answer.title %>
<% end %> <% end %>
<% end %> <% end %>

View File

@@ -7,13 +7,17 @@ class Polls::Questions::AnswersComponent < ApplicationComponent
end end
def already_answered?(question_answer) def already_answered?(question_answer)
user_answers.find_by(answer: question_answer.title).present? user_answer(question_answer).present?
end end
def question_answers def question_answers
question.question_answers question.question_answers
end end
def user_answer(question_answer)
user_answers.find_by(answer: question_answer.title)
end
private private
def user_answers def user_answers

View File

@@ -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

View File

@@ -112,6 +112,9 @@ module Abilities
can :answer, Poll::Question do |question| can :answer, Poll::Question do |question|
question.answerable_by?(user) question.answerable_by?(user)
end end
can :destroy, Poll::Answer do |answer|
answer.author == user && answer.question.answerable_by?(user)
end
end end
can [:create, :show], ProposalNotification, proposal: { author_id: user.id } can [:create, :show], ProposalNotification, proposal: { author_id: user.id }

View File

@@ -6,6 +6,7 @@ resources :polls, only: [:show, :index] do
resources :questions, controller: "polls/questions", shallow: true do resources :questions, controller: "polls/questions", shallow: true do
post :answer, on: :member post :answer, on: :member
resources :answers, controller: "polls/answers", only: :destroy, shallow: false
end end
end end

View File

@@ -18,18 +18,19 @@ describe Polls::Questions::AnswersComponent do
expect(page).to have_button "Yes" expect(page).to have_button "Yes"
expect(page).to have_button "No" expect(page).to have_button "No"
expect(page).to have_css "button[aria-pressed='false']", count: 2
end 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) user = create(:user, :verified)
create(:poll_answer, author: user, question: question, answer: "Yes") create(:poll_answer, author: user, question: question, answer: "Yes")
sign_in(user) sign_in(user)
render_inline Polls::Questions::AnswersComponent.new(question) render_inline Polls::Questions::AnswersComponent.new(question)
expect(page).to have_selector "span", text: "Yes" expect(page).to have_button "You have voted Yes"
expect(page).not_to have_button "Yes" expect(page).to have_button "Vote No"
expect(page).to have_button "No" expect(page).to have_css "button[aria-pressed='true']", text: "Yes"
end end
it "when user is not signed in, renders answers links pointing to user sign in path" do it "when user is not signed in, renders answers links pointing to user sign in path" do

View File

@@ -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_all_geozones) }
it { should_not be_able_to(:answer, expired_poll_question_from_other_geozone) } 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 context "without geozone" do
before { user.geozone = nil } before { user.geozone = nil }

View File

@@ -5,8 +5,8 @@ module Polls
within("#poll_question_#{question.id}_answers") do within("#poll_question_#{question.id}_answers") do
click_button answer click_button answer
expect(page).to have_css("span.answered", text: answer) expect(page).to have_button("You have voted #{answer}")
expect(page).not_to have_button(answer) expect(page).not_to have_button("Vote #{answer}")
end end
end end

View File

@@ -246,10 +246,10 @@ describe "Polls" do
visit poll_path(poll) visit poll_path(poll)
within("#poll_question_#{question.id}_answers") do 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 "You have voted Yes"
expect(page).to have_button "No" expect(page).to have_button "Vote No"
end end
end end
@@ -266,13 +266,13 @@ describe "Polls" do
within("#poll_question_#{question.id}_answers") do within("#poll_question_#{question.id}_answers") do
click_button "Yes" 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" expect(page).to have_button "Vote No"
click_button "No" click_button "No"
expect(page).not_to have_button "No" expect(page).to have_button "Vote Yes"
expect(page).to have_button "Yes" expect(page).to have_button "You have voted No"
end end
end end
@@ -309,7 +309,7 @@ describe "Polls" do
within("#poll_question_#{question.id}_answers") do within("#poll_question_#{question.id}_answers") do
click_button "Yes" 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" expect(page).to have_button "No"
end end
end end

View File

@@ -23,8 +23,10 @@ describe "Voter" do
visit poll_path(poll) visit poll_path(poll)
within("#poll_question_#{question.id}_answers") do within("#poll_question_#{question.id}_answers") do
click_button answer_yes.title click_button "Vote Yes"
expect(page).not_to have_button(answer_yes.title)
expect(page).to have_button("You have voted Yes")
expect(page).not_to have_button("Vote Yes")
end end
expect(Poll::Voter.count).to eq(1) expect(Poll::Voter.count).to eq(1)