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) %>
<% question_answers.each do |question_answer| %>
<% if already_answered?(question_answer) %>
<span class="button answered"
title="<%= t("poll_questions.show.voted", answer: question_answer.title) %>">
<%= 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 %>
</span>
<% 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 %>

View File

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

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

View File

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

View File

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

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_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 }

View File

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

View File

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

View File

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