diff --git a/app/models/votation_type.rb b/app/models/votation_type.rb index 79c974681..af2758527 100644 --- a/app/models/votation_type.rb +++ b/app/models/votation_type.rb @@ -1,6 +1,8 @@ class VotationType < ApplicationRecord belongs_to :questionable, polymorphic: true + validate :cannot_be_open_ended_if_question_has_options + QUESTIONABLE_TYPES = %w[Poll::Question].freeze enum :vote_type, { unique: 0, multiple: 1, open: 2 } @@ -18,4 +20,10 @@ class VotationType < ApplicationRecord def max_votes_required? multiple? end + + def cannot_be_open_ended_if_question_has_options + if questionable&.question_options&.any? && !accepts_options? + errors.add(:vote_type, :cannot_change_to_open_ended) + end + end end diff --git a/config/locales/en/activerecord.yml b/config/locales/en/activerecord.yml index 852155ee5..ec1402b59 100644 --- a/config/locales/en/activerecord.yml +++ b/config/locales/en/activerecord.yml @@ -629,6 +629,10 @@ en: attributes: code: invalid: "must start with the same code as its target followed by a dot and end with a number" + votation_type: + attributes: + vote_type: + cannot_change_to_open_ended: "can't change to open-ended type because you've already defined possible valid answers for this question" messages: translations_too_short: Is mandatory to provide one translation at least record_invalid: "Validation failed: %{errors}" diff --git a/config/locales/es/activerecord.yml b/config/locales/es/activerecord.yml index 61e389ee3..44e866faa 100644 --- a/config/locales/es/activerecord.yml +++ b/config/locales/es/activerecord.yml @@ -629,6 +629,10 @@ es: attributes: code: invalid: "debe empezar con el código de su meta seguido de un punto y terminar con un número" + votation_type: + attributes: + vote_type: + cannot_change_to_open_ended: "no se puede cambiar a respuesta abierta el tipo de votación porque ya has definido posibles respuestas válidas para esta pregunta" messages: translations_too_short: El obligatorio proporcionar una traducción como mínimo record_invalid: "Error de validación: %{errors}" diff --git a/db/dev_seeds/polls.rb b/db/dev_seeds/polls.rb index 1d5e25077..8e5a952c9 100644 --- a/db/dev_seeds/polls.rb +++ b/db/dev_seeds/polls.rb @@ -52,6 +52,7 @@ end section "Creating Poll Questions & Options" do Poll.find_each do |poll| (3..5).to_a.sample.times do + vote_type = VotationType.vote_types.keys.sample question_title = Faker::Lorem.sentence(word_count: 3).truncate(60) + "?" question = Poll::Question.new(author: User.sample, title: question_title, @@ -62,33 +63,29 @@ section "Creating Poll Questions & Options" do end end question.save! - Faker::Lorem.words(number: (2..4).to_a.sample).each_with_index do |title, index| - description = "
#{Faker::Lorem.paragraphs.join("
")}
" - option = Poll::Question::Option.new(question: question, - title: title.capitalize, - description: description, - given_order: index + 1) - Setting.enabled_locales.map do |locale| - Globalize.with_locale(locale) do - option.title = "#{title} (#{locale})" - option.description = "#{description} (#{locale})" + + question.create_votation_type!(vote_type: vote_type, max_votes: (3 if vote_type == "multiple")) + + if question.accepts_options? + Faker::Lorem.words(number: (2..4).to_a.sample).each_with_index do |title, index| + description = "#{Faker::Lorem.paragraphs.join("
")}
" + option = Poll::Question::Option.new(question: question, + title: title.capitalize, + description: description, + given_order: index + 1) + Setting.enabled_locales.map do |locale| + Globalize.with_locale(locale) do + option.title = "#{title} (#{locale})" + option.description = "#{description} (#{locale})" + end end + option.save! end - option.save! end end end end -section "Creating Poll Votation types" do - poll = Poll.first - - poll.questions.each do |question| - vote_type = VotationType.vote_types.keys.sample - question.create_votation_type!(vote_type: vote_type, max_votes: (3 unless vote_type == "unique")) - end -end - section "Creating Poll Booths & BoothAssignments" do 20.times do |i| Poll::Booth.create(name: "Booth #{i}", @@ -158,11 +155,16 @@ section "Creating Poll Voters" do poll.questions.each do |question| next unless [true, false].sample - option = question.question_options.sample - Poll::Answer.create!(question_id: question.id, - author: user, - option: option, - answer: option.title) + if question.accepts_options? + option = question.question_options.sample + Poll::Answer.create!(question_id: question.id, + author: user, + option: option, + answer: option.title) + else + text = Faker::Lorem.sentence(word_count: (6..14).to_a.sample) + Poll::Answer.create!(question_id: question.id, author: user, answer: text) + end end end @@ -254,6 +256,7 @@ section "Creating Poll Questions from Proposals" do end option.save! end + question.create_votation_type!(vote_type: "unique") end end diff --git a/spec/models/votation_type_spec.rb b/spec/models/votation_type_spec.rb index dac4799cd..b31090a6f 100644 --- a/spec/models/votation_type_spec.rb +++ b/spec/models/votation_type_spec.rb @@ -36,4 +36,26 @@ describe VotationType do expect(votation_type).not_to be_valid expect(votation_type.errors[:max_votes]).to include "can't be blank" end + + describe "#cannot_be_open_ended_if_question_has_options" do + it "allows changing to open-ended when the question has no options" do + votation_type = create(:votation_type_unique) + + votation_type.vote_type = :open + + expect(votation_type).to be_valid + end + + it "blocks changing to open-ended when the question has options" do + votation_type = create(:votation_type_unique) + create(:poll_question_option, question: votation_type.questionable) + + votation_type.vote_type = :open + + expect(votation_type).not_to be_valid + error = votation_type.errors[:vote_type].first + expect(error).to eq "can't change to open-ended type " \ + "because you've already defined possible valid answers for this question" + end + end end