Extract polls questions answers partial into a component
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
<div class="poll-question-answers">
|
||||
<% if can?(:answer, question) && !question.poll.voted_in_booth?(current_user) %>
|
||||
<% question.question_answers.each do |answer| %>
|
||||
<% if @answers_by_question_id[question.id] == answer.title &&
|
||||
(!voted_before_sign_in(question) ||
|
||||
<% if answers_by_question_id[question.id] == answer.title &&
|
||||
(!voted_before_sign_in? ||
|
||||
question.poll.voted_in_booth?(current_user)) %>
|
||||
<span class="button answered"
|
||||
title="<%= t("poll_questions.show.voted", answer: answer.title) %>">
|
||||
31
app/components/polls/questions/answers_component.rb
Normal file
31
app/components/polls/questions/answers_component.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
class Polls::Questions::AnswersComponent < ApplicationComponent
|
||||
attr_reader :question
|
||||
delegate :can?, :current_user, :user_signed_in?, to: :helpers
|
||||
|
||||
def initialize(question)
|
||||
@question = question
|
||||
end
|
||||
|
||||
def answers_by_question_id
|
||||
if params[:answer]
|
||||
{ question.id => params[:answer] }
|
||||
else
|
||||
stored_answers_by_question_id
|
||||
end
|
||||
end
|
||||
|
||||
def voted_before_sign_in?
|
||||
question.answers.where(author: current_user).any? do |vote|
|
||||
vote.updated_at < current_user.current_sign_in_at
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def stored_answers_by_question_id
|
||||
poll_answers = ::Poll::Answer.by_question(question.poll.question_ids).by_author(current_user&.id)
|
||||
poll_answers.each_with_object({}) do |answer, answers_by_question_id|
|
||||
answers_by_question_id[answer.question_id] = answer.answer
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -10,8 +10,6 @@ class Polls::QuestionsController < ApplicationController
|
||||
answer.answer = params[:answer]
|
||||
answer.save_and_record_voter_participation
|
||||
|
||||
@answers_by_question_id = { @question.id => params[:answer] }
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
redirect_to request.referer
|
||||
|
||||
@@ -21,13 +21,6 @@ class PollsController < ApplicationController
|
||||
@questions = @poll.questions.for_render.sort_for_list
|
||||
@poll_questions_answers = Poll::Question::Answer.where(question: @poll.questions)
|
||||
.with_content.order(:given_order)
|
||||
|
||||
@answers_by_question_id = {}
|
||||
poll_answers = ::Poll::Answer.by_question(@poll.question_ids).by_author(current_user&.id)
|
||||
poll_answers.each do |answer|
|
||||
@answers_by_question_id[answer.question_id] = answer.answer
|
||||
end
|
||||
|
||||
@commentable = @poll
|
||||
@comment_tree = CommentTree.new(@commentable, params[:page], @current_order)
|
||||
end
|
||||
|
||||
@@ -12,10 +12,6 @@ module PollsHelper
|
||||
booth.name + location
|
||||
end
|
||||
|
||||
def voted_before_sign_in(question)
|
||||
question.answers.where(author: current_user).any? { |vote| current_user.current_sign_in_at > vote.updated_at }
|
||||
end
|
||||
|
||||
def link_to_poll(text, poll)
|
||||
if can?(:results, poll)
|
||||
link_to text, results_poll_path(id: poll.slug || poll.id)
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
</h3>
|
||||
|
||||
<div id="<%= dom_id(question) %>_answers" class="padding">
|
||||
<%= render "polls/questions/answers", question: question %>
|
||||
<%= render Polls::Questions::AnswersComponent.new(question) %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1 +1 @@
|
||||
$("#<%= dom_id(@question) %>_answers").html("<%= j render("polls/questions/answers", question: @question) %>");
|
||||
$("#<%= dom_id(@question) %>_answers").html("<%= j render Polls::Questions::AnswersComponent.new(@question) %>");
|
||||
|
||||
110
spec/components/polls/questions/answers_component_spec.rb
Normal file
110
spec/components/polls/questions/answers_component_spec.rb
Normal file
@@ -0,0 +1,110 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Polls::Questions::AnswersComponent do
|
||||
include Rails.application.routes.url_helpers
|
||||
let(:poll) { create(:poll) }
|
||||
let(:question) { create(:poll_question, :yes_no, poll: poll) }
|
||||
|
||||
it "renders answers in given order" do
|
||||
render_inline Polls::Questions::AnswersComponent.new(question)
|
||||
|
||||
expect("Yes").to appear_before("No")
|
||||
end
|
||||
|
||||
it "renders buttons to vote question answers" do
|
||||
sign_in(create(:user, :verified))
|
||||
|
||||
render_inline Polls::Questions::AnswersComponent.new(question)
|
||||
|
||||
expect(page).to have_button "Yes"
|
||||
expect(page).to have_button "No"
|
||||
end
|
||||
|
||||
it "renders a span instead of a button for existing user answers" do
|
||||
user = create(:user, :verified)
|
||||
allow(user).to receive(:current_sign_in_at).and_return(user.created_at)
|
||||
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"
|
||||
end
|
||||
|
||||
it "hides current answer and shows buttons in successive sessions" do
|
||||
user = create(:user, :verified)
|
||||
create(:poll_answer, author: user, question: question, answer: "Yes")
|
||||
allow(user).to receive(:current_sign_in_at).and_return(Time.current)
|
||||
sign_in(user)
|
||||
|
||||
render_inline Polls::Questions::AnswersComponent.new(question)
|
||||
|
||||
expect(page).to have_button "Yes"
|
||||
expect(page).to have_button "No"
|
||||
end
|
||||
|
||||
it "when user is not signed in, renders answers links pointing to user sign in path" do
|
||||
render_inline Polls::Questions::AnswersComponent.new(question)
|
||||
|
||||
expect(page).to have_link "Yes", href: new_user_session_path
|
||||
expect(page).to have_link "No", href: new_user_session_path
|
||||
end
|
||||
|
||||
it "when user is not verified, renders answers links pointing to user verification in path" do
|
||||
sign_in(create(:user))
|
||||
|
||||
render_inline Polls::Questions::AnswersComponent.new(question)
|
||||
|
||||
expect(page).to have_link "Yes", href: verification_path
|
||||
expect(page).to have_link "No", href: verification_path
|
||||
end
|
||||
|
||||
it "when user already voted in booth it renders disabled answers" do
|
||||
user = create(:user, :level_two)
|
||||
create(:poll_voter, :from_booth, poll: poll, user: user)
|
||||
sign_in(user)
|
||||
|
||||
render_inline Polls::Questions::AnswersComponent.new(question)
|
||||
|
||||
expect(page).to have_selector "span.disabled", text: "Yes"
|
||||
expect(page).to have_selector "span.disabled", text: "No"
|
||||
end
|
||||
|
||||
it "user cannot vote when poll expired it renders disabled answers" do
|
||||
question = create(:poll_question, :yes_no, poll: create(:poll, :expired))
|
||||
sign_in(create(:user, :level_two))
|
||||
|
||||
render_inline Polls::Questions::AnswersComponent.new(question)
|
||||
|
||||
expect(page).to have_selector "span.disabled", text: "Yes"
|
||||
expect(page).to have_selector "span.disabled", text: "No"
|
||||
end
|
||||
|
||||
describe "geozone" do
|
||||
let(:poll) { create(:poll, geozone_restricted: true) }
|
||||
let(:geozone) { create(:geozone) }
|
||||
let(:question) { create(:poll_question, :yes_no, poll: poll) }
|
||||
|
||||
it "when geozone which is not theirs it renders disabled answers" do
|
||||
poll.geozones << geozone
|
||||
sign_in(create(:user, :level_two))
|
||||
|
||||
render_inline Polls::Questions::AnswersComponent.new(question)
|
||||
|
||||
expect(page).to have_selector "span.disabled", text: "Yes"
|
||||
expect(page).to have_selector "span.disabled", text: "No"
|
||||
end
|
||||
|
||||
it "reading a same-geozone poll it renders buttons to vote question answers" do
|
||||
poll.geozones << geozone
|
||||
sign_in(create(:user, :level_two, geozone: geozone))
|
||||
|
||||
render_inline Polls::Questions::AnswersComponent.new(question)
|
||||
|
||||
expect(page).to have_button "Yes"
|
||||
expect(page).to have_button "No"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -191,18 +191,6 @@ describe "Polls" do
|
||||
expect("Second question").to appear_before("Third question")
|
||||
end
|
||||
|
||||
scenario "Question answers appear in the given order" do
|
||||
question = create(:poll_question, poll: poll)
|
||||
answer1 = create(:poll_question_answer, title: "First", question: question, given_order: 2)
|
||||
answer2 = create(:poll_question_answer, title: "Second", question: question, given_order: 1)
|
||||
|
||||
visit poll_path(poll)
|
||||
|
||||
within("div#poll_question_#{question.id}") do
|
||||
expect(answer2.title).to appear_before(answer1.title)
|
||||
end
|
||||
end
|
||||
|
||||
scenario "More info answers appear in the given order" do
|
||||
question = create(:poll_question, poll: poll)
|
||||
answer1 = create(:poll_question_answer, title: "First", question: question, given_order: 2)
|
||||
@@ -248,8 +236,6 @@ describe "Polls" do
|
||||
visit poll_path(poll)
|
||||
|
||||
expect(page).to have_content("You must sign in or sign up to participate")
|
||||
expect(page).to have_link("Yes", href: new_user_session_path)
|
||||
expect(page).to have_link("No", href: new_user_session_path)
|
||||
end
|
||||
|
||||
scenario "Level 1 users" do
|
||||
@@ -265,89 +251,19 @@ describe "Polls" do
|
||||
visit poll_path(poll)
|
||||
|
||||
expect(page).to have_content("You must verify your account in order to answer")
|
||||
|
||||
expect(page).to have_link("Yes", href: verification_path)
|
||||
expect(page).to have_link("No", href: verification_path)
|
||||
end
|
||||
|
||||
scenario "Level 2 users in an expired poll" do
|
||||
expired_poll = create(:poll, :expired, geozone_restricted: true)
|
||||
expired_poll.geozones << geozone
|
||||
|
||||
question = create(:poll_question, :yes_no, poll: expired_poll)
|
||||
expired_poll = create(:poll, :expired)
|
||||
create(:poll_question, :yes_no, poll: expired_poll)
|
||||
|
||||
login_as(create(:user, :level_two, geozone: geozone))
|
||||
|
||||
visit poll_path(expired_poll)
|
||||
|
||||
within("#poll_question_#{question.id}_answers") do
|
||||
expect(page).to have_content("Yes")
|
||||
expect(page).to have_content("No")
|
||||
expect(page).not_to have_button "Yes"
|
||||
expect(page).not_to have_button "No"
|
||||
end
|
||||
expect(page).to have_content("This poll has finished")
|
||||
end
|
||||
|
||||
scenario "Level 2 users in a poll with questions for a geozone which is not theirs" do
|
||||
poll.update!(geozone_restricted: true)
|
||||
poll.geozones << create(:geozone)
|
||||
|
||||
question = create(:poll_question, :yes_no, poll: poll)
|
||||
|
||||
login_as(create(:user, :level_two))
|
||||
|
||||
visit poll_path(poll)
|
||||
|
||||
within("#poll_question_#{question.id}_answers") do
|
||||
expect(page).to have_content("Yes")
|
||||
expect(page).to have_content("No")
|
||||
expect(page).not_to have_button "Yes"
|
||||
expect(page).not_to have_button "No"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Level 2 users reading a same-geozone poll" do
|
||||
poll.update!(geozone_restricted: true)
|
||||
poll.geozones << geozone
|
||||
|
||||
question = create(:poll_question, :yes_no, poll: poll)
|
||||
|
||||
login_as(create(:user, :level_two, geozone: geozone))
|
||||
visit poll_path(poll)
|
||||
|
||||
within("#poll_question_#{question.id}_answers") do
|
||||
expect(page).to have_button "Yes"
|
||||
expect(page).to have_button "No"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Level 2 users reading a all-geozones poll" do
|
||||
question = create(:poll_question, :yes_no, poll: poll)
|
||||
|
||||
login_as(create(:user, :level_two))
|
||||
visit poll_path(poll)
|
||||
|
||||
within("#poll_question_#{question.id}_answers") do
|
||||
expect(page).to have_button "Yes"
|
||||
expect(page).to have_button "No"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Level 2 users who have already answered" do
|
||||
question = create(:poll_question, :yes_no, poll: poll)
|
||||
user = create(:user, :level_two)
|
||||
create(:poll_answer, question: question, author: user, answer: "No")
|
||||
|
||||
login_as user
|
||||
visit poll_path(poll)
|
||||
|
||||
within("#poll_question_#{question.id}_answers") do
|
||||
expect(page).to have_button "Yes"
|
||||
expect(page).to have_button "No"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Level 2 users answering" do
|
||||
poll.update!(geozone_restricted: true)
|
||||
poll.geozones << geozone
|
||||
|
||||
Reference in New Issue
Block a user