models: validate that no drop-downs are empty on publishing

Disallow publishing a procedure containing drop-downs with no selectable
values.
This commit is contained in:
Pierre de La Morinerie 2021-11-30 12:26:19 +01:00
parent e219ec33d8
commit b7d17b0989
5 changed files with 51 additions and 4 deletions

View file

@ -234,7 +234,10 @@ class Procedure < ApplicationRecord
validates :description, presence: true, allow_blank: false, allow_nil: false
validates :administrateurs, presence: true
validates :lien_site_web, presence: true, if: :publiee?
validates :draft_revision, 'revisions/no_empty_repetition': true, if: :validate_for_publication?
validates :draft_revision,
'revisions/no_empty_repetition': true,
'revisions/no_empty_drop_down': true,
if: :validate_for_publication?
validate :check_juridique
validates :path, presence: true, format: { with: /\A[a-z0-9_\-]{3,200}\z/ }, uniqueness: { scope: [:path, :closed_at, :hidden_at, :unpublished_at], case_sensitive: false }
validates :duree_conservation_dossiers_dans_ds, allow_nil: false, numericality: { only_integer: true, greater_than_or_equal_to: 1, less_than_or_equal_to: MAX_DUREE_CONSERVATION }

View file

@ -0,0 +1,22 @@
class Revisions::NoEmptyDropDownValidator < ActiveModel::EachValidator
def validate_each(procedure, attribute, revision)
return if revision.nil?
tdcs = revision.types_de_champ + revision.types_de_champ_private
drop_downs = tdcs.filter(&:drop_down_list?)
drop_downs.each do |drop_down|
validate_drop_down_not_empty(procedure, attribute, drop_down)
end
end
private
def validate_drop_down_not_empty(procedure, attribute, drop_down)
if drop_down.drop_down_list_enabled_non_empty_options.empty?
procedure.errors.add(
attribute,
procedure.errors.generate_message(attribute, :empty_drop_down, { value: drop_down.libelle })
)
end
end
end

View file

@ -311,6 +311,7 @@ fr:
forbidden_html: "Seul-e-s les usagers peuvent se connecter via France Connect. En tant quinstructeur ou administrateur, nous vous invitons à <a href='%{reset_link}'>réininitialiser votre mot de passe</a>."
procedure_archived: "Cette démarche en ligne a été close, il nest plus possible de déposer de dossier."
empty_repetition: 'Le bloc répétable « %{value} » doit comporter au moins un champ'
empty_drop_down: 'La liste de choix « %{value} » doit comporter au moins un choix sélectionnable'
# procedure_not_draft: "Cette démarche nest maintenant plus en brouillon."
cadastres_empty:
one: "Aucune parcelle cadastrale sur la zone sélectionnée"

View file

@ -89,6 +89,9 @@ FactoryBot.define do
trait :long do
drop_down_list_value { "alpha\r\nbravo\r\n--separateur--\r\ncharly\r\ndelta\r\necho\r\nfox-trot\r\ngolf" }
end
trait :without_selectable_values do
drop_down_list_value { "\r\n--separateur--\r\n--separateur 2--\r\n \r\n" }
end
end
factory :type_de_champ_multiple_drop_down_list do
type_champ { TypeDeChamp.type_champs.fetch(:multiple_drop_down_list) }

View file

@ -282,13 +282,17 @@ describe Procedure do
describe 'draft_revision' do
let(:repetition) { build(:type_de_champ_repetition, libelle: 'Enfants') }
let(:text_field) { build(:type_de_champ_text) }
let(:procedure) { create(:procedure, types_de_champ: [repetition]) }
let(:invalid_repetition_error_message) { 'Le bloc répétable « Enfants » doit comporter au moins un champ' }
let(:drop_down) { build(:type_de_champ_drop_down_list, :without_selectable_values, libelle: 'Civilité') }
let(:invalid_drop_down_error_message) { 'La liste de choix « Civilité » doit comporter au moins un choix sélectionnable' }
let(:procedure) { create(:procedure, types_de_champ: [repetition, drop_down]) }
context 'on a draft procedure' do
it 'doesnt validate repetitions' do
it 'doesnt validate the draft revision' do
procedure.validate
expect(procedure.errors[:draft_revision]).not_to include(invalid_repetition_error_message)
expect(procedure.errors[:draft_revision]).not_to be_present
end
end
@ -306,6 +310,15 @@ describe Procedure do
procedure.validate
expect(procedure.errors.full_messages_for(:draft_revision)).not_to include(invalid_repetition_error_message)
end
it 'validates that no drop-down type de champ is empty' do
procedure.validate
expect(procedure.errors.full_messages_for(:draft_revision)).to include(invalid_drop_down_error_message)
drop_down.update!(drop_down_list_value: "--title--\r\nsome value")
procedure.reload.validate
expect(procedure.errors.full_messages_for(:draft_revision)).not_to include(invalid_drop_down_error_message)
end
end
context 'when validating for publication' do
@ -313,6 +326,11 @@ describe Procedure do
procedure.validate(:publication)
expect(procedure.errors.full_messages_for(:draft_revision)).to include(invalid_repetition_error_message)
end
it 'validates that no drop-down type de champ is empty' do
procedure.validate(:publication)
expect(procedure.errors.full_messages_for(:draft_revision)).to include(invalid_drop_down_error_message)
end
end
end
end