Manage correctly results and stats for open-ended questions

Note that we are not including Poll::PartialResults for open-ended
questions resutls. The reason is that we do not contemplate the
possibility of there being open questions in booths. Manually
counting and introducing the votes in the system is not feasible.
This commit is contained in:
taitus
2025-08-22 07:44:39 +02:00
parent 2a2edd17d1
commit f3050a1aa5
7 changed files with 220 additions and 52 deletions

View File

@@ -0,0 +1,47 @@
require "rails_helper"
describe Polls::Results::QuestionComponent do
context "question that accepts options" do
let(:question) { create(:poll_question, :yes_no) }
let(:option_yes) { question.question_options.find_by(title: "Yes") }
let(:option_no) { question.question_options.find_by(title: "No") }
it "renders results table content" do
create(:poll_answer, question: question, option: option_yes)
create(:poll_answer, question: question, option: option_no)
render_inline Polls::Results::QuestionComponent.new(question)
expect(page).to have_table with_rows: [{ "Most voted answer: Yes" => "1 (50.0%)",
"No" => "1 (50.0%)" }]
page.find("table") do |table|
expect(table).to have_css "th.win", count: 1
expect(table).to have_css "td.win", count: 1
end
end
end
context "question that does not accept options" do
let(:open_ended_question) { create(:poll_question_open) }
it "renders open_ended headers and empty counts when there are no participants" do
render_inline Polls::Results::QuestionComponent.new(open_ended_question)
expect(page).to have_table with_rows: [{ "Valid" => "0 (0.0%)",
"Blank" => "0 (0.0%)" }]
end
it "renders counts and percentages provided by the model metrics" do
allow(open_ended_question).to receive_messages(
open_ended_valid_answers_count: 3,
open_ended_blank_answers_count: 1
)
render_inline Polls::Results::QuestionComponent.new(open_ended_question)
expect(page).to have_table with_rows: [{ "Valid" => "3 (75.0%)",
"Blank" => "1 (25.0%)" }]
end
end
end

View File

@@ -3,47 +3,34 @@ require "rails_helper"
describe Polls::ResultsComponent do
let(:poll) { create(:poll) }
let(:question_1) { create(:poll_question, poll: poll, title: "Do you like Consul Democracy?") }
let(:option_yes) { create(:poll_question_option, question: question_1, title: "Yes") }
let(:option_no) { create(:poll_question_option, question: question_1, title: "No") }
let(:question_1) { create(:poll_question, :yes_no, poll: poll, title: "Do you like Consul Democracy?") }
let(:option_yes) { question_1.question_options.find_by(title: "Yes") }
let(:option_no) { question_1.question_options.find_by(title: "No") }
let(:question_2) { create(:poll_question, poll: poll, title: "What's your favorite color?") }
let(:option_blue) { create(:poll_question_option, question: question_2, title: "Blue") }
let(:option_green) { create(:poll_question_option, question: question_2, title: "Green") }
let(:option_yellow) { create(:poll_question_option, question: question_2, title: "Yellow") }
let(:question_2) { create(:poll_question, :abc, poll: poll, title: "Which option do you prefer?") }
let(:option_a) { question_2.question_options.find_by(title: "Answer A") }
let(:option_b) { question_2.question_options.find_by(title: "Answer B") }
let(:option_c) { question_2.question_options.find_by(title: "Answer C") }
it "renders results content" do
create_list(:poll_answer, 2, question: question_1, option: option_yes)
create(:poll_answer, question: question_1, option: option_no)
create(:poll_answer, question: question_2, option: option_blue)
create(:poll_answer, question: question_2, option: option_green)
create(:poll_answer, question: question_2, option: option_yellow)
create(:poll_answer, question: question_2, option: option_a)
create(:poll_answer, question: question_2, option: option_b)
create(:poll_answer, question: question_2, option: option_c)
render_inline Polls::ResultsComponent.new(poll)
expect(page).to have_content "Do you like Consul Democracy?"
expect(page).to have_table "question_#{question_1.id}_results_table",
with_rows: [{ "Most voted answer: Yes" => "2 (66.67%)",
"No" => "1 (33.33%)" }]
page.find("#question_#{question_1.id}_results_table") do |table|
expect(table).to have_css "#option_#{option_yes.id}_result", text: "2 (66.67%)", normalize_ws: true
expect(table).to have_css "#option_#{option_no.id}_result", text: "1 (33.33%)", normalize_ws: true
end
expect(page).to have_content "What's your favorite color?"
page.find("#question_#{question_2.id}_results_table") do |table|
expect(table).to have_css "#option_#{option_blue.id}_result", text: "1 (33.33%)", normalize_ws: true
expect(table).to have_css "#option_#{option_green.id}_result", text: "1 (33.33%)", normalize_ws: true
expect(table).to have_css "#option_#{option_yellow.id}_result", text: "1 (33.33%)", normalize_ws: true
end
end
it "renders results for polls with questions but without answers" do
poll = create(:poll, :expired, results_enabled: true)
question = create(:poll_question, poll: poll)
render_inline Polls::ResultsComponent.new(poll)
expect(page).to have_content question.title
expect(page).to have_content "Which option do you prefer?"
expect(page).to have_table "question_#{question_2.id}_results_table",
with_rows: [{ "Most voted answer: Answer A" => "1 (33.33%)",
"Answer B" => "1 (33.33%)",
"Answer C" => "1 (33.33%)" }]
end
end