Add support for open-ended questions in admin section
Introduce a new "open" votation type for poll questions in the admin interface. This type allows open answers provided by the user.
This commit is contained in:
@@ -10,7 +10,8 @@ class Admin::VotationTypes::FieldsComponent < ApplicationComponent
|
|||||||
def descriptions
|
def descriptions
|
||||||
{
|
{
|
||||||
unique: t("admin.polls.votation_type.unique_description"),
|
unique: t("admin.polls.votation_type.unique_description"),
|
||||||
multiple: t("admin.polls.votation_type.multiple_description")
|
multiple: t("admin.polls.votation_type.multiple_description"),
|
||||||
|
open: t("admin.polls.votation_type.open_description")
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class Poll::Question < ApplicationRecord
|
|||||||
accepts_nested_attributes_for :question_options, reject_if: :all_blank, allow_destroy: true
|
accepts_nested_attributes_for :question_options, reject_if: :all_blank, allow_destroy: true
|
||||||
accepts_nested_attributes_for :votation_type
|
accepts_nested_attributes_for :votation_type
|
||||||
|
|
||||||
delegate :multiple?, :vote_type, to: :votation_type, allow_nil: true
|
delegate :multiple?, :open?, :vote_type, to: :votation_type, allow_nil: true
|
||||||
|
|
||||||
scope :sort_for_list, -> { order(Arel.sql("poll_questions.proposal_id IS NULL"), :created_at) }
|
scope :sort_for_list, -> { order(Arel.sql("poll_questions.proposal_id IS NULL"), :created_at) }
|
||||||
scope :for_render, -> { includes(:author, :proposal) }
|
scope :for_render, -> { includes(:author, :proposal) }
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ class VotationType < ApplicationRecord
|
|||||||
|
|
||||||
QUESTIONABLE_TYPES = %w[Poll::Question].freeze
|
QUESTIONABLE_TYPES = %w[Poll::Question].freeze
|
||||||
|
|
||||||
enum :vote_type, { unique: 0, multiple: 1 }
|
enum :vote_type, { unique: 0, multiple: 1, open: 2 }
|
||||||
|
|
||||||
validates :questionable, presence: true
|
validates :questionable, presence: true
|
||||||
validates :questionable_type, inclusion: { in: ->(*) { QUESTIONABLE_TYPES }}
|
validates :questionable_type, inclusion: { in: ->(*) { QUESTIONABLE_TYPES }}
|
||||||
|
|||||||
@@ -534,6 +534,7 @@ en:
|
|||||||
max_votes: Maximum number of votes
|
max_votes: Maximum number of votes
|
||||||
vote_type: Votation type
|
vote_type: Votation type
|
||||||
votation_type/vote_type:
|
votation_type/vote_type:
|
||||||
|
open: Open-ended
|
||||||
unique: Unique answer
|
unique: Unique answer
|
||||||
multiple: Multiple answers
|
multiple: Multiple answers
|
||||||
cookies/vendor:
|
cookies/vendor:
|
||||||
|
|||||||
@@ -1131,6 +1131,7 @@ en:
|
|||||||
title: "Votation type"
|
title: "Votation type"
|
||||||
unique_description: "It's only possible to answer one time to the question."
|
unique_description: "It's only possible to answer one time to the question."
|
||||||
multiple_description: "Allows to choose multiple answers. It's possible to set the maximum number of answers."
|
multiple_description: "Allows to choose multiple answers. It's possible to set the maximum number of answers."
|
||||||
|
open_description: "Open-ended question that allows users to provide a single answer in their own words."
|
||||||
questions:
|
questions:
|
||||||
index:
|
index:
|
||||||
create: "Create question"
|
create: "Create question"
|
||||||
|
|||||||
@@ -534,6 +534,7 @@ es:
|
|||||||
max_votes: Número máximo de votos
|
max_votes: Número máximo de votos
|
||||||
vote_type: Tipo de votación
|
vote_type: Tipo de votación
|
||||||
votation_type/vote_type:
|
votation_type/vote_type:
|
||||||
|
open: Respuesta abierta
|
||||||
unique: Respuesta única
|
unique: Respuesta única
|
||||||
multiple: Respuesta múltiple
|
multiple: Respuesta múltiple
|
||||||
cookies/vendor:
|
cookies/vendor:
|
||||||
|
|||||||
@@ -1131,6 +1131,7 @@ es:
|
|||||||
title: "Tipo de votación"
|
title: "Tipo de votación"
|
||||||
unique_description: "Solo se puede responder a la pregunta con una única respuesta."
|
unique_description: "Solo se puede responder a la pregunta con una única respuesta."
|
||||||
multiple_description: "Permite elegir más de una respuesta. Se puede elegir el número máximo de respuestas."
|
multiple_description: "Permite elegir más de una respuesta. Se puede elegir el número máximo de respuestas."
|
||||||
|
open_description: "Pregunta abierta que permite al usuario dar una única respuesta con sus propias palabras."
|
||||||
questions:
|
questions:
|
||||||
index:
|
index:
|
||||||
create: "Crear pregunta ciudadana"
|
create: "Crear pregunta ciudadana"
|
||||||
|
|||||||
@@ -94,6 +94,12 @@ FactoryBot.define do
|
|||||||
create(:votation_type_multiple, questionable: question, max_votes: evaluator.max_votes)
|
create(:votation_type_multiple, questionable: question, max_votes: evaluator.max_votes)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
factory :poll_question_open do
|
||||||
|
after(:create) do |question|
|
||||||
|
create(:votation_type_open, questionable: question)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
factory :poll_question_option, class: "Poll::Question::Option" do
|
factory :poll_question_option, class: "Poll::Question::Option" do
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ FactoryBot.define do
|
|||||||
max_votes { 3 }
|
max_votes { 3 }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
factory :votation_type_open do
|
||||||
|
vote_type { "open" }
|
||||||
|
end
|
||||||
|
|
||||||
questionable factory: :poll_question
|
questionable factory: :poll_question
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -30,6 +30,13 @@ describe Poll::Answer do
|
|||||||
expect(answer).not_to be_valid
|
expect(answer).not_to be_valid
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "is not valid without an answer when question is open-ended" do
|
||||||
|
answer.question = create(:poll_question_open)
|
||||||
|
answer.answer = nil
|
||||||
|
|
||||||
|
expect(answer).not_to be_valid
|
||||||
|
end
|
||||||
|
|
||||||
it "is not valid if there's already an answer to that question" do
|
it "is not valid if there's already an answer to that question" do
|
||||||
author = create(:user)
|
author = create(:user)
|
||||||
question = create(:poll_question, :yes_no)
|
question = create(:poll_question, :yes_no)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe VotationType do
|
describe VotationType do
|
||||||
let(:vote_types) { %i[votation_type_unique votation_type_multiple] }
|
let(:vote_types) { %i[votation_type_unique votation_type_multiple votation_type_open] }
|
||||||
let(:votation_type) { build(vote_types.sample) }
|
let(:votation_type) { build(vote_types.sample) }
|
||||||
|
|
||||||
it "is valid" do
|
it "is valid" do
|
||||||
@@ -27,6 +27,10 @@ describe VotationType do
|
|||||||
|
|
||||||
expect(votation_type).to be_valid
|
expect(votation_type).to be_valid
|
||||||
|
|
||||||
|
votation_type.vote_type = "open"
|
||||||
|
|
||||||
|
expect(votation_type).to be_valid
|
||||||
|
|
||||||
votation_type.vote_type = "multiple"
|
votation_type.vote_type = "multiple"
|
||||||
|
|
||||||
expect(votation_type).not_to be_valid
|
expect(votation_type).not_to be_valid
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ describe "Admin poll questions", :admin do
|
|||||||
expect(page).to have_content "It's only possible to answer one time to the question."
|
expect(page).to have_content "It's only possible to answer one time to the question."
|
||||||
expect(page).not_to have_content "Allows to choose multiple answers."
|
expect(page).not_to have_content "Allows to choose multiple answers."
|
||||||
expect(page).not_to have_field "Maximum number of votes"
|
expect(page).not_to have_field "Maximum number of votes"
|
||||||
|
expect(page).not_to have_content "Open-ended question that allows users to provide " \
|
||||||
|
"a single answer in their own words."
|
||||||
|
|
||||||
click_button "Save"
|
click_button "Save"
|
||||||
|
|
||||||
@@ -94,6 +96,8 @@ describe "Admin poll questions", :admin do
|
|||||||
|
|
||||||
expect(page).not_to have_content "It's only possible to answer one time to the question."
|
expect(page).not_to have_content "It's only possible to answer one time to the question."
|
||||||
expect(page).to have_content "Allows to choose multiple answers."
|
expect(page).to have_content "Allows to choose multiple answers."
|
||||||
|
expect(page).not_to have_content "Open-ended question that allows users to provide " \
|
||||||
|
"a single answer in their own words."
|
||||||
|
|
||||||
fill_in "Maximum number of votes", with: 6
|
fill_in "Maximum number of votes", with: 6
|
||||||
click_button "Save"
|
click_button "Save"
|
||||||
@@ -101,6 +105,21 @@ describe "Admin poll questions", :admin do
|
|||||||
expect(page).to have_content "Question with multiple answers"
|
expect(page).to have_content "Question with multiple answers"
|
||||||
expect(page).to have_content "Multiple answers"
|
expect(page).to have_content "Multiple answers"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scenario "Open-ended" do
|
||||||
|
fill_in "Question", with: "What do you want?"
|
||||||
|
select "Open-ended", from: "Votation type"
|
||||||
|
|
||||||
|
expect(page).not_to have_content "Allows to choose multiple answers."
|
||||||
|
expect(page).not_to have_field "Maximum number of votes"
|
||||||
|
expect(page).to have_content "Open-ended question that allows users to provide " \
|
||||||
|
"a single answer in their own words."
|
||||||
|
|
||||||
|
click_button "Save"
|
||||||
|
|
||||||
|
expect(page).to have_content "What do you want?"
|
||||||
|
expect(page).to have_content "Open-ended"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -143,7 +162,7 @@ describe "Admin poll questions", :admin do
|
|||||||
|
|
||||||
scenario "Update" do
|
scenario "Update" do
|
||||||
poll = create(:poll, :future)
|
poll = create(:poll, :future)
|
||||||
question = create(:poll_question, poll: poll)
|
question = create(:poll_question_open, poll: poll)
|
||||||
old_title = question.title
|
old_title = question.title
|
||||||
new_title = "Vegetables are great and everyone should have one"
|
new_title = "Vegetables are great and everyone should have one"
|
||||||
|
|
||||||
@@ -154,6 +173,12 @@ describe "Admin poll questions", :admin do
|
|||||||
end
|
end
|
||||||
|
|
||||||
expect(page).to have_link "Go back", href: admin_poll_path(poll)
|
expect(page).to have_link "Go back", href: admin_poll_path(poll)
|
||||||
|
expect(page).to have_select "Votation type", selected: "Open-ended"
|
||||||
|
expect(page).not_to have_content "Allows to choose multiple answers."
|
||||||
|
expect(page).not_to have_field "Maximum number of votes"
|
||||||
|
expect(page).to have_content "Open-ended question that allows users to provide " \
|
||||||
|
"a single answer in their own words."
|
||||||
|
|
||||||
fill_in "Question", with: new_title
|
fill_in "Question", with: new_title
|
||||||
|
|
||||||
click_button "Save"
|
click_button "Save"
|
||||||
|
|||||||
Reference in New Issue
Block a user