models: refactor the types_de_champ validators

Context: we want to validate public and private types_de_champ
separately.

Before we validated the whole revision (and then validators themselves
enumerated all champs, public and private).

Now we validate the actual public types_de_champ, which will let us
validate separately the private types_de_champ.
This commit is contained in:
Pierre de La Morinerie 2022-01-26 16:52:32 +00:00
parent 64d75360d0
commit e8e37cce15
8 changed files with 22 additions and 30 deletions

View file

@ -245,7 +245,7 @@ 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,
validates :draft_types_de_champ,
'revisions/no_empty_repetition': true,
'revisions/no_empty_drop_down': true,
if: :validate_for_publication?

View file

@ -1,10 +1,6 @@
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|
def validate_each(procedure, attribute, types_de_champ)
types_de_champ.filter(&:drop_down_list?).each do |drop_down|
validate_drop_down_not_empty(procedure, attribute, drop_down)
end
end

View file

@ -1,10 +1,6 @@
class Revisions::NoEmptyRepetitionValidator < ActiveModel::EachValidator
def validate_each(procedure, attribute, revision)
return if revision.nil?
revision_tdcs = revision.types_de_champ + revision.types_de_champ_private
repetitions = revision_tdcs.filter(&:repetition?)
repetitions.each do |repetition|
def validate_each(procedure, attribute, types_de_champ)
types_de_champ.filter(&:repetition?).each do |repetition|
validate_repetition_not_empty(procedure, attribute, repetition)
end
end

View file

@ -53,7 +53,7 @@
- if !@procedure.locked? || @procedure.feature_enabled?(:procedure_revisions)
- @procedure.validate(:publication)
- error_messages = @procedure.errors.messages_for(:draft_revision).to_sentence
- error_messages = @procedure.errors.messages_for(:draft_types_de_champ).to_sentence
= link_to champs_admin_procedure_path(@procedure), class: 'card-admin', title: error_messages do
- if @procedure.draft_types_de_champ.count == 0

View file

@ -328,8 +328,8 @@ fr:
connexion: "Erreur lors de la connexion à France Connect."
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'
empty_repetition: '« %{value} » doit comporter au moins un champ répétable'
empty_drop_down: '« %{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

@ -23,5 +23,5 @@ fr:
attributes:
api_particulier_token:
invalid: 'na pas le bon format'
draft_revision:
format: '%{message}'
draft_types_de_champ:
format: 'Le champ %{message}'

View file

@ -302,17 +302,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(:invalid_repetition_error_message) { 'Le bloc répétable « Enfants » doit comporter au moins un champ' }
let(:invalid_repetition_error_message) { 'Le champ « Enfants » doit comporter au moins un champ répétable' }
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(:invalid_drop_down_error_message) { 'Le champ « 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 the draft revision' do
procedure.validate
expect(procedure.errors[:draft_revision]).not_to be_present
expect(procedure.errors[:draft_types_de_champ]).not_to be_present
end
end
@ -321,35 +321,35 @@ describe Procedure do
it 'validates that no repetition type de champ is empty' do
procedure.validate
expect(procedure.errors.full_messages_for(:draft_revision)).to include(invalid_repetition_error_message)
expect(procedure.errors.full_messages_for(:draft_types_de_champ)).to include(invalid_repetition_error_message)
text_field.revision = repetition.revision
text_field.order_place = repetition.types_de_champ.size
procedure.draft_revision.types_de_champ.find(&:repetition?).types_de_champ << text_field
procedure.draft_types_de_champ.find(&:repetition?).types_de_champ << text_field
procedure.validate
expect(procedure.errors.full_messages_for(:draft_revision)).not_to include(invalid_repetition_error_message)
expect(procedure.errors.full_messages_for(:draft_types_de_champ)).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)
expect(procedure.errors.full_messages_for(:draft_types_de_champ)).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)
expect(procedure.errors.full_messages_for(:draft_types_de_champ)).not_to include(invalid_drop_down_error_message)
end
end
context 'when validating for publication' do
it 'validates that no repetition type de champ is empty' do
procedure.validate(:publication)
expect(procedure.errors.full_messages_for(:draft_revision)).to include(invalid_repetition_error_message)
expect(procedure.errors.full_messages_for(:draft_types_de_champ)).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)
expect(procedure.errors.full_messages_for(:draft_types_de_champ)).to include(invalid_drop_down_error_message)
end
end
end

View file

@ -47,7 +47,7 @@ describe 'Publishing a procedure', js: true do
end
context 'when the procedure has invalid champs' do
let(:empty_repetition) { build(:type_de_champ_repetition, types_de_champ: []) }
let(:empty_repetition) { build(:type_de_champ_repetition, types_de_champ: [], libelle: 'Enfants') }
let!(:procedure) do
create(:procedure,
:with_path,
@ -59,7 +59,7 @@ describe 'Publishing a procedure', js: true do
scenario 'an error message prevents the publication' do
expect(page).to have_content('Des problèmes empêchent la publication de la démarche')
expect(page).to have_content("Le bloc répétable « #{empty_repetition.libelle} » doit comporter au moins un champ")
expect(page).to have_content("Le champ « Enfants » doit comporter au moins un champ répétable")
expect(find_field('procedure_path').value).to eq procedure.path
fill_in 'lien_site_web', with: 'http://some.website'