Extract admin poll results to component
Note that we have the same code in the officing section. Then we can use the same component. Note also that we are removing the parts of the system specs that are now covered by the component itself, and taking the chance to unify tests. In these removals and unifications we take into account that there are other specs which already cover user interaction in this section.
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
<div class="admin-poll-results-question">
|
||||
<h3><%= question.title %></h3>
|
||||
<table class="margin">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= t("admin.results.result.table_answer") %></th>
|
||||
<th class="text-center"><%= t("admin.results.result.table_votes") %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% question.question_options.each_with_index do |option, i| %>
|
||||
<% by_answer = by_question[question.id].present? ? by_question[question.id].group_by(&:answer) : {} %>
|
||||
<tr id="question_<%= question.id %>_<%= i %>_result">
|
||||
<td><%= option.title %></td>
|
||||
<td class="text-center"><%= by_answer[option.title].present? ? by_answer[option.title].sum(&:amount) : 0 %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
12
app/components/admin/poll/results/question_component.rb
Normal file
12
app/components/admin/poll/results/question_component.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class Admin::Poll::Results::QuestionComponent < ApplicationComponent
|
||||
attr_reader :question, :partial_results
|
||||
|
||||
def initialize(question, partial_results)
|
||||
@question = question
|
||||
@partial_results = partial_results
|
||||
end
|
||||
|
||||
def by_question
|
||||
@by_question ||= partial_results.group_by(&:question_id)
|
||||
end
|
||||
end
|
||||
@@ -1,21 +1,3 @@
|
||||
<% by_question = @partial_results.group_by(&:question_id) %>
|
||||
<% @poll.questions.each do |question| %>
|
||||
<h3><%= question.title %></h3>
|
||||
<table class="margin">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= t("admin.results.result.table_answer") %></th>
|
||||
<th class="text-center"><%= t("admin.results.result.table_votes") %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% question.question_options.each_with_index do |option, i| %>
|
||||
<% by_answer = by_question[question.id].present? ? by_question[question.id].group_by(&:answer) : {} %>
|
||||
<tr id="question_<%= question.id %>_<%= i %>_result">
|
||||
<td><%= option.title %></td>
|
||||
<td class="text-center"><%= by_answer[option.title].present? ? by_answer[option.title].sum(&:amount) : 0 %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<%= render Admin::Poll::Results::QuestionComponent.new(question, @partial_results) %>
|
||||
<% end %>
|
||||
|
||||
@@ -27,27 +27,8 @@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<% by_question = @partial_results.group_by(&:question_id) %>
|
||||
<% @poll.questions.each do |question| %>
|
||||
<h3><%= question.title %></h3>
|
||||
|
||||
<table class="margin">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= t("admin.results.result.table_answer") %></th>
|
||||
<th class="text-center"><%= t("admin.results.result.table_votes") %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% question.question_options.each_with_index do |option, i| %>
|
||||
<% by_answer = by_question[question.id].present? ? by_question[question.id].group_by(&:answer) : {} %>
|
||||
<tr id="question_<%= question.id %>_<%= i %>_result">
|
||||
<td><%= option.title %></td>
|
||||
<td class="text-center"><%= by_answer[option.title].present? ? by_answer[option.title].sum(&:amount) : 0 %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<%= render Admin::Poll::Results::QuestionComponent.new(question, @partial_results) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Admin::Poll::Results::QuestionComponent do
|
||||
let(:poll) { create(:poll) }
|
||||
let(:question) { create(:poll_question, poll: poll, title: "What do you want?") }
|
||||
|
||||
before do
|
||||
create(:poll_question_option, question: question, title: "Yes")
|
||||
create(:poll_question_option, question: question, title: "No")
|
||||
end
|
||||
|
||||
it "renders question title and headers" do
|
||||
render_inline Admin::Poll::Results::QuestionComponent.new(question, poll.partial_results)
|
||||
|
||||
expect(page).to have_css "h3", text: "What do you want?"
|
||||
expect(page).to have_css "th", text: "Answer"
|
||||
expect(page).to have_css "th", text: "Votes"
|
||||
end
|
||||
|
||||
it "renders one row per option" do
|
||||
render_inline Admin::Poll::Results::QuestionComponent.new(question, poll.partial_results)
|
||||
|
||||
expect(page).to have_css "tbody tr", count: 2
|
||||
expect(page).to have_css "td", text: "Yes"
|
||||
expect(page).to have_css "td", text: "No"
|
||||
end
|
||||
|
||||
it "sums votes by answer title" do
|
||||
create(:poll_partial_result, question: question, answer: "Yes", amount: 2)
|
||||
create(:poll_partial_result, question: question, answer: "Yes", amount: 1)
|
||||
create(:poll_partial_result, question: question, answer: "No", amount: 5)
|
||||
|
||||
render_inline Admin::Poll::Results::QuestionComponent.new(question, question.partial_results)
|
||||
|
||||
page.find("tr#question_#{question.id}_0_result") do |yes_result|
|
||||
expect(yes_result).to have_css "td", text: "Yes"
|
||||
expect(yes_result).to have_css "td", text: "3"
|
||||
end
|
||||
|
||||
page.find("tr#question_#{question.id}_1_result") do |no_result|
|
||||
expect(no_result).to have_css "td", text: "No"
|
||||
expect(no_result).to have_css "td", text: "5"
|
||||
end
|
||||
end
|
||||
|
||||
it "shows 0 when an option has no partial results" do
|
||||
render_inline Admin::Poll::Results::QuestionComponent.new(question, poll.partial_results)
|
||||
|
||||
page.find("tr#question_#{question.id}_0_result") do |yes_result|
|
||||
expect(yes_result).to have_css "td", text: "Yes"
|
||||
expect(yes_result).to have_css "td", text: "0"
|
||||
end
|
||||
|
||||
page.find("tr#question_#{question.id}_1_result") do |no_result|
|
||||
expect(no_result).to have_css "td", text: "No"
|
||||
expect(no_result).to have_css "td", text: "0"
|
||||
end
|
||||
end
|
||||
|
||||
it "ignores partial results from other questions" do
|
||||
other_question = create(:poll_question, poll: poll)
|
||||
create(:poll_question_option, question: other_question, title: "Yes")
|
||||
create(:poll_question_option, question: other_question, title: "Irrelevant")
|
||||
create(:poll_partial_result, question: other_question, answer: "Yes", amount: 9)
|
||||
create(:poll_partial_result, question: other_question, answer: "Irrelevant", amount: 9)
|
||||
|
||||
render_inline Admin::Poll::Results::QuestionComponent.new(question, poll.partial_results)
|
||||
|
||||
expect(page).to have_css "td", text: "0", count: 2
|
||||
end
|
||||
end
|
||||
@@ -228,7 +228,7 @@ describe "Admin booths assignments", :admin do
|
||||
expect(page).not_to have_css "#recounts_list"
|
||||
end
|
||||
|
||||
scenario "Results for a booth assignment" do
|
||||
scenario "Recounts for a booth assignment" do
|
||||
poll = create(:poll)
|
||||
booth_assignment = create(:poll_booth_assignment, poll: poll)
|
||||
other_booth_assignment = create(:poll_booth_assignment, poll: poll)
|
||||
@@ -285,30 +285,6 @@ describe "Admin booths assignments", :admin do
|
||||
|
||||
click_link "Results"
|
||||
|
||||
expect(page).to have_content(question_1.title)
|
||||
|
||||
within("#question_#{question_1.id}_0_result") do
|
||||
expect(page).to have_content("Yes")
|
||||
expect(page).to have_content(11)
|
||||
end
|
||||
|
||||
within("#question_#{question_1.id}_1_result") do
|
||||
expect(page).to have_content("No")
|
||||
expect(page).to have_content(4)
|
||||
end
|
||||
|
||||
expect(page).to have_content(question_2.title)
|
||||
|
||||
within("#question_#{question_2.id}_0_result") do
|
||||
expect(page).to have_content("Today")
|
||||
expect(page).to have_content(5)
|
||||
end
|
||||
|
||||
within("#question_#{question_2.id}_1_result") do
|
||||
expect(page).to have_content("Tomorrow")
|
||||
expect(page).to have_content(6)
|
||||
end
|
||||
|
||||
within("#white_results") { expect(page).to have_content("21") }
|
||||
within("#null_results") { expect(page).to have_content("44") }
|
||||
within("#total_results") { expect(page).to have_content("66") }
|
||||
|
||||
@@ -343,46 +343,6 @@ describe "Admin polls", :admin do
|
||||
expect(page).to have_content "There are no results"
|
||||
end
|
||||
|
||||
scenario "Show partial results" do
|
||||
poll = create(:poll)
|
||||
|
||||
booth_assignment_1 = create(:poll_booth_assignment, poll: poll)
|
||||
booth_assignment_2 = create(:poll_booth_assignment, poll: poll)
|
||||
booth_assignment_3 = create(:poll_booth_assignment, poll: poll)
|
||||
|
||||
question_1 = create(:poll_question, poll: poll)
|
||||
create(:poll_question_option, title: "Oui", question: question_1)
|
||||
create(:poll_question_option, title: "Non", question: question_1)
|
||||
|
||||
question_2 = create(:poll_question, poll: poll)
|
||||
create(:poll_question_option, title: "Aujourd'hui", question: question_2)
|
||||
create(:poll_question_option, title: "Demain", question: question_2)
|
||||
|
||||
[booth_assignment_1, booth_assignment_2, booth_assignment_3].each do |ba|
|
||||
create(:poll_partial_result,
|
||||
booth_assignment: ba,
|
||||
question: question_1,
|
||||
answer: "Oui",
|
||||
amount: 11)
|
||||
|
||||
create(:poll_partial_result,
|
||||
booth_assignment: ba,
|
||||
question: question_2,
|
||||
answer: "Demain",
|
||||
amount: 5)
|
||||
end
|
||||
|
||||
create(:poll_recount,
|
||||
booth_assignment: booth_assignment_1,
|
||||
white_amount: 21,
|
||||
null_amount: 44,
|
||||
total_amount: 66)
|
||||
|
||||
visit admin_poll_results_path(poll)
|
||||
|
||||
expect(page).to have_content "Results by booth"
|
||||
end
|
||||
|
||||
scenario "Enable stats and results for booth polls" do
|
||||
unvoted_poll = create(:poll)
|
||||
|
||||
@@ -418,8 +378,9 @@ describe "Admin polls", :admin do
|
||||
expect(page).not_to have_content "Results by booth"
|
||||
end
|
||||
|
||||
scenario "Results by answer" do
|
||||
scenario "Show results, recount and details by booth" do
|
||||
poll = create(:poll)
|
||||
|
||||
booth_assignment_1 = create(:poll_booth_assignment, poll: poll)
|
||||
booth_assignment_2 = create(:poll_booth_assignment, poll: poll)
|
||||
booth_assignment_3 = create(:poll_booth_assignment, poll: poll)
|
||||
@@ -427,7 +388,7 @@ describe "Admin polls", :admin do
|
||||
question_1 = create(:poll_question, :yes_no, poll: poll)
|
||||
|
||||
question_2 = create(:poll_question, poll: poll)
|
||||
create(:poll_question_option, title: "Today", question: question_2)
|
||||
create(:poll_question_option, title: "Today", question: question_2)
|
||||
create(:poll_question_option, title: "Tomorrow", question: question_2)
|
||||
|
||||
[booth_assignment_1, booth_assignment_2, booth_assignment_3].each do |ba|
|
||||
@@ -436,12 +397,14 @@ describe "Admin polls", :admin do
|
||||
question: question_1,
|
||||
answer: "Yes",
|
||||
amount: 11)
|
||||
|
||||
create(:poll_partial_result,
|
||||
booth_assignment: ba,
|
||||
question: question_2,
|
||||
answer: "Tomorrow",
|
||||
amount: 5)
|
||||
end
|
||||
|
||||
create(:poll_recount,
|
||||
booth_assignment: booth_assignment_1,
|
||||
white_amount: 21,
|
||||
@@ -449,60 +412,21 @@ describe "Admin polls", :admin do
|
||||
total_amount: 66)
|
||||
|
||||
visit admin_poll_path(poll)
|
||||
|
||||
click_link "Results"
|
||||
|
||||
expect(page).to have_content(question_1.title)
|
||||
question_1.question_options.each_with_index do |option, i|
|
||||
within("#question_#{question_1.id}_#{i}_result") do
|
||||
expect(page).to have_content(option.title)
|
||||
expect(page).to have_content([33, 0][i])
|
||||
end
|
||||
end
|
||||
|
||||
expect(page).to have_content(question_2.title)
|
||||
question_2.question_options.each_with_index do |option, i|
|
||||
within("#question_#{question_2.id}_#{i}_result") do
|
||||
expect(page).to have_content(option.title)
|
||||
expect(page).to have_content([0, 15][i])
|
||||
end
|
||||
end
|
||||
expect(page).to have_content "Results by booth"
|
||||
|
||||
within("#white_results") { expect(page).to have_content("21") }
|
||||
within("#null_results") { expect(page).to have_content("44") }
|
||||
within("#total_results") { expect(page).to have_content("66") }
|
||||
end
|
||||
|
||||
scenario "Link to results by booth" do
|
||||
poll = create(:poll)
|
||||
booth_assignment1 = create(:poll_booth_assignment, poll: poll)
|
||||
booth_assignment2 = create(:poll_booth_assignment, poll: poll)
|
||||
expect(page).to have_link("See results", count: 3)
|
||||
|
||||
question = create(:poll_question, :yes_no, poll: poll)
|
||||
|
||||
create(:poll_partial_result,
|
||||
booth_assignment: booth_assignment1,
|
||||
question: question,
|
||||
answer: "Yes",
|
||||
amount: 5)
|
||||
|
||||
create(:poll_partial_result,
|
||||
booth_assignment: booth_assignment2,
|
||||
question: question,
|
||||
answer: "Yes",
|
||||
amount: 6)
|
||||
|
||||
visit admin_poll_path(poll)
|
||||
|
||||
click_link "Results"
|
||||
|
||||
expect(page).to have_link("See results", count: 2)
|
||||
|
||||
within("#booth_assignment_#{booth_assignment1.id}_result") do
|
||||
within("#booth_assignment_#{booth_assignment_1.id}_result") do
|
||||
click_link "See results"
|
||||
end
|
||||
|
||||
expect(page).to have_content booth_assignment1.booth.name
|
||||
expect(page).to have_content booth_assignment_1.booth.name
|
||||
expect(page).to have_content "Results"
|
||||
expect(page).to have_content "Yes"
|
||||
expect(page).to have_content "5"
|
||||
|
||||
@@ -123,6 +123,9 @@ describe "Officing Results", :with_frozen_time do
|
||||
click_link "See results"
|
||||
end
|
||||
|
||||
expect(page).to have_content(I18n.l(Date.current.to_date, format: :long))
|
||||
expect(page).to have_content(booth_name)
|
||||
|
||||
within("#question_#{question_1.id}_0_result") do
|
||||
expect(page).to have_content("5555")
|
||||
expect(page).not_to have_content("7777")
|
||||
@@ -134,50 +137,4 @@ describe "Officing Results", :with_frozen_time do
|
||||
within("#question_#{question_1.id}_0_result") { expect(page).to have_content("5555") }
|
||||
within("#question_#{question_1.id}_1_result") { expect(page).to have_content("200") }
|
||||
end
|
||||
|
||||
scenario "Index lists all questions and answers" do
|
||||
officer_assignment = poll_officer.officer_assignments.first
|
||||
booth_assignment = officer_assignment.booth_assignment
|
||||
booth = booth_assignment.booth
|
||||
|
||||
create(
|
||||
:poll_partial_result,
|
||||
officer_assignment: officer_assignment,
|
||||
booth_assignment: booth_assignment,
|
||||
date: poll.ends_at,
|
||||
question: question_1,
|
||||
amount: 33
|
||||
)
|
||||
|
||||
create(
|
||||
:poll_recount,
|
||||
officer_assignment: officer_assignment,
|
||||
booth_assignment: booth_assignment,
|
||||
date: poll.ends_at,
|
||||
white_amount: 21,
|
||||
null_amount: 44,
|
||||
total_amount: 66
|
||||
)
|
||||
|
||||
visit officing_poll_results_path(poll,
|
||||
date: I18n.l(poll.ends_at.to_date),
|
||||
booth_assignment_id: officer_assignment.booth_assignment_id)
|
||||
|
||||
expect(page).to have_content(I18n.l(poll.ends_at.to_date, format: :long))
|
||||
expect(page).to have_content(booth.name)
|
||||
|
||||
expect(page).to have_content(question_1.title)
|
||||
question_1.question_options.each_with_index do |answer, i|
|
||||
within("#question_#{question_1.id}_#{i}_result") { expect(page).to have_content(answer.title) }
|
||||
end
|
||||
|
||||
expect(page).to have_content(question_2.title)
|
||||
question_2.question_options.each_with_index do |answer, i|
|
||||
within("#question_#{question_2.id}_#{i}_result") { expect(page).to have_content(answer.title) }
|
||||
end
|
||||
|
||||
within("#white_results") { expect(page).to have_content("21") }
|
||||
within("#null_results") { expect(page).to have_content("44") }
|
||||
within("#total_results") { expect(page).to have_content("66") }
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user